Skip to main content
Glama
bhawnapannu2701

workbench-mcp

workbench-mcp

workbench-mcp is a Python FastMCP server for controlled local workspace inspection, bounded file reads/searches, guarded text patching, allowlisted test execution, read-only Git status, approved artifact collection, and workspace diagnostics.

It is intended for developer workbenches where an MCP client needs useful repository context without receiving unrestricted filesystem or shell access.

Problem Statement

AI-assisted development tools often need to inspect files, run tests, and collect reports. Giving those tools raw shell access or broad host filesystem access is risky. This project wraps common development actions in typed MCP tools backed by explicit workspace, artifact, command, timeout, output, and redaction controls.

Related MCP server: AI Knowledge Center MCP

Project Status

Status: v0.1.0 release preparation on branch codex/workbench-mcp-v1.

Implemented and locally verified:

  • stdio FastMCP server startup.

  • In-memory and stdio MCP client/server smoke tests.

  • Docker image build, direct container smoke test, Compose config, and Compose smoke workflow.

  • Reproducible public demo that creates a temporary Git workspace and writes a JSON report.

  • GitHub Actions CI is green for the latest pushed Phase 7 commit 34fc81ae32e4404f01f3f460b43e6508e108421d in run 29778875177.

  • Local final-audit fixes after that pushed commit require a new CI run after push.

Not implemented:

  • HTTP or Streamable HTTP transport for this project.

  • Complete arbitrary-code execution sandboxing.

  • Package publishing, Docker image publishing, Git tags, or GitHub releases.

Feature Overview

  • Workspace metadata through workspace_info.

  • Directory listing and UTF-8 text reads bounded to WORKSPACE_ROOT.

  • Text search with glob, case-sensitivity, result, and output limits.

  • One guarded expected-content text replacement through apply_patch when READ_ONLY_MODE=false.

  • Allowlisted command execution using argument arrays and shell=False.

  • Named predefined test commands with JSON reports under the artifact root.

  • Read-only Git status using non-mutating Git commands.

  • Approved artifact collection from category-specific artifact directories.

  • Diagnostic findings for workspace, artifact, executable, Git, and transport state.

  • Secret-pattern and host-root redaction before MCP-facing responses.

Architecture

flowchart TD
    Client["MCP client"] --> Transport["FastMCP stdio transport"]
    Transport --> Server["workbench_mcp.server.create_server"]
    Server --> ToolLayer["Typed MCP tool/resource layer"]
    ToolLayer --> Services["Service layer"]
    Services --> Config["Validated WorkbenchConfig"]
    Services --> Security["Security helpers"]
    Security --> Workspace["WORKSPACE_ROOT boundary"]
    Security --> Artifacts["ARTIFACT_DIRECTORY boundary"]
    Services --> Process["subprocess with shell=False"]
    Services --> Git["read-only git status"]
    ToolLayer --> Errors["safe ToolError conversion and redaction"]

More detail: docs/architecture.md.

Registered MCP Tools

These are the exact tool names registered by src/workbench_mcp/tools/common.py and verified by tests/unit/test_mcp_server.py.

Tool

Inputs

Behavior

workspace_info

none

Returns sanitized workspace metadata, read-only status, limits, capabilities, and Git summary.

list_files

relative_directory=".", max_depth=2, pattern=null, max_results=1000

Lists workspace-contained files/directories/symlinks with depth and result limits.

read_file

relative_path, optional start_line, optional line_count

Reads a workspace-contained UTF-8 text file within size limits.

search_text

query, relative_directory=".", glob=null, case_sensitive=false, result_limit=100, max_output_bytes=null

Searches workspace text files with output and result bounds.

apply_patch

relative_path, expected_content, replacement_content

Replaces exactly one expected text block when writes are enabled.

run_command

command, cwd="."

Runs an allowlisted executable with argument-array execution.

run_tests

test_name

Runs a configured named test command and writes a test report.

git_status

none

Returns branch, staged/modified/untracked files, and diff statistics without mutating Git state.

collect_artifact

category, relative_path

Reads approved text artifacts from test_report, coverage_report, structured_log, or diagnostic_report.

diagnose_workspace

none

Returns structured findings with severity, evidence, probable cause, and remediation.

No destructive Git tools, delete-file tools, shell tools, or unrestricted command tools are registered.

