Skip to main content
Glama
chunknet

Chunk MCP Server

Official
by chunknet
README.md
# Chunk MCP Server

Production-ready MCP server exposing Chunk MedianFeeds tools over stdio.

- Network: Chunk testnet (default RPC: `https://rpc.chunknet.org`)
- Contract: MedianFeeds (default): `0x78D02A47fA898ffF4B37A9B414Eace5eed3e7fAD`

Requirements
- Node.js 18+ (ESM modules)

Quickstart
- Install
  - `cd mcp-server`
  - `npm install`
- Build
  - `npm run build`
- Run (stdio transport)
  - `npm start`

Configuration
- Environment variables
  - `CHUNK_RPC` — JSON-RPC endpoint (default: `https://rpc.chunknet.org`)
  - `CHUNK_MEDIAN_ADDR` — MedianFeeds contract address (default: `0x78D02A47fA898ffF4B37A9B414Eace5eed3e7fAD`)
  - `METRICS_CACHE_TTL_MS` — metrics cache TTL in milliseconds (default: 30000)

Production .env (overrides optional)
```bash
CHUNK_RPC=https://rpc.chunknet.org
CHUNK_MEDIAN_ADDR=0x78D02A47fA898ffF4B37A9B414Eace5eed3e7fAD
METRICS_CACHE_TTL_MS=30000
```
Notes: You can omit `.env` entirely — these are the built-in defaults.

Tools
- `list_metrics` — List metric definitions from MedianFeeds
  - Args: `{ chain?, rpcUrl?, contractAddress?, currency?, tagIncludes?, nameContains?, limit?, offset? }`
- `quote_metrics` — Get last quotes for given metric names
  - Args: `{ names: string[], chain?, rpcUrl?, contractAddress?, format?: 'raw'|'int'|'decimal'|'all', decimals?: number }`
- `get_signed_root` — Get current signed Merkle tree root (epoch)
  - Args: `{ chain?, rpcUrl?, contractAddress? }`
- `get_metrics_count` — Total metrics count
- `has_metric` — Check if a metric exists by name
- `get_metrics_map` — Mapping `name -> id` (index-based)
- `quote_by_ids` — Quote metrics by numeric ids
  - Args: `{ ids: number[], chain?, rpcUrl?, contractAddress?, format?, decimals? }`
- `quote_metrics_at_block` — Quote metrics at specific block number
  - Args: `{ names: string[], blockNumber: number, chain?, rpcUrl?, contractAddress?, format?, decimals? }`
- `quote_metrics_at_epoch_end` — Quote metrics at the end of an epoch
  - Args: `{ names: string[], epochDuration?: number, epochId?: number, chain?, rpcUrl?, contractAddress?, format?, decimals? }`
- `quote_metrics_at_timestamp` — Quote metrics at specific UNIX timestamp (seconds)
  - Args: `{ names: string[], timestamp: number, chain?, rpcUrl?, contractAddress?, format?, decimals? }`
- `get_health` — RPC health info `{ chainId, blockNumber }`
- `check_staleness` — Check if metrics are stale w.r.t `maxAgeSeconds`
- `check_thresholds` — Threshold checks for rules of form `{ name, op: 'lt'|'lte'|'gt'|'gte'|'eq'|'neq', value: string|number }`

Formatting
- Raw values are returned as on-chain 2**112-scaled integers.
- Use `format: 'decimal'` and `decimals` to get human-friendly strings with rounding.

Resources
- `chunk://median/{chain}/metrics` — JSON array of metrics for a chain (`chunk` supported)
- `chunk://median/{chain}/metric/{name}` — JSON object with the latest quote for a metric

Subscriptions
- The server registers `resources.subscribe` capability.
- On epoch changes, `resources/updated` notifications are sent for subscribed URIs.

Client Example (Node.js)
```js
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';

const transport = new StdioClientTransport({
  command: 'node',
  args: ['dist/server.js'],
  env: process.env,
});

const client = new Client({ name: 'chunk-mcp', version: '0.1.0' });
await client.connect(transport);

const list = await client.callTool({ name: 'list_metrics', arguments: { limit: 5 } });
const names = list.structuredContent.metrics.map(m => m.name).slice(0, 2);
const quotes = await client.callTool({ name: 'quote_metrics', arguments: { names, format: 'decimal', decimals: 6 } });
console.log(quotes.structuredContent.quotes);

await client.close();
```

Claude Desktop (MCP) configuration (example)
- Configure a stdio MCP server:
```json
{
  "mcpServers": {
    "chunk-mcp": {
      "command": "node",
      "args": ["dist/server.js"],
      "env": {
        "CHUNK_RPC": "https://rpc.chunknet.org",
        "CHUNK_MEDIAN_ADDR": "0x78D02A47fA898ffF4B37A9B414Eace5eed3e7fAD"
      }
    }
  }
}
```

Operational Notes
- Timeouts and RPC limits depend on your provider.
- Handle network errors and transient failures with retries on the client side.
- For production, pin a stable RPC endpoint and contract address.

Project Structure
- `src/server.js` — source (ESM)
- `dist/server.js` — bundled build (after `npm run build`)
- No tests are included in this directory by design.

TDQS

C2.6/5.0

Scored across 14 tools

Disambiguation2/5

The quote_metrics, quote_by_ids, quote_metrics_at_block, quote_metrics_at_epoch_end, and quote_metrics_at_timestamp tools all return quotes and are easily confused. Additionally, ids_for_names and get_metrics_map both resolve names to IDs, creating ambiguity in tool selection.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern (get_*, check_*, list_*, quote_*), but ids_for_names deviates with a noun-preposition-noun structure. The mix of get and check for health-related actions is a minor inconsistency.

Tool Count4/5

14 tools is within the typical well-scoped range but slightly heavy for the domain. The multiple time-based quote variants could be consolidated, but the count is still reasonable for a comprehensive metrics oracle.

Completeness4/5

The server covers health checks, metric listing, quoting (current and historical), ID mapping, and existence checks. However, there is no direct get_metric_by_id tool, and the time-based quote tools are somewhat redundant with each other, leaving minor coverage gaps.

Maintenance

ActivityInactive
ResponsivenessNo issues