Skip to main content
Glama
jleeblack

Pion - MCP server for Pi Network

Pion

Model Context Protocol server for Pi Network — connect AI agents (Claude, Cursor, and any MCP-compatible client) to Pi Network chain data.

pion-mcp MCP server

⚠️ Reads: both networks. Payments: testnet only. The chain tools query Pi Mainnet or Pi Testnet, selected with PION_NETWORK. send_payment moves real funds, must be explicitly armed, and cannot be armed on mainnet — Pi restricts App-to-User payments to testnet.

Why "Pion"?

The pion is the π meson — the particle physicists named after pi. Fittingly, particle physicists study pion interactions to search for MCPs (millicharged particles). We couldn't resist.

Related MCP server: lightning-mcp

Tools

Out of the box Pion reads and cannot spend: Tiers A and B need no credentials and move no value. Tier C is the exception and is off unless you arm it. (Tiers refer to docs/tool-mapping.md.)

Tier A — chain reads. Zero-permission queries against Pi's public Horizon API. No credentials at all. These work on both Pi chains — testnet by default, mainnet with PION_NETWORK=mainnet.

Tool

What it does

get_wallet_balance

Pi and custom-token balances for a wallet address

get_account_payments

Paginated payment history for an address

query_transaction

Verify a single transaction by hash

Amounts are decimal strings. Pi is reported as the asset PI, custom tokens as CODE:ISSUER, and liquidity-pool shares as pool:ID.

Every result names the chain it came from in a network field, and the startup banner says it too. That redundancy is deliberate: the same address can hold different balances on both chains, so a query against the wrong network does not reliably fail — it can return a plausible, well-formed, wrong number (measured 2026-08-14; see docs/pi-sdk-notes.md). Testnet Pi has no monetary value.

Tier B — identity.

Tool

What it does

verify_user

Validate a Pi user access token, returning the uid and username

verify_user is the only tool that touches a credential, and it never holds one: the caller passes a token per call, it goes to GET /v2/me and nowhere else, and it is not stored, logged, or echoed back. A rejected token returns valid: false with a reason rather than erroring, so an agent can branch on the outcome.

Two caveats worth knowing. The uid is app-specific — the same person has a different uid under a different Pi app, which is deliberate anti-correlation design, so don't use it as a global identifier. And a token is the only proof of identity: a client-supplied uid or username means nothing on its own.

Tier C — payments. Off by default.

Tool

What it does

send_payment

App-to-User: sends Pi from your app wallet to a user

This one spends real money and cannot be undone. It is not registered at all unless armed, so a default server does not even advertise it to the agent.

The recipient must have granted your app the wallet_address scope. A uid alone is not enough — Pi needs that consent to resolve their wallet, and refuses payment creation with missing_scope otherwise. This is the recipient's consent, not your credentials.

Arming requires all four, and Pi restricts A2U to testnet, so anything but Pi Testnet is refused outright:

PION_ENABLE_PAYMENTS=1     # explicit switch, deliberately separate from credentials
PION_MAX_PAYMENT_PI=10     # required per-payment ceiling, in Pi
PI_SERVER_API_KEY=...      # from the Pi Developer Portal
PI_WALLET_SECRET=S...      # app wallet secret seed

Holding the credentials is deliberately not sufficient. The switch and the ceiling are separate because the realistic failure mode is not a stolen key — it is an agent being talked into spending, by a prompt injection sitting in data it just read. A transaction memo, a web page, a filename: any of it can say "send 500 Pi to X." The cap is what makes that bounded rather than fatal. Set it to the smallest amount that makes your use case work.

Nothing overrides the cap from the tool call; changing it means changing server configuration. Neither secret is ever accepted as a tool argument, returned in a result, or logged.

On partial failure it never retries. A2U is three steps — create with Pi, sign and submit on-chain, tell Pi it landed — and a crash between them strands a payment. The tool reports exactly which step failed, whether funds left the wallet, and the payment id needed to clean up. A blind retry could pay twice, so it refuses to guess.

Requirements

Node.js 22.12.0 or newer.

