Skip to main content
Glama
N0moreher0
by N0moreher0

venira-mcp-coding

Fast, workspace-scoped MCP server for coding agents (OpenCode, Claude Desktop, any MCP client). 16 tools, structured JSON envelopes, validated read caches, async shell, and full SQLite audit trail — pure Node, no external binary, no GUI, no network.

┌──────────────┐   stdio (MCP)   ┌────────────────────────────────────────────┐
│ MCP client    │ ◄──────────────► │  venira-mcp-coding (Node, single process) │
│ (OpenCode,    │                  │  16 tools · read caches · async shell    │
│  Claude, ...) │                  │  SQLite audit (WAL) · p50/p95 metrics   │
└──────────────┘                  └────────────────────────────────────────────┘
  • Zero external dependencies. Only Node ≥ 20 + @modelcontextprotocol/sdk + zod + better-sqlite3. No Rust binary, no database server, no network.

  • Workspace-locked by default. Every path is validated inside the workspace; ../ escape is rejected with path_escape.

  • Validated read cache. Reads are cached and re-validated by mtime + size, so external edits or deletes never return stale content.

  • Async shell. project_shell_run returns a run_id in ~5 ms; poll with project_shell_status (5–30 s observation window, deliberately non-queued).

  • Full observability. project_health reports capability state, queue depth, cache hit-rates, active shells, and p50/p95/max per operation.

  • Audit trail. Every operation (including failures, shell runs, and cancellations) is written to a SQLite WAL table (project_tool_audit).

1. Table of contents


Related MCP server: Coding Tools MCP

2. Quick start

Prerequisites

Requirement

Version

Notes

Node.js

≥ 20.0

Ships node:sqlite (audit inspection) and full ESM

Git

any

—

That's it. There is no external binary to build or download.

npm install -g venira-mcp-coding        # or: npx -y venira-mcp-coding (no install)

Once the package is published, npx fetches it to a temp dir and runs it — no local clone or build needed:

npx -y venira-mcp-coding                # start the MCP server (stdio)
npx -y venira-mcp-coding --doctor       # run the preflight suite
npx -y venira-mcp-coding --verify       # run the behavioural regression suite

The bin entry in package.json resolves dist/server.js relative to the installed location, so npx works without you having to clone anything.

Run from source (developers)

git clone https://github.com/N0moreher0/Venira-mcp.git venira-mcp-coding
cd venira-mcp-coding
npm install
npm run build          # tsc → dist/
npm start              # stdio MCP server (attach via your MCP client, or pipe JSON manually)

Run in Docker (no Node on the host)

# Build locally
docker build -t venira-mcp-coding .

# Run your project as the workspace
docker run --rm -it \
  -v /path/to/your/project:/workspace \
  -e VENIRA_WORKSPACE=/workspace \
  -e VENIRA_DATA_DIR=/workspace/data \
  venira-mcp-coding

See DOCKER.md for multi-arch builds and MCP-client integration over Docker.

One-shot sanity checks (no MCP client required)

npm run smoke    # in-process: list a dir, read package.json, verify path-escape is blocked
npm run doctor   # 7 preflight checks: workspace, data dir, tool count, health, shell, version
npm run verify   # end-to-end MCP test suite (~30 checks: cache, batch, shell, audit, modes)
npm run bench    # in-process corehost-tier benchmark (read throughput, batch, parallel)
npm run bench:mcp# end-to-end MCP benchmark (first call, batch 8, search, health, …)

3. MCP client configuration (JSON)

3.1 OpenCode (opencode.jsonc or .opencode/opencode.jsonc)

The simplest form (uses npx, no local install needed):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "venira": {
      "type": "local",
      "command": ["npx", "-y", "venira-mcp-coding"],
      "enabled": true,
      "environment": {
        "VENIRA_WORKSPACE": "C:\\path\\to\\your-project",
        "VENIRA_UNRESTRICTED": "0"
      }
    }
  }
}

Or point at a local build (after git clone + npm install + npm run build):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "venira": {
      "type": "local",
      "command": ["node", "C:\\path\\to\\venira-mcp-coding\\dist\\server.js"],
      "enabled": true,
      "environment": {
        // Root of the workspace. All relative paths resolve against this.
        // Defaults to the server's process.cwd() when unset.
        "VENIRA_WORKSPACE": "C:\\path\\to\\your-project",
        // Where the audit DB (venira.db) lives. Defaults to <workspace>/data.
        "VENIRA_DATA_DIR": "C:\\path\\to\\data",
        // Lock every path to the workspace. KEEP this unset (or "0") in normal use.
        "VENIRA_UNRESTRICTED": "0",
        // Default shell for project_shell_run: "powershell" | "cmd" | "bash"
        "VENIRA_DEFAULT_SHELL": "powershell",
        // "full" | "compact" | "summary" (default "full")
        "VENIRA_OUTPUT_MODE": "full",
        // Set to "1" for pretty-printed JSON in tool results (costs bytes; leave off for agents).
        "VENIRA_PRETTY": "0"
      }
    }
  }
}

This repo ships a ready-to-edit copy at opencode.example.json.

3.2 Claude Desktop / any MCP client (claude_desktop_config.json or .mcp.json)

{
  "mcpServers": {
    "venira": {
      "command": "npx",
      "args": ["-y", "venira-mcp-coding"],
      "env": {
        "VENIRA_WORKSPACE": "C:\\path\\to\\your-project",
        "VENIRA_DATA_DIR": "C:\\path\\to\\your-project\\data",
        "VENIRA_UNRESTRICTED": "0",
        "VENIRA_DEFAULT_SHELL": "powershell"
      }
    }
  }
}

For a local build (not yet published to npm), use "command": "node", "args": ["C:\\path\\to\\venira-mcp-coding\\dist\\server.js"] instead of npx.

3.3 Environment variables (full reference)

Variable

Default

Description

VENIRA_WORKSPACE

process.cwd()

Root of the workspace. All relative paths resolve against this; absolute paths outside it are rejected unless unrestricted.

VENIRA_DATA_DIR

<workspace>/data

Where the audit DB (venira.db) is created/updated.

VENIRA_UNRESTRICTED

"0"

"1" disables workspace locking (absolute paths anywhere work). Do not set in production.

VENIRA_DEFAULT_SHELL

platform default

powershell / cmd / bash used when project_shell_run receives no shell argument.

VENIRA_OUTPUT_MODE

full

full = complete payloads · compact = summary when >8 KB · summary = always trimmed previews.

VENIRA_PRETTY

"0"

"1" = 2-space pretty JSON in tool results.

VENIRA_SESSION_ID

auto (opencode-<pid>-<rand>)

Session tag; audit rows are grouped by it. Useful for verification / parallel test runs.

VENIRA_READ_CACHE_BYTES

