Generated, not hardcoded
Pointstellar-agentgate at any passkey-kit wallet and agent-policy instance, and it exposes exactly the methods that wallet’s policy currently allows — no more, no less. This comes from two on-chain reads at server start, implemented in src/spec-to-tools.ts:
1
Read the policy's allow-list
A read-only simulate of
agent-policy.get_config(wallet) returns the configured Vec<AllowedCall> — each entry naming a {contract, fn_name, amount_arg_index}.2
Fetch each target contract's own spec
server.getContractWasmByContractId() + contract.Spec.fromWasm() gives the REAL parameter names and types for each allowed method — sourced from the contract’s own compiled spec, never guessed.3
Build one MCP tool per allowed method
A JSON Schema is generated from the real parameter types, and the tool’s description states its spend cap (or confirms it’s uncapped) in plain language.
Address auto-fill
EveryAllowedCall this project’s demo contract exposes takes the wallet’s own address as its primary parameter (deposit(from, amount), withdraw(to, amount)) — the overwhelmingly common shape for a policy-gated call. Rather than requiring an agent to know and pass a 56-character C.../G... address just to say “deposit 100,” any Address-typed parameter the caller omits defaults to the wallet’s own address:
src/mcp-server.ts
Spend-cap hints on the amount argument itself
Beyond the tool-level description ((spend-capped by argument index N) or
(uncapped)), the JSON Schema property for that specific argument also
carries the note — so an agent inspecting just that one field, not the
whole tool description, still knows it’s the number that counts against the
wallet’s rolling-window allowance:
describeAmountArg in src/spec-to-tools.ts, keyed off the same
amount_arg_index policy__ itself reads on-chain — the hint and the
enforcement can never drift out of sync with each other.
Rejections are ordinary tool errors
When the policy rejects a call — cap exceeded, method not allowed — the MCP server does not crash or retry. It returns a normal MCP tool result withisError: true and the on-chain error surfaced in plain text:
Try it directly
Thepolicy-explain subcommand runs the same discovery logic and prints it in plain text, useful for a human auditing what an agent can currently do before trusting it: