-
Notifications
You must be signed in to change notification settings - Fork 11
feat: add Claude MCP server for background task delegation #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # Build stage for MCP server | ||
| FROM golang:1.24-alpine AS builder | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy go mod files | ||
| COPY go.mod go.sum ./ | ||
| RUN go mod download | ||
|
|
||
| # Copy source code | ||
| COPY . . | ||
|
|
||
| # Build the binary | ||
| RUN CGO_ENABLED=0 GOOS=linux go build -o claude-mcp-server ./claude/ | ||
|
|
||
| # Final stage - use Debian instead of Alpine for glibc compatibility | ||
| FROM ghcr.io/anomalyco/opencode | ||
|
|
||
| # Install required runtime dependencies | ||
| RUN apk add git curl bash | ||
|
|
||
| # Install GitHub CLI | ||
| RUN echo "@community http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && apk add github-cli@community | ||
|
|
||
| # Copy the MCP server binary | ||
| COPY --from=builder /app/claude-mcp-server /usr/local/bin/claude-mcp-server | ||
|
|
||
| # Set environment variables | ||
| ENV CLAUDE_SESSION_DIR=/root | ||
| ENV CLAUDE_BINARY=/usr/local/bin/claude | ||
| ENV CLAUDE_MAX_SESSIONS=10 | ||
| ENV CLAUDE_LOG_RETENTION_HOURS=24 | ||
| ENV CLAUDE_FORMAT=json | ||
| ENV CLAUDE_SHARE=false | ||
|
|
||
| # Optional environment variables (uncomment to use): | ||
| # ENV CLAUDE_MODEL=openai/gpt-4 | ||
| # ENV CLAUDE_AGENT= | ||
| # ENV CLAUDE_VARIANT= | ||
| # ENV CLAUDE_ATTACH= | ||
| # ENV CLAUDE_PORT=0 | ||
| # ENV CLAUDE_ALLOWED_TOOLS= | ||
| # ENV CLAUDE_TOOLS= | ||
|
|
||
| # Run the MCP server | ||
| ENTRYPOINT ["claude-mcp-server"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| # Claude MCP Server | ||
|
|
||
| This is an MCP (Model Context Protocol) server that provides integration with Claude Code CLI, allowing other MCP clients to delegate tasks to Claude Code in the background. It follows the same pattern as the opencode MCP server but is specifically designed for Claude Code. | ||
|
|
||
| ## Features | ||
|
|
||
| - **Background Task Delegation**: Start Claude Code sessions in the background and monitor their status | ||
| - **Session Management**: Create, monitor, stop, and list sessions | ||
| - **Log Access**: Retrieve stdout and stderr logs from running or completed sessions | ||
| - **Tool Restrictions**: Support for `--allowedTools` and `--tools` flags to control Claude's capabilities | ||
| - **Environment Passthrough**: All OS environment variables are passed to Claude subprocesses | ||
| - **Configurable**: Extensive environment variables for customization | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Adding the Server | ||
|
|
||
| Add this MCP server to your Claude Code configuration: | ||
|
|
||
| ```bash | ||
| claude mcp add claude-mcp -- npx -y mudler/MCPs/claude | ||
| ``` | ||
|
|
||
| Or use the Docker-based approach if you've built the Docker image: | ||
|
|
||
| ```bash | ||
| claude mcp add claude-mcp -- docker run -i --rm claude-mcp-server | ||
| ``` | ||
|
|
||
| ### Starting a Session | ||
|
|
||
| Use the `start_session` tool to begin a new Claude session: | ||
|
|
||
| ```json | ||
| { | ||
| "message": "Find and fix the bug in auth.py", | ||
| "allowed_tools": "Bash,Read,Edit", | ||
| "title": "Bug Fix Task" | ||
| } | ||
| ``` | ||
|
|
||
| This returns a session ID that can be used to monitor progress. | ||
|
|
||
| ### Checking Session Status | ||
|
|
||
| Use the `get_session_status` tool with the session ID to check if the session is: | ||
| - `starting` - Session is initializing | ||
| - `running` - Claude is actively working | ||
| - `completed` - Task finished successfully (exit code 0) | ||
| - `failed` - Task failed with non-zero exit code | ||
| - `stopped` - Session was manually stopped | ||
| - `not_found` - Session ID doesn't exist | ||
|
|
||
| ### Retrieving Logs | ||
|
|
||
| Use the `get_session_logs` tool to see what Claude is doing: | ||
| - Specify the session ID | ||
| - Optionally specify number of lines to retrieve (default 100) | ||
| - Returns both stdout and stderr | ||
|
|
||
| ### Stopping a Session | ||
|
|
||
| Use the `stop_session` tool to terminate a running session. Use `force=true` to kill immediately. | ||
|
|
||
| ### Listing Sessions | ||
|
|
||
| Use the `list_sessions` tool to see all sessions, optionally filtered by status. | ||
|
|
||
| ## Environment Variables | ||
|
|
||
| ### Server Configuration | ||
|
|
||
| - `CLAUDE_SESSION_DIR`: Directory for session state (default: `/tmp/claude-sessions`) | ||
| - `CLAUDE_MAX_SESSIONS`: Maximum concurrent sessions (default: `10`) | ||
| - `CLAUDE_LOG_RETENTION_HOURS`: Hours to keep logs before cleanup (default: `24`) | ||
| - `CLAUDE_WORK_DIR`: Working directory for Claude processes (default: `/root`) | ||
|
|
||
| ### Claude Code Invocation | ||
|
|
||
| - `CLAUDE_BINARY`: Path to Claude binary (default: `claude`) | ||
| - `CLAUDE_MODEL`: Default model to use (e.g., `sonnet`, `opus`) | ||
| - `CLAUDE_AGENT`: Specify an agent for sessions | ||
| - `CLAUDE_FORMAT`: Output format (default: `json`) | ||
| - `CLAUDE_SHARE`: Whether to share sessions (`true`/`false`) | ||
| - `CLAUDE_ATTACH`: Files to attach to sessions | ||
| - `CLAUDE_PORT`: Port for remote control | ||
| - `CLAUDE_VARIANT`: Model variant | ||
| - `CLAUDE_ALLOWED_TOOLS`: Tools allowed without prompting (e.g., `"Bash,Read,Edit"`) | ||
| - `CLAUDE_TOOLS`: Restrict which tools Claude can use (e.g., `"Bash,Read,Edit"`) | ||
|
|
||
| ### Tool Naming (Optional) | ||
|
|
||
| - `CLAUDE_TOOL_START_SESSION_NAME`: Override the start_session tool name | ||
| - `CLAUDE_TOOL_GET_SESSION_STATUS_NAME`: Override the get_session_status tool name | ||
| - `CLAUDE_TOOL_GET_SESSION_LOGS_NAME`: Override the get_session_logs tool name | ||
| - `CLAUDE_TOOL_STOP_SESSION_NAME`: Override the stop_session tool name | ||
| - `CLAUDE_TOOL_LIST_SESSIONS_NAME`: Override the list_sessions tool name | ||
|
|
||
| ## Integration with MCPs Repository | ||
|
|
||
| This server is designed to be part of the [MCPs](https://github.com/mudler/MCPs) collection. It follows the same structure and patterns as other MCP servers in that repository. | ||
|
|
||
| ### Directory Structure | ||
|
|
||
| ``` | ||
| claude/ | ||
| ├── main.go # MCP server setup and tool registration | ||
| ├── session.go # Session management logic | ||
| ├── handlers.go # Tool handlers (input/output types) | ||
| ├── Dockerfile # Container image definition | ||
| └── README.md # This file | ||
| ``` | ||
|
|
||
| ### Building | ||
|
|
||
| The server can be built using the Dockerfile or directly with Go: | ||
|
|
||
| ```bash | ||
| go build -o claude-mcp-server ./claude | ||
| ``` | ||
|
|
||
| ### Testing | ||
|
|
||
| You can test the server directly: | ||
|
|
||
| ```bash | ||
| # Run the server (it will wait for MCP input on stdin/stdout) | ||
| ./claude-mcp-server | ||
| ``` | ||
|
|
||
| Or test with the MCP inspector: | ||
|
|
||
| ```bash | ||
| npx @modelcontextprotocol/inspector ./claude-mcp-server | ||
| ``` | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| - The server runs Claude Code with the permissions of the user running the MCP client | ||
| - Environment variables are passed through to Claude subprocesses | ||
| - Tool restrictions (`--allowedTools`, `--tools`) should be used to limit Claude's capabilities | ||
| - Session logs are stored in the session directory and cleaned up based on retention policy | ||
| - Consider using `CLAUDE_MAX_SESSIONS` to limit resource usage | ||
|
|
||
| ## Example Workflow | ||
|
|
||
| 1. **Start a session** to fix a bug: | ||
| ``` | ||
| start_session(message="Fix the authentication bug in login.go", allowed_tools="Bash,Read,Edit") | ||
| ``` | ||
|
|
||
| 2. **Check status** after a few seconds: | ||
| ``` | ||
| get_session_status(session_id="abc123...") | ||
| ``` | ||
|
|
||
| 3. **Get logs** to see progress: | ||
| ``` | ||
| get_session_logs(session_id="abc123...", lines=50) | ||
| ``` | ||
|
|
||
| 4. **Stop if needed** (if it's taking too long or going wrong): | ||
| ``` | ||
| stop_session(session_id="abc123...", force=false) | ||
| ``` | ||
|
|
||
| 5. **List all sessions** to overview: | ||
| ``` | ||
| list_sessions(status_filter="running") | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Sessions fail to start | ||
| - Check that `CLAUDE_BINARY` points to a valid Claude executable | ||
| - Verify the Claude binary is in PATH or specify full path | ||
| - Check session logs for error messages | ||
| - Ensure environment variables are properly set | ||
|
|
||
| ### No tools available | ||
| - Check `CLAUDE_ALLOWED_TOOLS` and `CLAUDE_TOOLS` environment variables | ||
| - Remember that `--allowedTools` enables tools without prompting, while `--tools` restricts which tools are available | ||
| - Use `claude --help` to see available tool names | ||
|
|
||
| ### High resource usage | ||
| - Reduce `CLAUDE_MAX_SESSIONS` to limit concurrent sessions | ||
| - Set `CLAUDE_LOG_RETENTION_HOURS` to a lower value for faster cleanup | ||
| - Use `stop_session` to terminate unused sessions | ||
|
|
||
| ## License | ||
|
|
||
| This MCP server is part of the MCPs repository and follows the same license (MIT). | ||
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| module github.com/mudler/MCPs/claude | ||
|
|
||
| go 1.25.0 | ||
|
|
||
| require ( | ||
| github.com/google/uuid v1.6.0 | ||
| github.com/modelcontextprotocol/go-sdk v1.4.0 | ||
| github.com/mudler/go-processmanager v0.1.0 | ||
| ) | ||
|
|
||
| require ( | ||
| github.com/google/jsonschema-go v0.4.2 // indirect | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't bring go.mod and go.sum in the Claude sub-folder. There are already go.mod and go.sum at top level of the project. just add the necessary dependencies there |
||
| github.com/segmentio/asm v1.1.3 // indirect | ||
| github.com/segmentio/encoding v0.5.3 // indirect | ||
| github.com/yosida95/uritemplate/v3 v3.0.2 // indirect | ||
| golang.org/x/oauth2 v0.34.0 // indirect | ||
| golang.org/x/sys v0.40.0 // indirect | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= | ||
| github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= | ||
| github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= | ||
| github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= | ||
| github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= | ||
| github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= | ||
| github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= | ||
| github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= | ||
| github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | ||
| github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||
| github.com/modelcontextprotocol/go-sdk v1.4.0 h1:u0kr8lbJc1oBcawK7Df+/ajNMpIDFE41OEPxdeTLOn8= | ||
| github.com/modelcontextprotocol/go-sdk v1.4.0/go.mod h1:Nxc2n+n/GdCebUaqCOhTetptS17SXXNu9IfNTaLDi1E= | ||
| github.com/mudler/go-processmanager v0.1.0 h1:fcSKgF9U/a1Z7KofAFeZnke5YseadCI5GqL9oT0LS3E= | ||
| github.com/mudler/go-processmanager v0.1.0/go.mod h1:h6kmHUZeafr+k5hRYpGLMzJFH4hItHffgpRo2QIkP+o= | ||
| github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= | ||
| github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= | ||
| github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= | ||
| github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= | ||
| github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= | ||
| github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= | ||
| github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc= | ||
| github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg= | ||
| github.com/segmentio/encoding v0.5.3 h1:OjMgICtcSFuNvQCdwqMCv9Tg7lEOXGwm1J5RPQccx6w= | ||
| github.com/segmentio/encoding v0.5.3/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0= | ||
| github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= | ||
| github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= | ||
| golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0= | ||
| golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= | ||
| golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= | ||
| golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= | ||
| golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= | ||
| golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= | ||
| golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= | ||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
| golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= | ||
| golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= | ||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= | ||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||
| gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||
| gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update the top-level readme