Skip to content

Connect XESO over MCP

Your library over MCP — save, organize, and ask with sources from any MCP-aware client

XESO ships a Model Context Protocol (MCP) server so your saved library is addressable from any MCP-aware client. This document is the canonical setup guide; the in-app card at /settings/developer provides copy-paste configs for the same thing.

What you get

When connected, your MCP client can call these tools (source of truth: lib/services/mcp/tools.ts#MCP_TOOLS):

  • search — hybrid (semantic + lexical) search across your entire corpus
  • search_segment — same, scoped to a specific segment (folder)
  • read_note — fetch the full content of one note by ID
  • find_notes — list recent notes, optionally filtered by segment
  • cite — resolve a passage ID to a human-readable citation (title, source, excerpt) so your MCP client can render footnotes

Everything is grounded. Every result carries citations; vault-protected content is never returned over MCP (tokens can't carry a vault passphrase).

Endpoint

  • Server URL: https://app.xeso.ai/api/mcp (swap for your own host if self-hosted; default is the production app)
  • Protocol: JSON-RPC 2.0 over HTTPS (initialize, ping, tools/list, tools/call). Batching, notifications, and sampling/* are not yet implemented — XESO is a knowledge source, not a completion provider.
  • Rate limit: 60 requests per minute per token. On 429 we return a JSON-RPC error (code -32005) plus the HTTP Retry-After header so clients can back off cleanly.
  • Request correlation: every response includes an X-Request-Id header; quote it when reporting a bug.

Authentication options

Option A — OAuth 2.0 PKCE (recommended)

Your MCP client will handshake against these URLs automatically when you point it at the server URL above:

  • Authorization server metadata: /.well-known/oauth-authorization-server
  • Protected resource metadata: /.well-known/oauth-protected-resource
  • Dynamic client registration: /api/mcp/oauth/register (RFC 7591)
  • Authorization: /api/mcp/oauth/authorize (PKCE S256 required)
  • Token: /api/mcp/oauth/token

The consent screen is served at /settings/mcp-connect — you'll see the client name, the scopes it asked for, and approve or deny. Any client that cannot prove it registered ahead of time is flagged as "unverified" on that screen.

Scopes exposed today: read, write, ingest, chat, export, mcp. For /api/mcp you need at least one of read or mcp; most clients will ask for read only.

Option B — Personal API token

If your client doesn't speak OAuth yet, issue a token at /settings/tokens with the read scope and paste it as a Bearer token in your MCP config (Authorization: Bearer <token>).

Client configs

Cursor (~/.cursor/mcp.json)

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

Restart Cursor. When you first invoke an xeso tool, Cursor will pop a browser window to /settings/mcp-connect; approve the connection and the token is bound to that Cursor install.

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS / %APPDATA%\Claude\claude_desktop_config.json on Windows)

{
  "mcpServers": {
    "xeso": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-http", "https://app.xeso.ai/api/mcp"]
    }
  }
}

Restart Claude Desktop and approve the consent screen on first use.

Token-based (any HTTP MCP client)

{
  "mcpServers": {
    "xeso": {
      "url": "https://app.xeso.ai/api/mcp",
      "headers": {
        "Authorization": "Bearer <paste-your-token>"
      }
    }
  }
}

Troubleshooting

  • 401 unauthorized / JSON-RPC -32001 — no Bearer token, canary hit, or the token was revoked. Re-run the OAuth flow from /settings/developer → "Connect to an MCP client", or issue a new token.
  • 403 / JSON-RPC -32002 — token is valid but lacks read or mcp scope. Re-consent with the correct scope on /settings/mcp-connect.
  • 423 / JSON-RPC -32003 — your account is frozen. Unfreeze from /settings/privacy before retrying.
  • 429 rate_limited / JSON-RPC -32005 — you're over 60 req/min. Clients usually back off automatically. See lib/middleware/rate-limit.ts#RATE_LIMITS.mcp.
  • Empty tool list — check that consent was granted for the read scope. Scopes are visible on the consent screen.
  • Self-hosted: rewrite every URL above to your deployment. The only public-DNS prerequisite is that your MCP client can reach /api/mcp over HTTPS.

Security model

  • Tokens are SHA-256 hashed at rest; the raw value is shown once at creation and never logged.
  • Every tools/call emits an mcp_tool_invoked analytics event tagged with the tool name; sensitive arguments and results are never logged.
  • Vault-protected segments and notes are refused at the tool layer — an MCP token is not sufficient to prove you know the vault passphrase.
  • Scopes are never broadened automatically — expanding a scope requires a fresh consent grant and a new token.
  • OAuth authorization codes are single-use, PKCE S256 is required, and the in-memory code store expires codes after 60 seconds.
  • redirect_uri is matched exactly against the value supplied at dynamic registration; mismatches return invalid_grant.