Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
async-trait = "0.1"
eyre = "0.6"
colored = "2"
hex = "0.4"
34 changes: 29 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ arbitrum-cli block latest --human
| `watch blocks` | Stream new blocks (polling) |
| `exec <method> --params '[...]'` | Generic RPC passthrough |
| `agent-deposit <address> --action ...` | Create Protocol AgentDeposit — balance, deposit, withdraw, registered |
| `mcp` | Start MCP server for AI agents |
| `mcp` | Start MCP server (stdio) for AI agents |
| `info` | List supported Arbitrum chains |

## Agent mode
Expand Down Expand Up @@ -104,18 +104,42 @@ Phase 1 of Create Protocol is live on Sepolia with Arbitrum One redeployment imm

## MCP server

Expose arbitrum-cli as a [Model Context Protocol](https://modelcontextprotocol.io) server so Claude, Cursor, or any MCP-compatible agent can call Arbitrum directly.
Expose arbitrum-cli as a [Model Context Protocol](https://modelcontextprotocol.io) server so Claude, Cursor, or any MCP-compatible agent can call Arbitrum directly. The server speaks JSON-RPC 2.0 over **stdio** — the transport MCP hosts use when they launch a tool binary.

```bash
arbitrum-cli mcp --bind 127.0.0.1:3456
arbitrum-cli mcp
```

Tools exposed:
It handles `initialize`, `tools/list`, `tools/call`, and `ping`. Tools exposed:

- `arbitrum.block` · `arbitrum.tx` · `arbitrum.balance` · `arbitrum.token`
- `arbitrum.call` · `arbitrum.gas` · `arbitrum.exec`

*(MCP integration is stubbed in v0.1 — full stdio + SSE support in v0.2.)*
Each tool advertises a JSON Schema for its arguments and returns its result as both a text `content` block and `structuredContent`. Pass a custom endpoint with `--rpc <url>` or the `ARBITRUM_RPC_URL` env var.

Wire it into an MCP host (e.g. Claude Desktop's `claude_desktop_config.json`):

```json
{
"mcpServers": {
"arbitrum": {
"command": "arbitrum-cli",
"args": ["mcp"],
"env": { "ARBITRUM_RPC_URL": "https://arb1.arbitrum.io/rpc" }
}
}
}
```

You can also drive it by hand — one JSON-RPC request per line on stdin:

```bash
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"arbitrum.gas","arguments":{}}}' \
| arbitrum-cli mcp
```

## Configuration

Expand Down
19 changes: 8 additions & 11 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,15 +380,12 @@ pub async fn agent_deposit(
Ok(())
}

// ── mcp (stub) ──
pub async fn mcp(_rpc: &str, bind: &str) -> Result<()> {
// MCP server stub — production version would expose tools via stdio or SSE
// following the Model Context Protocol spec.
eprintln!("MCP server mode — stub implementation");
eprintln!("Bind: {bind}");
eprintln!("Tools exposed: block, tx, balance, token, call, gas, exec");
eprintln!();
eprintln!("Full MCP implementation coming — this stub validates the tool shape.");
eprintln!("See: https://modelcontextprotocol.io");
Ok(())
// ── mcp ──
//
// Run a real Model Context Protocol server over stdio. MCP hosts (Claude
// Desktop, Cursor, …) spawn this binary and speak JSON-RPC 2.0 on
// stdin/stdout. The protocol surface (initialize / tools/list / tools/call)
// and tool execution live in `crate::mcp`; this is just the entry point.
pub async fn mcp(rpc: &str) -> Result<()> {
crate::mcp::serve_stdio(rpc).await
}
15 changes: 8 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use clap::{CommandFactory, Parser, Subcommand};

mod agent_deposit;
mod commands;
mod mcp;
mod output;
mod rpc;

Expand Down Expand Up @@ -83,12 +84,12 @@ enum Commands {
params: String,
},

/// Start an MCP server exposing arbitrum-cli as tools for AI agents
Mcp {
/// Bind address
#[arg(long, default_value = "127.0.0.1:3456")]
bind: String,
},
/// Start an MCP server (over stdio) exposing arbitrum-cli as tools for AI agents
///
/// Speaks the Model Context Protocol over JSON-RPC 2.0 on stdin/stdout —
/// the transport MCP hosts (Claude Desktop, Cursor, …) use to launch tool
/// servers. Handles initialize, tools/list, and tools/call.
Mcp,

/// Interact with Create Protocol AgentDeposit on Arbitrum
///
Expand Down Expand Up @@ -143,7 +144,7 @@ async fn main() -> eyre::Result<()> {
Commands::Exec { method, params } => {
commands::exec(&rpc_url, &method, &params, out_mode).await?
}
Commands::Mcp { bind } => commands::mcp(&rpc_url, &bind).await?,
Commands::Mcp => commands::mcp(&rpc_url).await?,
Commands::AgentDeposit {
address,
action,
Expand Down
Loading
Loading