Yakwilik/exec-mcp
If you are the rightful owner of exec-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The Model Context Protocol (MCP) server is designed to manage the execution and termination of processes in a structured and efficient manner.
Exec MCP Server
A Model Context Protocol (MCP) server that provides tools for executing and managing processes. This server allows agents to execute processes and stop them by PID, making process management easier than using terminal commands.
Features
- exec_process: Execute a process and return its PID for later management (background execution)
- run_command: Execute a command and return its output immediately (synchronous execution)
- stop_process: Stop a process by its PID using SIGTERM or SIGKILL
- Non-blocking: Background processes run detached and don't block the MCP server
- Concurrent: Multiple processes can be managed simultaneously
Installation
Using go install (Recommended)
go install github.com/Yakwilik/exec-mcp/cmd/exec-mcp@latest
This will install the exec-mcp binary to $GOPATH/bin or $HOME/go/bin (make sure it's in your PATH).
Building from source
git clone https://github.com/Yakwilik/exec-mcp.git
cd exec-mcp
go build -o exec-mcp ./cmd/exec-mcp
Testing
Run the comprehensive test suite:
# Run all tests
go test ./... -v
# Run specific tool tests
go test ./internal/tools/exec/ -v
go test ./internal/tools/run/ -v
go test ./internal/tools/stop/ -v
# Run integration tests
go test ./internal/mcp/ -v
Usage
The server uses stdio transport for communication:
./exec-mcp
Connecting to MCP Clients
This MCP server can be connected to any MCP-compatible client, such as:
- Claude Desktop (Anthropic)
- Cursor (with MCP support)
- Other MCP-compatible agents
For Claude Desktop
Add the server to your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
If installed via go install, use:
{
"mcpServers": {
"exec-mcp": {
"command": "exec-mcp",
"args": []
}
}
}
Or if built manually, use the full path:
{
"mcpServers": {
"exec-mcp": {
"command": "/absolute/path/to/exec-mcp",
"args": []
}
}
}
Note: Make sure exec-mcp is in your PATH if using the first option, or use the full path to the binary.
For Cursor
If Cursor supports MCP servers, add similar configuration in Cursor's settings.
Testing the Connection
After connecting, the client should be able to use these tools:
exec_process- Start background processesrun_command- Execute commands synchronouslystop_process- Stop processes by PID
Tools
exec_process
Execute a process and return its PID.
Parameters:
command(string, required): The command to executeargs(array of strings, optional): Command line argumentsdir(string, optional): Working directory for the processenv(array of strings, optional): Environment variables (format: KEY=VALUE)
Example:
{
"command": "ls",
"args": ["-l", "/tmp"],
"dir": "/home/user"
}
Response:
{
"content": [
{
"type": "text",
"text": "Process started successfully:\n{\n \"pid\": 12345,\n \"command\": \"ls\",\n \"args\": [\"-l\", \"/tmp\"],\n \"start_time\": \"2024-01-01T12:00:00Z\",\n \"status\": \"running\"\n}"
}
],
"structuredContent": {
"pid": 12345,
"command": "ls",
"args": ["-l", "/tmp"],
"start_time": "2024-01-01T12:00:00Z",
"status": "running"
}
}
Note: The structuredContent field contains the structured data that can be directly accessed without parsing JSON text.
run_command
Execute a command and return its output immediately (synchronous execution).
Parameters:
command(string, required): The command to executeargs(array of strings, optional): Command line argumentsdir(string, optional): Working directory for the processenv(array of strings, optional): Environment variables (format: KEY=VALUE)timeout(integer, optional): Timeout in seconds (0 means no timeout)
Example:
{
"command": "ls",
"args": ["-l", "/tmp"],
"dir": "/home/user",
"timeout": 10
}
Response:
{
"content": [
{
"type": "text",
"text": "Command executed:\n{\n \"command\": \"ls\",\n \"args\": [\"-l\", \"/tmp\"],\n \"exit_code\": 0,\n \"stdout\": \"total 0\\n-rw-r--r-- 1 user user 0 Jan 1 12:00 file.txt\",\n \"stderr\": \"\",\n \"executed_at\": \"2024-01-01T12:00:00Z\",\n \"duration_seconds\": 0.05,\n \"success\": true\n}"
}
],
"structuredContent": {
"command": "ls",
"args": ["-l", "/tmp"],
"exit_code": 0,
"stdout": "total 0\n-rw-r--r-- 1 user user 0 Jan 1 12:00 file.txt",
"stderr": "",
"executed_at": "2024-01-01T12:00:00Z",
"duration_seconds": 0.05,
"success": true
}
}
Note: This tool waits for the command to complete and returns the full output. Use exec_process for background execution.
stop_process
Stop a process by its PID using SIGTERM or SIGKILL.
Parameters:
pid(integer, required): The process ID to stopkill(boolean, optional): If true, use SIGKILL instead of SIGTERM (force kill)
Example:
{
"pid": 12345,
"kill": false
}
Response:
{
"content": [
{
"type": "text",
"text": "Signal SIGTERM sent to process 12345"
}
],
"structuredContent": {
"pid": 12345,
"signal": "SIGTERM",
"status": "signal_sent"
}
}
Using Structured Data
The MCP server returns both human-readable text and structured JSON data. For programmatic access, use the structuredContent field:
// Example: Extract PID from exec_process response
result, err := clientSession.CallTool(ctx, execParams)
if err != nil {
log.Fatal(err)
}
// Access structured data directly
if processInfoMap, ok := result.StructuredContent.(map[string]interface{}); ok {
if pidFloat, exists := processInfoMap["pid"]; exists {
if pid, ok := pidFloat.(float64); ok {
processID := int(pid)
// Use processID for stop_process
}
}
}
Architecture
The project is organized into separate packages for maintainability:
./cmd/exec-mcp/main.go: Main entry point./internal/mcp/server.go: MCP server setup and configuration./internal/tools/tool.go: Tool interface definition./internal/tools/exec/: Process execution tool (background, struct-based)./internal/tools/run/: Command execution tool (synchronous, struct-based)./internal/tools/stop/: Process termination tool (struct-based)./internal/mcp/test_helpers.go: Helper functions for extracting structured data
Tool Architecture
Each tool is implemented as a struct that implements the Tool interface:
type Tool interface {
Name() string
Description() string
Handle(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, any, error)
}
This approach provides:
- No hardcoded tool names: Names are retrieved from tool structs
- Self-documenting: Each tool provides its own name and description
- Type safety: Interface ensures consistent tool implementation
- Easy testing: Tools can be tested independently
Benefits
This MCP server enables agents to:
- Execute processes and get their PIDs for precise management (background execution)
- Execute commands and get immediate output (synchronous execution)
- Stop processes without needing to search for them using terminal commands
- Manage multiple processes concurrently with their exact process IDs
- Use proper signal handling (SIGTERM/SIGKILL) for clean process termination
- Run processes in detached mode without blocking the MCP server
- Get command output, exit codes, and execution time for synchronous commands
Without this MCP, agents typically need to use terminal commands like ps, grep, and kill to find and manage processes, which is less reliable and more complex.