---
name: gecko-setup
description: Set up Gecko for this user - wire the hosted MCP surface into their agent client and verify a first real call
user-invocable: true
allowed-tools: Bash(curl:*), Bash(claude:*), Bash(npx:*), Bash(uvx:*), Bash(command:*)
supported_surfaces: [mcp, cli, skills, api]
metadata:
  author: gecko
  url: https://geckovision.tech/agents.md
---

# Gecko for agents

Gecko turns APIs and Solana programs into calls you can check before they
count. It never holds a key and never signs. This file tells you what to do
next; https://geckovision.tech/llms.txt tells you what exists.

## Start here

Pick the line that matches how you arrived, and read only that branch.

1. You have this link and a task that needs an API or a Solana program.
   Connect over MCP (next section). A session that arrives with a link and no
   task is here to get set up: treat the setup as the work, not as a question
   to put to the user.
2. You have a question about Gecko. Answer it from https://geckovision.tech/llms.txt. None of
   the setup applies.
3. You are making YOUR OWN API agent-ready, or you write code that keeps
   running after this session ends. Skip the hosted MCP and read "Choose
   another integration path" below.

## Connect over MCP

### Step 1: Fetch the config

One file carries every client's exact wiring:

```bash
curl -s https://geckovision.tech/mcp-config.json
```

### Step 2: Install for the client you are running in

- **Claude Code**: `claude mcp add --transport http gecko https://mcp.geckovision.tech/orquestra/mcp`
- **Claude web / desktop**: Settings -> Connectors -> Add custom connector with
  `https://mcp.geckovision.tech/orquestra/mcp` (the web UI takes only the URL; no JSON config there).
- **Cursor**: merge the `clients.cursor.json` block from mcp-config.json into
  `~/.cursor/mcp.json`.
- **VS Code**: merge `clients.vscode.json` into `.vscode/mcp.json`.
- **Any other MCP client**: `clients.generic_mcp_json` is the plain
  `mcpServers` shape. Clients differ on the top-level key; your client's own
  documentation names the exact one.

No account, no API key: the surface above is open. Gated surfaces answer 401
with a self-serve mint path; details in https://geckovision.tech/auth.md.

### Step 3: Verify with a real call

List the tools, then make one read-only call: `list_stores` (browses real
Solana storefronts, free) or `find_start` with a plain question. If the client
cannot list Gecko's tools, re-check step 2. The config is declarative, so a
typo in the URL is the usual fault.

### Raw MCP over HTTP (no client)

If you speak HTTP directly, the endpoint is Streamable HTTP. Four requests
open a session and list the tools. Responses arrive as server-sent events:
read the line that starts with `data:`.

```bash
MCP=https://mcp.geckovision.tech/orquestra/mcp
H='content-type: application/json'
A='accept: application/json, text/event-stream'

# 1. initialize: the response header mcp-session-id is your session
SID=$(curl -si -X POST "$MCP" -H "$H" -H "$A" -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"my-agent","version":"1"}}}' \
  | grep -i '^mcp-session-id:' | tr -d '\r' | cut -d' ' -f2)

# 2. acknowledge
curl -s -X POST "$MCP" -H "$H" -H "$A" -H "mcp-session-id: $SID" -d '{"jsonrpc":"2.0","method":"notifications/initialized"}'

# 3. list the tools
curl -s -X POST "$MCP" -H "$H" -H "$A" -H "mcp-session-id: $SID" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | grep '^data:' | cut -c6-

# 4. call one (tools/call with name + arguments); the result is JSON text in content[0].text
curl -s -X POST "$MCP" -H "$H" -H "$A" -H "mcp-session-id: $SID" -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_stores","arguments":{"network":"mainnet"}}}' | grep '^data:' | cut -c6-
```

The server answers `initialize` with the protocol version it will speak,
which is the version you asked for when it supports it. The server card at
https://geckovision.tech/.well-known/mcp/server-card.json lists the newest version it
supports and its `serverUrl` is the host root (comprehend_api,
list_surfaces); the remotes in the card are the surfaces, and the one this
file wires is `https://mcp.geckovision.tech/orquestra/mcp`. `serverInfo.version` in the initialize
result is the engine version, the same number the card carries.

## Definition of done

You are connected when you can list or call a Gecko tool. A configuration
shown in the chat is a suggestion, not a connection. An empty tool list is
not a verdict that Gecko is unavailable: it means the connection is not set
up yet, and setting it up is your work.

## The order for money paths

Every path that can move funds ends in UNSIGNED bytes plus a receipt. The
order matters, because step 3 starts a clock.

0. A HUMAN ENROLS THE SIGNER FIRST. Every signer path (PayBox, Phantom, Privy)
   needs a one-time human step: an OAuth connect, a desktop install, or a
   login on the machine. An agent with no client and no human has no path to
   funds; say so instead of looping.
1. BROWSE with `list_stores` (or `find_start` for other programs). Free, no
   expiry, every price and mint. Do all your deciding here. `network` has no
   default: say `mainnet`. A keyless call to `prepare_purchase` (no `buyer`)
   confirms the order resolved and names the signers that reach your client;
   it builds nothing and starts no clock.
