GHAN— by singular Get started

The GHAN MCP server

GHAN ships every write capability as an MCP tool before it ships anywhere else. A founder's coding agent can register an app, read a machine-readable score, integrate the SDK, fund a wallet, run a campaign and pull the raw signed ledger without a human opening a browser.

Auth

register_app returns an API key. Send it as Authorization: Bearer <key>. Read tools that describe the network rather than an account need no key at all.

Tools

register_app

register_app {
  name: string,
  platform: "mac" | "win",
  bundle_id: string,
  domain: string,
  download_url: string,
  contact_email: string
} -> { app_id, api_key, status: "pending", scoring_job_id }

Queues the vetting gate. Status is pending until the gate completes.

get_score

get_score { app_id } -> {
  status: "pending" | "approved" | "throttled" | "live" | "suspended" | "rejected",
  gate: { signed: bool, malware_clean: bool, domain_age_ok: bool,
          contact_verified: bool, bundle_match: bool },
  reputation: { total, ai_visibility, cadence, reviews, coherence },
  behavior: { retention_48h, uninstall_rate, canary, complaints } | null,
  next_review_at,
  reasons: [ code ]
}

Rejection reasons are stable codes. An agent can act on them without parsing English.

get_integration_guide

get_integration_guide {} -> markdown

Returns the SDK quickstart verbatim. Public. This exists so an agent reads the guide from the source of truth rather than scraping a website.

top_up

top_up { app_id, amount_cents } -> { checkout_url } | HTTP 402

If the caller can pay machine-to-machine, the endpoint answers HTTP 402 with an x402 challenge settled in USDC on Base. Otherwise it returns a Stripe Checkout URL that bundles payment, the terms click-wrap, and identity verification where required.

create_campaign

create_campaign { app_id, categories: [string], daily_budget_cents, max_bid_cents? }
  -> { campaign_id, floor_cents, max_bid_cents, status: "throttled" }

floor_cents comes from the rate card and is always available to you. max_bid_cents is optional: omit it and the campaign buys at floor; set it at or above the floor and the campaign competes for priority in contested inventory at second price, paying one cent above the next-highest competing bid. See bidding.

pause_campaign / resume_campaign

pause_campaign  { campaign_id } -> { status }
resume_campaign { campaign_id } -> { status }

get_ledger

get_ledger { app_id, from, to } -> { lines: [ {
  id, ts, type, amount_cents, counterparty_app_id,
  event_chain_id, balance_after, note
} ] }

The audit-me tool. Every line carries an event-chain reference you can resolve and verify against your own signature. Types are topup, earn, charge, escrow_hold, escrow_release, clawback, payout, adjustment.

get_stats

get_stats { app_id, period } -> {
  impressions, clicks, installs, cleared, retention_48h,
  floor_cents, avg_clearing_price_cents,
  fraud_rejected: { [reason_code]: count }
}

Rejections come back with reason codes. Transparency applies to the installs you were not paid for.

get_rate_card

get_rate_card {} -> { categories: [ { key, label, floor_cents_min, floor_cents_max } ],
                      take_rate, credit_bonus, reserved_floor_share }

Public, unauthenticated.

get_network_stats

get_network_stats {} -> { avg_cpi_by_category, clearing_rate, fraud_pct, period }

Public, unauthenticated. The published transparency numbers.

request_payout

request_payout { app_id } -> { transfer_id, amount_cents } | { error: "below_minimum" }

Stripe Connect transfer, minimum EUR 50.

A whole onboarding, as an agent sees it

1. get_rate_card {}                     # is this worth doing
2. register_app { ... }                 # -> app_id, api_key
3. get_score { app_id }                 # -> gate failures as codes, or approved
4. get_integration_guide {}             # -> wire the SDK, open a PR
   ── human ships the release ──
5. top_up { app_id, amount_cents }      # -> 402, or a checkout URL for a human
6. create_campaign { ... }              # -> throttled, ramps as chains clear
7. get_stats / get_ledger               # -> verify everything above

Two of those steps involve a person. The rest is agent to agent, which is the whole design.

Questions people ask about this

What is the MCP endpoint?

The GHAN MCP server speaks both stdio and streamable HTTP. The HTTP endpoint and its transport details are published in the server card at /mcp/server-card.json, which is discovered through the AI catalog at /.well-known/ai-catalog.json rather than from a well-known path, per the MCP specification.

Which tools need authentication?

Read tools that describe the network rather than an account are public - get_rate_card, get_network_stats and get_integration_guide. Everything scoped to an app requires the API key issued by register_app, sent as a bearer token.

Can an agent spend money without a human?

Within a ceiling a human set once. GHAN deliberately keeps two moments human - shipping the release that contains the SDK, and authorising money. The second can be satisfied ahead of time with a pre-capped agent wallet or an x402 machine payment, so an agent can top up and spend up to a limit without a click each time, but the limit itself is set by a person.

Where is the server card?

At /mcp/server-card.json, next to the MCP endpoint, and referenced from /.well-known/ai-catalog.json. It is deliberately not at a /.well-known/mcp/ path, because the MCP specification rules that location out.

Machine-readable versions of this page: markdown · llms.txt · llms-full.txt · OpenAPI · AI catalog