Server-Information Resource

Exact resource registration:

Field

Value

Name

server_info

URI

workbench://server-info

MIME type

application/json

Payload keys returned by server_information_payload:

{
  "package_version": "0.1.0",
  "server_capabilities": {
    "workspace_inspection": true,
    "filesystem_read": true,
    "text_search": true,
    "controlled_text_patch": false,
    "allowlisted_commands": [],
    "predefined_tests": [],
    "git_status": true,
    "artifact_collection": true,
    "diagnostics": true
  },
  "registered_tool_names": [
    "workspace_info",
    "list_files",
    "read_file",
    "search_text",
    "apply_patch",
    "run_command",
    "run_tests",
    "git_status",
    "collect_artifact",
    "diagnose_workspace"
  ],
  "active_safety_limits": {
    "max_file_size_bytes": 1048576,
    "max_command_seconds": 30,
    "max_output_bytes": 1048576
  },
  "read_only_status": true,
  "sanitized_workspace_metadata": {
    "name": "workbench-mcp",
    "exists": true,
    "is_directory": true
  },
  "supported_transports": ["stdio"]
}

Values reflect the active configuration. The tool list and supported transports are fixed for this release.

Installation With uv

Install uv, then install the locked project environment:

uv sync --frozen --all-groups
uv run python --version
uv run workbench-mcp --version

On this Windows verification shell, bare uv is not on PATH; the equivalent verified command prefix is:

& $env:APPDATA\Python\Python313\Scripts\uv.exe run python --version

Configuration Reference

Configuration loads from defaults, optional TOML via WORKBENCH_MCP_CONFIG, and environment variables. Environment variables override TOML values.

Environment variable

TOML key

Default

Notes

WORKBENCH_MCP_CONFIG

N/A

unset

Optional TOML file path. The file may contain a [workbench_mcp] table or top-level keys.

WORKSPACE_ROOT

workspace_root

current working directory

Must exist and be a directory. All workspace paths must resolve inside it.

READ_ONLY_MODE

read_only_mode

true

Blocks apply_patch when true.

MAX_FILE_SIZE_BYTES

max_file_size_bytes

1048576

Range: 1 to 100000000. Applies to text file reads/search inputs.

MAX_COMMAND_SECONDS

max_command_seconds

30

Range: 1 to 600. Applies to subprocess execution.

MAX_OUTPUT_BYTES

max_output_bytes

1048576

Range: 1 to 100000000. Applies to command and artifact output.

ALLOWED_COMMANDS

allowed_commands

empty

Comma-separated executables such as python,pytest, or JSON objects with name, executable, and optional default_args. Executables must be bare names.

TEST_COMMANDS

test_commands

empty

JSON list of objects with name and command, for example [{"name":"unit","command":["pytest","tests/unit"]}].

ARTIFACT_DIRECTORY

artifact_directory

artifacts under workspace root

Must exist and be a directory. Artifact collection is category-bounded inside it.

SECRET_PATTERNS

secret_patterns

one token/password/API-key regex

JSON list of regex strings or comma-separated regex strings.

LOG_LEVEL

log_level

INFO

One of DEBUG, INFO, WARNING, ERROR, CRITICAL.

Example TOML:

[workbench_mcp]
workspace_root = "."
read_only_mode = true
max_file_size_bytes = 1048576
max_command_seconds = 30
max_output_bytes = 1048576
allowed_commands = [{ name = "python", executable = "python" }]
test_commands = [{ name = "smoke", command = ["python", "-c", "print('ok')"] }]
artifact_directory = "artifacts"
secret_patterns = ["(?i)(api[_-]?key|token|secret|password)\\s*[:=]\\s*[^\\s]+"]
log_level = "INFO"

Verified Stdio Quick Start

For an MCP client, configure stdio with:

{
  "command": "uv",
  "args": ["run", "workbench-mcp", "--transport", "stdio"],
  "env": {
    "WORKSPACE_ROOT": "/path/to/workspace",
    "ARTIFACT_DIRECTORY": "/path/to/workspace/artifacts",
    "READ_ONLY_MODE": "true"
  }
}

Local stdio verification command:

uv run pytest tests/e2e/test_mcp_stdio.py

Do not configure HTTP ports for this project; HTTP is not implemented or tested here.

