Skip to content

cdcabrera/mcp-server-testing

Repository files navigation

Testing MCP Server

A testing MCP server featuring persistence, Git, and other essential tools for everyday project management, writing, and coding.

Overview

The mcp-server offloads heavy tool outputs (large file reads, git diffs/show, fetched URLs, command output) into a persistent, content-addressed SQLite store. Each captured payload is identified by a SHA-256 content hash and is reachable from the client via the records://{hash} MCP resource. Project decisions (when enabled) are cross-linked to the snapshots that were captured at the moment they were recorded, so the rationale and the code state stay tied together.

Key features:

  • Content-Addressed Records: All captured payloads live in a SQLite-backed scratchpad keyed by SHA-256 hash.
  • Automatic Snapshotting: Write tools (write_files, update_file) automatically snapshot the affected files and, when project tracking is enabled, attach those hashes to a recorded decision via snapshot_id.
  • Smart Caching: Tool results are persistently memoized (mtime, size, hash-aware) so repeated queries hit cache instead of disk/git.
  • Parallel Processing: Worker threads offload heavy I/O, git, and SQLite operations so the MCP request loop stays responsive.

MCP stdio Configuration

Node.js

Requires:

{
  "mcpServers": {
    "cabrera-mcp": {
      "command": "npx",
      "args": ["-y", "@cdcabrera/cabrera-mcp@latest"],
      "description": "Persistence, Git, and other essential tools for everyday project management, writing, and coding."
    }
  }
}

Podman (Experimental, there are issues with this setup)

Requires:

Important

When running in a container, you must mount the host directory you want the server to access to the /data volume inside the container.

Feature Activation

To activate optional features (like ALLOW_WRITE, ENABLE_NODE, etc.) or configure limits (like MCP_MAX_BUFFER) when running in a container, pass them as environment variables using the -e flag:

{
  "mcpServers": {
    "cabrera-mcp": {
      "command": "podman",
      "env": {
        "PODMAN_USERNS": "keep-id"
      },
      "args": [
        "run",
        "--rm",
        "-i",
        "-v", "/path/to/your/project:/data:z",
        "-e", "ALLOW_WRITE=true",
        "-e", "ENABLE_NODE=true",
        "-e", "MCP_MAX_BUFFER=52428800",
        "--security-opt=no-new-privileges",
        "--cap-drop=ALL",
        "localhost/cabrera-mcp:latest",
        "--log-stderr"
      ],
      "description": "Persistence, Git, and other essential tools for everyday project management, writing, and coding."
    }
  }
}

Environment Variables

Variable Description Default
ROOT_DIRECTORY Root path for all filesystem operations. Access outside this path is denied. May also be passed as the first CLI argument. Current working directory
ALLOW_WRITE Set to "true" to enable the write_files and update_file tools. "false"
ENABLE_NODE Set to "true" to enable the node and npm execution tools. "false"
ENABLE_PODMAN Set to "true" to enable the podman and podman-compose execution tools. "false"
ENABLE_PROJECT Set to "true" to enable the project decision tracking tools and automatic snapshot capture on file writes. "false"
SCRATCHPAD_DB_PATH Path to the SQLite scratchpad database. Use ":memory:" for volatile storage. ":memory:"
SCRATCHPAD_DB_SIZE_LIMIT Maximum size of the persistent store in bytes. 1073741824 (1 GiB)
SCRATCHPAD_DB_PROJECT_ID Stable project identifier. Required when using persistent storage (i.e., when SCRATCHPAD_DB_PATH is a file). ""
MCP_MAX_BUFFER Maximum buffer size for process execution in bytes. 52428800 (50 MiB)

MCP Tools

Unless noted, every tool is always registered. Tools gated by an environment variable are explicitly marked.

Filesystem

  • list_directory: List directory contents with details. Supports recursive listing, tree-style output, and name-pattern filtering.
  • get_file_info: Detailed file metadata and type information via stat and file.
  • read_file: Read a file. Supports summary (metadata + peek) and full detail levels; supports jq/yq filtering for JSON/YAML when those binaries are available.
  • search_files: Recursive grep-style search across a directory for strings and content.
  • grep: grep invocation with arbitrary flags (useful for context lines, case-insensitive matching, etc.).
  • diff: Compare two files or directories using the system diff tool. Only registered when diff is available on PATH.
  • write_files (requires ALLOW_WRITE=true): Write multiple files asynchronously.
  • update_file (requires ALLOW_WRITE=true): Update a single file: full overwrite or surgical search-and-replace.

