The server is the same runtime that backs the REST API and the SDK. There is no MCP-only behaviour: codespar_pay called from Claude Code and codespar_pay called through the SDK's session.execute() hit the same policy engine, the same mandate check and the same ledger. This page is the door for clients that speak MCP; the tool pages under it describe each tool's arguments and actions.
Connect in 60 seconds
Mint a key at Dashboard → API Keys. A new account already has a test project and a csk_test_ key. Then pick your client.
One command. --transport http is the hosted server; no local process is started.
claude mcp add --transport http codespar https://connect.codespar.dev/mcp \
--header "Authorization: Bearer csk_test_your_key"Then open a session and ask for the tool list, or say what you want done: "create a R$49.90 Pix charge for the Pro plan". Claude Code picks codespar_charge from the 15 and runs it.
Claude Desktop connects to remote servers through Settings → Connectors → Add custom connector. Paste the URL and connect; the sign-in that opens in the browser is the server's OAuth 2.1 flow, so there is no key to paste.
Name: CodeSpar
Remote MCP server URL: https://connect.codespar.dev/mcpThere is no header field on that path, so a bearer key cannot be used there. To use a key instead, run the same server as a local process with the @codespar/mcp package and put the key in env:
{
"mcpServers": {
"codespar": {
"command": "npx",
"args": ["-y", "@codespar/mcp", "serve"],
"env": { "CODESPAR_API_KEY": "csk_test_your_key" }
}
}
}Project-scoped in .cursor/mcp.json, or the same object in Cursor's global MCP settings. Cursor sends headers on every request.
{
"mcpServers": {
"codespar": {
"url": "https://connect.codespar.dev/mcp",
"headers": { "Authorization": "Bearer csk_test_your_key" }
}
}
}Reload the window and the 15 tools appear in agent mode. Keep the file out of git if the key is in it, or reference an environment variable from your shell profile.
Windsurf reads ~/.codeium/windsurf/mcp_config.json. Remote servers use serverUrl.
{
"mcpServers": {
"codespar": {
"serverUrl": "https://connect.codespar.dev/mcp",
"headers": { "Authorization": "Bearer csk_test_your_key" }
}
}
}Restart Windsurf, or refresh the MCP panel, and the tools show up under codespar.
Workspace-scoped in .vscode/mcp.json. VS Code calls the server type http.
{
"servers": {
"codespar": {
"type": "http",
"url": "https://connect.codespar.dev/mcp",
"headers": { "Authorization": "Bearer csk_test_your_key" }
}
}
}Anything that speaks MCP Streamable HTTP works: the official SDKs, a framework's MCP adapter, or plain HTTP from any language. The server needs the Authorization header on every request and answers JSON-RPC on POST.
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://connect.codespar.dev/mcp"),
{ requestInit: { headers: { Authorization: `Bearer ${process.env.CODESPAR_API_KEY}` } } },
);
const client = new Client({ name: "my-agent", version: "1.0.0" });
await client.connect(transport);
const { tools } = await client.listTools(); // 15 codespar_* tools
const result = await client.callTool({
name: "codespar_wallet",
arguments: { action: "balance" },
});import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
headers = {"Authorization": f"Bearer {os.environ['CODESPAR_API_KEY']}"}
async with streamablehttp_client("https://connect.codespar.dev/mcp", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools() # 15 codespar_* tools
balance = await session.call_tool("codespar_wallet", {"action": "balance"})No SDK at all: the handshake is three POSTs (initialize, notifications/initialized, then tools/list) with Content-Type: application/json and Accept: application/json, text/event-stream. If initialize returns an Mcp-Session-Id header, send it back on the following calls.
What the first call does
The MCP initialize handshake provisions a CodeSpar session for the key; there is no per-user URL to mint. tools/list then returns the 15 meta-tools. Without a valid key the hosted server answers 401 with a WWW-Authenticate header that points at its OAuth discovery document, which is how OAuth-capable clients find the sign-in flow on their own. The local stdio server behaves differently on a bad key: it boots into a setup mode that exposes only codespar_get_started, which walks the agent through fixing the key.
The 15 tools
Each tool is a stable interface over many providers: the agent says what it wants (charge R$249 over Pix, ship 2 kg to Rio, issue an NFS-e) and the router picks the provider, injects the credential server-side and records the call. The tool pages carry the argument table generated from the published schema.
codespar_shopcodespar_walletcodespar_paycodespar_crypto_paycodespar_issuecodespar_checkoutcodespar_chargecodespar_invoicecodespar_shipcodespar_notifycodespar_kyccodespar_ledgercodespar_discovercodespar_manage_connectionscodespar_get_startedNot sure which one? Ask the server. codespar_discover takes a use case in plain language and returns the tool to call; codespar_get_started returns the ordered happy path for the workspace the key belongs to.
What you need
| What it is | Where it comes from | |
|---|---|---|
| A key | csk_test_ reaches the test environment, csk_live_ reaches production. Same URL; the prefix picks the environment. | Dashboard → API Keys. The key must match the environment of its project, otherwise the server answers 401. See Authentication. |
| A mandate, for anything that spends | A signed spending authority: cap, scope, expiry. codespar_pay, codespar_shop with auto_pay and codespar_crypto_pay are checked against it server-side before any provider is called; a call outside it is refused before money moves. | A consent ceremony the person completes in the browser. The server signs the mandate and stores the signature; the agent references it by id and never signs anything. See Wallets and mandates and Directed pay. |
| A connected provider, for live rails | Charges, invoices, shipments and messages dispatch to a provider account you connect (Asaas, Melhor Envio, Z-API and so on). | codespar_manage_connections lists what is connected and hands back a dashboard deep link to connect more. Credentials never travel through the agent. |
Sandbox
In the test environment the sandbox rails for Pix in, Pix out and the wallet ship pre-connected, so an agent with a csk_test_ key can run the whole buy loop, codespar_shop → codespar_wallet → codespar_pay, with no bank connection, CNPJ or KYC, and no real money. Policy, mandate and audit run exactly as in production. Provider-backed tools in test mode dispatch against declared fixtures; Test mode is the reference for that.
Three things called MCP
They share a protocol and nothing else. This page is the first one.
The same 15 tools are also served over stdio by the @codespar/mcp package, for clients that cannot reach a remote server or that want the key in a local environment variable. It is a thin proxy to this server, not a different one.
Next steps
Quickstart (Python)
Get a CodeSpar commerce agent running in Python — sync for scripts and Django, async for FastAPI and LangChain. Under 5 minutes.
codespar_shop
Buy-side shopping. Act as the shopper, search a store's live catalog and buy, minting the store's real Pix copia-e-cola to settle from the governed wallet. VTEX guest checkout and Mercado Livre.