https://github.com/oceanprotocol/on-mcp
MCP server for ON network
https://github.com/oceanprotocol/on-mcp
Last synced: 27 days ago
JSON representation
MCP server for ON network
- Host: GitHub
- URL: https://github.com/oceanprotocol/on-mcp
- Owner: oceanprotocol
- License: apache-2.0
- Created: 2026-04-24T07:27:57.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-05-08T12:24:28.000Z (about 1 month ago)
- Last Synced: 2026-05-08T14:30:30.415Z (about 1 month ago)
- Language: TypeScript
- Size: 509 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# on-mcp
**on-mcp** is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server for the [Ocean Protocol](https://oceanprotocol.com/) network. It exposes Ocean **ocean-node** and **libp2p** capabilities as MCP **tools** and **resources**, so coding agents and other MCP clients can discover providers, run compute jobs, resolve DIDs, manage persistent storage, and perform other P2P operations through a consistent, schema-driven interface.
The server name reported to clients is `ocean-mcp` (see `src/server/createServer.ts`).
---
## What it does
- **P2P-first:** On startup the process joins the Ocean libp2p network (with configurable bootstrap peers). Most operations talk to **ocean-node** instances over **libp2p** via `@oceanprotocol/lib` (`ProviderInstance` / `P2pProvider`), not only over HTTP to a single gateway.
- **MCP tools:** Dozens of tools wrap node status, DHT `find_provider` discovery (including C2D capacity search strings), DDO resolution and validation, compute lifecycle (initialize, start, stop, status, results, logs), downloads, encryption helpers, auth tokens, policy-server flows, persistent storage, admin config, and peer utilities.
- **MCP resources:** Static documentation is exposed for C2D provider discovery (URI `ocean://docs/c2d-find-provider-search`) so agents can fetch how `find_provider` and `buildFindProviderC2dContent` align with ocean-node announcements.
- **Transports:** Supports **stdio** (typical for local editors and Claude Desktop) and **Streamable HTTP** (`MCP_TRANSPORT=sse`) for remote or containerized deployments.
- **EVM (optional):** If `EVM_CHAIN_RPCS` is set, the process builds an ethers **FallbackProvider** per chain; upcoming tools will use these for on-chain operations.
---
## Architecture (high level)
| Piece | Role |
|--------|------|
| `src/index.ts` | Chooses transport (stdio vs HTTP), initializes libp2p (`ProviderInstance.setupP2P`), optional HTTP app on `MCP_HOST` / `MCP_PORT`. |
| `src/server/createServer.ts` | Builds the `McpServer`, wires `NodeClient`, registers tools and resources. |
| `src/clients/nodeClient.ts` | Thin wrapper around `ProviderInstance` P2P APIs (status, compute, storage, DDO, fees, etc.). |
| `src/tools/p2pProviderTools.ts` | Registers all active MCP tools (Zod schemas, descriptions for agents). |
| `src/resources/registerResources.ts` | Registers MCP resources (markdown docs). |
| `src/config/env.ts` | Reads `NODE_URL`, `RPC`, `CHAIN_ID` for server-side config (defaults and chain context). |
| `src/evm/chainRpcConfig.ts` | Parses `EVM_CHAIN_RPCS` JSON into per-chain RPC URL lists. |
| `src/evm/evmProviderRegistry.ts` | One ethers `FallbackProvider` per configured chain (singleton, initialized in `main`). |
---
## Requirements
- **Node.js 22** (see `.nvmrc`).
- Network access for libp2p bootstrap and peer connections.
- A **private key** for signing where the protocol requires it. If `PRIVATE_KEY` is unset, the server generates an **ephemeral** key and logs a warning—fine for experiments, not for production identities.
---
## Install and build
```bash
nvm use # if you use nvm
npm ci
npm run build
```
Output is emitted to `dist/`. Typecheck only: `npm run type-check`.
---
## Run locally
### Stdio (default): editor and CLI MCP clients
```bash
npm start
# or
node --max-old-space-size=28784 --trace-warnings --experimental-specifier-resolution=node dist/index.js
```
Ensure `MCP_TRANSPORT` is unset or not `sse` so the server uses stdio.
### Streamable HTTP: remote access or Docker
```bash
export MCP_TRANSPORT=sse
export MCP_HOST=0.0.0.0 # listen on all interfaces
export MCP_PORT=3000
npm start
```
The MCP HTTP endpoint is **`http://:/mcp`** (and `/` is also wired for the same handler). Clients must support **Streamable HTTP** transport where used.
### Development (TypeScript without full build)
```bash
npm run dev:server
```
For MCP Inspector–style debugging:
```bash
npm run dev
```
---
## Environment variables
| Variable | Purpose |
|----------|---------|
| `PRIVATE_KEY` | Hex private key for p2p node. If omitted, a random ephemeral key is generated. |
| `BOOTSTRAP_PEERS` | Comma-separated libp2p multiaddrs **prepended** to the built-in Ocean bootstrap list (passing custom peers replaces library defaults, so extras are merged with Ocean defaults in code). |
| `MCP_TRANSPORT` | `stdio` (default) or `sse` for Streamable HTTP. |
| `MCP_HOST` | Bind address for HTTP mode (default `127.0.0.1`). |
| `MCP_PORT` | Port for HTTP mode (default `3000`). |
| `EVM_CHAIN_RPCS` | Optional JSON object mapping **chain id strings** to **arrays of RPC URLs** (primary first, fallbacks next). Used to build an ethers v6 `FallbackProvider` per chain for EVM tools. Example (shell-safe quoting) with public RPCs for **mainnet (1)**, **sepolia (11155111)**, **base (8453)**, **optimism (10)**: `EVM_CHAIN_RPCS='{"1":["https://cloudflare-eth.com","https://rpc.ankr.com/eth"],"11155111":["https://rpc.sepolia.org","https://rpc.ankr.com/eth_sepolia"],"8453":["https://mainnet.base.org","https://base.publicnode.com"],"10":["https://mainnet.optimism.io","https://optimism.publicnode.com"]}'`. Empty or unset means no EVM providers are registered. Invalid JSON causes startup to fail. |
---
## Docker
Build and run (HTTP mode is the default in the image):
```bash
docker build -t on-mcp .
docker run --rm -p 3000:3000 on-mcp
```
Set a wallet and optional bootstrap peers:
```bash
docker run --rm -p 3000:3000 \
-e PRIVATE_KEY=0x... \
-e BOOTSTRAP_PEERS=/ip4/.../p2p/... \
on-mcp
```
For stdio MCP (e.g. wiring the container to a host process), override transport and drop port publishing as needed:
```bash
docker run --rm -i -e MCP_TRANSPORT=stdio on-mcp
```
Override transport or port as needed for HTTP, for example `-e MCP_PORT=8080 -p 8080:8080`.
---
## MCP tools (overview)
Tools are defined in `src/tools/`. Names are stable identifiers for agents and client configs. Current tool ids include:
**Peers and discovery:** `mcp_server_peers`, `find_provider`, `buildFindProviderC2dContent`, `list_discovered_peers`, `resolve_peer_multiaddr`, `is_valid_provider`, `cid_from_raw_string`
**Node and DDO:** `node_status`, `getComputeEnvironments`, `resolveDdo`, `validateDdo`, `getNodeJobs`, `getNonce`, `getFileInfo`, `check_did_files`
**Compute:** `initializeCompute`, `computeStart`, `freeComputeStart`, `computeStop`, `computeStatus`, `getComputeResult`, `get_compute_result_url`, `compute_streamable_logs`, `downloadNodeLogs`
**Storage and downloads:** `createPersistentStorageBucket`, `getPersistentStorageBuckets`, `listPersistentStorageFiles`, `getPersistentStorageFileObject`, `deletePersistentStorageFile`, `upload_persistent_storage_file`, `get_download_fees`, `download_asset_file`
**Auth and crypto:** `create_auth_token`, `p2p_encrypt`
**Policy server:** `policy_server_passthrough`, `policy_server_initialize_verification`
**Admin / config:** `fetch_node_config`, `push_node_config`
**Resource access (for tool-only clients):** `list_resources`, `get_resource`
**EVM escrow and access lists:** `broadcast_transaction`, `escrow_get_funds`, `escrow_get_user_funds`, `escrow_get_user_tokens`, `escrow_get_locks`, `escrow_get_authorizations`, `escrow_deposit`, `escrow_withdraw`, `escrow_authorize`, `accesslist_get_details`, `accesslist_get_token_uri`, `accesslist_mint`, `accesslist_factory_is_deployed`, `accesslist_factory_deploy`
Many tools require targeting a peer via **`nodeId`** and/or **`multiaddress`** (see schemas in `src/tools/p2pSchemas.ts`). Operations that mutate state or access paid resources typically need **`authToken`** or a **`completeSignature`** payload—follow each tool’s description and `P2P_AUTH_SIGNING_GUIDE` in code.
---
## MCP resources
| Name | URI | Content |
|------|-----|--------|
| `c2d-find-provider-search` | `ocean://docs/c2d-find-provider-search` | Markdown: how C2D provider strings are advertised and how to combine `find_provider` results for multi-dimensional requirements. |
| `evm-supported-chains` | `ocean://evm/supported-chains` | JSON: configured EVM chains with latest block number and block timestamp from each chain's fallback provider. |
If your MCP client only shows **tools** (not resources), use `list_resources` and `get_resource` to discover and fetch these same contents.
Agents should **`read_resource`** on this URI when planning C2D discovery or intersecting multiple `find_provider` queries.
---
## Using with AI clients
This section describes how to attach **on-mcp** to common agent hosts. Exact UI paths change between product versions; if a menu differs, look for **MCP**, **Model Context Protocol**, or **Tools** in settings.
### General guidance (all agents)
1. **Build the project** (`npm run build`) unless you point the client at `tsx`/dev entrypoints.
2. Prefer a **fixed `PRIVATE_KEY`** when you need stable signatures across restarts.
3. Ensure **bootstrap connectivity** so libp2p can reach Ocean peers (firewall/NAT allowing outbound WebSocket to bootstrap hosts).
4. For **C2D discovery**, use `buildFindProviderC2dContent` → `find_provider`, and read the **`ocean://docs/c2d-find-provider-search`** resource for compound CPU/RAM/GPU queries.
5. Check **`node_status`** for **persistent storage** capabilities before using bucket/file tools.
### Cursor
1. Open **Cursor Settings → MCP** (or **Features → MCP**), or edit the MCP configuration file if your build exposes one (often under the user config directory for Cursor).
2. Add a server that runs the **compiled** entrypoint with **stdio**:
```json
{
"mcpServers": {
"ocean-mcp": {
"command": "node",
"args": [
"--max-old-space-size=8192",
"--trace-warnings",
"--experimental-specifier-resolution=node",
"/ABSOLUTE/PATH/TO/on-mcp/dist/index.js"
],
"env": {
"PRIVATE_KEY": "0xYOUR_KEY",
"NODE_URL": "http://localhost:8000"
}
}
}
}
```
3. Use **`cwd`** only if your install requires it; otherwise `args` may use a path relative to the project after `npm run build`.
4. Do **not** set `MCP_TRANSPORT=sse` for stdio—leave it unset for the default stdio transport.
5. After saving, restart Cursor or reload MCP servers so the new server appears. Enable **ocean-mcp** for the workspace or chat where you need Ocean tools.
For **remote HTTP** MCP (if your Cursor version supports URL-based Streamable HTTP servers), point the client at `http://:/mcp` with the transport your UI specifies; run the server with `MCP_TRANSPORT=sse` and reachable `MCP_HOST` / `MCP_PORT`.
### VS Code and GitHub Copilot (MCP-capable setups)
Recent VS Code builds and extensions can register MCP servers in **`mcp.json`** (user or workspace) or in settings under MCP-related keys, depending on version.
1. Install or enable the **MCP** support your workflow uses (built-in or extension).
2. Register a server using the same **`command` / `args` / `env`** pattern as in the Cursor example, with paths adjusted for your machine.
3. When using **GitHub Copilot** as the chat agent, ensure the Copilot session is allowed to use **MCP tools** for that workspace (policy depends on org and extension settings).
Because product names and settings move quickly, if the UI does not match: search the VS Code docs for **“MCP server configuration”** and mirror the documented JSON shape, substituting the `ocean-mcp` `command` and `args` above.
### Claude Desktop (Anthropic)
Edit the Claude Desktop MCP config (platform-specific path, e.g. macOS `~/Library/Application Support/Claude/claude_desktop_config.json`) and add a `mcpServers` entry with the same **`command`**, **`args`**, and **`env`** as for Cursor. Restart Claude Desktop after changes.
### Other agents and custom clients
Any MCP client that supports:
- **Stdio:** spawn `node … dist/index.js` with the env vars you need.
- **Streamable HTTP:** connect to `http://:/mcp` with session handling as required by `@modelcontextprotocol/sdk` (initialize POST, then session id on subsequent requests).
For **headless automation**, run the HTTP server and use an MCP client library that speaks Streamable HTTP to the same URL.
---
## Logging
`console.error` and libp2p stderr are redirected to **`debug.log`** in the process working directory (`src/index.ts`). Check this file when diagnosing connection or protocol errors.
---
## Scripts (npm)
| Script | Description |
|--------|-------------|
| `npm run build` | Clean `dist/`, compile TypeScript. |
| `npm start` | Run compiled server (`dist/index.js`). |
| `npm run dev` | MCP Inspector + `tsx` on `src/index.ts`. |
| `npm run dev:server` | `tsx src/index.ts` without Inspector. |
| `npm run lint` | ESLint + `tsc --noEmit`. |
| `npm test` | Lint and tests (see `package.json` for full pipeline). |
---
## License
Apache-2.0. See `package.json` for metadata and issue tracker links.
---
## Contributing and issues
Report issues at the repository linked from `package.json` (`bugs.url`). When opening bug reports, include relevant **`debug.log`** snippets (redact keys), transport mode (stdio vs HTTP), and whether libp2p peers were reachable.