Skip to main content

Connect an agent

Any MCP client that speaks MCP over HTTP can connect to your workspace's hosted endpoint. This page covers the endpoint, access tokens, and client configuration. For the packaged Claude Code integration, see the Claude Code plugin.

Endpoint and authenticationDirect link to Endpoint and authentication

Your workspace's MCP module in the app (the Connect tab) shows your endpoint URL. The server accepts MCP requests at POST /mcp and exposes an unauthenticated health check at GET /health:

curl -sS https://<workspace-mcp-host>/health

Every MCP request authenticates with a workspace access token in the Authorization header:

Authorization: Bearer mtt_<your-access-token>

There is no OAuth flow — the bearer token is the whole handshake. The workspace is resolved entirely from the token; clients never pass a workspace name or ID.

Issue and revoke tokensDirect link to Issue and revoke tokens

Tokens are issued in the Tokens tab of your workspace's MCP module. Issuing requires the workspace admin or owner role. A token:

  • looks like mtt_ followed by 64 hex characters;
  • is shown exactly once at issue — copy it immediately, it cannot be retrieved later;
  • can carry an optional expiry;
  • can carry an optional identity (agent kind, agent name, and a bound role);
  • can be revoked at any time from the Tokens tab.

Treat tokens like passwords: never commit them, never paste them into shared logs, and revoke any token that may have been exposed.

Token scopesDirect link to Token scopes

Every token carries a scope set, and there are exactly two valid sets:

Scope setWhat it can call
{read}The eight read and advisory tools, including check_request. This is the default.
{read, request}All nine, adding request_access — the one tool that writes.

read is a floor: it is always present and cannot be removed. request is never granted by default and never inferred — it is granted only by an explicit choice in the app, using the request-lane checkbox on the issue or rotate form.

A tool whose required scope the token lacks is refused with insufficient_scope, before the input is even parsed, so a caller outside the write lane learns nothing about parameter validity. The message is fixed and identical for every tool and token: "This token does not have the scope this tool requires. A workspace admin can issue or rotate a token that grants it."

Scopes are immutable, so an upgrade is a rotation. You cannot add request to an existing token. Rotate it with the request-lane option enabled: rotation mints a new secret, copies the name, expiry, and identity forward, and revokes the old token in the same transaction. That rotation is the workspace's deliberate opt-in to the write lane, and the audit event records both the old and the new scope set. Leaving the option untouched during a rotation preserves the token's current scopes; turning it off downgrades to {read}.

One consequence to plan for: rotation mints a new subject identity. Requests and granted exceptions are bound to a specific token id, so a rotated token cannot see its predecessor's requests or consume its exceptions. Resolve or re-file after a rotation.

Bound rolesDirect link to Bound roles

If you set a bound role on a token, that role is the actor identity every decision is evaluated against. Matching is trimmed, case-sensitive byte equality — Analyst and analyst are different roles, and there is no role hierarchy or registry. The role comes only from the token row; no tool accepts a role as input, and the strict schemas reject one.

A token with no bound role fails closed: rules that grant access to a named role resolve to require_review rather than allow. Restrictive outcomes are unaffected, and an answer with no role-sensitive rules is unchanged. If an agent sees unexpected reviews on role-gated assets, check whether its token has a role bound.

Every authorize_use and validate_query_context answer reports the role it used as evaluated_actor_role, so this is always verifiable from the answer itself.

Claude CodeDirect link to Claude Code

Register the endpoint with claude mcp add-json — this matches the snippet your Connect tab renders, with your endpoint and token filled in:

claude mcp add-json --scope user metatate '{"type":"http","url":"<mcp-server-url>/mcp","headers":{"Authorization":"Bearer <your-access-token>"}}'

Pasting a real token into a terminal command records it in shell history. The Claude Code plugin ships a helper that reads the token from an environment variable or a hidden prompt instead.

Any other MCP clientDirect link to Any other MCP client

Configure an HTTP MCP server with the same three values — no Metatate-specific client code is needed:

{
"type": "http",
"url": "<mcp-server-url>/mcp",
"headers": {
"Authorization": "Bearer mtt_<your-access-token>"
}
}

Once connected, the client's standard tool listing shows the nine tools described in the MCP server overview, with honest per-tool annotations: eight advertise readOnlyHint: true, and request_access advertises readOnlyHint: false. Compliant clients use that annotation to prompt before invoking the write tool. You can also exercise tools without wiring up a client at all: the Tools tab in the app previews calls using the same typed answer model as the live endpoint.

Security notesDirect link to Security notes

  • Tokens are hashed at rest; Metatate stores no recoverable copy.
  • Missing, malformed, expired, revoked, and unknown tokens all produce the same unauthorized response — the server never reveals which.
  • A token reads only its own workspace. Asset references from another workspace are indistinguishable from not found.
  • Rate limits and plan quotas are enforced before tool work runs, with typed rate_limited and quota_exceeded errors.
  • Scopes come only from the verified token row — never from a header, never from tool input.
  • Agents cannot modify governance state. The one write lane (request_access) creates a review request for a human and nothing else.
  • Errors use a closed, redacted code set and never include raw SQL, token material, policy prose, or credentials.

Answers describe published governance decisions and are advisory — see Typed answer states for how missing or conflicted state is reported.