Skip to content

bash tool description in v1.0.6 limits MCP hosts to git read-only, breaking git commit / push workflows #149

Description

@wuaishare

Summary

After upgrading DevSpace from v1.0.5 to v1.0.6, the bash tool description now causes MCP hosts (ChatGPT) to refuse executing git add, git commit, git push, git fetch, and git pull. The underlying execution layer is unaffected — only the tool's description field changed, and that string is what the host reads to decide whether a call is in scope.

Reproduction

  1. Install DevSpace v1.0.5 on a workspace with a git repo under allowedRoots.
  2. Configure ChatGPT (or another MCP host) to connect via Streamable HTTP to /mcp.
  3. Ask the host: "Please run git status and git diff for this workspace." → succeeds.
  4. Ask the host: "Please git add . and git commit -m 'test'." → succeeds (v1.0.5 description allowed it).
  5. Upgrade to v1.0.6 (git pull, npm install, npm run build, restart).
  6. Repeat step 4 in a new conversation. → Host refuses with a message like:
  The M4.bash tool contract says: "Use only for tests, builds, git inspection,
  package scripts, …". This contract only authorizes git inspection, so the
  current tool version still does not allow me to execute git write operations.
  I cannot bypass the tool's own permission contract.

Root cause

In src/server.ts the bash tool description (line ~1560 in v1.0.6) reads:

Run a shell command inside an open workspace. Use only for tests, builds,
git inspection, package scripts, … . Do not use bash to create or modify files.

Two issues compound here:

  1. The phrase "Use only for…" is read by MCP hosts as a whitelist. Anything not explicitly listed is treated as out-of-scope. git commit / push are
    not listed, so the host refuses them.
  2. The phrase "Do not use bash to create or modify files" is read as a
    blanket ban on file-mutating shell commands. Hosts further categorize
    git commit / push as file-mutating (because they update refs / remote),
    which makes the refusal tighter than the underlying implementation warrants.

There is no runtime enforcement of these limits. bash accepts any shell
command, the only checks are workspace-path containment and timeout (≤300s).
git add and git commit execute normally when invoked directly through the
MCP transport — the host simply declines to call.

Suggested fix

In v1.0.6's src/server.ts, replace the "Use only for…" prefix with an
explicit "Git write commands such as git add, git commit, git push,
git fetch, and git pull are also allowed through this tool." Also change
"Do not use bash to create or modify files" to "create or modify project
source files" so the limit is clearly bounded to source-code mutation,
not repository-metadata writes.

A complete replacement description (both branches of the
config.toolMode !== "full" ternary) and a rewrite of the command field's
describe() string are in the temp workaround section below.

Workaround until upstream lands

If you need git commit / push to work today, you can patch the description
strings yourself in your local checkout. The patch is small (~6 lines,
description only, no runtime logic) and is safe to re-apply after every
git pull until upstream resolves it.

