{
  "markdown": "# stellar-agent-search\n\n[![CI](https://github.com/berkingurcan/stellar-agent-search/actions/workflows/ci.yml/badge.svg)](https://github.com/berkingurcan/stellar-agent-search/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/stellar-agent-search.svg)](https://www.npmjs.com/package/stellar-agent-search)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%E2%89%A522-brightgreen.svg)](https://nodejs.org)\n[![MCP](https://img.shields.io/badge/MCP-SDK%20v2-6E56CF.svg)](https://modelcontextprotocol.io)\n\n> **A read-only discovery layer on top of the [stellar-8004](https://stellar8004.com) registry — the ERC-8004-style Identity/Reputation/Validation contracts on Stellar mainnet.**\n> 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.\n\n[**npm**](https://www.npmjs.com/package/stellar-agent-search) · [**GitHub**](https://github.com/berkingurcan/stellar-agent-search) · [**Docs**](docs/getting-started.md) · [**Evidence package**](docs/evidence.md)\n\n| npm | MCP Registry | Remote endpoint | Mainnet proof |\n|---|---|---|---|\n| ✅ [`0.1.0`](https://www.npmjs.com/package/stellar-agent-search) | ✅ published & verified | ⏳ [not deployed yet](#remote-endpoint-status) | ✅ [x402 payment](https://stellar.expert/explorer/public/tx/de0717ecb5b34b712fd196c8438cb20bff52e4f843fc7b8263e03b1dd5be3c55) · [feedback](https://stellar.expert/explorer/public/tx/10d739713a02ae517bc96b8507d0d6ae28913ccdd7b10484f77e37bf8c740846) |\n\n![find_agent, rank_agent and get_agent_profile running live against Stellar mainnet inside Claude Code](docs/assets/readme-hero.gif)\n\nThere are two official interfaces, not two copies of the stack. TypeScript applications, registration, and\nsigned writes use the canonical [`@trionlabs/stellar8004`](https://www.npmjs.com/package/@trionlabs/stellar8004)\nSDK from `trionlabs/stellar-8004`; MCP clients and terminal discovery use this package, which exact-pins that\nSDK internally. The upstream repo's restricted Supabase Studio `/mcp` is database-operator tooling behind\nSSH/IP controls, not an agent-registry MCP and must never be exposed as this runtime. See\n[the integration boundary](docs/stellar8004-integration.md).\n\nA **read-only, keyless** MCP server (and human CLI) that lets an AI agent — or you — **discover, rank, and\nvet on-chain [stellar-8004](https://stellar8004.com) agents** on Stellar mainnet, then prepare an x402\n(USDC pay-per-call) payment. One binary speaks the [Model Context Protocol](https://modelcontextprotocol.io)\nover stdio to Claude Code / Cursor / Windsurf / Cline / VS Code, and doubles as a plain-terminal tool. A\nseparate Cloudflare Worker implementation exposes the same surface over stateless Streamable HTTP, but that\nremote endpoint is **not live yet**; use the local stdio transport until its deployment canary passes.\n\n```bash\nnpx -y stellar-agent-search@0.1.0 find \"a paid web scraper with a good reputation\"\n```\n\n---\n\n## Why this exists: declared data vs. what the chain read can prove\n\nOff-chain agent directories (A2A cards, the MCP Registry, OASF, NANDA) list **self-declared** agents. That is\nexactly where the trust gap lives. A 2026 study of the ERC-8004 ecosystem (arXiv 2606.26028) found that only\n**3–15% of registrations have a live endpoint**, and **59–91% of \"reviewers\" are Sybils**.\n\nstellar-8004 is the only non-EVM ERC-8004 implementation **we are aware of** running on mainnet (66 agents on\nStellar mainnet as of July 2026; `get_registry_stats` returns the current count). No published survey\nenumerates non-EVM deployments — the study above restricts itself to Ethereum, BSC and Base, \"the three chains\nwith the highest registration and feedback volume\" — so read that as unrefuted, not as proven. This server\nadds something a directory listing cannot give you: a **bounded Reputation-contract reachability probe**.\nThe current path calls `get_clients_paginated` once with a six-slot observation window. The contract exposes\nno authoritative client count/cursor, and expired client-index entries create holes, so even an empty or short\npage cannot prove that no later live client exists. Calling `get_summary` over that set would manufacture a\nfalse match or mismatch; this release therefore does not call it and verifies no reputation fields. An\nattempted, reachable probe returns `unavailable` with reason `client-set-exhaustion-unprovable`;\n`verifiedFields` is empty and average, feedback count, and unique clients all remain unverified.\n`verified`/`partial`/`mismatch` are reserved for a future authoritative aggregate. The full status set remains\n`verified | partial | mismatch | unavailable | skipped`. Self-declared marketing text (name, description,\nservice labels, feedback tags) remains **untrusted data**, never instructions (see [Security](#security)).\n\nThat fail-closed boundary — plus a versioned **declared-evidence heuristic** — is the product. Normalized\nExplorer quality is multiplied by fixed evidence strength (`0.4 × capped volume + 0.6 × effective breadth`).\nEffective unique clients cannot exceed feedback rows, and repeated rows per declared client are capped. These\nare cost-of-manipulation proxies, not chain verification, proof of personhood, or Sybil resistance.\n\n---\n\n## What it exposes\n\nAll three MCP primitives, all read-only:\n\n### Tools\n\n| Tier | Tool | What it does |\n|---|---|---|\n| **0 · SOW** | `find_agent` | Natural-language discovery → ranked candidates |\n| | `rank_agent` | Rank an explicit id set or a query, full 3-axis declared-reputation breakdown + bounded chain reachability |\n| | `get_agent_profile` | Deep profile: identity, capabilities, declared reputation + contract-probe limits, recent feedback, unverified A2A projection |\n| | `list_services` | Self-declared x402/MPP endpoint candidates; liveness, ownership, conformance, and payment stay unverified |\n| **1 · complete-core** | `list_agents` | Paginated, filterable listing, ranked |\n| | `leaderboard` | Top agents in a bounded scan (client-side 3-axis rank + coverage) |\n| | `resolve_agent` | Any handle (id / stellar:…#id / owner G-address) → canonical identifiers |\n| | `get_agents_by_owner` | Current owner API page (up to 20 agents) with explicit continuation coverage |\n| | `get_agent_feedback` | Recent on-chain reviews (sanitized, labeled) |\n| | `verify_reputation` | Fail-closed Reputation-contract reachability probe; no current fields are verified |\n| | `get_agent_card` | Derived, unverified A2A-shaped projection + x402 hint; not protocol-conformance proof |\n| | `get_registry_stats` | Exact-count queries + capped sampled metrics, with definitions and coverage |\n| | `get_registry_health` | Per-registry indexer staleness |\n\nFull per-tool reference (inputs, outputs, defaults): **[docs/tools.md](docs/tools.md)**.\n\n### Resources — `stellar8004://` (pinnable context)\n\n`registry` · `leaderboard` · `health` · `agent/{id}` · `agent/{id}/card` · `agent/{id}/feedback` ·\n`agent/{id}/reputation` · `owner/{address}`. Each returns a dual **JSON + rendered-markdown** payload.\n\n### Prompts — slash workflows\n\n`/find-and-vet-agent` (flagship) · `/vet-agent` · `/compare-agents` · `/prepare-x402-call` ·\n`/explore-registry`. `prepare-x402-call` lays out the exact x402 flow and **stops before signing** — this\nserver holds no keys.\n\n---\n\n## Quickstart\n\n**One-command MCP setup (Claude Code):**\n\n```bash\nnpx -y stellar-agent-search@0.1.0 setup --client claude --scope user --handshake\n```\n\nThis downloads the package, registers a version-pinned `npx -y stellar-agent-search@0.1.0 mcp` stdio launch through\nClaude Code's own CLI, then performs a real MCP initialize + `tools/list` handshake. It is idempotent: rerun\nwith `--check --handshake` to verify without changing config, or use `--dry-run` to preview the registration.\nCursor and Codex examples, config paths, and scope limitations are in\n**[docs/getting-started.md](docs/getting-started.md)**. Manual configs for other clients remain in\n**[docs/integration.md](docs/integration.md)**.\n\nOptionally install the **skill** first — the usage guide your agent reads before it calls anything:\n\n```bash\nnpx skills add berkingurcan/stellar-agent-search --skill mcp\n```\n\n**Terminal (human CLI):**\n\n```bash\nnpx -y stellar-agent-search@0.1.0 find \"web scraper\" --x402       # discover\nnpx -y stellar-agent-search@0.1.0 profile 10                       # full profile for agent 10\nnpx -y stellar-agent-search@0.1.0 rank \"scraping agents\" --json    # rank + fail-closed contract-probe status, machine-readable\nnpx -y stellar-agent-search@0.1.0 services --x402                  # declared paid-endpoint candidates\nnpx -y stellar-agent-search@0.1.0 doctor                           # self-check: env, explorer, RPC, bounded read path\nnpx -y stellar-agent-search@0.1.0 setup --client cursor --scope project --dry-run  # preview client config\n```\n\nNew here? Start with **[docs/getting-started.md](docs/getting-started.md)**.\n\n### Remote endpoint status\n\nThe intended hosted URL is `https://mcp.stellar8004.com/mcp`. The Worker, transport tests, routing, and\nhardening are implemented, but **the route has not been deployed**: `/mcp` currently falls through to the\nlanding site and returns 404. Deployment remains deliberately blocked until the Cloudflare rate-limit\nnamespace is replaced from its sentinel value and a live canary proves that the original caller identity is\npreserved through the Service Binding. Do not configure a remote MCP client against that URL yet.\n\nThe landing page and MCP runtime are separate Workers. The assets-only landing Worker owns the\n`mcp.stellar8004.com` custom domain; exact `/mcp` and `/healthz` zone routes will send only those two paths to\nthe runtime Worker. The runtime reads the existing `stellar8004-web` API through a Cloudflare Service Binding.\nIt does **not** connect to Supabase, hold a service-role key, or create a second indexer. See\n**[docs/architecture.md](docs/architecture.md)** and\n**[docs/stellar8004-integration.md](docs/stellar8004-integration.md)**.\n\n---\n\n## Configuration\n\nAll configuration is via environment variables (canonical for MCP mode); CLI flags override them\n(precedence: flag → env → default).\n\n| Env var | Default | Purpose |\n|---|---|---|\n| `STELLAR_NETWORK` | `mainnet` | `mainnet` or `testnet` — `testnet` also requires `EXPLORER_BASE_URL`, see below |\n| `EXPLORER_BASE_URL` | `https://stellar8004.com` | Explorer HTTP API base. **Indexes mainnet only** |\n| `STELLAR_RPC_URL` | `https://mainnet.sorobanrpc.com` | Soroban RPC for the bounded Reputation-contract reachability probe |\n| `VERIFY_ONCHAIN` | `true` | Set `false` to skip the probe; reputation remains declared-only either way |\n| `RANK_SCORE_MAX` | `100` | Fixed v1 compatibility assertion; any value other than `100` is rejected |\n\nRanking uses the fixed, versioned `stellar-agent-search-declared-evidence-v1` policy: indexed average normalized\nagainst exactly `100`, multiplied by `0.4 × capped volume + 0.6 × effective breadth`. Both a changed\n`RANK_SCORE_MAX` and legacy `RANK_W_*` variables are rejected so a deployment cannot silently redefine\npublished score semantics.\n\n`STELLAR_PRIVATE_KEY` is **intentionally ignored** if present (and warned about on stderr) — this server is\nkeyless by construction.\n\n> **`testnet` needs its own explorer, and refuses to start without one.** The default explorer indexes\n> **mainnet only**, while `STELLAR_NETWORK` also selects the Soroban contracts and RPC. That pairing would give\n> you mainnet registry rows alongside testnet on-chain reads — two chains described as one — so\n> `STELLAR_NETWORK=testnet` **fails at startup** unless `EXPLORER_BASE_URL` is set explicitly. No public testnet\n> indexer exists today, so in practice testnet is for someone running their own; the dry-run gate for the x402\n> demo is `DRY_RUN=1` on mainnet, which spends nothing.\n\n---\n\n## Security\n\n- **Read-only and keyless.** No signer, no write clients, no private keys anywhere under `src/`. The only\n  keyed actor in the repo is the standalone [`examples/x402-demo.ts`](examples/README.md), run under explicit\n  human control.\n- **stdout is JSON-RPC only.** Every log/diagnostic goes to stderr, so the protocol stream is never\n  corrupted.\n- **Trust boundary.** Server-authored summary text (`content[].text`) interpolates only typed/enum/numeric\n  values. All agent-authored free text (names, descriptions, service labels, feedback tags) lives only in\n  labeled `selfDeclared` slots of the structured output, sanitized (control/zero-width/bidi stripped) and\n  length-bounded — never treated as instructions.\n\nFull threat model + disclosure policy: **[SECURITY.md](SECURITY.md)** and\n**[docs/architecture.md](docs/architecture.md)**.\n\n---\n\n## How it works\n\n```mermaid\nflowchart LR\n    A[\"MCP client<br/>Claude Code · Cursor · Windsurf …\"] -- \"stdio JSON-RPC\" --> B[\"stellar-agent-search<br/>one Node binary · read-only · keyless\"]\n    T[\"Terminal (human CLI)\"] --> B\n    B -- \"HTTP\" --> C[\"ExplorerService<br/>stellar8004.com API · primary data\"]\n    B -- \"Soroban RPC\" --> D[\"ReputationVerifier<br/>bounded reachability probe\"]\n    C -.indexes.-> E[(\"stellar-8004 contracts<br/>Stellar mainnet\")]\n    D --> E\n```\n\nLocal MCP client (or terminal) → **one Node binary** → `ExplorerService` (stellar8004 HTTP API, primary\ndata) + `ReputationVerifier` (Soroban RPC, bounded reachability probe) → canonical stellar-8004 contracts on\nmainnet. Indexed reputation remains explicitly **Explorer-declared**; the contract probe either reports its\nlimited reachability observation or degrades closed without manufacturing a comparison.\n\nThe not-yet-live hosted path adds only an edge adapter: remote client → stateless Cloudflare Worker →\nexisting `stellar8004-web` service → its canonical Supabase-backed index. The Worker never reads Supabase\ndirectly and never owns indexer credentials. It still uses Soroban RPC for the same bounded reachability probe.\nArchitecture, ranking formula, cache boundaries, and the upstream discovery contract are documented in\n**[docs/architecture.md](docs/architecture.md)**.\n\nBuilt on the split MCP v2 packages (`@modelcontextprotocol/server` and `@modelcontextprotocol/client`\n2.0.0), Zod 4, `@trionlabs/stellar8004`, TypeScript ESM, Node ≥ 22. The local stdio handshake currently\nnegotiates protocol `2025-11-25`; the remote handler targets the modern stateless `2026-07-28` protocol while\nretaining a stateless legacy compatibility lane. That is an implementation target, not a live conformance\nclaim until the remote canary is recorded.\n\n---\n\n## Contributing\n\nReviewing this against a grant or SOW? Start at **[docs/evidence.md](docs/evidence.md)** — a\ndeliverable-to-evidence map with verification steps, written to be checked without a technical background.\n\nKnown open work and release blockers are tracked in **[issues/](issues/README.md)**, one file per issue.\n\nBug reports and PRs welcome. Read **[CONTRIBUTING.md](CONTRIBUTING.md)** first — it covers the project layout and\nthe four invariants CI enforces (read-only/keyless, stdout-is-JSON-RPC-only, the trust boundary, and\ndegrade-closed verification). Release history lives in **[CHANGELOG.md](CHANGELOG.md)**.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n",
  "bytes": 15392,
  "sha": "6a9aa9d3d3ddc77b345c4093606b320dd26a861ab1793e0eb2bf91806b32a822",
  "repo_slug": "berkingurcan/stellar-agent-search",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_berkingurcan_stellar_agent_sea_2900dfac/readme"
}