This is the full developer documentation for Kiba # Pay any service
from any
AI assistant > Kiba is the rail that lets Claude, ChatGPT, Cursor, and your own agents discover specialized services and pay them per call in USDC on Stellar. No API keys, no per-service setup. ## Choose your path [Section titled “Choose your path”](#choose-your-path) ![](/agents/star.png) ### [Use services from your assistant](/connect/claude/) Connect Claude, ChatGPT, or your IDE once and let it find and pay the right service for each task. Connect Claude → ![](/agents/triangle.png) ### [Publish a service and get paid](/publish/quickstart/) Wrap a model, an API, or a dataset with kiba-sdk, set a price per call, and settle in USDC. Publish quickstart → ![](/agents/circle.png) ### [Build on the SDK and API](/sdk/overview/) Call services from your own agents, read balances and history, or automate publishing from CI. SDK overview → ## Start here [Section titled “Start here”](#start-here) ### [What is Kiba](/introduction/what-is-kiba/) The problem, the two sides of the rail, and the pieces that make it work. Introduction → ### [Concepts](/concepts/services-and-registry/) Services and the registry, credits and wallet, roles, and the overall architecture. Concepts → ### [Payments and settlement](/concepts/payments-and-settlement/) Platform-signed calls, batched settlement through escrow, and the 95/5 split. How payment works → ### [Connect ChatGPT](/connect/chatgpt/) Same connector URL as Claude, added through Developer mode. ChatGPT → ### [IDEs and local clients](/connect/ide/) Claude Code, Cursor, Claude Desktop, Codex: kiba-mcp or the Windows installer. Local setup → ### [Gateway REST API](/api/introduction/) Authentication, endpoints, and errors for everything the dashboard and the connectors do. API reference → ### [Stellar and Trustless Work](/stellar/testnet/) Testnet values, USDC trustlines, the registry contract, and the escrow. Stellar → ### [Publisher dashboard](/publish/dashboard/) Earnings, settlements, analytics, and the services you manage from app.kiba.tools. Dashboard → ### [FAQ and troubleshooting](/support/faq/) Common questions and fixes for connectors, payments, and publishing. Support → ## What you can do [Section titled “What you can do”](#what-you-can-do) * Ask your assistant for a translation, a price feed, a code review, or a scraped page, and let it pay the specialist that does it well. * Publish a model, an API, or a dataset once and charge per call, even when the caller is an AI agent rather than a person. * Build your own agent on the SDK and pay other services trustlessly from its own wallet. ## Links [Section titled “Links”](#links) [Landing ↗](https://kiba.tools)[Dashboard ↗](https://app.kiba.tools)[GitHub ↗](https://github.com/CoKeFish/kiba)[kiba-sdk on npm ↗](https://www.npmjs.com/package/kiba-sdk)[kiba-mcp on npm ↗](https://www.npmjs.com/package/kiba-mcp)[llms.txt](/llms.txt) # 404 > That page does not exist. It may have moved while the docs were being reorganized. # Authentication > API keys for scripts, OAuth 2.0 for connectors, and the discovery endpoints clients use. The gateway accepts three credentials on the same endpoints: | Credential | For | How | | -------------------------- | -------------------------------------------- | -------------------------------------------------------------- | | **API key** | scripts, servers, CI | `Authorization: Bearer sk_live_…` | | **OAuth 2.0 access token** | MCP connectors (Claude, ChatGPT, `kiba-mcp`) | `Authorization: Bearer ` obtained through the PKCE flow | | **Session cookie** | the dashboard | set by the sign-in form | ## API keys [Section titled “API keys”](#api-keys) Create a key in the dashboard under **Credentials**, or with the API once you hold any credential: ```bash curl -X POST https://api.kiba.tools/v1/api-keys \ -H "Authorization: Bearer $KIBA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"my-script"}' ``` The plain key is returned **once**; the gateway stores only a hash. Revoke with `DELETE /v1/api-keys/:id`. Keys do not expire. ## OAuth 2.0 (connectors) [Section titled “OAuth 2.0 (connectors)”](#oauth-20-connectors) The gateway is an OAuth 2.0 authorization server with PKCE (S256) and dynamic client registration, so MCP clients configure themselves from the connector URL: | Endpoint | Standard | Purpose | | ------------------------------------------- | ---------------- | ----------------------------------------------------------------- | | `/.well-known/oauth-protected-resource/mcp` | RFC 9728 | Points the `/mcp` resource at its authorization server | | `/.well-known/oauth-authorization-server` | RFC 8414 | Lists `authorize`, `token`, `register`, and the supported methods | | `POST /register` | RFC 7591 | Clients self-register and get a `client_id` | | `GET /authorize` | OAuth 2.1 + PKCE | Sign-in and consent screen | | `POST /token` | OAuth 2.1 + PKCE | Exchanges the code for an access token | | `POST /revoke` | RFC 7009 | Revokes a token | A request to `/mcp` without a bearer returns `401` with a `WWW-Authenticate` header that points at the resource metadata, which is how a client starts the flow. Access tokens are bound to the `/mcp` resource (RFC 8707) and are valid for 30 days. Authorized apps are listed at `GET /v1/oauth/connections` and disconnected with `DELETE /v1/oauth/connections/:id`. ## MCP endpoint [Section titled “MCP endpoint”](#mcp-endpoint) `POST /mcp` is the remote MCP server (Streamable HTTP) behind the OAuth flow above. It exposes the four [tools](/connect/tools/). # Endpoints > Reference of the /v1 endpoints of the Kiba gateway, grouped by what they do. Every endpoint requires a credential unless noted. See [Authentication](/api/authentication/). ## Account [Section titled “Account”](#account) ### `GET /v1/me` [Section titled “GET /v1/me”](#get-v1me) The signed-in account: `id`, `email`, `custodial_wallet` (its Stellar address), `is_publisher`, `publisher_name`, `created_at`, plus the balance fields below. ### `GET /v1/balance` [Section titled “GET /v1/balance”](#get-v1balance) ```json { "asset": "USDC", "base_unit_name": "stroops", "balance_base_units": 48000000, "balance_usd": 4.8, "wallet_base_units": 0, "wallet_asset_amount": 0, "wallet_usd": 0, "total_base_units": 48000000, "total_asset_amount": 4.8, "total_usd": 4.8 } ``` `balance_*` is credits, `wallet_*` is the on-chain wallet, `total_*` is the sum. Legacy `*_lamports` and `*_sol` fields carry the same values. ### `GET /v1/wallet` [Section titled “GET /v1/wallet”](#get-v1wallet) On-chain state of the account’s wallet: `pubkey`, `asset`, `base_units`, `asset_amount`, and the platform’s `master_wallet`. ### `POST /v1/topup` [Section titled “POST /v1/topup”](#post-v1topup) Body `{ "amount": 10 }` in USD, between 0 and 1,000 per request. Aggregated credits are capped at 10,000 USD. Returns the new balance. ## Catalog and calls [Section titled “Catalog and calls”](#catalog-and-calls) ### `GET /v1/agents` [Section titled “GET /v1/agents”](#get-v1agents) Lists services. With `?q=` it runs hybrid search and returns results ordered by relevance. Each item: ```json { "service": "translator-pro", "pricePerCall": 0.01, "description": "English → Spanish translation. Input: { text: string }", "endpoint": "https://agent-translator.kiba.tools", "ownerWallet": "G…", "acceptedToken": "USDC", "totalCalls": 128, "totalEarned": 1.28, "createdAt": 1760000000, "source": "chain" } ``` ### `POST /v1/call` [Section titled “POST /v1/call”](#post-v1call) Calls a service and pays from the account’s balance. ```json { "service": "translator-pro", "payload": { "text": "hello" } } ``` Only `service` and `payload` are accepted at the top level. Any other field is rejected with `400` before anything is charged. The response: ```json { "result": { "translation": "hola" }, "cost": { "lamports": 100000, "usd": 0.01 }, "paidWith": "credit", "mode": "virtual", "newBalance": { "lamports": 47900000, "usd": 4.79 }, "explorerUrl": "https://stellar.expert/explorer/testnet/tx/…", "trace": { "steps": [] } } ``` `paidWith` is `credit` or `wallet`. `explorerUrl` links to the on-chain transaction of this call when one was produced. `trace` is the step-by-step timeline of the payment. ### `GET /v1/transactions` [Section titled “GET /v1/transactions”](#get-v1transactions) The account’s history, newest first. `?limit=` up to 500 (default 50). Each item has `type` (`topup`, `call`), `amount_lamports`, `service`, `tx_signature`, `explorer_url`, `status`, and `created_at`. ## Credentials [Section titled “Credentials”](#credentials) ### `GET /v1/api-keys`, `POST /v1/api-keys`, `DELETE /v1/api-keys/:id` [Section titled “GET /v1/api-keys, POST /v1/api-keys, DELETE /v1/api-keys/:id”](#get-v1api-keys-post-v1api-keys-delete-v1api-keysid) List, create (`{ "name": "my-script" }`; the plain key is returned once), and revoke API keys. ### `GET /v1/oauth/connections`, `DELETE /v1/oauth/connections/:id` [Section titled “GET /v1/oauth/connections, DELETE /v1/oauth/connections/:id”](#get-v1oauthconnections-delete-v1oauthconnectionsid) Apps authorized through OAuth (Claude, ChatGPT, `kiba-mcp`) and how to disconnect them. ## Publisher [Section titled “Publisher”](#publisher) ### `POST /v1/publisher/activate` [Section titled “POST /v1/publisher/activate”](#post-v1publisheractivate) Body `{ "name": "Acme" }`. Turns the account into a publisher. ### `GET /v1/publisher/overview` [Section titled “GET /v1/publisher/overview”](#get-v1publisheroverview) Totals earned, number of calls, the account’s services with their stats, and the on-chain wallet balance. ### `GET /v1/publisher/settlements` [Section titled “GET /v1/publisher/settlements”](#get-v1publishersettlements) Settlement batches released to the publisher, with the fee applied (`fee.pct`) and the on-chain transaction of each. `?limit=` up to 200. ### `GET /v1/publisher/analytics` [Section titled “GET /v1/publisher/analytics”](#get-v1publisheranalytics) Daily series of calls and net earnings. `?days=` from 1 to 90 (default 30). Each point: `day`, `calls`, `earned_base_units`, `earned_asset`, `earned_usd`. ### `GET /v1/agents/mine`, `POST /v1/agents`, `PUT /v1/agents/:service`, `DELETE /v1/agents/:service` [Section titled “GET /v1/agents/mine, POST /v1/agents, PUT /v1/agents/:service, DELETE /v1/agents/:service”](#get-v1agentsmine-post-v1agents-put-v1agentsservice-delete-v1agentsservice) Services registered by this account from the dashboard, signed with the account’s wallet. `POST` body: `service`, `pricePerCallLamports` (base units), `endpoint`, `description`. Services published with the SDK are owned by their own keypair and are managed from the SDK, not here. ## Platform [Section titled “Platform”](#platform) ### `GET /v1/platform/stats` [Section titled “GET /v1/platform/stats”](#get-v1platformstats) Aggregate marketplace stats and platform revenue. ### `GET /health` [Section titled “GET /health”](#get-health) No credential. Returns `{ "ok": true, "service": "kiba-gateway" }`. # Errors > HTTP statuses and error shapes returned by the gateway. Every error is a JSON object with a single `error` string: ```json { "error": "service required" } ``` | Status | Meaning | | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `400` | Invalid input: a missing or unknown field, an invalid amount, a name that is too long. The message says which. | | `401` | Missing or invalid credential. On `/mcp` the response carries a `WWW-Authenticate` header with the resource metadata URL. | | `404` | Unknown user, key, or connection. | | `500` | The call to a service failed, or an upstream (discovery, Trustless Work, Stellar) returned an error. The `error` string carries the upstream message. A failed call is refunded to credits. | ## Common messages [Section titled “Common messages”](#common-messages) * `service required` on `POST /v1/call`: the body has no `service`. * An unknown-field message on `POST /v1/call`: the body has fields other than `service` and `payload`. Put the service’s input inside `payload`. * `insufficient balance`: credits and wallet together do not cover the price. Top up or fund the wallet. * `invalid amount (must be 0 < n <= 1000)` on top-up. * `balance cap exceeded (max $10000)`: aggregated credits cannot exceed the cap. * `name required` / `name too long (max 64)` when creating an API key. # Introduction > The Kiba gateway exposes a REST API for everything the dashboard and the connectors do. Base URL: ```plaintext https://api.kiba.tools ``` All application endpoints live under `/v1/` and return JSON. The same endpoints serve the dashboard, the MCP connectors, and your own scripts. Only the credential differs; see [Authentication](/api/authentication/). ## Amounts [Section titled “Amounts”](#amounts) Amounts are returned both in **USD** (`*_usd`) and in **base units** of the settlement asset (`*_base_units`; 1 USDC = 10,000,000 base units, named `stroops` in `base_unit_name`). Fields named `*_lamports` carry the same base-unit values and are kept for backward compatibility. ## Conventions [Section titled “Conventions”](#conventions) * Send JSON with `Content-Type: application/json`. * Errors return a JSON object with an `error` string and an HTTP status that describes the failure. See [Errors](/api/errors/). * List endpoints are not paginated; they accept a `limit` query parameter. # Architecture > The components of the Kiba platform and how they talk to each other. Kiba is a set of small services around one on-chain registry. Components are named by **what they are**, not by who uses them. ```plaintext Assistants (Claude, ChatGPT, Cursor, Claude Code) Apps and agents │ MCP over HTTP + OAuth 2.0 │ kiba-sdk ▼ ▼ ┌─────────────────┐ search ┌─────────────────┐ x402 (USDC escrow) │ Gateway │ ──────────▶ │ Discovery │ │ │ api.kiba.tools │ │ data.kiba.tools │ │ │ auth, credits, │ │ FTS + vectors │ │ │ signed calls, │ └────────┬────────┘ │ │ settlement │ │ indexes │ └───┬─────────┬───┘ ▼ ▼ │ │ batched settle ┌─────────────────┐ ┌───────────────────┐ │ └────────────────▶│ Trustless Work │ │ Registry contract │ │ signed call │ escrow (USDC) │ │ (Soroban) │ ▼ └─────────────────┘ └─────────▲─────────┘ ┌─────────────────┐ │ register │ Service │ ─────────────────────────────────────────────┘ │ (kiba-sdk) │ └─────────────────┘ ``` ## Components [Section titled “Components”](#components) | Component | Role | Public host | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | | Gateway | OAuth 2.0 server, remote MCP endpoint, credits ledger, user wallets, calls on behalf of users, publisher ledger and batched settlement | `api.kiba.tools` | | Discovery backend | Indexes the registry contract and serves hybrid search | `data.kiba.tools` | | Dashboard | Web app for users and publishers | `app.kiba.tools` | | Landing | Marketing site | `kiba.tools` | | MCP adapter (`kiba-mcp`) | Local stdio bridge for clients that cannot use a remote connector | npm | | SDK (`kiba-sdk`) | Library to publish or consume services | npm | | Registry contract | Soroban contract with one entry per service | Stellar testnet | | Trustless Work | Escrow and 95/5 split in USDC | external | ## Integration channels [Section titled “Integration channels”](#integration-channels) | | MCP connector | Gateway REST API | SDK | | --------------- | ---------------------- | ----------------------- | -------------------- | | Packaging | URL, or `npx kiba-mcp` | HTTPS | npm `kiba-sdk` | | Wallet | Managed by the gateway | Managed by the gateway | Your own keypair | | Auth | OAuth 2.0 with PKCE | API key or OAuth bearer | Stellar keypair | | Billing | USD credits | USD credits | USDC escrow per call | | Typical latency | \~200 ms | \~200 ms | 15 to 150 s | The same `/v1/*` endpoints serve the dashboard (session cookie), the connectors (OAuth bearer), and scripts (API key bearer). The full internal architecture, with data models and sequence diagrams, lives in the repository under `docs/architecture.md`. # Credits and wallet > Each Kiba account has two balances, off-chain USD credits and an on-chain Stellar wallet. Here is what each one is for. Every account on the gateway has **two separate balances**. They are easy to confuse. ## Credits (off-chain) [Section titled “Credits (off-chain)”](#credits-off-chain) Credits are a USD balance kept in the gateway’s ledger. They are what an assistant spends when it calls a service through Kiba. * New accounts start with a **5 USD** sign-up credit. * Top up from the dashboard’s **Billing** page or with `POST /v1/topup`. * Spending is immediate and off-chain: a call through the gateway debits credits in milliseconds. * `get_balance` and `GET /v1/balance` report credits as `balance_usd`. ## Wallet (on-chain) [Section titled “Wallet (on-chain)”](#wallet-on-chain) Each account also gets a **Stellar wallet**, provisioned as a non-custodial server wallet on [Privy](https://privy.io): the key lives in a secure enclave and the gateway only requests signatures. Its public address is shown in the dashboard and returned by `GET /v1/me` as `custodial_wallet`. * It holds **USDC** on Stellar. The gateway sets up the USDC trustline for it. * To fund it, send USDC to its address. There is no memo and no special flow; it is a plain Stellar account. * Funding the wallet does **not** add credits. The two balances are independent. ## Which one pays a call [Section titled “Which one pays a call”](#which-one-pays-a-call) When you call a service through the gateway, credits are used first (`paidWith: "credit"`). The wallet path (`paidWith: "wallet"`) runs the full on-chain escrow from your own USDC and is slower. Most users never need to fund the wallet. Publishers receive their earnings on-chain, not as credits. See [Payments and settlement](/concepts/payments-and-settlement/). # Payments and settlement > How a call is paid, how the publisher gets the money, and where the 95/5 split happens. Kiba uses the **x402** pattern: an HTTP request is answered with `402 Payment Required` and a quote, the caller pays, then retries with proof of payment. On Kiba the escrow and the revenue split run on [Trustless Work](https://www.trustlesswork.com), an escrow-as-a-service on Stellar, in **USDC**. ## Two payment paths [Section titled “Two payment paths”](#two-payment-paths) | Path | Who uses it | Speed | Trust | | ----------------------------------------- | -------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------- | | **Platform-signed** (through the gateway) | Assistants and dashboard users paying with credits | hundreds of milliseconds | the service verifies the platform’s signature; earnings settle in batches | | **x402 escrow** (direct) | SDK clients paying from their own wallet | 15 to 150 seconds | fully trustless on-chain | ### Platform-signed calls [Section titled “Platform-signed calls”](#platform-signed-calls) 1. The gateway debits the user’s credits. 2. It calls the service with a short signed certificate: service name, hash of the payload, timestamp, nonce. The service verifies the signature with the platform’s **public** key. No shared secret is ever sent. 3. The service runs and answers. The gateway records the earning in the publisher’s ledger. If the service fails, the debit is refunded. 4. The gateway funds the publisher’s current **settlement escrow** on Trustless Work with the amount of the call. The response includes an explorer link to that transaction. 5. Periodically the gateway **settles** the cycle: it releases the escrow and sweeps the funds to the publisher’s wallet. Trustless Work applies the platform fee at release. ### Direct escrow calls [Section titled “Direct escrow calls”](#direct-escrow-calls) An SDK client opens and funds a single-release escrow naming the service as receiver, calls the service with the escrow id in the `X-PAYMENT` header, and the service releases the funds after serving. Each escrow is served exactly once. ## The split [Section titled “The split”](#the-split) Trustless Work is configured with a **5 % platform fee**: for every call, **95 %** goes to the service owner and **5 %** to the Kiba treasury. The split scales with the quoted amount, so dynamic pricing works without extra configuration. ## What the publisher sees [Section titled “What the publisher sees”](#what-the-publisher-sees) Earnings and settlements appear in the dashboard’s publisher panel and in `GET /v1/publisher/overview`, `/settlements`, and `/analytics`, always **net** of the fee. Payouts land in the Stellar account that **owns the on-chain registration**, which for an SDK-published service is the keypair it bootstrapped with. See [Publisher dashboard](/publish/dashboard/). # Roles > The parties in a Kiba call and what each one controls. | Role | Who | Controls | | --------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | **User** | A person using an AI assistant | Their credits and wallet, and which services the assistant calls | | **Assistant** | Claude, ChatGPT, Cursor, Claude Code, or any MCP client | Searches the catalog and calls services with the user’s balance, inside the user’s session | | **Publisher** | A company, an organization, or a developer | The service: its code, price, endpoint, and the Stellar account that receives earnings | | **Platform (Kiba gateway)** | The operator of the rail | Sign-in, credits, signing calls on the user’s behalf, batched settlement, dispute resolution on escrows | | **Trustless Work** | Escrow provider on Stellar | Holds funds in escrow and applies the 95/5 split at release | A few consequences: * The platform never holds a publisher’s secret. Services verify the platform with a public key. * A publisher can be paid without the platform: a direct SDK client can pay any service trustlessly. * The registry is permissionless and first-come on names. Read [Naming and trust](/publish/naming-and-trust/) before you pick a service name. # Services and the registry > Every Kiba service is registered on-chain in a Soroban contract. Discovery indexes that registry and searches it in any language. ## What a service is [Section titled “What a service is”](#what-a-service-is) A service is anything that answers an HTTP request for a price: an AI agent, a REST API, an indexer, a scraper, a calculator. On Kiba every service is published by an **external publisher**. There are no first-party services, only templates you can copy. Each service has: * a **name** (`service`), unique across the registry, up to 32 characters, for example `translator-pro`; * a **price per call** in USDC, optionally dynamic per request; * a public **endpoint** that speaks the Kiba payment handshake (the SDK does this for you); * a **description** that search uses and that tells assistants what payload to send; * an **owner**, the Stellar account that registered it and receives its earnings. ## The on-chain registry [Section titled “The on-chain registry”](#the-on-chain-registry) Registration lives in a Soroban smart contract on Stellar. The contract stores one entry per service name, and only the owner can create, update, or delete their own entry. It emits events (`agent_registered`, `agent_updated`, `agent_deregistered`) that indexers consume. See [Registry contract](/stellar/registry-contract/). Because the registry is public on-chain data, **anyone can run an indexer**. A publisher is not locked into a single catalog. ## Discovery [Section titled “Discovery”](#discovery) Kiba’s discovery backend mirrors the registry and answers searches with a hybrid scorer: * **Keyword**: full-text search with BM25 ranking. * **Semantic**: 384-dimension sentence embeddings computed in-process, so a query in Spanish finds a service described in English. * **Hybrid**: weighted fusion of both (0.6 keyword, 0.4 semantic). Assistants reach discovery through the `list_agents` tool; applications through `GET /v1/agents?q=…` on the gateway. A service appears in results as soon as its registration event is indexed. There is no approval step. About the word “agent” Identifiers such as `list_agents`, `call_agent`, or the `AgentProvider` class keep the historical word *agent*. They work for every kind of service. # ChatGPT > Connect Kiba to ChatGPT through Developer mode, using the same connector URL as Claude. ChatGPT connects to the same remote MCP server as Claude. The connector is created once in **Developer mode** and then used from any chat. Connector URL ```plaintext https://api.kiba.tools/mcp ``` ## Steps [Section titled “Steps”](#steps) 1. Open **Settings → Apps & Connectors → Advanced settings** and enable **Developer mode**. 2. Back in **Apps & Connectors**, click **Create**. 3. Give it a name (for example *Kiba*) and a short description, paste the connector URL, and click **Create**. ChatGPT validates the connection and lists the tools. 4. ChatGPT opens the Kiba sign-in page. Create an account or sign in, then click **Authorize**. You are redirected back to ChatGPT. 5. In a chat, click **+ → More** and select the Kiba connector. Developer mode is available on ChatGPT’s Plus, Pro, Business, Enterprise, and Edu plans. ## Notes [Section titled “Notes”](#notes) * Sign-in uses OAuth 2.0 with PKCE and dynamic client registration. ChatGPT discovers the authorization server from the connector URL on its own. * The access token is bound to the Kiba connector and cannot be reused elsewhere. * The connector is private to your account. Publishing it to every ChatGPT user would require OpenAI’s review, which is not needed to use it. # Claude > Connect Kiba to Claude on the web, desktop, or mobile by pasting one URL. Nothing to install. Claude connects to Kiba as a **custom connector**: a remote MCP server reachable by URL, with sign-in through OAuth. Nothing to install, no API keys. Connector URL ```plaintext https://api.kiba.tools/mcp ``` ## Steps [Section titled “Steps”](#steps) 1. In Claude, open **Settings → Connectors** and choose **Add custom connector**. 2. Paste the connector URL above and click **Add**. 3. Claude opens the Kiba sign-in page. Create an account or sign in, then click **Authorize**. 4. Back in Claude, the Kiba tools are available in new conversations. If the connector is off in a chat, enable it from the tools menu. Custom connectors are available on Claude’s Pro, Max, Team, and Enterprise plans. Once added to your account, the connector works in Claude on the web, Claude Desktop, and the mobile apps. ## What you get [Section titled “What you get”](#what-you-get) Four tools: search the catalog, call a service, check your balance, list your transactions. See [Tools](/connect/tools/). New accounts come with 5 USD of credit. Top up at when you need more. ## Try it [Section titled “Try it”](#try-it) Ask Claude something like: > Find a service on Kiba that translates text to Portuguese and translate this paragraph: … Claude searches the catalog, shows the price, calls the service, and reports the cost and the remaining balance. ## Claude Code and Claude Desktop with a local adapter [Section titled “Claude Code and Claude Desktop with a local adapter”](#claude-code-and-claude-desktop-with-a-local-adapter) If you prefer a local MCP server, or you are on a plan without custom connectors, use the `kiba-mcp` package or the Windows installer. See [IDEs and local clients](/connect/ide/). # IDEs and local clients > Use Kiba from Claude Code, Cursor, Claude Desktop, Codex, or any MCP client with the kiba-mcp package or the Windows installer. For clients that run MCP servers locally, Kiba ships `kiba-mcp`, a small adapter that talks to the gateway on your behalf. It signs you in through the browser the first time and stores a token locally. ## Option A: Windows installer [Section titled “Option A: Windows installer”](#option-a-windows-installer) Download the one-click installer from the [latest release](https://github.com/CoKeFish/kiba/releases/latest) (`Kiba-Installer-x64-setup.exe`). It installs the `kiba` MCP server into **Claude Desktop, Cursor, and Claude Code** automatically. Restart the client when it finishes. Note Windows SmartScreen may warn because the installer is not code-signed yet. Choose *More info → Run anyway*. The installer is built and published from the public repository. ## Option B: add the MCP config manually (macOS, Linux, Windows) [Section titled “Option B: add the MCP config manually (macOS, Linux, Windows)”](#option-b-add-the-mcp-config-manually-macos-linux-windows) Add this block to your client’s MCP configuration. It needs Node.js 18 or newer. ```json { "mcpServers": { "kiba": { "command": "npx", "args": ["-y", "kiba-mcp"] } } } ``` Where the configuration lives: | Client | Where | | -------------- | ----------------------------------------------------------------------------------------------------------- | | Claude Code | `~/.claude.json`, or run `claude mcp add kiba -- npx -y kiba-mcp` | | Cursor | `~/.cursor/mcp.json`, or `.cursor/mcp.json` in the project | | Claude Desktop | `claude_desktop_config.json` in the app’s configuration folder | | Codex CLI | `~/.codex/config.toml`, section `[mcp_servers.kiba]` with `command = "npx"` and `args = ["-y", "kiba-mcp"]` | Restart the client. On the first tool call: 1. The adapter detects you are not signed in and opens your browser at the gateway. 2. Sign in or create an account, then click **Authorize**. 3. The page says you can close the tab. The token is saved at `~/.config/kiba/token.json`. ## Headless use (CI, servers, automation) [Section titled “Headless use (CI, servers, automation)”](#headless-use-ci-servers-automation) Skip the browser flow by setting an API key. Create one in the dashboard under **Credentials**, or with `POST /v1/api-keys`. ```json { "mcpServers": { "kiba": { "command": "npx", "args": ["-y", "kiba-mcp"], "env": { "KIBA_API_KEY": "sk_live_…" } } } } ``` ## Environment variables [Section titled “Environment variables”](#environment-variables) | Variable | Default | Purpose | | ------------------ | --------------------------- | --------------------------------------------- | | `KIBA_URL` | `https://api.kiba.tools` | Gateway to talk to (for self-hosted gateways) | | `KIBA_API_KEY` | unset | Long-lived key; when set, OAuth is skipped | | `KIBA_TOKEN_PATH` | `~/.config/kiba/token.json` | Where the OAuth token is stored | | `KIBA_CLIENT_NAME` | `kiba-mcp` | Name shown on the consent page | # Tools > The four MCP tools Kiba exposes to an assistant and what each one returns. Whether connected by URL or through `kiba-mcp`, the assistant gets the same four tools. ### `list_agents` [Section titled “list_agents”](#list_agents) Searches the catalog. With no `query` it returns the whole catalog. | Parameter | Type | Notes | | --------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `query` | string, optional | Free text in any language, for example “translate text to Spanish” or “audit a smart contract”. Runs hybrid keyword and semantic search and returns results ordered by score. | Each result includes the service name, endpoint, description, price per call, and usage stats. ### `call_agent` [Section titled “call_agent”](#call_agent) Calls a service and pays for it from the user’s balance. | Parameter | Type | Notes | | --------- | ------ | -------------------------------------------------------------------------------------------- | | `service` | string | The service identifier, for example `translator-pro`. | | `payload` | object | The JSON input the service expects. Each service documents its own shape in its description. | Returns the service’s result plus the cost of the call, the remaining balance, and an explorer link to the on-chain transaction when one was produced. ### `get_balance` [Section titled “get_balance”](#get_balance) No parameters. Returns the user’s credits in USD and base units, and the on-chain wallet balance. ### `get_transactions` [Section titled “get_transactions”](#get_transactions) No parameters. Returns the most recent transactions: top-ups and calls, with amounts and explorer links when available. ## How an assistant uses them [Section titled “How an assistant uses them”](#how-an-assistant-uses-them) A typical turn: the assistant calls `list_agents` with the user’s request as the query, picks a service, shows the price, calls `call_agent` with a payload built from the conversation, and summarizes the result together with the cost. Prices are per call and visible before the call, so the user can decline. # Links > Every public Kiba surface in one place. | What | Where | | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | Landing | | | Dashboard (sign up, credits, publisher panel) | | | Gateway API | | | MCP connector URL | `https://api.kiba.tools/mcp` | | Windows installer | | | `kiba-mcp` on npm | | | `kiba-sdk` on npm | | | Source code | | | Registry contract (testnet) | [stellar.expert](https://stellar.expert/explorer/testnet/contract/CDYLMRS2UTBHNTWS67NC2OPQIH2HXGS36WZYC4JUMLKZWT7XXVUUX7XF) | | Trustless Work | | ## For AI agents [Section titled “For AI agents”](#for-ai-agents) These docs publish a machine-readable index at [`/llms.txt`](/llms.txt) and the full text at [`/llms-full.txt`](/llms-full.txt), so an assistant can read them directly. # What is Kiba > Kiba is a payment rail that lets any AI assistant discover specialized services and pay them per call, settled in USDC on Stellar. Kiba is a single entry point for any AI assistant (Claude, ChatGPT, Cursor, Claude Code) to find a specialized service for a task and pay for it per call, with no API keys and no per-service setup. A **service** can be an AI agent, an API, an indexer, or any procedural tool, published by a company, an organization, an institution, or an independent developer. Kiba is the rail that connects the two sides: * **For the assistant’s user:** the assistant locates a service, receives a price, pays in a single round trip, and returns the answer. No per-service sign-up, no keys, no wallet management. * **For the service publisher:** registration, discovery, payment, and the revenue split are provided by the marketplace. Expose a service once and charge per call, even when the consumer is an AI agent rather than a person. ## The problem it solves [Section titled “The problem it solves”](#the-problem-it-solves) A general-purpose assistant draws on open sources and often returns outdated or shallow information without the user noticing. The specialized sources that would solve the problem sit behind friction: signing up, integrating, an API key or a subscription just to use them once. On the other side, whoever builds such a service has nowhere to offer it or charge for it, least of all when the consumer is an AI agent. ## How the pieces fit [Section titled “How the pieces fit”](#how-the-pieces-fit) | Piece | What it does | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Connector (MCP)** | Exposes four tools to the assistant: search the catalog, call a service, check the balance, list transactions. Reachable by URL (remote) or through the `kiba-mcp` package and the Windows installer (local). | | **Gateway** | Handles sign-in (OAuth 2.0), credits, wallets, calls on the user’s behalf, and settles publishers’ earnings in batches. | | **Discovery** | Mirrors the on-chain registry and runs hybrid keyword and semantic search in any language. | | **Registry contract** | A Soroban smart contract on Stellar where every service is registered: owner, price, endpoint, description. | | **Settlement** | USDC escrow through [Trustless Work](https://www.trustlesswork.com), with a 95/5 split between the publisher and the platform. | | **SDK** | `kiba-sdk`, a TypeScript library to publish a service or to consume services directly, self-custodially. | ## Status [Section titled “Status”](#status) Kiba runs on **Stellar testnet** today. Everything in these docs works end to end on testnet. Mainnet deployment, a formal audit, and production fiat billing are on the roadmap and explicitly out of scope for now. # Who is it for > Kiba serves anyone who uses an AI assistant and anyone who wants to sell a service to AI assistants. Kiba is built for two audiences. Neither needs to know anything about blockchains. ## People who use an AI assistant [Section titled “People who use an AI assistant”](#people-who-use-an-ai-assistant) You already talk to Claude, ChatGPT, Cursor, or Claude Code. When the assistant’s own knowledge is not enough, the specialized service that would solve your problem sits behind a sign-up, an integration, an API key, or a subscription you only need once. With Kiba connected, your assistant finds that service and pays for the single call it needs, from the conversation you are already in. Start at [Connect your assistant](/connect/claude/). ## People who build a service [Section titled “People who build a service”](#people-who-build-a-service) You have a model, an API, a dataset, a scraper, an indexer, a domain-specific tool. You want to charge for it, including when the caller is an AI agent and not a person, without building billing, discovery, and auth yourself. With Kiba you register the service once, set a price per call, and get discovered by every connected assistant. Payment is verified before your code runs, and earnings settle to your Stellar wallet in USDC. Start at [Publish a service](/publish/quickstart/). ## Teams integrating directly [Section titled “Teams integrating directly”](#teams-integrating-directly) If you are building your own agent or product and want to consume services programmatically, the [SDK](/sdk/overview/) and the [Gateway REST API](/api/introduction/) give you the same rail without an assistant in the middle. # Publisher dashboard > Activate the publisher panel at app.kiba.tools to see earnings, settlements, analytics, and your registered services. The dashboard at has a **publisher panel** that reads the gateway’s earnings ledger. ## Activate it [Section titled “Activate it”](#activate-it) Sign in, open **Publisher**, and activate it with a display name (`POST /v1/publisher/activate` does the same). One account can be both a user and a publisher. ## Pages [Section titled “Pages”](#pages) | Page | What it shows | | ------------- | -------------------------------------------------------------------------------------------------- | | **Overview** | Total earned, number of calls, your services with their stats, and the balance of your Kiba wallet | | **Services** | The services registered by your account, with edit and delete | | **Analytics** | Calls and net earnings per day, for the last 30 to 90 days | | **Payouts** | Settlement history: each batch released to you, with its on-chain transaction | | **Pricing** | Price per call and pricing note per service | | **Publish** | Register a service from the browser, signed with your Kiba wallet | All amounts are **net**, after the 5 % platform fee. ## Where the money lands [Section titled “Where the money lands”](#where-the-money-lands) Settlements are paid to the Stellar account that **owns the on-chain registration**: * A service published with the SDK is owned by the keypair it bootstrapped with. Payouts go there, **not** to the wallet of your dashboard account. * A service registered from the dashboard’s **Publish** page is owned by your Kiba wallet, so payouts show up in that wallet. The counters stored in the registry contract are informational. The gateway’s ledger is the source of truth for earnings and settlements. ## Programmatic access [Section titled “Programmatic access”](#programmatic-access) The same data is available through the [Gateway REST API](/api/endpoints/#publisher) with an API key. # Deploy > Host your service with a stable public URL and keep its on-chain identity across restarts. Host the process anywhere that gives it a **stable public HTTPS URL**: a VPS, a container platform, a serverless function. Set `endpoint` (or `PUBLIC_ENDPOINT`) to that URL. It is what callers hit, and it is stored on-chain at registration. ## Keep the identity [Section titled “Keep the identity”](#keep-the-identity) Persist the keypair file, or pass the secret through `AGENT_WALLET_SECRET` (an `S…` secret), so the service keeps the same Stellar account across restarts and redeploys. That account is its registration and where its earnings land. ## Changing price, description, or endpoint [Section titled “Changing price, description, or endpoint”](#changing-price-description-or-endpoint) Change the option and restart. Re-running `bootstrap()` reconciles the on-chain record automatically. ## Without express [Section titled “Without express”](#without-express) If you prefer Fastify, Hono, or a serverless runtime, skip `listen()` and mount the framework-agnostic core: ```ts const { status, body } = await provider.verifyAndServe({ body, // parsed JSON headers, // request headers rawBody, // exact request bytes (needed to verify platform-signed calls) ip, // for rate limiting }); ``` `express` is an optional peer dependency. You only need it for the built-in `provider.app` and `provider.listen()`. ## Checklist [Section titled “Checklist”](#checklist) * Public HTTPS endpoint reachable from the internet. * Keypair persisted, or secret injected. * `STELLAR_CONTRACT_ID`, `KIBA_PLATFORM_PUBLIC_KEY`, `TRUSTLESS_WORK_API_KEY`, and `KIBA_PLATFORM_ADDRESS` set for the target network. * Host clock in sync. Platform-signed calls are rejected if the clock drifts more than about two minutes. # Discovery and payment > How your service shows up in search and the two ways a call can pay you. ## Showing up in search is automatic [Section titled “Showing up in search is automatic”](#showing-up-in-search-is-automatic) You do not submit anything to anyone. The moment `bootstrap()` registers you on-chain, the contract emits an `agent_registered` event, and the marketplace indexer picks it up by watching those public events. No allowlist, no approval. Within moments your service is indexed, embedded, and appears in keyword and semantic search alongside everyone else. Because it is public on-chain data, **anyone** can run an indexer. You are not locked to one catalog. ## Being called [Section titled “Being called”](#being-called) Any `AgentClient` pointed at the same registry can find and pay you: ```ts import { AgentClient } from 'kiba-sdk'; const client = new AgentClient({ wallet: callerKeypair, network: 'testnet', contractId: process.env.STELLAR_CONTRACT_ID, trustlessWork: { apiKey: process.env.TRUSTLESS_WORK_API_KEY, platformAddress: process.env.KIBA_PLATFORM_ADDRESS, }, }); const out = await client.call('sentiment', { text: 'I love this' }); ``` Through the Kiba gateway, which is how assistants call you, requests arrive **platform-signed**: fast and off-chain, settled to you in batches. ## How you get paid [Section titled “How you get paid”](#how-you-get-paid) | Path | When | Speed | Trust | | --------------- | --------------------------------------------------- | ------------------------ | ------------------------------------------------------- | | Platform-signed | through the Kiba gateway (assistants, credit users) | hundreds of milliseconds | you verify the platform’s signature; settled in batches | | x402 escrow | direct callers, no platform trust | 15 to 150 s | fully trustless on-chain | Before your handler runs, the SDK verifies that: * a platform-signed call carries a **valid, fresh, non-replayed** signature for **your** service over **this** payload; or * an escrow is **funded**, **pending**, and names **you** as receiver, and it serves each escrow **exactly once**. The platform fee (5 %) is applied at settlement. You receive the rest in USDC, in the Stellar account your service registered with. Track it in the [publisher dashboard](/publish/dashboard/). # Handler and pricing > What your handler receives, how to validate input, and how to charge a different price per request. ## What your handler receives [Section titled “What your handler receives”](#what-your-handler-receives) Your handler is called **only after payment is verified**. It gets the raw request payload and returns any JSON-serializable value. **Validate your own input**: callers, and the language models driving them, may send unexpected shapes. ```ts provider.serve(async (req: unknown) => { const text = String((req as { text?: unknown })?.text ?? ''); if (!text) throw new Error('field "text" is required'); /* … */ }); ``` The SDK enforces a body-size limit (`bodyLimit`, default `256kb`) and rate-limits the unpaid quote path (`rateLimitPerMinute`, default 60) for you. ## Describe your payload [Section titled “Describe your payload”](#describe-your-payload) Assistants build the payload from your service **description**. Say which fields you expect and in what shape, for example: “Input: `{ text: string, target: 'es' | 'pt' }`. Output: `{ translation: string }`.” A clear description means fewer failed calls. ## Fixed price [Section titled “Fixed price”](#fixed-price) `pricePerCall` is the price in USDC charged for every call. ## Dynamic pricing [Section titled “Dynamic pricing”](#dynamic-pricing) Charge per request by returning an amount from `priceFn`. The result is raised to `pricePerCall` if lower, so `pricePerCall` acts as a floor. ```ts new AgentProvider({ /* … */ pricePerCall: 0.001, // floor priceFn: (req: { text: string }) => 0.001 + req.text.length * 0.00001, pricingNote: '0.001 USDC + 0.00001 USDC per character', }); ``` `priceFn` **must be deterministic** in the payload: the same input must yield the same price, so the quote and the post-payment check agree. `pricingNote` is shown to callers next to the price. The 95/5 split scales with the quoted amount. Nothing else changes. # Going to mainnet > What changes when a service moves from Stellar testnet to mainnet. Caution Kiba itself runs on **testnet** today. This page describes what the SDK supports so you can prepare. The public gateway and catalog are testnet-only until the mainnet launch. | Item | Testnet | Mainnet | | --------------------------- | ---------------------------------------------------- | --------------------------------------------------------- | | `network` | `testnet` (default) | `mainnet` | | Funding the service account | automatic through friendbot | you fund it with XLM (reserve plus fees) | | USDC trustline | set by `bootstrap()` | set before `bootstrap()`, with the mainnet USDC issuer | | Trustless Work | `https://dev.api.trustlesswork.com`, testnet API key | `https://api.trustlesswork.com`, mainnet API key | | Registry contract | testnet contract id | mainnet contract id, published with the launch | | RPC | `https://soroban-testnet.stellar.org` | a Soroban RPC provider; public endpoints are rate-limited | Two instances with different networks can coexist in one process, for example a testnet and a mainnet client, each with its own configuration. # Naming and trust > Service names are global and first-come. What the registry guarantees and what it does not. Service names are **global and first-come** in the on-chain registry. The contract guarantees that only the owner can create, modify, or delete **their** registration, so nobody can hijack an existing one. Two further protections matter when services consume other services. ## Endpoint verification [Section titled “Endpoint verification”](#endpoint-verification) A squatter could register a name that points at *someone else’s* endpoint. Pass `verifyEndpoint: true` to `AgentClient` and discovery cross-checks the endpoint’s live `/manifest`: its `service` and `ownerWallet` must match the on-chain record, or the call throws `EndpointVerificationError`. ```ts const client = new AgentClient({ /* … */ verifyEndpoint: true }); ``` ## Escrow receiver binding [Section titled “Escrow receiver binding”](#escrow-receiver-binding) A provider only serves an escrow that names **it** as receiver, so a registration pointing at a victim’s endpoint cannot extract free work. ## What is not protected [Section titled “What is not protected”](#what-is-not-protected) Taking an **unused brand name** before its rightful owner is inherent to a permissionless registry. Production marketplaces are expected to curate discovery on top of the registry with reputation and verified badges. Namespacing by owner plus service with a curated alias is the planned hardening; it changes call-by-bare-name, so it is a deliberate non-goal of the current version. Pick a descriptive, specific name you are willing to keep. # Quickstart > Go from nothing to a live paid service on Kiba with kiba-sdk in a few minutes. This guide takes an external publisher from nothing to a live service that assistants can discover and pay per call. Everything uses [`kiba-sdk`](https://www.npmjs.com/package/kiba-sdk). The working examples in `packages/demo-agents/` of the [repository](https://github.com/CoKeFish/kiba) are templates you can copy. ## 1. Prerequisites [Section titled “1. Prerequisites”](#1-prerequisites) * **Node.js 18** or newer. * A **Stellar account** for your service. On testnet the SDK creates and funds one for you through friendbot; on mainnet you fund it yourself. * A **Trustless Work API key**, created in the Trustless Work BackOffice dApp. It lets the on-chain escrow settle. See [Trustless Work](/stellar/trustless-work/). * The Kiba **registry contract id** and the **platform public key** for the network you target. See [Testnet](/stellar/testnet/). ## 2. Scaffold the service [Section titled “2. Scaffold the service”](#2-scaffold-the-service) ```bash mkdir my-service && cd my-service npm init -y npm install kiba-sdk express ``` `src/index.ts`: ```ts import { AgentProvider, loadOrCreateKeypair } from 'kiba-sdk'; const provider = new AgentProvider({ wallet: loadOrCreateKeypair(process.env.KEYPAIR_PATH ?? './data/wallet.json'), service: 'sentiment', // unique id, max 32 chars pricePerCall: 0.002, // USDC description: 'Sentiment analysis (positive/negative/neutral). Input: { text: string }', endpoint: process.env.PUBLIC_ENDPOINT ?? 'http://localhost:5010', network: (process.env.STELLAR_NETWORK as 'testnet' | 'mainnet') ?? 'testnet', contractId: process.env.STELLAR_CONTRACT_ID, trustlessWork: { apiKey: process.env.TRUSTLESS_WORK_API_KEY, platformAddress: process.env.KIBA_PLATFORM_ADDRESS, }, // Accept fast platform-signed calls from the gateway. Omit to require escrow on // every call. platform: process.env.KIBA_PLATFORM_PUBLIC_KEY ? { publicKey: process.env.KIBA_PLATFORM_PUBLIC_KEY } : undefined, }); provider.serve(async (req: { text: string }) => { const score = analyze(req.text); // your model / business logic return { label: score > 0 ? 'positive' : 'negative', score }; }); (async () => { await provider.bootstrap(); // fund + register on-chain await provider.listen(Number(process.env.PORT) ?? 5010); })(); function analyze(text: string): number { return /good|great|love/i.test(text) ? 1 : -1; } ``` Run it: ```bash KEYPAIR_PATH=./data/wallet.json \ STELLAR_NETWORK=testnet \ STELLAR_CONTRACT_ID=C... \ TRUSTLESS_WORK_API_KEY=tw_... \ KIBA_PLATFORM_ADDRESS=G... \ KIBA_PLATFORM_PUBLIC_KEY=G... \ npx tsx src/index.ts ``` On the first run `bootstrap()` funds the account (testnet friendbot), sets the USDC trustline, and registers `sentiment` in the on-chain registry. From that moment the service is discoverable. There is nothing to submit. ## 3. Next steps [Section titled “3. Next steps”](#3-next-steps) * [Handler and pricing](/publish/handler-and-pricing/): validate input and charge per request. * [Deploy](/publish/deploy/): host it with a stable public URL. * [Discovery and payment](/publish/discovery-and-payment/): how calls reach you and how you get paid. # Troubleshooting > Common errors when running a service and what they mean. * **`degraded mode` / refuses to serve.** No `contractId` resolved. Pass `contractId` or set `STELLAR_CONTRACT_ID`. For a no-chain local demo only, set `allowUnverified: true`. * **`ConfigError: … platformAddress`.** You set a Trustless Work `apiKey` but no `platformAddress`. Provide a funded `G…` address. * **`escrow receiver does not match`.** The caller funded an escrow for a different service. The SDK is correctly refusing a cross-service reuse. * **Mainnet account not funded.** There is no friendbot on mainnet. Fund the account and set its USDC trustline before `bootstrap()`. * **Platform-signed calls rejected.** Confirm `platform.publicKey` matches the gateway’s published key and that your host clock is within about two minutes of real time. * **Service not in search results.** Check that `bootstrap()` completed without error and that the registration appears on the [registry contract](/stellar/registry-contract/). Indexing happens within moments of the on-chain event. * **Calls succeed but nothing is settled yet.** Settlements are batched and run periodically. Check **Payouts** in the dashboard. Payouts go to the account that owns the registration; see [Publisher dashboard](/publish/dashboard/). See [SDK configuration](/sdk/configuration/) for every option. # AgentClient > Consume services from your own code, paying from your own wallet through a Trustless Work escrow or with a platform signature. ```ts import { AgentClient } from 'kiba-sdk'; const client = new AgentClient({ wallet: myKeypair, network: 'testnet', contractId: process.env.STELLAR_CONTRACT_ID, trustlessWork: { apiKey: process.env.TRUSTLESS_WORK_API_KEY, platformAddress: process.env.KIBA_PLATFORM_ADDRESS, }, }); await client.bootstrap(); const result = await client.call('translate-en-es', { text: 'hello' }); // → { translation: 'hola', _payment: { … } } ``` `client.call()` discovers the service in the on-chain registry (with a discovery-backend fallback), funds a Trustless Work escrow naming the service as receiver, then calls again with proof of payment. The result carries a `_payment` field with the escrow details. ## Methods [Section titled “Methods”](#methods) * `bootstrap()`: funds the caller account on testnet and sets the USDC trustline. * `call(service, payload)`: the full x402 handshake. Slow (15 to 150 s) but trustless. * `callWithTrace(service, payload)`: the same, plus a step-by-step timeline (quote, escrow opened, service responded, …) useful for debugging and for UIs. * `callSigned(endpoint, payload, { signer, service })`: platform-signed call, for operators who hold the platform’s private key. Fast and off-chain. See [Trust model](/sdk/trust-model/). * `listRegisteredServices()`: reads the registry directly. ## Options [Section titled “Options”](#options) | Option | Notes | | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | `wallet` / `secret` / `signer` | The caller’s Stellar identity. It must hold USDC on the target network. | | `network`, `contractId`, `rpcUrl` | Chain settings, see [Configuration](/sdk/configuration/). | | `trustlessWork.apiKey`, `trustlessWork.platformAddress` | Needed to open escrows. | | `discoveryUrl` | Fallback registry lookup (`KIBA_DISCOVERY_URL`). | | `verifyEndpoint` | Cross-check the live manifest against the registry before paying. See [Naming and trust](/publish/naming-and-trust/). | # Configuration > Every chain setting resolves as option, then environment variable, then network preset. All chain settings resolve as **`option` → environment variable → network preset**, so you can pass everything explicitly (recommended) or lean on environment variables and presets. | Option | Env fallback | Notes | | ------------------------------- | ------------------------------------- | ------------------------------------------------ | | `network` | `STELLAR_NETWORK` | `'testnet'` (default) or `'mainnet'` | | `contractId` | `STELLAR_CONTRACT_ID` | Kiba registry; omit for degraded (no-chain) mode | | `rpcUrl` | `STELLAR_RPC_URL` | Soroban RPC | | `trustlessWork.apiKey` | `TRUSTLESS_WORK_API_KEY` | escrow will not settle without it | | `trustlessWork.platformAddress` | `TRUSTLESS_WORK_PLATFORM_ADDRESS` | **required** when Trustless Work is active | | `platform.publicKey` (provider) | `KIBA_PLATFORM_PUBLIC_KEY` | accept platform-signed calls | | `discoveryUrl` (client) | `KIBA_DISCOVERY_URL`, `BACKEND_URL` | fallback registry lookup | | `wallet` / `secret` | `AGENT_WALLET_SECRET`, `KEYPAIR_PATH` | identity | Two instances with different configuration can coexist in one process, for example a testnet and a mainnet client. ## Testnet values [Section titled “Testnet values”](#testnet-values) | Setting | Value | | ------------------ | ---------------------------------------------------------- | | Registry contract | `CDYLMRS2UTBHNTWS67NC2OPQIH2HXGS36WZYC4JUMLKZWT7XXVUUX7XF` | | Soroban RPC | `https://soroban-testnet.stellar.org` | | USDC issuer | `GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5` | | Trustless Work API | `https://dev.api.trustlesswork.com` | See [Testnet](/stellar/testnet/) for the platform values of the public gateway. # Overview > kiba-sdk is the TypeScript library to publish a paid service or to consume services directly from your own code. ```bash npm install kiba-sdk # express is an optional peer dependency, only for the built-in HTTP server: npm install express ``` Requires **Node.js 18** or newer. The SDK is open: every service is built and owned by an external publisher. There is no privileged “Kiba service”. ## Two roles [Section titled “Two roles”](#two-roles) * **`AgentProvider`**: you **offer** a service. It verifies payment *before* running your handler, then serves and settles. See [AgentProvider](/sdk/provider/). * **`AgentClient`**: you **consume** a service. It discovers the service and handles payment automatically through the x402 handshake. See [AgentClient](/sdk/client/). The classes keep their historical `Agent*` names for API stability. They work for any kind of service. ## What the SDK abstracts [Section titled “What the SDK abstracts”](#what-the-sdk-abstracts) * The on-chain registry (register, update, deregister, discover) behind a `ChainClient` interface, implemented for Stellar and Soroban. * The Trustless Work escrow lifecycle (deploy, fund, release) and USDC trustlines. * The payment handshake: `402` quotes, the `X-PAYMENT` header, platform-signed certificates, replay protection. * Account bootstrap on testnet through friendbot. ## Where it is used [Section titled “Where it is used”](#where-it-is-used) The same library powers the Kiba gateway, the demo services, and the orchestrator. Anything the platform can do with a service, you can do from your own process. # AgentProvider > Offer a paid service. Configuration, handler, bootstrap, and serving options. ```ts import { AgentProvider, loadOrCreateKeypair } from 'kiba-sdk'; const provider = new AgentProvider({ // Identity (any of: wallet | secret | signer). wallet: loadOrCreateKeypair('./data/wallet.json'), // What you offer. service: 'translate-en-es', pricePerCall: 0.01, // floor price in USDC description: 'English → Spanish translation. Input: { text: string }', endpoint: 'https://my-service.example.com', // Where it settles. network: 'testnet', // 'testnet' | 'mainnet' contractId: process.env.STELLAR_CONTRACT_ID, // Kiba registry contract trustlessWork: { apiKey: process.env.TRUSTLESS_WORK_API_KEY, platformAddress: process.env.KIBA_PLATFORM_ADDRESS, // funded G... address }, // Accept fast platform-signed calls from the Kiba gateway. platform: { publicKey: process.env.KIBA_PLATFORM_PUBLIC_KEY! }, }); provider.serve(async (req: { text: string }) => ({ translation: translate(req.text), })); await provider.bootstrap(); // fund (testnet friendbot) + register on-chain await provider.listen(5001); // built-in express server (optional) ``` ## Options [Section titled “Options”](#options) | Option | Required | Notes | | ------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------- | | `wallet` / `secret` / `signer` | one of them | The service’s Stellar identity. `loadOrCreateKeypair(path)` creates and persists one. | | `service` | yes | Unique name, max 32 characters. | | `pricePerCall` | yes | Price in USDC. Acts as a floor when `priceFn` is set. | | `priceFn`, `pricingNote` | no | Dynamic pricing, see [Handler and pricing](/publish/handler-and-pricing/). | | `description` | yes | Shown in search. Describe the expected payload. | | `endpoint` | yes | Public URL stored on-chain. | | `network`, `contractId`, `rpcUrl` | see [Configuration](/sdk/configuration/) | Chain settings. | | `trustlessWork.apiKey`, `trustlessWork.platformAddress` | for escrow | Without them, escrow calls cannot settle. | | `platform.publicKey` | to accept gateway calls | The platform’s public key. Omit to require escrow on every call. | | `bodyLimit` | no | Default `256kb`. | | `rateLimitPerMinute` | no | Rate limit on the unpaid quote path, default 60. | | `allowUnverified` | no | Local demos only: serve without a chain. | ## Methods [Section titled “Methods”](#methods) * `serve(handler)`: registers the function that produces the result. It is called only after payment is verified. * `bootstrap()`: funds the account on testnet, sets the USDC trustline, and registers or reconciles the on-chain entry. * `listen(port)`: starts the built-in express server. `provider.app` exposes the express app if you want to add routes. * `verifyAndServe({ body, headers, rawBody, ip })`: the framework-agnostic core. Returns `{ status, body }`. ## Routes the built-in server exposes [Section titled “Routes the built-in server exposes”](#routes-the-built-in-server-exposes) | Route | Purpose | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `POST /service` | The paid endpoint. Without payment it answers `402` with a quote; with a valid `X-PAYMENT` header or platform signature it runs the handler. | | `GET /manifest` | Service name, owner wallet, price, and description. Used by discovery and by endpoint verification. | | `GET /health` | Liveness check. | # Trust model > How the platform proves a paid call to a service without sharing any secret. The platform proves a paid call to a service with an **asymmetric signature**: * The platform holds an ed25519 **private** key it never discloses. * Each service is configured with the platform’s **public** key (`platform.publicKey`, a Stellar `G…` address, safe to publish). * For each call the platform mints a short certificate `{ service, payloadHash, ts, nonce }` and **signs** it. The service **verifies** the signature, that the payload hash matches the body it received, that the certificate is fresh, and that the nonce has not been replayed. Because what a service holds (a public key) cannot mint calls, a leak of any single service’s configuration can never impersonate the platform to other services. ## Operating your own platform [Section titled “Operating your own platform”](#operating-your-own-platform) If you run your own gateway, mint the headers yourself: ```ts import { LocalPlatformSigner } from 'kiba-sdk'; const platform = LocalPlatformSigner.fromSecret(process.env.KIBA_PLATFORM_SECRET!); await client.callSigned(serviceEndpoint, payload, { signer: platform, service }); ``` Publish the corresponding public key to the services that should trust you. ## Without a platform [Section titled “Without a platform”](#without-a-platform) Standalone callers that do not trust any platform use the **x402 escrow** path, the default `call()`. It is fully trustless: the service checks the escrow on-chain and releases it after serving. Slower, but no party has to be trusted. # Registry contract > The Soroban smart contract that holds the service registry. The registry is a Soroban contract written in Rust and deployed to Stellar testnet. Its single responsibility is the **service registry**. Payments do not go through it. * **Contract id (testnet):** [`CDYLMRS2UTBHNTWS67NC2OPQIH2HXGS36WZYC4JUMLKZWT7XXVUUX7XF`](https://stellar.expert/explorer/testnet/contract/CDYLMRS2UTBHNTWS67NC2OPQIH2HXGS36WZYC4JUMLKZWT7XXVUUX7XF) * **Source:** `packages/contracts-soroban/` in the [repository](https://github.com/CoKeFish/kiba). ## Functions [Section titled “Functions”](#functions) | Function | Who can call | Effect | | ------------------ | -------------------------- | ---------------------------------------- | | `register_agent` | the owner (`require_auth`) | Creates the entry for a new service name | | `update_agent` | the owner | Changes price, endpoint, or description | | `deregister_agent` | the owner | Removes the entry | | `get_agent` | anyone | Reads one entry | ## Storage [Section titled “Storage”](#storage) One `Agent` entry per `service` name: `owner`, `service`, `price_per_call`, `endpoint`, `description`, `total_calls`, `total_earned`, `created_at`. Entries live in persistent storage with a TTL of about 30 days that the SDK renews before expiry. ## Events [Section titled “Events”](#events) `agent_registered`, `agent_updated`, `agent_deregistered`. The discovery backend consumes them to keep its index current. Anyone can do the same. ## What is not in the contract [Section titled “What is not in the contract”](#what-is-not-in-the-contract) The x402 escrow and the 95/5 split are handled by [Trustless Work](/stellar/trustless-work/). The `total_calls` and `total_earned` counters are informational; the gateway’s ledger is the source of truth for publisher earnings. # Testnet > Kiba runs on Stellar testnet. Public values, faucets, and explorers. Kiba runs on **Stellar testnet** today: the public gateway, the catalog, and the demo services all point at it. Testnet funds have no value, which makes it a safe place to try the whole flow end to end. ## Public values [Section titled “Public values”](#public-values) | Setting | Value | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Network passphrase | `Test SDF Network ; September 2015` | | Soroban RPC | `https://soroban-testnet.stellar.org` | | Horizon | `https://horizon-testnet.stellar.org` | | Friendbot | `https://friendbot.stellar.org` | | Registry contract | [`CDYLMRS2UTBHNTWS67NC2OPQIH2HXGS36WZYC4JUMLKZWT7XXVUUX7XF`](https://stellar.expert/explorer/testnet/contract/CDYLMRS2UTBHNTWS67NC2OPQIH2HXGS36WZYC4JUMLKZWT7XXVUUX7XF) | | USDC issuer (Circle, testnet) | `GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5` | | Trustless Work API | `https://dev.api.trustlesswork.com` | ## Platform values [Section titled “Platform values”](#platform-values) Two more values belong to the public gateway and are needed only by publishers: the **platform public key** (`KIBA_PLATFORM_PUBLIC_KEY`, to accept platform-signed calls) and the **platform address** (`KIBA_PLATFORM_ADDRESS`, the treasury that receives the fee on escrows). Both are public keys and safe to share. Ask the marketplace operator, or read them from the deployment you connect to. ## Getting testnet funds [Section titled “Getting testnet funds”](#getting-testnet-funds) * **XLM**: friendbot funds any new account with test XLM. The SDK calls it for you during `bootstrap()`. * **USDC**: Circle’s [testnet faucet](https://faucet.circle.com) issues test USDC on Stellar to an account that already has the trustline. See [USDC and trustlines](/stellar/usdc-and-trustlines/). ## Explorers [Section titled “Explorers”](#explorers) [stellar.expert](https://stellar.expert/explorer/testnet) shows accounts, contracts, and transactions. The explorer links that Kiba returns with each call point there. ## Resets [Section titled “Resets”](#resets) Stellar testnet is reset periodically by the Stellar Development Foundation. After a reset, accounts and the registry must be re-created: Kiba redeploys the contract and services re-run `bootstrap()`. # Trustless Work > Kiba settles payments through Trustless Work, an escrow-as-a-service on Stellar. How the integration works. [Trustless Work](https://www.trustlesswork.com) is a non-custodial escrow service on Stellar and Soroban. Kiba uses it for the escrow and the revenue split of every payment, in USDC, instead of a payment contract of its own. The Kiba contract keeps only the [registry](/stellar/registry-contract/). ## How Trustless Work works [Section titled “How Trustless Work works”](#how-trustless-work-works) A REST API (`https://dev.api.trustlesswork.com` on testnet, `https://api.trustlesswork.com` on mainnet) authenticated with an `x-api-key` header. The pattern is: 1. `POST` to an endpoint returns an **unsigned transaction** (XDR). 2. The caller **signs** it locally with its Stellar keypair. 3. `POST /helper/send-transaction` with the signed XDR submits it to the network. Trustless Work **deploys one contract per escrow**, so an escrow is identified by its `contractId`. The SDK calls this the `escrowId`. It travels in the `X-PAYMENT` header and is what a provider verifies and releases. ## Role mapping [Section titled “Role mapping”](#role-mapping) | Trustless Work role | In Kiba | | ---------------------------------------------------------- | ----------------------------------------------------------------------------- | | `serviceProvider`, `receiver`, `releaseSigner`, `approver` | the service owner (serves and releases to itself) | | `platformAddress`, `disputeResolver` | the Kiba treasury (receives the `platformFee`, resolves disputes and refunds) | | signer of deploy and fund | whoever pays: the treasury (credit mode) or the caller’s wallet (direct mode) | `platformFee = 5` (%) is the 95/5 split. ## Lifecycle of a direct call [Section titled “Lifecycle of a direct call”](#lifecycle-of-a-direct-call) ```plaintext open: POST /deployer/single-release → sign → send (→ contractId) POST /escrow/single-release/fund-escrow → sign → send (the service serves the request) release: POST /escrow/single-release/release-funds → sign → send refund: Trustless Work dispute flow, resolved by the disputeResolver ``` ## Batched settlement for gateway calls [Section titled “Batched settlement for gateway calls”](#batched-settlement-for-gateway-calls) Calls through the gateway do not open an escrow each. The treasury funds a **settlement escrow per publisher and cycle** as calls happen, and periodically releases it and sweeps the remainder to the publisher’s wallet. Trustless Work applies the 5 % at release. ## Configuration [Section titled “Configuration”](#configuration) ```plaintext TRUSTLESS_WORK_API_KEY= # from the Trustless Work BackOffice dApp TRUSTLESS_WORK_API_URL=https://dev.api.trustlesswork.com TRUSTLESS_WORK_PLATFORM_ADDRESS= # treasury (platformFee + disputes) TRUSTLESS_WORK_PLATFORM_FEE=5 TRUSTLESS_WORK_TRUSTLINE_ADDRESS= # escrow asset issuer (testnet: USDC) TRUSTLESS_WORK_TRUSTLINE_SYMBOL=USDC ``` Without `TRUSTLESS_WORK_API_KEY` the SDK starts with escrow disabled: registration and discovery keep working, and any escrow operation throws a clear error. ## Getting an API key [Section titled “Getting an API key”](#getting-an-api-key) Sign in to the Trustless Work BackOffice dApp, create a profile, and generate an API key for the network you target. Trustless Work’s own [documentation](https://docs.trustlesswork.com) covers the dApp and the API in depth. # USDC and trustlines > Why a Stellar account needs a USDC trustline and how Kiba sets it up. On Stellar, an account can hold an asset other than XLM only after it opens a **trustline** to that asset’s issuer. Kiba settles in **USDC**, so every account that receives or spends USDC needs the trustline: * **Service accounts** get it during `bootstrap()`. * **User wallets** on the gateway get it when they are provisioned. * **SDK clients** paying directly get it during `bootstrap()` and must then be funded with USDC. A trustline raises the account’s minimum XLM reserve by 0.5 XLM. On testnet friendbot covers it; on mainnet fund the account first. ## Issuers [Section titled “Issuers”](#issuers) | Network | USDC issuer | | ------- | ------------------------------------------------------------------- | | Testnet | `GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5` (Circle) | | Mainnet | `GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN` (Circle) | ## Funding a user wallet [Section titled “Funding a user wallet”](#funding-a-user-wallet) A user’s Kiba wallet is a plain Stellar account. To fund it, send USDC to the address shown in the dashboard. Funding the wallet does not add credits; see [Credits and wallet](/concepts/credits-and-wallet/). # FAQ > Short answers to the questions people ask most about Kiba. ### Do I need crypto to use Kiba? [Section titled “Do I need crypto to use Kiba?”](#do-i-need-crypto-to-use-kiba) No. You sign in with an email, start with 5 USD of credit, and top up in USD. The on-chain settlement happens behind the gateway. ### Do I need crypto to publish a service? [Section titled “Do I need crypto to publish a service?”](#do-i-need-crypto-to-publish-a-service) Your service needs a Stellar account, which the SDK creates for you on testnet, and a Trustless Work API key. Earnings arrive as USDC on Stellar. ### Is this on mainnet? [Section titled “Is this on mainnet?”](#is-this-on-mainnet) Not yet. Kiba runs on Stellar testnet. The flow is complete end to end, but balances have no real value. ### What does Kiba charge? [Section titled “What does Kiba charge?”](#what-does-kiba-charge) 5 % of each call, applied at settlement. The publisher receives 95 %. There are no subscriptions or monthly fees. ### Which assistants work? [Section titled “Which assistants work?”](#which-assistants-work) Claude (web, desktop, mobile) and ChatGPT through the remote connector. Claude Code, Cursor, Claude Desktop, Codex, and any MCP client through `kiba-mcp` or the Windows installer. ### Can my service be called without Kiba? [Section titled “Can my service be called without Kiba?”](#can-my-service-be-called-without-kiba) Yes. Any `AgentClient` can pay any registered service directly through a Trustless Work escrow. The registry is public, and anyone can run an indexer. ### Where is the money when I publish? [Section titled “Where is the money when I publish?”](#where-is-the-money-when-i-publish) In the Stellar account that owns the on-chain registration: the keypair your service bootstrapped with, or your Kiba wallet if you registered from the dashboard. See [Publisher dashboard](/publish/dashboard/). ### Can I self-host the gateway? [Section titled “Can I self-host the gateway?”](#can-i-self-host-the-gateway) The whole platform is open source. `docker compose up` in the repository brings up the gateway, discovery, dashboard, and demo services against testnet. Point `kiba-mcp` at it with `KIBA_URL`. ### Where do I report a bug? [Section titled “Where do I report a bug?”](#where-do-i-report-a-bug) Open an issue at . # Troubleshooting > Problems connecting an assistant or calling a service, and how to fix them. ## Connecting [Section titled “Connecting”](#connecting) * **Claude cannot add the connector.** Check that the URL is exactly `https://api.kiba.tools/mcp` and that your plan supports custom connectors (Pro, Max, Team, Enterprise). Otherwise use [`kiba-mcp`](/connect/ide/). * **ChatGPT rejects the connector.** Developer mode must be enabled first, and the URL must be HTTPS. * **The browser never opens with `kiba-mcp`.** Restart the client after editing the MCP configuration, then trigger any Kiba tool. On a headless machine, use `KIBA_API_KEY` instead. * **“Unauthorized” after it used to work.** Disconnect the app in the dashboard under **Credentials** and connect again. Tokens last 30 days. ## Calling services [Section titled “Calling services”](#calling-services) * **`insufficient balance`.** Top up credits on the dashboard’s **Billing** page, or fund your wallet with USDC. * **The call takes a long time.** Platform-signed calls return in under a second. Direct escrow calls (SDK) wait for Trustless Work and the Stellar network and can take 15 to 150 seconds. * **The service returned an error.** The gateway refunds the debit to your credits. Check the payload against the service’s description; the assistant may have guessed the fields. * **Unknown field error on `POST /v1/call`.** Put the service’s input inside `payload`. Only `service` and `payload` are allowed at the top level. ## Publishing [Section titled “Publishing”](#publishing) See [Troubleshooting for publishers](/publish/troubleshooting/). # Use cases > What people build on Kiba, on both sides of the rail. ## For users of an assistant [Section titled “For users of an assistant”](#for-users-of-an-assistant) * **Specialized answers inside a normal chat.** Ask Claude or ChatGPT for a translation, a market price, a code review, a scraped page, or a risk assessment, and let it pay the specialist that does it well instead of guessing. * **One balance for every tool.** Top up once. Every service is paid from the same credits, with the price shown before each call and a transaction history afterwards. * **No accounts to manage.** No API keys to copy, no subscriptions to a tool you need once. ## For publishers [Section titled “For publishers”](#for-publishers) * **Monetize a model or an API per call.** Wrap it with the SDK, set a price, and get discovered by every connected assistant. Billing, discovery, and auth are the rail’s job. * **Sell data.** Indexers, feeds, and datasets charged per query, with dynamic pricing per request size. * **Agents paying agents.** A service can consume other services with the SDK, paying from its own wallet, trustlessly. * **Internal tools for a team’s assistants.** Publish a service and point your team’s assistants at it. Usage and earnings are tracked per call. ## Industries where per-call payment fits [Section titled “Industries where per-call payment fits”](#industries-where-per-call-payment-fits) | Industry | Example service | | ------------------ | ---------------------------------------------------- | | Language | translation, localization review, transcription | | Finance and crypto | price feeds, yield search, smart-contract risk audit | | Software | code review, dependency audit, test generation | | Data | web scraping, document extraction, entity lookup | | Operations | geocoding, time-zone conversion, scheduling | The demo services in the repository (`packages/demo-agents/`) are working templates for several of these.