Skip to main content
Glama

Kaia MCP Server

Production-ready Model Context Protocol (MCP) server for the Kaia blockchain. Exposes 25 partner-safe tools (26 if KAIA_ALLOW_UNSAFE_WALLET=1), 5 resources, and 6 prompts for balance, transactions, blocks, tokens, NFTs, contracts, network info, and calldata encoding.

HTTP is a partner-style connector: OAuth 2.1 with PKCE (browser) or device flow (CLI), fail-closed bearer auth, and token scopes mapped to an allowed-tool registry. An in-process demo IdP runs with the HTTP server so tests and CI need no real credentials. See docs/AUTH.md.

Installation

npm install -g kaia-mcp
# or
npx kaia-mcp

Related MCP server: KaiaFun MCP

Quick start

stdio (default) — run and connect via stdin/stdout (e.g. Claude Desktop, Cursor):

npx kaia-mcp
# or
npx kaia-mcp --transport stdio

HTTP — Streamable HTTP on a port. Partner default (KAIA_AUTH_MODE=required) requires Authorization: Bearer on every MCP request. The same process serves the demo OAuth/OIDC endpoints.

npx kaia-mcp --transport http --port 3100
# GET http://127.0.0.1:3100/health
# GET http://127.0.0.1:3100/.well-known/openid-configuration

Tools (25 partner-safe)

Tool

Description

get_kaia_balance

Get KAIA balance for an address

get_account_info

Get account summary: balance, tx count, nonce

get_account_tokens

List ERC-20 token holdings for an address

get_account_nfts

List NFT holdings for an address

get_transaction

Get transaction by hash

get_transaction_receipt

Get transaction receipt and status

get_account_transactions

List recent transactions for an address

estimate_gas

Estimate gas for a transaction

get_block_number

Current block number

get_block

Get block by number or tag

get_block_rewards

Block rewards for a block

get_token_info

Token metadata (name, symbol, supply)

get_token_holders

Top token holders

get_token_transfers

Token transfer history

get_token_allowance

ERC-20/KIP-7 allowance (owner/spender) for DeFi

get_nft_info

NFT collection info

get_nft_item

Single NFT item (owner, metadata)

get_nft_transfers

NFT transfer history

read_contract

Read contract view/pure function

get_contract_abi

Verified contract ABI from KaiaScan

get_contract_source

Verified contract source from KaiaScan

get_gas_price

Current gas price

get_kaia_price

KAIA price (USD, BTC, stats) from KaiaScan

get_chain_info

Chain id and name (mainnet/kairos)

encode_function_data

Encode contract call data from ABI and args (kaia:encode)

generate_wallet

Not in the default list. Unsafe local-dev only (KAIA_ALLOW_UNSAFE_WALLET=1 + kaia:wallet). Never returns private keys in partner mode.

Resources (5)

URI

Description

kaia://mainnet/status

Mainnet status: block height, gas price, KAIA price

kaia://kairos/status

Kairos testnet status

kaia://mainnet/tokens/popular

Popular mainnet token addresses with name/symbol

kaia://mainnet/top-accounts

Top 100 KAIA holders

kaia://docs/rpc-methods

Static reference of Kaia RPC methods

Prompts (6)

Name

Args

Description

analyze-wallet

address, network?

Analyze wallet: balance, txs, tokens

investigate-transaction

txHash

Investigate tx: status, gas, transfers

token-research

contractAddress, network?

Research token: supply, holders, activity

nft-lookup

contractAddress, tokenId, network?

Look up NFT: owner, metadata, history

gas-report

network?

Gas report: price, history, recommendations

smart-contract-audit

contractAddress, network?

Review contract: ABI, source, type

Configuration

Environment variables (see .env.example):

Variable

Description

Default

KAIA_RPC_URL

Kaia mainnet RPC endpoint

https://public-en.node.kaia.io

KAIA_KAIROS_RPC_URL

Kairos testnet RPC

https://public-en-kairos.node.kaia.io

KAIASCAN_API_KEY

KaiaScan API key (optional)

—

KAIA_DEFAULT_NETWORK

mainnet or kairos

mainnet

LOG_LEVEL

debug, info, warn, error

info

RATE_LIMIT_RPC

Max RPC requests per second

10

RATE_LIMIT_KAIASCAN

Max KaiaScan requests per second

5

RPC_TIMEOUT_MS

RPC request timeout (ms)

30000

KAIASCAN_TIMEOUT_MS

KaiaScan request timeout (ms)

15000

KAIA_AUTH_MODE

HTTP auth: required or off

required

KAIA_OAUTH_CLIENT_ID

Demo public client id

kaia-mcp-demo

KAIA_ACCESS_TOKEN_TTL_SECONDS

Demo access-token TTL

900

KAIA_PUBLIC_URL

Public origin (https://host[:port], no path): OAuth issuer, canonical resource URI and token aud; also the default allowed browser Origin

http://127.0.0.1:<port>

KAIA_OAUTH_LEGACY_AUDIENCE

Extra aud minted next to the canonical URI for gateways that pin a non-URI audience (never accepted alone). KAIA_OAUTH_AUDIENCE is a deprecated alias

unset

KAIA_OAUTH_REQUIRE_RESOURCE

Reject authorize/device/token requests without an RFC 8707 resource

off (missing = this server)

KAIA_ALLOWED_ORIGINS

Extra browser origins allowed on the MCP/OAuth endpoints (comma-separated); a foreign Origin gets 403, no Origin passes

only the public origin

KAIA_OAUTH_PREVIOUS_SIGNING_KEY_FILES

Retired signing keys (comma-separated PEMs) still published in the JWKS and accepted for verification

unset

KAIA_OAUTH_SIGNING_KEY_FILE

Dev RS256 key path, created 0600 if missing; keep it gitignored (.kaia-dev/)

unset (in-memory key per process)

KAIA_OAUTH_REVOCATION_FILE

Where revoked access-token jtis are persisted (atomic, durable writes, 0600). A corrupt, unreadable or group/world-writable file refuses startup. One file per server process: a file another running instance holds is refused at startup, so instances sharing a signing key must each set their own

revoked-jti.json next to the signing key file; in memory when no key file is set

KAIA_INTROSPECTION_CLIENT_ID

Gateway client id for /oauth/introspect

kaia-mcp-gateway

KAIA_INTROSPECTION_CLIENT_SECRET

Gateway secret (HTTP Basic). Unset: introspection is not offered

unset

KAIA_ALLOW_UNSAFE_WALLET

Enable generate_wallet private keys (local only)

off

MCP client setup

Cursor — add to Cursor MCP settings (e.g. ~/.cursor/mcp.json or project MCP config):

{
  "mcpServers": {
    "kaia": {
      "command": "npx",
      "args": ["kaia-mcp"],
      "env": {}
    }
  }
}

Claude Desktop — in Claude Desktop config (e.g. ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "kaia": {
      "command": "npx",
      "args": ["kaia-mcp"],
      "env": {}
    }
  }
}

Override env as needed, e.g. "env": { "KAIA_RPC_URL": "https://your-rpc.io", "KAIASCAN_API_KEY": "your-key" }.

Programmatic use

import { createKaiaMcpServer, runKaiaMcpServer } from "kaia-mcp";

// Get the MCP Server instance (e.g. for custom transport)
const server = createKaiaMcpServer();

// Run over stdio (CLI default)
await runKaiaMcpServer();

For HTTP:

import { runKaiaMcpServerHttp } from "kaia-mcp";
await runKaiaMcpServerHttp(3100);

Docker

docker build -t kaia-mcp .
docker run -p 3100:3100 -e KAIA_RPC_URL=https://public-en.node.kaia.io kaia-mcp

Server listens on port 3100 (Streamable HTTP transport). Override env as needed.

Connecting to the Docker server

The container runs the HTTP transport (not stdio), so clients must connect by URL.

Cursor — in MCP settings (e.g. ~/.cursor/mcp.json or project MCP config), add a server entry with url:

{
  "mcpServers": {
    "kaia": {
      "url": "http://localhost:3100"
    }
  }
}

If your client expects a path, use http://localhost:3100/mcp. Restart Cursor after changing MCP config.

Claude Desktop — if your Claude Desktop build supports remote MCP URLs, use the same url in its MCP config.

Test from the host (with the container running). Health is unauthenticated; MCP is not:

curl -s http://localhost:3100/health
# Obtain a demo token (see docs/AUTH.md), then:
curl -s -X POST http://localhost:3100 \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | jq

