Back to Browse

Stellar Agent Search MCP Server

Developer ToolsUse Caution4.8MCP RegistryLocal
Free

Server data from the Official MCP Registry

Discover and rank Stellar 8004 agents with a read-only MCP server and fail-closed contract probes.

About

Discover and rank Stellar 8004 agents with a read-only MCP server and fail-closed contract probes.

Security Report

4.8
Use Caution4.8High Risk

This is a well-architected MCP server with strong security boundaries. The core server (src/) is read-only and keyless by design, properly isolating sensitive operations from the discovery layer. The examples/x402-demo.ts file appropriately handles secrets with proper redaction, env-var controls, and child-process isolation. Minor code quality issues and overly broad error handling do not materially impact security posture. Supply chain analysis found 9 known vulnerabilities in dependencies (2 critical, 2 high severity). Package verification found 1 issue.

4 files analyzed · 15 issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

HTTP Network Access

Connects to external APIs or services over the internet.

env_vars

Check that this permission is expected for this type of plugin.

File System Read

Reads files on your machine. Normal for tools that analyze or process local data.

File System Write

Writes or modifies files on your machine. Check that this is expected for the tool.

process_spawn

Check that this permission is expected for this type of plugin.

system_info

Check that this permission is expected for this type of plugin.

What You'll Need

Set these up before or after installing:

Stellar network to target: mainnet | testnet. testnet also requires EXPLORER_BASE_URL — the default explorer indexes mainnet only, and the server refuses to start on the mismatched pair.Optional

Environment variable: STELLAR_NETWORK

Override the stellar-8004 explorer API base URL.Optional

Environment variable: EXPLORER_BASE_URL

Override the Soroban RPC URL used for the bounded Reputation-contract probe.Optional

Environment variable: STELLAR_RPC_URL

Set to 'false' to skip the bounded contract probe; reputation fields remain Explorer-declared either way.Optional

Environment variable: VERIFY_ONCHAIN

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-berkingurcan-stellar-agent-search": {
      "env": {
        "VERIFY_ONCHAIN": "your-verify-onchain-here",
        "STELLAR_NETWORK": "your-stellar-network-here",
        "STELLAR_RPC_URL": "your-stellar-rpc-url-here",
        "EXPLORER_BASE_URL": "your-explorer-base-url-here"
      },
      "args": [
        "-y",
        "stellar-agent-search"
      ],
      "command": "npx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

stellar-agent-search

CI npm License: MIT Node MCP

A read-only discovery layer on top of the stellar-8004 registry — the ERC-8004-style Identity/Reputation/Validation contracts on Stellar mainnet. It adds no contracts and forks nothing: it exposes the existing on-chain registry to MCP clients, keeps indexed reputation explicitly declared-vs-verified, and proves the full agent-finds-agent loop with recorded mainnet transactions.

npm · GitHub · Docs · Evidence package

npmMCP RegistryRemote endpointMainnet proof
✅ 0.1.0✅ published & verified⏳ not deployed yet✅ x402 payment · feedback

find_agent, rank_agent and get_agent_profile running live against Stellar mainnet inside Claude Code

There are two official interfaces, not two copies of the stack. TypeScript applications, registration, and signed writes use the canonical @trionlabs/stellar8004 SDK from trionlabs/stellar-8004; MCP clients and terminal discovery use this package, which exact-pins that SDK internally. The upstream repo's restricted Supabase Studio /mcp is database-operator tooling behind SSH/IP controls, not an agent-registry MCP and must never be exposed as this runtime. See the integration boundary.

A read-only, keyless MCP server (and human CLI) that lets an AI agent — or you — discover, rank, and vet on-chain stellar-8004 agents on Stellar mainnet, then prepare an x402 (USDC pay-per-call) payment. One binary speaks the Model Context Protocol over stdio to Claude Code / Cursor / Windsurf / Cline / VS Code, and doubles as a plain-terminal tool. A separate Cloudflare Worker implementation exposes the same surface over stateless Streamable HTTP, but that remote endpoint is not live yet; use the local stdio transport until its deployment canary passes.

npx -y stellar-agent-search@0.1.0 find "a paid web scraper with a good reputation"

