Skip to main content
Glama
Asutorufa
by Asutorufa

Workspace Bridge

Workspace Bridge is a single-user, Linux-first MCP server for giving ChatGPT controlled access to local development projects.

It runs locally and exposes only registered projects. It supports both Streamable HTTP and stdio MCP transports. An OpenAI Secure MCP Tunnel client can start the stdio command directly, without a separate HTTP service process.

Quick start

npm install
npm run build
npm run start

npm run start listens on 127.0.0.1:3001 and exposes:

  • GET /health

  • MCP Streamable HTTP at /mcp

When the server listens on loopback (the default), the MCP endpoint does not require a Bearer token. This is the intended setup for a local OpenAI Secure MCP Tunnel client.

For a stdio MCP client, build the project and start the stdio entrypoint:

npm run build
npm run stdio

The stdio entrypoint writes only MCP JSON-RPC messages to stdout. Keep logs and diagnostics on stderr so the transport remains valid.

If you intentionally bind the server to a non-loopback address, configure a Bearer token before starting it:

node dist/cli.js auth generate

Retrieve the configured token later with:

export WORKSPACE_BRIDGE_TOKEN="$(node dist/cli.js auth show)"

Register a project from another terminal:

node dist/cli.js project add my-project /absolute/path/to/project
node dist/cli.js project list
node dist/cli.js project show my-project

# Add another folder to the same project under a named root.
node dist/cli.js project root add my-project frontend /absolute/path/to/frontend
node dist/cli.js project root list my-project

The configuration is stored at ~/.config/workspace-bridge/config.json unless --config is supplied.

A project starts with a main root. The legacy single-folder configuration is stored as { "path": "..." }; after adding another folder it is represented as named roots, for example:

{
  "projects": {
    "my-project": {
      "roots": {
        "main": { "path": "/absolute/path/to/project" },
        "frontend": { "path": "/absolute/path/to/frontend" }
      }
    }
  }
}

Use root on file, command, process, and Git tools to select a named root. It defaults to main, so existing calls remain compatible. Paths and command cwd values are relative to the selected root. File moves are restricted to a single root; Git operations run from the selected root.

Related MCP server: OpenAI Secure MCP Tunnel

Permission modes

The default mode is guarded. Change it locally with:

node dist/cli.js policy set-mode guarded
node dist/cli.js policy set-mode permissive

guarded marks writes and process execution as consequential so ChatGPT can request confirmation. permissive removes that confirmation hint. Both modes still enforce project selection, path validation, output limits, and timeouts.

Commands run with a root-relative cwd (the main root by default), optional per-process environment overrides, and optional one-shot UTF-8 stdin. Cwd is resolved and checked inside the selected project root; this still does not provide a complete filesystem sandbox for arbitrary commands.

Coding-focused MCP tools

The bridge includes batch tools so a coding task does not need one MCP round trip per file or command:

  • workspace_context: returns project overview, a bounded tree, and optionally Git diff in one read-only call.

  • file_read_many: reads multiple files concurrently while deduplicating paths and bounding the response size.

  • file_write_many: writes multiple UTF-8 files after validating every path and expected hash, with one confirmation.

  • file_patch_many: applies multiple exact unified diffs after validating every path, patch, and expected hash, with one confirmation.

  • apply_patch: applies a Codex-style *** Begin Patch envelope with Add/Delete/Update/Move operations after validating all hunks.

  • file_replace: replaces an exact text fragment when its occurrence count matches expectedOccurrences (default 1), failing safely when it is missing or ambiguous.

  • file_stat: returns lstat-style metadata for a known path and can stream a SHA-256 when requested.

  • file_mkdir: creates a project directory with explicit recursive behavior.

  • bridge_info: reports bridge capabilities, limits, policy, and project-root restrictions without secrets.

  • project_root_add / project_root_remove: manage named folders inside an existing project; project_info and project_list return all configured roots.

  • git_show: shows a bounded local revision, optionally for one project-relative historical path.

  • command_run_batch: runs bounded commands with configurable concurrency, per-command cwd/env/stdin, and independent results.

