Skip to main content

Add a custom MCP server

Connect any MCP server your agents need that is not in the catalog: a remote URL, an npm or PyPI package, a GitHub release, or a package store artifact. Covers credentials, private network routing, agent access, the API, and every error you can hit.

Use a custom MCP server when the tool your agents need is not in the catalog. You give SchemaBounce the server's location and its credentials once, then grant it to the agents that should use it. Agents call its tools the same way they call any catalog server.

WhatDetail
WhereAgents > Tools, then Add custom server
Permissionadl:manage on the workspace. Without it the button is disabled.
PlansStarter and above. Free and Personal workspaces connect catalog servers only.
SourcesRemote URL, npm, PyPI, GitHub release, package store
Where it runsA remote server runs where you host it. A package server runs in your workspace's gateway.
SecretsEncrypted at rest, write-only, never shown again after you save

Before you start​

  • Know where the server comes from. You need its URL, or its package name and an exact version.
  • Have its credentials ready. API keys and tokens go in the Credentials rows of the form, never in a URL, a package name or a command.
  • Check your plan. On Free and Personal, saving a custom server is refused with "The free plan can connect curated marketplace MCP servers. Upgrade to connect custom or community servers." Every plan also limits how many MCP servers a workspace can connect, and custom servers count toward it. See Pricing.

Choose a source​

SourceUse it whenYou enterPinning
Remote URLYou or a vendor already host the serverHTTPS URL, optional auth header nameNone needed. You control the server.
npmThe server is published to npmPackage name and exact versionExact version required (1.4.2)
PyPIThe server is published to PyPIPackage name and exact versionExact version required (0.6.2)
GitHub releaseThe server ships as a binary on a GitHub releaseRepository, release tag, asset nameRelease tag required, checksum verified
Package storeThe server is published as a versioned artifact in the registryRepository path, version or digestResolved to a sha256 digest on save

A remote server is the fastest path when the vendor already runs one. A package server is the right choice for a server you would otherwise run on your own computer with npx or uvx.

Add the server​

  1. Open Agents > Tools.

  2. Select Add custom server. The form opens with the Remote URL tab selected.

  3. Choose who owns the connection:

    • Personal: your own account. Used only for your messages and runs. Available when personal connections are turned on for the workspace.
    • Team: a shared account for one team. Only the team's head can choose it.
    • Workspace: a company service or shared account. Used for anyone's messages and scheduled runs, wherever it is granted to an agent.
    • Agent: a dedicated identity for one agent. It is assigned from the agent's setup, not from this form.

    The owner cannot be changed after you save. See MCP ownership and sharing.

  4. Enter a Display name, for example Internal Scraper. The form shows the server ref it derives, custom/internal-scraper. Two custom servers cannot share a ref, so pick a different name if the form says the ref is taken. The name cannot be changed later.

  5. Pick the source tab and fill in its fields. Each tab is described below. If the vendor gives you a setup snippet, select Paste setup snippet instead and paste it; the form fills itself in. See Bring a server from Claude Desktop, Claude Code or Cursor.

  6. Check the Launch preview. It shows exactly what will run or which URL will be called.

  7. Add each secret the server needs under Credentials, one name and value per row.

  8. Select Add to workspace (or Add personal connection or Add team connection, matching the owner).

What happens next depends on the source:

  • Remote URL: SchemaBounce checks the server right away. The form shows the result, or a "Checking connection" notice while the check finishes in the background.
  • npm and PyPI: the button reads Preparing server while the gateway installs that exact version. This can take a few minutes. When it is done you see "Server prepared", and a server check starts.
  • GitHub release and package store: the release or artifact is fetched and verified the first time the server starts.

You can also add a custom server from an agent: open the agent, go to Data & Tools > Live tools, select Add a tool, then Add a custom server. A server added this way is granted to that agent as soon as it is saved.

Remote URL​

Your team or a vendor operates the server. SchemaBounce connects to it over Streamable HTTP and sends your credential as a request header.

FieldWhat to enter
Server URLThe server's MCP endpoint, for example https://mcp.example.com/mcp. If you leave out the scheme, the form adds https:// and uses port 443.
Auth headerWhich row under Credentials to send as a request header. The options are None and the names you entered under Credentials. The row's name is the header name, and its value is sent exactly as written on every request.

Example: a server that expects Authorization: Bearer <token>.

  1. Server URL: https://mcp.example.com/mcp
  2. Credentials: name Authorization, value Bearer sk-your-token
  3. Auth header: Authorization

The Auth header is always a credential's name, never its value, so the secret stays encrypted. If you leave it at None, SchemaBounce picks the header from the credential's name:

Credential nameHeader sent
Authorization (any case)Authorization: <value>, exactly as written. Use this for Basic ... credentials.
Contains TOKEN or BEARER, such as API_TOKENAuthorization: Bearer <value>. A value that already starts with Basic, Bearer, Token or Digest is sent as written.
Contains API_KEY or APIKEYX-Api-Key: <value>

Rules for the URL:

  • HTTPS only. http:// is refused, because the credential would travel in plain text.
  • No secrets in the URL. A query parameter named token, api_key, apikey, access_token, password, secret or key is refused. Put the value in Credentials instead.
  • No private addresses. A URL pointing at a private, link-local or internal IP is refused. To reach a server inside your own network, route it over the private network.

npm​

SchemaBounce installs this exact package version in your workspace's MCP gateway before any agent uses it, then runs its installed entry point. Agent sessions never download packages.

FieldExampleRule
npm package@my-org/my-mcp-serverA valid npm name, scoped or not
Exact version1.0.01.2.3, v1.2.3 or 1.2.3-beta.1. No ranges, no latest.

The launch preview shows the command, for example npx -y @my-org/[email protected]. Credentials reach the server as environment variables.

PyPI​

SchemaBounce builds a prepared virtual environment for this exact version. Agent sessions run it without calling uvx.

FieldExampleRule
PyPI packagemy-mcp-serverA valid PyPI name
Exact version0.6.2An exact release such as 1.2.3 or 1.2.3rc1

The launch preview shows uvx [email protected]. Credentials reach the server as environment variables.

GitHub release​

SchemaBounce downloads a release asset, checks its SHA-256 against the release's published checksums, and runs it in your workspace's gateway.

FieldExampleRule
Repositorymy-org/my-mcpAny owner/name. With GitHub connected to the workspace, your repos are suggested as you type.
Release tagv1.2.3A fixed tag. latest, main, master and head are refused.
Release assetmy-mcp-linux-amd64The file name of the Linux x86-64 binary, or of a .tar.gz, .tgz or .zip holding it

What the release needs:

  • A checksum file that covers the asset. SchemaBounce looks for checksums.txt, checksums, <asset>.sha256, or goreleaser's <repo>_<version>_checksums.txt. Without one the server does not start.
  • For an archive, a findable binary. The archive's top level must hold a file named exactly like the repository (my-mcp for my-org/my-mcp), or exactly one file.
  • For a private repository, a token. Connect GitHub to the workspace, or add a GITHUB_TOKEN credential with read access to the repository.

SchemaBounce runs the repository saved on the connection and nothing else. A request for any other repository under that connection is refused.

Package store​

SchemaBounce pulls a versioned artifact from the registry, checks it against a pinned sha256 digest, and runs it in your workspace's gateway. The artifact is the published package for an MCP server (a tarball or a single binary), not a source repository.

FieldExampleRule
Repositoryorg/bots/my-mcpLowercase path with at least two parts
Versionv1.2.3Resolved to a digest when you save. Enter a version, a digest, or both.
Pinned digestsha256: + 64 hex charactersOptional when a version is set
Layer selectormy-mcp-linux-amd64Only for an artifact that ships builds for several platforms

For a private artifact, add an OCI_TOKEN credential with pull access. As with GitHub releases, SchemaBounce runs only the repository saved on the connection.

Credentials​

Each row under Credentials is a name and a secret value.

  • A package server (npm, PyPI, GitHub release, package store) receives every row as an environment variable, for example MY_API_TOKEN.
  • A remote server receives credentials as request headers. See Remote URL for which row becomes which header.
  • Values are write-only. After you save, the form shows only the names. Leave a value blank when editing to keep the stored secret, or type a new one to replace it.
  • Values are encrypted at rest with per-workspace envelope encryption, and the API never returns them.
  • Secrets never go anywhere else. The form refuses a package name that contains a space, a colon, or a credential label such as "Client Secret", and the API refuses a command or URL that carries one (--token=, --api-key=, --password=, Authorization:, Bearer ). The launch recipe is visible to workspace members and recorded in the audit log, so a secret there would be exposed.

Never paste a token into a chat with an agent. If one was pasted, revoke it where it was issued and create a new one.

Reach a server on your private network​

A remote server inside your own network (a VPC, a data center, a tailnet) is reached through the workspace's private network connection.

  1. Connect a VPN first, in Settings > Agent Platform > Private network. Without one, the form warns that the server will not reach private hosts.
  2. On the Remote URL tab, turn on Route this server over the private network (VPN).
  3. Under Allowed domains, list each host the server may reach, one per line, as host or host:port. For example metrics.internal:443. At least one entry is required, and only these hosts are reachable through the tunnel.