AI agents: read AGENTS.md first. It routes each goal to the right document: using the tools, integrating from code, building a service other agents can find and pay (provider guide), or changing this repo. Link index: llms.txt · machine-readable schemas: mcp-surface.json.


Why this exists: declared data vs. what the chain read can prove

Off-chain agent directories (A2A cards, the MCP Registry, OASF, NANDA) list self-declared agents. That is exactly where the trust gap lives. A 2026 study of the ERC-8004 ecosystem (arXiv 2606.26028) found that only 3–15% of registrations have a live endpoint, and 59–91% of "reviewers" are Sybils.

stellar-8004 is the only non-EVM ERC-8004 implementation we are aware of running on mainnet (66 agents on Stellar mainnet as of July 2026; get_registry_stats returns the current count). No published survey enumerates non-EVM deployments — the study above restricts itself to Ethereum, BSC and Base, "the three chains with the highest registration and feedback volume" — so read that as unrefuted, not as proven. This server adds something a directory listing cannot give you: a bounded Reputation-contract reachability probe. The current path calls get_clients_paginated once with a six-slot observation window. The contract exposes no authoritative client count/cursor, and expired client-index entries create holes, so even an empty or short page cannot prove that no later live client exists. Calling get_summary over that set would manufacture a false match or mismatch; this release therefore does not call it and verifies no reputation fields. An attempted, reachable probe returns unavailable with reason client-set-exhaustion-unprovable; verifiedFields is empty and average, feedback count, and unique clients all remain unverified. verified/partial/mismatch are reserved for a future authoritative aggregate. The full status set remains verified | partial | mismatch | unavailable | skipped. Self-declared marketing text (name, description, service labels, feedback tags) remains untrusted data, never instructions (see Security).

That fail-closed boundary — plus a versioned declared-evidence heuristic — is the product. Normalized Explorer quality is multiplied by fixed evidence strength (0.4 × capped volume + 0.6 × effective breadth). Effective unique clients cannot exceed feedback rows, and repeated rows per declared client are capped. These are cost-of-manipulation proxies, not chain verification, proof of personhood, or Sybil resistance.


What it exposes

All three MCP primitives, all read-only:

Tools

