Skip to main content
Glama
Ev3lynx727

server-commands-rtk

by Ev3lynx727
README.md
# commands-rtk

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/Ev3lynx727/commands-rtk/actions/workflows/ci.yml/badge.svg)](https://github.com/Ev3lynx727/commands-rtk/actions/workflows/ci.yml)
[![npm version](https://img.shields.io/npm/v/commands-rtk)](https://www.npmjs.com/package/commands-rtk)
[![server-commands-rtk MCP server](https://glama.ai/mcp/servers/Ev3lynx727/server-commands-rtk/badges/score.svg)](https://glama.ai/mcp/servers/Ev3lynx727/server-commands-rtk)

---
[![server-commands-rtk MCP server](https://glama.ai/mcp/servers/Ev3lynx727/server-commands-rtk/badges/card.svg)](https://glama.ai/mcp/servers/Ev3lynx727/server-commands-rtk)

MCP server that executes shell commands via MCP tools - with streaming spawn, automatic [RTK](https://github.com/rtk-ai/rtk) token reduction, persistent caching, and full execution logging.

- **Streaming spawn** - uses `spawn` (not `exec`), no `maxBuffer` ceiling, pipes stdout/stderr directly
- **Auto-RTK** - transparently wraps commands with RTK for ~90% token reduction
- **Timeout + cancellation** - `AbortController` cancels stream collection immediately, `SIGKILL` terminates process tree
- **Persistent cache** - results cached in `~/.local/share/state/commands-rtk/command-cache.json` across sessions
- **Execution logger** - append-only JSONL with auto-rotation, gzip compression, archive listing
- **Safe file writes** - `write_file` with base64 content avoids JSON serialization breakage on special characters
- **URI resolver** - `resolve_uri` resolves `scheme://path` to absolute file paths via shared TOML config

## Includes

- ✅ **License** - This repository contains a LICENSE file
- ✅ **Prompts** - This MCP Server includes prompts users can invoke
- ✅ **Resources** - This MCP Server includes resources for attaching and managing context data

---

## Requirements

- **Node.js 24+** (ESM, `"type": "module"` in package.json)
- **rtk CLI** - install via

  ```
  `curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh`
  ```

## Installation

### npx (no install)

```bash
npx commands-rtk                    # Run MCP server (downloads on demand)
npx commands-rtk setup              # Apply one-time patches (rtk fix, etc.)
```

### npm (global install)

```bash
npm install -g commands-rtk
commands-rtk setup                  # One-time patch setup
```

### From source

```bash
git clone https://github.com/Ev3lynx727/server-commands-rtk.git
cd server-commands-rtk
npm install
npm run build
npm run setup                       # One-time patch setup (rebuilds rtk from source if needed)
```

### npx (no install, MCP client config)

```json
{
  "mcpServers": {
    "commands-rtk": {
      "command": "npx",
      "args": ["commands-rtk"],
      "env": {}
    }
  }
}
```

> **First run:** Run `npx commands-rtk setup` once before first use to apply one-time patches.

### Global install (MCP client config)

```json
{
  "mcpServers": {
    "commands-rtk": {
      "command": "commands-rtk",
      "args": [],
      "env": {}
    }
  }
}
```

### OpenCode

```json
{
  "mcp": {
    "commands-rtk": {
      "type": "local",
      "command": ["node", "/path/to/commands-rtk/dist/index.js"],
      "enabled": true,
      "timeout": 60000
    }
  }
}
```

## Tools

| Tool | Description |
|------|-------------|
| `run_process` | Execute a shell command with RTK auto-filtering |
| `get_cache_stats` | Show cache hit/miss counts and entry count |
| `clear_command_cache` | Wipe all cached command results |
| `cached_commands` | List all cached command keys and timestamps |
| `execution_log` | Read execution log entries, optionally from archives |
| `list_archives` | List rotated `.jsonl.gz` archive files |
| `write_file` | Write a file from base64 content (safe for special characters) |
| `resolve_uri` | Resolve `scheme://path` to absolute file path via TOML config or `MCP_RESOURCE_ROOTS` |

## Schema

How commands-rtk processes an MCP tool call:

![commands-rtk MCP Server Schema](.assets/schema.svg)

The flow: `server.ts` receives `tools/call` → `Zod.parse()` validates → `executor.ts` spawns with `rtk` prefix → result cached + logged → JSON-RPC response returned.

## Usage

```javascript
// Auto-RTK (default) - ~90% token reduction
run_process({command: "ls -la"})

// Bypass RTK filtering entirely
run_process({command: "ls -la"})

// Explicitly enable/disable RTK
run_process({command: "ls -la"})

// Override default timeout (60s) per call
run_process({command: "sleep 30", timeout_ms: 5000})

// Set working directory and attach metadata
run_process({
  command: "npm test",
  cwd: "/path/to/project",
  description: "run unit tests",
  model_used: "claude-sonnet-4",
  timeout_ms: 30000
})

// Force cache bypass
run_process({command: "npm install", clear_cache: true})
```

### execution_log

```javascript
// Tail last 100 entries
execution_log({limit: 100})

// Include rotated archives for full history
execution_log({limit: 500, include_archives: true})
```

### write_file

MCP tool parameters are JSON-serialized. Content with quotes, backticks, or long special-character strings can break the JSON framing. Use `write_file` with base64 encoding:

```javascript
write_file({
  path: "/tmp/output.txt",
  content_b64: "SGVsbG8gV29ybGQ="
})
```

### resolve_uri

```javascript
resolve_uri({uri: "headquarters://."})
// { scheme: "headquarters", relativePath: ".", absolutePath: "/home/ev3lynx/headquarters" }

resolve_uri({uri: "datasets://train/run-001.parquet"})
// { scheme: "datasets", relativePath: "train/run-001.parquet", absolutePath: "/home/ev3lynx/datasets/memory-graph/train/run-001.parquet" }
```

Schemes are loaded from `~/.config/uri-resolver/config.toml` (primary) with `MCP_RESOURCE_ROOTS` as fallback. `scheme://.` resolves to the base directory.

### list_archives

```javascript
list_archives()
// Returns: { archives: ["file1.jsonl.gz", ...], count: 7 }
```

## Configuration (rtk-hook.toml)

| Section | Key | Default | Description |
|---------|-----|---------|-------------|
| `[execution]` | `timeout_ms` | `60000` | Default per-command timeout (overridable per call) |
| `[execution]` | `max_buffer_mb` | `10` | Max stdout/stderr collected per command |
| `[execution]` | `max_log_entries` | `1000` | Entries kept in active log before rotation |
| `[execution]` | `max_archives` | `50` | Max rotated archive files retained |
| `[execution]` | `compress_archives` | `true` | Compress rotated logs with gzip |
| `[cache]` | `debounce_ms` | `2000` | Window for deduplicating identical commands |

Example:

```toml
[execution]
timeout_ms = 60000
max_buffer_mb = 10
max_log_entries = 1000
max_archives = 50
compress_archives = true

[cache]
debounce_ms = 2000
```

## State Files

All runtime state lives under `~/.local/share/state/commands-rtk/`:

```
~/.local/share/state/commands-rtk/
├── command-cache.json      # Persistent command cache
└── execution-log.jsonl     # Append-only execution log
```

Created automatically on first run (`mkdirSync` with `recursive: true`).

### Cache

- **File**: `command-cache.json` - persistent JSON, survives server restart
- **Key**: SHA-256 hash of `(command + cwd)`
- **Stats**: Hit/miss counters via `get_cache_stats`
- **Flush**: Written to disk on every mutation + on SIGTERM/SIGINT

### Execution Log

- **File**: `execution-log.jsonl` - append-only, one JSON object per line
- **Rotation**: When `max_log_entries` reached, half of entries archived. Rotated files land alongside the active log as `execution-log-{timestamp}.jsonl.gz`
- **Per-entry metadata**: `timestamp`, `key`, `command`, `rtk_filtered`, `rtk_rewritten`, `cached`, `success`, `exitCode`, `duration_ms`, `error_type`, `stdout`/`stderr`, `stdout_lines`/`stderr_lines`, `model_used`

## MCP Resources & URI Resolution

Resource templates and URI resolution share a unified scheme registry loaded from two sources (TOML wins):

1. **Primary**: `~/.config/uri-resolver/config.toml` — shared with the standalone uri-resolver MCP server
2. **Fallback**: `MCP_RESOURCE_ROOTS` env var — for deployment-specific overrides

```bash
export MCP_RESOURCE_ROOTS='{"headquarters": "~/headquarters"}'
```

Each scheme registers a resource template `{scheme}://{path}` and is queryable via the `resolve_uri` tool. Path traversal is denied via `startsWith()` guard.

## Response Format

All tools return JSON:

```json
{
  "cached": false,
  "key": "sha256-hash",
  "command": "echo hello",
  "result": {
    "success": true,
    "stdout": "hello\n",
    "stderr": "",
    "exitCode": 0,
    "duration_ms": 12,
    "error_type": null
  },
  "rtk_filtered": true,
  "rtk_rewritten": true
}
```

Error types: `timeout`, `not_found` (ENOENT), `permission_error` (EACCES/EPERM), `memory_error` (ENOMEM), `unknown_error`.

Timeout returns `exitCode: 124` with message in `stderr`.

## Token Savings

| Command | Raw Tokens | RTK Tokens | Savings |
|---------|-----------|------------|---------|
| `ls -la` | ~25,000 | ~3,000 | **88%** |
| `tree` | ~50,000 | ~5,000 | **90%** |
| `git diff` | ~15,000 | ~500 | **97%** |
| `npm install` | ~5,000 | ~200 | **96%** |

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `SERVER_DIR` | No | Custom server root (defaults to directory containing `dist/`) |
| `RTK_MODEL_USED` | No | Override for `model_used` in execution log metadata |
| `MCP_RESOURCE_ROOTS` | No | JSON object mapping scheme names to directory paths (fallback, TOML config is primary) |
| `LOG_LEVEL` | No | Log level (`error`, `warn`, `info`, `debug`) |

## Credit

This project would not work without [RTK](https://github.com/rtk-ai/rtk) — the Rust token reducer that filters shell command output for ~90% token savings.

## License

MIT

TDQS

A3.6/5.0

Scored across 8 tools

Disambiguation5/5

Each tool targets a distinct action or resource: cache listing/clearing/stats, log retrieval/archives, URI resolution, process execution, and file writing. No overlapping purposes.

Naming Consistency5/5

All tool names use consistent snake_case and follow a verb_noun pattern (e.g., list_archives, run_process, write_file). No mixed conventions.

Tool Count5/5

8 tools is well-scoped for a command server utility set. Each tool serves a clear need without excess or deficiency.

Completeness4/5

Covers core operations (run, write, cache management, logging, URI resolution). Minor gap: no tool to delete or manipulate archive files, but core workflows are covered.

Maintenance

ActivityStale
ResponsivenessNo issues