Private network routing is available on the Team plan and above, and only for remote URL servers. It is refused for npm and PyPI servers. See Private network.

Give agents access​

A saved server does nothing until an agent is granted it.

  • From the server: on Agents > Tools, open the connection and use Agents with access.
  • For several agents at once: use the Access matrix tab on the same page.
  • From the agent: open the agent, go to Data & Tools > Live tools, and select Add a tool.

A grant can be narrowed to a list of the server's tools. Through the API or the SchemaBounce MCP, allowedTools set to a list allows only those tools, an empty list allows none, and leaving it out allows all of them.

Calls to a custom server's tools follow the same approval rules as any connected server. Set them for one agent under the agent's Governance > Approvals, or for every agent under Settings > Agent Platform.

Check that it works​

The connection card on Agents > Tools shows the server's state.

StateMeaningWhat to do
Saved, not yet verifiedSaved, but nothing has proven it works yetSelect Test connection, or let an agent use it
CheckingA check or a package preparation is runningWait a few seconds; npm and PyPI preparation can take minutes
ConnectedThe server answered and a read-only tool call succeededGrant it to agents
Reachable, not authenticated or Reachable (handshake accepted)The server answered and listed its tools, but none can run without arguments, so the credential is unprovenAgents can use it. If calls fail, check the credential and the Auth header choice
Needs setupA credential or a sign-in is missingSelect Edit credentials and add it
Needs attentionThe server could not be reached, or it rejected the credentialOpen the card to see the error, then fix the URL or credential
At session limitThe workspace is running as many MCP servers at once as its plan allowsStop idle agents, grant fewer servers per agent, or upgrade

A check starts the server, lists its tools, and calls one read-only tool that needs no arguments, when the server has one. That call is what proves the credential. A server whose tools all need arguments shows Reachable (handshake accepted), and agents can still use it. An agent sees a server's tools only after a check lists them.

Bring a server from Claude Desktop, Claude Code or Cursor​

The fastest way: select Paste setup snippet at the top of the Add custom MCP server form and paste what the vendor gave you. It accepts:

  • a JSON block from claude_desktop_config.json, ~/.claude.json or .cursor/mcp.json (an mcpServers or servers object, one server object, or a bare "name": { ... } fragment)
  • a claude mcp add ... or claude mcp add-json ... command

The form fills in the name, the tab, the URL or the package and version. Header and environment values go into the masked Credentials rows, Auth header is set (to Authorization when there is one), and the paste box clears itself because the snippet can hold a secret. It lists anything you still need to fix, such as a placeholder value or a missing version pin. An mcp-remote bridge becomes a direct Remote URL. A Docker or local program is refused with the reason. A snippet with several servers asks you to pick one.

To map a config by hand instead, here is how each field lands. That file configures your own computer only; it does nothing in a SchemaBounce workspace.

{
"mcpServers": {
"weather": {
"command": "npx",
"args": ["-y", "@my-org/[email protected]"],
"env": { "WEATHER_API_KEY": "..." }
},
"docs": {
"url": "https://mcp.example.com/mcp",
"headers": { "Authorization": "Bearer ..." }
}
}
}
In the config fileIn SchemaBounce
"command": "npx" with a package in argsnpm tab. Enter the package and pin an exact version.
"command": "uvx" with a packagePyPI tab. Pin an exact version.
"url"Remote URL tab
Each "env" entryA row under Credentials with the same name
A header such as "Authorization"A row under Credentials with the header's name and full value, chosen as Auth header
"command": "docker" or a local binaryNot supported. Publish the server to npm or PyPI, or host it remotely.

Add a server with the API or the SchemaBounce MCP​

Everything the form does is one API call, so you can script it. Authenticate with a service account that has adl:manage.

POST https://api.schemabounce.com/api/v1/workspaces/{workspaceId}/mcp/connections

A remote server:

{
"serverRef": "custom/docs-search",
"displayName": "Docs Search",
"credentials": { "Authorization": "Bearer sk-your-token" },
"transportConfig": {
"transportType": "streamable-http",
"packageType": "remote",
"url": "https://mcp.example.com/mcp",
"authHeaderName": "Authorization"
}
}

An npm server:

{
"serverRef": "custom/weather",
"displayName": "Weather",
"credentials": { "WEATHER_API_KEY": "your-key" },
"transportConfig": {
"transportType": "stdio",
"packageType": "npm",
"command": "npx",
"args": ["-y", "@my-org/[email protected]"]
}
}