When ENABLE_PROJECT=true, write_files and update_file additionally trigger an automatic capture of the affected files into the scratchpad and record a decision row whose snapshot_id references the captured content hashes.

Git

  • git_log: Commit log. Supports summary (one-line) and full detail levels.
  • git_show: Show a commit. summary returns metadata + file list; full returns the patch. Large outputs are also captured into the scratchpad in the background.
  • git_diff: Show diff. summary returns --stat; full returns the patch. Large outputs are also captured into the scratchpad in the background.
  • git_query: Execute a read-only git subcommand (status, blame, branch, tag, ls-files, ls-tree, config, remote, rev-parse, describe, stash, grep, log, show, diff) with allow-listed flags. Destructive flags are rejected.

Fetch

  • fetch_url: Fetch content from one or more URLs in parallel. Supports summary and full detail levels.

System

  • get_system_info (registered only when ps, lsof, or netstat are available): System information such as active processes, open ports, and network status. The supported type values depend on which binaries are present.

Node / NPM (requires ENABLE_NODE=true)

  • node: Run a local node command.
  • npm: Run a local npm command.

Podman (requires ENABLE_PODMAN=true)

  • podman: Run a local podman command.
  • podman_compose: Run a local podman-compose command. Only registered when podman-compose (or podman compose) is available on PATH.

Asynchronous Tasks

  • run_async_command: Run a command in the background and return a job ID immediately. Useful for long-running tasks.
  • get_async_job_status: Get the status, stdout, stderr, and exit code of a background job.
  • stop_async_job: Forcefully stop a running background job using its jobId.
  • list_async_jobs: List all active and completed background jobs with their respective jobIds and execution statuses.

Project Decisions (requires ENABLE_PROJECT=true)

  • record_decision: Explicitly record a significant architecture/project decision or plan. Parameters: title, description, category (architectural | refactor | feature | manual, default manual). The server does not accept a diff parameter — file snapshots are linked automatically by the filesystem write tools via snapshot_id.
  • search_decisions: Search historical decisions by query, file_path, start_date / end_date, category, with limit / offset. Uses a Project ID → Project Root → Orphans fallback so history survives project renames.
  • get_decision_log: Chronological list of recent decisions. Supports category, limit, offset.
  • get_decision_entry: Retrieve a single decision and its linked record content. Accepts either id (decision row id; appends content for every linked snapshot_id hash) or hash (returns the raw record body directly). Useful for clients that do not natively support MCP resources.

MCP Prompts

Project Decisions (requires ENABLE_PROJECT=true)

  • record: Provides a template for recording decisions. Takes directions (e.g., "the plan we just went over") and instructs the model to use record_decision to document it, inferring the title, rationale, and category from the conversation context.

MCP Resources

Content-Addressed Records and Context

Three resource templates are registered to retrieve scratchpad records and runtime configuration details:

  • records://{hash}: Resolves to the decoded body of a specific scratchpad record by its content hash.
  • records://{id}: Resolves to the decoded body of a specific scratchpad record by its metadata ID.
  • records://context (Registered as project-context): Yields general information, limits, and runtime environment settings of the running MCP server.

Background Job Results

  • results://{jobId}: Resolves to the current status and captured output (stdout/stderr) of a specific background job.
  • jobs://list (Registered as async-jobs-list): Resolves to a structured text listing of all active and recently executed background jobs.

Records are produced automatically by:

  • Filesystem writes (write_files, update_file) capturing the touched files.
  • Background ingestion in git_show / git_diff when their summary form is requested.
  • Any tool path that calls into the scratchpad (loadFromFile, loadFromCommand, etc.).

When ENABLE_PROJECT=true, the comma-separated hashes captured during a write are stored in project_decisions.snapshot_id and can be replayed through get_decision_entry or directly through the records:// resource.

Testing with MCP Inspector

The @modelcontextprotocol/inspector is the recommended way to visualize the server's interface.

  1. Build the MCP:
    npm install
    npm run build
  2. Start the Inspector:
    npx -y @modelcontextprotocol/inspector node dist/index.js
  3. Interact: The inspector opens a web interface (typically at http://localhost:5173) where you can list tools, resources, and prompts, then execute and view their responses.

Security

  • Path isolation: Every filesystem and git operation is resolved against ROOT_DIRECTORY; any path that escapes the root is rejected.
  • Injection protection: Prepared statements for all SQLite access; execFile (never shell) with allow-listed arguments for child processes; git_query rejects destructive flags.
  • Non-blocking architecture: Heavy I/O, git, and SQLite work runs in worker threads so MCP requests stay responsive.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors