gecko-surf

gecko-surf

Projects an Agent Surface (deterministic call graph) for any OpenAPI, enabling LLM agents to make correct, chain-of-calls interactions without guessing.

Category
Visit Server

README

gecko-surf — project the Agent Surface for any API

<!-- mcp-name: tech.geckovision/surf -->

Python 3.11+ uv Claude Code x402 License tests

An OpenAPI tells an agent what endpoints exist. MCP tells it how to invoke one. Neither tells it which calls, in what order, from what data — so the agent guesses, and on a painful API it guesses wrong.

Gecko derives the missing layer: the Agent Surface — the deterministic, provenance-carrying, safety-checked call graph your agent traverses to get the call right the first time. Point it at an API; it projects a surface built for agents, not a Swagger rewritten for them. Free and open source.

We don't hand you an OpenAPI. Unless you don't have one — then we generate one, and the surface above it.

<p align="center"> <img src="docs/assets/hero.gif" alt="One command: install gecko-surf, then project the Agent Surface — a deterministic call graph — for any API" width="820"> </p>

Three layers — Gecko is the one nobody else fills

Layer Answers Format
Shape what endpoints & fields exist OpenAPI, GraphQL
Transport how to invoke one tool MCP
Surface ← Gecko given intent: which chain of calls, in what order, at what confidence, from what basis — and is it safe the Agent Surface

Shape and transport are probabilistic at the moment of use. The Surface is the deterministic answer, so the model doesn't have to guess. Gecko composes on OpenAPI (input) and MCP (transport) — it never replaces them.


Table of Contents

Where Gecko sits — three verbs, three layers

Layer What it does Who
APIs get PAID billing / settlement rail pay.sh
skills get DISTRIBUTED marketplace / discovery frames.ag, Bazaar
APIs get USED comprehension / consumption Gecko

We compose on x402 / MCP / pay.sh. We are not a payment rail or a marketplace.


Try it in 10 seconds

One line, zero install. No pip, no spec, no key — 18 first-call-correct tools on the TxODDS TxLINE World Cup API (two-token on-chain paywall). Recorded demo ($0, schema-synthesized); use your own TxLINE session for live data. Also live: Jito at /jito/mcp, Jupiter at /jupiter/mcp.

claude mcp add --transport http gecko-txline https://mcp.geckovision.tech/txline/mcp

Cursor / VS Code / any MCP client — same endpoint in mcp.json:

{ "mcpServers": { "gecko-txline": { "type": "http", "url": "https://mcp.geckovision.tech/txline/mcp" } } }

Transport is MCP Streamable HTTP (2025-11-25), not SSE — use streamablehttp_client, not sse_client. Ready for your own API? → Make any API agent-usable.

Prefer the CLI? gecko connect txline serves the same surface over stdio and adds an anonymous X-Gecko-Install-Id header (an opaque per-install id — no key, no PII; GECKO_TELEMETRY=off to skip) so distinct installs are countable. The copy-paste config above stays credential-free and header-free.


Open source engine, hosted platform

You just used both. The endpoint above is mcp.geckovision.tech — our hosted layer, running the exact engine in this repo.

This repository is the open-source engine: ingest, catalog, tool generation, the surface graph, the anti-poisoning sanitizer, and the auth seam. Apache-2.0, patent grant included, no feature gates. Clone it, embed the SDK, self-host the MCP server — that path is complete and stays free.

The hosted platform is where an API stays live for agents without you operating anything: comprehended surfaces served over Streamable-HTTP MCP, credentials injected at call time (never in mcp.json), per-surface key gating for paid and private APIs, and first-call-correctness suites that run against the surface as it drifts.

Who pays: API providers, to keep their surface live, correct, and agent-reachable — a flat price per API, never a cut of your calls. Developers never pay. Gecko takes no percentage, holds no funds, and settles nothing; when money moves it moves over x402 between the agent and the provider, and we are not in the path.

That split is the whole business model: the engine is open because distribution is the point, and the hosted layer is what a provider buys. → docs.geckovision.tech


Watch it run

The 70-second launch demo:

<div align="center">

Gecko 70s launch demo — 18 first-call-correct TxODDS tools; redteam blocks 8/8 poisoned attacks; gecko test 32/32 checks

MP4 version

</div>

Every number from a real run:

  • Plug in TxODDS → 18 first-call-correct tools, recorded/$0 first call (live when subscribed).
  • Stay safe → poisoned-spec attacks that hit a naive agent 8/8 are blocked 0/8.
  • Stay correctgecko test writes 32/32 first-call-correctness checks for CI.

What you'd actually type

Gecko's surfaces take the question, not the endpoint. Once a surface is added, these are literal prompts:

Which fixtures kick off in the next hour, and what are the current odds?
Get me live odds updates for tomorrow's Brazil match
What's the price of this token and its 24h volume?
Show me Jito's current tip floor before I send this bundle

The second one is the interesting case. GET /api/odds/updates/{fixtureId} needs a fixtureId the agent doesn't have — so Gecko returns a chain, not a 404:

1. GET /api/fixtures/snapshot     # supplies fixtureId
2. GET /api/odds/updates/{fixtureId}

Onboarding your own API is the same shape — a sentence, not a config file:

/make-agent-ready https://api.example.com/openapi.json
gecko test https://api.example.com/openapi.json     # first-call-correctness suite
gecko from-docs https://docs.example.com/api        # no spec? recover a draft one

Architecture

Control plane, never data plane. Gecko holds the API surface, tool defs, and correctness metadata — never response payloads, user data, or secrets. That invariant is what lets it ingest any API unilaterally.

<div align="center">

Gecko architecture — agent intent → ingest/catalog/tools/access control plane → agent calls the real API directly

Interactive diagram · SVG

</div>

  1. Ingest — OpenAPI 3.x → normalized ops/params (never response data).
  2. Catalog — intent → endpoint (lexical at this scale).
  3. Tools — question-shaped defs; auth headers hidden.
  4. Access — subscribe/session via one seam: Session.auth_headers().
  5. Call — agent hits the real API; Gecko injects credentials, stays off the data path.
  6. Validate — replay, confirm first-call-correct, JSONL log → V2 correctness corpus seed.

What you get

Surface Entry point Status
Serve any API to agents (paste a spec → hosted MCP + one-click "add to Claude/Cursor") gecko serve <openapi-url> (or bare gecko <openapi-url>) shipped
Generate + run first-call-correctness tests (before any live call) gecko test <openapi-url> [-o test_api.py] shipped
Recover a draft OpenAPI from human docs (no spec? point it at the doc page) gecko from-docs <doc-url-or-path> [-o draft.json] shipped
Embed the SDK (search / list_tools / prepare / call) from gecko import AgentApiClient shipped
Cross-API chains (join two surfaces on a declared entity) gecko.compose.cross_plan shipped
Forkable starter (an app on any API, ~20 lines, $0) examples/_starter/ shipped
$0 recorded demo (goal → discover → correct call → data, offline) python -m gecko.demo runnable now
Live demo against real TxODDS World Cup data gecko.demo:live_demo (after subscribe) mainnet-proven
Correctness harness (first-call-correct + flywheel log) gecko.validator shipped

The surface graph

Intent → the right chain of calls. Real questions rarely map to one endpoint. "Get live odds updates" needs a fixtureId — so Gecko plans a chain from the spec alone (no call logs, no training data):

agent intent: "get live odds updates"

plan:
  1. GET /api/fixtures/snapshot              # supplies fixtureId
  2. GET /api/odds/updates/{fixtureId}
explain:
  fixtureId ← FixtureId   [INFERRED · entity:fixture · high]

Spec-derived with provenance on every edge (EXTRACTED / INFERRED / DECLARED plus confidence). Plans are suggestions — your agent still makes every call. Measured offline: Stripe control cut false links 66,984 → 337 (−99.5%) while finding every known chain on a paywalled API — see docs/benchmarks.md. On by default in search_capabilities.