Field rules:

  • serverRef must start with custom/, and transportConfig is then required. Sending the same serverRef again updates that connection.
  • transportType is streamable-http or sse for a remote server, stdio for a package server.
  • packageType is remote, npm, pypi, github or oci (the package store).
  • GitHub release uses repo, ref and asset. Package store uses ociRepository with ociVersion, ociDigest, or both.
  • Private network routing adds "network": { "scope": "private-network", "allowedDomains": ["metrics.internal:443"] } to transportConfig.
  • Non-secret settings such as a base URL can go in variables instead of credentials. A name cannot be in both.
  • authHeaderName must be the name of one of the connection's credentials (for example Authorization), never a value. A value is refused with a 400.

The response is the saved connection. Its credentialKeys lists the credential names, never the values. Check it with POST .../mcp/connections/{connectionId}/validate. That call returns 202 while the check runs in the background.

From an MCP client connected to the SchemaBounce MCP, call sb_access with action: connection_create and pass server_ref, display_name, credentials and transport_config, using the same fields as above. Then grant it with action: grant.

Change or remove a server​

  • Edit: on Agents > Tools, open the connection and select Edit credentials. You can change the source fields, the pinned version and the credentials. The display name and the owner stay fixed.
  • Move to a new version: edit the server and enter the new exact version, tag or digest. Custom servers do not take the catalog's one-click upgrade.
  • Remove: select Remove on the connection card. This deletes the connection and its stored credentials, and agents that were granted it can no longer call its tools.

Troubleshooting​

You seeCauseFix
"The free plan can connect curated marketplace MCP servers. Upgrade to connect custom or community servers."The workspace is on Free or PersonalUpgrade to Starter or above
"Plan limit reached: your plan allows N connected MCP servers."The workspace is at its plan's server limitRemove a server you no longer use, or upgrade
"Personal MCP connections are not enabled for this workspace."Personal ownership is off for this workspaceChoose Workspace or Team
transportConfig.authHeaderName must be the name of one of the connection's credentialsA header value was sent in authHeaderNamePut the value in credentials and send only its name
transportConfig.url must use httpsThe URL starts with http://Use the server's HTTPS address
transportConfig.url must not point at an internal/private addressThe URL is a private IPRoute the server over the private network
... must not contain an inline credentialA token is in the URL, command or argumentsMove it to Credentials
"An exact version is required." or is not an exact pinThe version is empty, a range, or a tag such as latestEnter one exact version
"This looks like a credential."The package field holds a secretPut the package name there and the secret under Credentials
ref "main" is not pinnedThe GitHub tag is a branch or latestUse a release tag such as v1.2.3
repo "owner/name" is not on the allowlistThe repository differs from the one saved on the connection, or the workspace is on Free or PersonalEdit the server to the right repository. Custom servers need Starter or above
no checksums asset in release or no checksum entryThe GitHub release has no checksum file, or it does not list the assetPublish checksums.txt (goreleaser does this by default) with the release
ambiguous archive: no top-level file named ...The archive holds several files and none is named like the repositoryName the binary after the repository, or ship it alone in the archive
"A custom server already uses the ref ..."Another custom server has the same derived refChoose a different display name, or edit the existing server
scope "private-network" is not allowed for packageType "npm"Private network routing was set on a package serverHost the server remotely, or turn routing off
At session limit on the cardToo many MCP servers running at once for the planStop idle agents, grant fewer servers per agent, or upgrade

Limits​

  • No Docker images and no local binaries. A server comes from a URL or a published package. SchemaBounce does not run a container per session.
  • No floating versions. Every package server runs one exact version, so every run uses the same code.
  • No plain HTTP. Remote servers use HTTPS.
  • Plan limits apply. Custom servers count toward the plan's connected MCP server limit and its limit on servers running at once.

Common questions​

Can I add an MCP server that is not in the catalog?​

Yes. On Starter and above, open Agents > Tools, select Add custom server, and enter its URL or package. Free and Personal workspaces connect catalog servers only.

Where does my custom MCP server run?​

A remote server runs wherever you or the vendor host it; SchemaBounce only connects to it. A package server (npm, PyPI, GitHub release, package store) runs as a process inside your workspace's MCP gateway.

Can SchemaBounce run my server from a Docker image?​

No. Publish it to npm or PyPI, or host it and add it by URL.

How do I use a server from my Claude Desktop config?​

Copy each field into the matching tab: npx packages into npm, uvx packages into PyPI, a url into Remote URL, and each env entry or header into Credentials. See Bring a server from Claude Desktop, Claude Code or Cursor.

Who can see my credentials?​

Nobody, after you save. Values are encrypted and write-only; the console and the API show only their names.

Can an agent add a custom server by itself?​

An agent inside the workspace cannot add a server or enter its credentials. An MCP client you connect to the SchemaBounce MCP can, through sb_access with action: connection_create, using your permissions.

Continue exploring