MCP server
@ripar/skills is an MCP server over the live Algorand registries, plus x402 quoting and
calling. Six of its tools read the chain, one composes an unsigned transaction, and one
forwards a payment header you supply.
There is no wallet in this process and no credential story at all — it reads what anyone can read from public AlgoNode endpoints. It cannot create a payment. To complete a paid call you sign the payment yourself and pass the header in.
Connect
Not published to npm. Run it straight from the repository:
{
"mcpServers": {
"ripar": {
"command": "npx",
"args": ["-y", "github:nickthelegend/ripar-skills"],
"env": { "RIPAR_NETWORK": "testnet" }
}
}
}Or from a local clone, which is faster after the first build:
git clone https://github.com/nickthelegend/ripar-skills && cd ripar-skills
npm install && npm run build{
"mcpServers": {
"ripar": {
"command": "node",
"args": ["/absolute/path/to/ripar-skills/dist/bin/mcp-stdio.js"],
"env": { "RIPAR_NETWORK": "testnet" }
}
}
}# Claude Code
claude mcp add ripar -- npx -y github:nickthelegend/ripar-skillsRIPAR_NETWORK is the only variable that matters, and testnet is the default —
TestNet is the only network the registries are deployed on today. There is no token
and no server-side spend cap to configure: see Security for where
budget enforcement actually lives.
The registries it reads
| Registry | Algorand TestNet app | Holds |
|---|---|---|
| Identity | 769444119 | Agent id → domain → controlling address |
| Reputation | 769444120 | Payments credited, USDC volume, validator verdicts |
| Validation | 769444121 | The job board and its verdicts |
Tools
ripar_search_agents
List or search agents in the IdentityRegistry by domain substring, exact agent id, or Algorand address. Read-only.
{ "query": "ripar.io", "limit": 25, "withReputation": true }Returns live registry records and an /.well-known/agent.json URL for each. If the chain
is unreachable it fails rather than guessing.
ripar_get_agent
One agent, by agentId, domain or address, optionally with its reputation score and
its jobs. Read-only.
Returns found: false with a reason when the registry has no such agent — the contract's
"not found" value is a literal 0, so an absent agent is a real answer, not an error.
ripar_get_reputation
An agent's score from the ReputationRegistry: payments credited, total USDC volume, and validator verdicts. Read-only.
Each credit is keyed to a payment transaction id and the contract refuses to count the
same id twice — but it does not verify that the id names a real transfer. Check it
against the indexer with ripar_settlements before trusting a number.
ripar_list_jobs
Jobs on the ValidationRegistry, newest first, filterable by status, agentId or
jobId. Read-only. Each job commits to its spec by hash; the spec and result themselves
stay offchain.
{ "status": "submitted", "limit": 25 }Statuses are open, assigned, submitted, validated, disputed, cancelled.
ripar_settlements
Real USDC transfers for an agent from the Algorand indexer, each marked with whether the ReputationRegistry has already counted it. Read-only.
Inbound payments marked counted: false are reputation the agent earned but was never
credited for — a gap only visible because the transfer log and the registry are read
together.
ripar_quote_endpoint
Ask a paid endpoint what it charges, without paying. Makes the request, reads the 402 challenge, and reports the cheapest acceptable payment: amount, asset, network, payee. Read-only.
{ "url": "https://api.ripar.io/api/summarize", "method": "POST", "body": { "text": "…" } }An endpoint that answers 200 is reported as free rather than as an error.
ripar_call_endpoint
Call an endpoint and return its response. Can spend money, but only with a payment header you supply.
{
"url": "https://api.ripar.io/api/summarize",
"method": "POST",
"body": { "text": "…" },
"paymentHeader": "<base64 signed payment>"
}Without paymentHeader, a 402 comes back as the challenge rather than a result. The
header is forwarded untouched as X-PAYMENT.
ripar_post_job
Compose a ValidationRegistry post_job call and return it unsigned, as base64
msgpack, with a plain-language summary of what signing it would do. Nothing is submitted
and no key is used.
{
"sender": "KBDRZK3B…KEISKQ",
"specHash": "<hex of the 32-byte sha256 of the spec>",
"budgetMicro": 2500000,
"validatorAgentId": 0
}budgetMicro is USDC base units — 2500000 is $2.50. See Jobs &
validation for what that number does and, importantly, does not do.
ripar_fund_job
Composes the two-transaction group that moves a budget into escrow: the asset transfer to
the ValidationRegistry's own account, then the fund_job call that reads the amount off
it. Grouped in that order, returned unsigned — the server holds no key.
Refuses before a fee is spent when the sender is not the client, the job is past funding, or the amount is zero.
ripar_settle_escrow
Composes release_escrow or refund_escrow, chosen with action.
Release needs a passing verdict, and may be called by the client — or by anyone once the dispute window has passed, because a validator who never returns would otherwise freeze the worker's money. Refund needs a failed verdict or a cancelled job, and pays the client whoever triggers it: the destination is read off the job, so calling it cannot redirect it.
Resources
Registry state, readable without calling a tool:
| URI | What |
|---|---|
ripar://registries | The three app ids and the escrow terms, read from global state |
ripar://agents | Every registered agent |
ripar://agent/{id} | One agent, with its score and jobs |
ripar://jobs | Every job, with budget and escrow |
ripar://job/{id} | One job |
Both templates ship list callbacks that read the chain, so resources/list returns the
real roster rather than URI patterns.
Prompts
| Name | For |
|---|---|
vet_agent | Check an agent's identity and score before paying it |
post_and_fund_job | Post work and move the budget into escrow |
settle_job_escrow | Release or refund once it has been judged |
Each references only tools that exist — asserted in the test suite, because a prompt naming a missing tool fails at the point somebody trusts it.
A full exchange
user → Which registered Ripar agents have actually been paid?
tool → ripar_search_agents({ query: "", withReputation: true })
tool → 2 agents; agent 2 has a score box, agent 1 does not
tool → ripar_settlements({ agentId: 2 })
tool → 4 inbound USDC transfers, 3 counted, 1 counted:false
agent → Agent 2 has been paid four times but only three of those were
credited to its on-chain score. Agent 1 has never been credited.
Every number there came off the chain. Nothing in this server fabricates one — a failed read is an error, never a plausible-looking zero.