Use the batch tools for independent files or checks. Keep dependent commands and edits in separate calls so their ordering remains explicit. The existing single-file and single-command tools remain available for focused work.

file_patch and file_patch_many require standard unified diffs with ---, +++, and @@ headers. Use apply_patch for Codex-style *** Begin Patch input. Unsupported or malformed input is rejected instead of being treated as a successful no-op.

command_run accepts optional cwd, env, stdin, and yieldTimeMs. If the command is still running after that wait, the result includes a sessionId; use process_read with that ID and stop it with process_stop when finished. Command summaries retain the beginning and end of noisy output and report omitted bytes.

File writes and patches are UTF-8 only. Images under the configured byte and pixel limits are returned as MCP image content; other binary files return metadata. Symlinks are allowed only when their resolved target stays inside the selected project root. Directory listings and trees do not follow symlinks.

The audit log is stored beside the config as audit.log and contains request metadata only: tool, project, duration, command name, exit code, and errors. It does not record tokens, file contents, environment variables, or full command output.

OpenAI Secure MCP Tunnel

The tunnel client can launch the stdio entrypoint itself, so no HTTP bridge process is needed:

tunnel-client init \
  --sample sample_mcp_stdio_local \
  --profile workspace-bridge-stdio \
  --tunnel-id tunnel_0123456789abcdef0123456789abcdef \
  --mcp-command "node /absolute/path/to/workspace-bridge/dist/cli.js stdio"
tunnel-client doctor --profile workspace-bridge-stdio
tunnel-client run --profile workspace-bridge-stdio

Replace the tunnel ID and absolute project path with the local values. CONTROL_PLANE_API_KEY must be present in the tunnel client's environment.

For the existing HTTP transport, run the bridge and the OpenAI Secure MCP Tunnel client in separate terminals:

npm run start
./tunnel-client run --profile workspace-bridge --health.listen-addr 127.0.0.1:18081

The tunnel client forwards to the local MCP endpoint configured by the workspace-bridge profile. No extra Authorization header is needed for the default loopback listener. CONTROL_PLANE_API_KEY is unrelated to Workspace Bridge MCP authentication. The systemd setup below loads it from an environment file.

The tunnel client's health endpoint is available at http://127.0.0.1:18081.

Run both with systemd

systemd/workspace-bridge.service is a user-service unit for the current checkout. It starts both npm run start and ./tunnel-client run ..., forwards both processes' logs to the journal, and restarts the pair if either process exits.

Create the tunnel client's environment file without committing it:

mkdir -p ~/.config/workspace-bridge
editor ~/.config/workspace-bridge/tunnel-client.env
chmod 600 ~/.config/workspace-bridge/tunnel-client.env

Put the following in that file:

CONTROL_PLANE_API_KEY=your_runtime_api_key

Install and start the user unit:

mkdir -p ~/.config/systemd/user
cp systemd/workspace-bridge.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now workspace-bridge.service
systemctl --user status workspace-bridge.service

Follow logs with:

journalctl --user -u workspace-bridge.service -f

If the repository is moved, update WorkingDirectory, ExecStart, and RequiresMountsFor in the unit. To run it without an active login session, enable user lingering once with loginctl enable-linger "$USER".

Cloudflare Tunnel

For a later HTTPS deployment, point a Cloudflare Tunnel published application at http://127.0.0.1:3001 and protect it with Cloudflare Access. The bridge's loopback exception is intentional: it does not replace an Access policy for a publicly published hostname. This is a transport option, not a replacement for Workspace Bridge project authorization.

The optional tunnel child process can be configured and managed locally:

node dist/cli.js tunnel set cloudflared -- tunnel --url http://127.0.0.1:3001
node dist/cli.js tunnel enable
node dist/cli.js serve

For a named Cloudflare Tunnel or another client, replace the command and arguments. serve stops the managed tunnel and all bridge-owned project processes during shutdown.

Development

npm run typecheck
npm test
npm run build

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Asutorufa/workspace-bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server