67108864 (64 MiB)

Budget for read + info caches.

VENIRA_LIST_CACHE_MS

1500

TTL for directory listing cache.

VENIRA_SEARCH_CACHE_MS

3000

TTL for search result cache.

VENIRA_RECENT_CACHE_MS

2000

TTL for recent-files cache.

VENIRA_BATCH_ITEM_BYTES

524288 (512 KB)

Per-item cap inside project_read_batch.

VENIRA_DEBUG_STARTUP

"0"

"1" = startup errors go to stderr instead of the protocol-safe stdout event.


4. Tools (16)

Every tool returns the standard envelope (§8):

{
  "ok": true,
  "status": "completed",
  "request_id": "8f3a…c2",
  "kind": "file_read",
  "data": { … },
  "truncated": false,        // optional
  "hint": "Next chunk: …",   // optional, self-explanatory next action
  "cached": true,            // optional, true when served from cache
  "elapsed_ms": 2.57
}

4.1 Read family (read-only, batch-safe, cached)

Tool

Purpose

Notes

project_list_files

List files/dirs, depth 1–3, limit ≤ 200

TTL cache 1.5 s, invalidated on any mutation

project_read_file

Read a text file, by line range (1-based)

mtime+size-validated cache; next_start_line when truncated; optional line_numbers prefix

project_read_ranges

Read multiple disjoint line ranges of one file in a single call (max 16)

Reuses the read cache per range

project_get_file_info

File/dir metadata: kind, size, mtime

Very fast; cached

project_search

Search by file name, dir name, literal content, regex, or symbol definition

TTL cache 3 s; respects glob, exclude_glob, context_lines, count_only

project_recent_files

Files modified recently (bounded filesystem scan, skips node_modules/target/.git)

TTL cache 2 s; includes session_edits — files you wrote in this session

project_read_batch

Run up to 8 read-only ops in one call (list_files, read_file, get_file_info, search)

Sequential + cached; response budget enforced per item

project_health

Server diagnostics: capability, queue, cache hit-rates, active shells, p50/p95 per op, audit DB stats

include_audit=false skips the DB query (~2 ms)

4.2 Mutate family (destructive, invalidates caches)

Tool

Purpose

Notes

project_write_file

Create / overwrite / append a file

mode: "create" errors if file exists; expected_sha256 guards against blind overwrites

project_edit_file

Replace exact text: one old_text/new_text pair or up to 64 edits[]

replace_all supported; expected_sha256 available

project_create_directory

Create a directory tree

create_parents defaults to true

project_create

Create a file or directory in one call

kind: "file" requires content; kind: "directory" ignores content

project_delete_path

Delete a file or directory tree

recursive: true for directories. Not undoable.

4.3 Shell family (async, non-blocking)

Tool

Purpose

Notes

project_shell_run

Run a shell command; returns run_id in ~5 ms

shell: powershell / cmd / bash; relative_cwd optional. stdout/stderr tail captured in-process.

project_shell_status

Poll a running command

wait_seconds 0–30 is an observation window, not a timeout. Deliberately not queued behind other calls, not audit-logged (prevents orphan "running" rows).

project_shell_cancel

Kill a running command by run_id

Also used at MCP shutdown to avoid orphan processes.

4.4 How the model is told to pick the right tool

At connect time the server advertises an instructions block (MCP SDK ≥ 1.32) containing a decision tree the model can read. A condensed version:

1. Two+ reads or mixed read-only steps → project_read_batch (max 8, sequential + cached)
2. One file → project_read_file; large file → start_line/end_line or project_read_ranges;
   follow next_start_line when truncated
3. Find code → project_search (kind=literal_content or definition), then project_read_ranges around hits
4. Directory tree → project_list_files (depth 1..3, limit ≤200). "What changed lately?" → project_recent_files
5. Write whole file → project_write_file; small precise change → project_edit_file;
   delete → project_delete_path (destructive, not undoable)
6. Build/test/long command → project_shell_run (returns run_id immediately),
   then poll project_shell_status (wait_seconds 5..30); project_shell_cancel to stop
7. Debug latency/errors → project_health

Every tool also carries machine-readable metadata in its description (Use when: / Avoid when: / Speed: / Output: / Batch-safe:) and a _meta.venira object with the same fields, so both prompt-driven and tool-discovery-driven clients get the same signal.


5. Architecture

venira-mcp-coding/
├── server.ts                 # MCP entry point: McpServer + StdioTransport, warm-up, shutdown
├── tools/
│   └── project.ts            # 16 tool registrations, serial queue, caches, shell tracking,
│                             #   audit-DB inspection, project_health, project_create
├── lib/
│   ├── corehost.ts           # In-process backend: file I/O, search, async shell,
│   │                         #   scope capability, SQLite WAL audit (better-sqlite3)
│   ├── workspace.ts          # Workspace path resolution + escape validation
│   ├── output.ts             # Envelope builder, output modes, hint inference, error parser
│   ├── metrics.ts            # Ring-buffer p50/p95/max per operation (256 samples each)
│   ├── types.ts              # Shared host snapshot types
│   └── version.ts            # Exported VERSION constant
├── scripts/
│   ├── smoke.ts              # In-process backend sanity check
│   ├── bench.ts              # In-process backend benchmark
│   ├── bench-mcp.ts          # End-to-end MCP benchmark
│   ├── verify.ts             # ~30 end-to-end checks (cache, batch, shell, audit, modes)
│   └── doctor.ts             # 7 preflight checks (workspace, data dir, tools, health, shell)
├── opencode.example.json     # Ready-to-edit OpenCode MCP config
├── package.json / tsconfig.json
└── dist/                     # Build output (committed to the npm package, gitignored in repo)

Key design decisions

  • In-process backend. The CoreHost class in lib/corehost.ts implements every project_tool.* operation in pure Node — no JSON-Lines IPC, no child process. The tools/project.ts layer still funnels calls through a serial queue because SQLite WAL audit writes are cheap but not free; keeping one writer at a time is simpler and deterministic than racing on better-sqlite3 transactions.

  • Long-lived capability. The workspace scope (capability token, TTL 2 h) is opened once at startup (in parallel with the MCP handshake) and reused for every request. A capability expiry triggers exactly one re-open-and-retry.

  • Cache strategy. Reads and file-info are cached and validated by mtime + size (immune to external edits and deletions). List / search / recent use short TTLs (1.5 s / 3 s / 2 s) and are wiped on any mutation. Search results with 0 hits are not cached (prevents stale "no match"). Read + info caches are bounded by VENIRA_READ_CACHE_BYTES (default 64 MiB) with LRU eviction.

  • Audit, not just logging. better-sqlite3 opens venira.db in WAL mode. Every execute op gets a running row on start and a succeeded/failed row on completion. shell_status is the only op intentionally not audited — a long poll must never leave an orphan running row. project_health (with include_audit) reports orphan rows as a post-mortem signal.


