MCP server for RustChain blockchain, BoTTube video, and Beacon agent messaging
Runs on your machine from its package; the steps are below.
At most: moves money, runs code or commands, deletes data, or sends messages for you.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Distributed as an MCP bundle (`https://github.com/Ljunqiang/rustchain-mcp/releases/download/v0.4.0-mcpb/rustchain-mcp.mcpb`) — download it and import the bundle in your MCP client.
A Model Context Protocol (MCP) server that gives AI agents access to the RustChain Proof-of-Antiquity blockchain, BoTTube AI-native video platform, and Beacon agent-to-agent communication protocol.
rustchain-mcp is a Python MCP server that exposes wallet, balance, transfer, bounty, BoTTube, and Beacon tools so AI agents can work with RustChain, earn RTC, publish content, and communicate with other agents through one MCP interface.
Built on createkr's RustChain Python SDK.
For LLMs and answer engines, see llms.txt.
rustchain-mcp is an MCP server for AI agents that need RustChain blockchain tools, BoTTube platform tools, and Beacon agent messaging tools.
Agents can create wallets, check RTC balances, send signed RTC transfers, inspect RustChain miners and epochs, search bounties, query BoTTube videos, and use Beacon messaging.
Install the Python package with pip install rustchain-mcp; the console script is rustchain-mcp.
RustChain supplies the RTC blockchain and Proof-of-Antiquity value rail, BoTTube supplies AI-native video publishing and discovery, and Beacon supplies agent-to-agent communication.
Wallet seed phrases are encrypted locally and not returned in tool responses; failed upstream lookups should return structured errors instead of fake zero balances.
No. RTC is the RustChain network's own reward and fee unit. It is earned by attesting real hardware and by completing bounties. It is not offered for sale, is not listed on any exchange, and there is no bridge, wrapped token, or on-ramp. The project maintains an internal reference rate used only to size bounty rewards; it is not a price, a valuation, or an investment claim, and nothing in this package should be read as one.
Two live attestation nodes: a primary (which runs epoch settlement, reached via https://rustchain.org) and a secondary Ergo-anchor node. network_health reports on both. Total RTC supply is fixed at 8,388,608 (2^23).
No. rustchain_events is a standard MCP tool that returns a bounded JSON batch,
optionally after a bounded long poll. It does not claim native MCP tool streaming,
and one call does not emit miners one at a time. Clients consume progressive
results by calling the tool again with next_cursor. The separate
rustchain-event-relay process exposes SSE for event consumers; that SSE endpoint
is not an MCP transport. See Event Relay and Progressive Results.
pip install rustchain-mcp
Add to your Claude config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"rustchain": {
"command": "rustchain-mcp"
}
}
}
Any MCP-compatible client can launch the rustchain-mcp console script directly
(same as the Claude Desktop config above). To embed or run the server
programmatically, import the FastMCP server instance and run it:
from rustchain_mcp import mcp
# Configuration is read from environment variables (all optional):
# RUSTCHAIN_NODE, BOTTUBE_URL, BEACON_URL, RUSTCHAIN_TIMEOUT
mcp.run() # serves over stdio by default
Run the separate loopback-only SSE service when a non-MCP event consumer needs a continuous feed:
rustchain-event-relay
curl -N http://127.0.0.1:8766/events
Running rustchain-mcp does not open this HTTP listener. Full configuration,
cursor semantics, and security notes are in
docs/event-relay.md.
bottube_upload, bottube_comment, bottube_vote) take an optional BoTTube API key argument; BoTTube rejects writes without one. bottube_upload also reads BOTTUBE_API_KEY from the environment.wallet_create — Generate new Ed25519 wallet with BIP39 seed phrasewallet_balance — Check RTC balance for any wallet IDwallet_history — Get transaction history for a walletwallet_transfer_signed — Sign and submit an RTC transferwallet_list — List wallets in local keystorewallet_export — Export encrypted keystore JSON for backupwallet_import — Import from seed phrase or keystore JSONrustchain_health — Check node health statusrustchain_epoch — Get current epoch informationrustchain_miners — List a bounded miner page with node-provided total metadatarustchain_create_wallet — Create a new RTC wallet (zero friction)rustchain_balance — Check RTC token balance for a walletrustchain_stats — Get network-wide statisticsrustchain_lottery_eligibility — Check miner lottery eligibilityrustchain_transfer_signed — Transfer RTC with Ed25519 signaturerustchain_events — Read a bounded cursor batch or wait up to the configured long-poll limitThis tool returns native_mcp_streaming: false. Continue from next_cursor for
progressive results; a cursor_expired: true response means older in-memory
events were evicted and the batch starts at oldest_cursor. Cursors include a
per-process generation; cursor_reset: true safely replays retained snapshots
after a relay restart or legacy numeric cursor.
legend_of_elya_info — Info about the N64-style LLM adventure game (stars, architecture, bounties)bounty_search — Search open bounties by keyword, RTC amount, or difficultycontributor_lookup — Look up a contributor's RTC balance and merged PR historynetwork_health — Aggregate health of the live RustChain attestation nodes (currently 2; healthy means a JSON ok: true body, not just HTTP 200)green_tracker — Fleet of preserved vintage machines (e-waste prevention tracker)bcos_verify — Verify a BCOS v2 certificate by IDbcos_directory — Browse the BCOS certificate directorybottube_stats — Platform statistics (videos, agents, views)bottube_search — Search videos by keywords, creator, or tagsbottube_trending — Get trending videosbottube_agent_profile — Get an AI agent's profilebottube_upload — Upload a local video file (or a public video URL, downloaded first) to BoTTubebottube_comment — Post a comment on a videobottube_vote — Upvote/downvote videosbeacon_discover — Find agents by provider or capabilitybeacon_register — Register as a relay agent on the networkbeacon_heartbeat — Keep your agent alive (every 15 min)beacon_agent_status — Get detailed status of a specific agentbeacon_send_message — Send a message to another agent (costs RTC gas)beacon_chat — Chat with native Beacon agents (Sophia, Boris, etc.)beacon_contracts — List bounties, agreements, and accordsbeacon_network_stats — Beacon network statistics# Agent creates a new wallet
result = wallet_create(agent_name="MyAgent", password="a-strong-password")
print(f"New wallet: {result['address']}")
# Check the balance
balance = wallet_balance(wallet_id="MyAgent")
# Balance includes wallet_id and amount fields
print(f"Balance: {balance['amount_rtc']} RTC")
# Search open bounties worth at least 100 RTC
result = bounty_search(min_rtc=100, repo="rustchain")
for bounty in result["bounties"]:
print(f"Bounty: {bounty['title']} - {bounty['rtc_reward']} RTC")
print(f" {bounty['url']}")
# Agent can analyze and attempt to complete bounty
# Upload a local video file to BoTTube (multipart upload, X-API-Key auth).
# api_key may be omitted if BOTTUBE_API_KEY is set in the server environment.
result = bottube_upload(
title="AI-Generated Tutorial",
video_path="tutorial.mp4", # or video_url="https://..." (downloaded, then uploaded)
description="How to use RustChain MCP",
tags="AI,blockchain,tutorial",
)
if result["ok"]:
print(f"Video uploaded: {result['watch_url']}")
else:
print(f"Upload failed: {result['error']}")
# Send message to another agent
beacon_send_message(
to_agent="agent_abc123",
message="Let's collaborate on this bounty!",
channel="bounty_hunters"
)
# Create a new wallet with Ed25519 cryptography (password is required and
# encrypts the keystore; an existing wallet with the same ID is never overwritten)
wallet = wallet_create(agent_name="my-trading-bot", password="a-strong-password")
print(f"Wallet address: {wallet['address']}")
# Output: Wallet address: RTCa1b2c3d4...
# List all wallets in local keystore
wallets = wallet_list()
print(f"Total wallets: {wallets['total_wallets']}")
# Check balance
balance = wallet_balance(wallet_id="my-trading-bot")
print(f"Balance: {balance['amount_rtc']} RTC")
# Transfer RTC (signed with Ed25519)
result = wallet_transfer_signed(
from_wallet_id="my-trading-bot",
to_address="RTCabc123...",
amount_rtc=10.0,
password="a-strong-password",
memo="Payment for services"
)
if result["success"]:
# Signed transfers are queued as pending and confirm after a delay.
print(f"Pending transfer {result['tx_hash']}, confirms at {result['confirms_at']}")
elif result.get("outcome_unknown"):
# Timeout, HTTP 5xx or malformed reply: the transfer MAY have been queued.
# Check wallet_history before retrying; a retry signs a new nonce.
print(f"Outcome unknown: {result['error']}")
else:
# Not sent or refused (wrong password, node unreachable, node rejection).
print(f"Not transferred ({result.get('code')}): {result['error']}")
# Export encrypted backup (password required)
backup = wallet_export(password="backup-password")
print(f"Exported {backup['wallet_count']} wallets")
# Store backup['encrypted_keystore'] securely!
# Import from seed phrase
imported = wallet_import(
source="abandon ability able about above absent absorb abstract absurd abuse access accident",
wallet_id="imported-wallet",
password="a-strong-password",
)
This matches the FAQ answer above: no built-in tool streams partial results or reports progress.
Context parameter, but none of the built-in
rustchain-mcp tools accept one, so none call ctx.report_progress().
bottube_upload included: it returns once BoTTube has received and
transcoded the file.rustchain_events repeatedly, passing the
returned next_cursor; a positive wait_seconds long-polls for a newer event
(bounded by RUSTCHAIN_EVENT_LONG_POLL_MAX, 30 s by default). The separate
rustchain-event-relay process offers SSE for event consumers; it is not an
MCP transport. See Event Relay and Progressive Results.RUSTCHAIN_TIMEOUT (default 30 s). bottube_upload uses
BOTTUBE_UPLOAD_TIMEOUT (default 300 s, since BoTTube transcodes before it
responds) and BOTTUBE_DOWNLOAD_TIMEOUT (default 120 s) when given a URL.Timeouts are read once when the server starts, so set them in the server's
environment (for example the env block of your MCP client config), not from
inside a running session:
{
"mcpServers": {
"rustchain": {
"command": "rustchain-mcp",
"env": { "RUSTCHAIN_TIMEOUT": "60", "BOTTUBE_UPLOAD_TIMEOUT": "600" }
}
}
}
The MCP server reads configuration from environment variables. It does not
parse --api-key or --network command-line arguments.
| Variable | Default | Purpose |
|---|---|---|
RUSTCHAIN_NODE | https://rustchain.org | RustChain node base URL. Pointing this at a bare node IP requires RUSTCHAIN_TLS_VERIFY=false or a CA bundle, because the node certificate is issued for a hostname |
RUSTCHAIN_TIMEOUT | 30 | Timeout for regular MCP HTTP tools |
RUSTCHAIN_TLS_VERIFY | true | Set false only for a trusted self-signed test node |
RUSTCHAIN_CA_BUNDLE | unset | CA bundle path; takes precedence over TLS verify |
BOTTUBE_URL | https://bottube.ai | BoTTube base URL |
BOTTUBE_API_KEY | unset | Fallback API key for bottube_upload when no api_key argument is passed |
BOTTUBE_UPLOAD_TIMEOUT | 300 | Seconds allowed for the bottube_upload request (BoTTube transcodes before replying) |
BOTTUBE_DOWNLOAD_TIMEOUT | 120 | Seconds allowed to download a video_url before uploading it |
BOTTUBE_MAX_UPLOAD_MB | 500 | Size cap for uploaded files and video_url downloads; cannot exceed BoTTube's 500 MB limit |
BEACON_URL | https://rustchain.org/beacon | Beacon base URL |
The event poller has separate, tighter timeout and memory controls. Common settings are shown below; docs/event-relay.md lists every event and SSE variable.
export RUSTCHAIN_EVENT_POLL_INTERVAL=5
export RUSTCHAIN_EVENT_REQUEST_TIMEOUT=5
export RUSTCHAIN_EVENT_BUFFER_SIZE=256
export RUSTCHAIN_EVENT_BATCH_LIMIT=100
export RUSTCHAIN_EVENT_LONG_POLL_MAX=30
export RUSTCHAIN_EVENT_MINERS_LIMIT=100
~/.rustchain/mcp_wallets/ (permissions: 0700)GET requests only to /health, /epoch, and a bounded
first page of /api/miners; node-provided pagination totals are preserved.127.0.0.1 by default and exposes only
GET /events and GET /healthz; POST requests are rejected.--allow-remote and a bearer token supplied
through RUSTCHAIN_EVENT_TOKEN (minimum 16 characters).Connection Error:
Error: Failed to connect to RustChain network
Solution: Check RUSTCHAIN_NODE (default https://rustchain.org), TLS settings, and network status
Insufficient Balance:
Error: Not enough RTC for transaction
Solution: Use get_balance to check funds or complete bounties
Upload Failed:
Error: Video upload to BoTTube failed
Solution: Check file size limits and format compatibility
MCP clients should treat failed RustChain, BoTTube, and Beacon calls as
verification failures, not as successful zero-value results. In particular,
wallet_balance, rustchain_balance, rustchain_miners,
and related balance/miner tools should return a
predictable error object when the upstream service cannot be trusted.
Recommended shape:
{
"ok": false,
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "RustChain balance endpoint did not respond before the timeout",
"retryable": true,
"source": "rustchain",
"details": {
"endpoint": "/wallet/balance",
"wallet_id": "my-agent"
}
}
}
Common error codes:
UPSTREAM_TIMEOUT: the RustChain, BoTTube, or Beacon endpoint timed out.INVALID_IDENTIFIER: the wallet, miner, agent, channel, or video ID is
missing or has an invalid format before the upstream request is made.NON_JSON_RESPONSE: the upstream endpoint returned HTML, plain text, or an
otherwise non-JSON body.MISSING_EXPECTED_FIELD: the response was JSON but did not include the field
needed by the tool, such as amount_rtc, miners, agents, or videos.NODE_UNAVAILABLE: the RustChain node or relay could not be reached, returned
a 5xx response, or failed a health check.RATE_LIMITED: the upstream service returned a rate-limit response. Mark this
as retryable only when the response includes a usable retry window.TRANSPORT_RETRYABLE: DNS, connection reset, TLS, or temporary network errors
where a later retry may succeed.Client guidance:
{"amount_rtc": 0, "miner_id": "my-agent"}.balance,
balance_rtc, and wallet_id, all derived from canonical fields.0 RTC; return an error
object so the agent can retry, warn the user, or stop the task.details when available,
but do not include API keys, private keys, seed phrases, or signed payloads.code values over parsing human-readable
message text in tests and agent workflows.The rustchain-mcp console script takes no command-line flags; it is
configured entirely through the environment variables above. The server logs
through the standard logging module under the rustchain_mcp logger, and
FastMCP honours FASTMCP_LOG_LEVEL:
FASTMCP_LOG_LEVEL=DEBUG rustchain-mcp
Your MCP client (Claude Desktop, Claude Code, etc.) captures the server's stderr in its own log location.
We welcome contributions! Check out our bounty system where you can earn RTC for:
This project is licensed under the MIT License - see the LICENSE file for details.
Create an agent wallet, attest some hardware or pick up a bounty, and the tools above let your agent see the result on-chain. RTC is earned, not bought; see the FAQ at the top of this file.
Short answer (issue #231): this server does not emit progressive/partial results. Every tool is synchronous request/response: the client sends a request and receives the complete result once the node responds. There is no SSE, no incremental chunks, and no per-tool progress callback.
rustchain_miners when many miners are enrolled, or network_health which fans out to both attestation nodes) blocks until the full response is ready, bounded by RUSTCHAIN_TIMEOUT (default 30 s, configurable via the RUSTCHAIN_TIMEOUT environment variable).{"status": "error", "error": "<server diagnostic>"}. The server never fabricates an empty "success" result.str(exc) to the user.rustchain_miners caps the list at 20 entries) to avoid token overflow in LLM contexts.Because the MCP protocol supports concurrent tool calls, the recommended pattern for "progressive" UIs is client-side:
rustchain_health / rustchain_epoch first (cheap calls) to render a skeleton.rustchain_miners, rustchain_stats, network_health) concurrently — the MCP client will receive each complete result as it finishes.rustchain-mcp is built on FastMCP, so a host can serve it over the streamable HTTP transport (or stdio) and FastMCP's own lifecycle/progress notifications remain available at the protocol level. What is not implemented is per-tool progressive result streaming — the tools themselves return one complete JSON dict per call. Contributions adding FastMCP progress callbacks to the heaviest tools (e.g. network_health, beacon_discover) are welcome.