Metadata-Version: 2.4
Name: gecko-surf
Version: 0.4.10
Summary: Make any API agent-usable without integration code. V1: comprehension layer — turn a human-shaped OpenAPI surface into question-shaped, first-call-correct agent tools. (Working name; rename on brand pick.)
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Requires-Python: >=3.11
Requires-Dist: keyring>=25
Requires-Dist: pyyaml>=6.0
Provides-Extra: credentials
Provides-Extra: dense
Requires-Dist: anthropic>=0.40; extra == 'dense'
Requires-Dist: certifi>=2024.0; extra == 'dense'
Requires-Dist: pymongo>=4.10; extra == 'dense'
Provides-Extra: events
Requires-Dist: pymongo>=4.9; extra == 'events'
Provides-Extra: fcc
Requires-Dist: anthropic>=0.40; extra == 'fcc'
Provides-Extra: serve
Requires-Dist: mcp[cli]>=1.28.1; extra == 'serve'
Requires-Dist: uvicorn>=0.49.0; extra == 'serve'
Provides-Extra: sosbot
Requires-Dist: anthropic>=0.40; extra == 'sosbot'
Requires-Dist: openai>=1.40; extra == 'sosbot'
Requires-Dist: python-telegram-bot>=21; extra == 'sosbot'
Description-Content-Type: text/markdown

