TapeAPI

MCP serverEverything else

Signed BNB Chain reads (balances, tokens, NFTs, prices, TapeOut names) with verifiable receipts

Available today. Use it from your connected AI after setup.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Then ask your AI: use TapeAPI

Install TapeAPI

The server’s own address, for the clients that take one directly. Or connect ahel onceand every client you use reads it from one address, with the account kept on ahel rather than in each client’s config.

  • Claude Code

    claude mcp add --transport http --scope user tapeapi 'https://api.tapeapi.fun/mcp'

    Run it once in your project, then open /mcp to approve any sign-in the server asks for.

  • Claude Desktop

    https://api.tapeapi.fun/mcp

    Add a custom connector in Settings, paste this address, and approve the sign-in.

  • Cursor

    cursor://anysphere.cursor-deeplink/mcp/install?name=tapeapi&config=eyJ1cmwiOiJodHRwczovL2FwaS50YXBlYXBpLmZ1bi9tY3AifQ==

    Open the link and Cursor adds the server at that address.

  • ChatGPT

    https://api.tapeapi.fun/mcp

    In Settings, enable Developer mode, create an MCP app, and paste this address. Your plan and workspace must allow custom apps.

  • Codex

    codex mcp add tapeapi --url 'https://api.tapeapi.fun/mcp'

    Run it once, then sign in with codex mcp login tapeapi if the server asks for an account.

From the project's README

As published by BruceLanLan/tapeapi in README.md.

Tape out a circuit, and its container is your API. Every response is signed by it, anyone can verify it against the chain, and containers can talk to each other over end-to-end encrypted channels.

TapeAPI is the service and communication layer of the TapeOut ecosystem on BNB Chain. In that ecosystem, DeWEB is websites, TapeSend is messaging, and TapeAPI is services.

中文说明 · Guides · Specifications · Examples · Docs · Website · Changelog · Roadmap · Contributing · Code of Conduct

Status: pre-alpha (v0.4.0). The free tier needs no contract of ours and runs on TapeOut's deployed contracts. Our own contracts (the paid-call escrow, the service directory, ChannelBus) are not audited by a third party; ChannelBus is deployed (address below). Interfaces may still change. The TAP numbers below are proposed to the TapeKit maintainers and not yet assigned.

Try the live service in 30 seconds

A free public service runs at https://api.tapeapi.fun under the TapeOut name 11.1013.tape. Ask it for the BNB price:

curl -s https://api.tapeapi.fun/tapeapi/v1/bnbUsd -H 'content-type: application/json' -d '{"id":"1","params":{}}'

curl shows you the signed envelope (result, container, ts, block, sig) but does not check it. The SDK does. The packages are not on npm yet, so set up the repository once (Node.js 20 or later):

git clone https://github.com/BruceLanLan/tapeapi.git && cd tapeapi && npm install

Or install just the SDK into your own project from the GitHub release (not the npm registry):

npm install https://github.com/BruceLanLan/tapeapi/releases/download/v0.4.0/tapeapi-sdk-0.4.0.tgz

