Install
$ agentstack add mcp-msanlisavas-casper-mcp ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
About
casper-mcp
MCP (Model Context Protocol) server for the Casper Network blockchain. Gives any AI assistant or MCP-compatible tool access to on-chain data — accounts, blocks, deploys, validators, smart contracts, tokens, NFTs, transfers, and network status.
Language-agnostic. Supports both stdio (local) and Streamable HTTP (remote, multi-tenant) transports. Use it from any project — Python, Node.js, Rust, Go, or any MCP client.
Built with CSPR.Cloud.Net and the ModelContextProtocol SDK.
> v3.0.0 BREAKING CHANGES — if you are upgrading from v2.x, see the [Breaking Changes](#breaking-changes-v300) section before updating.
Quick Start
Option 1: .NET Global Tool (recommended)
dotnet tool install -g CasperMcp
casper-mcp --api-key YOUR_API_KEY
Option 2: Docker (no .NET required)
# Pre-built image from GitHub Container Registry
docker pull ghcr.io/msanlisavas/casper-mcp:latest
docker run -i ghcr.io/msanlisavas/casper-mcp:latest --api-key YOUR_API_KEY
# Or build locally
docker build -t casper-mcp .
docker run -i casper-mcp --api-key YOUR_API_KEY
Option 3: Build from source
git clone https://github.com/msanlisavas/casper-mcp.git
cd casper-mcp
dotnet build
dotnet run --project src/CasperMcp -- --api-key YOUR_API_KEY
Configuration
| Argument | Environment Variable | Description | |---|---|---| | --api-key | CSPR_CLOUD_API_KEY | CSPR.Cloud API key (required in stdio mode). Get one at cspr.cloud | | --network | CASPER_MCP_NETWORK | mainnet (default) or testnet | | --transport | CASPER_MCP_TRANSPORT | stdio (default) or http (Streamable HTTP for remote/multi-tenant access) | | --port | CASPER_MCP_PORT | HTTP port for http mode (default: 3001) | | --mcp-path | CASPER_MCP_PATH | URL path for the MCP endpoint in http mode (default: /mcp) | | --auth-mode | CASPER_MCP_AUTH_MODE | Auth mode for http transport: none (default), apikey, or jwt | | --auth-api-key | CASPER_MCP_AUTH_API_KEY | Shared secret for apikey auth mode | | --auth-jwt-authority | CASPER_MCP_AUTH_JWT_AUTHORITY | JWT authority URL for jwt auth mode | | --auth-jwt-audience | CASPER_MCP_AUTH_JWT_AUDIENCE | JWT audience for jwt auth mode | | --enable-writes | CASPER_MCP_ENABLE_WRITES | Enable the local stdio signer (write tools). Never valid with http. | | --key-path | CASPER_MCP_KEY_PATH | PEM secret key path (required with --enable-writes). | | --policy-path | CASPER_MCP_POLICY_PATH | Write-policy JSON path (default ~/.casper-mcp/policy.json). |
Breaking Changes (v3.0.0)
| What changed | Old (v2.x) | New (v3.0) | |---|---|---| | Remote MCP endpoint | GET /sse (SSE transport) | POST /mcp (Streamable HTTP, stateless) | | Transport flag value | --transport sse | --transport http | | CSPR.Cloud key in remote mode | Set once at startup via --api-key | Sent per-request via header X-CSPR-Cloud-Api-Key | | Server protection | --server-api-key / CASPER_MCP_SERVER_API_KEY | --auth-mode apikey + --auth-api-key / CASPER_MCP_AUTH_API_KEY | | WebSocket streaming tools | 10 Watch* tools | Removed — poll request/response tools instead (e.g. GetDeploy) | | Tool count | 92 | 82 |
Client Setup
The server works with any MCP client regardless of what language your project uses. Below are copy-paste configs for popular clients.
Claude Desktop
Add to claude_desktop_config.json:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"casper": {
"command": "casper-mcp",
"args": ["--api-key", "YOUR_API_KEY"]
}
}
}
Alternative: using Docker
{
"mcpServers": {
"casper": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/msanlisavas/casper-mcp:latest", "--api-key", "YOUR_API_KEY"]
}
}
}
Alternative: using environment variable
{
"mcpServers": {
"casper": {
"command": "casper-mcp",
"env": {
"CSPR_CLOUD_API_KEY": "YOUR_API_KEY"
}
}
}
}
Claude Code (CLI)
claude mcp add casper -- casper-mcp --api-key YOUR_API_KEY
Or add to your MCP settings JSON:
{
"mcpServers": {
"casper": {
"command": "casper-mcp",
"args": ["--api-key", "YOUR_API_KEY"]
}
}
}
Cursor
Add to .cursor/mcp.json in your project root:
{
"mcpServers": {
"casper": {
"command": "casper-mcp",
"args": ["--api-key", "YOUR_API_KEY"]
}
}
}
VS Code (GitHub Copilot)
Add to .vscode/mcp.json in your project root:
{
"servers": {
"casper": {
"type": "stdio",
"command": "casper-mcp",
"args": ["--api-key", "YOUR_API_KEY"]
}
}
}
Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"casper": {
"command": "casper-mcp",
"args": ["--api-key", "YOUR_API_KEY"]
}
}
}
Continue.dev
Add to ~/.continue/config.json:
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "stdio",
"command": "casper-mcp",
"args": ["--api-key", "YOUR_API_KEY"]
}
}
]
}
}
Any MCP Client (generic)
The server supports stdio and Streamable HTTP transports. For stdio, start the process and communicate over stdin/stdout using JSON-RPC. For http, connect over HTTP:
# stdio mode (local, default)
casper-mcp --api-key YOUR_API_KEY
# Or with environment variable
CSPR_CLOUD_API_KEY=YOUR_API_KEY casper-mcp
# Or with Docker
docker run -i --rm casper-mcp --api-key YOUR_API_KEY
# HTTP mode (remote/multi-tenant, stateless Streamable HTTP at /mcp)
casper-mcp --transport http --port 3001
# Clients must send: X-CSPR-Cloud-Api-Key: in each request
Transport Modes
The server supports two transport modes. Choose based on your use case:
| Scenario | Transport | Command | |---|---|---| | Local AI tool (Claude Desktop, Cursor, VS Code) | stdio (default) | casper-mcp --api-key KEY | | Building your own AI app / multi-agent backend | http | casper-mcp --transport http | | Multi-tenant / multi-user access with auth | http + auth | Add --auth-mode apikey --auth-api-key SECRET | | Production cloud deployment | http + Docker | docker compose up -d |
Understanding the Two API Keys
In stdio mode there is a single API key that identifies the local user to CSPR.Cloud:
| Key | Purpose | Required? | |---|---|---| | --api-key / CSPR_CLOUD_API_KEY | Authenticates with CSPR.Cloud to fetch blockchain data | Required in stdio mode |
In http mode the CSPR.Cloud key is supplied per request (no startup key required):
| Key / Header | Purpose | Required? | |---|---|---| | X-CSPR-Cloud-Api-Key request header | Per-request CSPR.Cloud key — identifies the calling agent | Required (missing → HTTP 401) | | X-Casper-Network request header | Per-request network override (mainnet/testnet) | Optional (defaults to --network) | | --auth-api-key / CASPER_MCP_AUTH_API_KEY | Protects your MCP server in apikey auth mode | Optional (set when --auth-mode apikey) |
Authentication Modes (http transport)
Configure with --auth-mode / CASPER_MCP_AUTH_MODE:
| Mode | Description | Configuration | |---|---|---| | none (default) | No built-in auth — trust a fronting WAF/reverse proxy to handle access control | — | | apikey | Shared secret; clients send Authorization: Bearer or X-API-Key: | --auth-api-key / CASPER_MCP_AUTH_API_KEY | | jwt | OAuth 2.1 resource server; validates Authorization: Bearer from your IdP; serves /.well-known/oauth-protected-resource metadata | --auth-jwt-authority, --auth-jwt-audience |
The server validates tokens only — it does not issue them.
Remote Deployment (v3.0.0)
From v3.0.0, casper-mcp is designed for stateless multi-tenant remote deployment:
- Endpoint:
POST /mcp(Streamable HTTP, stateless — no persistent SSE sessions). - Per-agent CSPR.Cloud key: each HTTP request must carry
X-CSPR-Cloud-Api-Key:. Different agents can use different keys in the same server instance. - Per-request network: optionally override the network via
X-Casper-Network: mainnet|testnet. - Pluggable auth: choose
none(WAF-trust),apikey(shared secret), orjwt(OAuth 2.1) at startup. - Designed to sit behind a WAF/reverse proxy for TLS termination, rate limiting, and IP filtering.
Built for remote AI agents behind a WAF (at scale)
One shared instance can serve thousands of agents as a remote MCP endpoint. How each common requirement is met:
| Requirement | How casper-mcp supports it | |---|---| | Run one shared instance in your infrastructure | A single stateless process — scale it horizontally behind your load balancer with no sticky sessions required | | Expose it to remote agents over HTTP | Streamable HTTP at POST /mcp — the transport the MCP C# SDK recommends for remote deployments (replaces the old /sse) | | Protect it with your WAF/auth layer | --auth-mode none trusts your fronting WAF; or enable apikey / jwt (OAuth 2.1) at the server edge | | Avoid long-lived/stateful session issues behind a WAF/proxy | Stateless mode — every tool call is an independent request → response (RPC-like). There is no persistent SSE session to pin to one backend | | Let each agent pass its own CSPR.Cloud key | Per-request X-CSPR-Cloud-Api-Key header. A fresh CSPR.Cloud client is built per request over a pooled connection, so credentials never mix between tenants | | No request that hangs for ~120s and trips proxy timeouts | The WebSocket Watch* tools (which held a request open up to 120s) were removed. Every remaining tool is request/response and returns within normal latency — safe under typical WAF/proxy idle timeouts |
Per-tenant isolation and connection reuse are handled by IHttpClientFactory (pooled sockets) plus a fresh per-request client, so a single instance handles many distinct agent keys concurrently without leaking credentials across tenants or exhausting sockets.
Run locally in http mode
dotnet run --project src/CasperMcp -- --transport http --port 3001
Output:
Casper MCP (http) on http://0.0.0.0:3001/mcp | auth=None | default-network=mainnet
Endpoints:
POST /mcp— Streamable HTTP transport for MCP clients (requiresX-CSPR-Cloud-Api-Keyheader)GET /health— Liveness check (returns JSON status, always public)GET /ready— Readiness check (always public)
Docker (http mode)
docker pull ghcr.io/msanlisavas/casper-mcp:latest
docker run -p 3001:3001 ghcr.io/msanlisavas/casper-mcp:latest \
--transport http --port 3001
Each MCP client request must include X-CSPR-Cloud-Api-Key: YOUR_API_KEY.
Docker Compose
# Optional: set auth mode
echo "CASPER_MCP_AUTH_MODE=none" > .env
# Optional: protect the endpoint with a shared API key
# echo "CASPER_MCP_AUTH_MODE=apikey" > .env
# echo "CASPER_MCP_AUTH_API_KEY=your-secret-key" >> .env
# Start the server
docker compose up -d
# Verify
curl http://localhost:3001/health
curl http://localhost:3001/ready
Authentication Examples
apikey mode:
# Start with apikey auth
casper-mcp --transport http --auth-mode apikey --auth-api-key my-secret
# Client sends both headers
curl -X POST http://localhost:3001/mcp \
-H "Authorization: Bearer my-secret" \
-H "X-CSPR-Cloud-Api-Key: YOUR_CSPR_CLOUD_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
jwt mode:
# Start with JWT auth
casper-mcp --transport http \
--auth-mode jwt \
--auth-jwt-authority https://your-idp.example.com \
--auth-jwt-audience casper-mcp
# Client sends JWT + CSPR key
curl -X POST http://localhost:3001/mcp \
-H "Authorization: Bearer " \
-H "X-CSPR-Cloud-Api-Key: YOUR_CSPR_CLOUD_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Observability
The server is instrumented so you can watch traffic and health in your own stack.
OpenTelemetry (traces + metrics). Set the standard OTEL_EXPORTER_OTLP_ENDPOINT env var and the server exports to your OTLP collector (Grafana/Tempo/Jaeger, Prometheus via the OTel Collector, Datadog, etc.). When the var is unset, telemetry is off and the server runs normally.
docker run -p 3001:3001 \
-e CASPER_MCP_TRANSPORT=http \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 \
ghcr.io/msanlisavas/casper-mcp:latest
What's emitted:
- Traces: an ASP.NET Core server span per request, an outbound HttpClient span per CSPR.Cloud call, and a
tool/span per MCP tool call (taggedmcp.toolandcasper.tenant). - Metrics:
casper_mcp.tool.calls(counter) andcasper_mcp.tool.duration(histogram, ms), both tagged bytoolandstatus(ok/error/cancelled), plus standard ASP.NET Core, HttpClient, and .NET runtime metrics (request rate, latency, in-flight, GC, etc.). - Structured logs (JSON to stdout): one line per tool call —
tool,status,duration_ms,tenant,correlation_id— so you can grep/ship logs even without OTLP.
Per-agent correlation without exposing keys. Logs, spans, and metrics tag traffic with a tenant value that is a non-reversible fingerprint of the agent's CSPR.Cloud key (k_ + a short SHA-256 prefix, e.g. k_3f9a1c2b4d5e). You can see per-agent request volume, latency, and error rates and correlate a tenant's activity across logs/traces — the raw key is never logged, traced, or returned in errors. (anonymous is used when no key is present.)
Health probes: GET /health (liveness) and GET /ready (readiness) — both unauthenticated, for your load balancer / k8s.
HTTP Client Configs
Clients that support Streamable HTTP transport can connect to a running server:
Claude Desktop (HTTP remote)
{
"mcpServers": {
"casper": {
"url": "http://localhost:3001/mcp",
"headers": {
"X-CSPR-Cloud-Api-Key": "YOUR_CSPR_CLOUD_KEY"
}
}
}
}
VS Code / GitHub Copilot (HTTP remote)
{
"servers": {
"casper": {
"type": "http",
"url": "http://localhost:3001/mcp",
"headers": {
"X-CSPR-Cloud-Api-Key": "YOUR_CSPR_CLOUD_KEY"
}
}
}
}
Cursor (HTTP remote)
{
"mcpServers": {
"casper": {
"url": "http://localhost:3001/mcp",
"headers": {
"X-CSPR-Cloud-Api-Key": "YOUR_CSPR_CLOUD_KEY"
}
}
}
}
Connecting from Python
pip install mcp
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
headers = {
"X-CSPR-Cloud-Api-Key": "YOUR_CSPR_CLOUD_KEY",
# Optional: "X-Casper-Network": "testnet"
}
async with streamablehttp_client("http://localhost:3001/mcp", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
result = await session.call_tool("GetNetworkStatus", {})
print(result)
asyncio.run(main())
Connecting from Node.js
npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("http://localhost:3001/mcp"),
{
requestInit: {
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [msanlisavas](https://github.com/msanlisavas)
- **Source:** [msanlisavas/casper-mcp](https://github.com/msanlisavas/casper-mcp)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.