See it — graphviz for APIs. gecko graph svg <spec> renders the Surface: operations as nodes, feeds edges as arrows colored by provenance (emerald = DECLARED, amber = INFERRED). Deterministic, self-contained, structure-only (no payloads). This is a real render of the TxLINE surface:

<p align="center"> <img src="docs/assets/surface-txline.svg" alt="The TxLINE Agent Surface: operations as nodes, feeds edges as provenance-colored arrows — the deterministic call graph an agent traverses" width="820"> </p>

from gecko import Surface
Surface.from_spec("https://api.example.com/openapi.json").render_svg()  # -> SVG string

Chains cross APIs too. Two surfaces never merge into one graph; they join only on a DECLARED entity the provider vouches for, so a name collision can't invent a link between unrelated APIs — design. What's next (body-carried join keys, semantic tiebreak, live validation) is in the correlation roadmap.


Make any API agent-usable

Point at an OpenAPI — no client code, auth handled, first call correct.

A · Claude Code — Marketplace plugin (skills + live demo surface):

/plugin marketplace add GeckoVision/gecko-surf
/plugin install gecko-surf@geckovision
/make-agent-ready https://api.example.com/openapi.json

Wires gecko-txline plus /make-agent-ready, /setup-x402, and anti-poisoning.

B · Everywhere else — CLI (Cursor, VS Code, any framework):

uvx --from "gecko-surf[serve]" gecko <openapi-url>

Prefer uvx (nothing to verify). Or prove the installer first with scripts/verify_install.py, then curl -fsSL https://get.geckovision.tech/install.sh | bash.

gecko <url> prints the MCP URL and one-click add links (Cursor / VS Code / raw). Claude Code → Marketplace; everything else → CLI. You don't need both.

Or embed the SDK — derive the Surface, then read it:

from gecko import Surface, public_session

surface = Surface.from_spec(spec, session=public_session())

surface.graph                       # the call graph: nodes + provenance-tagged edges
surface.plan("get live odds")       # the deterministic chain for an intent (+ explain)
surface.safety.clean                # anti-poisoning verdict (untrusted-spec defense)
surface.project("llms.txt")         # one artifact, N projections (gecko.json, SKILL.md, …)

Still want the call layer? Surface.client is the AgentApiClientsearch / list_tools / prepare / call.

Forkable starter: examples/_starter/ (~20 lines, $0). Full agent: examples/sos_vzla_bot/.

Registry surfaces

gecko serve --registry colosseum --auth-env COLOSSEUM_COPILOT_PAT

Free surfaces need no account. Premium: GECKO_API_KEY via POST /registry/keys → OTP → gk_live_... (shown once; we store a salted hash). Your provider key stays local — Gecko never sees it.

Alongside Context7

Context7 tells the agent what to call; Gecko proves it's right before the call fires and chains the calls Context7-fed agents get wrong. Register both MCP servers side by side — the copy-pasteable mcp.json and the gecko verify-docs note are in docs/context7-integration.md. We compose Context7 as a docs input; we don't replace it.


Develop offline

$0, no keys, no subscription:

git clone https://github.com/GeckoVision/gecko-surf
cd gecko-surf && uv sync
uv run pytest                       # 1,630 passing
uv run python -m gecko.demo         # E2E: goal → discover → correct call → data (recorded, $0)

The recorded demo runs the same code path as live — it just synthesizes responses from the schema instead of hitting the network. That's the point: you can falsify the comprehension offline before spending a cent.


Going live

Real World Cup data. Recorded mode needs no subscription. For live data, do the one-time on-chain subscribe — see scripts/SUBSCRIBE.md — then pass a real Session:

from gecko.client import AgentApiClient
client = AgentApiClient(spec, base_url="https://...", session=my_session)
client.call(tool, args, mode="live")   # same path as recorded

Mainnet boundary: the subscribe transaction is founder-run only. The tooling simulates (no spend) and hands over the exact command; a human broadcasts.


What's in this repo

