MCP Servers API

Browse the public MCP connector directory, register workspace-owned MCP servers, and call tools on connected servers.

Three surfaces work together:

SurfaceEndpointsPurpose
Public directory/mcps, /mcps/{slug}Discover featured connectors (Linear, Slack, GitHub, …)
Workspace registrations/mcp-serversRegister custom MCP server URLs for your workspace
Tool proxy/mcps/{slug}/toolsList and invoke tools after OAuth or API-key connect

Connecting (OAuth, API keys) uses POST /credentials with provider: "mcp" (requires credentials:write). This page covers directory browsing, workspace CRUD, discovery, and tool calls.

See REST overview — response format.

→ Browsing & connecting: CLI and web app workflows
→ Using connector tools — belt mcp tools and agent tool setup


Public directory

No API key required.

List MCP servers

GET /mcps or POST /mcps/list

Returns approved store listings sorted by rank. Accepts standard cursor-list parameters (cursor, limit, filters, sort, search) on POST.

Response (PublicMCPServerDTO):

FieldDescription
idServer ID
slugShort identifier (used in URLs and belt mcp connect {slug})
nameStable identifier (often matches slug)
titleDisplay name; falls back to name when empty
descriptionShort summary
icon_urlServer icon
categorydeveloper, productivity, data, communication, ai, or other
server_urlMCP endpoint URL
auth_typeoauth, api_key, or none
default_scopesOAuth scopes requested on connect
documentation_urlVendor docs link
namespacePublisher namespace
is_featured, rankStore placement
installs, usesUsage counters
connection_statusconnected when you or your workspace have a connected MCP credential for this server_url. Omitted otherwise. The match compares server_url with the credential's account_identifier.

Send an API key or session on list and get calls to receive connection_status. Unauthenticated directory requests omit it.

bash
1curl "https://api.inference.sh/mcps?limit=20"

Get by slug

GET /mcps/{slug}

Returns one public listing. Responds 404 when the slug is not in the directory.

bash
1curl https://api.inference.sh/mcps/linear

Discover server metadata

GET /mcps/discover?url={url}

Proxy for MCP remote discovery. Use this from custom UIs when browser CORS blocks direct fetches to /.well-known/mcp-server-card or OAuth metadata endpoints.

No API key required. The API tries, in order:

  1. GET {origin}/.well-known/mcp-server-card (MCP server card)
  2. OAuth protected-resource metadata on the URL

Returns the JSON document with Cache-Control: public, max-age=300. Responds 404 when neither document is found.

QueryRequiredDescription
urlYeshttp or https URL (typically a bare origin like https://mcp.example.com)
bash
1curl "https://api.inference.sh/mcps/discover?url=https://mcp.example.com"

The same resolution runs automatically when you connect via CLI, the web app, or POST /credentials with a bare server_url origin.


Workspace MCP server registrations

Manage servers your workspace publishes or connects privately. Requires API key scopes credentials:read (list, get) and credentials:write (create, update, delete).

List workspace servers

GET /mcp-servers or POST /mcp-servers/list

Cursor-paginated list of MCP servers owned by the authenticated workspace. Same pagination shape as Skills. Returns MCPServerDTO objects (see below).

Get workspace server

GET /mcp-servers/{id}

Returns MCPServerDTO for one registration.

MCPServerDTO fields

FieldDescription
idServer ID
user_id, team_id, visibilityOwnership and sharing
slugURL-safe identifier
nameStable identifier (often matches slug)
titleDisplay name; falls back to name when empty
description, icon_urlListing metadata
server_urlMCP endpoint URL
auth_typeoauth, api_key, or none
oauth_client_idBYOK OAuth client ID when set
default_scopesOAuth scopes to request on connect
headersStatic HTTP headers your workspace admins set on this registration. The platform sends them on every MCP request for this server_url (for example Azure DevOps X-MCP-Toolsets, X-MCP-Readonly). Non-secret only — never put tokens here.
setupOptional MCPServerSetup hints from the public directory for this server's host (see below). Omitted when the directory has no setup row for the host.
documentation_urlVendor docs link
connection_statusconnected when you or your workspace have a connected MCP credential for this server_url. Omitted otherwise. The match compares server_url with the credential's account_identifier.
connection_scopeWhen connection_status is connected, who owns that login: user, team, org, or platform. Omitted when not connected.
credentialsThe credential the server declares it needs, same shape as an app's credentials: ([{slug, scopes, capabilities, …}], written as a map keyed by slug or a list). Each slug must name an auth provider your workspace can connect: a catalog slug, your team's own scheme, or an MCP server's provider such as <server-slug>-mcp. When set, connection_status means the caller has a connected login for that slug, and tool calls send that login's token (or API key, per the slug's auth method) instead of a server-specific MCP login. Empty for servers that still sign in the MCP-specific way.
credential_slugThe first declared slug, for linking to the vault entry (/credentials/{slug}). Empty when the server declares nothing.

List and get responses set connection_status and connection_scope from your MCP credentials, so a connect/disconnect UI does not need to merge GET /credentials/configs.

setup (MCPServerSetup)

Directory maintainers store setup metadata per MCP host (not per workspace registration). When you list or get a workspace server whose server_url shares a host with a directory entry, the API attaches that host's setup object so connect UIs can show vendor-specific guidance without hard-coding servers in the app.

FieldDescription
resource_app_idApplication ID at the server's authorization server. Organizations need this before they can approve access (for Microsoft Entra: the application ID a tenant uses when creating a service principal).
recommended_headersLeast-privilege static headers the vendor documents (same validation rules as workspace headers). The web app offers these as presets in the headers editor; GET /credentials/mcp/app also returns recommended_headers for MCP connect flows.

Python types: MCPServerSetup on MCPServerDTO in inferencesh.types (inferencesh ≥ v0.14.3).

Create workspace server

POST /mcp-servers

Register a custom MCP server URL. The API enriches missing fields from the remote server card and OAuth discovery metadata, then declares the server's sign-in the way connect does: it creates or reuses the auth provider for the server's URL and sets credentials from what discovery found. A body that already sends credentials keeps them. A server that cannot be reached saves with no provider; set credentials later with update or refresh.

Body (common fields):

FieldRequiredDescription
server_urlYesMCP endpoint or bare origin (resolved via discovery when needed)
nameNoStable name (defaults from server card or hostname)
titleNoDisplay title
slugNoURL-safe identifier (auto-generated from name when omitted)
descriptionNoShort summary (max 200 characters; a description discovered from the server is clipped to the limit when the server is registered)
auth_typeNooauth (default), api_key, or none
oauth_client_idNoOAuth client ID when you bring your own client
default_scopesNoOAuth scopes to request
headersNoStatic, non-secret HTTP headers on every MCP request (for example X-MCP-Toolsets, X-MCP-Readonly). At most 16 headers; values up to 1024 characters. Cannot override auth or MCP transport headers (Authorization, Mcp-*, and similar).
credentialsNoThe credential the server needs, as a map keyed by slug ({"aikido-mcp": {"scopes": ["issues:read"]}}) or a list of entries. Usually omitted on create, since discovery declares it. Validated like an app's credentials:, and each slug must name a provider your workspace can connect (see credentials on MCPServerDTO above). On update, a present value replaces the declaration and [] clears it.
documentation_urlNoLink to vendor docs
visibilityNoteam (default) or public — team keeps the registration in your workspace; public lists it in the MCP directory

Response: MCPServerCreateResponse:

FieldDescription
id, slug, name, …Created MCPServerDTO
discoveryOptional hints for the connect UI (ready_to_connect, needs_credentials, cross_domain, cross_domain_issuer)

Errors:

HTTPCodeCause
409already_existsDuplicate slug within the workspace
400validation_errorInvalid field values (credentials, headers, slug, …); detail names the field
400invalid_requestA credentials slug names no provider; detail names it and adds leave the credential slug empty to set up sign-in from the server
400create_failedAny other discovery or input failure (for example a missing server_url), with the error text in detail
402 / 403entitlement or refusalConnector limit reached on your plan, a missing scope, or no manage_vault
bash
1curl -X POST https://api.inference.sh/mcp-servers \2  -H "Authorization: Bearer inf_your_key" \3  -H "Content-Type: application/json" \4  -d '{5    "server_url": "https://mcp.example.com",6    "name": "Example MCP",7    "visibility": "team"8  }'

Register vs connect: Creating a server only registers its URL and who can see it. It does not share your OAuth login. Each person connects their own account afterward — see Browsing & connecting — custom MCP servers.

After create, connect with POST /credentials (provider: "mcp", metadata.server_url) or belt mcp connect — see Browsing & connecting.

Update workspace server

PUT /mcp-servers/{id}

Send only fields to change. Same field names as create.

For headers:

Request bodyEffect
Field omittedStored headers stay as they are
"headers": { … }Replaces the whole set (validated)
"headers": {}Clears all static headers

Errors: the same codes as create (validation_error, invalid_request, refusals, 404 for an unknown server). Other failures answer 400 update_failed with the error text in detail. Nothing is saved when validation fails.

Update workspace server visibility

POST /mcp-servers/{id}/visibility

Changes who can see a workspace registration (not who can use your connection): your workspace only, or the public MCP directory. Requires credentials:write and the workspace manage_vault capability (same as create and update). Public servers get a store listing without sharing anyone's OAuth login — only the server registration is shared.

json
1{2  "visibility": "public"3}
ValueDescription
teamOnly your workspace (default)
publicListed in the MCP directory; others can connect with their own credentials

Response: Updated MCPServerDTO.

bash
1curl -X POST "https://api.inference.sh/mcp-servers/mcp_abc123/visibility" \2  -H "Authorization: Bearer inf_your_key" \3  -H "Content-Type: application/json" \4  -d '{"visibility":"public"}'

You can still set visibility on create; this endpoint updates an existing registration.

Refresh workspace server metadata

POST /mcp-servers/{id}/refresh

Re-runs MCP server card and OAuth discovery against the stored server_url, then persists updated fields. Requires credentials:write.

Use this when a registration has stale metadata — for example a hostname used as the display name, or an incorrect auth_type from before automatic discovery was wired in. The same enrichment logic runs on create; refresh applies it again without recreating the server.

CLI equivalent: belt mcp refresh <slug> (resolves the public directory slug to the server ID).

Response: same shape as Create workspace server: updated MCPServerDTO plus optional discovery hints.

Errors: the same codes as create (validation_error, invalid_request, refusals, 404 for an unknown server). Other discovery or save failures answer 400 refresh_failed with the error text in detail.

bash
1curl -X POST "https://api.inference.sh/mcp-servers/mcp_abc123/refresh" \2  -H "Authorization: Bearer inf_your_key"

Delete workspace server

DELETE /mcp-servers/{id}

Returns { "deleted": true }.


List and call tools

Requires authentication and an active credential for the server (credentials:read to list, credentials:write to call).

You must connect first — GET /mcps/{slug}/tools returns 400 mcp_error with not connected to {name} when no credential exists for that server's URL.

List tools

GET /mcps/{slug}/tools

Returns an array of MCP tool definitions:

FieldDescription
nameTool identifier
titleDisplay title (optional)
descriptionWhat the tool does
inputSchemaJSON Schema for arguments. Per MCP (SEP-1613), schemas without "$schema" use the 2020-12 dialect; an explicit "$schema" (including draft-07) is respected.
outputSchemaJSON Schema for results (optional)
annotationsOptional MCP hints (title, readOnlyHint, destructiveHint, idempotentHint, openWorldHint). Values come from the connected MCP server as returned by tools/list.
bash
1curl https://api.inference.sh/mcps/linear/tools \2  -H "Authorization: Bearer inf_your_key"

Call tool

POST /mcps/{slug}/tools/{tool}

Body — JSON object of tool arguments (empty object when the tool takes no input).

Success — MCP tool result (content blocks and structured output). When the remote tool declares an MCP Apps page (SEP-1865), the response may also include:

FieldDescription
ui.resource_uriResource URI from the tool's _meta.ui
ui.htmlFetched HTML document (text/html;profile=mcp-app)
ui.cspContent-Security-Policy for the sandboxed iframe
ui.prefers_borderWhen true, hosts may draw a border around the page
ui.domainOptional postMessage domain hint
ui.page_hashWhen the HTML is stored once in mcp_ui_pages, the inline ui.html is omitted and this SHA-256 key names the page (see Stored MCP Apps pages)

Recorded runs (GET /mcp-tool-calls/{id}) keep the same ui payload (or ui.page_hash plus a fetch) so permalinks can reopen the page with the stored input and output. Nested tool calls from the page go back through the MCP proxy on the same connection — by directory slug when one exists, or by credential_id when it does not (see below).

Tool-level error — HTTP 200 with { "error": true, "content": "..." } when the remote server reports isError.

Connection errors — 400 not_connected or 502 mcp_error when the credential is missing or the remote call fails.

bash
1curl -X POST https://api.inference.sh/mcps/linear/tools/list_issues \2  -H "Authorization: Bearer inf_your_key" \3  -H "Content-Type: application/json" \4  -d '{"teamId": "TEAM-123", "limit": 10}'

Call tool by connection (credential_id)

POST /mcp-credentials/{credential_id}/tools/{tool}

Same request body, scopes (credentials:write), audit row, usage policy, and response shape as Call tool. Use this when the MCP server is not in the public directory (no resolvable /mcps/{slug}) but you have a connected MCP credential — for example an MCP Apps page in chat that must proxy follow-up tools/call on the same connection.

The caller must be allowed to use that connection: their own, their workspace's, their org's, or a platform-wide MCP credential. A teammate's personal connection is never used directly; the API substitutes the caller's own connection to the same server_url when possible, or responds 403 when they must connect their own account.

bash
1curl -X POST "https://api.inference.sh/mcp-credentials/cred_abc123/tools/list_issues" \2  -H "Authorization: Bearer inf_your_key" \3  -H "Content-Type: application/json" \4  -d '{"limit": 10}'

Read MCP Apps resource by connection

POST /mcp-credentials/{credential_id}/resources/read

Proxies MCP resources/read to the server behind the credential. Only ui:// URIs are accepted (MCP Apps pages and their parts). Requires credentials:read. The body matches MCPResourceReadRequest:

json
1{ "uri": "ui://vendor.example/widget.html" }

Responses follow MCP resources/read (contents array). Total payload size is capped at 2 MiB, the same limit as tool-result UI fetch. Blocked servers are rejected under the same usage policy as tool calls (even though no tool-call row is written). Unknown credentials, non-MCP credentials, and unreachable connections respond 404 with a generic not-found message so credential IDs cannot be probed.


Stored MCP Apps pages

Large MCP Apps HTML is stored once under a content hash (SHA-256 over HTML plus framing metadata). Tool-call records and chat widgets reference the page with ui.page_hash instead of repeating ui.html.

Get stored page

GET /mcp-ui-pages/{hash}

Returns MCPUIPageDTO (html, csp, prefers_border, domain, created_at). Requires credentials:read. You may read a page only when you can see at least one MCP tool-call record that rendered with that hash; otherwise the API responds 404 (same response for unknown hashes, so hashes cannot be enumerated). Responses are cacheable (Cache-Control: private, max-age=31536000, immutable) because a hash always names the same document.

Chat embeds that already carry inline HTML do not need this route; it is for permalinks, audit views, and clients that received only page_hash on the tool call.


JavaScript SDK

typescript
1import { inference } from '@inferencesh/sdk';23const client = inference({ apiKey: process.env.INFERENCE_API_KEY });45// Public directory6const directory = await client.mcpServers.list({ limit: 20 });7const linear = await client.mcpServers.get('linear');89// Team-owned registrations10const owned = await client.mcpServers.listOwned();11const created = await client.mcpServers.create({12  server_url: 'https://mcp.example.com',13  name: 'Example MCP',14});1516// Tools (requires connect first)17const tools = await client.mcpServers.listTools('linear');18const result = await client.mcpServers.callTool('linear', 'list_issues', { limit: 10 });

→ JavaScript SDK


MCP tool call history

GET /mcp-tool-calls (cursor-paginated) returns MCPToolCallDTO records for connector tool invocations. Requires credentials:read.

When a remote tool declares an MCP Apps page in _meta.ui.resourceUri, the platform fetches that ui:// resource at call time (up to 2 MiB), stores the document in mcp_ui_pages, and attaches a reference on the record:

FieldDescription
ui.resource_uriThe ui:// URI from the tool definition or result
ui.htmlFetched HTML when the record was written before hash storage, or on live responses before persistence
ui.page_hashContent hash when the HTML is stored once; fetch with GET /mcp-ui-pages/{hash}
ui.csp, ui.domain, ui.prefers_borderFraming hints from the resource _meta.ui block

Chat and audit clients use this to render connector widgets the same way an MCP host would after tools/call. Follow-up tool calls and resources/read from the page use POST /mcp-credentials/{credential_id}/tools/{tool} and POST /mcp-credentials/{credential_id}/resources/read when no directory slug applies. See inference shell as an MCP server — MCP Apps.


NeedEndpoint / guide
OAuth connect and disconnectPOST /credentials with provider: "mcp" — Browsing & connecting
Tool call audit historyGET /mcp-tool-calls (same credentials:read scope)
Add tools to agentsConnector tools
CLI workflowsBrowsing & connecting

we use cookies

we use cookies to ensure you get the best experience on our website. for more information on how we use cookies, please see our cookie policy.

by clicking "accept", you agree to our use of cookies.
learn more.