Verified Docker Quick Start

Build and smoke-test the local image:

docker build -t workbench-mcp:local .
uv run python scripts/run-container-smoke.py --image workbench-mcp:local

Compose smoke workflow:

mkdir -p .workbench-demo/workspace .workbench-demo/artifacts
printf 'hello compose\n' > .workbench-demo/workspace/smoke.txt
docker compose config
docker compose run --rm --build workbench-mcp-smoke

PowerShell equivalent for the mount preparation:

New-Item -ItemType Directory -Force .workbench-demo\workspace, .workbench-demo\artifacts | Out-Null
Set-Content -LiteralPath .workbench-demo\workspace\smoke.txt -Value "hello compose"

The container defaults to stdio, non-root UID/GID 10001:10001, no published ports, no host networking, no Docker socket mount, dropped Linux capabilities in Compose, and no-new-privileges:true in smoke workflows.

Demo

Run the public reproducible demo:

uv run python scripts/run-demo.py

The demo creates a temporary Git workspace, writes deterministic files, configures the real server, invokes the MCP tools through a FastMCP client, runs an approved test, applies one controlled patch, demonstrates a blocked traversal attempt, writes artifacts/demo/workbench-demo-report.json, prints a short summary, and cleans up the temporary workspace.

Testing Commands

uv run ruff format --check .
uv run ruff check .
uv run mypy src
uv run pytest -rs
uv run pytest --cov=workbench_mcp --cov-report=term-missing
uv build
uv run pytest tests/e2e/test_mcp_stdio.py
uv run python scripts/run-demo.py

Docker checks:

docker build -t workbench-mcp:local .
uv run python scripts/run-container-smoke.py --image workbench-mcp:local
docker compose config
docker compose run --rm --build workbench-mcp-smoke

Security Model

  • Deny by default for commands and writes.

  • Workspace paths are resolved with pathlib and must remain inside WORKSPACE_ROOT.

  • Artifact paths are resolved inside category directories under ARTIFACT_DIRECTORY.

  • Symlink escapes, parent traversal, absolute-path escapes, oversized files, binary text reads, shell operators, executable paths, command timeouts, bounded output capture, and truncation are covered by source checks and tests.

  • Expected service errors are converted to sanitized MCP ToolError messages.

  • Git behavior is read-only, bounded by the configured command timeout/output limit, and disables external diff execution for diff-stat inspection.

  • Docker smoke workflows use a non-root runtime user and avoid privileged mounts.

This is not a complete arbitrary-code execution sandbox. Allowlisting a powerful executable such as python, pytest, or git still grants that executable whatever behavior it can perform inside the configured workspace and OS permissions.

More detail: docs/threat-model.md and SECURITY.md.

Known Limitations

  • Only stdio transport is implemented and verified.

  • HTTP and Streamable HTTP are not configured, exposed, or tested by this project.

  • The server relies on host OS permissions; it is not a VM, kernel sandbox, or container escape prevention system.

  • Windows symlink security tests skip when the OS denies symlink creation with WinError 1314; Linux CI runs those tests explicitly.

  • Command safety depends on narrow allowlists. Do not allowlist broad interpreters for untrusted workspaces unless the surrounding environment is disposable.

  • Artifact collection supports approved text suffixes only.

  • Docker and Compose smoke workflows are finite verification commands, not a long-running hosted service.

Troubleshooting

  • uv not found: install uv or use the full uv.exe path on Windows as shown above.

  • workspace_root does not exist: set WORKSPACE_ROOT to an existing directory.

  • artifact_directory does not exist: create the directory or set ARTIFACT_DIRECTORY.

  • writes are blocked because READ_ONLY_MODE is enabled: set READ_ONLY_MODE=false only for workspaces where controlled patching is acceptable.

  • executable is not allowlisted: add a bare executable name to ALLOWED_COMMANDS.

  • Docker bind-mount permission failures on Linux: run smoke workflows with a host-compatible UID/GID, as documented in docs/runbook.md.

  • HTTP port questions: there is no project HTTP listener in this release.

Evidence And Docs

Available Tools

3 tools
list_filesC

List files in a workspace-contained directory.

ParametersJSON Schema
NameRequiredDescriptionDefault
patternNo
max_depthNo
max_resultsNo
relative_directoryNo.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior2/5

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