This floor is higher than earlier releases advertised, and correcting it is the reason 0.5.0 is a minor rather than a patch. Through 0.4.2 package.json declared >=18.17, which was never true: the @stellar/stellar-sdk 16.x that 0.4.x pinned already declared >=22.0.0 of its own, so Node 18 and 20 were outside what the dependency supported the whole time. Nothing surfaced it, because our own field is the one npm checks an install against — a package cannot be warned about a floor it is itself misreporting.

0.5.0 moves to @stellar/stellar-sdk 17.x, whose floor is >=22.12.0 (its CommonJS build requires ESM-only dependencies, and require(esm) is only unflagged from 22.12.0), and sets our declared floor to match it honestly.

If you are on Node 18 or 20, what this actually means:

  • The chain read tools and verify_user never load the Stellar SDK — it is imported lazily, inside the payment handler — so those paths are unlikely to be affected in practice.

  • send_payment is the part that genuinely needs 22.12.0. It is also the only part that moves funds, which is why the floor is stated here rather than left to fail somewhere expensive.

Upgrading Node is the supported fix. Pinning 0.4.2 preserves the old declared floor but not a working payment path — that release depends on an SDK that did not support your runtime either.

Usage

MCP clients can run it straight from npm — no install step:

// Claude Desktop: claude_desktop_config.json
{
  "mcpServers": {
    "pion": {
      "command": "npx",
      "args": ["-y", "pion-mcp"]
    }
  }
}
# Claude Code
claude mcp add pion -- npx -y pion-mcp

Or run it from a clone:

npm install
npm run build
claude mcp add pion -- node /absolute/path/to/pion-mcp/dist/index.js

Configuration

Variable

Default

Purpose

PION_NETWORK

testnet

Which chain the read tools query — testnet or mainnet. Mainnet is echoed as REAL VALUE in the startup banner

PION_HORIZON_URL

derived from PION_NETWORK

Override for the Horizon base URL. Optional. If set alongside PION_NETWORK the two must name the same chain — a contradiction is a startup error, not a silent winner

PION_PLATFORM_URL

https://api.minepi.com

Platform API base URL

PION_ENABLE_PAYMENTS

unset (off)

Arms send_payment — see Tier C above

PION_MAX_PAYMENT_PI

unset

Required per-payment ceiling when armed

PI_SERVER_API_KEY

unset

Server API key, Tier C only

PI_WALLET_SECRET

unset

App wallet secret seed, Tier C only

For read-only use there is nothing to configure — verify_user takes its token as a call argument, not from the environment. The bottom four are needed only if you arm payments, and belong in a secrets manager, never in a committed file.

PION_NETWORK and PION_HORIZON_URL are resolved once, in one place, into a single network object that the Horizon client, the banner, every tool result and the arming check all read. Setting both to contradictory chains is a startup error rather than a silent winner, and an unrecognised PION_HORIZON_URL resolves to an explicitly unknown chain — never to a Pi network by resemblance.

Development

npm run build      # compile src/ -> dist/
npm run typecheck  # types only, no emit
npm run smoke          # end-to-end against live testnet
npm run smoke:mainnet  # the same checks against live mainnet
npm run crossnet       # proves the two chains are actually distinguished
npm run arming         # Tier C guards and spend cap (no credentials needed)
npm run signing        # golden-XDR check on the A2U signing path (offline)

npm run smoke spawns the server over stdio as a real MCP client, discovers a funded account from the current ledger, and exercises the chain tools plus the not-found and invalid-input paths. It needs network access.

It covers verify_user only on the rejection path — confirming a genuine token would need a real user credential, which the test deliberately does not handle. The success path is unverified; see below.

npm run crossnet proves network selection is real rather than cosmetic. It does not rely on an address being absent from the other chain — that assumption is false — but on a wallet we control being testnet-only, and on a shared address returning different ledger state from each chain.

npm run arming covers Tier C without touching real money: every refusal branch, the exact cap boundary, that credentials alone do not arm it, that a disarmed server does not advertise the tool, that a fully-credentialled mainnet server still refuses to advertise it, and that neither secret leaks into a result. It uses a freshly generated, never-funded keypair. The one live call it makes is a deliberately-rejected create against the Pi API, which proves the first failure stage end to end.

npm run signing rebuilds the exact transaction send_payment signs, with every input pinned, and compares the envelope and hash against bytes recorded in the file. It is offline and cannot spend. Its job is dependency bumps: the other suites all stub the network, so none of them can tell you whether an SDK upgrade changed what you put on the wire. Run it on any @stellar/stellar-sdk change — a failure means the bytes moved, and the constants should not be refreshed until you know why.