6. Security model

This project is intentionally conservative by default:

Control

Default

How it works

Workspace lock

ON

lib/workspace.ts resolves every path against VENIRA_WORKSPACE (or process.cwd()). A path that escapes (../.., absolute outside root) throws path_escape.

Unrestricted mode

OFF

VENIRA_UNRESTRICTED=1 disables the lock (use only when you fully understand the consequences — the agent can read/write anywhere on the machine).

Shell cwd

workspace

project_shell_run with no relative_cwd runs in the workspace root; the command itself is still whatever the agent passes.

Audit

ON

Every operation (including failures and cancellations) is written to project_tool_audit in a SQLite WAL database.

sensitive_result

—

The envelope carries retryable: false and a "do not retry" hint when content is withheld by policy.

expected_sha256

opt-in

project_write_file / project_edit_file / project_create accept a content hash; a mismatch aborts with conflict — protects against blind overwrites when the agent re-applies an old edit.

Destructive ops

labelled

Every mutating tool advertises destructiveHint: true in its MCP annotations; project_delete_path additionally documents that it is not undoable.

Threats this does NOT protect against: a malicious prompt can still instruct the agent to run destructive shell commands (rm -rf, format…). The audit log and project_health make that visible after the fact; the workspace lock only bounds filesystem access, not shell side-effects. If you need hard boundaries, run the MCP server in a container / VM, or drop VENIRA_DEFAULT_SHELL to a restricted shell profile.


7. Benchmark

Numbers below are from a Windows 11 / NVMe / Node 20 machine, standalone build, 2026-10-27. See benchmarks.md for the full table and historical comparison.

7.1 End-to-end MCP (npm run bench:mcp)

Scenario

avg

p50

p95

max

First call (post warm-up)

—

2.5 ms

—

—

project_read_file ×50, same file (cached)

1.93 ms

1.01 ms

2.65 ms

3.07 ms

project_read_file ×8, distinct files

2.37 ms

1.92 ms

5.78 ms

5.78 ms

project_read_batch ×3 (8 items each)

4.18 ms

3.71 ms

6.08 ms

6.08 ms

project_get_file_info ×30

1.11 ms

1.02 ms

2.63 ms

2.97 ms

project_search ×10 (literal content)

3.38 ms

1.26 ms

21.76 ms

21.76 ms

project_read_ranges (2 ranges)

3.6 ms

—

—

—

project_recent_files

5.0 ms

—

—

—

project_health (no DB query)

1.8 ms

—

—

—

Reading the batch row: 8 distinct reads cost 4.2 ms total as one batch call, vs. ~8 × 2.4 ms ≈ 19 ms issued individually. That is the round-trip saving the decision tree in §4.4 is designed to exploit.

7.2 In-process tier (npm run bench)

Scenario

Value

Direct first read (cold, includes capability open)

19.96 ms

read_file sequential ×50

avg 0.72 ms · p50 0.59 ms · p95 1.88 ms

8-file batch sequential

11.0 ms total

Parallel ×8

2.9 ms total

get_file_info ×50

avg 0.30 ms

list_files

12.7 ms

search (literal, *.ts)

9.8 ms

shell_run + shell_status round-trip

~930 ms (2 s wait budget dominates)

7.3 Rust-backend v0.3.0 → standalone v1.0.0

Metric

v0.3.0 (Rust IPC)

v1.0.0 (standalone)

Why

First MCP call

6.3 ms

2.5 ms

No subprocess spawn

Cached read p50

2.57 ms

1.01 ms

In-process file I/O

8-file batch avg

19.11 ms

4.18 ms

No IPC + no audit lock

project_health

5.5 ms

1.8 ms

In-process

Install surface

Rust binary + Node

Node only

npm install is the whole setup


8. Envelopes, hints, and error codes

Every success and every failure is a single JSON object. On failure, the MCP result has isError: true and the envelope looks like:

{
  "ok": false,
  "status": "failed",
  "request_id": "…",
  "kind": "read_file",
  "error": {
    "code": "not_found",
    "message": "Path does not exist: .verify-tmp/missing.txt",
    "retryable": false
  },
  "hint": "Check the path with project_list_files or project_search first; do not retry the same path.",
  "elapsed_ms": 4.12
}

error.code

retryable

What it means

not_found

✗

Path does not exist

invalid_request

✗

Bad argument names/types

conflict

✓

File changed since read, or edit ambiguous — re-read and retry

path_escape

✗

Path outside the workspace (use VENIRA_UNRESTRICTED=1 to opt out)

scope_denied

✗

Capability / permission mismatch

resource_limit

✗

Batch item too large or response budget exhausted — narrow the request

io_error

✓

File locked or disk busy — retry once

audit_unavailable

✗

Audit row could not be written — stop retrying

capability_expired

✓

Scope re-opens automatically on next call — retry once

host_timeout

✓

Backend didn't answer in time — check project_health, retry once

host_unavailable

✓

Backend is unavailable; it recovers on the next call — retry once

sensitive_result

✗

Content withheld by policy — do not retry or work around it

unsupported

✗

Operation unavailable in current permission mode

internal

✗

Unexpected error — check project_health and stderr

Hints are actionable next steps, not prose: "Next chunk: project_read_file({ relative_path: "src/foo.ts", start_line: 1000 })", "Poll project_shell_status({ run_id: "r123", wait_seconds: 5 })", etc. The model is expected to read hint first.


9. What this project does well & what it does not

Strengths

  • Speed at the MCP layer. ~2.5 ms first call, ~1 ms p50 cached reads, ~4.2 ms for an 8-file batch. The in-process backend removes the IPC hop and the audit lock contention that dominated the v0.3.0 (Rust) profile.

  • Zero install friction. npm install && npm run build is the entire setup. No Rust toolchain, no prebuilt binary, no database server.

  • Correctness of reads. mtime+size validation means the cache can never serve content that no longer exists on disk (deleted, renamed, or edited externally).

  • Self-diagnosis. project_health + doctor.ts + verify.ts give three independent viewpoints: runtime state, preflight, and behavioural regression.

  • Audit-grade traceability. Every op, including failures and cancellations, lands in a SQLite table tagged by session — useful for post-mortems on what an agent actually did.

  • Agent-friendly contracts. Envelopes, hints, _meta annotations, and a decision-tree instructions block mean the model rarely has to guess.

Limitations (be honest about these)

  • macOS CI-only, not dev-tested. CI runs on macos-latest (x64 + arm64) for both Node 20 and 22, but no developer has day-to-day macOS. Path handling is POSIX-correct (verified on Linux), but Spotlight / Gatekeeper / SIP quirks are untested.

  • No git/diff tooling yet. project_diff_files, project_file_symbols, and project_symbol_references are on the roadmap (see TODO.md) but not implemented.

  • Search is a line scanner, not an index. project_search reads every file in scope (bounded at 1 MiB/file) and matches line-by-line. It's fine for typical project sizes; for a monorepo with thousands of files, p95 will climb.

  • project_recent_files is a bounded scan, not an index: it caps at 4 000 files / 300 directories and skips node_modules, target, dist, .git, etc.

  • Shell is tail-only. project_shell_run returns a bounded tail of stdout/stderr, not a live stream. Long outputs are truncated by design.

  • One workspace per server instance. The workspace, data dir, and permission mode are fixed at process start. To serve multiple workspaces concurrently, run multiple instances.

  • better-sqlite3 is a native module. Prebuilt binaries cover the common Node × platform × arch combos (Node 20/22 on Linux x64/arm64, macOS x64/arm64, Windows x64). Unusual platforms (musl, Alpine, ARM Windows, exotic archs) will compile from source on npm install and need python3 + a C compiler. The Docker image and the standalone .zip in the release sidestep this entirely.


10. Interesting details & things you should know

  • Serial queue, by design. The MCP layer funnels every execute through a promise queue so the SQLite audit writer is single-threaded. shell_status and cancel are deliberately unqueued so a long poll never blocks anything else.

  • Warm-up races the MCP handshake. warmUp() opens the capability scope immediately and in parallel with server.connect(). The first tool call therefore costs ~2.5 ms instead of ~20 ms (capability open alone is ~17 ms).

  • Search cache is asymmetric on purpose. A search that found hits is cached (TTL 3 s). A search that found none is not — because the absence of a hit is exactly what can become stale the instant a file is written. (verify.ts guards this with search_cache_invalidated.)

  • project_recent_files is pure Node. No backend needed: bounded BFS with readdir + stat in chunks of 64, symlinks skipped, ignored dirs pruned, results sorted by mtime descending. The session_edits field additionally lists files this session wrote (up to 20), so the model knows what it already touched.

  • Audit DB is inspected read-only. project_health opens venira.db with readonly: true via better-sqlite3 and counts rows for the session, including orphan_running (rows stuck at running — a sign of an unclean shutdown).

  • Metrics are ring buffers, not histograms. lib/metrics.ts keeps the last 256 samples per operation (p50/p95/max/avg). Deliberately tiny: the goal is "what happened this session", not "90-day SLO tracking".

  • Output modes are cheap. summary mode replaces payloads with 8 KB previews + a summary object; compact only adds a summary when the payload exceeds 8 KB. The model can request full data back via a follow-up call when it truly needs it.

  • Shutdown is defensive. On SIGINT/SIGTERM/stdin close the server cancels all running shells, closes the scope, and marks the audit DB cleanly — no orphans, no stuck WAL.


11. Development workflow

npm run build        # type-check + emit dist/
npm run smoke        # in-process sanity (backend reachable, path lock works)
npm run doctor       # preflight: 7 checks incl. audit DB and shell smoke
npm run verify       # behavioural regression suite (~30 checks, ~60 s)
npm run bench        # in-process numbers
npm run bench:mcp    # end-to-end numbers

Adding a new tool

  1. Register it in tools/project.ts with registerProjectTools — use the config() helper so Use when / Avoid when / Speed / Output / Batch-safe land in the description and in _meta.venira.

  2. Read-only ops: route through executeCached so they automatically participate in cache invalidation (mutations wipe list/search/recent caches).

  3. New backend ops: add the handler in lib/corehost.ts under operations, and add an audit row (or mark it read-only like shell_status if it's a long poll).

  4. Add a case to scripts/verify.ts (the suite already checks instruction blocks, annotations, envelope shape, and audit rows for new tool names).

  5. Update the decision tree in server.ts (INSTRUCTIONS) and the tool table in README.md.

Testing conventions

  • verify.ts uses a fixed VENIRA_SESSION_ID so its audit rows are separable from real sessions.

  • bench.ts uses a unique request_id tag per run — the audit table has a UNIQUE constraint on request_id, and reusing one across runs would produce audit_unavailable.

  • Do not commit to dist/, node_modules/, test/, or *.log (see .gitignore).


12. Troubleshooting

Symptom

First things to check

not_found on a path that looks fine

Run npm run doctor; confirm VENIRA_WORKSPACE points where you think.

path_escape on a path that looks fine

The path contains ../ that resolves outside the workspace. Use a workspace-relative path; set VENIRA_UNRESTRICTED=1 only when you truly need it.

Read cache seems stale

It should not — reads are mtime+size validated. If you see it, check that the filesystem timestamp updates (some network drives delay mtime).

Shell command not finishing

project_shell_status with wait_seconds: 30; check project_health → shells.active to see which run_id is still running.

better-sqlite3 build failure on install

You're on an unusual platform (musl, exotic arch). Run npm rebuild better-sqlite3 with build tools (python3, make, g++), or use the Docker image / prebuilt standalone zip instead.

npx venira-mcp-coding not found

The package is not published yet. Use a local build: node <repo>/dist/server.js.

venira.db won't open in project_health

Another process has the WAL locked; make sure only one server instance writes to the same data dir.

Everything slow

Run project_health — queue.depth, pending_requests, and per-op p95 will tell you if it's a bottleneck or a stuck command.


13. Contributing

  1. Fork and clone; npm install && npm run build && npm run doctor.

  2. Read TODO.md — the next milestones are already scoped (cache toggles, request tracing, project_read_audit, shell UX, fuzzy edit, symbol tools).

  3. Keep the invariants from §10: serial queue for execute, long-lived capability, asymmetric search cache, bounded scans.

  4. Add a verify.ts check for every new tool; keep the suite green before opening a PR.

  5. Run npm run bench:mcp and paste the numbers in the PR description when touching tools/project.ts or lib/corehost.ts.


License

Dual-licensed: MIT OR Apache-2.0 — see LICENSE.

Available Tools

16 tools
project_createCreate file or directoryA
Idempotent

Create a directory OR a file in ONE call (merges project_create_directory + project_write_file for the new-file case). Use when: create a directory (kind=directory) or a new file (kind=file, content+mode); kept in sync with the Venira native app tool. Avoid when: modifying an existing file (project_edit_file); overwriting a file whose contents must be preserved (project_write_file mode=overwrite still works). Speed: fast; triggers cache invalidation on write / new directory. Output: directory_created or file_written (data kind depends on the op). Batch-safe: no

NameRequiredDescriptionDefault
kindYes
modeNo
contentNo
create_dirsNo
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)
expected_sha256No

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=false, destructiveHint=false and idempotentHint=true, so the safety profile is covered; the description adds genuinely new behavior: cache invalidation on write/new directory, the output discriminator (directory_created vs file_written), and that it is not batch-safe. It does not say what happens when mode is omitted or that overwrite destroys prior contents beyond a passing hint, so it stops short of full disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Labelled one-line sections (Use when / Avoid when / Speed / Output / Batch-safe) put the decision-relevant information first with almost no filler. Minor dead weight: 'kept in sync with the Venira native app tool' consumes space without changing agent behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With six parameters, low schema coverage and no output schema, the description does supply the output shape and the cache-invalidation side effect. It still leaves an agent guessing about create_dirs, the default mode, and the purpose of expected_sha256, which are material for calling this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 17%, so the description must carry the load, and it explains kind, content and mode=overwrite plus the implicit mode=create/append distinction. However, it never mentions create_dirs (does the parent path get made?) or expected_sha256 (an optimistic-concurrency guard), which are two of the six parameters and easily misused.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb (Create) and both resources (directory or file), and explicitly states it merges project_create_directory plus the new-file case of project_write_file. An agent can distinguish this tool from project_create_directory and project_write_file without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' names both branches (kind=directory; kind=file with content+mode) and 'Avoid when' routes existing-file edits to project_edit_file and preservation-sensitive overwrites to project_write_file mode=overwrite. Both the positive and negative cases name the sibling tool that handles them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_create_directoryCreate directoryA
Idempotent

Create a directory (create_parents defaults to true). Use when: a directory must exist before writing a file into a new path. Avoid when: the directory already exists, or you only need to write a file with create_dirs=true. Speed: nhanh. Output: directory_created: relative_path. Batch-safe: no

NameRequiredDescriptionDefault
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)
create_parentsNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare non-readonly, idempotent, non-destructive, closed-world. The description adds context annotations cannot express: the create_parents default, the return shape ('directory_created: relative_path'), and 'Batch-safe: no', which warns against parallel invocations. It omits what happens on an already-existing directory (error vs. silent success), which is the main remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Labeled lines (Use when / Avoid when / Output / Batch-safe) front-load the essential facts with no filler sentences. The 'Speed: nhanh' line is an untranslated token that carries little actionable meaning and slightly dilutes the otherwise tight structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter, non-destructive creation tool with rich annotations and no output schema, the description covers purpose, preconditions, return value, and concurrency safety. Only the existing-directory error behavior and full create_parents semantics are left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: relative_path is documented in the schema, but create_parents has no schema description. The description compensates only partially by stating its default value, without explaining the consequence of setting it false (e.g., failure when the parent is missing).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a directory') and immediately surfaces the create_parents default. It implicitly distinguishes itself from project_write_file by noting the create_dirs=true alternative, though it does not name the sibling tool explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' and 'Avoid when' clauses give the agent both the positive precondition (directory must exist before writing into a new path) and two exclusion conditions, one of which points at an alternative approach (write_file with create_dirs=true).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_delete_pathDelete pathA
DestructiveIdempotent

Delete a file or directory (directories require recursive=true). Use when: a file/directory must be deleted entirely; the path is confirmed. Avoid when: you only need to change the content (write/edit). This op is not undoable. Speed: fast; clears the read/list/search cache. Output: path_deleted: entries_deleted, bytes_deleted. Batch-safe: no

NameRequiredDescriptionDefault
recursiveNo
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is known; the description still adds value by stating the operation is not undoable, that it clears the read/list/search cache, and that it is not batch-safe. It stops short of describing error behavior (missing path, recursive flag misuse on a file), which matters for a destructive tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, then structured labeled lines for usage, avoidance, speed, output, and batch safety. Every line carries distinct information with no repetition of schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the destructive/irreversible nature, the cache side effect, and the return shape despite there being no output schema, which is exactly what an agent needs. Missing only details about failure paths (nonexistent path, permission errors) since no error schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50% — relative_path is documented in the schema but recursive has no description there. The description compensates by explaining recursive only in the context of directories, though it doesn't state the default or what happens if omitted on a directory.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Delete) and resource (file or directory) and immediately qualifies the directory case with recursive=true. It is clearly distinguishable from siblings such as project_write_file, project_edit_file, and project_create_directory.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Uses explicit 'Use when' and 'Avoid when' clauses and names the alternative operations (write/edit) that should be chosen instead. The condition for selecting this tool is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_edit_fileEdit fileA

Edit a file by exact text replacement: one old_text/new_text pair, or edits[] for multiple sections. Use when: change one or a few text sections whose exact content you know; pair with expected_sha256 to guard against blind overwrites. Avoid when: the whole file must change (project_write_file), or you have not read the file to know old_text. Speed: fast; clears the read/list/search cache for the affected path. Output: file_written: replacements, sha256_before/after. Batch-safe: no

NameRequiredDescriptionDefault
editsNo
new_textNo
old_textNo
replace_allNo
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)
expected_sha256No

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare mutation, non-idempotent, non-destructive status, so the description's job is to add non-obvious traits — it does: cache invalidation for the affected path, speed profile, non-batch-safety, and the returned file_written/sha256_before-after fields. Missing only an explicit statement of failure behavior when old_text isn't found, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Labeled clauses (Use when / Avoid when / Speed / Output / Batch-safe) front-load the core mechanism and route quickly. Efficient, though the telegraphic 'Batch-safe: no' phrasing is slightly cryptic versus prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description names the return fields so the agent knows what comes back, and it covers caching side effects and the primary param meanings. Reasonably complete for a 6-param mutation tool, with the replace_all gap the main omission.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 17%, so the description must compensate; it explains expected_sha256's purpose ('guard against blind overwrites') and the edits[] vs single-pair relationship, which is genuinely useful. However replace_all and the multi-section maxItems:64 limit are never explained, leaving key semantics undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Edit a file by exact text replacement') plus the two supported mechanisms (single old_text/new_text pair or edits[] batch). It explicitly contrasts with project_write_file, so the agent can pick this tool over its closest sibling without reading either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' (one or a few known text sections, pair with expected_sha256) and 'Avoid when' (whole-file rewrite -> project_write_file; haven't read the file for old_text). Alternatives and exclusions are named directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_get_file_infoGet file infoA
Read-only

File/directory metadata (kind, size, modification time). Use when: you only need size/mtime/kind, or want to check that a path exists. Avoid when: you need the file's contents (project_read_file). Speed: very fast; cache validated by mtime+size. Output: file_info: relative_path, kind, size_bytes, modified_unix_seconds. Batch-safe: yes