Path Purpose
gecko/ingest.py OpenAPI 3.x → normalized Operation/Param ($ref resolution, guarded)
gecko/catalog.py Lexical capability search (intent → endpoint)
gecko/tools.py Operation → question-shaped agent tool defs (auth hidden)
gecko/caller.py tool + args → correct PreparedRequest (stdlib urllib)
gecko/graph.py The surface graph — entities, edges, provenance, chain planning
gecko/compose.py Cross-API chains — per-surface graphs joined on DECLARED entities only
gecko/sanitize.py Anti-poisoning — untrusted spec/doc text, fail-closed arg routing
gecko/access.py Session.auth_headers() — the engine/adapter seam; two-token session
gecko/sample.py deterministic schema → example (powers $0 recorded mode)
gecko/client.py AgentApiClientsearch / list_tools / prepare / call
gecko/mcp_server.py McpSurface — the agent-facing MCP surface
gecko/validator.py replay + first-call-correct + JSONL outcome log (moat seed)
gecko/demo.py run() (recorded) + live_demo()
gecko/serve.py gecko <url> CLI — comprehend + serve over Streamable-HTTP MCP (+ one-click add)
examples/_starter/ forkable "app on any API" (engine-only, $0); examples/sos_vzla_bot/ is the full LLM agent
scripts/subscribe.py one-time on-chain subscribe (solders); simulate by default
docs/ · private/ strategy & PRD · gitignored business docs (canvas, pitch, numbers)

Rule: the comprehension logic is the product and lives in gecko/. The MCP server, the client, and scripts are thin transport.


Stack

Layer Tool
Language Python 3.11+, managed with uv
Engine stdlib-first (urllib); minimal deps; pyyaml for spec loading
Agent surface mcp (Model Context Protocol)
Access / payments x402; on-chain subscribe via solders; modes stub / live
Quality ruff · mypy · pytest (1,630 tests)

Environment variables

Source of truth: .env.example.

Variable Required Default Notes
X402_MODE no stub stub / live. Stub is intentional during user-testing — do not flip to live without founder go-ahead.
TXODDS_* / session file for live only live World Cup access after the on-chain subscribe (see scripts/SUBSCRIBE.md)

Recorded mode and the test suite need no keys.


Development

uv run ruff format && uv run ruff check --fix
uv run mypy gecko
uv run pytest                       # 1,630 passing; targeted invocations preferred
uv run python -m gecko.demo         # $0 recorded smoke

See CLAUDE.md for the architecture invariants, the subagent team, and conventions.


FAQ

General

<details> <summary><strong>Isn't this just a better MCP wrapper?</strong></summary>

A wrapper is a snapshot: someone hand-writes tool defs from a spec, and they go stale on the next API change. Gecko is the generator, plus three things a wrapper doesn't have: the surface graph (a question that needs two calls gets a chain with provenance, not a 404), anti-poisoning (the spec is untrusted input, and a poisoned tool loses auth injection), and the auth seam (credentials are injected at call time, so the tool def never carries a key). Re-point at the spec and the tools regenerate; a wrapper needs a human.

</details>

<details> <summary><strong>Which APIs is this actually for?</strong></summary>

The painful ones. A coding agent already one-shots Stripe — it has seen Stripe a million times. It does not one-shot a long-tail API with drifting docs, an odd auth handshake, or a paywall in front of the spec. That's the wedge. If your agent already calls your API correctly, you don't need Gecko.

</details>

<details> <summary><strong>Does the agent call through Gecko?</strong></summary>

No. Gecko hands the agent a correct, credentialed request; the agent calls the API directly. We are the control plane, never the data plane — see Architecture.

</details>

<details> <summary><strong>What if my API has no OpenAPI spec?</strong></summary>

gecko from-docs <doc-url> recovers a draft spec from human documentation. It's a draft — review it, then feed it to gecko serve. If the docs are a JS-rendered SPA with no embedded schema, it will honestly recover nothing rather than hallucinate endpoints.

</details>

Install & use

<details> <summary><strong>Do I need to install anything to try it?</strong></summary>

No. The 10-second quickstart points your MCP client at a hosted surface. Installing (uvx --from "gecko-surf[serve]" gecko <url>) is only for comprehending your own API.

</details>

