> ## Documentation Index
> Fetch the complete documentation index at: https://docs.geckovision.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# The 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`.

<Tip>
  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).
</Tip>

## 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://<tunnel>` 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

<Steps>
  <Step title="Discover">
    Call `search_capabilities` with the goal in plain language → ranked tool names.
  </Step>

  <Step title="Inspect">
    Read the question-shaped `description` and `inputSchema` of the top tool.
  </Step>

  <Step title="Call">
    Call the tool by name with the inputs. Gecko builds the correct request,
    injects auth, and returns the result.
  </Step>
</Steps>

## 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")
```

<Note>
  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.
</Note>
