stellar-copilot-mcp
Provides tools to interact with the Stellar blockchain, including reading account balances, diagnosing transaction failures, and explaining Soroban contract capabilities, with optional unsigned payment proposals.
Click on "Install 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., "@stellar-copilot-mcpWhat tokens does my account hold?"
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.
stellar-copilot-mcp
MCP server for Stellar. Ask an AI assistant what an account holds, why a transaction failed, or what a Soroban contract does — and get an answer in plain language. Optionally, propose payments the user approves in their own wallet.
Holds no keys. Signs nothing. Submits nothing. Reads use public chain data. Transactions are built unsigned and handed to a page the user controls; signing happens in Freighter and nowhere else.
Tools
Tool | Answers |
| "What do I hold?" · "Why can't I spend my whole balance?" · "Is my trustline set up?" |
| "Why did this fail?" — decodes transaction and operation result codes into causes and fixes, and recovers Soroban contract error codes |
| "What can this contract do?" — reads a deployed contract's published interface |
Running the HTTP transport adds three more:
Tool | Purpose |
| Returns a link the user opens in the browser where Freighter lives |
| Whether the wallet connected, and how an approval turned out |
| Builds an unsigned payment and sends it to the user's approval page |
The stdio binary exposes only the three read tools. Pairing needs a server to host the approval page and hold session state, which stdio has neither of.
Related MCP server: StellarMCP
Install
Requires Node 20+.
npm install && npm run buildClaude Code
claude mcp add stellar-copilot -- node /absolute/path/to/stellar-copilot-mcp/dist/index.jsClaude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"stellar-copilot": {
"command": "node",
"args": ["/absolute/path/to/stellar-copilot-mcp/dist/index.js"],
"env": { "STELLAR_NETWORK": "testnet" }
}
}
}Cursor and other local clients take the same command; see their connector docs.
Remote clients (ChatGPT, Gemini)
Remote clients connect over a URL rather than spawning a process, so run the HTTP transport:
npm run start:httpServes MCP at http://127.0.0.1:3000/mcp and a health check at /health. Point your client at
the /mcp URL.
To use it from Claude, ChatGPT, or Gemini you need a public HTTPS URL — those clients cannot
reach localhost. A Dockerfile and fly.toml are included. See DEPLOY.md.
Configuration
Variable | Default | Notes |
|
|
|
| network default | Override for a private Horizon |
| testnet default; empty on mainnet | Required on |
HTTP transport only:
Variable | Default | Notes |
|
| Listen port |
|
| Bind address. Keep it on loopback unless it is behind a reverse proxy. |
|
| Endpoint path |
| localhost variants | Comma-separated. Required when deployed under a real hostname, or requests are rejected with 403. |
| unset | Comma-separated browser origins, if any |
On mainnet you must set STELLAR_RPC_URL. SDF does not operate a public mainnet Soroban RPC
endpoint, so there is no sensible default. Horizon-backed tools (explain_account,
diagnose_transaction) work on mainnet without it; explain_contract needs it and will tell you so
rather than failing at startup.
Try it
npm run inspect # MCP InspectorOr drive it directly:
printf '%s\n%s\n%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"cli","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
| node dist/index.jsDevelopment
npm run typecheck # tsc --noEmit
npm run dev # tsc --watch
npm run build # emit to dist/Two constraints to respect when adding code
stdout is the JSON-RPC channel. Never write to it. All logging goes to stderr — a stray
console.log corrupts the protocol stream, and the failure looks like a client bug.
The HTTP transport is stateless. No session IDs, no shared state — a fresh server per request. Every tool is a pure read, so there is nothing to remember between calls, and stateless means no session table to leak, expire, or scale. It also means POST is the only meaningful method: there is no stream to open and no session to delete.
DNS rebinding protection is on by default. Without it, any web page the user visits could POST
to a server bound on localhost and drive its tools from the browser. Deploying under a real hostname
means adding it to MCP_ALLOWED_HOSTS.
Keep this server read-only. No key material, no signing, no submission. Transaction building and
signing belong behind an independent simulation-and-approval step in a separate deployable
(see ../TECHNICAL-SPEC.md). The boundary is structural, not a policy note.
Decoding contract errors
Contract-defined codes (Error(Contract, #1205)) mean whatever that contract's
#[contracterror] enum says, so they need a protocol table. Pass a protocol hint:
diagnose_transaction(hash: "...", protocol: "blend-v2-pool")Known tables: blend-v1-pool, blend-v2-pool, soroswap-pair — see
src/lib/contractErrorTables.ts.
Tables are keyed by protocol, not contract address, because Blend pools are permissionless: every pool is a separate deployment sharing one error enum, so an address-keyed registry would mean enumerating every pool that will ever exist.
KNOWN_CONTRACTS maps verified addresses to protocols and is intentionally empty. An address
goes in only once confirmed against a published deployment list — a wrong entry would attach a
confident wrong explanation to someone's real failed transaction. Every table must cite the
source and date it was read from; a test enforces this.
Adding a failure explanation
src/lib/resultCodes.ts maps XDR result-code names to a { meaning, fix } pair. Add the code, write
the explanation for someone who has never read the Stellar docs, and say what to do about it.
Contract-defined codes are not in the result XDR, and they are not recoverable from the
historical record either: Horizon 27 returns no transaction meta at all, and public Soroban RPC
nodes leave diagnosticEvents empty. The server recovers them by re-simulating the call, and
says so in its output — simulation runs against current ledger state, so it is evidence rather
than proof of the original error.
Status
Verified against live Stellar testnet on 30 July 2026: clean typecheck under strict +
noUncheckedIndexedAccess, working MCP handshake, correct reserve math on a Friendbot-funded account,
and correct diagnosis of a real failed Soroban contract call.
62 unit tests (including the HTTP transport and the approval page end to end) and 9 live integration tests pass. The pairing flow, independent decoding, and injection blocking are verified in a real browser.
Not yet verified: Freighter signing itself. It is a browser extension, so signTransaction
and the submit path need a machine with Freighter installed. Known gap: KNOWN_CONTRACTS is empty, so
contract errors need an explicit protocol hint until verified deployment addresses are added.
Proposing transactions
Only over the HTTP transport:
PUBLIC_BASE_URL=https://your-host npm run start:httpThe flow:
start_pairingreturns a link. The user opens it where Freighter is installed.The page connects the wallet and reports the address back.
propose_paymentbuilds an unsigned transaction and queues it for the page.The page decodes the XDR itself and shows what it actually does.
The user signs in Freighter. The page submits.
get_pairing_statusreports the outcome.
Why the page decodes it again
The assistant's description of a transaction is treated as an untrusted claim, never as truth. If a prompt injection made the model build a malicious transaction, the model's description of that transaction would be malicious too — so the only thing that catches it is comparing the description against independently decoded reality.
When they disagree, the page shows the mismatch and disables the approve button. A warning a user can click straight past is not a control.
For the same reason, no tool returns a decoded preview to the model. If it could read the decode, it could misreport it, and the user would be approving the model's account of the transaction rather than the transaction. A test asserts no such tool exists.
PUBLIC_BASE_URL must be an origin the user's browser can reach; it is what pairing links point
at. Sessions are in-memory, expire after 30 minutes idle, and hold no key material.
Privacy
The server runs locally, stores nothing, and handles only public blockchain identifiers — never keys or credentials. It queries public Stellar infrastructure (Horizon, Soroban RPC), both of which you can repoint via environment variables. Full policy: PRIVACY.md.
Licence
Apache-2.0
Available Tools
3 toolsdiagnose_transactionExplain why a transaction failedARead-only
Look up a Stellar transaction by hash and explain its outcome in plain language. For failures, decodes the transaction and operation result codes into what actually went wrong and what to do about it. Use this whenever a user asks why a transaction, payment, swap, or contract call failed.
| Name | Required | Description | Default |
|---|---|---|---|
| hash | Yes | The 64-character hex transaction hash to diagnose. | |
| protocol | No | Optional protocol hint used to decode contract-defined error codes, e.g. "blend-v2-pool", "blend-v1-pool", or "soroswap-pair". Needed because permissionless protocols deploy one contract per pool, all sharing one error enum, so the contract address alone cannot identify the protocol. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, covering safety. The description adds behavioral context: it decodes transaction/operation result codes, provides actionable guidance, and explains the need for a protocol hint. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences that front-load the core function and immediately follow with usage guidance. Every word earns its place; no redundant or vague phrasing.
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?
For a read-only diagnostic tool with full schema coverage and no output schema, the description sufficiently conveys the return value ('plain language', 'what to do about it') and the protocol hint's role. It lacks only explicit handling of invalid hashes, but that is not essential here.
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 100%, with detailed descriptions for both 'hash' and 'protocol' including the rationale for the protocol hint. The description does not add new parameter semantics beyond restating the use case, so the baseline 3 applies.
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 uses a specific verb and resource: 'Look up a Stellar transaction by hash and explain its outcome in plain language.' It clearly distinguishes from sibling tools (explain_account, explain_contract) by focusing on transactions, with explicit mention of payments, swaps, and contract calls.
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?
The description explicitly states when to use the tool: 'Use this whenever a user asks why a transaction, payment, swap, or contract call failed.' It does not explicitly name sibling tools as alternatives, but the usage context is clear and the sibling names imply when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_accountExplain a Stellar accountARead-only
Read a Stellar account and explain its state in plain language: XLM balance and how much of it is locked by the reserve, every asset held, trustline limits and authorization status, signers and thresholds. Use this to answer 'what do I hold', 'why can't I spend my full balance', or 'is my trustline set up'.
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Stellar account address (starts with G). Contract addresses (C...) are not accounts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint and openWorldHint, so the description need not repeat safety. It adds value by disclosing that the output is an interpreted explanation (plain language) rather than raw data, and describes the scope (reserve, trustline authorization, etc.). This goes beyond the annotations, though it doesn't cover error cases.
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 exceptionally concise: two sentences front-load the purpose and details, followed by practical example questions. Every word earns its place, and the structure makes it easy to scan.
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?
Given no output schema, the description clearly explains the return content (balance, reserve, assets, trustlines, signers, thresholds). It also covers representative user intents and distinguishes from sibling tools. The single parameter is fully documented in the schema, and the overall context is complete.
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?
The input schema fully describes the only parameter (address) with details about format (starts with G, not C), so schema coverage is 100%. The description adds no extra parameter meaning beyond what the schema provides, making a baseline 3 appropriate.
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 clearly states the tool's purpose: to read and explain a Stellar account's state in plain language. It lists specific details (XLM balance, reserve, assets, trustlines, signers, thresholds) and differentiates from siblings like explain_contract by focusing on accounts. Example questions ('what do I hold') further clarify intent.
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?
The description gives explicit use cases ('Use this to answer...'), which indicates when to use the tool. It does not explicitly mention alternatives or when not to use it, but the account-specific focus and sibling tool names provide clear context. This is close to a 5 but lacks explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_contractExplain a Soroban contractARead-only
Read a deployed Soroban contract's published interface and list the functions it exposes, with parameter names, parameter types, return types, and any documentation the contract author published. Use this before interacting with an unfamiliar contract, or to answer 'what can this contract do' and 'what arguments does this function take'.
| Name | Required | Description | Default |
|---|---|---|---|
| contractId | Yes | Soroban contract address (starts with C). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description reinforces this with 'Read.' It adds useful context that it only shows the published interface, not source code, and that it includes documentation published by the contract author. This goes beyond the basic read-only hint to clarify scope.
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 composed of two efficient sentences. The first states what it does; the second gives usage context. No redundant text or filler; every clause adds value.
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?
For a simple read-only tool with one parameter and no output schema, the description adequately explains what is returned (functions, params, types, docs) and when to use it. Annotations cover safety, leaving no significant gaps.
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?
The schema covers the single parameter (contractId) with a description confirming it's a Soroban contract address. The tool description does not add extra parameter details beyond what the schema already provides, so it meets the baseline for 100% coverage without enhancing semantics.
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 clearly states the tool reads a deployed Soroban contract's published interface and lists its functions, parameters, return types, and documentation. It distinguishes itself from sibling tools (explain_account, diagnose_transaction) by focusing specifically on contract interface discovery.
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?
The description explicitly advises using this tool before interacting with an unfamiliar contract or to answer specific questions about contract capabilities and function arguments. It does not mention alternatives or exclusions, but the context is clear enough given the sibling tools' different purposes.
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.
3 tool updates
v0.1.0- First observed
diagnose_transaction - First observed
explain_account - First observed
explain_contract
TDQS
Each tool addresses a distinct aspect of Stellar (account state, transaction outcomes, contract interfaces), with no functional overlap. An agent can reliably select the correct tool based on the user's question.
All tool names follow a consistent verb_noun pattern in snake_case (explain_account, diagnose_transaction, explain_contract). While the verbs differ, the structural pattern is uniform and predictable.
Three tools is well-scoped for a focused explanatory server. Each tool covers a core need, and the count is within the typical 3-15 range without being too heavy or too thin.
The tools cover the primary explanatory use cases for Stellar: account state, transaction diagnosis, and contract interface. Minor gaps might include explaining specific operations or network-level details, but these are not critical for the stated purpose.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for Gainium — manage trading bots, deals, and balances via AI assistants
MCP server connecting AI agents to non-custodial staking data across 130+ networks.
The OpenZeppelin Stellar Contracts MCP server generates secure smart contracts for the Stellar blockchain based on OpenZeppelin templates. It integrates with AI assistants to automatically enforce OpenZeppelin's security best practices, style rules, and standards at every prompt, enabling developers to create production-ready Fungible Token, Non-Fungible Token, and Stablecoin contracts through AI-driven workflows.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseBqualityDmaintenanceA Model Context Protocol server for integrating AI assistants like Claude Desktop with the Stellar blockchain, enabling wallet connections, token listings, balance queries, and fund transfers.418JavaScriptMIT
- AlicenseAqualityCmaintenanceMCP server for Stellar that provides tools for accounts, payments, XDR, Horizon/Soroban RPC, AMM liquidity, SEP anchors, and Soroban contract operations.2916MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that translates natural language requests into Stellar blockchain CLI commands.137MIT
- AlicenseAqualityBmaintenanceMCP server for Stellar: accounts, payments, XDR, Horizon/Soroban RPC, AMM liquidity, SEP anchors, and Soroban operations. Intended for agents and IDE integrations with strict validation and normalized errors.29MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/kennyrivaldi/stellar-copilot-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server