<details> <summary><strong>It's SSE vs Streamable HTTP — which one?</strong></summary>

Streamable HTTP (2025-11-25). Use streamablehttp_client, not sse_client. This is the most common connection failure.

</details>

<details> <summary><strong>Can I self-host instead of using mcp.geckovision.tech?</strong></summary>

Yes, and nothing is held back. gecko serve <openapi-url> runs the same server this repo ships. The hosted layer saves you operating it; it doesn't unlock engine features.

</details>

<details> <summary><strong>How do I test correctness before I trust it?</strong></summary>

gecko test <openapi-url> generates a first-call-correctness suite you can drop into CI, and the $0 recorded mode runs the identical code path offline. Falsify it before spending a cent.

</details>

Security & data

<details> <summary><strong>Do you store my API responses or my users' data?</strong></summary>

No. Gecko stores the API surface — operations, params, generated tool defs, and correctness metadata. Never response payloads, never user data, never secrets. It's an architectural invariant, not a policy: the data plane never touches our storage.

</details>

<details> <summary><strong>Where do my API keys live?</strong></summary>

Not in mcp.json. Credentials resolve through one seam (Session.auth_headers()) and are injected at call time; the tool definitions the agent sees never contain them. For self-hosting, your provider key stays on your machine.

</details>

<details> <summary><strong>What happens if a spec is poisoned?</strong></summary>

Ingested spec and doc text is treated as untrusted input. The sanitizer scans for prompt-injection and fund-routing patterns; a tool that trips it is quarantined per-tool — it loses auth injection and cannot be called with credentials, while the rest of the surface keeps working. Argument routing fails closed. The launch demo runs 8 attacks that land on a naive agent and are blocked 8/8.

</details>

<details> <summary><strong>Can Gecko move funds or sign transactions?</strong></summary>

No. Gecko holds no funds, signs nothing, and takes no cut. The on-chain subscribe tooling simulates by default and hands a human the exact command to broadcast.

</details>

Commercial

<details> <summary><strong>Is it really free? What's the catch?</strong></summary>

The engine is Apache-2.0 with a patent grant, no feature gates, and developers are never charged. Revenue comes from API providers paying a flat price to keep their surface hosted, correct, and agent-reachable. See Open source engine, hosted platform.

</details>

<details> <summary><strong>Do you take a cut of my API calls?</strong></summary>

Never. Flat pricing per API, no take-rate, no funds custody. When payment happens it goes over x402 directly between the agent and the provider — we compose that rail, we are not it.

</details>

<details> <summary><strong>I'm an API provider. What do I get?</strong></summary>

Your API becomes reachable by agents that would otherwise call it wrong or not at all: a hosted MCP surface, first-call-correctness suites that track your spec as it drifts, key gating for paid or private endpoints, and the anti-poisoning layer in front of it. Your own MCP server, if you have one, stays intact — we aggregate, we don't replace. → docs.geckovision.tech

</details>


Contributing

The engine is open because distribution is the point. See CONTRIBUTING.md for setup, the mandatory gate (ruff · mypy · pytest · $0 demo), and the architectural ground rules — the control-plane invariant, auth-injection, untrusted-spec handling, and no-SSRF are enforced in review, not just style.

Skills welcome. skills/ is the gecko-surf Claude Code plugin marketplace (use-any-api, read-js-docs, anti-poisoning, api-agent-ready, x402-payai-setup). Adding one is a SKILL.md plus a line in the plugin manifest — the contributing guide has the details, including the rule that a skill points at engine code rather than restating it.


Team

  • Ernani (@ernanibritto) — Technical co-founder. Builds the Gecko engine end-to-end: ingest, comprehension, the access layer, and the MCP surface.
  • Leticia (@0xLeti) — Co-founder, Product Designer. 8+ years designing for enterprises and startups; ex-Liga Ventures.

License

Apache License 2.0 — see LICENSE and NOTICE. Apache-2.0 carries an explicit patent grant. The engine is open (the distribution funnel); the correctness corpus and hosted layer stay private (open-core).


The comprehension layer for the agentic economy.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured