Skip to main content
Glama
arrivets

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