forked from claude-did-this/claude-hub
initial commit
This commit is contained in:
31
.env.example
31
.env.example
@@ -1,13 +1,18 @@
|
||||
# Application Configuration
|
||||
NODE_ENV=development
|
||||
PORT=3003
|
||||
PORT=3002
|
||||
|
||||
# GitHub Webhook Settings
|
||||
GITHUB_WEBHOOK_SECRET=your_webhook_secret_here
|
||||
GITHUB_TOKEN=ghp_your_github_token_here
|
||||
|
||||
# Bot Configuration (REQUIRED) - the GitHub mention that triggers the bot
|
||||
BOT_USERNAME=ClaudeBot
|
||||
# Bot Configuration (REQUIRED)
|
||||
BOT_USERNAME=@ClaudeBot
|
||||
BOT_EMAIL=claude@example.com
|
||||
|
||||
# Security Configuration
|
||||
AUTHORIZED_USERS=admin,username2,username3
|
||||
DEFAULT_AUTHORIZED_USER=admin
|
||||
|
||||
# Default GitHub Configuration for CLI
|
||||
DEFAULT_GITHUB_OWNER=your-org
|
||||
@@ -15,19 +20,25 @@ DEFAULT_GITHUB_USER=your-username
|
||||
DEFAULT_BRANCH=main
|
||||
|
||||
# Claude API Settings
|
||||
CLAUDE_API_AUTH_REQUIRED=1
|
||||
CLAUDE_API_AUTH_TOKEN=your_auth_token_here
|
||||
ANTHROPIC_API_KEY=your_anthropic_api_key_here
|
||||
|
||||
# Container Settings
|
||||
CLAUDE_USE_CONTAINERS=1
|
||||
CLAUDE_CONTAINER_IMAGE=claudecode:latest
|
||||
CLAUDE_CONTAINER_IMAGE=claude-code-runner:latest
|
||||
REPO_CACHE_DIR=/tmp/repo-cache
|
||||
REPO_CACHE_MAX_AGE_MS=3600000
|
||||
CONTAINER_LIFETIME_MS=7200000 # Container execution timeout in milliseconds (default: 2 hours)
|
||||
|
||||
# AWS Bedrock Credentials for Claude
|
||||
AWS_ACCESS_KEY_ID=secret_key
|
||||
AWS_SECRET_ACCESS_KEY=access_key
|
||||
AWS_REGION=us-east-2
|
||||
# AWS Bedrock Credentials for Claude (if using Bedrock)
|
||||
AWS_ACCESS_KEY_ID=your_aws_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key
|
||||
AWS_REGION=us-east-1
|
||||
CLAUDE_CODE_USE_BEDROCK=1
|
||||
ANTHROPIC_MODEL=us.anthropic.claude-3-7-sonnet-20250219-v1:0
|
||||
|
||||
# AWS Profile (uncomment if using AWS profiles instead of direct credentials)
|
||||
# USE_AWS_PROFILE=true
|
||||
# AWS_PROFILE=claude-webhook
|
||||
|
||||
# Test Configuration
|
||||
TEST_REPO_FULL_NAME=owner/repo
|
||||
13
CLAUDE.md
13
CLAUDE.md
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## Claude GitHub Webhook
|
||||
|
||||
This repository contains a webhook service that integrates Claude with GitHub, allowing Claude to respond to mentions in GitHub comments and help with repository tasks. When someone mentions `@MCPClaude` in a GitHub issue or PR comment, the system processes the command with Claude Code and returns a helpful response.
|
||||
This repository contains a webhook service that integrates Claude with GitHub, allowing Claude to respond to mentions in GitHub comments and help with repository tasks. When someone mentions the configured bot username (configured via environment variables) in a GitHub issue or PR comment, the system processes the command with Claude Code and returns a helpful response.
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
@@ -95,7 +95,7 @@ The repository includes a `.devcontainer` configuration that allows Claude Code
|
||||
This configuration enables the use of `--dangerously-skip-permissions` flag when running Claude Code CLI.
|
||||
|
||||
### Workflow
|
||||
1. GitHub comment with `@MCPClaude` triggers a webhook event
|
||||
1. GitHub comment with bot mention (configured via BOT_USERNAME) triggers a webhook event
|
||||
2. Express server receives the webhook at `/api/webhooks/github`
|
||||
3. Service extracts the command and processes it with Claude in a Docker container
|
||||
4. Claude analyzes the repository and responds to the command
|
||||
@@ -126,6 +126,15 @@ The `awsCredentialProvider.js` utility handles credential retrieval and rotation
|
||||
- Container execution settings
|
||||
- Webhook URL and port configuration
|
||||
|
||||
### Required Environment Variables
|
||||
- `BOT_USERNAME`: GitHub username that the bot responds to (e.g., `@ClaudeBot`)
|
||||
- `DEFAULT_AUTHORIZED_USER`: Default GitHub username authorized to use the bot (if AUTHORIZED_USERS is not set)
|
||||
- `AUTHORIZED_USERS`: Comma-separated list of GitHub usernames authorized to use the bot
|
||||
- `BOT_EMAIL`: Email address used for git commits made by the bot
|
||||
- `GITHUB_WEBHOOK_SECRET`: Secret for validating GitHub webhook payloads
|
||||
- `GITHUB_TOKEN`: GitHub token for API access
|
||||
- `ANTHROPIC_API_KEY`: Anthropic API key for Claude access
|
||||
|
||||
## Code Style Guidelines
|
||||
- JavaScript with Node.js
|
||||
- Use async/await for asynchronous operations
|
||||
|
||||
@@ -89,10 +89,15 @@ For comprehensive documentation, see:
|
||||
- This setting is required to prevent infinite loops
|
||||
- Example: `BOT_USERNAME=@MyBot`
|
||||
- No default is provided - this must be explicitly configured
|
||||
- Set `BOT_EMAIL` for the email address used in git commits made by the bot
|
||||
- Set `DEFAULT_AUTHORIZED_USER` to specify the default GitHub username authorized to use the bot
|
||||
- Use `AUTHORIZED_USERS` for a comma-separated list of GitHub usernames allowed to use the bot
|
||||
|
||||
**e. Server Port and Other Settings**
|
||||
- By default, the server runs on port 3000
|
||||
- To use a different port, set the `PORT` environment variable in your `.env` file
|
||||
- Set `DEFAULT_GITHUB_OWNER` and `DEFAULT_GITHUB_USER` for CLI defaults when using the webhook CLI
|
||||
- Set `TEST_REPO_FULL_NAME` to configure the default repository for test scripts
|
||||
- Review other settings in the `.env` file for customization options
|
||||
|
||||
**AWS Credentials**: The service now supports multiple AWS authentication methods:
|
||||
@@ -264,6 +269,7 @@ To enable container-based execution:
|
||||
CLAUDE_CONTAINER_IMAGE=claudecode:latest
|
||||
REPO_CACHE_DIR=/path/to/cache # Optional
|
||||
REPO_CACHE_MAX_AGE_MS=3600000 # Optional, defaults to 1 hour (in milliseconds)
|
||||
CONTAINER_LIFETIME_MS=7200000 # Optional, container execution timeout in milliseconds (defaults to 2 hours)
|
||||
```
|
||||
|
||||
### Container Test Utility
|
||||
|
||||
@@ -41,9 +41,9 @@ else
|
||||
sudo -u node git checkout main >&2 || sudo -u node git checkout master >&2
|
||||
fi
|
||||
|
||||
# Configure git for commits
|
||||
sudo -u node git config --global user.email "claude@mcp.ai"
|
||||
sudo -u node git config --global user.name "MCPClaude"
|
||||
# Configure git for commits using environment variables (with defaults)
|
||||
sudo -u node git config --global user.email "${BOT_EMAIL:-claude@example.com}"
|
||||
sudo -u node git config --global user.name "${BOT_USERNAME:-ClaudeBot}"
|
||||
|
||||
# Configure Anthropic API key
|
||||
export ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY}"
|
||||
|
||||
@@ -25,7 +25,7 @@ GITHUB_TOKEN=your-github-token
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
# Using the wrapper script (defaults to Cheffromspace user)
|
||||
# Using the wrapper script (defaults to the DEFAULT_GITHUB_OWNER env variable)
|
||||
./claude-webhook myrepo "Your command for Claude"
|
||||
|
||||
# With explicit owner
|
||||
@@ -38,7 +38,7 @@ node cli/webhook-cli.js --repo myrepo --command "Your command"
|
||||
### Options
|
||||
|
||||
- `-r, --repo <repo>`: GitHub repository (format: owner/repo or repo) [required]
|
||||
- If only repo name is provided, defaults to `Cheffromspace/repo`
|
||||
- If only repo name is provided, defaults to `${DEFAULT_GITHUB_OWNER}/repo`
|
||||
- `-c, --command <command>`: Command to send to Claude [required]
|
||||
- `-i, --issue <number>`: Issue number (default: 1)
|
||||
- `-p, --pr`: Treat as pull request instead of issue
|
||||
@@ -51,7 +51,7 @@ node cli/webhook-cli.js --repo myrepo --command "Your command"
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Basic issue comment (defaults to Cheffromspace user)
|
||||
# Basic issue comment (uses default owner)
|
||||
./claude-webhook myrepo "Analyze the code structure"
|
||||
|
||||
# With explicit owner
|
||||
@@ -79,7 +79,7 @@ The CLI will display:
|
||||
|
||||
Example output:
|
||||
```
|
||||
🚀 Sending command to Claude for Cheffromspace/myrepo...
|
||||
🚀 Sending command to Claude for owner/myrepo...
|
||||
📋 Command: Analyze the code structure
|
||||
📄 Type: Issue
|
||||
|
||||
@@ -93,7 +93,7 @@ Here's an analysis of the code structure...
|
||||
|
||||
📍 Context:
|
||||
{
|
||||
"repo": "Cheffromspace/myrepo",
|
||||
"repo": "owner/myrepo",
|
||||
"issue": 1,
|
||||
"type": "issue_comment"
|
||||
}
|
||||
|
||||
@@ -34,5 +34,5 @@ echo "2. Run the CLI with: ./claude-webhook myrepo \"Your command\""
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " ./claude-webhook myrepo \"List all files\""
|
||||
echo " ./claude-webhook Cheffromspace/myrepo \"Analyze code structure\""
|
||||
echo " ./claude-webhook owner/myrepo \"Analyze code structure\""
|
||||
echo " ./claude-webhook myrepo \"Review PR\" -p -b feature-branch"
|
||||
@@ -35,8 +35,8 @@ GitHub → Webhook Service → Docker Container → Claude API
|
||||
|
||||
### 3. Command Extraction
|
||||
|
||||
1. Checks for `@MCPClaude` mention in comment body
|
||||
2. Extracts command using regex: `/@MCPClaude\s+(.*)/s`
|
||||
1. Checks for bot mention in comment body (using BOT_USERNAME env variable)
|
||||
2. Extracts command using regex pattern based on configured bot username
|
||||
3. Captures:
|
||||
- Repository full name
|
||||
- Issue/PR number
|
||||
|
||||
@@ -31,6 +31,10 @@ These issues may be related to:
|
||||
- Docker engine configuration
|
||||
- Claude CLI output mechanism
|
||||
|
||||
### Container Execution Timeout
|
||||
|
||||
By default, containers have a 2-hour lifetime before being terminated. This can be configured via the `CONTAINER_LIFETIME_MS` environment variable (in milliseconds). For complex tasks requiring more time, you can increase this value.
|
||||
|
||||
### Claude Authentication
|
||||
|
||||
Another issue was authentication for the Claude CLI inside the container:
|
||||
@@ -63,7 +67,7 @@ To properly enable full Claude execution in containers, consider:
|
||||
|
||||
The current workaround, as implemented in `claudeService.js`, provides a reliable and useful service while addressing these limitations:
|
||||
|
||||
1. For known repositories (like MCPControl), we provide curated responses
|
||||
1. For known repositories (configured via environment variables), we provide curated responses
|
||||
2. For other repositories, we automatically:
|
||||
- Clone the repository (or use cache)
|
||||
- Analyze its structure
|
||||
@@ -77,8 +81,8 @@ This approach provides value while the container execution issues are resolved.
|
||||
You can test the current implementation using the provided test utilities:
|
||||
|
||||
```bash
|
||||
# Test with MCPControl repository (uses predefined response)
|
||||
./test-container.js Cheffromspace/MCPControl "What is this repository about?"
|
||||
# Test with a repository (uses predefined response if known)
|
||||
./test-container.js owner/repo "What is this repository about?"
|
||||
|
||||
# Test with any other repository (uses automatic analysis)
|
||||
./test-container.js n8n-io/n8n "What is this repository about?"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# GitHub Workflow with MCPClaude
|
||||
# GitHub Workflow with Claude Webhook
|
||||
|
||||
This document describes how the GitHub webhook integration works with Claude Code CLI.
|
||||
|
||||
## Overview
|
||||
|
||||
When someone mentions `@MCPClaude` in a GitHub issue or pull request comment, the following workflow is triggered:
|
||||
When someone mentions the configured bot (via BOT_USERNAME environment variable) in a GitHub issue or pull request comment, the following workflow is triggered:
|
||||
|
||||
1. GitHub sends a webhook to our service
|
||||
2. The service validates the webhook signature
|
||||
3. If valid, it extracts the command after `@MCPClaude`
|
||||
3. If valid, it extracts the command after the bot username
|
||||
4. A Docker container is spun up with Claude Code CLI
|
||||
5. The repository is cloned and the correct branch is checked out
|
||||
6. Claude Code executes the command with full GitHub CLI access
|
||||
@@ -38,9 +38,9 @@ Each request runs in an isolated Docker container with:
|
||||
|
||||
## Supported Events
|
||||
|
||||
- **Issue Comments**: When `@MCPClaude` is mentioned in an issue comment
|
||||
- **Pull Request Comments**: When `@MCPClaude` is mentioned in a PR comment
|
||||
- **Pull Request Review Comments**: When `@MCPClaude` is mentioned in a PR review
|
||||
- **Issue Comments**: When the bot is mentioned in an issue comment
|
||||
- **Pull Request Comments**: When the bot is mentioned in a PR comment
|
||||
- **Pull Request Review Comments**: When the bot is mentioned in a PR review
|
||||
|
||||
## Authentication
|
||||
|
||||
@@ -54,7 +54,7 @@ The following credentials are required:
|
||||
In a GitHub issue or PR comment:
|
||||
|
||||
```
|
||||
@MCPClaude Please analyze the performance of the current implementation and suggest optimizations.
|
||||
@ClaudeBot Please analyze the performance of the current implementation and suggest optimizations.
|
||||
```
|
||||
|
||||
Claude will:
|
||||
|
||||
@@ -6,11 +6,11 @@ This document describes the workflow for how GitHub comments trigger Claude resp
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[GitHub Comment with @MCPClaude] -->|Triggers| B[GitHub Webhook Event]
|
||||
A[GitHub Comment with bot mention] -->|Triggers| B[GitHub Webhook Event]
|
||||
B -->|POST Request| C[claude.jonathanflatt.org API]
|
||||
C -->|/api/webhooks/github| D[Express Server]
|
||||
D -->|githubController.handleWebhook| E[Webhook Verification]
|
||||
E -->|issue_comment event| F[Check for @MCPClaude mention]
|
||||
E -->|issue_comment event| F[Check for bot mention]
|
||||
F -->|Extract command| G[claudeService.processCommand]
|
||||
G -->|Clone repository| H[Create temporary directory]
|
||||
H -->|Run Claude Code CLI| I[claude --print command]
|
||||
@@ -22,7 +22,7 @@ graph TD
|
||||
## Detailed Flow
|
||||
|
||||
1. **GitHub Comment Trigger**
|
||||
- User creates a GitHub comment mentioning "@MCPClaude" with a command
|
||||
- User creates a GitHub comment mentioning the bot with a command
|
||||
- GitHub detects the comment creation event
|
||||
|
||||
2. **Webhook Delivery**
|
||||
@@ -38,7 +38,7 @@ graph TD
|
||||
- Validates the event type is `issue_comment` and action is `created`
|
||||
|
||||
5. **Command Extraction**
|
||||
- For issue comments, the code checks for "@MCPClaude" mentions
|
||||
- For issue comments, the code checks for mentions of the configured bot username
|
||||
- If found, it extracts the command text that follows the mention
|
||||
|
||||
6. **Claude Service Processing**
|
||||
|
||||
@@ -105,7 +105,7 @@ async function handleWebhook(req, res) {
|
||||
// Check if the comment author is authorized
|
||||
const authorizedUsers = process.env.AUTHORIZED_USERS ?
|
||||
process.env.AUTHORIZED_USERS.split(',').map(user => user.trim()) :
|
||||
['Cheffromspace']; // Default authorized users
|
||||
[process.env.DEFAULT_AUTHORIZED_USER || 'admin']; // Default authorized user
|
||||
const commentAuthor = comment.user.login;
|
||||
|
||||
if (!authorizedUsers.includes(commentAuthor)) {
|
||||
|
||||
@@ -195,9 +195,13 @@ Please complete this task fully and autonomously.`;
|
||||
}
|
||||
};
|
||||
|
||||
// Get container lifetime from environment variable or use default (2 hours)
|
||||
const containerLifetimeMs = parseInt(process.env.CONTAINER_LIFETIME_MS, 10) || 7200000; // 2 hours in milliseconds
|
||||
logger.info({ containerLifetimeMs }, 'Setting container lifetime');
|
||||
|
||||
const result = await execAsync(dockerCommand, {
|
||||
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
||||
timeout: 600000 // 10 minute timeout
|
||||
timeout: containerLifetimeMs // Container lifetime in milliseconds
|
||||
});
|
||||
|
||||
// Clean up temporary files used for command passing
|
||||
|
||||
@@ -27,8 +27,9 @@ function sanitizeBotMentions(text) {
|
||||
// Look for the username with @ symbol anywhere in the text
|
||||
const botMentionRegex = new RegExp(escapedUsername, 'gi');
|
||||
|
||||
// Replace mentions with a sanitized version (remove @ symbol)
|
||||
const sanitized = text.replace(botMentionRegex, 'MCPControl');
|
||||
// Replace mentions with a sanitized version (remove @ symbol if present)
|
||||
const sanitizedName = BOT_USERNAME.startsWith('@') ? BOT_USERNAME.substring(1) : BOT_USERNAME;
|
||||
const sanitized = text.replace(botMentionRegex, sanitizedName);
|
||||
|
||||
// If sanitization occurred, log it
|
||||
if (sanitized !== text) {
|
||||
|
||||
@@ -10,7 +10,7 @@ docker run --rm \
|
||||
--cap-add=AUDIT_WRITE \
|
||||
--cap-add=SYS_ADMIN \
|
||||
-v $HOME/.aws:/home/node/.aws:ro \
|
||||
-e REPO_FULL_NAME="Cheffromspace/MCPControl" \
|
||||
-e REPO_FULL_NAME="${TEST_REPO_FULL_NAME:-owner/repo}" \
|
||||
-e ISSUE_NUMBER="1" \
|
||||
-e IS_PULL_REQUEST="false" \
|
||||
-e COMMAND="What is this repository?" \
|
||||
|
||||
@@ -10,7 +10,7 @@ docker run --rm \
|
||||
--cap-add=AUDIT_WRITE \
|
||||
--cap-add=SYS_ADMIN \
|
||||
-v $HOME/.aws:/home/node/.aws:ro \
|
||||
-e REPO_FULL_NAME="Cheffromspace/MCPControl" \
|
||||
-e REPO_FULL_NAME="${TEST_REPO_FULL_NAME:-owner/repo}" \
|
||||
-e ISSUE_NUMBER="1" \
|
||||
-e IS_PULL_REQUEST="false" \
|
||||
-e COMMAND="echo test" \
|
||||
|
||||
@@ -3,7 +3,7 @@ echo "Testing full entrypoint flow..."
|
||||
|
||||
docker run --rm -i \
|
||||
-v $HOME/.aws:/home/node/.aws:ro \
|
||||
-e REPO_FULL_NAME="Cheffromspace/MCPControl" \
|
||||
-e REPO_FULL_NAME="${TEST_REPO_FULL_NAME:-owner/repo}" \
|
||||
-e ISSUE_NUMBER="1" \
|
||||
-e IS_PULL_REQUEST="false" \
|
||||
-e COMMAND="echo 'test'" \
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"action": "created",
|
||||
"comment": {
|
||||
"id": 1234567890,
|
||||
"body": "@MCPClaude What is the purpose of the authentication function in this repo?",
|
||||
"body": "@ClaudeBot What is the purpose of the authentication function in this repo?",
|
||||
"user": {
|
||||
"login": "testuser"
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ const payload = {
|
||||
},
|
||||
comment: {
|
||||
id: 123,
|
||||
body: '@MCPClaude Test command for webhook response',
|
||||
body: `${process.env.BOT_USERNAME || '@ClaudeBot'} Test command for webhook response`,
|
||||
user: {
|
||||
login: 'testuser'
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ docker run --rm \
|
||||
--cap-add=AUDIT_WRITE \
|
||||
--cap-add=SYS_ADMIN \
|
||||
-v $HOME/.aws:/home/node/.aws:ro \
|
||||
-e REPO_FULL_NAME="Cheffromspace/MCPControl" \
|
||||
-e REPO_FULL_NAME="${TEST_REPO_FULL_NAME:-owner/repo}" \
|
||||
-e ISSUE_NUMBER="1" \
|
||||
-e IS_PULL_REQUEST="false" \
|
||||
-e COMMAND="What is this repository?" \
|
||||
|
||||
Reference in New Issue
Block a user