Capxul Docs
For agents

MCP server

The @capxul/mcp server exposes auth, Account, identity, Organization, relationship, request, destination, and test-faucet tools over Streamable HTTP.

@capxul/mcp is a runnable Model Context Protocol server that exposes Capxul's financial operations as tools any MCP client (Claude, Cursor, other agents) can call. The package ships a CLI, not a library: the published artifact is the capxul-mcp executable. Like the SDK, the tool surface speaks money — tool results carry Money values, labels, and opaque ids, never custody internals.

Alpha surface

The MCP surface ships on the 1.0.0-alpha.x train and is still moving. Tool names, inputs, and gating may change between alpha releases. Pin an exact version, and treat the startup banner — which prints the exact tool set the running server registered — as the authority for your launch.

Install and run

# one-off, via npx
npx @capxul/mcp serve --mode live

# or install globally
npm i -g @capxul/mcp
capxul-mcp serve --mode live
Usage:
  capxul-mcp serve [--mode live|dev] [--port <port>] [--approval-url <url>] [--stdio]

Options:
  --mode live|dev       Launch mode. Defaults to live. There is no env-var mode selector.
  --port <port>         Bind port. Defaults to CAPXUL_MCP_PORT or 8788. (HTTP transport only.)
  --approval-url <url>  Approval app base URL. Defaults to CAPXUL_MCP_APPROVAL_URL or http://localhost:5998.
  --stdio               Serve over stdio (local spawn) instead of HTTP. Defaults to off (HTTP).
  --help                Show this help.

The server speaks MCP over Streamable HTTP at POST /mcp — a fresh, stateless server instance per request, with shared state (sessions, approvals) held in the process. Pass --stdio to serve over stdio instead, for clients that spawn the server locally.

On startup the banner prints the bound URL, the mode, whether the faucet is enabled, and the full list of registered tools. That list is computed from the live registry at boot, so it never drifts from what the server actually exposes.

Auth model

There are two independent layers:

Transport auth — OAuth bearer. An in-memory PKCE OAuth provider gates POST /mcp when CAPXUL_MCP_OAUTH_REQUIRED=1. The server publishes the standard discovery documents (/.well-known/oauth-protected-resource, /.well-known/oauth-authorization-server) and the /oauth/authorize and /oauth/token endpoints. A proof-issuer secret (CAPXUL_MCP_OAUTH_PROOF_ISSUER_SECRET) can mint bearer tokens for automated probes — and is currently required whenever OAuth is required, because external-issuer validation is not implemented yet. Stdio mode skips OAuth entirely: a local spawn is trusted IO with no bearer-token surface.

Financial auth — email OTP sessions. Signing in to Capxul happens through tools: auth.requestOtp emails a one-time code, auth.verifyOtp exchanges it for an opaque sessionToken that every session-scoped tool takes as an argument. The OTP travels only as a tool argument, and no other credential — no backend JWT, no key material — ever appears in a tool result.

The dev-mode custody gate

The --mode flag decides how money-moving operations get signed:

  • --mode live (default) uses the production signer path. Full account activation needs a one-time human approval in the browser: account.ensureReady with requirement deployed returns { status: "pending", approvalUrl, approvalId } — open approvalUrl (the dedicated Approval app), complete the approval there, then poll account.deploymentStatus with the approvalId. The server itself never holds key material.
  • --mode dev runs against a deterministic dev signer seed (CAPXUL_MCP_DEV_SIGNER_SEED) and a dev backend deployment, so agent journeys can be exercised headlessly, without live custody. Dev mode also gates the wider development tool set.

Runtime configuration

Environment is read lazily on the first authenticated tool call, so liveness (system.ping) needs no secrets. A missing variable surfaces as a structured ENV_MISSING tool error naming the exact variable. Notable variables:

VariablePurpose
CAPXUL_MCP_PORTBind port (default 8788; 0 = ephemeral).
CAPXUL_FAUCET_ENABLED1 or true to register the testnet faucet tool.
CAPXUL_MCP_DEV_SIGNER_SEEDDeterministic dev signer seed (--mode dev).
CAPXUL_MCP_OAUTH_REQUIRED1 to require an OAuth bearer token on POST /mcp.
CAPXUL_MCP_OAUTH_PROOF_ISSUER_SECRETSecret to mint proof bearer tokens.
CAPXUL_MCP_APPROVAL_URLBase URL of the Approval app for activation approvals.

Which tools are registered

Three tiers, decided at launch:

  1. Always registered — system, auth, account, identity, and payee tools.
  2. Faucetfaucet.fundTestnet registers only when CAPXUL_FAUCET_ENABLED is set. Otherwise it is absent from tools/list.
  3. Wider development set — Organizations, requests/inbox, and actor projection tools register only when the development gate is on: --mode dev and the faucet enabled. In --mode live these tools are absent today.

A typical first session, in order: system.pingauth.requestOtpauth.verifyOtp (returns sessionToken) → account.ensureReadyaccount.balance.

Tool reference

Inputs marked ? are optional. sessionToken is always the opaque token returned by auth.verifyOtp.

System and auth

ToolInputWhat it does
system.pingecho?Liveness probe; echoes back the optional value. Needs no auth and no secrets.
auth.requestOtpemailEmail a one-time sign-in code. Works for new and returning users alike.
auth.verifyOtpemail, otpVerify the emailed code and start a session. Returns the opaque sessionToken.
auth.statussessionToken?Report whether the session is authenticated, and for whom.
auth.signOutsessionTokenEnd the session and revoke the token.

Account readiness and balance

ToolInputWhat it does
account.statussessionTokenReadiness ladder: loading, settingUp (with the current step), ready (with accountId and canTransact), or failed.
account.ensureReadysessionToken, requirement? (provisioned or deployed)Run account setup to completion; idempotent. With deployed, may return pending plus an approvalUrl for the one-time browser approval.
account.deploymentStatusapprovalIdPoll the activation approval started by account.ensureReady. pending until it completes, then ready with canTransact.
account.balancesessionTokenThe account's balance and available balance, as Money.

Identity and payees

ToolInputWhat it does
me.getsessionTokenThe authenticated identity: authUserId, email, displayName.
me.depositInstructionssessionTokenInstructions for depositing money into the account.
handles.resolvesessionToken, handleResolve a Capxul handle or org handle to its current payment destination.
payees.createsessionToken, label, recipient, handle?Save a recipient as a Payee. The recipient must resolve by email or org handle.
payees.getsessionToken, payeeIdLoad a saved Payee by id.
payees.resolvesessionToken, recipientResolve an email, handle, org handle, or Payee id to a payment destination.

Faucet

Registered only when CAPXUL_FAUCET_ENABLED is set. Test environments only — the same guardrails as the Sandbox CLI apply: never wire the faucet into production UX.

ToolInputWhat it does
faucet.fundTestnetsessionToken, amount { value, currency?, decimals? }Mint test money into the session's account (testnet only). value is a decimal string, e.g. "10" for $10. Returns { status: "funded" } — no settlement internals.

The wider dev-mode surface

The same development gate also registers these tool families. They mirror the SDK's org, request/inbox, and projection surfaces; expect them to evolve the fastest of anything on this page.

FamilyToolsWhat it covers
Organizationsorg.create, org.list, org.members, org.roles, org.inviteCreate and read Organizations and invitations.
Address bookaccount.addressBook.* and org.addressBook.* (list, get, add, hide, unhide, label)Relationship entries per actor scope, refs and labels only.
Requests and inboxaccount.requests.*, org.requests.* (issue, list, get, cancel); account.inbox.*, org.inbox.* (list, approve, decline)Issue requests to payers. List, approve, or decline payable items.
Destinationsdestinations.add, destinations.list, destinations.removeManage saved destination metadata.

The capability constraints on the equivalent SDK surfaces apply here too — check Capability status before building a product flow on any of them.

What never crosses the wire

Tool results are leak-safe by design: they carry Money values, validated recipient labels, opaque ids, and committed document hashes. Settlement internals — transaction hashes, account addresses, raw minor units, approval token values — stay server-side. If you find one in a tool result, that is a defect worth reporting, not a feature to depend on.

On this page