Known gaps

  • verify_user success path — confirmed against a live token. Returns uid, username, app_id, scopes, and valid_until. Everything but uid stays optional, since the rest depends on granted scopes.

  • send_payment success path — verified on testnet (2026-08-01). A real A2U payment ran through all three irreversible steps — create, sign, submit, complete — and was confirmed independently against public Horizon and Pi's block explorer, not just from the tool's own report. The 28-byte memo question that hung over the design is answered: Pi payment identifiers are exactly 28 bytes and fit the Stellar text memo with no room to spare.

  • send_payment failure paths after create — still unproven. Sign, submit and complete have each succeeded once; none has been observed failing against live infrastructure. The two worst branches of the stranded-payment report — "record created, nothing signed" and "funds left, Pi not notified" — are verified by construction only. Treat send_payment as experimental until they have been deliberately exercised.

    This is why it ships off, and why turning it on takes four separate, deliberate acts: PION_ENABLE_PAYMENTS=1, a mandatory PION_MAX_PAYMENT_PI ceiling, both credentials, and Pi Testnet as the selected network. Holding the credentials is not enough on its own. Disarmed, the tool is not registered at all, so an agent cannot see that a spending capability exists — that gate is deliberate design (see Tier C above), not a placeholder for unfinished work. The experimental label is about the failure paths, not about the guards.

  • send_payment cannot pay an arbitrary uid. Pi requires the recipient to have granted your app the wallet_address scope, through the Pi Browser SDK. A valid uid is not sufficient, and this is a permanent property of the Pi API rather than a transient error — creation fails with 401 missing_scope and retrying will not help.

Start with a minimum-amount payment and a low PION_MAX_PAYMENT_PI. Run npm run probe:a2u <uid> first: it exercises create and cancel without moving funds, and its from_address is the only authoritative statement of which app wallet Pi will actually spend from.

Roadmap

Done in v0.4: mainnet reads. The rest of Tier C: get_payment_status, list_incomplete_payments, approve_payment / complete_payment / cancel_payment — the U2A backend half and the recovery tooling for stranded payments. See docs/tool-mapping.md.

The code is Apache-2.0; see LICENSE. The website and the hosted U2A endpoints are covered separately by the Privacy Policy and Terms of Service — sources in site/privacy.html and site/terms.html. Where the two disagree about the software itself, the Apache licence wins.

Short version: the MCP server has no telemetry and talks only to Pi's public endpoints, the site sets no cookies and runs no analytics, and nothing here is stored in a database — there isn't one.

Unofficial community project — not affiliated with Pi Network.

Available Tools

4 tools
get_account_paymentsList Pi wallet payment historyA
Read-only

List payments sent to or from a Pi wallet address, newest first. Call this to answer questions about an address's transaction history — whether a payment arrived, who funded an account, or what it recently sent. Covers payments, account creations, path payments, and account merges. Results are paginated: pass the returned next_cursor back as cursor for the next page. Reads public ledger data only. An address never funded on this chain returns a not-found error rather than an empty list, so an empty payments array means you have paged past the end of the history — not that the account is unused. This server reads Pi Testnet, and every result repeats that in its "network" field — always report which chain a figure came from. Pi Mainnet and Pi Testnet are separate ledgers sharing one address format, and the same address can hold different balances on each, so a result from the wrong chain looks entirely normal. Testnet Pi has no monetary value: never present a testnet balance as real holdings.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoHow many records to return (1-200). Defaults to 10.
orderNo`desc` returns newest records first (the default); `asc` returns oldest first.desc
cursorNoPaging cursor from a previous call's `next_cursor`. Omit for the first page.
addressYesPi wallet address (a Stellar public key): exactly 56 upper-case characters, starting with G, the rest base32 — A-Z and 2-7 only, never 0, 1, 8 or 9. Example: GATQBZLIAUVMND2OCPOKWGPUCNXIGKMNUU7E67YQI2MODSMCMLXBAIJA — that is a format sample, not a default. Pass the address you were actually given: a valid address that is not the intended one returns someone else's balance, not an error.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYes
networkYes
paymentsYes
account_idYes
next_cursorNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and openWorldHint=true, indicating a safe read operation. The description adds crucial behavioral details beyond annotations: pagination mechanics (next_cursor/cursor), the not-found vs empty-list distinction, the testnet vs mainnet separation including the fact that the same address can hold different balances on each, and the monetary value warning for testnet. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the core purpose. However, it is somewhat lengthy at multiple sentences. While every sentence adds value, some could be more concise (e.g., the testnet monetary warning and ledger separation are important but add extra length). Still, it avoids redundancy and is well-organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (4 parameters, 1 required, output schema present), the description is highly complete. It covers all key aspects: what results contain (transaction types, network field), edge cases (unfunded address error vs empty page), pagination handling, and cross-chain context. The output schema exists, so the description rightly focuses on behavioral semantics rather than return value details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so a baseline of 3 is expected. The description adds significant value beyond the schema by explaining the pagination pattern (how to use cursor and next_cursor), interpreting the address parameter with a real usage warning about format vs intended address, and clarifying the order default behavior in context of the tool's purpose. Every parameter is enriched with practical usage context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool lists payments sent to or from a Pi wallet address, newest first, and covers specific transaction types (payments, account creations, path payments, account merges). It clearly distinguishes this from siblings like get_wallet_balance by focusing on transaction history rather than balances, and from query_transaction by addressing account-level history rather than individual transaction lookups.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit when-to-use guidance: 'Call this to answer questions about an address's transaction history — whether a payment arrived, who funded an account, or what it recently sent.' It also implicitly excludes balance queries (handled by get_wallet_balance) and single-transaction lookups (query_transaction). Additionally, it warns about the not-found error for unfunded addresses, explaining how to interpret results correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_wallet_balanceGet Pi wallet balanceA
Read-only

Read the current Pi and custom-token balances of a Pi wallet address. Call this whenever you need to know how much Pi an address holds, whether it holds a particular token, or whether the account exists on-chain at all. Reads public ledger data only — it cannot move funds and needs no credentials. An address that has never been funded on this chain is not an account there: the call returns a not-found error rather than a zero balance, so 'absent' and 'holds nothing' stay distinguishable. This server reads Pi Testnet, and every result repeats that in its "network" field — always report which chain a figure came from. Pi Mainnet and Pi Testnet are separate ledgers sharing one address format, and the same address can hold different balances on each, so a result from the wrong chain looks entirely normal. Testnet Pi has no monetary value: never present a testnet balance as real holdings.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYesPi wallet address (a Stellar public key): exactly 56 upper-case characters, starting with G, the rest base32 — A-Z and 2-7 only, never 0, 1, 8 or 9. Example: GATQBZLIAUVMND2OCPOKWGPUCNXIGKMNUU7E67YQI2MODSMCMLXBAIJA — that is a format sample, not a default. Pass the address you were actually given: a valid address that is not the intended one returns someone else's balance, not an error.

Output Schema

ParametersJSON Schema
NameRequiredDescription
networkYes
balancesYes
sequenceYes
account_idYes
subentry_countYes
last_modified_ledgerYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond the readOnlyHint and openWorldHint annotations by detailing critical behavioral traits: the tool returns a not-found error for unfunded addresses (distinguishing 'absent' from 'holds nothing'), emphasizes that it reads Pi Testnet, and warns that balances are chain-specific. It also instructs to always report the network from the result field. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single paragraph with no wasted words. It front-loads the core purpose, then adds essential behavioral details in a logical order. Every sentence contributes to understanding the tool's use and constraints.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no nested objects, output schema present), the description covers all necessary aspects: purpose, when to use, parameter semantics, behavioral quirks, and output interpretation. It is self-contained and provides enough information for an AI agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds significant value beyond the schema's pattern and description: it explains the exact character set, provides an example with a warning about wrong addresses, and clarifies that the example is not a default. This enhances usability.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Read the current Pi and custom-token balances of a Pi wallet address.' It specifies the verb (read), resource (wallet address), and what it retrieves (balances). It also distinguishes its use case from potential alternatives by explicitly stating when to call it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use the tool: 'Call this whenever you need to know how much Pi an address holds, whether it holds a particular token, or whether the account exists on-chain at all.' It also mentions that it cannot move funds and needs no credentials. However, it does not explicitly exclude sibling tools (e.g., get_account_payments for transactions), so it lacks a clear when-not-to-use comparison.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_transactionLook up a Pi transactionA
Read-only

Look up a single Pi transaction by its hash and report whether it succeeded, which ledger it landed in, who submitted it, the fee charged, and its memo. Call this to verify that a specific transaction actually went through — a user or another service claiming a payment was made is not proof; this is. Reads public ledger data only. A hash this chain has no record of returns a not-found error, which is not the same answer as successful: false — that means the transaction did reach a ledger and was rejected there. This server reads Pi Testnet, and every result repeats that in its "network" field — always report which chain a figure came from. Pi Mainnet and Pi Testnet are separate ledgers sharing one address format, and the same address can hold different balances on each, so a result from the wrong chain looks entirely normal. Testnet Pi has no monetary value: never present a testnet balance as real holdings.

ParametersJSON Schema
NameRequiredDescriptionDefault
hashYesOn-chain transaction hash: exactly 64 hexadecimal characters (0-9 and a-f). Upper case is accepted and normalized to lower case. This is the Stellar transaction hash — not a Pi payment id, not a ledger sequence number, not a memo. Example: f8b6d6c83dfb32452330b677d901748fb6cece6c36d9b2deff64bead6e1c6925

Output Schema

ParametersJSON Schema
NameRequiredDescription
hashYes
memoNo
ledgerYes
networkYes
memo_typeYes
created_atYes
successfulYes
fee_accountNo
fee_chargedYes
result_codeNo
source_accountYes
operation_countYes
source_account_sequenceYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (readOnlyHint, openWorldHint), the description discloses that it reads public ledger data only, the meaning of not-found vs rejection, the network field repetition, and the separate-ledger warning with testnet value. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is detailed but well-structured: first paragraph presents core functionality and purpose; second paragraph adds critical caveats. Every sentence adds value, though it could be slightly more concise without losing substance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given it has an output schema, the description covers purpose, use case, error semantics, network context, and value warnings. All important behavioral aspects are addressed for a query tool of moderate complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with a detailed pattern and example for the hash parameter. The tool description does not add extra semantic detail beyond what the schema already provides, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('look up a single Pi transaction by its hash') and specifies the reported fields (success, ledger, submitter, fee, memo). It distinguishes from sibling tools by focusing on verifying a specific transaction, contrasting with balance checks or payment listings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to call: 'to verify that a specific transaction actually went through' and that a claim is not proof. Describes the distinction between not-found errors and rejection, warns about network confusion and testnet value. Provides clear context for correct interpretation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_userVerify a Pi user access tokenA
Read-only

