workspace-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MCP_TOKEN | No | Bearer token for HTTP authentication. When set, every HTTP request must send `Authorization: Bearer <token>` or gets 401. Use a long random token for security. | |
| WORKSPACE_MCP_SHELL | No | Enable command execution tools (run_command, start_job, job_kill) in allowlist mode. Set to '1' or 'true' to enable. | false |
| WORKSPACE_MCP_JOB_DIR | No | Directory for background job logs. Defaults to system temp directory under workspace-mcp-jobs. | |
| WORKSPACE_MCP_SHELL_MODE | No | Set shell execution mode. 'allowlist' (default) or 'any'. Setting this also enables the shell tools. If 'any', unrestricted execution is allowed (implies allowlist mode). | |
| WORKSPACE_MCP_SHELL_ALLOW | No | Comma-separated list of executables to add to the shell allowlist (e.g., 'git,docker'). Only used when shell is enabled. | |
| WORKSPACE_MCP_JOURNAL_MAX_BYTES | No | Maximum size in bytes for journal and notes files before rotation. Default 5242880 (5 MiB). | 5242880 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| workspace_listA | Read-only list of the named project workspaces served by this process: name, absolute root path, which one is primary, whether it already has workspace state under .workspace-mcp/, and the id of its active change when state.json exists. Every path or state tool accepts an optional workspace argument (defaults to the primary workspace), so call this first to discover the available names. |
| read_fileA | Read a UTF-8 text file from the workspace and return its content with 1-based line numbers in the form 'N: '. Use this before editing a file, or to inspect specific line ranges with offset/limit. Do not use it for binary files (they are rejected), to search file contents (use grep), or to discover files (use list_files). |
| write_fileA | Create a file (parent directories are created automatically) or overwrite an existing file with exactly the given content. Use this for new files or full rewrites. Prefer edit_file or patch for targeted changes to existing files, because this tool replaces the whole file and is not reversible. The file is written to disk immediately. |
| edit_fileA | Replace an exact string in an existing text file. The oldString must match the file content exactly, including whitespace and indentation. If oldString appears more than once, either add more surrounding context to make it unique or set replaceAll=true. Read the file first with read_file. The change is written to disk immediately and is not reversible. For several files or several changes at once, prefer patch so all edits succeed or none are applied. |
| patchA | Apply several exact-string edits across one or more files in a single all-or-nothing operation. Every edit is validated against the current file contents first; if any edit fails, NO file is modified and the failing edit index is reported. Use this instead of several edit_file calls when changes belong together. Read the affected files first with read_file. Changes are written to disk immediately when all edits are valid. |
| grepA | Search file contents in the workspace with a JavaScript regular expression and return matches as 'relative/path:LINE: '. Use this to find where a symbol, string or pattern appears. Narrow the search with path and include. Skips binary files and the .git, node_modules and .cache directories. Do not use it to list files (use list_files) or to read a known file (use read_file). |
| list_filesA | List files and directories inside the workspace, sorted by workspace-relative path. Directories are marked with a trailing '/'. Use this to discover what exists before reading or editing, optionally filtered with a glob pattern. Skips the .git, node_modules and .cache directories and does not follow symbolic links. Do not use it to read content (use read_file) or to search text (use grep). |
| work_logA | Read the automatic activity journal of this workspace: a newest-first list of the mutating operations this server performed (write_file, edit_file, patch, run_command, start_job, job_kill) plus the change-tracking operations (change_create, change_activate, change_doc, task_add, task_update, constraint_add), each with timestamp, paths, a short detail and the outcome. Entries made while a change was active carry a change tag, so the log can be scoped to one change. Call it at the start of a session to recover what happened in previous chats. Read-only operations (read_file, grep, list_files, work_log itself, recall, git tools, change_status) are never journaled. Filter with since, path and change; use recall to read the deliberate notes saved with remember. |
| rememberA | Save a short persistent note for this workspace so any future chat can recover it with recall. Use it after finishing a chunk of work: record what changed, what should happen next, or a decision that must survive the conversation. Notes are append-only JSONL stored under /.workspace-mcp/ and are never edited or deleted by this tool. Keep each note short and self-contained; use tags for later filtering. |
| recallA | Read the persistent notes saved with remember for this workspace, newest first. Call it at the start of a session together with work_log to recover context from previous chats. Filter by free-text query (case-insensitive substring) and/or tag. This tool is read-only; use work_log for the automatic activity journal instead. |
| git_statusA | Read-only git status of the workspace: runs 'git status --porcelain=v1 -b' without a shell (LC_ALL=C, 10 s timeout) and returns a 'branch: ...' header followed by the porcelain lines exactly as git prints them. A clean tree reports 'working tree clean'. A directory that is not a git repository or a missing git binary is reported as a clear error. No --shell flag is needed for this tool. |
| git_diffA | Read-only git diff of the workspace: runs 'git diff' without a shell (LC_ALL=C, 30 s timeout) and returns the patch text. Use staged=true for the index (--cached), stat=true for a diffstat (--stat), and path to limit the diff to one workspace-relative file (passed after '--'). Reports '(no changes)' when the diff is empty. Output longer than 64 KiB keeps the first 32 KiB and the last 32 KiB. No --shell flag is needed for this tool. |
| change_createA | Create a tracked change (the unit of work) and make it the active change. A change is a JSON record plus a directory that holds its stage documents (proposal.md, spec.md, design.md, notes.md) written on demand with change_doc. Use it to track multi-step work so any future chat can re-orient with a single change_status call. The id is a kebab-case slug of the title, deduplicated with -2, -3, ... on collision. Next step: write the proposal with change_doc, then break the work into tasks with task_add. |
| change_activateA | Make an existing change the active one. While a change is active, every journal entry written by mutating operations is tagged with its id, and the change tools default to it. Returns a short summary of the change. |
| change_docA | Write one stage document of a change: proposal, spec, design or notes. By default the document is replaced; with append: true the new content is appended after a blank line. Documents live under /.workspace-mcp/changes//.md and can be written in any order, on demand. Returns the workspace-relative path and which stage documents exist. |
| change_statusA | Read-only orientation call: the single way to re-orient on tracked work at the start of any chat. Without arguments it renders the active change in full: title, goal, stage documents present or missing, tasks grouped by status, constraints, the last ten journal entries tagged with the change, and a derived suggested next action. With all: true (or with no active change) it lists every change newest-first with done/total task counts. Never writes state and is never journaled. |
| task_addA | Append one task to a change. Task ids are sequential (T1, T2, ...). The task starts as pending unless another status is given. Use task_update to move a task between statuses. |
| task_updateA | Update the status of one or more tasks in a single all-or-nothing write: every taskId is validated before anything is stored, so one unknown id leaves the change untouched and the error lists the bad entries. An optional note is appended to the task's notes. One aggregate journal entry is written. |
| constraint_addA | Append one constraint to a change: a rule, limit or requirement that the work must respect (for example 'no new runtime dependencies'). Constraints are shown by change_status so later chats do not have to re-ask. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 19 tools
Every tool targets a distinct operation: file read/write/edit/patch/list/grep are clearly separated, work_log is distinguished from remember/recall, and each change/task tool has a unique role. The closest pair is edit_file vs patch, but their single-edit vs atomic-multi-edit scopes are explicitly documented.
Most file tools use verb_noun style (read_file, write_file, edit_file, list_files), while change and task tools reverse it (change_create, task_add, constraint_add), and standalone names appear (patch, grep, git_status). The naming is readable and grouped by domain, but the mixed verb placement makes the pattern less predictable.
19 tools is on the upper end, but the server spans four distinct subdomains—file editing, persistent memory, git inspection, and change/task tracking—and each tool has a separate responsibility. The count feels slightly heavy rather than bloated, with no true redundancy.
The file surface covers list/read/write/edit/patch/grep but lacks a delete or rename operation, leaving cleanup workflows with a dead end. Change tracking supports create/status/document/task updates but has no way to remove a change or constraint. These are notable, work-around-able gaps rather than a total lack of coverage.