xrpl-did-mcp
An MCP server for deriving, resolving, and authorizing did:xrpl identities on the XRP Ledger, read-only by default with ledger writes gated behind --allow-writes and keychain-held signing.
Derive a
did:xrplDID from an XRP address.Resolve a
did:xrplto its on-ledger DID Document.Check whether an agent is authorized using caller and operator trust policies, with auditable reasons.
Look up account balance/on-ledger state and transaction results.
When writes are enabled and a signing seed is available: publish a DID Document, delete/revoke a DID, and revoke a credential.
The provided schema exposes these 8 tools; the README also describes credential issue/accept/get tools that are not present in this schema.
Provides tools for deriving and resolving did:xrpl W3C-compatible decentralized identifiers on the XRP Ledger, checking agent authorization, looking up ledger account and transaction data, and optionally publishing DID Documents to the ledger.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@xrpl-did-mcpgive me a DID for rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
xrpl-did-mcp
An MCP server for did:xrpl — W3C-compatible decentralized identifiers for AI agents on the XRP Ledger.
Point any MCP client at it and your agent can derive, resolve, and authorize identities natively.
# not on PyPI yet -- install from GitHub, pinned to the release tag
pip install "xrpl-did-mcp @ git+https://github.com/DuNorth595/xrpl_did_mcp.git@v0.5.0"That one command pulls in xrpl-agent-id and xrpl-py as well. Both are
pinned to release tags, so an install cannot silently change underneath
you.
What it gives an MCP client
Tool | What it does | Writes to the ledger? |
| Turn an XRP address into a | No |
| Read a DID Document for a | No |
| Decide whether an agent may act, with reasons | No |
| Read an account's balance and on-ledger state | No |
| Read a transaction's result and inclusion status | No |
| Read a credential's state — exists, accepted, URI, expiry | No |
| Create a credential for a subject | Yes — spends XRP |
| Accept a credential issued to the signing account | Yes — spends XRP |
| Publish an agent's DID Document | Yes — spends XRP |
| Delete an account's DID Document | Yes — spends XRP |
| Withdraw one credential | Yes — spends XRP |
Six of the eleven tools are read-only. The five that write:
Refuse by default. Each returns
WRITES_DISABLEDunless the server was started with--allow-writes.Take no seed argument. The signing seed comes from the OS keychain, which the server reads itself, so the seed never passes through the agent's context.
Revocation
revoke_did submits a DIDDelete, so the DID no longer resolves.
DIDDelete always targets the signer's own DID, so the tool refuses with
ADDRESS_MISMATCH if the address is not the one the seed controls —
before anything is submitted.
revoke_credential submits a CredentialDelete, withdrawing one
credential. A credential is identified by the triple (issuer, subject,
credential_type); the subject may be an address or a did:xrpl.
Deleting a DID does not delete the account's credentials. A DID and a
credential are separate ledger objects — a DID is keyed by its owner
account, a credential by (issuer, subject, credential_type). rippled's
DIDDelete erases only the DID. To withdraw an authorization, revoke the
credential too.
The credential lifecycle
A credential is identified by the triple (issuer, subject, credential_type), and it takes two signatures before it is valid for the subject:
Step | Tool | Who signs |
1. Create |
| the issuer |
2. Accept |
| the subject |
3. Read |
| nobody — it is a read |
4. Withdraw |
| the issuer |
issue_credential submits a CredentialCreate. The credential exists on
the ledger at that point, but XLS-70 only sets the accepted flag when the
subject signs — so until accept_credential runs, the credential does not
count as held. get_credential reports the two states separately, because
existence is not acceptance.
The subject and issuer may each be an address or a did:xrpl; a
did:xrpl is reduced to its address before the transaction is built.
Related MCP server: xrpl-identity-mcp
Connect it
Claude Desktop / Claude Code
{
"mcpServers": {
"xrpl-did": {
"command": "xrpl-did-mcp",
"env": { "XRPL_MCP_NETWORK": "testnet" }
}
}
}Any other MCP client (stdio)
xrpl-did-mcp # stdio, testnet, read-only
xrpl-did-mcp --network mainnet # stdio, mainnet, read-only
xrpl-did-mcp --allow-writes # enable the write tools
xrpl-did-mcp --http 8080 # streamable-httpEnabling the write tools
The write tools — publish_did_set, revoke_did, revoke_credential,
issue_credential and accept_credential — need two things: the server
started with --allow-writes, and a signing seed in the OS keychain.
# Store a seed (macOS). The server reads it; the agent never sees it.
security add-generic-password -a "$USER" -s xrpl-did-mcp -w '<your seed>'The keychain service defaults to xrpl-did-mcp; set
XRPL_MCP_KEYCHAIN_SERVICE to change it.
If the keychain has no entry, the tool returns NO_SEED with the setup
instructions. It never falls back to something weaker.
For throwaway testnet use where a seed in the conversation is harmless,
--allow-inline-seed permits passing one directly as the tool's seed
argument. It is off by default, because a seed in the agent's context is a
seed the agent can read.
Without that flag the seed argument is refused: the tool returns
INLINE_SEED_REFUSED and falls back to the keychain. The keychain is
always tried first, even when an inline seed is supplied.
Operator trust policy
The caller of a tool is not necessarily the operator of the server. An agent that chooses its own trust policy can always choose a permissive one, so the server keeps its own policy on disk and applies it on top of whatever the caller passes.
Put a trust_policy.json in the server's working directory, or point
XRPL_MCP_POLICY at one:
{
"require": {
"issuers": ["rTrustedIssuer..."],
"credential_type": "agent-authorization"
},
"deny": {
"issuers": ["rRevokedIssuer..."],
"credential_type": "agent-authorization"
},
"ban": {
"agents": ["did:xrpl:1:rBanned...", "rBannedPlain..."]
}
}Every section is optional.
require— the agent must hold this credential.deny— holding this credential is grounds for refusal, whatever else it holds.ban— the agent is refused outright.
The operator's rules cannot be waived by the caller. A missing policy file means the operator has not expressed an opinion — it does not mean allow everything; it means no operator rules are added to the caller's.
A policy file that exists but cannot be parsed is surfaced as
POLICY_INVALID rather than ignored, because silently dropping the
operator's deny rules would quietly remove the property the file exists to
provide.
What it looks like in a conversation
Agent: Give me a DID for
rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh.
Tool
derive_did:did:xrpl:1:rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh— derived from the address. No registration, no fee, no database row.
Agent: Resolve it.
Tool
resolve_did: reads theDIDSetfrom the ledger and returns the DID Document. Anyone can do this — there is no server of ours in the path.
Agent: Can this agent act?
Tool
check_authorization:ALLOW— orDENYwith the list of missing credentials and the deny rules that fired.
Why a DID and not just an address
An XRP address says who holds a key. It does not say what that key is allowed to do, who vouches for it, or whether it was revoked.
did:xrpl adds a resolvable DID Document, so an agent's identity can
carry credentials — and the authorization decision becomes a ledger read
rather than a trust-me.
Built on xrpl_agent_id,
which implements the XLS-40d DID model and XLS-70d credentials.
Networks
Testnet by default. Mainnet is the same code with network="mainnet".
xrpl_agent_id has been validated on XRPL mainnet — all six authorization
roles, verified against the public ledger. See the
mainnet decision record.
Development
git clone https://github.com/DuNorth595/xrpl_did_mcp
cd xrpl_did_mcp
pip install -e ".[dev]"
pytestThe default suite is fully offline. Two ledger-backed tests are skipped unless
XRPL_MCP_LIVE=1 is set.
Documentation
Document | What it covers |
Reporting a vulnerability, and the security-relevant design decisions | |
How to contribute, and how to add a tool | |
Release history |
License
MIT — see LICENSE.
Available Tools
11 toolsaccept_credentialAccept a credential issued to this account (writes to the ledger)A
Accept a credential that was issued to this account, making it valid for the subject. THIS WRITES TO THE LEDGER and spends XRP.
A credential created with issue_credential is not valid for the subject until the subject signs it. This tool is the subject's side of that: it submits the CredentialAccept.
The signing seed comes from the OS keychain, which the server reads itself, so the agent never sees the seed. This tool is only available if the server was started with --allow-writes.
An optional seed argument exists for throwaway testnet use. It is refused unless the server was started with --allow-inline-seed.
To read a credential's state without changing anything, use get_credential. To withdraw a credential, use revoke_credential.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| issuer | Yes | ||
| network | No | ||
| credential_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does: it flags the write to the ledger and the XRP spend, discloses that signing material comes from the OS keychain and is never exposed to the agent, and documents both gating flags (--allow-writes for the tool, --allow-inline-seed for the seed argument). This is exactly the behavioral context annotations would otherwise supply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the destructive consequence in capitals before any mechanics, then the lifecycle rationale, then the seed/flag caveats, then the sibling routing. Every sentence carries distinct information; nothing repeats the schema or the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be described, and the safety/availability picture is thorough for a mutation tool with no annotations. The remaining gap is the undocumented issuer/credential_type/network semantics, which matter for correctness on a ledger write.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and it only partly does: it explains the optional `seed` argument's purpose and the condition under which it is refused, which is high-value. But `issuer`, `credential_type` and `network` get no explanation at all — an agent must infer whether credential_type is free-form, a hex value, or an enum, and what network's empty default means.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (accept a credential issued to this account) and immediately explains the lifecycle position: a credential from issue_credential is not valid until the subject signs, and this submits the CredentialAccept. That distinguishes it from issue_credential, get_credential and revoke_credential without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names alternatives and the conditions selecting them: get_credential to read state without changes, revoke_credential to withdraw, and issue_credential as the counterpart operation this complements. It also states a hard availability precondition (server must be started with --allow-writes), which is the kind of when-you-can-use-this guidance agents usually have to discover by failing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_authorizationDecide whether an agent is authorized to actA
Evaluate an agent against a trust policy and return an allow/deny decision with the reasons. The result reports which required credentials are missing and which deny rules matched, so the decision is auditable rather than a bare boolean.
The caller's policy is combined with the server operator's policy file, if one is configured. The operator's deny and ban rules are applied on top of the caller's and cannot be waived by them.
| Name | Required | Description | Default |
|---|---|---|---|
| network | No | ||
| agent_did | Yes | ||
| banned_agents | No | ||
| denied_issuers | No | ||
| credential_type | Yes | ||
| trusted_issuers | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the return shape (allow/deny with reasons, missing credentials, matched deny rules) and the important policy-layering behavior. It explains that operator deny/ban rules are applied on top of caller rules and cannot be waived, which is exactly the kind of non-obvious behavior an agent needs. It does not state whether the check is purely read-only or whether it has side effects such as logging.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight paragraphs, front-loaded with the decision outcome and followed by the most consequential policy-layering caveat. Every sentence adds useful information with no repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not explain return values in full, and its behavioral policy notes are strong. However, with six undocumented input parameters at 0% schema coverage, the definition is incomplete about what each input controls, which is a material gap for an authorization decision tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across six parameters, so the description must compensate. It mentions 'required credentials' and 'deny rules' only abstractly and never maps meaning to agent_did, trusted_issuers, credential_type, banned_agents, denied_issuers, or network. An agent must infer parameter semantics entirely from names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: evaluate an agent against a trust policy and return an allow/deny decision with reasons. This is clearly distinct from the DID/credential-management siblings, though it does not explicitly name or differentiate itself from them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'evaluate an agent against a trust policy' and the auditability framing, but the description never says when to call this versus alternatives, nor when not to call it. For a gatekeeping decision tool, this is adequate but leaves timing and prerequisites to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
derive_didDerive a did:xrpl from an XRP addressA
Derive the W3C-compatible decentralized identifier for an account on the XRP Ledger. Format: did:xrpl::. This is a pure derivation -- no transaction, no registration, no fee.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | ||
| network | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description does carry real weight here and it does disclose the key behavioral fact: the operation is side-effect-free, involving no transaction and no fee. It does not say whether the computation is local/deterministic, what happens with an unknown or empty network, or whether the same address on different networks yields different DIDs beyond the format hint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the purpose first, then the format, then the non-mutating guarantee. Nothing is padded and every clause adds information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value description is rightly omitted, and the mutation profile is stated. The gap is the network parameter: an agent cannot tell from the description what to pass there or what the default empty string produces, which matters for a derivation whose output embeds that value.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and the format string did:xrpl:<network-id>:<address> does clarify what both parameters mean and how they are composed. However, the optional `network` parameter's empty-string default and acceptable values are left entirely unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb ("derive") and resource ("W3C-compatible decentralized identifier for an account on the XRP Ledger") and even shows the exact output shape, so the operation is unmistakable. It stops short of naming the inverse sibling resolve_did, so differentiation from the surrounding DID tools is only implicit via the "pure derivation" note.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"This is a pure derivation -- no transaction, no registration, no fee" usefully rules out the write-path siblings like publish_did_set, but no tool is named as the alternative and no positive trigger ("use when you need to compute a DID from a known address") is stated. Usage is implied rather than prescribed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_credentialRead a credential's state on the ledgerA
Read one credential's state from the XRP Ledger: whether it exists, whether the subject has accepted it, its URI, and its expiration.
This is a pure read. It submits no transaction, spends nothing, and does not need --allow-writes.
Existence is not acceptance: a credential issued with issue_credential does not become valid for the subject until the subject accepts it. This tool reports which of those is true.
For an account's balance and other state, use lookup_account. To accept a credential, use accept_credential.
| Name | Required | Description | Default |
|---|---|---|---|
| issuer | Yes | ||
| network | No | ||
| subject | Yes | ||
| credential_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it states that the tool submits no transaction, spends nothing, and needs no write permission. It also explains the critical semantic that existence does not imply acceptance, which is exactly the kind of context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then adds only useful routing and behavioral context. Every sentence earns its place by clarifying scope, safety, or alternative tools.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema already covers return values, and the description adequately explains the read-only behavior and acceptance semantics. However, for a tool with four parameters at 0% schema coverage, the missing parameter documentation leaves a meaningful completeness gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must define the four parameters, but it does not explain issuer, subject, credential_type, or network formats. It hints at subject/issuer semantics through the acceptance explanation, but credential_type and network remain undocumented in both schema and description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: reading one credential's state from the XRP Ledger. It names the exact state returned (existence, acceptance, URI, expiration) and distinguishes the tool from issue_credential, accept_credential, and lookup_account.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says this is a pure read requiring no transaction and no --allow-writes, and routes the agent elsewhere for account balance and accepting a credential. The distinction between issuance and acceptance further clarifies when this read is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
issue_credentialIssue a credential to a subject (writes to the ledger)A
Create a credential on the XRP Ledger, so a subject can be authorised to act. THIS WRITES TO THE LEDGER and spends XRP.
The signing seed comes from the OS keychain, which the server reads itself, so the agent never sees the seed. This tool is only available if the server was started with --allow-writes.
An optional seed argument exists for throwaway testnet use. It is refused unless the server was started with --allow-inline-seed, because a seed in the agent's context is a seed the agent can read.
The credential is created but not yet valid for the subject until the subject accepts it with accept_credential. To withdraw a credential, use revoke_credential instead. To read a credential's state without changing anything, use get_credential.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | No | ||
| seed | No | ||
| network | No | ||
| subject | Yes | ||
| expiration | No | ||
| credential_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does most of it well: it declares the write, the XRP cost, the OS-keychain seed handling, the --allow-writes and --allow-inline-seed feature gates, and the two-phase pending/accept state transition. What is missing is failure behavior — duplicate/already-issued credentials, idempotency, and error conditions — so the agent cannot predict how the call fails.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the verb, target, and cost in the first sentence, then layers secrets handling, gating, and sibling routing in short paragraphs. Every sentence carries distinct information — no restatement of the title or name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the mutation/safety context is unusually complete. However, for a 6-parameter, 0%-coverage mutation tool, the description leaves too many inputs undefined; it is adequate for deciding whether to call, less so for calling correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 6 parameters, yet the description only explains `seed` and the gating around it. `subject`, `credential_type`, `uri`, `network`, and `expiration` receive no meaning, format, or default guidance anywhere, leaving the agent to guess at critical inputs like credential type and expiration units.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Create a credential on the XRP Ledger') plus the goal ('so a subject can be authorised to act'). It explicitly distinguishes itself from the three credential siblings (accept_credential, revoke_credential, get_credential) at the end, so an agent can route correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use and when-to-use-something-else guidance: creates a pending credential, requires accept_credential to become valid, revoke_credential to withdraw, get_credential to read without mutating. It also names the precondition (server started with --allow-writes), which is exactly the eligibility gate an agent must know before attempting the call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_accountLook up an account's balance and state on the ledgerA
Read an XRP Ledger account's on-ledger state: its balance in drops, the number of objects it owns, and its next transaction sequence.
For an account's DID Document, use resolve_did instead -- that tool returns the document itself, not the account's other state.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | ||
| network | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. It does establish this as a read-only state lookup and names the three returned quantities, but it is silent on the failure mode for a non-existent/unfunded account, whether the call requires a specific network, and any rate or cost constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler: the capability and its returned fields come first, followed by the disambiguation clause. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value detail is rightly omitted, and the sibling disambiguation is present. But against a 0%-covered two-parameter schema with no annotations, the missing address format and network semantics leave real gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate and largely does not. 'Account's address' is never defined in terms of XRP classic address format, and the optional 'network' parameter with an empty-string default is never mentioned at all, leaving the agent to guess which ledger is queried.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read an XRP Ledger account's on-ledger state') and enumerates exactly what is returned: balance in drops, owned-object count, and next transaction sequence. It explicitly demarcates itself from the sibling resolve_did, so an agent can choose between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent to resolve_did when a DID Document is wanted, which is a genuine when-not clause against a real sibling. However, nothing is said about when *not* to use this tool for other ledger data (e.g. transactions vs lookup_transaction), so the guidance covers only one of several plausible confusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_transactionLook up a transaction's result on the ledgerA
Read a transaction's outcome from the XRP Ledger by its hash: the result code (for example tesSUCCESS for a successful transaction, or tecUNFUNDED_PAYMENT for one that failed), the ledger index it was included in, and whether it has been validated.
For the account that sent or received it, use lookup_account.
| Name | Required | Description | Default |
|---|---|---|---|
| network | No | ||
| tx_hash | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It discloses that this is a read operation and outlines the returned result fields, but does not mention network behavior, unknown-hash handling, or authentication/rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences, front-loaded with the core action and followed by a useful sibling redirect. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema reduces the need to explain return values, and the description still gives useful examples. However, the network parameter is entirely undocumented and the behavior for missing or invalid hashes is unstated, leaving invocation ambiguity for a simple but network-sensitive lookup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description clarifies that lookup is by transaction hash, adding meaning for tx_hash, but says nothing about the network parameter, its default, or valid values. With only one of two parameters explained, it does not compensate for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource (read a transaction's outcome from the XRP Ledger by hash) and explicitly distinguishes the scope from account lookups. An agent can tell this is the transaction-level lookup, not the account-level one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes account-related lookups to lookup_account, which is the closest sibling. It does not state exclusions or prerequisites, but the primary alternative is named clearly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_did_setPublish an agent's DID Document (writes to the ledger)A
Submit a DIDSet transaction so the agent's DID resolves to a DID Document. THIS WRITES TO THE LEDGER and spends XRP.
The signing seed comes from the OS keychain, which the server reads itself, so the agent never sees the seed. This tool is only available if the server was started with --allow-writes.
An optional seed argument exists for throwaway testnet use. It is refused unless the server was started with --allow-inline-seed, because a seed in the agent's context is a seed the agent can read.
Defaults to testnet; pass network='mainnet' explicitly to use mainnet.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| address | Yes | ||
| network | No | ||
| document_uri | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so well: it discloses that the tool writes to the ledger, spends XRP, uses an OS keychain seed, is gated by --allow-writes, and refuses inline seeds unless --allow-inline-seed is set. These are exactly the safety and permission details an agent needs before invoking it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the critical fact that this writes to the ledger and spends XRP, then layers in seed and network constraints. Slightly repetitive on seed security, but overall efficient and well structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the operational and safety context thoroughly, and an output schema exists so return values need not be described. However, for a write tool with 0% schema coverage, the omission of address and document_uri semantics leaves an important gap in invocation completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain all four parameters. It explains seed and network behavior well, but never explains address, which is required, or document_uri, leaving two parameters undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: submit a DIDSet transaction so the agent's DID resolves to a DID Document. It also makes the distinction from read-oriented siblings like resolve_did clear by emphasizing that this writes to the ledger.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context: only available when the server was started with --allow-writes, defaults to testnet, and requires explicit network='mainnet' for mainnet. It does not explicitly compare against sibling tools such as derive_did or resolve_did, but the write-versus-read distinction is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_didResolve a did:xrpl to its DID DocumentA
Resolve a did:xrpl into its DID Document by reading the XRP Ledger. The document is fetched from the ledger itself, so the result is verifiable by anyone and does not depend on this server.
This is the only tool that returns a DID Document. For an account's balance and other on-ledger state, use lookup_account.
| Name | Required | Description | Default |
|---|---|---|---|
| did | Yes | ||
| network | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description must carry the burden; it does disclose a key trust trait — the document is read from the ledger and doesn't depend on the server. It omits failure behavior (unresolvable DID, invalid network) and permission requirements, which matters for a no-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences: purpose first, trust property second, sibling routing last. Nothing is redundant or buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return values need no explanation, and the description covers purpose and verifiability well. The remaining gap is operational: what 'network' selects and what happens when resolution fails.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, yet neither parameter is explained. The 'network' parameter (with an empty-string default) is never mentioned, and the expected did:xrpl string format is only hinted at by the tool name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (resolve a did:xrpl into its DID Document) and adds mechanism (reading the XRP Ledger). It also distinguishes itself from lookup_account, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative and its condition: 'For an account's balance and other on-ledger state, use lookup_account.' It also claims uniqueness ('only tool that returns a DID Document'), but does not address related siblings like derive_did or check_authorization, leaving some routing inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
revoke_credentialRevoke a credential (writes to the ledger)A
Submit a CredentialDelete transaction, withdrawing one credential so it no longer counts as held. THIS WRITES TO THE LEDGER and spends XRP.
A credential is identified by the triple (issuer, subject, credential_type). The issuer or the subject may sign the delete.
This tool is only available if the server was started with --allow-writes. The signing seed comes from the OS keychain, which the server reads itself, so the seed never passes through the agent's context.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| network | No | ||
| subject | Yes | ||
| credential_type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so well: it discloses that this writes to the ledger, that it spends XRP, that it is gated behind --allow-writes, and that the signing seed is read from the OS keychain so it never enters the agent's context. That is exactly the cost, permission, and secret-handling information an agent needs before invoking a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short paragraphs, front-loaded with the action and its cost, then identity, then access constraints. Every sentence contributes distinct information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description covers cost, signing authority, and the write gate. The remaining gap is the undocumented 'network' parameter and any note on irreversibility or failure behavior for a ledger write.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across four parameters, so the description must compensate. It usefully clarifies the identity of a credential as (issuer, subject, credential_type) and implicitly tells the agent not to supply a seed, but 'network' is never explained and 'issuer' is described as part of the identity triple even though it is not an input parameter, which could confuse the caller.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Submit a CredentialDelete transaction, withdrawing one credential so it no longer counts as held.' The effect is unambiguous and clearly about credentials rather than DIDs, though it never explicitly contrasts itself with the sibling revoke_did tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives real preconditions: the server must have been started with --allow-writes, and either the issuer or the subject may sign the delete. It does not, however, say when to choose this over revoke_did or other siblings, nor what to do if the credential is already absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
revoke_didDelete an account's DID Document (writes to the ledger)A
Submit a DIDDelete transaction, removing the account's DID Document from the ledger so the DID no longer resolves. THIS WRITES TO THE LEDGER and spends XRP.
DIDDelete takes only common fields -- it always deletes the signer's own DID, so the address must match the account the seed controls.
This does NOT delete the account's credentials. A DID and a credential are separate ledger objects, and rippled's DIDDelete erases only the DID. To withdraw an authorization, revoke the credential too.
This tool is only available if the server was started with --allow-writes. The signing seed comes from the OS keychain, which the server reads itself, so the seed never passes through the agent's context.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| address | Yes | ||
| network | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it flags that this WRITES TO THE LEDGER and spends XRP, explains the seed is read from the OS keychain and never enters the agent context, and clarifies that credentials are untouched by rippled's DIDDelete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the write-cost warning, then scope, then the credential caveat, then the availability/seed note. Every paragraph earns its place, though the seed explanation could be tighter and the title already signals the write-to-ledger aspect.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A destructive ledger mutation with no annotations; the description covers cost, authorization scope, seed handling, availability and the credential/DID distinction. It stops short of saying the ledger write is irreversible or explaining the network parameter, but an output schema exists so return values need no coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It does for address (must match the signer's account) and seed (keychain-sourced, server-read), but the network parameter is never mentioned, leaving one of three parameters undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific verb, resource and mechanism: submits a DIDDelete transaction that removes the account's DID Document from the ledger. The final paragraph also distinguishes it from sibling revoke_credential by explicitly scoping what it does not delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the precondition (server must be started with --allow-writes), states the constraint that the address must match the account the seed controls, and routes the agent to revoke_credential when the goal is withdrawing an authorization.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.5.0- Added
accept_credential - Added
get_credential - Added
issue_credential
6 tool updates
v0.4.0- Changed
check_authorization2 fields changed- added
Input schema / properties / banned_agentsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Banned Agents" +} - added
Input schema / properties / denied_issuersAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Denied Issuers" +}
- Removed
ledger_lookup - Added
lookup_account - Added
lookup_transaction - Added
revoke_credential - Added
revoke_did
5 tool updates
v0.2.0- First observed
check_authorization - First observed
derive_did - First observed
ledger_lookup - First observed
publish_did_set - First observed
resolve_did
TDQS
Scored across 11 tools
Each tool has a distinct purpose: DID derivation, DID publishing/resolution/deletion, credential issuance/acceptance/read/revocation, account/transaction lookup, and policy authorization are all clearly separated. The descriptions explicitly cross-reference neighboring tools to prevent confusion between pure reads, writes, and derivations.
All tools use snake_case and a verb-first pattern, such as derive_did, issue_credential, lookup_account, resolve_did, and revoke_credential. The naming is predictable and stable across the whole set.
Eleven tools is well scoped for XRPL DID and credential operations. Each tool maps to a meaningful operation, and there is no obvious filler or redundant tool.
The core lifecycle is covered: DID derivation, publishing, resolution, and deletion; credential issuance, acceptance, reading, and revocation; plus account/transaction lookup and authorization checks. A minor gap is the lack of a credential listing/discovery operation, which could make it harder to enumerate credentials without already knowing the issuer, subject, and type.
Maintenance
Related MCP Connectors
Discover MCP servers and A2A agents; verify, message, post, follow, react, and receive webhooks.
Neutral W3C DID/VC identity and reputation oracle for AI agents (did:key/did:web, eddsa-jcs-2022).
Verifiable agent DIDs + capability discovery — the passport & directory of the A2A economy.
Public MCP for agent verification, work discovery and governed interoperability.
Related MCP Servers
- FlicenseAqualityBmaintenanceMock identity-management MCP server for decentralized identity that allows minting DIDs, issuing signed Verifiable Credentials, and verifying them.8-
- AlicenseAqualityDmaintenanceAn MCP server for XRP Ledger identity features including DIDs, credentials, multisig, and safe transaction workflows.1223 npm1MIT

vantic-mcpofficial
AlicenseNot gradedqualityDmaintenanceEnables MCP hosts to verify agent spending mandates and receipts, providing stateless tools for authorization, chain verification, credential verification, and DID resolution.Apache 2.0
Proofable MCPofficial
AlicenseAqualityBmaintenanceEnables AI agents to manage identity, permissions, secrets, and verifiable proofs through a hosted MCP server, letting clients sign in and check what an agent may do before it acts.1527 npmApache 2.0