Skip to content
Yohn Gutierrez edited this page Jun 17, 2026 · 1 revision

MCP (Model Context Protocol)

Jarvis is an MCP host: add MCP servers and their tools become available to whatever brain is answering — provider-agnostic by design. HTTP backends receive them as native tool-calls; the Claude CLI is handed the same servers through its own --mcp-config. Implemented in jarvis/mcp.py (stdlib only).

Two transports

  • Local (stdio) — Jarvis spawns a subprocess and speaks newline-delimited JSON-RPC.
    mcp:
      servers:
        - name: filesystem
          command: npx
          args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/expose"]
          enabled: true
  • Remote (HTTP) — streamable HTTP with OAuth 2.1: RFC 9728/8414 discovery, PKCE, dynamic client registration (or an explicit client_id), and automatic token refresh.
    mcp:
      servers:
        - name: my-remote
          url: https://example.com/mcp
          scope: "openid email offline_access"   # optional; auto-discovered if omitted
          enabled: true

Connecting an HTTP server

In Settings → MCP, add the server and click Connect. Jarvis discovers the OAuth endpoints, registers a client (or uses your client_id), and opens the provider's login. The provider redirects your browser back to the dashboard's loopback callback, Jarvis exchanges the code, and stores the tokens. The OAuth redirect uses the host you opened the dashboard on and normalizes to localhost (many providers only allow http redirects to localhost, not a bare IP) — so open the dashboard at http://localhost:8787 (or via an SSH tunnel) when connecting.

Once connected, the token lives server-side and auto-refreshes, so the tools work from any browser and in every chat/loop session — you only Connect once.

Secrets

config.yaml holds only references, never values:

mcp:
  servers:
    - name: my-stdio
      command: npx
      args: ["-y", "some-mcp-server"]
      env: { API_KEY: "${env:MY_API_KEY}" }   # resolved from .env at spawn time

OAuth tokens are stored under state/mcp-auth/<name>.json (chmod 600) and are never committed.

How tools are exposed

  • Tool names are namespaced mcp__<server>__<tool> so multiple servers can't collide.
  • HTTP brains get them merged into the native tool list (all_tool_specs).
  • The Claude CLI is given a generated --mcp-config (with a live Bearer for HTTP servers and the resolved env for stdio servers) plus --allowedTools mcp__<server> so it can call them non-interactively. The temp config is written chmod 600 and deleted after the turn.
  • Every model also sees a compact catalog of the available MCP tools in its prompt, so it knows they exist.

Degrade-safe: a server that fails to start or authorize is skipped, never crashing a chat turn. See Configuration and Model Routing.

Clone this wiki locally