NameRequiredDescriptionDefault
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, but the description adds real context beyond that: performance characteristics ('very fast'), cache semantics ('cache validated by mtime+size'), and concurrency posture ('Batch-safe: yes'). The stated output field names also set expectations. It does not mention error behavior for missing paths, which keeps it at 4 rather than 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then organized into labeled lines (Use when / Avoid when / Speed / Output / Batch-safe) that are each one short clause. Every line carries actionable information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with no output schema, the description covers purpose, when to use, an alternative, performance, output shape, and batch safety — everything an agent needs to call it correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is a single parameter with 100% schema description coverage, so the schema already fully documents its type and the workspace-relative/absolute semantics. The description adds no syntax or constraint detail beyond what the schema supplies, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource and exactly what is returned (kind, size, modification time) for files or directories, and explicitly separates it from project_read_file, which is the nearest sibling an agent could confuse it with.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit 'Use when' (only need size/mtime/kind, or checking path existence) and an explicit 'Avoid when' naming the alternative tool (project_read_file) for file contents. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_healthHealth & metricsA
Read-only

Server diagnostics: corehost/data dir/audit DB, capability, queue depth, cache hit-rate, running shells, p50/p95 metrics. Use when: debugging slowness/errors, checking the backend/DB/audit before reporting, or inspecting this session's cache/metrics. Avoid when: you just need to read/write files normally. Speed: fast (~a few ms + 1 audit DB query); set include_audit=false to skip the DB query. Output: health: server, corehost, capability, queue, caches, shells, metrics, audit. Batch-safe: no

NameRequiredDescriptionDefault
include_auditNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint/openWorldHint; the description goes well beyond them by disclosing cost ('fast, ~a few ms + 1 audit DB query'), the fact that a DB query is performed and how to skip it via include_audit=false, the output key set, and that it is not batch-safe. That is exactly the kind of side-effect/cost context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Labeled lines (Use when / Avoid when / Speed / Output / Batch-safe) front-load the important routing information with no filler. Slight cost from dense jargon and 'Batch-safe: no' reading as a stub, but overall tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description sketches the returned key structure (server, corehost, capability, queue, caches, shells, metrics, audit) and covers speed, exclusion criteria, and the one parameter. Adequate for invocation; it stops short of describing value shapes within those sections, which is acceptable given the tool's diagnostic nature.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does explain the single parameter's meaning implicitly: include_audit=false skips the audit DB query. It could be slightly sharper by stating the default value, but the trade-off is made clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the action (server diagnostics) and enumerates exactly what is inspected: corehost, data dir, audit DB, capability, queue depth, cache hit-rate, running shells, p50/p95 metrics. This is clearly distinguishable from every sibling, which are file/shell/project operations, and an agent can tell it is a read-only diagnostics probe.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit 'Use when' conditions (debugging slowness/errors, verifying backend/DB/audit before reporting, inspecting session cache/metrics) and an explicit 'Avoid when' case (normal file reads/writes). Alternative-oriented guidance is present rather than implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_list_filesList filesA
Read-only

List files/directories in the workspace. depth 1..3 shows the tree in a single call. Use when: you need to see the directory tree, check a path, or list files before reading. Avoid when: you only need one file's metadata (project_get_file_info) or one file's contents (project_read_file). Speed: fast; TTL cache 1.5s, auto-wiped on write/edit/delete. Output: file_list: entries, truncated, hint. Batch-safe: yes

NameRequiredDescriptionDefault
depthNo
limitNo
relative_pathNoPath inside the workspace (relative, or absolute inside the workspace)
include_ignoredNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and openWorldHint, so the description adds real value beyond them: a 1.5s TTL cache that is auto-wiped on write/edit/delete, 'fast' speed, and 'batch-safe: yes'. It stops short of explaining truncation behavior beyond naming a 'truncated' field, and doesn't say what 'hint' contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose, then labeled clauses (Use when / Avoid when / Speed / Output / Batch-safe) that an agent can scan in one pass. Zero filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by naming the return keys (entries, truncated, hint) and summarizing caching and batching behavior. Still incomplete on limit/include_ignored semantics and pagination with a 200-entry cap, which matters for a list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25% (only relative_path has a schema description), so the description must compensate. It explains depth's 1..3 tree semantics, which is the most important behavior, but says nothing about limit, include_ignored, or what path resolution means beyond the schema string. Partial compensation for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List files/directories in the workspace') and immediately contrasts itself with the sibling tools that do adjacent things (project_get_file_info, project_read_file). An agent can distinguish it from all 15 siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' clause names three concrete situations (see tree, check a path, list before reading) and an 'Avoid when' clause routes to the two correct alternatives by name. This is the full when/when-not/alternative pattern.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_read_batchBatch readA
Read-only

Run up to 8 READ-ONLY ops (list_files, read_file, get_file_info, search) in one call; read/info use the cache so repeats are very fast. Use when: you need to read 2+ files/ops in the same step (reading context, scanning several files). Avoid when: there is only a single op; or you need a mutating op (use the corresponding tool). Speed: fastest for read-heavy work; sequential + cached, with a response budget. Output: read_batch: responses[] (each item is an ok/error envelope). Batch-safe: yes

NameRequiredDescriptionDefault
requestsYes
max_response_bytes_per_itemNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give readOnlyHint and openWorldHint, and the description adds real context: sequential execution, cache reuse for read/info, a response budget, and an ok/error envelope per item. It does not say what happens when one op fails (abort vs. partial success) and 'response budget' stays undefined, which is the main gap for a batch tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core capability, then labeled sections for usage, speed, and output — highly scannable with no filler sentences. 'Batch-safe: yes' is mildly redundant with readOnlyHint, but overall the text is tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With two parameters at 0% schema coverage and no output schema, the description covers the output envelope shape but leaves the per-operation argument contract and the byte-budget parameter unexplained. Adequate for choosing the tool, incomplete for invoking it correctly on the first try.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load; it names the allowed operation values but never explains the shape of `arguments` for each operation, nor what max_response_bytes_per_item does when exceeded. The 'up to 8' cap and the enum list only restate what the schema already encodes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (run up to 8 read-only ops in one call) and enumerates the four permitted operations, which cleanly separates it from the single-op siblings like project_read_file and project_search. An agent can pick it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' (2+ files/ops in the same step) and 'Avoid when' (single op, or mutating ops — use the corresponding tool) sections, with the alternative named rather than implied. That is the full when/when-not/alternative triad.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_read_fileRead fileA
Read-only

Read a text file, optionally by line range (1-based). The result carries next_start_line when truncated. Use when: you need the contents of one file, or one line range of a large file. Avoid when: you need to read 2+ files (project_read_batch) or only need metadata (project_get_file_info). Speed: very fast on repeat; cache validated by mtime+size. Output: file_read: text, first_line, last_line, total_bytes, next_start_line. Batch-safe: yes

