# Access & auth Source: https://docs.geckovision.tech/access-and-auth The whole engine/adapter seam is one function — Session.auth_headers(). How Gecko handles auth and paywalls invisibly to the agent. Auth is invisible to the agent. The agent describes intent; Gecko injects credentials at call time. The agent sees a tool with no auth field; Gecko injects the credentials into the real request (BYOK) The entire engine/adapter seam is **one function**: ```python theme={null} class AuthSession(Protocol): def auth_headers(self) -> dict[str, str]: ... ``` Any object with `auth_headers() -> dict[str, str]` is a valid session. A paywalled API returns its tokens; a public API returns an empty dict. This is the design that keeps the engine **API-agnostic** — adding an API is data (the spec) plus, at most, this one adapter. ## Sessions you get out of the box A two-token authenticated session (JWT + API token). Returned by the access handshake. For public, no-auth APIs — `auth_headers()` returns an empty dict. A non-live session for recorded demos: auth headers are present but not real. ## Store your keys safely — the credential resolver You don't have to hand-write a `Session`. Gecko ships a credential resolver that keeps provider secrets in your **OS keychain** and injects them at call time — the key never enters the agent's context, shell history, a dotfile, or a log, and **it never leaves your machine**. ```bash theme={null} gecko auth set colosseum # hidden prompt — paste the key; it goes to your OS keychain gecko auth list # names only, never values gecko auth test colosseum # reports which backend answered — never the value gecko auth rm colosseum # remove ``` The resolver tries, in order: your **OS keychain** → an external secret-manager command (`op` / `vault` / `pass`) → an environment variable (CI/headless). For CI, just `export COLOSSEUM_COPILOT_PAT=...`. **Local vs hosted.** Because the key stays on *your* machine, an API that needs *your* key runs **locally** (`gecko auth set …` then serve it). The hosted `mcp.geckovision.tech` serves only the **public** surfaces — Gecko never holds a user's key, so a keyed, per-person API can't be a shared hosted surface. ## How auth gating works When a session returns an **empty** auth-header dict, Gecko treats it as "this session can't satisfy auth-gated operations" and **hides those operations from the agent** — it could only mis-call them. A session *with* auth surfaces everything, unchanged. If an auth-gated tool is forced anyway, `prepare()` raises a typed error rather than firing a request that can't succeed. ```python theme={null} from gecko.access import public_session from gecko.client import AgentApiClient client = AgentApiClient(spec, session=public_session()) client.list_tools() # auth-gated operations are not in this list client.prepare("some_auth_only_op", {}) # raises CallError — correctly refused ``` ## The two-token handshake (worked example) The live reference integration (the TxODDS World Cup API) uses a flow the agent never has to learn. Gecko encodes it so the agent only ever describes intent: ``` guest JWT → on-chain subscribe (txSig) → sign(txSig:leagues:jwt) → activate → apiToken ``` producing a two-token session: ``` Authorization: Bearer (httpAuth) X-Api-Token: (apiKeyAuth) ``` Transport and signer are **injected**, so the whole flow is unit-testable with no network and no keys: ```python theme={null} from gecko.access import establish_session session = establish_session(base_url, tx_sig, leagues, signer=my_signer) session.auth_headers() # {"Authorization": "Bearer ...", "X-Api-Token": "..."} ``` ## The on-chain step The `subscribe` transaction itself is a wallet-signing, network-specific step that lives outside the access layer (in `scripts/`). The access layer takes the resulting `txSig` plus a signer and finishes the session. **Mainnet boundary.** The subscribe transaction is **founder-run only**. The tooling *simulates* by default (no spend) and hands over the exact command; a human broadcasts it. Gecko does not sign or broadcast mainnet transactions on its own. ## Short-lived tokens & OAuth — auto-refresh Most production APIs hand you a **short-lived access token plus a refresh token** (the OAuth pattern). Gecko manages that lifecycle for you, behind the same `auth_headers()` seam — the agent never sees an expiry: * **Proactive refresh** — when the token is within a leeway window of expiry, the session refreshes it *before* returning headers. * **Reactive self-heal** — if a live call still comes back `401`, Gecko re-authenticates and retries the identical call **once** (bounded — a second failure raises a typed, redacted error, never an infinite loop). You do the one-time interactive login yourself (Gecko can't complete a human's 2FA); after that, Gecko takes over. `OAuth2Lifecycle` refreshes via a `refresh_token` grant, and adapters like `oauth2_from_dpo2u()` read a local token file and refresh on their own. ```python theme={null} from gecko.access import oauth2_from_dpo2u # reads ~/.dpo2u/oauth.json, refreshes at the token endpoint session = oauth2_from_dpo2u() session.auth_headers() # a valid Bearer token — refreshed transparently as it nears expiry ``` The refresh token (a secret) resolves through the credential resolver in your local runner; the short-lived access token lives in memory only. Nothing about the token is persisted by Gecko's control plane. ## What Gecko never does with credentials * It never exposes auth headers in the agent-facing tool definitions. * It never logs tokens or keys — secrets are redacted before any error is raised. * Its **control plane** never stores or transmits your secret: the credential resolver reads it from your local OS keychain (or env) and injects it at call time, on your machine. Gecko only ever sends it toward the API's own host — never anywhere else. See [Architecture](/architecture) for how this fits the control-plane model. # Architecture Source: https://docs.geckovision.tech/architecture Gecko is a control plane, not a data plane. The invariants, the module map, and the single API-agnostic seam. Gecko is a **control plane, not a data plane.** It holds the API's *surface*, the generated tool defs, and *correctness metadata* — and never the data flowing through. That single invariant is what makes the rest of the design coherent. ## The flow Two auth relationships and two run modes, around one control-plane engine. Your agent connects to the **MCP surface**; the engine comprehends the API once, then serves and calls it — injecting credentials at call time and staying out of the data path. Gecko flow — the agent states intent to the MCP surface; the control plane comprehends the API (ingest → catalog → tools) and the caller builds the request; access injects credentials at call time; in live mode the real API's data returns to the agent directly, never through Gecko; recorded mode synthesizes the response from the schema for $0 offline. Local `gecko add` stays **zero-login**; the identity plane gates only the hosted surface. In `recorded` mode the request is built and proven well-formed but the response is synthesized from the schema — it never touches the provider plane. In `live` mode `access` injects credentials and the agent gets the real API's data **directly**; that data never passes through Gecko. ## Invariants Stores the API surface, tool defs, and correctness metadata only — never response payloads, user data, or secrets. Everything API-specific reduces to data (the spec) plus one adapter seam, `Session.auth_headers()`. Adding an API doesn't touch ingest/catalog/tools/caller. `recorded` and `live` differ only at the transport edge. The free offline simulation comes first; live smoke is the final check. Tool defs never expose auth headers. The agent describes intent; Gecko injects credentials at call time. ## Module map The comprehension logic is the product and lives in the package; the MCP server, the client, and the scripts are thin transport. | Module | Responsibility | | --------------------- | --------------------------------------------------------------------------------------- | | `gecko/ingest.py` | OpenAPI 3.x → normalized `Operation` / `Param` (`$ref` resolution, cycle/depth 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/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` | `AgentApiClient` — `search` / `list_tools` / `prepare` / `call` | | `gecko/mcp_server.py` | `McpSurface` — the agent-facing MCP surface | | `gecko/validator.py` | replay + first-call-correct check + JSONL outcome log (metadata only) | | `gecko/evaluate.py` | task-based first-call-correct scorecard (top-1 / top-5 / well-formed) | | `gecko/demo.py` | `run()` (recorded, \$0) + `live_demo()` | ## The one seam that matters Adding a new API should not require touching ingest, catalog, tools, or the caller. The only API-specific code is, at most, an auth adapter — an object that implements: ```python theme={null} def auth_headers(self) -> dict[str, str]: ... ``` A public API uses the built-in no-auth adapter (returns `{}`); a paywalled API supplies a session that returns its tokens. See [Access & auth](/access-and-auth). ## Outcome logging (control-plane safe) The validator and the evaluation harness append **outcome metadata only** — tool name, rank, ok/reason — to a JSONL log. They never write response payloads. Turning that metadata into a richer, multi-API correctness signal is V2 work and is **not live today**; see [Status](/status). ## Security posture * Ingested spec/doc content is treated as **untrusted input**. * URLs are validated before fetching (no SSRF — private/loopback/link-local ranges and non-http schemes blocked). * Secrets come from the environment/session and are never logged or persisted; errors redact tokens before they're raised. * Stdlib-first networking (`urllib`); minimal dependencies, so the engine ports anywhere. # Cloud Source: https://docs.geckovision.tech/cloud The free gecko-surf engine makes any API agent-usable and stays free forever. Cloud is the hosted, always-correct layer API providers pay for — and you pay only when it scales. **The engine is free and stays free.** Everything that makes an agent call an API correctly the first time is in the open-source `gecko-surf` you run yourself — no account, telemetry off by default. **Cloud** is what we're **building on top**: the hosted, continuously-correct, cross-customer layer. This page describes what it does. ## Who pays, and why One sentence: **the engine is free forever for builders; API providers pay a flat per-API subscription for hosted, drift-watched, agent-ready surfaces.** The free engine is the **funnel**: any developer points it at any painful API and gets first-call-correct tools, forever, on their own machine — builders never pay. **Cloud is where API providers pay** — to make *their* API the one agents call correctly, keep it correct as it drifts, and turn more correct calls into more usage (and, connected to their payment rail, more revenue). A provider starts free and steps up **as their API scales with agents** — the tiers below are performance and reach, not a builder meter. If you own an API, start at [For API providers](/for-providers). ## What Cloud adds over the free engine * Comprehend any OpenAPI → **first-call-correct** tools · auth hidden * `$0` recorded mode · the MCP surface + one-click add — you host it * Anti-poisoning defenses + agent-native artifacts * Local eval + your own telemetry — **on your disk, we see nothing** * No account. Telemetry ships **disabled**. * **Hosted MCP** — always-on endpoint, nothing to run or scale * **Drift-watch** — re-comprehend when your API changes, alert *before* your integrators break * **Access analytics** — first-call-correct rate, dark ops, failed→settled * **Correctness corpus** — day-one-correct on a new API, from across the fleet * **Team** — shared surfaces, roles, audit, deploy-to-your-domain **Control-plane holds in the cloud.** We store the API **surface**, the generated **tool definitions**, and **correctness metadata** — never your response payloads, user data, or secrets. No lock-in: you can go back to fully self-hosted anytime. ## Plans — you pay when you scale The tier is what scales — performance and reach, not the core capability (that's free). The open-source engine + a free hosted tier to try — **shared throughput, best-effort latency.** Point it at your API and see the agent-native surface today. **Low latency, dedicated throughput, faster drift-watch, analytics, longer retention.** For an API that's becoming load-bearing for agents. **SLA, high throughput, white-label private discoverability, onboarding.** For an API that's a real part of the agent economy. We price the **value** — keeping your surface correct through drift and turning failed agent calls into settled ones — **not the compute**, and **never a cut of what agents pay you.** The model we're building toward is a **flat per-API subscription** that steps up with performance/scale (Free → Pro → Scale), the Pro tier illustratively in the low hundreds/month per API, deliberately below the coding-agent seat you already pay for. Prices are **illustrative** — they land when Cloud ships. We're showing the shape now, not locking a number. ## Payments — you keep 100% We collect **our own flat fee** over whatever rail fits you — **x402 / USDC** (or **PayAI** for recurring), or **card / fiat** via **Privy**, **abacatepay**, or Stripe. It's an injected, neutral seam, so the rail is a config choice, not a rewrite. And when it comes to *your* API getting paid by agents, we **compose** your rail — we point the tools at your x402 endpoint (**PayAI, Metera, or pay.sh**) as part of the setup. You keep every cent; **Gecko is never the payment rail and never a marketplace.** ## How we make money, plainly A flat monthly subscription per API we keep agent-correct and drift-watched — collected as our own fee, **never a cut of what agents pay you.** The engine developers use is free and open source; the compounding **correctness corpus** is the moat. Metera meters it; Gecko multiplies it. ## Come build it with us Cloud is being built alongside the API providers who feel it most. If agents keep calling your API wrong — or you want it to be the one they call *right* — that's exactly the surface we want to make agent-ready. Join the Discord — we build in the open and figure out which API to make agent-ready next. `npx @geckovision/gecko ` runs the whole engine on your machine today. # How comprehension works Source: https://docs.geckovision.tech/comprehension Ingest, catalog, and the question-shaped tool generator — the path from an OpenAPI surface to first-call-correct agent tools, tied to the real engine. Comprehension is the product. It is the path from a raw API surface to tools an agent calls correctly the first time. Three stages, each a small focused module. Gecko turns a raw OpenAPI operation into a question-shaped tool with a JSON schema — auth header removed ## 1. Ingest the surface Gecko parses an **OpenAPI 3.x** document (YAML or JSON) into a normalized list of operations. It resolves local `$ref`s with **cycle and depth guards** — on a cycle or when the depth cap is hit, the `$ref` is left in place rather than expanded, so callers still get a usable (if shallow) schema. Path-level parameters are merged into each operation's own parameters. Each `Operation` carries: method, path, `operation_id`, summary, description, tags, parameters, request body, responses, and security. Each `Param` carries: name, location, required, schema, description. Ingest reads the **surface only** — method, path, params, request/response schemas. It never reads or stores response data. The ingestor is stdlib + PyYAML by design, so it runs anywhere with zero heavy dependencies. Ingested spec content is treated as **untrusted input**, and any URL fetched to load a remote spec is validated first. ## 2. Catalog — intent to endpoint The catalog lets an agent go from a natural-language goal to the right endpoint. It scores each operation by lexical overlap between the query and the operation's surface text — summary, description, path, tags, and id — with **summary matches weighted double** (it's the most intent-bearing field). Results are ranked and returned. ```python theme={null} catalog.search("get live odds for a fixture", limit=5) # → ranked CatalogEntry list, highest score first ``` It can also group capabilities by tag and emit a human/agent-readable capability map. This is **lexical, not vector** search: at tens of endpoints it is more accurate and far simpler than vector RAG. Vectorization is a deliberately deferred multi-API / large-API concern, not part of V1. ## 3. Comprehend — the question-shaped tool Each operation becomes an MCP-compatible tool definition: a name, a **question-shaped description**, and a JSON-Schema input. Two decisions make this more than a raw OpenAPI dump: **Hide the plumbing.** Auth headers (`Authorization`, `X-Api-Token`, and similar) are stripped from the agent-facing input. The agent reasons only about decision-relevant inputs; the [access layer](/access-and-auth) injects credentials at call time. **Carry invocation metadata.** The tool keeps an internal `_invoke` block — method, path, and the location of each parameter — so the caller can build the real HTTP request without re-parsing the spec. A generated tool looks like: ```json theme={null} { "name": "get_odds_snapshot_fixtureId", "description": "Live odds snapshot for a fixture. Required: fixtureId.", "inputSchema": { "type": "object", "properties": { "fixtureId": { "type": "integer" } }, "required": ["fixtureId"] }, "requires_auth": true, "auth_schemes": ["apiKeyAuth", "httpAuth"] } ``` `requires_auth` is true only when *every* way to call the operation needs auth (an OpenAPI `security` requirement of `{}` means "no-auth is also acceptable", which keeps it optional). The client uses `requires_auth` + the session to **hide operations a no-auth session could never satisfy**, so the agent never wastes a call on them. ## 4. Build the correct request When the agent calls a tool, the caller places each argument by its location, injects the hidden auth headers, and assembles the request. Crucially, it **catches the silent first-call failure** — for example a missing required path parameter raises a typed `CallError` instead of firing a malformed request the agent can't diagnose. ## Measuring first-call-correct Gecko ships a falsifiable scorecard. Given a client and a list of `{goal, expect_op, args}` tasks, it measures whether the comprehension layer retrieves the right operation (top-1 / top-5) and builds a well-formed request for it — recorded and offline, recording **only outcome metadata** (tool, rank, ok/reason), never payloads. ```python theme={null} from gecko.evaluate import evaluate_tasks card = evaluate_tasks(client, tasks) print(card["top1_rate"], card["top5_rate"], card["well_formed_rate"]) ``` This is the same harness used to score a **second public API** end-to-end (see the `scripts/pegana_eval.py` worked example in the repo, which ingests a public peg-state API with a no-auth session and scores first-call-correctness, including correctly **refusing** to fire an auth-gated operation on a public read). It's evidence the engine is API-agnostic, not a claim that Gecko one-shots every API. # Concepts Source: https://docs.geckovision.tech/concepts The vocabulary behind Gecko — surface, operation, question-shaped tool, session, and the two run modes. A small, precise vocabulary runs through the whole system. Learn these and the rest of the docs read cleanly. ## Surface The *surface* of an API is everything that describes how to call it: methods, paths, parameters, request/response **schemas**, auth schemes. It is **not** the data the API returns. Gecko ingests the surface and nothing more — this is the basis of the [control-plane](/architecture) promise. ## Operation A single callable endpoint, normalized from the spec into a typed record: method, path, `operation_id`, summary/description, tags, parameters, request body, responses, and security. Local `$ref`s are resolved (with cycle and depth guards) so each operation is self-contained. ## Parameter A normalized input to an operation, carrying its `name`, `location` (`path` / `query` / `header` / `cookie`), whether it's `required`, and its schema. The location is what lets the caller place each agent-supplied value in the right spot. ## Catalog The "find the right endpoint" layer. It does lexical search over each operation's surface text (summary, description, path, tags, id), with summary matches weighted highest. At the scale of tens of endpoints this is more accurate and far simpler than vector search — vectorization is a deliberately deferred multi-API concern. ## Question-shaped tool The comprehension payload: an operation rendered as an agent-reasonable tool definition — a name, a question-shaped description, and a JSON-Schema input. Two decisions separate it from a raw OpenAPI dump: * **Auth is hidden.** Authorization-style headers are removed from the agent-facing input. The agent only sees decision-relevant inputs. * **Invocation metadata travels with the tool.** The method, path, and per-parameter locations ride along so the caller can build a real request without re-parsing the spec. Each tool also carries `requires_auth` and the `auth_schemes` it references, so a session with no credentials can hide operations it could never satisfy. ## Session The access/auth seam. Any object with `auth_headers() -> dict[str, str]` is a valid session. A paywalled API returns its tokens; a public API returns an empty dict. The agent never sees these headers — Gecko injects them at call time. See [Access & auth](/access-and-auth). ## Caller Turns a question-shaped tool plus the agent's arguments into a correct HTTP request: it places each value in the right location (path / query / header), injects the hidden auth headers, and **catches the failure the agent can't see** — like a missing required path parameter — instead of firing a malformed call. ## Modes: recorded vs live Gecko runs one code path in two modes: | Mode | Network | Cost | What you get | | ---------- | ------- | ----------- | ------------------------------------------------------------------- | | `recorded` | none | \$0 | response synthesized from the response schema — falsifiable offline | | `live` | yes | per the API | the real upstream response | They differ **only at the transport edge**. See [Recorded mode](/recorded-mode). ## First-call-correct The bar Gecko holds itself to: given a natural-language goal, retrieve the right operation and build a **well-formed** request for it on the first try — no trial calls, no malformed requests the agent can't diagnose. A built-in evaluation scores retrieval (top-1 / top-5) and request well-formedness against a task set. # Agent discoverability Source: https://docs.geckovision.tech/discoverability Gecko exists to make an API discoverable to agents — question-shaped tools, intent-to-endpoint search, hidden auth, and an llms.txt for the API itself. Gecko's whole reason to exist is **discoverability for agents**. A human can read docs, infer the right call, and guess at parameters. An agent shouldn't have to. These are the mechanisms that make an ingested API discoverable. ## Intent, not endpoints An agent describes *what it wants* — not which path to hit. The catalog turns that intent into a ranked list of candidate operations, and the `search_capabilities` tool on the [MCP surface](/mcp-surface) exposes it directly: ```python theme={null} client.search("what fixtures are coming up?") # → [{ "name": ..., "summary": ..., "path": ..., "method": ... }, ...] ``` ## Question-shaped descriptions Every tool's description is written as the question it answers, with required and optional inputs called out. The agent picks the right tool from the description alone — no API docs in front of it. See [How comprehension works](/comprehension). ## Auth is out of the way Auth headers never appear in the agent-facing tool input, and operations the current session can't authenticate are hidden entirely. The agent's surface is exactly the set of calls it can actually make — nothing it would only fail at. See [Access & auth](/access-and-auth). ## Only the calls that will work When a [session](/access-and-auth) can't satisfy an operation's auth, that operation is removed from `list_tools()` and `search()`. Discoverability means surfacing the *usable* surface, not the whole spec — an agent should never discover a call it can't complete. ## An llms.txt for the API Gecko can emit an agent/human-readable capability map grouped by tag — the machine-facing equivalent of a table of contents for the API: ```python theme={null} print(client.catalog.describe()) # ## fixtures # - GET /api/fixtures/snapshot — upcoming fixtures # ## odds # - GET /api/odds/snapshot/{fixtureId} — live odds for a fixture ``` This docs site itself ships an [`llms.txt`](/llms.txt) — a discoverability map for these docs, in the same spirit. If you're an agent, start there. ## The agent-native layer — and we dogfood it Docs are a human handoff. An `llms.txt` or an MDX page is something an agent has to *read and trust*; the agent-native contract is a **structured tool it calls**. Gecko's job is to turn the human-shaped surface into that tool — so an agent finds and uses the right call without reading prose. Gecko projects one comprehended surface three ways, for three moments: * **`llms.txt`** — a breadcrumb for an agent that lands on the docs: the capability map plus a pointer to the live MCP and `search_capabilities`. (These docs ship one — [read it](/llms.txt).) * **OpenAPI + `x-gecko`** — the spec an OpenAPI-native tool already ingests, enriched in place with question-shaped intents, prerequisites, and worked examples. Unknown `x-` keys degrade gracefully, so a non-Gecko consumer just ignores them. * **`/.well-known/gecko.json`** — the machine-precise manifest `search_capabilities` navigates: the capability graph (which call produces the id another call needs), worked examples, and first-call-correct stats. All three cross-link, so an agent landing on any one reaches the callable tool. This docs site is the reference implementation — our own surface is exposed through the same layer we generate for any API. ## Everything an agent can fetch This docs site publishes the same agent-native surface Gecko generates for any API — point your agent at any of these: * [`llms.txt`](https://docs.geckovision.tech/llms.txt) — the curated index of these docs * [`llms-full.txt`](https://docs.geckovision.tech/llms-full.txt) — the whole docs as one Markdown file * [`gecko.json`](https://docs.geckovision.tech/gecko.json) — the machine-readable manifest for this site * [`/.well-known/gecko.json`](https://docs.geckovision.tech/.well-known/gecko.json) — the manifest at the discovery-convention path * **Any page as Markdown** — append `.md` to its URL (e.g. [`/discoverability.md`](https://docs.geckovision.tech/discoverability.md)) * [Hosted MCP endpoint](https://mcp.geckovision.tech/mcp) — the live Gecko MCP (Streamable-HTTP), one-click add to Claude or Cursor * [Product manifest (canonical)](https://geckovision.tech/gecko.json) — the source-of-truth manifest on the landing Shipped today: the MCP surface, `search_capabilities`, hidden auth, a usable-only surface, and this site's own agent-native artifacts — `llms.txt`, `gecko.json`, and `/.well-known/gecko.json` (discovery level). Rolling out (see [Roadmap](/roadmap)): the `x-gecko` OpenAPI enrichment and the richer `/.well-known/gecko.json` **capability graph** (which call produces the id another call needs), `search_capabilities` returning the full call recipe inline (prerequisites + a worked example), and access-quality measurement — did the agent find and correctly use the call. We build these against our own docs first. ## Scope Discoverability is live today on an ingested **OpenAPI 3.x** surface. Gecko makes a *known* API surface agent-usable — it doesn't crawl arbitrary human-only docs, auto-discover APIs across the internet, or verify the data an API returns. See [Status](/status). # For API providers Source: https://docs.geckovision.tech/for-providers Agents are becoming a consumer of your API — and they fail it silently. Make yours the API agents find, call correctly on the first try, and keep calling as you ship. ## The problem you can't see from your side Your docs are written for humans — and they work for humans. But a growing share of your integrations are now attempted by **AI agents**, and for them the experience is different: * **Agents mis-call you.** Wrong parameter, wrong endpoint, an auth scheme inferred incorrectly from prose. On your side that's malformed requests, retry storms, rate-limit pressure, and support tickets that read "your API doesn't work" — when really, the agent guessed wrong. * **Agents can't find you.** An agent picks the API it can *discover and call correctly today*. If that's your competitor, the traffic — and the integration — goes there. You never see the loss; it just never arrives. * **Your own changes break your integrators.** A renamed field that no human would miss silently breaks every downstream agent. Their 2am incident becomes your support ticket and, eventually, your churn. * **A hand-rolled MCP server goes stale.** Teams that ship their own agent surface cover a handful of endpoints, then drift out of date the next time the API ships. None of this shows up in your analytics, because failed and never-attempted agent calls are invisible by definition. That's the trap: the pain is real, and it's unmeasured. ## What Gecko does about it Gecko is **where agents and APIs finally speak the same language**. Point it at your OpenAPI (or your docs — [no spec needed](/from-docs)) and your **whole surface** becomes question-shaped, first-call-correct agent tools: auth handled invisibly, operations an agent can't satisfy hidden, everything provable offline first. ## Bringing your API onboard — five moves Some moves are self-serve and free today; one is a deliberate manual handshake (we don't want your credentials flowing through a form); a couple are still hands-on while we build them toward self-serve. Each is labeled with what's real right now. Before anything else, see where you stand. `gecko inspect ` grades your API across four dimensions — **first-call-correct**, **spec hygiene**, **agent-friendliness** (ambiguous routing traps a schema linter can't see), and **security** — and prints located, fixable findings. Integrate it into CI (`--min-grade B`) to fail a deploy that regresses. It's TDD for your API. ```bash theme={null} npx @geckovision/gecko inspect # or a bare domain / docs URL ``` Paste your OpenAPI URL — or [your docs](/from-docs), no spec needed — and get question-shaped, first-call-correct tools back, provable offline before a single live call. Run it yourself: `npx @geckovision/gecko `. You see your own API comprehended in one session, no account, no cost. Most real APIs are auth-gated, so this is the step that needs a human exchange: hand us a **sandbox key** and agree the **safe scope** — which operations agents may call; anything that moves money is excluded or step-up-gated, not handed to an arbitrary agent. Gecko stores the credential as an *opaque reference* and injects it at call time — the agent never sees a token. See [Access & auth](/access-and-auth). Your comprehended surface is hosted at `/{you}/mcp` with the agent-native breadcrumbs — `llms.txt`, `gecko.json`, `/.well-known/gecko.json`, `/.well-known/x402.json` — so agents *discover* you, not just call you ([Agent discoverability](/discoverability)). Your own MCP, if you have one, keeps running untouched; Gecko sits **beside** it. You get one line to hand your developers: `claude mcp add --transport http you https://mcp.geckovision.tech/you/mcp`. Charge agents per call by pointing the generated tools at **your own** x402 endpoint (PayAI, Metera, or pay.sh). The 402 challenge, the funds, and the settlement are yours; Gecko composes the rail, holds nothing, signs nothing, and **takes no cut.** You see the full challenge→settle handshake offline first (`X402_MODE=stub`) before any real money moves; on-chain settlement is proven on devnet, and any mainnet transaction is run by you, never by us. Drift-watch re-comprehends your API when you ship and regenerates the tools, so your next release doesn't silently break downstream agents — the alert fires **before their prod does.** The surface fingerprint that makes this tractable exists today; the auto-update loop and the adoption dashboard are **designed for V2, not yet shipped** ([Stay correct](/stay-correct)). ## What we need from you To take a real API from comprehended to a live, measured surface: * **A sandbox / test API key** (+ the sandbox base URL) — unlocks the gated operations and keeps calls off production. * **Your current OpenAPI spec** (or confirmation the docs URL is current) — so the surface reflects today's API, and drift is measured against a real baseline. * **The safe scope** — which operations agents may call; what to exclude or step-up-gate (anything that moves money). * **Distribution** — put the add-command in front of your developers. Gecko *measures* the funnel (who connected, called, came back); it doesn't *create* the traffic. That's the whole ask. **No production credentials, no build work on your side, no money changing hands to start, no exclusivity.** ## Who pays, in one sentence > **The engine is free forever for builders; API providers pay a flat per-API > subscription for hosted, drift-watched, agent-ready surfaces.** Flat fee. Never a percentage of your revenue, never a cut of what agents pay you, never a public catalog listing you didn't ask for. Illustrative shape on the [Cloud page](/cloud) — prices land when Cloud ships. ## Why this is measurable (unlike docs spend) Human-docs spend is famously unattributable. Agent comprehension isn't: a first-call-correct fix turns a **failed** call into a **completed** one — and if your API is x402-metered, into a **settled** one. The delta is visible per API revision. That's the difference between a cost center and an ROI line. ## What's live The comprehension engine, the scorecard, discoverability artifacts, and the free self-serve flow are **live today**. Drift-watch, access analytics, and the hosted provider plane are **building now** — with the first design partners. See [Status](/status) and [Roadmap](/roadmap) for the exact line. ## Bring your API `npx @geckovision/gecko inspect ` — your agent-readiness grade + fixable findings in one session. Self-serve, offline, \$0, no account. Run the open-source engine against your own spec today — comprehend, serve over MCP, emit your agent-native surface. # From docs Source: https://docs.geckovision.tech/from-docs No OpenAPI? Point `gecko from-docs` at an API's doc site and it recovers a draft OpenAPI, then comprehends it into agent tools — with honest review notes for anything it couldn't pin down. Not every painful API ships a spec. The long-tail, paywalled, human-documented ones — the exact APIs an agent *can't* one-shot — often have **only a doc site**. `gecko from-docs` is the on-ramp: it reads the docs and hands the comprehension engine a *draft* OpenAPI. ```bash theme={null} gecko from-docs https://docs.some-api.com gecko from-docs ./api-docs.html # a local file, for dev gecko from-docs -o draft.json # also write the draft spec ``` ## What it does 1. **Fetch** the doc page — SSRF-validated (private / loopback / link-local ranges and non-HTTP schemes are refused, every redirect re-checked). The bytes are parsed and **discarded**: Gecko is control-plane only, it never stores the doc. 2. **Recover** candidate operations from the page's structure — headings, code blocks, and parameter tables, in document order — into a draft OpenAPI 3.1. JSON-RPC methods are modeled honestly (one operation per method; the envelope carried on `x-jsonrpc-*`). 3. **Comprehend** the draft through the *same* engine as any spec → question-shaped, first-call-correct agent tools. ```text theme={null} Gecko from-docs — recover a draft API from human docs ======================================================== source: https://docs.some-api.com recovered 3 candidate operation(s): - sendBundle [POST /api/v1/bundles] (jsonrpc, high) - getTipAccounts [POST /api/v1/bundles] (jsonrpc, high) - getTipFloor [GET /api/v1/bundles/tip_floor] (rest, medium) honesty: 2 x-review note(s), 2 low/medium-confidence field(s) to confirm. optional auth recovered: x-tip-auth header (injected by the access layer, invisible to the agent). comprehended draft -> 3 agent tools. ``` ## It's an assistive draft, not zero-touch `from-docs` is honest about its uncertainty. Every field it couldn't pin down from the docs is flagged with `x-review` and a confidence level in the draft spec — so a human (or an agent) confirms those before going live. It gets the **surface and shape** right; you confirm the ambiguous edges, then run [`gecko test `](/quickstart) to prove the calls before you ship. ## JS-heavy doc sites Static docs work out of the box with the built-in reader — no extra dependencies. For doc sites that render their navigation with JavaScript, `from-docs` tells you when it recovered only a few operations and points you at the agent-browser driver in [`spikes/docs_reader`](https://github.com/GeckoVision/gecko-surf/tree/main/spikes/docs_reader), which renders the JS nav before extracting. ## Why this matters This is the painful-API wedge, made concrete. A coding agent can one-shot a popular, well-specified API — it can't one-shot the **Nth painful one** with no OpenAPI. `from-docs` turns that API's docs into agent-usable tools without you hand-writing a client or a spec. # Introduction Source: https://docs.geckovision.tech/introduction Where agents and APIs finally speak the same language — point Gecko at any API and your agent calls it right the first time. ## What Gecko is Docs and endpoints are built for humans. **Gecko is where agents and APIs finally speak the same language** — it translates any API into tools your agent calls right the first time. Point an agent at an API — even one behind human-shaped docs and a paywall — and it finds the right call, makes it correctly the first time, and runs. No client to hand-write, no key pasted into a config, no guessing whether the agent is calling it right. Three promises, one layer: * **Right the first time** — Gecko reads the API before your agent calls it. Right endpoint, right parameters, right auth. * **Keys stay hidden** — your key lives on your machine and is used only at the moment of the call, sent only to the API's own host. Never in a file, never inside the agent. * **Poison gets caught** — a manipulated API (a doctored description, a poisoned example) is screened and quarantined before your agent ever sees it. gecko comprehends an API and prints the MCP URL + one-click add strings The brand is **Gecko**. The PyPI package is **`gecko-surf`** (`pip install gecko-surf`), the import is **`gecko`** (`from gecko import …`), and the CLI is **`gecko`**. Today a builder reads the docs, hand-writes a client, and **still can't tell if the agent is calling the API correctly.** Gecko removes that step. It ingests an API's *surface* (an OpenAPI spec, or one recovered from a docs page), turns it into question-shaped, first-call-correct agent tools, drives the access/auth handshake, and lets the agent call the **real API directly** for data. ## Where Gecko sits — three verbs, three layers There are three distinct jobs in the agentic economy. Gecko does exactly one. | Layer | What it does | Examples | | -------------------------- | ------------------------------- | ------------------- | | APIs get **PAID** | billing / settlement rail | x402, payment rails | | skills get **DISTRIBUTED** | marketplace / discovery | skill marketplaces | | **APIs get USED** | **comprehension / consumption** | **Gecko** | Gecko **composes on top of** x402 / MCP / payment catalogs — it *consumes* them as input. It is **not** a payment rail and **not** a marketplace. It is the layer that makes an API actually *usable* by an agent. ## What it does, in one path Parse an OpenAPI 3.x document into normalized operations and parameters — the *surface only* (method, path, params, schemas). Never the response data. Build a capability list so an agent can go from natural-language intent to the right endpoint. Lexical at this scale; no vectors. Turn each operation into a question-shaped tool an agent picks correctly with no API docs in front of it. Auth headers are hidden from the agent. Drive the access/subscription handshake. The whole engine/adapter seam is one function: `Session.auth_headers()`. The agent calls the real API directly; Gecko injects credentials and stays out of the data path. ## Control plane, never data plane Gecko holds the API's *surface*, the generated tool defs, and *correctness metadata*. It **never** stores response payloads, user data, or secrets. That invariant is what lets it ingest an API's surface unilaterally — and it is a hard boundary, not a setting. ## What's live Comprehension is **live end-to-end on Solana mainnet** against a real paywalled API (the TxODDS World Cup API, 857 tests passing), and the same engine is proven keyless at scale: **Stripe — 587 tools, 99.8% first-call-correct · Twilio — 100% · Jupiter — 100%** — with a **`$0` recorded mode** that runs the whole path offline. Ingest is OpenAPI 3.x, or a spec recovered from a docs page. See [Status](/status) for what's next. ## Next Run the \$0 recorded demo — goal to correct call to data, no keys, no spend. The vocabulary: surface, operation, question-shaped tool, session, modes. Ingest, catalog, and the question-shaped tool generator, tied to the real code. The MCP surface an agent installs, and how Gecko makes an API discoverable. # The MCP surface Source: https://docs.geckovision.tech/mcp-surface What an agent installs — a framework-agnostic MCP surface over any ingested API, plus a synthetic search_capabilities tool for intent-to-endpoint discovery. Gecko exposes an ingested API to an agent through the **Model Context Protocol (MCP)**. The surface is framework-agnostic and fully testable: it's a thin view over the client with two methods — `list_tools` and `call_tool`. Want to see it without installing anything? Add a live, hosted surface to your agent: ```bash theme={null} claude mcp add --transport http gecko-txline https://mcp.geckovision.tech/txline/mcp ``` That's the TxODDS TxLINE World Cup API (18 first-call-correct tools, served recorded/\$0). In Claude Code you can instead `/plugin install gecko-surf@geckovision` — it wires that surface **and** the make-agent-ready workflow. See the [Quickstart](/quickstart). ## Connect it in one step The fastest way to give an agent an API: run the CLI and paste the printed line. It comprehends the spec, serves it over **Streamable-HTTP MCP**, and prints a one-click "add" string for each host app. ```bash theme={null} npx @geckovision/gecko https://api.example.com/openapi.json ``` ```text theme={null} MCP URL (Streamable HTTP): http://127.0.0.1:8000/mcp Add it to an agent (one step): Claude Code: claude mcp add --transport http your-api http://127.0.0.1:8000/mcp Cursor: cursor://…/mcp/install?name=your-api&config=… VS Code: vscode:mcp/install?… ``` * **Claude Code** — paste the printed `claude mcp add …` line. * **Cursor / VS Code** — open the printed deeplink (click it, or paste it into the address bar). Serving to a *remote* agent? Add `--public-url https://` so the add strings and the DNS-rebinding `Host`/`Origin` guard use your public URL. (For an embedded, in-process server there's also a stdio variant — see [Using it in code](#using-it-in-code) below.) ## What the agent sees The surface lists every usable, question-shaped tool for the API **plus one synthetic tool**, `search_capabilities`, so the agent can go from plain-language intent to the right endpoint and then call it. ```json theme={null} { "name": "search_capabilities", "description": "Find which endpoint/tool fits a natural-language intent. Returns ranked tool names you can then call.", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "description": "What you want to do, in plain language." } }, "required": ["query"] } } ``` Each real tool is listed with only `name`, `description`, and `inputSchema` — auth plumbing and invocation metadata stay internal. Operations the current [session](/access-and-auth) can't satisfy are not listed at all. ## The agent loop Call `search_capabilities` with the goal in plain language → ranked tool names. Read the question-shaped `description` and `inputSchema` of the top tool. Call the tool by name with the inputs. Gecko builds the correct request, injects auth, and returns the result. ## Using it in code `McpSurface` wraps an `AgentApiClient` and is testable without any MCP SDK installed: ```python theme={null} from gecko.client import AgentApiClient from gecko.mcp_server import McpSurface surface = McpSurface(AgentApiClient(spec), mode="recorded") surface.list_tools() # search_capabilities + the API's tools surface.call_tool("search_capabilities", {"query": "live odds for a fixture"}) surface.call_tool("get_odds_snapshot_fixtureId", {"fixtureId": 123}) ``` ## Running a real stdio server For a live MCP server, `serve_stdio` wraps the surface with the `mcp` SDK. It is import-guarded, so the surface and its tests work without the SDK installed. ```bash theme={null} uv add mcp ``` ```python theme={null} from gecko.mcp_server import serve_stdio serve_stdio("path/to/openapi.yaml", base_url="https://...", mode="recorded") ``` The MCP server is **thin transport**. All comprehension logic lives in the engine; the server just parses input, calls the package, and formats output. Run it in `recorded` mode for a \$0 surface, or `live` once a session is in place. # Quickstart Source: https://docs.geckovision.tech/quickstart Point Gecko at any API and your agent calls it right the first time. One command to add it, $0 recorded mode to prove every call offline first. Point Gecko at an API — even a messy, paywalled one with no published spec. It reads the API's *surface*, turns every endpoint into a question-shaped, first-call-correct tool, and wires it into your agent. No client code, no key in a config file. **Handing these docs to a coding agent?** Point it at [`/llms.txt`](https://docs.geckovision.tech/llms.txt) — a compact, agent-readable map of this site — or append `.md` to any page URL for raw markdown (e.g. `/quickstart.md`). ## Add any API to your agent Straight from `npx`, no clone, no Python. It comprehends the API, seals your key in the OS keychain, and wires it into Claude Code over stdio. ```bash theme={null} npx @geckovision/gecko add https://api.provider.com/openapi.json ``` It prompts once (hidden) for the key and injects it **live** at call time — the agent never sees it. Keyless APIs (e.g. Jupiter) skip the prompt. **No `openapi.json`?** That's the normal case for a painful API — `add` takes whatever you have: ```bash theme={null} npx @geckovision/gecko add https://docs.someapi.com # recovers a spec from the docs npx @geckovision/gecko add ./openapi.json # a file you already have npx @geckovision/gecko add api.stripe.com # a bare domain — Gecko finds it ``` ``` You: search the API for X Agent: ✓ called GET /v1/search?q=X → 200, first try ``` No integration code, no docs-diving, no key in sight. That's the whole loop. Every path has a **recorded mode** that runs the *same code* but synthesizes the response from the API's own schema — no network, no key, no spend. Falsify the calls before going live, then flip one flag (`--mode live`) for real data. ```bash theme={null} uv run python -m gecko.demo # goal → discover → correct call → data (recorded, $0) ``` **Gecko never holds your keys.** A provider's key is yours — sealed in *your* OS keychain, resolved only at call time. Control plane only: Gecko stores the API surface, never keys or response data. This whole path is **local** — it never touches Gecko's servers. ## Try it in 10 seconds — no install Give your agent a live, Gecko-comprehended surface and watch it call correctly — no `pip`, no spec, no key: ```bash theme={null} claude mcp add --transport http gecko-txline https://mcp.geckovision.tech/txline/mcp ``` That's **TxODDS TxLINE** — 18 first-call-correct tools over a World Cup API with a two-token on-chain paywall a coding agent does *not* one-shot. Served **recorded** (\$0/offline), so you explore the real surface without a subscription. `claude mcp add` is Claude-Code-only. In **Cursor**, **VS Code**, or any MCP client, add the same endpoint to your `mcp.json` — transport is **MCP Streamable HTTP** (`2025-11-25`), not SSE: ```jsonc theme={null} { "mcpServers": { "gecko-txline": { "type": "http", "url": "https://mcp.geckovision.tech/txline/mcp" } } } ``` ## Other ways in Bundles the skills + a live demo surface. ``` /plugin marketplace add GeckoVision/gecko-surf /plugin install gecko-surf@geckovision /make-agent-ready https://api.example.com/openapi.json ``` Prints the MCP URL + one-click add strings, then serves the API. ```bash theme={null} uvx --from "gecko-surf[serve]" gecko https://api.example.com/openapi.json ``` For your own app or agent loop. ```python theme={null} from gecko import AgentApiClient, public_session client = AgentApiClient(spec, session=public_session()) hit = client.search("what you want")[0] client.call(hit["name"], {...}, mode="recorded") ``` Recover a draft spec from the docs, then comprehend it. ```bash theme={null} uv run gecko from-docs https://api.example.com/docs ``` Review the draft (especially auth) before trusting it live. ## Good to know Nothing here pipes a remote script into a shell. Run in order and you never take an unchecked step: 1. **Check (no side effects):** `npx @geckovision/gecko doctor` — read-only; reports your setup and the exact next step. 2. **Dry-run (\$0):** `gecko serve ` defaults to **recorded** — no request reaches the real API, nothing is billed. 3. **Live:** add `--mode live` (and `gecko auth set` first for a keyed API). Gecko is open-source (Apache-2.0), installed from a public registry **with a live SLSA provenance attestation** tracing the package to its CI build — verifiable, not an opaque script. Control-plane only: it never stores your responses or your keys. Gecko refuses to trust a spec's `servers[]` host when the spec was fetched from a different origin (the token-exfil defense). Assert the real host yourself: ```bash theme={null} npx @geckovision/gecko add \ https://raw.githubusercontent.com/GeckoVision/gecko-surf/main/gecko/examples/colosseum_copilot_openapi.json \ --base-url https://copilot.colosseum.com/api/v1 --mode live ``` `add` prompts once for your PAT, seals it, pins the host, and connects in live mode. Drop `--mode live` to falsify the calls offline first. Linux (x64 + arm64) and Apple Silicon Macs — one command, no Python. On an Intel Mac or Windows, use the Python path (same CLI, your system's own certificates): ```bash theme={null} uvx gecko-surf add api.stripe.com # no install, needs Python/uv pip install gecko-surf && gecko add api.stripe.com # or a normal pip install ``` Serve behind an HTTPS tunnel with `--public-url https://` (trusted for the Host/Origin guard). Gecko also runs a hosted surface at `mcp.geckovision.tech`. A vectorized semantic index (today's catalog is lexical) and an auto-update job that re-comprehends an API when it ships a new version. See [Stay correct](/stay-correct). # Recorded mode ($0) Source: https://docs.geckovision.tech/recorded-mode One code path, two modes. Recorded mode synthesizes responses from the spec so you can prove the comprehension offline, for free, before going live. Gecko runs **one code path in two modes**. `recorded` and `live` differ *only at the transport edge* — same discovery, same tool selection, same request building. The only difference is where the response comes from. | Mode | Network | Cost | Response source | | ---------- | ------- | ----------- | ------------------------------------------------ | | `recorded` | none | \$0 | synthesized from the operation's response schema | | `live` | yes | per the API | the real upstream API | ## Why recorded mode exists The first deliverable for any live-API integration is a **free local simulation that can falsify it offline**. Live smoke is the final check, never the primary debugger. If the agent picks the wrong endpoint or builds a malformed request, recorded mode catches it before a single network call — or a single cent — is spent. Recorded mode proves the agent **selected the right call and built a well-formed request**. It does not prove the upstream returns that exact data — for that, run `live`. Recorded responses are schema-shaped samples, not real data. ## How the sample is built For each operation, Gecko finds the success response schema (`200` / `201` / `default`, JSON content) and synthesizes a minimal valid instance from it. The generator is **deterministic** — the same schema always yields the same sample — and walks the schema sensibly: * honors `example`, then `default`, then the first `enum` value * follows `anyOf` / `oneOf` (first branch) and merges `allOf` * builds objects from `properties`, arrays from `items` * emits typed placeholders for primitives (e.g. an ISO timestamp for a `date-time` string), with a bounded recursion depth This is what powers the `$0` demo: many real specs ship almost no response examples, so to demo and validate without live calls, Gecko synthesizes from the schema. ## Running it ```bash theme={null} uv run python -m gecko.demo # E2E recorded demo, $0 ``` Or programmatically: ```python theme={null} result = client.call(tool_name, args, mode="recorded") # { # "status": 200, # "request": "https://.../api/odds/snapshot/123", # "method": "GET", # "data": { ... schema-shaped sample ... }, # "mode": "recorded" # } ``` Switching to live is a one-word change once you have a [session](/access-and-auth): ```python theme={null} result = client.call(tool_name, args, mode="live") ``` Because the path is identical, a green recorded run is a strong signal the live call will be well-formed too — the remaining unknowns are purely network and credentials. # Roadmap Source: https://docs.geckovision.tech/roadmap What's live, what's coming, and what we'll never build. We label everything — no vaporware on this page. We label everything. **Live** = run it today. **Building** = designed and in progress. **Exploring** = we want your input before we commit. No vaporware on this page. ## Live today — V1, comprehension * **Ingest any OpenAPI → first-call-correct MCP tools** (`gecko `). Run it now. * **`gecko from-docs`** — an API with no OpenAPI? Point it at the doc site → a draft spec → agent tools. See [From docs](/from-docs). * **Invisible auth** — the credential is injected at call time, never in the tool defs, never seen by the agent. * **`$0` recorded mode** — falsify every call offline, from the schema, before you spend a token. * **Hosted MCP** — one-click add to Claude Code / Cursor / VS Code. * **Control-plane correctness corpus + replay** — call-outcome *metadata* (never payloads) that proves first-call-correctness. ## Building — V2, continuous correctness Designed, in progress. The primitives ship today; the scheduled pieces are being built. * **Stay-correct watcher** — notice when an API drifts, diff what moved, regenerate the tool defs, and tell you — *before* your agent breaks in prod. See [Stay correct](/stay-correct). * **The correctness corpus as a compounding asset** — every call teaches how to call an API right, so a new painful API is more first-call-correct because someone already paid the tax. * **Poisoning / tampering monitoring** — we treat every ingested spec and doc as **untrusted**. When a stable surface silently shifts — a moved auth location, a changed host, a dropped required field — we quarantine it and alert, instead of letting the agent fire a poisoned call. * **Vectorized semantic catalog · multi-API scale.** ## Exploring — V3, trust + Cloud Unbuilt. If one of these is the reason you'd adopt, tell us below — it moves up. * **Trust & verification** — *"is this the **right** call, is this response **sane**?"* * **Cloud** — hosted always-on watcher jobs, drift + poisoning alerts, team entitlements, and the shared correctness corpus that makes an API you've never called **day-one-correct**. ## Free vs Cloud The **`gecko-surf` engine is free and open-source, forever** — ingest, comprehend, first-call-correct tools, recorded mode, run it yourself. **Cloud** (hosted) adds what you don't want to operate: the always-on stay-correct watcher, drift + poisoning alerts, team entitlements, and the managed cross-customer corpus. Who pays, in one sentence: **the engine is free forever for builders; API providers pay a flat per-API subscription for hosted, drift-watched, agent-ready surfaces** — and nobody ever pays us a cut of an API call ([For API providers](/for-providers)). ## What we'll never build So the labels above stay credible: * **No browsable provider marketplace.** Point us at the OpenAPI URL — the flow is identical for every API. * **No payment rail, no custody** of your funds or your provider keys. We compose x402 / pay.sh; the provider charges you directly. * **No storage of your API responses, request values, or secrets.** The correctness corpus is metadata-only *by construction* — a fail-closed allowlist, not a policy you have to trust. ## Tell us what to comprehend next The Nth painful, paywalled, poorly-documented API — the one your agent *can't* one-shot. Open an issue and tell us. Public 👍s rank what we comprehend next. # Status Source: https://docs.geckovision.tech/status What's live, and what's next. ## What's live Comprehension is **live end-to-end on Solana mainnet** against a real, paywalled API (the TxODDS World Cup API) — and the same engine is proven keyless at scale: **Stripe — 587 tools, 99.8% first-call-correct · Twilio — 100% · Jupiter — 100%**. * ingest → catalog → question-shaped tools → access → first-call-correct request → real data * a **`$0` recorded mode** that runs the whole path offline — no subscription, no keys, no spend * **857 tests passing**, with a falsifiable first-call-correct scorecard * **API-agnostic by construction** — one adapter seam; a new API touches no engine code Ingest is OpenAPI 3.x, or a spec recovered from a docs page. ## What's next * **Multi-API correlations** — a spec-derived surface graph that plans the right *chain* of calls across APIs. * **Comprehension-native anti-poisoning** — provenance on every inferred edge, so a manipulated spec can't trick your agent. ## What Gecko is not It comprehends and consumes APIs. It doesn't verify the data an API returns, and it isn't a payment rail or a marketplace — it **composes on** x402, MCP, and [pay.sh](https://pay.sh). ## Payments x402 runs in **stub** mode by default. The on-chain subscribe is founder-run — the tooling simulates, a human broadcasts; Gecko never signs or broadcasts a mainnet transaction on its own. # Stay correct Source: https://docs.geckovision.tech/stay-correct What happens when the upstream API changes — content-addressed surfaces, the regenerable-tool model, and the corpus tripwire. The watcher is V2. It's Saturday. Nobody shipped anything. Your agent is down anyway — upstream renamed a field, moved a path, tightened an enum, and your hand-written client knew none of it. It keeps sending the old shape; the API keeps returning 422; the agent keeps confidently retrying a call that can no longer succeed. A hand-written client is a **frozen snapshot of an API that doesn't hold still.** Every rename is a manual diff a human has to notice, read, and re-code. Multiply by the Nth painful API and "keep the integrations correct" becomes a standing on-call burden. ## Why the generated-tool model changes the failure mode Your agent never calls a hand-written client through Gecko — it calls **tools generated from the spec.** Tool generation is a *pure function of the surface*: same spec in, same tools out. If the source of truth moves, the tools move with it — you re-comprehend the surface instead of hand-editing a client. Gecko knows which surface a tool came from, down to the revision: ``` surface_rev = sha256(canonicalized spec)[:12] ``` Same spec → same `surface_rev`; any edit bumps it. It's a content fingerprint stamped on the cached comprehension and on **every** correctness record in the corpus. Editing one field flips surface_rev and regenerates the affected tool The loop below is **on the roadmap; the watcher, the op-level diff, and the alert are V2.** What's shipped today: content-addressed surfaces, comprehension as a pure function of the spec, and the validator replay. The architecture makes the watcher a small addition, not a rewrite. ## The stay-correct loop Poll the spec URL, take a provider webhook, or re-scrape the docs. Recompute `surface_rev`. Unchanged? Nothing happened, stop. Run the same comprehension engine on the new spec. Old `surface_rev` vs new: what params were added, removed, renamed, retyped; what endpoints moved. Emit the new tool defs and a human-readable changelog of what moved. ## The corpus is your early-warning system There's a second drift signal that doesn't need the spec to change — because providers don't always tell you. Every call your agent makes through Gecko logs a **control-plane-only** outcome: status class, error class, first-call-correct or not, and the `surface_rev` it ran against — **never** the response body, a param value, or a token (the writer is a fail-closed allowlist). When a tool that was first-call-correct for ten thousand calls starts returning `422` / `404` under the same `surface_rev`, the corpus tells you *something moved* before a human files a bug. ## In one line A hand-written client makes *you* the diffing engine: read the changelog, edit the code, hope you caught everything before Saturday. Gecko makes the **spec** the source of truth and the **tools a regenerable function of it** — so a change propagates instead of rotting, and the corpus warns you when the surface moves under a spec that never changed. # Example: TxLINE trading agent Source: https://docs.geckovision.tech/txline-trading-agent Start a new Solana project with Gecko — an agent comprehends the paywalled TxLINE World Cup odds API, flags sharp moves, and settles a prediction market on-chain, with a policy-gated wallet. Runs $0 offline. A complete, runnable use case for the whole thesis on one *painful, paywalled* API. A trader wants a Solana agent that watches the World Cup and settles prediction markets. Starting from nothing — with **Gecko as the brain** and a **policy-gated wallet as the hands** — the agent comprehends [TxLINE](https://txodds.com) (odds behind a two-token on-chain paywall), flags **sharp moves**, and settles a market against TxLINE's **on-chain Merkle proof**. The user reads no docs and writes no integration code. It runs **`$0` offline** (recorded feed + a sandbox wallet); mainnet swaps only the signer edge. ## See the whole thing in one run ```bash theme={null} git clone https://github.com/GeckoVision/gecko-surf && cd gecko-surf && uv sync uv run python -m examples.txline_sharp_agent.story ``` The user's *entire* on-chain surface is **three acts**: fund a wallet, set it up once, and **authorize one policy** (`spend ≤ $50 for {subscription, settlement}`). Nothing else is on the user — the agent does the rest. One line turns TxLINE into **18 first-call-correct tools**. Auth-gated odds tools stay hidden until a session can satisfy them, so the agent can't mis-call what it can't see. No docs, no hand-written client. ```bash theme={null} npx @geckovision/gecko add \ examples/txline_demo/spec/txline_openapi.yaml \ --base-url https://txline.txodds.com --mode recorded ``` The agent builds the on-chain subscribe transaction; the wallet signs it **within** the authorized policy. Gecko never touches a key. Successive odds snapshots run through the detector; a shift past the threshold is the trading signal: `fixture 42 · Home 45.6% → 54.8% (+9.2pp) ⚡`. Every TxLINE call is **risk-scored** by the security gateway. The agent maps the 3-stage Merkle proof onto the on-chain `validate_stat` instruction and the wallet signs the settle — the program never decides the outcome, the proof does. The user did **3 acts** (fund · set up · authorize). The agent comprehended a paywalled API, subscribed, caught the move, and settled a market — the wallet signing only within the policy, **Gecko never holding a key or a dollar**. ## The agentic wallet in the middle The user funds the wallet with the budgeted USDC. Funding is always the user's side. One-time wallet setup (social login on a Privy/Phantom embedded wallet, or a `pay --sandbox` ephemeral wallet for the `$0` demo). One policy: a spend cap + an allow-list of purposes. The wallet signs **only** within it — an over-cap request is refused. **Gecko is the brain; the wallet is the policy-gated hands.** They meet at a `WalletSeam` — an injected boundary, exactly like Gecko's `Session` seam — so the wallet is pluggable and Gecko is never the signer. * **Mainnet hands:** **Privy** (Solana instruction-level policy enforced in-enclave at signing) or **Phantom** (embedded wallet + social login, MCP-native). **OKX OnchainOS** is a valid alternate. * **The rail:** **pay.sh** sits *on top* as the x402 payment rail — the wallet signs, the rail settles. (pay.sh is a rail, not a wallet.) * **Deferred:** MagicBlock — its session keys only bind if the counterparty program integrated them, so they don't provide bounded authority for an arbitrary third-party API. Gecko is **control-plane only** — it never holds keys, funds, or response payloads. The offline sim **profiles** transactions (via Surfpool's `surfnet_profileTransaction`) and **never signs or broadcasts**. A real mainnet settle is always the user's own signed action, under the policy they pre-authorized. ## Break it into parts Each piece runs on its own, `$0` and offline: | Command | What it shows | | ------------------------------------------------------ | -------------------------------------------------------------- | | `python -m examples.txline_sharp_agent.story` | **The whole use case, end to end** | | `python -m examples.txline_sharp_agent.demo` | Comprehension + first-call-correct call + sharp-move detection | | `python -m examples.txline_sharp_agent.settlement_sim` | A flagged move → the on-chain `validate_stat` settlement plan | | `python -m examples.txline_sharp_agent.wallet_sim` | The 3-step agentic wallet, policy-bounded | The example also bundles curated Solana subagents (`defi-engineer`, `solana-architect`, `solana-qa-engineer`) and a Surfpool MCP config, so a forked project can build the on-chain settlement side. See the example's [README on GitHub](https://github.com/GeckoVision/gecko-surf/tree/main/examples/txline_sharp_agent). ## Going live Recorded mode needs nothing. For live TxLINE data the user completes an on-chain subscription (fund a wallet + sign — their action); the agent drives the guest → subscribe → activate handshake and Gecko seals the two tokens in the OS keychain. Same tool-building code path — only the transport edge changes. See [Access & auth](/access-and-auth). `gecko add ` and your agent is calling it correctly, first try — then integrate a policy-gated wallet the same way.