# gecko-surf — make any API agent-usable without integration code

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

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-3776AB.svg)](https://www.python.org/)
[![uv](https://img.shields.io/badge/uv-managed-DE5FE9.svg)](https://docs.astral.sh/uv/)
[![Claude Code](https://img.shields.io/badge/surface-MCP-D97757.svg)](https://modelcontextprotocol.io/)
[![x402](https://img.shields.io/badge/x402-stub%20%7C%20live-9945FF.svg)](https://x402.org/)
[![status](https://img.shields.io/badge/V1-live%20on%20one%20API-orange.svg)](#-status-honest)

> **Coding agents already one-shot clean, documented APIs. They break on the painful
> ones** — messy, paywalled, half-documented, always drifting. Today your options are:
> dump the whole spec (your agent picks the wrong call and sends malformed requests)
> or hand-write an MCP wrapper (tedious — and stale the next time the API changes).
>
> **Gecko reads the API and turns it into tools your agent calls right the _first_
> time — no integration code.** Point an agent at an API — even one behind human-shaped
> docs and a paywall — add it in one line, and it finds the right call, drives the
> access/auth handshake, and calls the real API directly. Free and open source.
>
> *Docs and endpoints are built for humans. Gecko translates them for agents.*

<p align="center">
  <img src="docs/assets/hero.gif" alt="One command: install gecko-surf, then comprehend any API into first-call-correct MCP tools" width="820">
</p>

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* (OpenAPI/docs), 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

| Layer | What it does | Who |
|---|---|---|
| APIs get **PAID** | billing / settlement rail | Metera (gate402), MCPay |
| skills get **DISTRIBUTED** | marketplace / discovery | frames.ag, Bazaar |
| **APIs get USED** | **comprehension / consumption** | **Gecko** |

Gecko **composes on top of** x402 / MCP / pay.sh — it *consumes* a payment catalog
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.

---

## Try it in 10 seconds — one line, zero install

Give your agent a **Gecko-comprehended surface** and watch it make first-call-correct
calls — no `pip`, no spec, no key:

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

That connects your agent to the **TxODDS TxLINE** World Cup API — 18 question-shaped,
first-call-correct tools over an API with a two-token on-chain paywall, served
agent-native. It's a **recorded demo** (responses synthesized from schema, `$0`,
offline — so you can explore the surface without a subscription); point it at your own
TxLINE session for live data. Also live: **Jito** at `/jito/mcp`.

**Not using Claude Code?** `claude mcp add` and `/plugin` are Claude-Code-only. Everywhere
else — **Cursor** (`~/.cursor/mcp.json`), **VS Code**, or any MCP client — add the same
endpoint to your `mcp.json`:

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

The transport is **MCP Streamable HTTP** (protocol `2025-11-25`), not SSE. From the Python
MCP SDK, connect with `mcp.client.streamable_http.streamablehttp_client(url)` (an
`sse_client` will `400`).

This is the fastest way to *see what Gecko does* before you bring your own API. When
you're ready to make **your** API agent-usable, jump to
[Make any API agent-usable](#make-any-api-agent-usable) below.

---

## ⚠️ Status (honest)

V1 is **live on mainnet, end-to-end, against the real TxODDS World Cup API**: ingest →
comprehend → catalog → access (a two-token on-chain subscribe) → first-call-correct →
real data. A **$0 recorded mode** runs the entire path offline with no subscription.
**442 tests pass.**

What is **not** proven: **consumer willingness-to-pay** — the actual decider for the
business. That is discovery-interview work, not a demo claim. So: never read this repo
as *"Gecko is a proven business."* What is real today is a **working comprehension
path on one genuinely painful API**, and a clean, API-agnostic engine behind it.

---

## Watch it run — the 70-second launch demo

<p align="center">
  <img src="docs/assets/launch.gif" alt="Gecko launch demo — comprehend TxODDS into 8/8 first-call-correct tools + live odds; block a poisoned spec 8/8→0/8; gecko test writes 32/32 checks" width="820">
</p>

Three acts, **every number from a real run**:

- **Plug in** a paywalled API (TxODDS) → 18 ops comprehended, **8/8 first-call-correct**, live World Cup odds.
- **Stay safe** → a poisoned spec that drains a naive agent **8/8** is blocked **0/8**, benign calls still served — caught in simulation, before any signature exists.
- **Stay correct** → `gecko test` writes **32/32** first-call-correctness checks and emits them to CI.

---

## Architecture

Gecko is a **control plane**, not a data plane. It 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 any API
unilaterally.

```mermaid
flowchart TD
    A["AI agent<br/>(has a goal, no API docs)"] -->|"what can this API do for X?"| S

    subgraph SC["Gecko — comprehension layer (control plane)"]
        direction TB
        ING[("ingest<br/>OpenAPI / docs — the *surface* only")]
        CAT["catalog<br/>intent → endpoint"]
        TOOL["tools<br/>question-shaped, first-call-correct<br/>(auth hidden)"]
        ACC["access<br/>subscribe / session handshake"]
        ING --> CAT --> TOOL
        TOOL --> ACC
    end

    S --> TOOL
    ACC -->|"injects auth"| CALL
    A -->|"calls the real API directly"| CALL["the real API<br/>(data plane — Gecko never stores it)"]
    CALL -->|"data"| A
```

1. **Ingest** the API surface (OpenAPI 3.x) → normalized operations + params (`$ref`
   resolved, cycle/depth guarded). Never the response data.
2. **Catalog** — a structured capability list (intent → endpoint). Lexical at this
   scale; no vectors.
3. **Comprehend** — each operation becomes a question-shaped tool def an agent picks
   correctly with no API docs. Auth headers are hidden.
4. **Access** — drive the access/subscription handshake; the seam is one function,
   `Session.auth_headers()`.
5. **Call** — the agent calls the real API directly; Gecko injects credentials and
   stays out of the data path.
6. **Validate** — replay calls, confirm first-call-correct, log outcomes (JSONL). That
   log is the seed of the V2 **correctness corpus** — the compounding moat.

---

## 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 |
| **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 |

---

## Make any API agent-usable

Point it at an OpenAPI and your agent can call it — no client code, auth handled,
first call correct. **Two ways in — by where your agent lives:**

**A · In Claude Code — install the plugin** (skills + commands + a live demo surface):

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

Installing wires the live `gecko-txline` demo surface (working tools, zero setup) **and**
gives you the skills/commands: `/make-agent-ready` comprehends your API, serves it over
MCP, and prints the one-click add string — plus `/setup-x402` and the anti-poisoning guard.

**B · Anywhere else — install the CLI** (Cursor, VS Code, any agent framework, or a plain terminal):

```bash
# no-install, nothing to trust — a versioned package, run directly:
uvx --from "gecko-surf[serve]" gecko <openapi-url>

# or the one-line installer — but VERIFY it first (an agent should never blind-execute):
python3 <(curl -fsSL https://raw.githubusercontent.com/GeckoVision/gecko-surf/main/scripts/verify_install.py)
#   → checks the served script's SHA-256 + static-scans it; prints SAFE/UNSAFE
curl -fsSL https://get.geckovision.tech/install.sh | bash    # only after it says SAFE
gecko <openapi-url>
```

> **Prove it's safe before you run it.** `verify_install.py` (stdlib-only, readable) confirms
> the installer is **tamper-evident** (SHA-256 matches the value published in this repo),
> **no-blind-execute** (the only pipe-to-shell is the official `uv` installer; everything
> else pins a versioned GitHub release), and **pattern-clean** (no eval, no credential reads,
> no exfil). Prefer the `uvx` line and there's nothing to verify at all.

`gecko <url>` prints the comprehension summary, the MCP URL, and a **one-click add** for
each host — a **Cursor** or **VS Code** deeplink to click, or the raw **MCP URL** to point
any framework at. Building your own app? Skip the server and embed the SDK (below).

**Claude Code → the Marketplace; everything else → the CLI.** You don't need both.

**Or embed the SDK** in your own app:

```python
from gecko import AgentApiClient, public_session

client = AgentApiClient(spec, session=public_session())
hit = client.search("what you want")[0]            # intent → right endpoint
client.call(hit["name"], {...}, mode="recorded")   # correct call; "live" for real data
```

A complete forkable example: [`examples/_starter/`](examples/_starter/) — an app on
*any* API in ~20 lines, runnable at $0. For a full agent (Telegram + an LLM tool-loop),
see [`examples/sos_vzla_bot/`](examples/sos_vzla_bot/).

### Fetch surfaces from the registry

Surfaces can be served straight from the Gecko registry — fixes propagate as
rev bumps, no package upgrade:

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

Free surfaces need no account. Premium surfaces take a Gecko key
(`GECKO_API_KEY`), issued agent-natively: `POST /registry/keys {email}` →
email OTP → `POST /registry/keys/verify` → `gk_live_...` (shown once; we
store only a salted hash). Your PROVIDER key never travels to Gecko — the
runner injects it locally and calls the provider directly.

---

## Develop / falsify offline ($0, no keys, no subscription)

```bash
git clone https://github.com/GeckoVision/gecko-surf
cd gecko-surf && uv sync
uv run pytest                       # 442 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`](scripts/SUBSCRIBE.md) — then pass a real `Session`:

```python
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/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 + 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` (442 tests) |

---

## Environment variables

**Source of truth:** [`.env.example`](.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

```bash
uv run ruff format && uv run ruff check --fix
uv run mypy gecko
uv run pytest                       # targeted invocations preferred
uv run python -m gecko.demo      # $0 recorded smoke
```

See [`CLAUDE.md`](CLAUDE.md) for the architecture invariants, the subagent team, and
conventions.

---

## Team

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

---

## License

**Apache License 2.0** — see [`LICENSE`](LICENSE) and [`NOTICE`](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.*