2. GET A SIGNER before you need one, and warm it up. Add a signer connector
   (PayBox at https://api.paybox.sh/mcp reaches chat clients; Phantom's or
   Privy's local servers reach desktop clients). While still browsing: load
   its tools, ask it for the wallet address, FUND that address with the price
   plus a little SOL, and check its approval mode. If the signer needs human
   approval, settle it first. Approve, then prepare, then sign.
3. PREPARE with `prepare_purchase` only once the buyer has chosen. It starts a
   ~60-second clock: the bytes carry a live blockhash and expire with it; the
   exact budget comes back in `expires`. Prepare late, never several options.
4. SIGN those exact bytes. A hosted signer is asynchronous: it returns a
   request id, and you poll for the artifact. Never re-call the signing tool to
   finish one; that starts a second operation. Then VERIFY with
   `verify_signed_transaction`, passing the `binding` from prepare and
   `expires.last_valid_block_height`.
5. SUBMIT with `submit_transaction`. It re-verifies, sends, rebroadcasts the
   same bytes until the node confirms or the blockhash expires, and reports
   which. If a signer tool returns an error, reconcile first: check the
   signer's request status and the chain before any second operation. An
   error from a signer is a claim, not a fact.

### What a successful `prepare_purchase` returns

Read this before the clock starts, so the sign, verify and submit calls are
wired in advance. The shape (values shortened; every field is real):

```json
{
  "refused": false,
  "status": "pass",
  "units_consumed": 42494,
  "binding": "ff4a4ba6...16f7985f",
  "binding_strength": "exact",
  "network": "mainnet",
  "fee_payer": "<your buyer address>",
  "accounts": [{ "account": "receipts", "address": "H7Bj...Dt5V", "role": "..." }],
  "transaction": { "signed": false, "encoding": "base64", "unsigned_transaction": "AQAA...AAA=" },
  "expires": { "blockhash": "9Bbn...eYyv", "last_valid_block_height": 371004211, "blocks_remaining": 149, "seconds_remaining_estimate": 60 },
  "submit": { "rpc_url": "https://api.mainnet-beta.solana.com", "preflight_commitment": "confirmed" },
  "next_steps": [ { "step": "sign" }, { "step": "verify", "tool": "verify_signed_transaction", "binding": "ff4a...985f" }, { "step": "submit", "tool": "submit_transaction" } ]
}
```

Sign `transaction.unsigned_transaction`. Then call
`verify_signed_transaction` with `transaction` (the signed base64),
`binding`, `binding_strength` and `expires.last_valid_block_height`; then
`submit_transaction` with the same three plus `rpc_url` from `submit`.

`binding` is a hash of the exact message bytes the receipt attests.
`binding_strength` says how much of the message it covers: `exact` covers the
blockhash too, so the receipt dies with the blockhash; `structural` covers
the instructions and accounts but not the blockhash. `prepare_purchase`
returns `exact`, and `submit_transaction` accepts nothing weaker.

A refusal is an answer, not an error. It is a JSON result with
`refused: true`, a `code`, and a `reason` that says what to change. Read it
and act on it; do not retry the same call.

## Vocabulary

- **surface**: one comprehended API or program, served at its own MCP mount,
  for example `/orquestra/mcp`.
- **tool**: one MCP tool on a surface. Question-shaped, annotated with
  read-only and destructive hints.
- **refusal**: a result with `refused: true`. The call did not proceed, and
  `reason` says why. Not a transport error.
- **receipt**: the simulation record attached to prepared bytes: status,
  compute units, what would move.
- **binding**: a hash that ties a receipt to the exact message bytes.
  `verify_signed_transaction` checks signed bytes against it.
- **signer**: whatever holds the key and signs: PayBox, Phantom, Privy, or the
  user's own wallet. Gecko is not a wallet, not a signer, and not a payment
  rail.

## Choose another integration path

| Situation | Use |
|---|---|
| Interactive MCP client (Claude, Cursor, VS Code) | The hosted surface: steps 1 to 3 above |
| Headless code, a script, a server | Raw MCP over HTTP (above) |
| Client that only speaks local stdio MCP | Run Gecko locally: `uvx --from "gecko-surf[serve]" gecko serve <your-api> --stdio` |
| Coding agent onboarding an API you provide | `npx skills add GeckoVision/gecko-surf`, then the api-agent-ready skill; or `npx @geckovision/gecko add https://api.example.com/openapi.json` |
| Agent with a wallet that must buy or swap on Solana | The hosted orquestra surface plus a signer; follow "The order for money paths" |

Claude Code plugin: `/plugin marketplace add GeckoVision/gecko-surf`

## What this domain is

Gecko lets an agent verify an API call against the real surface before
sending it, so the first call is correct, and for money paths, checked before
it counts. Docs: https://docs.geckovision.tech (agent index: https://docs.geckovision.tech/llms.txt).

## Machine-readable artifacts on this domain

- https://geckovision.tech/llms.txt: curated index (llmstxt.org shape)
- https://geckovision.tech/mcp-config.json: every client's MCP wiring, one file
- https://geckovision.tech/AGENTS.md: this file, uppercase alias
- https://geckovision.tech/llms-full.txt: full landing content as Markdown
- https://geckovision.tech/auth.md: the auth story (anonymous API + self-serve MCP key)
- https://geckovision.tech/pricing.md: honest machine-readable pricing
- https://geckovision.tech/versioning.md: API versioning and deprecation policy
- https://geckovision.tech/.well-known/api-catalog: RFC 9727 API catalog linkset
- https://geckovision.tech/index.md: Markdown twin of the homepage
- https://geckovision.tech/gecko.json + https://geckovision.tech/.well-known/gecko.json: product manifest
- https://geckovision.tech/.well-known/agent-card.json: A2A-style card for the MCP endpoint
- https://geckovision.tech/.well-known/ard.json: agent-readiness self-assessment
- https://geckovision.tech/.well-known/oauth-protected-resource: RFC 9728 metadata
- https://geckovision.tech/openapi.json: the public HTTP contract
- https://geckovision.tech/.well-known/mcp/server-card.json: the MCP server card

## Constraints

- The hosted MCP endpoint requires no API key on its open surfaces.
- Source is open: https://github.com/GeckoVision/gecko-surf

## Do not

- Do not scrape rendered HTML for install commands; the canonical wiring is
  https://geckovision.tech/mcp-config.json and will not match client-side rendered text.
- Do not ask the user to paste key material. A signer holds the key; Gecko
  never does.
- Do not prepare several purchase options to compare them; browse first,
  prepare once.
