Read-oriented local workspace MCP server — bounded filesystem, git and named-task tools over authorized roots
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Documented (README)
git clone https://github.com/peter4leadson/local-workspace-mcp{
"mcpServers": {
"local-workspace-mcp": {
"command": "node",
"args": ["/path/to/local-workspace-mcp/dist/index.js"]
}
}
}Resumen de MCP Servers
# local-workspace-mcp
Your AI assistant needs context. It does not need unrestricted access.
A read-oriented MCP server for local workspaces. Write, delete, and
arbitrary-shell tools do not exist in it. Not gated or disabled: absent. Every
filesystem path is checked against operator-authorized roots and a
default-deny list for secrets, `.env` files, private keys, and `.git`
internals. Git read tools and operator-declared named tasks provide
bounded capability without giving the model a shell.
- **14 tools** over stdio JSON-RPC: bounded filesystem reads/searches,
read-only git (status/diff/log/show/branches), and `task_run` for
explicitly allowlisted commands.
- **One transport:** each MCP host spawns `workspace-mcp serve --stdio`.
No inbound listener, no daemon; the server itself makes no network calls
(allowlisted tasks run as your user and are not network-restricted).
- **Honest scope:** `task_run` executes real commands as your user. The
allowlist bounds _what can be invoked_, not what invoked code can do.
It is not a sandbox.
Evaluating this for team use? Start at [docs/THREAT-MODEL.md](docs/THREAT-MODEL.md)
and [SECURITY.md](SECURITY.md).
## The problem
Hosts' built-in file tools are convenient but live in the client's
permission loop, the same loop users bypass out of fatigue
(`--dangerously-skip-permissions`, "yes to everything"). The official
`@modelcontextprotocol/server-filesystem` ships read **and** write tools
with no default secrets denylist, and has already overwritten a user's
`.env` ([upstream issue #1869](https://github.com/modelcontextprotocol/servers/issues/1869)). Generic filesystem MCPs give a model file
access; they do not give it _bounded_ access.
This server moves the boundary server-side: roots, deny rules, task
allowlists, and audit live in an operator config that repository content
cannot widen. A compromised or bypassed prompt loop cannot invoke a tool
that does not exist.
## Quick start
Requires Node ≥ 20, plus `git` for `git_*` tools and ripgrep (`rg`) for
content search. Building from a clone needs pnpm (`corepack enable`).
```sh
npm install -g local-workspace-mcp # puts workspace-mcp on PATH
# or from a clone:
pnpm install && pnpm build && npm link
workspace-mcp init-config # writes ~/.config/local-workspace-mcp/config.json (mode 600)
$EDITOR ~/.config/local-workspace-mcp/config.json # replace the example workspace (below)
workspace-mcp doctor # must print "doctor: ALL GREEN" (use --json for CI)
```
The generated config ships a placeholder workspace named `example` —
replace it with a real root or `doctor` will report `root.example` FAIL.
A healthy run ends:
```text
PASS policy.selftest — 9/9 cases correct
PASS mcp.startup — tool registration ok
doctor: ALL GREEN
```
Minimal working config (strict JSON — no comments or trailing commas):
```json
{
"version": 1,
"workspaces": {
"myproj": { "path": "/absolute/path/to/repo", "tasks": [] }
},
"tasks": {},
"deny": []
}
```
Then connect a host (below), confirm it registered (`claude mcp list`,
`/mcp`, or your host's equivalent), and ask: _"use workspace_roots, then
fs_list on myproj"_. First useful call sequence: `fs_list` → `git_status`
→ `git_diff` on uncommitted work, where a chat client otherwise
has no eyes.
## Usage examples
```text
# what the assistant can ask for
workspace_roots # authorized workspace ids, no host paths
fs_list {workspace:"myproj"}
fs_read {workspace:"myproj", path:"src/index.ts", startLine:1, maxLines:120}
fs_search_content {workspace:"myproj", query:"TODO"} # literal; regex:true for rg syntax
git_status {workspace:"myproj"} # branch, HEAD, uncommitted truth
git_diff {workspace:"myproj"} # worktree diff, bounded output
git_show {workspace:"myproj", spec:"HEAD"}
task_list {workspace:"myproj"}
task_run {workspace:"myproj", taskId:"typecheck"}
```
Denied behavior is explicit, never silent:
```text
fs_read {workspace:"myproj", path:".env"} → ACCESS_DENIED (or NOT_FOUND if absent)
fs_read {workspace:"myproj", path:"../../etc/passwd"} → OUTSIDE_ROOT
task_run {workspace:"myproj", taskId:"nuke"} → TASK_DENIED (valid id, not enabled)
task_run {workspace:"myproj", taskId:"rm -rf /"} → INVALID_ARGUMENT (malformed task id)
git_show {workspace:"myproj", spec:"--exec"} → INVALID_ARGUMENT
```
Denial codes are the policy working as intended, not errors to report;
widening access happens only in the operator config. Task/search timeouts
and output limits return `timedOut:true`/`truncated:true` in a normal
result rather than an error. `INTERNAL_ERROR` covers spawn/tool failures and should not
appear in healthy use; `git_*` on a non-git root returns `{repo:false}`
gracefully.
## Tool surface
All 14 tools, annotated `readOnlyHint` where true (hosts can auto-approve
pure reads). `task_run` is the only tool with side effects.
| Tool | Scope | Notes |
| ------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `workspace_roots` | reads config | workspace ids + availability; never host paths |
| `fs_list` | one directory | bounded, paginated; denied entries flagged by class |
| `fs_stat` | one path | metadata; symlink resolution disclosed |
| `fs_read` | one file | line-range, byte-capped; binary refused |
| `fs_read_many` | batch | per-file inline errors, total cap |
| `fs_search_files` | filenames | glob; git file universe where a repo exists (honors .gitignore at the repo toplevel); bounded directory walk otherwise |
| `fs_search_content` | file contents | ripgrep `--json`; literal or `regex:true`; time/count bounded |
| `git_status` | repo | branch, HEAD, staged/modified/deleted/renamed/untracked |
| `git_diff` | repo | worktree/staged/ref diff; bounded; denied paths redacted |
| `git_log` | repo | ≤100 commits |
| `git_show` | repo | commits/tags and `ref:path` blobs; strict ref validation |
| `git_branches` | repo | branches, upstreams, worktrees (host paths redacted) |
| `task_list` | config | task ids enabled per workspace |
| `task_run` | subprocess | allowlisted argv only; `shell:false`; caps on time/output |
## Supported hosts
| Host | Mechanism | Status |
| ----------------------- | ------------------------------------------------------------------------------------------------------------ | ---------- |
| Claude Code | `claude mcp add local-workspace --scope user -- workspace-mcp serve --stdio`; confirm with `claude mcp list` | verified |
| Claude Desktop | `mcpServers` entry in `claude_desktop_config.json`; restart app | configured |
| Codex CLI | `mcp_servers` stdio entry in `~/.codex/config.toml` | supported |
| ChatGPT / Responses API | OpenAI Secure MCP Tunnel (`openai/tunnel-client`, outbound-only) | verified |
| MCP Inspector | `scripts/inspector-smoke.sh` battery, 17 checks | verified |
GUI hosts (Claude Desktop especially) spawn servers with a minimal PATH,
not your shell's. If a host reports ENOENT or stays disconnected while
`doctor` is green, the binary is not on the host's PATH. Use the absolute
path (`which workspace-mcp`) as the command and check the host's MCP log.
Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`
on macOS):
```json
{
"mcpServers": {
"local-workspace": {
"command": "/absolute/path/to/workspace-mcp",
"args": ["serve", "--stdio"]
}
}
}
```
Codex CLI (`~/.codex/config.toml`, or `codex mcp add`):
```toml
[mcp_servers.local-workspace]
command = "/absolute/path/to/workspace-mcp"
args = ["serve", "--stdio"]
```
For ChatGPT, `tunnel-client` polls an outbound HTTPS path and spawns the
stdio command locally; no inbound network listener opens. (tunnel-client
can optionally bind a loopback-only health endpoint — see OPERATIONS.)
Operator runbook: [docs/OPERATIONS.md](docs/OPERATIONS.md).
## Permission model
- **Roots are explicit.** Nothing outside `workspaces[].path` is reachable;
`~`, control characters, Windows drive paths, and `..` traversal are
rejected before any syscall, and again after `realpath`. Point roots at
the projects you actually work on; never authorize `~/` or a parent
directory that contains things the assistant should not read.
- *Lo que la gente pregunta sobre local-workspace-mcp
¿Qué es peter4leadson/local-workspace-mcp?
+
peter4leadson/local-workspace-mcp es mcp servers para el ecosistema de Claude AI. Read-oriented local workspace MCP server — bounded filesystem, git and named-task tools over authorized roots Tiene 0 estrellas en GitHub y su última actualización registrada es del 2026-10-09.
¿Cómo se instala local-workspace-mcp?
+
Puedes instalar local-workspace-mcp clonando el repositorio (https://github.com/peter4leadson/local-workspace-mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar peter4leadson/local-workspace-mcp?
+
Nuestro agente de seguridad ha analizado peter4leadson/local-workspace-mcp y le ha asignado un Trust Score de 87/100 (tier: Trusted). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene peter4leadson/local-workspace-mcp?
+
peter4leadson/local-workspace-mcp es mantenido por peter4leadson. La última actividad registrada en GitHub es del 2026-10-09, con 0 issues abiertos.
¿Hay alternativas a local-workspace-mcp?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega local-workspace-mcp en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/peter4leadson-local-workspace-mcp)<a href="https://claudewave.com/repo/peter4leadson-local-workspace-mcp"><img src="https://claudewave.com/api/badge/peter4leadson-local-workspace-mcp" alt="Featured on ClaudeWave: peter4leadson/local-workspace-mcp" width="320" height="64" /></a>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
The fastest path to AI-powered full stack observability, even for lean teams.