TierToolWhat it does
0 · SOWfind_agentNatural-language discovery → ranked candidates
rank_agentRank an explicit id set or a query, full 3-axis declared-reputation breakdown + bounded chain reachability
get_agent_profileDeep profile: identity, capabilities, declared reputation + contract-probe limits, recent feedback, unverified A2A projection
list_servicesSelf-declared x402/MPP endpoint candidates; liveness, ownership, conformance, and payment stay unverified
1 · complete-corelist_agentsPaginated, filterable listing, ranked
leaderboardTop agents in a bounded scan (client-side 3-axis rank + coverage)
resolve_agentAny handle (id / stellar:…#id / owner G-address) → canonical identifiers
get_agents_by_ownerCurrent owner API page (up to 20 agents) with explicit continuation coverage
get_agent_feedbackRecent on-chain reviews (sanitized, labeled)
verify_reputationFail-closed Reputation-contract reachability probe; no current fields are verified
get_agent_cardDerived, unverified A2A-shaped projection + x402 hint; not protocol-conformance proof
get_registry_statsExact-count queries + capped sampled metrics, with definitions and coverage
get_registry_healthPer-registry indexer staleness
2 · provider networkget_provider_manifestA Provider Standard v1 provider's prices in USDC, network, payee and result retention; its binding to the on-chain registration and wallet; conformance badges from trusted validators

Full per-tool reference (inputs, outputs, defaults): docs/tools.md.

Resources — stellar8004:// (pinnable context)

registry · leaderboard · health · agent/{id} · agent/{id}/card · agent/{id}/feedback · agent/{id}/reputation · owner/{address}. Each returns a dual JSON + rendered-markdown payload.

Prompts — slash workflows

/find-and-vet-agent (flagship) · /vet-agent · /compare-agents · /prepare-x402-call · /explore-registry. prepare-x402-call lays out the exact x402 flow and stops before signing — this server holds no keys.


Quickstart

One-command MCP setup (Claude Code):

npx -y stellar-agent-search@0.1.0 setup --client claude --scope user --handshake

This downloads the package, registers a version-pinned npx -y stellar-agent-search@0.1.0 mcp stdio launch through Claude Code's own CLI, then performs a real MCP initialize + tools/list handshake. It is idempotent: rerun with --check --handshake to verify without changing config, or use --dry-run to preview the registration. Cursor and Codex examples, config paths, and scope limitations are in docs/getting-started.md. Manual configs for other clients remain in docs/integration.md.

Optionally install the skill first — the usage guide your agent reads before it calls anything:

npx skills add berkingurcan/stellar-agent-search --skill mcp

Terminal (human CLI):

npx -y stellar-agent-search@0.1.0 find "web scraper" --x402       # discover
npx -y stellar-agent-search@0.1.0 profile 10                       # full profile for agent 10
npx -y stellar-agent-search@0.1.0 rank "scraping agents" --json    # rank + fail-closed contract-probe status, machine-readable
npx -y stellar-agent-search@0.1.0 services --x402                  # declared paid-endpoint candidates
npx -y stellar-agent-search@0.1.0 doctor                           # self-check: env, explorer, RPC, bounded read path
npx -y stellar-agent-search@0.1.0 setup --client cursor --scope project --dry-run  # preview client config

New here? Start with docs/getting-started.md.

Remote endpoint status

The intended hosted URL is https://mcp.stellar8004.com/mcp. The Worker, transport tests, routing, and hardening are implemented, but the route has not been deployed: /mcp currently falls through to the landing site and returns 404. Deployment remains deliberately blocked until the Cloudflare rate-limit namespace is replaced from its sentinel value and a live canary proves that the original caller identity is preserved through the Service Binding. Do not configure a remote MCP client against that URL yet.

The landing page and MCP runtime are separate Workers. The assets-only landing Worker owns the mcp.stellar8004.com custom domain; exact /mcp and /healthz zone routes will send only those two paths to the runtime Worker. The runtime reads the existing stellar8004-web API through a Cloudflare Service Binding. It does not connect to Supabase, hold a service-role key, or create a second indexer. See docs/architecture.md and docs/stellar8004-integration.md.


Configuration

All configuration is via environment variables (canonical for MCP mode); CLI flags override them (precedence: flag → env → default).

Env varDefaultPurpose
STELLAR_NETWORKmainnetmainnet or testnet. With no other data source set, testnet reads its newest agents straight from the Identity contract, see below
EXPLORER_BASE_URLhttps://stellar8004.com on mainnetExplorer HTTP API base. Indexes mainnet only, so testnet never falls back to it
REGISTRY_AGENT_IDS—Registry mode over an allowlist: comma-separated agent ids (at most 50) read straight from the Identity contract, no explorer. Not combinable with EXPLORER_BASE_URL or REGISTRY_SCAN_LIMIT
REGISTRY_SCAN_LIMIT50 on testnetRegistry mode over the newest agents: how many (1–50) of the most recently registered agents lists and searches read. Testnet's default source; set it on mainnet to use it there instead of the explorer. Not combinable with EXPLORER_BASE_URL or REGISTRY_AGENT_IDS
TRUSTED_VALIDATORS—Comma-separated G… or C… addresses (at most 20) of the verifiers whose Validation Registry records earn Provider Standard badges. Empty: the registry is not read
STELLAR_RPC_URLhttps://mainnet.sorobanrpc.comSoroban RPC for the bounded Reputation-contract reachability probe and the Identity and Validation reads
VERIFY_ONCHAINtrueSet false to skip the probe; reputation remains declared-only either way
RANK_SCORE_MAX100Fixed v1 compatibility assertion; any value other than 100 is rejected

Ranking uses the fixed, versioned stellar-agent-search-declared-evidence-v1 policy: indexed average normalized against exactly 100, multiplied by 0.4 × capped volume + 0.6 × effective breadth. Both a changed RANK_SCORE_MAX and legacy RANK_W_* variables are rejected so a deployment cannot silently redefine published score semantics.

STELLAR_PRIVATE_KEY is intentionally ignored if present (and warned about on stderr) — this server is keyless by construction.

testnet reads testnet, and works with no other setting. The default explorer indexes mainnet only, while STELLAR_NETWORK also selects the Soroban contracts and RPC, so testnet never uses it: that would give you mainnet registry rows alongside testnet on-chain reads, two chains described as one. With no data source set, STELLAR_NETWORK=testnet turns on registry mode over the newest 50 agents of the testnet Identity contract (below). You can instead set:

  • EXPLORER_BASE_URL, pointing at a testnet indexer you run,
  • REGISTRY_AGENT_IDS, to read only the agents you name, or
  • REGISTRY_SCAN_LIMIT, to read fewer of the newest agents.

The dry-run gate for the x402 demo is DRY_RUN=1 on mainnet, which spends nothing.

Registry mode (no indexer)

No public testnet indexer exists, so the server reads agents straight from the Identity contract instead. Registry mode is unreleased (not in 0.1.0), so run it from a checkout for now:

npm ci && npm run build
STELLAR_NETWORK=testnet node dist/index.js find "inference"                         # the newest 50 agents
STELLAR_NETWORK=testnet REGISTRY_AGENT_IDS=12,40 node dist/index.js find "inference"  # only these agents

It reads one of two scopes:

  • The newest agents (testnet's default; REGISTRY_SCAN_LIMIT, 50 unless set). The contract assigns agent ids in order from 0 and cannot delete one, so its total_agents count names the newest: ids count − 50 to count − 1, read newest first. An agent that registered a moment ago is found by the next search. Any older agent can still be read by id (profile, rank_agent ids, get_provider_manifest).
  • An allowlist (REGISTRY_AGENT_IDS): only the agents you list, and nothing else.

For each agent it reads the URI, wallet and owner from the Identity contract (keyless simulations), then decodes the registration file the URI points at into the same profile the explorer path builds: a data: URI, or an https: URL on a public host (no redirect, 10 s, 64 KiB). Rows are cached for a minute, the agent count for 30 s, and a registration that could not be read is not fetched again for a minute either.

Works over the allowlist or the newest agents (filters applied locally)Needs an indexer — returns INDEXER_REQUIRED
find_agent, list_services, list_agents, rank_agent, get_agent_profile, get_agent_card, verify_reputation, get_provider_manifestleaderboard, get_registry_stats, get_registry_health, get_agents_by_owner, get_agent_feedback, resolve_agent for an owner address, a minExplorerScore filter (an argument, or a stated number like "score above 70")

What registry mode cannot know, it says. Coverage is never complete: an allowlist carries registry-allowlist-only; a scan that stopped short of agent 0 carries registry-newest-agents-only and says how many agents exist in registryAgentCount. Agents it could not read are listed in unreadableAgentIds. There is no indexed reputation, so results carry source: { kind: "registry", scope, reputationIndexed: false }: scores, feedback counts and unrated reflect missing data, not an agent without feedback. A query word like "best" or "trusted", which implies a minimum score on mainnet, is not applied as a filter here; coverage carries implied-score-filter-not-applied and the summary says so. Agents registered with provider-kit register show their manifest URL in list_services as an unverified stellar-agent-services service entry, marked providerStandard: true.

Searches match a provider's services. In registry mode, an agent whose registration names a Provider Standard manifest is also matched against that manifest's services (name, title, description and tags), if the manifest is bound to it ([I1]–[I3]) and its registration text did not already match. A search reads at most 10 manifests, newest agents first, through the same guarded reader as get_provider_manifest (public HTTPS, no redirect, 256 KiB, 5 s), and lists any it could not read in unsearchedManifestAgentIds. Every find_agent and rank_agent row says why it matched in match.fields (name, description, registrationServices, manifestServices), with the matching services in a labeled, sanitized slot. Over the explorer only the name and description are matched: its v1 list omits services[], and the hosted Worker fetches no registrant-chosen URL.

Provider Standard providers (find → approve → pay)

Provider Standard v1 providers publish a manifest with their services, prices and payee, and name it in their registration. get_provider_manifest (CLI: manifest <id>) reads it for one agent and returns:

  • Terms: each service's price in USDC, the network, payTo, the charge mode (on-success or upfront) and how long results stay collectable for job recovery. These are checked against the standard; a manifest whose payment terms can't be read exactly is invalid and shows no price at all.
  • Identity ([I1]–[I3]): the on-chain registration names this manifest, the manifest names this agent, and payTo is the agent's on-chain wallet. identityBound is true only when all three pass. Over the explorer the registration is read again from the Identity contract, so the indexer never decides whom a user pays.
  • Conformance: badges (Standard v1, Payment verified, Recovery verified) from the Stellar 8004 Validation Registry, counted only for the verifiers you list in TRUSTED_VALIDATORS, and never for a validator that is the agent's own owner or wallet.

The server stays read-only: a payment client pays from the manifest URL after the user approves, and refuses to sign if the 402 challenge differs from the manifest. A manifest for another network than the server's is refused, so one flow never mixes testnet and mainnet.

STELLAR_NETWORK=testnet REGISTRY_AGENT_IDS=12,40 TRUSTED_VALIDATORS=G... node dist/index.js manifest 12

Security

  • Read-only and keyless. No signer, no write clients, no private keys anywhere under src/. The only keyed actor in the repo is the standalone examples/x402-demo.ts, run under explicit human control.
  • stdout is JSON-RPC only. Every log/diagnostic goes to stderr, so the protocol stream is never corrupted.
  • Trust boundary. Server-authored summary text (content[].text) interpolates only typed/enum/numeric values. All agent-authored free text (names, descriptions, service labels, feedback tags) lives only in labeled selfDeclared slots of the structured output, sanitized (control/zero-width/bidi stripped) and length-bounded — never treated as instructions.

Full threat model + disclosure policy: SECURITY.md and docs/architecture.md.


How it works

flowchart LR
    A["MCP client<br/>Claude Code · Cursor · Windsurf …"] -- "stdio JSON-RPC" --> B["stellar-agent-search<br/>one Node binary · read-only · keyless"]
    T["Terminal (human CLI)"] --> B
    B -- "HTTP" --> C["ExplorerService<br/>stellar8004.com API · primary data"]
    B -- "Soroban RPC" --> D["ReputationVerifier<br/>bounded reachability probe"]
    C -.indexes.-> E[("stellar-8004 contracts<br/>Stellar mainnet")]
    D --> E

Local MCP client (or terminal) → one Node binary → ExplorerService (stellar8004 HTTP API, primary data) + ReputationVerifier (Soroban RPC, bounded reachability probe) → canonical stellar-8004 contracts on mainnet. Indexed reputation remains explicitly Explorer-declared; the contract probe either reports its limited reachability observation or degrades closed without manufacturing a comparison.

The not-yet-live hosted path adds only an edge adapter: remote client → stateless Cloudflare Worker → existing stellar8004-web service → its canonical Supabase-backed index. The Worker never reads Supabase directly and never owns indexer credentials. It still uses Soroban RPC for the same bounded reachability probe. Architecture, ranking formula, cache boundaries, and the upstream discovery contract are documented in docs/architecture.md.

Built on the split MCP v2 packages (@modelcontextprotocol/server and @modelcontextprotocol/client 2.0.0), Zod 4, @trionlabs/stellar8004, TypeScript ESM, Node ≥ 22. The local stdio handshake currently negotiates protocol 2025-11-25; the remote handler targets the modern stateless 2026-07-28 protocol while retaining a stateless legacy compatibility lane. That is an implementation target, not a live conformance claim until the remote canary is recorded.


Contributing

Reviewing this against a grant or SOW? Start at docs/evidence.md — a deliverable-to-evidence map with verification steps, written to be checked without a technical background.

The proposed continuation is Stellar Agent Search Phase 2. The first phase helps users find agents. Phase 2 will give independent developers a standard way to offer paid services, while wallets and private keys remain outside this read-only search server.

Known open work and release blockers are tracked in issues/, one file per issue.

Bug reports and PRs welcome. Read CONTRIBUTING.md first — it covers the project layout and the four invariants CI enforces (read-only/keyless, stdout-is-JSON-RPC-only, the trust boundary, and degrade-closed verification). Release history lives in CHANGELOG.md.

License

MIT — see LICENSE.

Reviews

No reviews yet

Be the first to review this server!