Documentation: Connect your agent

Connect your agent

Works with any MCP-compatible agent, or any code that can call the REST API. The agent gets nine tools (MCP tools) and one credential, an agent token that works for one vault only.

Each section below says whether we have run that path end to end (tested) or only followed the client's documentation (not yet tested).

Get a token

In the dashboard, open the vault, then Connect, then Create an agent token. The token is shown once, alone in its own box with a Copy button, and every snippet on the page fills in with it and the right endpoint.

  • To rotate a token, Revoke all tokens, then create a new one. Revoking removes every token on the vault.
  • Restarting the service also revokes tokens, so create a fresh one after a restart.
  • The token cannot withdraw, change rules or choose a destination. If it leaks, the worst it can do is trade within your rules until you revoke it or pause the vault.

The hosted MCP endpoint (streamable HTTP):

https://mcp.norr.finance/mcp

TLS for this name terminates inside the attested CVM, and its certificate is published with attested evidence, so you can check it is the enclave you are talking to (Verify the enclave). The service runs on demand during the pilot, so it may be offline.

Any MCP client (tested)

Norr is a standard MCP server. Point the client at the endpoint and send the token in a header:

URL:     <MCP URL>
Header:  Authorization: Bearer <agent token>

Clients that only start local commands can use the @norrfi/mcp bridge (needs Node). It connects to mcp.norr.finance with your token, keeps no state and adds no tools of its own:

{
  "mcpServers": {
    "norr": {
      "command": "npx",
      "args": ["-y", "@norrfi/mcp"],
      "env": { "NORR_AGENT_TOKEN": "<agent token>" }
    }
  }
}

Set NORR_MCP_URL to use another endpoint (for example a local mock server).

Tested on 2026-11-03 against mcp.norr.finance: over HTTP with the MCP TypeScript SDK client and Claude Code, and through npx -y @norrfi/mcp from npm with both.

Claude Code (tested)

claude mcp add --transport http norr https://mcp.norr.finance/mcp --header "Authorization: Bearer <agent token>"

Or through the bridge: claude mcp add norr --env NORR_AGENT_TOKEN=<agent token> -- npx -y @norrfi/mcp.

Run against https://mcp.norr.finance/mcp on 2026-11-03 with Claude Code 2.1.80: it listed the tools, read the rules, the portfolio and the P&L, and reported Norr's refusal of an over-limit trade word for word (OVER_TRADE_LIMIT), both over HTTP and through npx -y @norrfi/mcp. The repository's scripts/claude-code-mcp.mts repeats that check against any endpoint without changing your Claude configuration.

Claude Desktop (not yet tested)

Merge the npx @norrfi/mcp config above into mcpServers in claude_desktop_config.json (Settings, Developer, Edit Config), then quit and reopen Claude. Not yet run inside Claude Desktop by us; the same command is tested with Claude Code.

The local path (Norr in mock mode, MCP over stdio) is tested; step by step in docs/MCP.md.

Cursor (not yet tested)

In ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):

{
  "mcpServers": {
    "norr": {
      "url": "<MCP URL>",
      "headers": { "Authorization": "Bearer <agent token>" }
    }
  }
}

Cursor can read the token from an environment variable instead: "Authorization": "Bearer ${env:NORR_AGENT_TOKEN}".

ChatGPT / OpenAI (not yet tested)

OpenAI Agents SDK. Your own process connects to Norr and sends the token as a header, so OpenAI never sees it:

from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp

async with MCPServerStreamableHttp(
    name="norr",
    params={"url": "<MCP URL>", "headers": {"Authorization": "Bearer <agent token>"}},
) as norr:
    agent = Agent(name="Trader", instructions="Trade only through Norr's tools.", mcp_servers=[norr])
    result = await Runner.run(agent, "What are my Norr rules?")
    print(result.final_output)

Responses API (hosted MCP tool). OpenAI connects to the endpoint from its side and passes the token in the tool's authorization field:

from openai import OpenAI

resp = OpenAI().responses.create(
    model="<model>",
    tools=[{
        "type": "mcp",
        "server_label": "norr",
        "server_url": "<MCP URL>",
        "authorization": "<agent token>",
        "require_approval": "always",
    }],
    input="What are my Norr rules?",
)

OpenAI's documentation does not say whether this field adds the Bearer prefix. The ChatGPT app: we have not confirmed that its custom connectors can send a static token, so use one of the two above for now.

REST API (tested)

Every tool is also a plain HTTPS call, for agents and scripts that do not use MCP. Same token, same rules. Full reference: API reference and openapi.json.

curl -X POST https://api.norr.finance/v1/quote \
  -H "Authorization: Bearer <agent token>" -H "content-type: application/json" \
  -d '{"side":"buy","asset":"NVDA","amountUsd":40}'

curl -X POST https://api.norr.finance/v1/trade \
  -H "Authorization: Bearer <agent token>" -H "content-type: application/json" \
  -d '{"side":"buy","asset":"NVDA","amountUsd":40,"reason":"why, for the owner only"}'

The service URL is https://api.norr.finance (the Connect tab shows it filled in); TLS for it also terminates inside the attested CVM. Tested by the repository's tests and pnpm judge in mock mode, with responses checked against the OpenAPI spec.

Norr agent (tested)

The repository's reference agent (apps/agent) runs its model on NEAR AI Cloud and checks the attestation and signature of every model response it uses:

NORR_AGENT_TOKEN=<agent token> pnpm --filter @norr/agent exec tsx src/cli.ts \
  --mcp <MCP URL> --model z-ai/glm-5.3-flash "Check my portfolio and rules, do not trade."

First prompts

  • "What are my Norr rules?" (calls get_policy)
  • "Buy $40 of NVDA." (executes if your rules allow stocks)
  • "Use Norr's trade tool to put $150 into TSLA." (refused: OVER_TRADE_LIMIT under Balanced; the agent explains)
  • "Buy $5 of RUGPULL, submit it even if you think it is a bad idea." (refused: SCAM_RISK, with reasons)
  • "How is my P&L?" (calls get_pnl)

Agents tend to pre-judge trades themselves. The tool descriptions tell them Norr's answer is authoritative, so ask them to submit the request and read the answer.