--- a/src/server.ts
+++ b/src/server.ts
@@ -1558,8 +1558,8 @@ export function createMcpServer(
       title: "Bash",
       description: config.toolMode !== "full"
-        ? `Run a shell command inside an open workspace. Use only for tests, builds, git inspection, package scripts, search, file discovery, and directory inspection. In minimal tool mode, ${toolNames.grep}, ${toolNames.glob}, and ${toolNames.ls} are disabled; use command-line tools such as grep, rg, find, ls, and tree for those read-only inspection actions. Do not use ${toolNames.shell} to create or modify files. Do not use shell redirection, heredocs, tee, sed -i, perl -i, node/python/ruby scripts, or generated scripts to write project files; use ${toolNames.edit} for targeted changes and ${toolNames.write} for new files or full rewrites. Prefer ${toolNames.read} for direct file reads. Call open_workspace first and pass workspaceId. This is powerful local execution and should only be exposed behind strong authentication.`
-        : `Run a shell command inside an open workspace. Use only for tests, builds, git inspection, package scripts, and commands that are better executed by the shell. Do not use ${toolNames.shell} to create or modify files. Do not use shell redirection, heredocs, tee, sed -i, perl -i, node/python/ruby scripts, or generated scripts to write project files; use ${toolNames.edit} for targeted changes and ${toolNames.write} for new files or full rewrites. Prefer ${toolNames.read}, ${toolNames.grep}, ${toolNames.glob}, and ${toolNames.ls} for file inspection. Call open_workspace first and pass workspaceId. This is powerful local execution and should only be exposed behind strong authentication.`,
+        ? `Run a shell command inside an open workspace. In minimal tool mode, ${toolNames.grep}, ${toolNames.glob}, and ${toolNames.ls} are disabled; use command-line tools such as grep, rg, find, ls, and tree for read-only inspection. Allowed purposes include tests, builds, package scripts, search, file discovery, directory inspection, and shell-side tooling. Git read commands such as git status, git diff, git log, and git show are allowed; git write commands such as git add, git commit, git push, git fetch, and git pull are also allowed through this tool. Do not use ${toolNames.shell} to create or modify project source files; use ${toolNames.edit} for targeted changes and ${toolNames.write} for new files or full rewrites. Do not use shell redirection, heredocs, tee, sed -i, perl -i, node/python/ruby scripts, or generated scripts to write project files. Prefer ${toolNames.read} for direct file reads. Call open_workspace first and pass workspaceId. This is powerful local execution and should only be exposed behind strong authentication.`
+        : `Run a shell command inside an open workspace. Allowed purposes include tests, builds, package scripts, search, file discovery, directory inspection, and any shell-side tooling. Git read commands such as git status, git diff, git log, and git show are allowed; git write commands such as git add, git commit, git push, git fetch, and git pull are also allowed through this tool. Do not use ${toolNames.shell} to create or modify project source files; use ${toolNames.edit} for targeted changes and ${toolNames.write} for new files or full rewrites. Do not use shell redirection, heredocs, tee, sed -i, perl -i, node/python/ruby scripts, or generated scripts to write project files. Prefer ${toolNames.read}, ${toolNames.grep}, ${toolNames.glob}, and ${toolNames.ls} for file inspection. Call open_workspace first and pass workspaceId. This is powerful local execution and should only be exposed behind strong authentication.`,
 inputSchema: {
         workspaceId: z
           .string()
@@ -1567,7 +1567,7 @@ export function createMcpServer(
         command: z
           .string()
           .describe(
-            `Shell command to run. Must not create or modify project files; use ${toolNames.edit} or ${toolNames.write} for file changes.`,
+            `Shell command to run. Allowed commands include tests, builds, package scripts, search, file discovery, directory inspection, and Git operations (both read such as git status / git diff / git log and write such as git add / git commit / git push / git fetch / git pull). Must not be used to create or modify project source files; use ${toolNames.edit} or ${toolNames.write} for those.`,
           ),

Rebuild and restart:

cd /path/to/devspace
npm run build
launchctl kickstart -k gui/$(id -u)/dev.local.devspace  # or systemd equivalent

After restart, a fresh tools/list response will surface the new description
and the host will resume git add / commit / push calls.

Versioning note

The previous v1.0.5 description used:

Run a shell command inside an open workspace. Use only for tests, builds, and
git inspection. Do not use bash to modify or create files; use edit and write.

…and while still whitelist-framed, hosts consistently interpreted "git
inspection" loosely enough to include commit / push in practice. The v1.0.6
revision tightened the surrounding context (added "package scripts",
"search", "file discovery", "directory inspection") without adding any
explicit git commit / push allowance, which tipped the host's interpretation
from permissive to strict.

Environment

  • DevSpace v1.0.6 (commit 3bd0378, tag v1.0.6)
  • macOS 15.7.7 / Node v24.15.0 (ABI 137)
  • MCP host: ChatGPT (Apps & Connectors, Streamable HTTP transport)
  • Workspace mode: checkout, toolMode: "full"

描述(中文版)

概要

从 v1.0.5 升级到 v1.0.6 后,DevSpace 的 bash 工具描述字符串会让 MCP host(以 ChatGPT 为例)拒绝执行 git add / git commit / git push / git fetch / git pull。底层执行层完全没动——只有工具的 description字段改了,而 host 正是根据这个字段判断调用是否在工具合同范围内。

复现步骤

  1. 在 allowedRoots 包含 git仓库的工作区里安装 v1.0.5。
  2. 在 ChatGPT(或其他 MCP host)里通过 Streamable HTTP 连接 /mcp。
  3. 让 host 跑 git status / git diff → 正常。
  4. 让 host 跑 git add . 和 git commit -m 'test' →正常(v1.0.5 描述允许)。
  5. 升级到 v1.0.6(git pull / npm install / npm run build / 重启)。
  6. 在新会话里重复步骤 4 → host 拒绝:
  M4.bash 工具合同说:'Use only for tests, builds, git inspection,
  package scripts, …'。该合同只授权 git inspection,
  所以当前工具版本不允许执行 Git写操作。

根因

src/server.ts 里 bash 工具的描述(v1.0.6 第1560 行附近):

Run a shell command inside an open workspace. Use only for tests, builds,
git inspection, package scripts, … . Do not use bash to create or modify files.

两个问题叠加:

  1. "Use only for..." 被 MCP host 读为白名单——列表里没有写 git commit / push,host 直接拒绝。
  2. "Do not use bash to create or modify files" 被读成"凡是会变更文件的 shell 命令都禁"——host 把 git commit / push(更新 ref / remote)也归到这一类。

运行时没有任何强制拦截。 bash 工具接受任意 shell 命令,唯一校验是 workspace路径 containment 和 ≤300 秒超时。直接通过 MCP调 git add / git commit 都能正常执行——只是 host 不肯调。

建议修复

把 "Use only for..." 改成显式列出 "Git write commands such as git add, git commit, git push, git fetch, git pull are also allowed through this tool." 把 "Do not use bash to create or modify files" 改成 "create or modify project source files"——把限制明确收敛到源代码修改。

临时解决方案(issue 内容里直接附 patch diff)

参见上面的英文版 diff。

环境- DevSpace v1.0.6(commit 3bd0378,tag v1.0.6)

  • macOS 15.7.7 / Node v24.15.0(ABI 137)
  • MCP host:ChatGPT(Apps & Connectors,Streamable HTTP transport)
  • 工作区模式:checkout,toolMode: "full"

Activity

  1. teddyli18000 commented on Aug 10, 2026

    @teddyli18000

    I opened #181 with a focused fix for this.

    It updates the Bash tool descriptor, command schema, and server initialization instructions so MCP hosts can see that git add, git commit, git fetch, git pull, and git push are supported. The source-editing guidance remains in place, and destructive Git commands such as git reset --hard, git clean, and git checkout -- are explicitly excluded.

    The PR includes regression coverage for both full and minimal tool modes using the actual MCP tools/list response and initialization instructions.

  2. teddyli18000 commented on Aug 12, 2026

    @teddyli18000

    The maintainer asked about the ChatGPT connector permission used during reproduction and shared a screenshot showing Permissions → Allow all actions: #181 (comment)

    @wuaishare, could you confirm whether your #149 reproduction also used Allow all actions, or a different permission option? The reported DevSpace settings (toolMode: "full", checkout mode, Streamable HTTP) are already clear; this ChatGPT-side permission is the remaining configuration difference we need to rule out.

  3. wuaishare commented on Aug 12, 2026

    @wuaishare
    Author

    Yes — I can confirm that I reproduced this across multiple separate ChatGPT conversation threads.

    The first time I encountered it was in an existing conversation that had originally been created while I was still using DevSpace v1.0.5. Git operations had been working normally in that thread. After upgrading DevSpace to v1.0.6, the issue started appearing.

    Before the issue occurred, the ChatGPT connector was using the default permission settings. After seeing the failures, I changed the connector permissions to Allow all actions, specifically to rule out a ChatGPT-side permission restriction, but that did not resolve the problem.

    I then reproduced it again in two newly created conversation threads. I also tested from a different device using a newly configured DevSpace connector and a brand-new conversation, and the same behavior appeared there as well.

    The problem only disappeared after I modified the Bash tool description, restarted the DevSpace service, and refreshed/reconnected the connector so that ChatGPT received the updated tool metadata.

    So from my testing, the connector permission setting was not the deciding factor: both the default permission configuration and Allow all actions still reproduced the issue with the original v1.0.6 Bash tool description.

  4. Waishnav commented on Aug 25, 2026

    @Waishnav
    Owner

    @wuaishare you can try devspace in codex mode, it now has exec_command and write_stdin tools compare with just bash tool, i feel like since i use devspace in codex mode it just works seemlessly for me

  5. Waishnav commented on Sep 7, 2026

    @Waishnav
    Owner

    @wuaishare @teddyli18000 Thanks again for the detailed reproduction and focused PR around Git write commands being rejected by the shell tool description. I’ve addressed this in v1.1.0-beta.1; the shell contract now allows general local command execution, including Git write operations, while source-file edits remain covered by the dedicated tools.

    Try npm install @waishnav/devspace@beta, restart DevSpace, and refresh the MCP connector so it receives the updated tool metadata. I’d appreciate confirmation that commands such as git add, git commit, and git push now work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions