Add an MCP Server

Register a Remote endpoint or run a container as a Managed Server, then edit or remove it.

Agentic Friendly

Only a Platform Admin can add an MCP Server. A member who opens the create form is told that only a Platform Admin can change MCP Servers.

Adding a server makes it available to the whole organization. It does not give anyone access to the system behind it. Each member still links their own credential.

Open the section

In the Portal sidebar, under Workspace, select MCP Servers. The list shows every server the organization has, with its runtime, its status, and whether you have linked a credential to it.

MCP Servers list in the Portal showing a Remote and a Managed server with runtime, status, and credential columns

Select Add MCP Server.

Start from a preset

The create page opens with a preset picker. A preset fills in the form for a well-known MCP Server so you only have to review it.

PresetRuntimeAddress or image
LinearRemotehttps://mcp.linear.app/mcp
Linear (read-only)Remotehttps://mcp.linear.app/mcp/readonly
NotionRemotehttps://mcp.notion.com/mcp
GitHubRemotehttps://api.githubcopilot.com/mcp
Context7Manageddocker.io/mcp/context7:latest
CustomEitherNothing prefilled

MCP Server preset picker showing the available presets and the Custom option

Choose Custom to configure a server yourself.

Fill in the basic information

Every server, of either runtime, needs these fields.

FieldRule
RuntimeManaged or Remote. Permanent once saved.
NameLowercase letters, numbers, and dashes, starting and ending with a letter or number. Up to 63 characters. Unique within the organization. Permanent once saved.
Display nameThe label people read. Up to 200 characters. Editable.
DescriptionOptional. Up to 500 characters.

The name is the identifier the organization's own references are written against, so it cannot be changed later. The display name carries any wording you want to revise.

Add a Remote Server

A Remote Server has one runtime field.

Address is the full MCP endpoint, including the path. For example, https://mcp.linear.app/mcp.

The address must satisfy these rules:

  • It uses the http or https scheme, written in full. A bare hostname is refused.
  • It has no leading or trailing whitespace.
  • It carries no username or password. Credentials belong in a User Credential, not in the URL.
  • Its host is publicly resolvable. Private IP ranges, localhost, single-label hostnames, and cluster-internal names such as svc.cluster.local are all refused.
  • It is at most 2048 characters.

A refused address returns mcp_server_address_invalid and names the rule it broke.

Create form with runtime set to Remote, showing the Address field

Add a Managed Server

A Managed Server needs the container definition as well.

FieldRule
ImageRegistry-qualified, with a tag or digest. docker.io/mcp/context7:latest is accepted. mcp-probe:v1 is refused.
PortThe port the image itself listens on, between 1 and 65535.
PathWhere the image serves MCP. Defaults to /mcp. Must start with a slash.
ArgumentsOne per line. Optional.

A rejected image returns mcp_server_image_invalid and names the reference rule it broke. The API applies the same image-reference rules as the operator CRD. Form acceptance does not prove that the registry is reachable or that the image exists; those failures appear in the Managed Server status.

Four settings decide whether the container ever answers.

The image must already serve Streamable HTTP. Most MCP images start in stdio mode. Something has to switch the image out of stdio, and the switch differs per image. Context7 reads MCP_TRANSPORT=http from the environment. The GitHub server takes http --port 8080 as arguments. Without the switch the container starts, reports healthy, and never listens on the port.

Arguments replace the image's default command, and the entrypoint stays. An image whose CMD is node dist/index.js needs that listed first, then your own flags. Passing only a flag runs the entrypoint with that flag and the container dies.

Port must be the port the image listens on, not one you pick.

Path must be where the image serves MCP. Usually /mcp.

Create form with runtime set to Managed, showing image, port, path, and arguments

Environment variables

The Environment card takes one KEY=VALUE per line. Names must start with a letter or underscore and contain only letters, numbers, and underscores.

Values are write-only. They go into a Kubernetes Secret, and no endpoint returns them. A read reports names only, each marked as configured. The platform's own permissions include no read access to the Secret, so this is enforced rather than promised.

Because values are not readable, they are not recoverable. Record them wherever you keep other secrets.

If the values cannot be written to the cluster, the whole request fails with mcp_server_environment_not_stored and no server is created. This is the one part of a Managed Server that is not converged later, because the values exist nowhere else.

Security context

Every MCP Server container runs as a non-root user, with a read-only root filesystem and all capabilities dropped. Some images cannot survive that.

The Security context (advanced) section is the exception mechanism. It holds four settings.

SettingEffect
Run as user IDSets the numeric user the container runs as. Leave blank to keep the default.
Run as group IDSets the numeric group. Leave blank to keep the default.
Require a non-root userUndecided keeps the default. Switch it off only for an image that must run as root.
Read-only root filesystemUndecided keeps the default. Switch it off for an image that writes to its own filesystem.

An undecided setting leaves the platform's decision alone. Change one only when the image genuinely cannot run hardened. The container runs somebody else's code with your organization's credentials in its environment.

Context7 needs Run as user ID set to 1000 because the image ships no user of its own.

Expanded security context and environment sections on the Managed create form

Wait for a Managed Server to become ready

Open the server. Its status is one of four values.

StatusMeaning
ReadyThe workload is up and completed an MCP handshake.
Not readyThe workload exists but is not serving.
Status unknownA Managed Server the cluster has not reported on yet. Normal for a few seconds after creation.
Not reportedA Remote Server. It runs outside the platform and reports nothing. This is normal and permanent.

The detail page refreshes an unready Managed Server on its own for a minute, then offers a Refresh status button.

Creating a server records your intent. It succeeds even when the cluster is busy or unreachable, and the workload converges on the record afterwards. Status stays empty until the cluster catches up.

If a Managed Server never becomes ready, check the four settings above. A container that starts healthily and never answers is almost always still in stdio mode, or listening on a different port.

Managed MCP Server detail page in the ready state showing the status card

Edit a server

Select Edit MCP Server on the detail page. Runtime and name are shown as fixed. Everything else is editable.

The edit form replaces what you send. Fields you clear are cleared on the record. Environment variables are the deliberate exception.

An untouched edit form sends no environment at all, and the stored environment is preserved. To change it, select Replace environment. That replaces every variable at once, so retype every one you want to keep. Values cannot be read back, so a variable you leave out is a variable you remove. Keep the stored environment abandons the replacement.

Edit form environment card listing the currently set variable names

A server cannot change runtime. Editing a Managed Server as a Remote one, or the reverse, returns mcp_server_runtime_mismatch. To change runtime, delete the server and add a new one. The new server has a different identifier, so every member links it again and every Agent referencing it must be updated.

Delete a server

Select Delete on the detail page and confirm. Deleting removes the MCP Server and every User Credential linked to it. It cannot be undone. For a Managed Server, the workload is removed too.

Create a server with the API

The create form has a Create this with the API instead section that shows the exact request the form will send, built from what you have typed. Environment values are masked in that preview, so replace each placeholder before running it.

The equivalent request for a Remote Server:

export BSQAI_TOKEN=sk-bsq-v1-...

curl -X POST "https://api.<platform-domain>/v1/mcp/servers" \
  -H "Authorization: Bearer $BSQAI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "runtime": "remote",
    "name": "linear",
    "display_name": "Linear",
    "address": "https://mcp.linear.app/mcp"
  }'

And for a Managed Server:

curl -X POST "https://api.<platform-domain>/v1/mcp/servers" \
  -H "Authorization: Bearer $BSQAI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "runtime": "managed",
    "name": "context7",
    "display_name": "Context7",
    "image": "docker.io/mcp/context7:latest",
    "port": 8080,
    "path": "/mcp",
    "env": {"MCP_TRANSPORT": "http", "PORT": "8080"},
    "security": {"run_as_user": 1000}
  }'

Create an API key under Settings → API Keys in the Portal.

On this page