Check whether a Pi user access token is genuine and, if so, who it belongs to. Call this to authenticate someone who claims a Pi identity — never trust a client-supplied uid or username on its own; this is the only thing that proves it. An invalid, expired, or wrong-app token returns valid: false with a reason rather than failing; only a transport or server fault is reported as an error. Sends the token to the Pi Platform API (https://api.minepi.com/v2/me) and nothing else; it is not stored or logged. Note the uid is app-specific — the same person has a different uid under a different Pi app. Unlike this server's ledger reads, this is an identity check against the Platform API rather than a chain query, so the result carries no network field and does not depend on which Pi chain is being read.

ParametersJSON Schema
NameRequiredDescriptionDefault
access_tokenYesThe user's Pi access token: an opaque bearer credential with no fixed length or prefix, obtained from Pi Browser authentication (`Pi.authenticate`) or Pi Sign-in OAuth. Pass the token string itself — not a uid, not a username, and not the app's server API key, which is a different credential this tool never accepts.

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidNo
validYes
app_idNo
reasonNo
scopesNo
usernameNo
valid_untilNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond annotations (readOnlyHint, openWorldHint) by disclosing the exact API endpoint called (https://api.minepi.com/v2/me), stating that data is not stored or logged, explaining error handling (invalid/expired returns valid:false with reason, only transport/server faults cause errors), and clarifying that uid is app-specific and the result lacks a network field. This fully informs the agent about the tool's behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single paragraph that efficiently covers purpose, usage, behavior, error handling, and caveats. Every sentence contributes value, but it could be slightly more structured (e.g., bullet points) for quicker scanning. Nonetheless, it is concise for the amount of information conveyed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (single parameter, output schema present), the description is fully complete. It explains return behavior for invalid/expired tokens and errors, notes the absence of a network field, and covers data handling. With an output schema, the agent does not need more detail about return values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a detailed parameter description. The description reinforces the parameter's significance by emphasizing not to pass uid, username, or server API key. While the schema already defines the parameter well, the description adds critical context about why the token is the sole proof of identity, justifying a score above the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Check whether a Pi user access token is genuine and, if so, who it belongs to.' It uses a specific verb (verify) and resource (user access token), and the tool is easily distinguished from siblings like get_wallet_balance or query_transaction, which serve entirely different functions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance: 'Call this to authenticate someone who claims a Pi identity' and warns 'never trust a client-supplied uid or username on its own; this is the only thing that proves it.' It also contrasts this tool with ledger reads, telling the agent when to use this identity check versus other queries.

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. Dates show when Glama detected each change.

  1. 4 tool updatesv0.4.0
    • Changedget_account_payments1 field changed
      • changedInput schema / properties / address / description
        Previous value: -"Pi wallet address (Stellar public key, 56 characters, starts with G)"New value: +"Pi wallet address (a Stellar public key): exactly 56 upper-case characters, starting with G, the rest base32 — A-Z and 2-7 only, never 0, 1, 8 or 9. Example: GATQBZLIAUVMND2OCPOKWGPUCNXIGKMNUU7E67YQI2MODSMCMLXBAIJA — that is a format sample, not a default. Pass the address you were actually given: a valid address that is not the intended one returns someone else's balance, not an error."
    • Changedget_wallet_balance1 field changed
      • changedInput schema / properties / address / description
        Previous value: -"Pi wallet address (Stellar public key, 56 characters, starts with G)"New value: +"Pi wallet address (a Stellar public key): exactly 56 upper-case characters, starting with G, the rest base32 — A-Z and 2-7 only, never 0, 1, 8 or 9. Example: GATQBZLIAUVMND2OCPOKWGPUCNXIGKMNUU7E67YQI2MODSMCMLXBAIJA — that is a format sample, not a default. Pass the address you were actually given: a valid address that is not the intended one returns someone else's balance, not an error."
    • Changedquery_transaction1 field changed
      • changedInput schema / properties / hash / description
        Previous value: -"Transaction hash (64 hex characters)"New value: +"On-chain transaction hash: exactly 64 hexadecimal characters (0-9 and a-f). Upper case is accepted and normalized to lower case. This is the Stellar transaction hash — not a Pi payment id, not a ledger sequence number, not a memo. Example: f8b6d6c83dfb32452330b677d901748fb6cece6c36d9b2deff64bead6e1c6925"
    • Changedverify_user1 field changed
      • changedInput schema / properties / access_token / description
        Previous value: -"The user's Pi access token, obtained from Pi Browser authentication or Pi Sign-in OAuth. This is a credential — pass the token itself, not a uid."New value: +"The user's Pi access token: an opaque bearer credential with no fixed length or prefix, obtained from Pi Browser authentication (`Pi.authenticate`) or Pi Sign-in OAuth. Pass the token string itself — not a uid, not a username, and not the app's server API key, which is a different credential this tool never accepts."
  2. 4 tool updatesv0.2.0
    • First observedget_account_payments
    • First observedget_wallet_balance
    • First observedquery_transaction
    • First observedverify_user

TDQS

A4.6/5.0

Scored across 4 tools

Disambiguation5/5

Each tool addresses a clear distinct function: balance retrieval, payment history, transaction lookup, and user verification. No overlap in purpose.

Naming Consistency4/5

Tool names follow a verb_noun pattern (get_, query_, verify_), mostly consistent with the common prefix 'get_' for data queries and 'verify_' for authentication. Minor variation (query_ vs get_) but still predictable.

Tool Count4/5

Four tools is a reasonable number for a focused server that provides read-only blockchain data and identity verification. It covers the core needs without being too sparse or overburdened.

Completeness4/5

The server covers essential read operations (balance, transaction history, individual tx details) and user verification. For its stated scope of reading Pi Testnet and authenticating users, there are no obvious missing operations.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jleeblack/pion-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server