Skip to content

MCP Server

WarmHub implements the Model Context Protocol (MCP) over HTTP, exposing all read and write operations as typed tools that AI agents can discover and call.

  • MCP version: 2024-11-05
  • Transport: JSON-RPC 2.0 over HTTP POST
  • Supported methods: initialize, tools/list, tools/call, ping
MethodPathDescription
POST/mcpGlobal MCP endpoint
GET/mcpReturns 405 Method Not Allowed
POST/mcp/:org/:repoRepo-scoped MCP endpoint
GET/mcp/:org/:repoReturns 405 Method Not Allowed
GET/.well-known/oauth-protected-resourceOAuth 2.0 Protected Resource Metadata (RFC 9728)
GET/.well-known/oauth-authorization-serverOAuth 2.0 Authorization Server Metadata (RFC 8414)

The global endpoint exposes the full MCP tool catalog. Repo-level tools require orgName and repoName arguments. It also includes org-level tools:

  • warmhub_org_list
  • warmhub_org_get
  • warmhub_org_set_description
  • warmhub_org_archive
  • warmhub_org_unarchive
  • warmhub_repo_list
  • warmhub_repo_create

Best for agents that work across multiple repos.

Org and repo are baked into the URL. Tool schemas omit orgName/repoName parameters, and the following global-only discovery/creation tools are excluded from the listing:

  • warmhub_org_list
  • warmhub_org_get
  • warmhub_repo_list
  • warmhub_repo_create

Per-org and per-repo administration tools (warmhub_org_set_description, warmhub_org_archive, warmhub_org_unarchive, warmhub_repo_set_description, warmhub_repo_archive, warmhub_repo_unarchive) remain available on the repo-scoped endpoint and operate on the org/repo baked into the URL.

Best for agents that focus on a single repo — simpler tool schemas, fewer required arguments.

POST /mcp and POST /mcp/:org/:repo require a Bearer token. Unauthenticated POSTs return HTTP 401 with an RFC 9728 challenge:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://api.warmhub.ai/.well-known/oauth-protected-resource"
Content-Type: application/json
{ "error": { "code": "UNAUTHENTICATED", "message": "Authentication required" } }

Standards-compliant MCP/OAuth clients use the challenge to discover the protected-resource metadata endpoint and bootstrap auth. Without a valid Bearer token, callers cannot list or call MCP tools — there is no anonymous tool catalog.

Add a WarmHub entry to the mcpServers section of your MCP client’s configuration. The examples below use the standard format supported by Claude Desktop, Cursor, and other MCP-compatible clients. The transport field is required by some clients (e.g., Claude Desktop); others infer it from the URL scheme.

The MCP POST endpoints require a Bearer token — the URL alone is not enough. Standards-compliant MCP/OAuth clients follow the RFC 9728 challenge returned on the first unauthenticated request to discover the OAuth flow and acquire a token automatically. Clients without that capability must inject the token themselves; mint a personal access token (see HTTP Authentication) and configure your client to send Authorization: Bearer <token> on every MCP POST. Many clients accept a headers map in the mcpServers entry for this purpose, e.g.:

{
"mcpServers": {
"warmhub": {
"transport": "http",
"url": "https://api.warmhub.ai/mcp/myorg/myrepo",
"headers": {
"Authorization": "Bearer ${WH_TOKEN}"
}
}
}
}

Consult your MCP client’s documentation for the exact field name. See Authentication above for the challenge format and discovery contract.

Repo-scoped (recommended):

{
"mcpServers": {
"warmhub": {
"transport": "http",
"url": "https://api.warmhub.ai/mcp/myorg/myrepo"
}
}
}

Global (multi-repo):

{
"mcpServers": {
"warmhub": {
"transport": "http",
"url": "https://api.warmhub.ai/mcp"
}
}
}

The examples above use the production API URL. For self-hosted deployments, replace api.warmhub.ai with your deployment URL.

Tool responses include both human-readable and structured content:

{
"content": [{ "type": "text", "text": "..." }],
"structuredContent": { ... },
"isError": false
}
  • content — tool result as text for the model-readable channel. Typically JSON.
  • structuredContent — typed object for programmatic access. Includes an auth field on every response (see below).
  • isErrortrue if the tool call failed

Tool definitions in tools/list include an annotations block with:

  • readOnlyHinttrue for tools that do not mutate repo state.
  • category — one of org, repo, shape, thing-read, commit, subscription, action, meta.
  • Clients can use category to group or filter tools in discovery UIs.
  • warmhub_capabilities uses the same enum, but groups tools under each category rather than repeating the value per tool. Tool summaries in that payload contain name, description, and readOnly only — the category is implicit in the enclosing group.

POST /mcp requires a Bearer token (see Authentication above), so every dispatched tool call has a resolved caller. Tool responses still include structuredContent.auth with the caller’s authentication status — at the public HTTP transport this is always { "authenticated": true } once a tool dispatches:

