Arkiv MCP Server
by arrivets
README.md
# Arkiv MCP Server
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that exposes Arkiv database chain querying capabilities to AI agents and applications.
## Quick Start
**1. Build**
```bash
cd arkiv-mcp
npm install
npm run build
```
**2. Add to Claude Code**
Run this from the `arkiv-mcp` directory:
```bash
claude mcp add arkiv -- node $(pwd)/dist/index.js
```
Or add it manually to `~/.claude/settings.json`:
```json
{
"mcpServers": {
"arkiv": {
"command": "node",
"args": ["/absolute/path/to/arkiv-mcp/dist/index.js"]
}
}
}
```
For Claude Desktop, add the same block to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows).
**3. Query the Kaolin testnet**
Once connected, the `query_entities` tool is available. Example prompts:
- "Query all entities on Arkiv"
- "Find all Arkiv entities where `type = "post"` and `score > 10`"
- "Show me entities owned by `0x1234...` on the Arkiv testnet"
- "Get the first 5 entities matching `status = "active"`, then paginate"
---
## Features
- Query entities from Arkiv database chains using a SQL-like filter expression
- Full `arkiv_query` syntax: comparisons, logical operators, glob matching, synthetic attributes
- Pagination support with cursor
- Configurable return fields (attributes, metadata, payload)
- Defaults to Kaolin testnet
## Installation
```bash
cd arkiv-mcp
npm install
npm run build
# Or use tsx for development
npm run dev
```
## Usage
### Start the server
```bash
# Using default Kaolin testnet
npm start
# With custom node URL
npm start -- --node-url https://your-arkiv-node.rpc
# Or with tsx for development
npm run dev -- --node-url https://your-arkiv-node.rpc
```
### Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| `ARKIV_NODE_URL` | Arkiv node RPC URL | No (defaults to Kaolin testnet) |
### Command Line Options
| Option | Description | Default |
|--------|-------------|---------|
| `--node-url <url>` | Arkiv node RPC URL | Kaolin testnet |
| `--help`, `-h` | Show help | - |
## MCP Tool
### `query_entities`
Query entities from an Arkiv database chain.
#### Parameters
| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `filter` | string | Filter expression (see syntax below) | `$all` |
| `limit` | number | Maximum number of entities to return (max 200) | - |
| `cursor` | string | Pagination cursor from a previous response | - |
| `withAttributes` | boolean | Include attributes in results | true |
| `withMetadata` | boolean | Include metadata (owner, creator, expiry) in results | true |
| `withPayload` | boolean | Include payload in results (base64 encoded) | true |
| `validAtBlock` | number | Query state at a specific block number | - |
#### Filter Syntax
The `filter` parameter uses the `arkiv_query` expression language:
| Operator | Description | Example |
|----------|-------------|---------|
| `=` | Equality | `status = "active"` |
| `!=` | Not equal | `status != "deleted"` |
| `>`, `>=`, `<`, `<=` | Numeric range | `score > 100` |
| `&&` | Logical AND | `type = "post" && score > 50` |
| `\|\|` | Logical OR | `status = "active" \|\| status = "pending"` |
| `!` | Negation | `!(status = "deleted")` |
| `~` | Glob match | `name ~ "test*"` |
| `!~` | Negated glob | `name !~ "draft*"` |
**Synthetic attributes** (prefixed with `$`):
| Attribute | Description |
|-----------|-------------|
| `$all` | Match all entities |
| `$owner` | Current owner address |
| `$creator` | Original creator address (immutable) |
| `$key` | Entity key |
#### Filter Examples
```
# All entities
$all
# By entity key
$key = "0xabc123..."
# By owner or creator
$owner = "0x1234567890abcdef..."
$creator = "0x1234567890abcdef..."
# Attribute equality
status = "active"
type = "post"
# Numeric range
score > 100
price >= 50 && price <= 200
# Compound
project = "myapp" && type = "post" && score > 10
# Glob matching
name ~ "draft*"
!(status = "deleted")
```
#### Response Format
```json
{
"entities": [
{
"key": "0x...",
"owner": "0x...",
"creator": "0x...",
"createdAtBlock": "12345",
"lastModifiedAtBlock": "12350",
"expiresAtBlock": "99999",
"contentType": "application/json",
"payload": "<base64-encoded bytes>",
"attributes": [
{ "key": "type", "value": "post" },
{ "key": "score", "value": 42 }
]
}
],
"cursor": "0x2a",
"blockNumber": "12350",
"count": 1
}
```
Paginate by passing the returned `cursor` back as the `cursor` parameter in the next call. When `cursor` is absent, there are no more results.
## Development
The server uses:
- [@arkiv-network/sdk](https://github.com/Arkiv-Network/arkiv-sdk-js) — Arkiv TypeScript SDK
- [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) — MCP Server SDK
### Project Structure
```
arkiv-mcp/
├── src/
│ └── index.ts # Main server implementation
├── package.json
├── tsconfig.json
└── README.md
```
## License
MIT
TDQS
A3.9/5.0
Scored across 1 tool
Disambiguation5/5
Only one tool exists, so there is no risk of confusion between tools. Perfect disambiguation.
Naming Consistency5/5
With a single tool, there are no naming inconsistencies. The name 'query_entities' follows a clear verb_noun pattern.
Tool Count1/5
A single tool is insufficient for a database server; even if it's query-only, missing CRUD operations severely limits functionality. Extreme mismatch.
Completeness2/5
The server only offers query functionality, omitting essential operations like create, update, or delete. Significant gaps for typical database interaction.
Maintenance
ActivityInactive
ResponsivenessNo issues