You should see a list of tools filtered by the token’s scopes. Replace localhost with your machine’s IP or hostname when connecting from another device.

Partner integration

This server is an MCP connector, not a hosted product partnership. Integrate over HTTP with OAuth; do not treat stdio as a partner path.

Integration checklist

  1. Discover /.well-known/oauth-protected-resource and /.well-known/openid-configuration (demo) or your authorization server’s metadata. Access tokens are RS256 JWTs; fetch keys from the discovery jwks_uri and pin iss and aud (both the server's canonical URI, KAIA_PUBLIC_URL) instead of trusting whatever the token says. Send resource=<canonical URI> on authorize and token requests (RFC 8707) and check the iss on the authorization response (RFC 9207).

  2. Register a public client. Require PKCE S256 for browser agents; use device flow for CLIs that cannot host a redirect.

  3. Allowlist redirect URIs. The demo IdP accepts only http://127.0.0.1/callback, http://localhost/callback, and /cb variants.

  4. Request least privilege: kaia:read for chain reads, add kaia:encode only if the agent must build calldata. Never request kaia:wallet in production.

  5. Send Authorization: Bearer <access_token> on every MCP HTTP request. The transport is stateless (MCP 2026-07-28 via SDK v2 createMcpHandler): no Mcp-Session-Id, modern clients may use server/discover instead of initialize, GET/DELETE answer 405. Match Mcp-Method/Mcp-Name/MCP-Protocol-Version to the body on modern requests (-32020 on mismatch). tools/list is cacheScope: private.

  6. Handle fail-closed errors literally: -32040 unauthorized, -32041 token_expired, -32043 invalid_token (HTTP 401 with a WWW-Authenticate challenge naming resource_metadata), and -32042 insufficient_scope (HTTP 403, error="insufficient_scope" with the required scope). Retry only after a new token; do not retry a denied tool.

  7. On disconnect or user logout, POST /oauth/revoke with the access or refresh token. Revocation is by jti and only the issuer knows about it: a gateway that verifies JWTs offline must also call /oauth/introspect (client-authenticated) if it needs to see revocations before exp.

  8. Keep tokens out of logs, crash dumps, eval fixtures, and git. Prefer a token fingerprint if you must correlate requests.

  9. Leave KAIA_ALLOW_UNSAFE_WALLET unset. generate_wallet must not appear in partner tool lists and must not return private keys.

  10. Point production at your own OIDC issuer; the in-process demo IdP is for tests/CI/local bring-up only. No real user secrets or signing keys belong in this repo.

  11. If you keep your own copy of the tool → scope map (e.g. in a policy gateway), compare it against GET /.well-known/kaia-mcp/tool-scopes at startup and refuse to run on drift.

Threat notes

  • Scopes. A kaia:read token must not call encode_function_data. Scope checks run before handlers; a deny has no chain or wallet side effect.

  • Secret handling. Access tokens are signed JWTs and are not stored; refresh tokens are hashed at rest. The logger redacts bearer values and bare JWTs. The signing key is generated at startup (or read from a gitignored dev path) and only the public JWK is published. Wallet private keys are not emitted unless the explicit unsafe dev flag is on.

  • Offline verification vs revocation. A JWT stays cryptographically valid until exp even after /oauth/revoke. kaia-mcp itself rejects revoked jtis; external verifiers need introspection or a short TTL.

  • Algorithm confusion. Only RS256 with the published kid is accepted; alg=none, HS*, and foreign keys fail as invalid_token.

  • Sessions and DNS rebinding. There are no MCP sessions to steal; the bearer token is checked on every request. A browser page on a foreign origin is refused with 403 before auth (allow-list with KAIA_ALLOWED_ORIGINS).

  • PKCE downgrade. code_challenge_method=plain is rejected.

  • Open redirect. Unregistered redirect_uri values are rejected.

  • Fallbacks. KAIA_AUTH_MODE=off and stdio skip OAuth. Those paths are local-only. Partners must not ship them as a “fallback” for failed authentication; failed auth is a deny.

  • Unsafe wallet flag. If an operator enables KAIA_ALLOW_UNSAFE_WALLET=1, private keys can leave the process. Treat that as a break-glass local tool, not a partner feature.

Full protocol detail: docs/AUTH.md.

License

MIT

Related MCP Connectors

Related MCP Servers