Set up the MCP server
Three steps: create a key, add SorenPay to your assistant, ask a question.
1. Create an API key
Your assistant signs in with a SorenPay API key (apk_…). Give it only the
read scopes for the tools you want it to use. A read-only key is the safe
choice for an AI assistant:
| Scope | Tools it unlocks |
|---|---|
read:treasury | get_treasury, get_recent_activity |
read:cards | list_cards |
read:agents | list_agents |
read:checkout | list_checkout_sessions |
From the dashboard (in sandbox). Go to
Developers → API keys and choose Create key. That
key covers treasury, cards and checkout, so every tool except list_agents
works with it. It also carries write scopes for the dashboard's own forms.
MCP never uses them, but anyone who gets the key could, so use a read-only key
(below) for anything beyond a quick test.
A read-only key with the API. For a key that can only read, and can also
call list_agents, create one with an existing key that holds
write:api_keys and every scope you ask for (a key can't hand out more
than it has):
curl -X POST https://sorenpay.com/api/auth/keys \
-H "Authorization: Bearer apk_<existing key>" \
-H "Content-Type: application/json" \
-d '{
"label": "claude-read-only",
"scopes": ["read:treasury", "read:cards", "read:agents", "read:checkout"]
}'The new key's secret is shown once. Keep it somewhere safe; you'll paste it into your assistant's config next.
2. Add SorenPay to your assistant
Claude Code
Claude Code connects to HTTP MCP servers directly:
read -rs SOREN_API_KEY # paste your apk_ key, then Enter (not echoed)
claude mcp add --transport http soren-pay https://sorenpay.com/api/mcp \
--header "Authorization: Bearer $SOREN_API_KEY"Using the variable keeps the key out of your shell history.
Run claude mcp list to check it's connected, then ask Claude Code something
like "What's our SorenPay balance?".
Claude Desktop
Claude Desktop starts MCP servers as local programs, so SorenPay connects
through a tiny bridge (@sorenpay/mcp-bridge, no dependencies, needs Node 18+)
that forwards each message to the HTTP endpoint with your key.
Open the config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add SorenPay under mcpServers:
{
"mcpServers": {
"soren-pay": {
"command": "npx",
"args": ["-y", "@sorenpay/mcp-bridge", "--base-url", "https://sorenpay.com"],
"env": { "SOREN_API_KEY": "apk_<your key>" }
}
}
}Quit and reopen Claude Desktop. The SorenPay tools show in the tools menu.
The key goes in env, not args: other programs on the computer can read a
process's arguments, but not its environment. The bridge still accepts
--api-key, but avoid it on shared machines. The bridge package isn't
published to npm yet, so npx can't download it today. Until it is, ask
support@sorenpay.com for a copy and run it with "command": "node",
"args": ["/path/to/mcp-bridge/bin/cli.js", "--base-url", "https://sorenpay.com"],
keeping the same env.
Cursor
Add SorenPay to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json
(one project):
{
"mcpServers": {
"soren-pay": {
"url": "https://sorenpay.com/api/mcp",
"headers": {
"Authorization": "Bearer apk_<your key>"
}
}
}
}Then open Cursor Settings → MCP and check that soren-pay is enabled.
Windsurf and other clients that accept an HTTP URL plus headers use the same
two values. Clients that only run local programs can use the bridge config
from the Claude Desktop section.
A project-level .cursor/mcp.json often ends up in git. Keep keys in your
user-level config, or add the file to .gitignore.
3. Check it works
Ask your assistant: "Use SorenPay to tell me how much we can spend right
now." It should call get_treasury and answer with your available balance.
You can also call the server directly:
curl -X POST https://sorenpay.com/api/mcp \
-H "Authorization: Bearer apk_<your key>" \
-H "Content-Type: application/json" \
-d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'curl -X POST https://sorenpay.com/api/mcp \
-H "Authorization: Bearer apk_<your key>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": { "name": "list_cards", "arguments": { "state": "active", "limit": 5 } }
}'Troubleshooting
| You see | What it means | Fix |
|---|---|---|
unauthorized (code -32001) on every call | The key is missing, mistyped, revoked or expired | Check the Authorization: Bearer apk_… value, or create a new key |
missing_scope:read:agents (code -32001) | The key works but doesn't have that tool's scope | Create a key with the scope (step 1) |
invalid_arguments (code -32602) | An argument is the wrong type or out of range | See the tool's inputs in the tool reference |
tool_not_found (code -32601) | The tool name doesn't exist | Run tools/list for the exact names |
Bridge exits with missing --api-key | No key passed and SOREN_API_KEY isn't set | Add --api-key apk_… to args |
Errors come back as JSON-RPC errors with HTTP status 200, so check the
error field rather than the status code.
Security
- The assistant can do whatever the key's scopes allow. Today every MCP tool is read-only, but a key with write scopes could still be used against the REST API if it leaks, so prefer a read-only key.
- Treat tool results as untrusted text. They include things other people choose, like merchant names, card and agent names, and checkout details. Text like that can try to give your assistant instructions ("ignore previous instructions and…"). Watch for this when the same assistant can also send email, browse, run commands or use other write tools. Review what it does with those tools, and don't let it run them without asking you first.
- Each key only sees its own workspace.
- Revoke the key to cut the assistant off immediately.
- Tool calls are recorded for product analytics with the tool name and outcome only. Tool arguments and results aren't recorded.