A Model Context Protocol server that implements a points-based payment system (NP - NANDA Points) with x402 payment protocol support, enabling agent-to-agent transactions, wallet management, and optional tool monetization
The NANDA Points MCP server has 7 tools with basic schemas and descriptions present, but exhibits significant quality gaps. Tool definitions are visible in src/combined-server.ts with Zod schemas for input validation. However, descriptions lack depth (most are 50-100 chars, below the 194-char baseline for production tools), parameter descriptions are minimal, and output schemas are not documented. Error handling provides basic JSON error objects but no recovery guidance. The server accepts string agent_ids without validation or natural identifier support. Three tools (initiateTransaction, setServiceCharge, attachWallet) perform destructive operations but lack toolAnnotations (destructiveHint) or confirmation mechanisms. Payment parameters in getTimestamp use underscored names (_paymentAgent, _paymentTxId) which are non-standard and poorly documented. No per-tool security scopes or audit trail declarations.
Attach a wallet to an agent. If the agent doesn't have a wallet, creates a new one and attaches it. If agent already has a wallet, returns the existing wallet. Returns error if agent does not exist.
Returns NP balance for an agent. Returns error if agent does not exist. This tool is free to use.
Get x402-NP payment requirements for all paid tools. This tool is free to use.
Return receipt for a transaction id. This tool is free to use.
Returns current server timestamp. Requires payment: 1 NP to system.
Transfer NP from one agent to another and record ledger + receipt. Returns error if either agent does not exist. This tool is free to use.
Output schemas not documented. Tools return JSON.stringify() responses with no declared structure (e.g., getBalance returns {agent_id, currency, scale, balanceMinor, balancePoints} but this is inferred, not in the tool definition). LLMs cannot reliably parse or chain results.
Payment parameters use non-standard underscore prefixes (_paymentAgent, _paymentTxId, _paymentAmount) with minimal descriptions ('Payment agent identifier (optional)', etc.). This violates naming conventions and provides no guidance on format, dependencies, or mutual exclusivity. Documentation indicates these are optional but does not explain the scenario where they are used or how the x402-NP system consumes them.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 52 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Set per-call service charge (points) on agent facts. Returns error if agent does not exist.
Destructive operations (initiateTransaction, setServiceCharge, attachWallet) lack toolAnnotations. destructiveHint and idempotentHint are missing, preventing LLM agents from reasoning about safety and retry logic. initiateTransaction can transfer NP but returns no idempotence markers; retrying with identical params risks duplicate transfers.
Error responses return JSON objects with basic fields (error, agent_id) but do not guide recovery. Example: 'AGENT_NOT_FOUND' error for getBalance does not suggest calling a discovery/search tool. Errors lack classification (retryable vs. user-fixable vs. fatal) that LLM agents need to determine next steps.
Parameter descriptions are generic or missing context. 'Agent identifier' (getBalance.agent_id) does not explain format, constraints, or how to obtain valid identifiers. 'Sender agent ID' vs. 'Receiver agent ID' in initiateTransaction lack examples of valid values or references to a lookup mechanism. LLMs must guess how to construct or discover agent_ids.
Tool descriptions are too brief (40-55 chars average vs. 194 baseline). 'Returns NP balance for an agent. Returns error if agent does not exist. This tool is free to use.' for getBalance does not explain when to use it, what the response contains, or how balance units relate to scale/minor-major conversions. No context for LLM tool selection.
initiateTransaction lacks confirmation or dry-run mode for an irreversible operation. The tool transfers NP between agents with no preview or rollback. If an LLM agent misunderstands the intent, the transaction executes immediately. No pattern:confirmation-request implemented.
No permission/scope declarations. Tools do not declare required scopes (e.g., 'read:balance', 'write:transfer', 'admin:service_charge'). No audit trail or logging of who called which tool and when. Agents operating with these tools have no visibility into authorization or compliance requirements.
getPaymentInfo has empty input schema ({}) but no description of what it returns. The description 'Get x402-NP payment requirements for all paid tools. This tool is free to use.' does not explain the response structure or how to use the returned data to call paid tools. Output schema is undocumented.
attachWallet's seedPoints parameter defaults to 1000 (per description) but Zod schema shows z.number() with no explicit default. Discrepancy between documentation and code. No explanation of when to seed, how seedPoints affects wallet behavior, or whether multiple calls are idempotent (attach existing wallet vs. create new one) is unclear.