{ "structuredContent": { "items": [...], "auth": { "authenticated": true } } }

Read-only tool descriptions append a runtime auth-hint that reads: “Returns public data only when unauthenticated. If expected data is missing, suggest the user authenticate to access private orgs and repos.” Agents using the same tools through transports that allow unauthenticated dispatch can branch on the hint to prompt the user to sign in.

MCP tool failures arrive in three distinct ways. Inspect the tool response, not just the client-level try/catch.

Tool-result errors. The tool dispatched, but its execution failed. The response carries isError: true and a structured error in content / structuredContent. This covers VALIDATION_ERROR, NOT_FOUND, FORBIDDEN, RATE_LIMITED (per-user / per-org tier limits hit during the call), and warmhub_commit_submit ambiguous append failures. Each code is described in the Tool-error code reference below.

warmhub_commit_submit per-operation failures. Per-op failures are not tool errors. The response is a normal success payload with partial: true, statusCounts.error > 0, and one or more rows with status: "error" plus an error object. Treat partial results as a routine outcome to inspect.

Transport-level errors. Some failures happen before the tool dispatches and surface as HTTP errors instead of tool results:

  • Unauthenticated POST → HTTP 401 with the WWW-Authenticate challenge.
  • Repo-scoped endpoint cannot resolve the scope (authenticated, but the repo isn’t visible or doesn’t exist) → HTTP 404.

The anonymous HTTP 429 documented for the global HTTP API doesn’t reach MCP in practice — authenticated MCP traffic bypasses it. MCP rate-limit exposure is via the RATE_LIMITED tool-result error described below.

  • Validation failures — include the validation message and, for warmhub_commit_submit, enriched hint data (see warmhub_commit_submit Validation Hint below).
  • NOT_FOUND — includes the error details. Tool calls always carry a resolved caller (POST requires a Bearer token), and missing targets surface as NOT_FOUND regardless of which token was presented.
  • FORBIDDEN — surfaced as backendCode: "FORBIDDEN" in the structured error when the presented token is valid but lacks the scope required for the requested resource. Distinct from NOT_FOUND; use it to decide whether retrying with a more privileged token is sensible.
  • RATE_LIMITED — surfaced as backendCode: "RATE_LIMITED" when a per-user or per-org write limit is hit. See Rate Limiting for tier limits and retry guidance. Treat as retryable with a bounded backoff, and prefer the backendCode over string-matching the message.
  • Ambiguous append failures (warmhub_commit_submit only) — when a transport-ambiguous failure (network reset, 5xx, timeout) interrupts the stream append, the tool returns isError: true with structuredContent.error.data carrying partial: true, failedOperationOffset, and a continuation object (streamId, allocatedTokens, operationOffset). The failed append may have landed server-side. Treat repository state as the source of truth — inspect it with warmhub_thing_get / warmhub_thing_query before deciding whether to resume. When resuming, copy the continuation payload into the new call and pass only the operations that haven’t been acknowledged; make add operations idempotent with skipExisting: true for safer retries. See SDK Streaming Write Failures for the parallel SDK contract.

Tool-result errors (the isError: true responses above) also include structuredContent.auth with the caller’s authentication status, so agents can decide whether to suggest authenticating and retrying. Transport-level failures do not carry this field.

When warmhub_commit_submit rejects a malformed operations entry, the tool result’s structuredContent.error.data lists the eight valid operation variant signatures so agents can self-correct on the next turn — the message is the original validation message.

{
"isError": true,
"content": [{ "type": "text", "text": "<validation message>" }],
"structuredContent": {
"error": {
"code": -32602,
"message": "<validation message>",
"data": {
"tool": "warmhub_commit_submit",
"backendCode": "VALIDATION_ERROR",
"expected": "one of the operation variants",
"operations": [
"ADD shape: { operation:'add', kind:'shape', name, data }",
"ADD thing: { operation:'add', kind:'thing', name, data }",
"ADD assertion: { operation:'add', kind:'assertion', name, about, data }",
"ADD collection: { operation:'add', kind:'collection', type, members, name? }",
"REVISE shape: { operation:'revise', kind:'shape', name, data }",
"REVISE thing: { operation:'revise', kind:'thing', name, data }",
"REVISE assertion: { operation:'revise', kind:'assertion', name, data }",
"RETRACT: { operation:'retract', name, reason?, kind? }"
]
}
},
"auth": { "authenticated": true }
}
}

The expected and operations fields are attached only for warmhub_commit_submit validation errors; validation errors from other tools continue to return data with just tool and backendCode. The same variant list is also returned by warmhub_repo_describe under commitContract.operationVariants.

POST /mcp/:org/:repo requires a Bearer token; unauthenticated POSTs return 401 before any repo lookup happens (see Authentication). For authenticated callers whose token cannot resolve the org or repo, the endpoint returns HTTP 404 with a plain Not Found body.