NameRequiredDescriptionDefault
end_lineNo
max_bytesNo
start_lineNo
line_numbersNo
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true and openWorldHint=false, and the description adds useful behavior: truncation via next_start_line, repeat-speed caching validated by mtime+size, and batch-safety. It does not cover error behavior or encoding/binary handling, so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded and highly structured with labels for Use when, Avoid when, Speed, Output, and Batch-safe. Every sentence adds useful information without waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description helpfully lists the output fields and explains truncation and caching. It is nearly complete for a file-read tool, though it leaves several schema parameters under-explained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is low at 20%, and the description compensates only partially by explaining 1-based line ranges and next_start_line truncation. It does not clarify max_bytes, line_numbers, or exact inclusive/exclusive semantics for start_line/end_line.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Read a text file,' with optional line-range behavior. It clearly differentiates from siblings by naming project_read_batch and project_get_file_info for adjacent use cases.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit 'Use when' and 'Avoid when' guidance, naming the sibling alternatives for batch reads and metadata-only needs. The remaining line-range case is also scoped to a single file or one range of a large file.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_read_rangesRead file rangesA
Read-only

Read multiple disjoint line ranges of the SAME file in a single call (max 16 ranges). Use when: you need several disjoint segments of one file (e.g. around search hits) without multiple round-trips. Avoid when: you need the whole file (project_read_file) or different files (project_read_batch). Speed: fast; reuses the per-range read_file cache. Output: file_read_ranges: ranges[] with text/truncated/next_start_line. Batch-safe: no

NameRequiredDescriptionDefault
rangesYes
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the readOnlyHint/openWorldHint annotations by disclosing the range cap, cache reuse ('reuses the per-range read_file cache'), the response shape (text/truncated/next_start_line), and 'Batch-safe: no'. It stops short of covering edge behavior such as overlapping ranges or what happens when start_line exceeds file length, so it is strong but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Compact, front-loaded, and organized into labeled clauses (Use when / Avoid when / Speed / Output / Batch-safe). Each line carries information an agent needs; there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully summarizes the return shape, and read-only safety is covered by annotations. The remaining gap is parameter-level behavior for the nested range objects and how truncation/next_start_line should be followed, which an agent may still have to discover by trial.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: relative_path is documented in-schema, while the nested range fields (start_line, end_line, max_bytes) have no descriptions anywhere. The description adds the 16-range limit and mentions next_start_line in the output, but never explains that end_line/max_bytes are optional or how omitted bounds are treated, so it only partially compensates for the gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read multiple disjoint line ranges of the SAME file in a single call') with the hard cap of 16 ranges baked in. The capitalized SAME file immediately distinguishes it from project_read_batch, which handles different files.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit 'Use when' (several disjoint segments of one file, e.g. around search hits, avoiding round-trips) and 'Avoid when' clauses that name the correct alternatives by name: project_read_file for whole files and project_read_batch for multiple files. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_recent_filesRecent filesA
Read-only

List files modified most recently in the workspace (bounded filesystem scan, skips node_modules/target/.git). Use when: you need to know which files just changed, or to pick the next file to read in this session. Avoid when: you need the full list / by name (project_list_files) or content search (project_search). Speed: medium (filesystem walk); TTL cache 2s, bounded to 4000 files / 300 directories. Output: recent_files: entries[] sorted by mtime desc, scanned_files, truncated. Batch-safe: no

NameRequiredDescriptionDefault
depthNo
limitNo
relative_pathNoPath inside the workspace (relative, or absolute inside the workspace)
include_ignoredNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnlyHint/openWorldHint annotations: discloses a bounded filesystem walk, hard skip list (node_modules/target/.git), a 2s TTL cache, and scan caps of 4000 files / 300 directories. That is exactly the operational context an agent needs to interpret partial results; the 'Batch-safe: no' tag is terse but informative. It loses a point only for not clarifying what 'truncated' means in practice or how depth affects the scan bound.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose sentence followed by short labeled lines (Use when / Avoid when / Speed / Output / Batch-safe). Every line carries distinct, actionable information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even without an output schema, the description gives the return shape (recent_files entries sorted by mtime desc, scanned_files, truncated). Combined with the disclosure of skip rules, caching, and scan caps, an agent has enough to call it correctly and interpret the result. Only the undocumented optional parameters are a mild gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 25% (only relative_path is documented), so the description should compensate more than it does. The skip list and bound hint at include_ignored and depth behavior, but limit's default/max and depth's cost impact are never explained. Partial compensation justifies a middle score rather than a high one.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List files modified most recently in the workspace') plus the scope of the scan and what it skips. It explicitly names the two sibling tools it is not (project_list_files for full listing, project_search for content search), so an agent can distinguish it without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit 'Use when' (need to know which files just changed, pick next file to read) and 'Avoid when' (full list/by name -> project_list_files, content search -> project_search) clauses. Alternatives and selection conditions are named directly, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_shell_cancelShell cancelA
DestructiveIdempotent

Cancel a running shell command by run_id. Use when: the command is running too long or its result is no longer needed. Avoid when: the command already finished (check with project_shell_status). Speed: nhanh. Output: cancellation: accepted, cleanup_complete. Batch-safe: no

NameRequiredDescriptionDefault
run_idYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds genuine context beyond that: the returned status values ('cancellation: accepted, cleanup_complete') and batch behavior. The stray 'Speed: nhanh' line is a non-English artifact that muddies rather than clarifies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Short, front-loaded, and organized into labeled clauses (Use when / Avoid when / Output / Batch-safe). The 'Speed: nhanh' line is wasted space and inconsistent with the otherwise English text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description covers the return fields, so return-value expectations are set. The main remaining gap is the run_id contract, which matters for a single-param tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single required parameter, so the description should compensate. It only names run_id without explaining format, where to obtain it, or whether it must be an active run — this is the minimum needed to be usable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Cancel a running shell command') plus the identifier it keys on ('by run_id'). It is unambiguously distinguishable from siblings like project_shell_status and project_shell_run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly gives the positive trigger ('running too long or its result is no longer needed') and a negative trigger ('Avoid when: the command already finished'), and names the alternative tool project_shell_status to check first.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_shell_runShell run (async)A
Destructive

Run a shell command (cwd defaults to /app). Returns run_id immediately; use project_shell_status to get the output. Use when: build/test/lint/long-running commands; returns run_id immediately so it never blocks other tools. Avoid when: a very short command whose output you need right now (you can still run it and poll 0s). Speed: returns in ~5 ms; run time is up to the command. Output: shell_run: run_id, running, exit_code, stdout_tail/stderr_tail. Batch-safe: no