Save this as try.mjs inside the tapeapi directory (@tapeapi/sdk resolves through the repository's workspace; a script saved anywhere else fails with ERR_MODULE_NOT_FOUND) and run node try.mjs:

import { createTapeAPI } from '@tapeapi/sdk'

const api = createTapeAPI({
  rpcUrls: ['https://bsc-dataseed.bnbchain.org', 'https://bsc-dataseed1.defibit.io', 'https://bsc-dataseed1.ninicoin.io'],
  quorum: 2,
})
const svc = await api.resolve('11.1013.tape')             // name -> container -> on-chain manifest -> holder's delegation
const { result, verified } = await api.call(svc, 'bnbUsd', {})
console.log(result, verified)                              // verified is true only after the signature checked out

No install at all: the playground runs the same SDK in the browser. Every method of the public service is listed in Public API.

Use it from Claude, Cursor or any MCP client

The same eight methods are MCP tools at https://api.tapeapi.fun/mcp (Streamable HTTP, no key). In Claude, add it under Settings > Connectors > Add custom connector; in Cursor, add it to mcp.json:

{ "mcpServers": { "tapeapi": { "url": "https://api.tapeapi.fun/mcp" } } }

Every result is signed by the service's on-chain delegated key and carries a receipt with a verification link that anyone can check against the chain. The remote server signs its answers; the local command tapeapi-mcp, in the SDK's release package, checks every answer itself before the model sees it. Setup for each client, receipts and limits: MCP guide.


Why TapeAPI

An API today is a URL plus an account plus trust. You sign up with the vendor, you trust whatever its server says, and the vendor can change the answer, the price or the rules at any time.

TapeAPI makes the identity of a service an on-chain object and every answer a signed statement:

  • The service is a circuit. Whoever holds the circuit NFT owns the service. Transfer the NFT and the service moves with it; nobody can take the name away.
  • Every answer is signed and bound to your request. A client checks the signature against a key the circuit's holder authorised on chain. A tampered, replayed or unsigned answer is an error, never a result.
  • No sign-up, no API keys. Free methods are just called. Paid methods are paid with off-chain vouchers that settle on chain in batches; the protocol takes zero fees.
  • Private channels between containers. Two services, two agents or two apps can open an end-to-end encrypted channel, carried by a relay or by the chain itself, where the carrier only ever sees ciphertext.

How it works

sequenceDiagram
    autonumber
    participant C as Client (SDK)
    participant B as BNB Chain
    participant S as Service
    C->>B: resolve: circuit -> container (DeWebHub), holder (ownerOf)
    C->>B: read the manifest from the container's site (SiteRegistry, SHA-256 checked)
    Note over C: check the holder's EIP-712 delegation of the service's signing key
    C->>S: POST /tapeapi/v1/{method} { id, params, voucher? }
    S-->>C: { result, container, ts, block, sig }
    Note over C: verify the signature over the request and the answer; only then return the result
  1. Identity (TAP-20). A circuit's ERC-6551 container is the service identity. Its site holds .well-known/tapeapi.json, the manifest: endpoints, methods, prices and the service's signing key.
  2. Delegation. The circuit's holder signs an EIP-712 delegation that names that signing key and an expiry. The domain is anchored on TapeOut's deployed DeWebHub, so a service works before any contract of ours exists.
  3. Signed envelope (TAP-21). Every answer, success or error, is signed over a digest that binds the container, the request id, the method and parameters, the result and a timestamp.
  4. Payment (TAP-22). Paid methods take cumulative vouchers, settled from a per-provider escrow channel.
  5. Channels (TAP-26, TAP-27). Holder-authorised channel keys, an X3DH-style handshake and ChaCha20-Poly1305 frames, over a relay or over ChannelBus, a stateless event-only contract.

Quick start

Requirements: Node.js 20 or later. The packages are not on npm yet; use the repository.

git clone https://github.com/BruceLanLan/tapeapi.git
cd tapeapi
npm install

Call a service

Run the minimal example service locally (it reads BNB Chain through public nodes):

node examples/reader-service/index.mjs        # listens on :8787 with a throwaway signing key

Call it from code. The SDK resolves the manifest, calls the method and verifies the signature before it returns:

import { createTapeAPI } from '@tapeapi/sdk'

const api = createTapeAPI({ dev: true })                           // dev: allow a local http:// service
const svc = await api.resolve({ dev: 'http://127.0.0.1:8787' })
const { result, verified } = await api.call(svc, 'blockNumber', {})
console.log(result.blockNumber, verified)

On mainnet, resolve by TapeOut name, container address or circuit, with at least two RPC nodes that must agree:

const api = createTapeAPI({
  rpcUrls: ['https://bsc-dataseed.bnbchain.org', 'https://bsc-dataseed1.defibit.io', 'https://bsc-dataseed1.ninicoin.io'],
  quorum: 2,
})
const svc = await api.resolve('0x<container>')                     // or '11.1013.tape', or { circuits: '0x…', tokenId: '11' }
const { result } = await api.call(svc, 'blockNumber', {})

Or with curl, and verify by hand later (how):

curl -s -X POST http://127.0.0.1:8787/tapeapi/v1/blockNumber \
  -H 'content-type: application/json' -d '{"id":"1","params":{}}'

Run a service

Wrap any function, or any existing REST API, as a signed method:

import { createProvider } from '@tapeapi/server'

const provider = createProvider({
  manifest,                                  // your tapeapi.json
  signerKey: process.env.SIGNER_KEY,         // the key the circuit's holder delegates to
  rpcUrls: [/* >= 2 BNB Chain nodes */], quorum: 2,
  methods: {
    blockNumber: async (_params, ctx) => ({ blockNumber: ctx.block }),
    quote: async ({ symbol }) => fetch(`https://your.api/quote/${symbol}`).then((r) => r.json()),
  },
})
await provider.listen(8787)                  // Node; on Cloudflare Workers use provider.handleRequest(request)

Going live takes a circuit with an opened container, a delegation signed by its holder, and the manifest written to the container's site. The holder console does all three from a phone wallet. See Run a service.

Features

Verifiable answersSigned envelopes bound to the exact request; signer checked against the on-chain holder; freshness window; an independent Python implementation checks the test vectors.
Quorum readsChain reads need agreement from every answering node, never a majority. callQuorum accepts a result only when independent providers return the same bytes.
Pay per callCumulative EIP-712 vouchers, session keys, an escrow with a withdrawal cooldown, zero protocol fee, optional voluntary contribution chosen by each provider.
Private channelsTAP-26: mutual authentication, forward secrecy, per-direction keys, replay and reorder protection; relay or on-chain transport.
Private groupsTAP-27: up to 32 containers, owner-managed epochs, encrypted roster, per-sender signatures.
On-chain transport that does not lose messagesThe ChannelBus reader holds rather than skips: it works with public nodes' history limits, result caps and failures, and warns about anything it cannot read. Tested with thousands of randomised adversarial runs.
AI agentsexposeTapeAPI turns any service into WebMCP tools for in-browser agents; every answer is signature-checked, paid methods need an explicit budget.
Runs anywhereNode, Cloudflare Workers (Fetch API), browsers and DeWEB sites; three small audited dependencies (@noble/curves, @noble/hashes, @noble/ciphers).

Packages and repository layout

PathWhat it is
sdk/@tapeapi/sdk: resolve, call, pay, verify, channels, groups, WebMCP bridge.
server/@tapeapi/server: the provider runtime (Node listen and Fetch handleRequest), metering, rate limits.
contracts/Solidity with Foundry tests: TapeAPIEscrow, ServiceDirectory, ChannelBus.
spec/The TAPs, bilingual (English authoritative), with test vectors and an independent Python verifier.
examples/Runnable services: minimal reader, Web2 adapter, DeFi reads, attested cross-chain reads, a relay, a Cloudflare Worker, a WebMCP demo.
conformance/A black-box suite any provider or relay implementation can run against a URL.
site/The website and the holder console (site/console/), plain static files.
docs/Guides and design notes; start at docs/README.md.

Specifications

TAPTitleIn one line
TAP-1TAP processTypes, statuses, numbering and required sections.
TAP-20Service identity and manifestA service is a circuit; .well-known/tapeapi.json; the holder's EIP-712 delegation; the resolution algorithm.
TAP-21Signed response envelopePOST {live}/{method}; the TAPI-1/resp/v2 digest; canonical JSON; error codes.
TAP-22Metered paymentCumulative vouchers, per-provider escrow channels, zero protocol fee.
TAP-23Attested ReadSigned, block-pinned reads of other chains, agreed by independent providers.
TAP-24Intent RFQSigned quotes for bridge-free cross-chain swaps (frozen until staking exists).
TAP-25Circuit-Verified MethodsMethods bound to a circuit whose on-chain eval() settles disputes.
TAP-26Tape ChannelEnd-to-end encrypted channels between containers; relays and ChannelBus.
TAP-27Tape GroupPrivate groups of up to 32 containers.

On-chain addresses (BNB Chain, chainId 56)

ContractAddressOwner
DeWebHub0xe61A9C7213a6Aa616C246a2B569e555B417b25eeTapeOut (deployed)
SiteRegistry0xd006ffdd5Ae313B17729621A00999cD3C71CE5e6TapeOut (deployed)
Processor factory0x68224F668083c29e9800Be2a646d42d18cedF7e2TapeOut (deployed)
BEM token0x5ce033b2bfca3af30b3e8c8457deaf776a8b695aTapeOut (deployed)
ChannelBus0x486110c35d9b90a9d6D85c8063A065f9e7b6b707TapeAPI (no owner, no state, no upgrade path)
TapeAPIEscrow, ServiceDirectorynot deployedTapeAPI

Quality

  • Tests: about 710 JavaScript tests (npm test), 169 Foundry tests (cd contracts && forge test), and 102 checks by an independent Python implementation of the signatures, hashes and encodings (python3 spec/vectors/verify.py).
  • Adversarial review: twelve rounds of review with a written finding, a failing test and a fix for each; the on-chain reader is covered by a randomised test of faulty, lying and noisy nodes, reorgs and room changes.
  • Recorded reality: what real BNB Chain nodes answer (history refusals, result caps, lagging backends) is recorded from mainnet and replayed in tests.
  • Not yet: an external audit of the contracts. Do not hold funds you cannot afford to lose in the escrow.

Security

Report vulnerabilities privately, as described in SECURITY.md. Please do not open public issues for security problems.

Contributing

Issues and pull requests are welcome; see CONTRIBUTING.md. Specification changes go through the TAP process in TAP-1. All three test suites must pass.

License

Code is MIT (LICENSE): contracts/, sdk/, server/, examples/, conformance/, scripts/, site/. The specifications in spec/ are CC0-1.0 (LICENSE-SPEC).

Credits

The idea of a service layer for TapeOut, "DeWEB is websites, TapeSend is messaging, TapeAPI is services", came from @Theairresearch. A permanent 10% of any revenue TapeAPI earns goes to them.

Built on TapeOut and TapeKit.

Advanced
Delivery
tapeapi MCP server → your ahel connector (mcp.ahel.ai) → your AI.
Item type
mcp-server
Key
io-github-brucelanlan-tapeapi
Source
github.com/BruceLanLan/tapeapi
Hosted endpoint
https://api.tapeapi.fun/mcp