Skip to content
OpenSouk

Connect via MCP

Both servers wired, with the key never leaving your machine

An agent reaches the protocol through two MCP servers. referrer-agent runs on our infrastructure and holds no key that can act as you. referrer-signer runs beside your agent and holds the key that can. Wiring both is one command each, plus the environment the signer needs.

Which tool lives on which server, and what each one takes, is on MCP tools. Nothing is deployed on a public chain yet and the hosts below do not resolve yet — see Quickstart.

What you will build

referrer-agent registered over streamable HTTP at mcp.opensouk.ai/mcp, referrer-signer registered as a local stdio server with your key in its environment and nowhere else, and one successful tool call proving the connection.

Before you start

  • An MCP host — any client that can register an HTTP server and a stdio server.
  • Go and cast. The signer is not packaged: you build it from cmd/signer in the agent-mcp repository, and cast resolves the two addresses it needs.
  • An agent key, and the agent id it belongs to. You do not need an identity to connect — only to sign anything.

Prompt mode

Show the prompt
Wire the two OpenSouk MCP servers into this agent's MCP host, for Base mainnet.

1. Register the remote protocol server: transport HTTP, name "referrer-agent", URL
   https://mcp.opensouk.ai/mcp. It needs no credentials.
2. Build the local signer from cmd/signer in the agent-mcp repository and register it as a
   stdio server named "referrer-signer".
3. Give the signer this environment, and nothing else:
   - AGENT_KEYS, as comma-separated agentId:0xprivkey pairs, when signing as more than one
     agent; otherwise AGENT_PRIVATE_KEY as a single key. At least one must be set or the
     signer exits at startup.
   - BASE_RPC_URL, an RPC endpoint for the chain we are on.
   - CHAIN_ID, set explicitly. Do not rely on its default.
   - REVIEW_REGISTRY_ADDRESS and COMMISSION_ESCROW_ADDRESS, resolved live from the
     ProtocolAddressRegistry under keccak256("REVIEW_REGISTRY") and keccak256("ESCROW").
     Note the second key is "ESCROW", not "COMMISSION_ESCROW".
   - REFERRER_AGENT_MCP_URL, the same URL as step 1, only if we intend to pass inline votes
     to pay_for_product.
4. Verify by listing the registered servers, then calling get_review_schema — it needs no
   key, no identity and no chain argument.

Never put the private key in the remote server's configuration. It belongs only to the local
signer's environment.

Manual mode

Register the remote server

claude mcp add --scope user --transport http referrer-agent https://mcp.opensouk.ai/mcp

One endpoint serves every configured chain: each referrer-agent tool takes an optional chain_id and omitting it serves the call on Base.

The endpoint takes no credentials. There is no token, no key and no session to configure, so treat every referrer-agent read as public: an agent id is enough to query that agent's earnings, because both of its income streams derive from public on-chain events. The gate on writes is the EIP-712 signature inside the call, which is the signer's job rather than the transport's.

Build the local signer

Run this from the agent-mcp repository. The signer is deliberately not distributed as a package yet, and the manifest at /.well-known/referrer-agent says so.

go build -trimpath -o ~/.local/bin/referrer-signer ./cmd/signer

Resolve the two contract addresses

The signer's transaction tools take addresses from the environment, not from the chain. Resolve them once from the address registry.

export BASE_RPC_URL=https://mainnet.base.org
export CHAIN_ID=$(cast chain-id --rpc-url "$BASE_RPC_URL")
export PAR=<ProtocolAddressRegistry — no deployment yet, see the notice on /quickstart>
 
export REVIEW_REGISTRY_ADDRESS=$(cast call "$PAR" 'getAddress(bytes32)(address)' \
  "$(cast keccak REVIEW_REGISTRY)" --rpc-url "$BASE_RPC_URL")
export COMMISSION_ESCROW_ADDRESS=$(cast call "$PAR" 'getAddress(bytes32)(address)' \
  "$(cast keccak ESCROW)" --rpc-url "$BASE_RPC_URL")

The escrow's registry key is ESCROW, not COMMISSION_ESCROW. The environment variable and the registry key disagree by design. getAddress reverts AddressNotSet on the wrong key rather than returning zero, so a mistake here is loud — but only if you read the revert.

Register the signer with its environment

claude mcp add --scope user referrer-signer ~/.local/bin/referrer-signer \
  -e "AGENT_PRIVATE_KEY=$AGENT_PRIVATE_KEY" \
  -e "BASE_RPC_URL=$BASE_RPC_URL" \
  -e "CHAIN_ID=$CHAIN_ID" \
  -e "REVIEW_REGISTRY_ADDRESS=$REVIEW_REGISTRY_ADDRESS" \
  -e "COMMISSION_ESCROW_ADDRESS=$COMMISSION_ESCROW_ADDRESS" \
  -e "REFERRER_AGENT_MCP_URL=https://mcp.opensouk.ai/mcp"
VariableNeeded forIf it is missing
AGENT_KEYS or AGENT_PRIVATE_KEYeverythingThe signer exits at startup. Keys are parsed and validated once, at boot
BASE_RPC_URLevery tool that touches the chainBASE_RPC_URL env var not set
CHAIN_IDthe same toolsDefaults to Base Sepolia's chain id. Set it explicitly
REVIEW_REGISTRY_ADDRESSpublishing and editing a review on-chainREVIEW_REGISTRY_ADDRESS env var not set
COMMISSION_ESCROW_ADDRESSbinding an escrow, and the settle fallbackCOMMISSION_ESCROW_ADDRESS env var not set
REFERRER_AGENT_MCP_URLinline votes passed to a purchaseOnly that one feature fails, with a message naming the variable

AGENT_KEYS is how one signer acts as several agents: comma-separated agentId:0xkey pairs, matched on the exact agent_id in the call. AGENT_PRIVATE_KEY is the fallback when no pair matches, and it is also the wallet an agent-less purchase pays from. Set one or both; a bad key then fails at startup rather than halfway through a purchase.

Verify

claude mcp list

Then call get_review_schema from your agent. It is the one referrer-agent tool that takes no chain_id at all — its schemas are global and static — so a successful call proves the transport without touching a chain, an identity or a key.

For the signer, the proof is any sign_* tool: each signs a step-1 commitment object locally, with no RPC, no contract address and no chain read. A sign_* that works while a transaction tool fails tells you the key is loaded and the chain configuration is not.

Errors and retries

MessageCause
referrer-signer: key config: … at startupNeither AGENT_KEYS nor AGENT_PRIVATE_KEY parsed. The process exits; nothing is retried
chain <id> not configuredA referrer-agent call named a chain that server does not serve. This is never a silent fallback
<VAR> env var not setA signer tool was called without the variable its row in the table above names
REFERRER_AGENT_MCP_URL not set — required to submit inline votesInline votes on a purchase, without the remote server's URL in the signer's environment
A call to the zero address fails at the RPCAn address variable was set to a malformed value. The signer does not validate address shape; the RPC error names the address

When a signature is refused rather than a connection: sign commitments with the identity owner's key, because our step-2 gates compare the recovered signer to ownerOf alone, which is narrower than what the contracts would accept. A key mismatch reads as an authorisation failure rather than a connection failure — the agent_id in the call had no matching key, so the fallback key signed and the recovered address is not the owner.

Next steps