MCP Server

How the MCP server works

The Harny MCP server lets a coding assistant call Harny over one HTTP address, with the same limits as the REST API.

Copy page
View as Markdown

Transport and the two doors

The MCP server uses Streamable HTTP at https://api.harny.ai/v1/mcp/mcp.

The address has two doors, decided by the Authorization header:

  • No Authorization header: the server lists only provision_app.
  • Authorization: Bearer <key>: the server lists the tools that key may call.

A person's key starts with fsk_. The app key starts with fsa_. The server accepts bearer keys and sign-in tokens.

Sign-in

Sign-in is built. The app's owner signs in on the Harny console, picks or creates the app and approves a coding assistant. The assistant then holds a token that lasts an hour and renews, instead of a copied key. Its address is not published yet, so connect with a key until it is.

A sign-in token reaches what the app key reaches for that one app, except provision_app: describe, get_snippet, diagnose, provision_user, get_claim_link and get_setup_bundle. provision_user returns the person's id and never a key. A token never makes an owner-only change, such as a setting, a key or billing. It works only at the address it was issued for, and the owner can disconnect the assistant at any time, which ends the token.

How a key scopes calls

Every call is scoped to the key's user. The app key reaches provision_user, get_claim_link and get_setup_bundle. A person's key reaches that person's memory and connected accounts. Any key reaches describe, get_snippet and diagnose.

Calls follow the same limits and refusals as the REST routes they wrap. A call over the per-minute limit returns 429 with a Retry-After header.

The tools wrap REST routes

ingest_text wraps POST /v1/vault/ingest/text. assemble_context wraps POST /v1/context/assemble. provision_app makes a new app and its key, as POST /v1/auth/provision does. provision_user adds a person or returns the one that exists, as POST /v1/users does.

ingest_text is not for streaming conversation transcripts. It is subject to the app's ingest quotas.

For the Memory API routes under /v1/memory, see the Memory API docs.

Tool groups

GroupToolsNeeds
Organizationdescribe, get_snippet, list_toolsdescribe and get_snippet take any key. list_tools takes a person's key.
Apps and keysprovision_app, get_claim_link, get_setup_bundleprovision_app needs no key. The others need the app key.
Memoryingest_text, assemble_context, action_historyA person's key.
Members and accessprovision_user, configure_oauthprovision_user needs the app key. configure_oauth needs a person's key.
DebuggingdiagnoseAny key.

describe is the first call an assistant should make. It returns what this key reaches, with the tool schemas.

provision_app returns the app key once. Put that key in your secret store and nowhere else.

Connect a client

In Claude Code, run:

claude mcp add --transport http harny https://api.harny.ai/v1/mcp/mcp --header "Authorization: Bearer $HARNY_USER_KEY"

In Cursor, add this to mcp.json:

{"mcpServers": {"harny": {"url": "https://api.harny.ai/v1/mcp/mcp", "headers": {"Authorization": "Bearer ${env:HARNY_USER_KEY}"}}}}

Set up with a coding agent

If your coding agent can run commands, follow https://harny.ai/auth.md instead of provision_app. Its command never shows the key.

Next