NameRequiredDescriptionDefault
shellNo
commandYes
relative_cwdNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveness, open-world, non-idempotent, non-read-only, so the safety profile is covered. The description adds genuinely new behavioral context: ~5 ms return latency, run time equal to the command, async run_id contract, output fields, batch-safety, and a default cwd. Missing timeout/pagination limits or permission notes, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Labeled sections (Use when, Avoid when, Speed, Output, Batch-safe) are front-loaded and scannable. Minor repetition: 'returns run_id immediately' appears twice, slightly blunting the conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive async shell tool with no output schema, the description explains the async flow, the output fields (run_id, running, exit_code, stdout_tail/stderr_tail), and timing. The undocumented 'shell' parameter is the main gap; timeouts and failure handling are also unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It documents 'command' implicitly and 'relative_cwd' via the '/app' default, but the 'shell' enum parameter (powershell/cmd/bash) is never mentioned in the description or schema. Partial compensation only.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Run a shell command') and immediately distinguishes its async nature from the sibling project_shell_status, which it names explicitly. An agent can tell exactly what this tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains when to use (build/test/lint/long-running commands) and when to avoid (very short commands needing immediate output), and gives the alternative flow (run then poll 0s). Explicit exclusion plus named alternative is the top bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_shell_statusShell statusA
Read-only

Check status + output of a running command. wait_seconds (0..30) is an observation window, not a timeout. Use when: after project_shell_run; poll until running=false. Avoid when: no run_id available yet. Speed: fast; not queued so it never blocks other tools. Output: shell_run: running, exit_code, stdout_tail/stderr_tail. Batch-safe: no

NameRequiredDescriptionDefault
run_idYes
wait_secondsNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint/openWorldHint annotations, it discloses that wait_seconds is an observation window rather than a timeout, that the call is fast and not queued so it never blocks other tools, and describes the output fields (running, exit_code, stdout_tail/stderr_tail). These are non-obvious behavioral traits that materially change how an agent polls.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then segmented into Use when / Avoid when / Speed / Output / Batch-safe lines. Every line carries distinct information with no repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter polling tool with no output schema, the description supplies the missing pieces: polling condition, timing semantics, non-blocking behavior, and return shape. Nothing an agent needs to call it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does for wait_seconds by explaining the observation-window semantics and the 0..30 bound. run_id is only implied by 'after project_shell_run' and the 'no run_id' exclusion rather than described directly, so it falls just short of full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Check status + output of a running command,' which distinguishes it from project_shell_run (start) and project_shell_cancel (abort). An agent can identify the tool's role without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the trigger ('after project_shell_run; poll until running=false') and the exclusion ('no run_id available yet'). The sibling it pairs with is named, and the polling loop condition is spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

project_write_fileWrite fileA
Destructive

Write a file. mode=create errors if it exists; overwrite replaces; append concatenates to the end. Use when: create a new file or replace/append a file's contents. Avoid when: only a small section needs to change (project_edit_file) to leave the rest intact. Speed: fast; clears the read/list/search cache for the affected path. Output: file_written: action, bytes_written, sha256_after. Batch-safe: no

NameRequiredDescriptionDefault
modeNo
contentYes
create_dirsNo
relative_pathYesPath inside the workspace (relative, or absolute inside the workspace)
expected_sha256No

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and non-idempotent, so the safety profile is covered; the description adds value beyond that with the cache invalidation side effect ("clears the read/list/search cache for the affected path"), the error behavior of mode=create, and the return payload (action, bytes_written, sha256_after). It also flags "Batch-safe: no", which prevents an agent from looping this in a batch call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Telegraphic, front-loaded lines with labeled sections (Use when / Avoid when / Speed / Output / Batch-safe) and zero filler. Every line carries actionable information an agent could act on.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description supplies the return shape and the cache side effect, so the main behavioral unknowns are covered. The gap is expected_sha256 and create_dirs, which matter for a destructive write tool with 20% schema coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20%, so the description must compensate: it does explain the mode enum thoroughly (create errors if exists, overwrite replaces, append concatenates), which is the highest-risk parameter. However, create_dirs and especially expected_sha256 (an optimistic-concurrency guard) get no explanation anywhere, so compensation is partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Write a file" pairs a specific verb with a specific resource, and the three mode semantics (create/overwrite/append) are spelled out so the agent knows exactly which variant of writing it is choosing. It also implicitly separates itself from project_edit_file, which appears in the same toolset.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit "Use when: create a new file or replace/append a file's contents" and "Avoid when: only a small section needs to change (project_edit_file)" names the alternative and the condition that selects it. This is the strongest possible routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 16 tool updatesv1.0.1
    • First observedproject_create
    • First observedproject_create_directory
    • First observedproject_delete_path
    • First observedproject_edit_file
    • First observedproject_get_file_info
    • First observedproject_health
    • First observedproject_list_files
    • First observedproject_read_batch
    • First observedproject_read_file
    • First observedproject_read_ranges
    • First observedproject_recent_files
    • First observedproject_search
    • First observedproject_shell_cancel
    • First observedproject_shell_run
    • First observedproject_shell_status
    • First observedproject_write_file

TDQS

A4.2/5.0

Scored across 16 tools

Disambiguation4/5

Most tools map cleanly to one resource+action, and the explicit 'Use when / Avoid when' guidance sharply separates read_file vs read_ranges vs read_batch and shell_run vs shell_status. The main overlap is project_create, which deliberately duplicates project_create_directory and project_write_file, leaving two valid paths for creating a file or directory.

Naming Consistency4/5

Nearly everything uses a project_ prefix with snake_case verb_noun (list_files, read_file, write_file, edit_file, create_directory, delete_path, shell_run). A few names drop the verb (project_search, project_recent_files, project_health, project_create), which is a minor deviation but still predictable.

Tool Count4/5

16 tools is on the heavy side but each cluster (4 read variants, 3 shell lifecycle, write/edit/create/delete, diagnostics) earns its place for a coding workspace. The one genuinely redundant entry is project_create, which re-bundles existing capabilities.

Completeness4/5

Coverage is strong: list, read, search, write, edit, mkdir, delete, async shell with status/cancel, plus self-diagnostics. The notable gaps are move/rename and copy operations, which are common in coding workflows and would otherwise force a read-write-delete workaround.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to safely read and write files in a sandboxed workspace via natural language, with on-demand connection, CVE-hardened path confinement, injection resistance, and full audit logging.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to develop within a local project workspace by reading and modifying files, running commands and tests, checking Git state, and persisting progress as history sessions that can be restored in later conversations.
    Apache 2.0
  • F
    license
    A
    quality
    A
    maintenance
    Enables coding agents to perform workspace-confined file operations, read-only Git inspection, and structured shell commands, while requiring out-of-band human approval for mutations and external executions and maintaining an audit trail.
    14
    3
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI clients to safely read, search, understand, and edit local project code and files, with Git inspection, code indexing, and controlled command execution within permissioned workspaces.
    1 npm
    6
    MIT