With no annotations provided, the description bears full responsibility for disclosing behavioral traits. It only states 'list files', omitting whether the operation is read-only, whether it requires permissions, the scope depth, or any side effects. The presence of an output schema is not leveraged to clarify return behavior.

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

Conciseness3/5

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

The description is a single, short sentence with no wasted words. However, it is under-specified for a tool with 4 parameters and no schema descriptions, making conciseness come at the cost of completeness.

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

Completeness1/5

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

Given the tool has 4 parameters, no schema descriptions, and an output schema, the description is critically incomplete. It fails to explain parameter behavior, return values, or usage context, making it inadequate for effective agent invocation.

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

Parameters1/5

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

Schema description coverage is 0%, and the description adds no meaning to any of the 4 parameters (pattern, max_depth, max_results, relative_directory). It fails to clarify their roles, defaults, or constraints, leaving the agent to rely solely on the schema's field names and types.

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?

The description clearly states the verb 'list' and resource 'files', and specifies the scope 'workspace-contained directory', distinguishing it from siblings like 'read_file' (reads a single file) and 'workspace_info' (workspace-level info). However, 'workspace-contained directory' is slightly vague, lacking specificity about whether it lists recursively or the root directory.

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

Usage Guidelines2/5

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

No guidance is given on when to use this tool versus its siblings (read_file, workspace_info). The description does not mention prerequisites, context, or alternatives, leaving the agent to infer usage from the name alone.

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

read_fileC

Read a workspace-contained UTF-8 text file.

ParametersJSON Schema
NameRequiredDescriptionDefault
line_countNo
start_lineNo
relative_pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior2/5

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

No annotations are present. The description does not disclose behavioral traits such as error handling (e.g., file not found), permissions required, or that reading may be restricted. It merely states the basic function without beyond what is obvious.

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

Conciseness3/5

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

The description is a single concise sentence with no fluff. However, it is overly brief, sacrificing essential information for brevity. It earns its place but could be more informative.

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

Completeness2/5

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

Given the presence of an output schema and sibling tools, the description is incomplete. It fails to explain the partial reading feature, return format, or any edge cases. The minimal description does not cover the complexity of three parameters.

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

Parameters1/5

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

The schema has 0% coverage with no parameter descriptions. The tool description does not explain any of the three parameters (relative_path, start_line, line_count), leaving the agent without guidance on how to use them meaningfully.

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?

The description clearly states the action (Read) and resource (a workspace-contained UTF-8 text file). It specifies encoding and scope, distinguishing it from siblings like list_files (which lists files) and workspace_info (which provides workspace metadata), though it does not explicitly differentiate.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool vs alternatives, or any prerequisites. The description lacks context for appropriate usage, leaving the agent to infer from the name alone.

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

workspace_infoA

Return sanitized workspace and server capability information.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior2/5

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

No annotations provided; description only says 'sanitized' without explaining what that entails, and lacks disclosure of auth needs or rate limits.

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?

Single sentence, no extraneous words, efficiently communicates purpose.

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 output schema covering return values, description is mostly complete, though 'sanitized' could be elaborated.

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?

No parameters exist (100% schema coverage), so description need not add param info; baseline 4 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?

Description clearly states the tool returns workspace and server capability information, distinguishing it from sibling tools that handle file operations.

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

Usage Guidelines3/5

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

Implicitly useful for getting workspace info, but no explicit guidance on when to use or alternatives beyond sibling tool names.

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. 3 tool updatesv0.1.0
    • First observedlist_files
    • First observedread_file
    • First observedworkspace_info

TDQS

B3.1/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing files, reading a file, and returning workspace information. No ambiguity or overlap.

Naming Consistency5/5

All tools follow a consistent verb_noun snake_case pattern (list_files, read_file, workspace_info), making them predictable and easy to understand.

Tool Count4/5

Three tools is minimal but reasonable for a focused workspace file server. The count feels slightly low but not problematic given the apparent scope.

Completeness2/5

The set covers listing and reading files but lacks write, delete, or directory operations, leaving significant gaps for typical file management workflows.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A local-first MCP server providing guarded access to a workspace with file operations, search, commands, tests, Git helpers, checkpoints, and structured tool results. It supports multiple tool modes and emphasizes security with workspace restrictions and secret blocking.
    1
    MIT