Skip to main content
Every Metabind project is a standard MCP server, so any MCP client can connect to it: your own application, an agent framework, an internal tool, or a host without a dedicated guide. This page covers what a client needs to know: which URL to use, how to authenticate, which protocol versions the server speaks, and what its tools and UI resources look like. To use your tools in ChatGPT or Claude, follow Connect to ChatGPT or Connect to Claude instead. To put an assistant inside your own iOS, Android, or web app, see Embed an assistant in your app.

Server URLs

Copy the URL from the Server tab in Metabind Studio, with the endpoint dropdown set to Production or Draft. A project gets a plugin address only when you assign one. It’s permanent and doesn’t change when you rename the project. For how publishing moves changes from draft to production, see Draft and production.

Authentication

How a client authenticates depends on the project’s Access setting and the URL: Change a project’s access in Project Settings → General → Access. See Public and private projects. Send the token as Authorization: Bearer <token> on every request. The server checks it per request, so a session opened with a token doesn’t remember it. The MCP endpoint doesn’t read an x-api-key header. A request that carries only x-api-key is treated as anonymous. A signed-in session also gets Metabind’s platform tools, such as search_assets, alongside your project’s tools. Anonymous sessions on a public project get only your published tools.

API keys

Use an API key when your client runs on a server you control, or for scripts and tests. Create one in Metabind Studio:
  1. Click the gear icon at the top right (Project Settings), and choose API Keys.
  2. Click +, enter a Name, and click Create.
  3. Copy the key. Studio shows it only once.
A key created in Studio has no scopes, which gives it full access within its project, so it works on both the production and draft URLs. Keep it on a server you control. Keys created through the API keys API can carry scopes instead. For MCP, a scoped key needs execute:mcp and read:types, plus execute:mcp-draft for the draft URL.

OAuth

Use OAuth when each person signs in with their own Metabind account. Metabind supports the MCP authorization flow:
  1. An unauthenticated request to a URL that requires sign-in returns 401 with a WWW-Authenticate header. Its resource_metadata parameter points to the URL’s protected-resource metadata.
  2. That metadata names https://api.metabind.ai as the authorization server. Its metadata is at https://api.metabind.ai/.well-known/oauth-authorization-server.
  3. Register your client with dynamic client registration, then run the authorization code flow with PKCE (S256). The person signs in to Metabind and clicks Authorize.
Most MCP SDKs run this flow for you. The person must be a member of the organization, with a role that can run MCP tools. See Team management.

Protocol versions

The server speaks two generations of the MCP protocol: An MCP SDK picks the version and sets these headers for you. If you write the HTTP layer yourself, send Accept: application/json, text/event-stream on every request.

Connect with the TypeScript SDK

This client uses the official MCP TypeScript SDK to list a project’s tools and call one. Set METABIND_MCP_URL to the URL from Studio. Set METABIND_API_KEY too, unless you’re connecting to a public project’s production URL anonymously.
The tool name and arguments come from the Oak & Ivory sample. Replace them with one of your own tools.

Tools

Each published Type is one tool:
  • Name: the Type’s slug, such as product_search.
  • Title: the title set in Studio, or the Type’s name.
  • Input: inputSchema is the Type’s JSON schema.
  • Data Tools also declare an outputSchema. A call returns the result as structuredContent, with the same JSON as text in content.
  • Interactive Tools declare a UI resource in _meta.ui.resourceUri. See Rendering Interactive Tools.

Annotations

Every tool carries readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. Use them to decide when to ask the person before a call, for example before any tool with destructiveHint: true. A tool whose author didn’t set annotations reports readOnlyHint: true, destructiveHint: false, idempotentHint: true, and openWorldHint: false. Those are defaults, not a promise about what the tool does.

Long-running Data Tools

A Data Tool declares execution.taskSupport, which defaults to forbidden. The server doesn’t implement MCP tasks yet, so every call answers synchronously, within the 60-second execution limit, whatever the tool declares. See Task support.

Rendering Interactive Tools

Interactive Tools follow the MCP Apps extension. To show their UI, your client must be an MCP Apps host:
  1. Read the tool’s _meta.ui.resourceUri, such as ui://metabind/render/<id>?v=<hash>, and use it exactly as given.
  2. Fetch it with resources/read. The result is an HTML document with the MIME type text/html;profile=mcp-app. Its _meta.ui.csp lists the domains the view loads code and images from.
  3. Render the HTML in a sandboxed iframe, and pass it the tool call’s input and result over the MCP Apps bridge.
The view draws the UI from the tool’s input. The call result carries a short text, such as Rendered product_detail (…), and the tool’s input with its defaults as structuredContent, but no UI. A client that can’t render the view can show only that data. On a plugin address, each UI resource also declares that address as its _meta.ui.domain, in the format ChatGPT expects. The path URLs share one host, so their resources declare no domain. Hosts that check _meta.ui.domain against their own format may refuse to render views from a plugin address. Claude does, so connect Claude through a path URL. UI resources and tools also carry openai/* metadata for ChatGPT. Other clients can ignore it. Nothing in it is needed to list or call a tool. To render Interactive Tools as native SwiftUI or Jetpack Compose instead of HTML, see Native MCP Apps on iOS and Android.

Rate limits

Anonymous traffic to a public project is rate-limited. Every anonymous response carries RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset headers. When a limit runs out, the server answers 429 with a Retry-After header and a JSON-RPC error:
scope names the limit that ran out: client for one session, address for one network address, or project for all anonymous callers together. Wait retryAfter seconds before retrying. Opening a session, listing tools, and loading views don’t use up a session’s tool calls. See Rate limiting.

Debugging

For deeper debugging, check Recent Executions under Analytics in Metabind Studio, which records every call from any host. Execution history is available on paid plans.

Troubleshooting

Connect to ChatGPT

Add a project to ChatGPT as a custom MCP server.

Connect to Claude

Add a project to Claude as a custom connector.

Embed an assistant in your app

Run your tools inside your own iOS, Android, or web app.

Draft and production

Why two endpoints exist and when to use each.