fix(beads-mcp): prevent subprocess stdin inheritance breaking MCP protocol
When running as an MCP server, subprocesses must not inherit stdin because MCP uses stdin for JSON-RPC protocol communication. Inherited stdin causes subprocesses to block indefinitely waiting for input or steal bytes from the MCP protocol stream. Added stdin=subprocess.DEVNULL (or asyncio.subprocess.DEVNULL for async) to all subprocess calls: - server.py: _resolve_workspace_root() git subprocess - tools.py: _resolve_workspace_root() git subprocess - bd_client.py: _run_command(), _check_version(), add_dependency(), quickstart(), and init() async subprocess calls 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import asyncio
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, List, Optional
|
||||
|
||||
@@ -290,6 +291,7 @@ class BdCliClient(BdClientBase):
|
||||
try:
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*cmd,
|
||||
stdin=asyncio.subprocess.DEVNULL, # Prevent inheriting MCP's stdin
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
cwd=working_dir,
|
||||
@@ -333,6 +335,7 @@ class BdCliClient(BdClientBase):
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
self.bd_path,
|
||||
"version",
|
||||
stdin=asyncio.subprocess.DEVNULL, # Prevent inheriting MCP's stdin
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
cwd=self._get_working_dir(),
|
||||
@@ -583,6 +586,7 @@ class BdCliClient(BdClientBase):
|
||||
try:
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*cmd,
|
||||
stdin=asyncio.subprocess.DEVNULL, # Prevent inheriting MCP's stdin
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
cwd=self._get_working_dir(),
|
||||
@@ -610,6 +614,7 @@ class BdCliClient(BdClientBase):
|
||||
try:
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*cmd,
|
||||
stdin=asyncio.subprocess.DEVNULL, # Prevent inheriting MCP's stdin
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
cwd=self._get_working_dir(),
|
||||
@@ -754,6 +759,7 @@ class BdCliClient(BdClientBase):
|
||||
try:
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
*cmd,
|
||||
stdin=asyncio.subprocess.DEVNULL, # Prevent inheriting MCP's stdin
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
cwd=self._get_working_dir(),
|
||||
|
||||
@@ -218,6 +218,7 @@ def _resolve_workspace_root(path: str) -> str:
|
||||
text=True,
|
||||
check=False,
|
||||
shell=sys.platform == "win32",
|
||||
stdin=subprocess.DEVNULL, # Prevent inheriting MCP's stdin
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.strip()
|
||||
|
||||
@@ -124,6 +124,7 @@ def _resolve_workspace_root(path: str) -> str:
|
||||
text=True,
|
||||
check=False,
|
||||
shell=sys.platform == "win32",
|
||||
stdin=subprocess.DEVNULL, # Prevent inheriting MCP's stdin
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.strip()
|
||||
|
||||
Reference in New Issue
Block a user