A flexible proxy service that bridges Slack conversations with pluggable agentic systems, providing a seamless interface for users to interact with AI agents through Slack.
This service acts as a middleware layer between Slack and various AI agent backends (AWS Lambda, Docker containers). It receives Slack webhooks, fetches user configuration from a bootstrap server, forwards messages to the appropriate agent backend, and maintains session continuity across Slack threads.
- Multi-Backend Support: Run agents via AWS Lambda or Docker containers
- Session Persistence: Maintains conversation context across Slack threads
- Dual Deployment Modes: Deploy as HTTP server or AWS Lambda function
- Async Processing: Non-blocking message handling for responsive Slack interactions
- User Configuration: Dynamic user config fetching from bootstrap server
- Error Handling: Graceful error reporting back to Slack users
- Slack Handler: Processes incoming Slack webhooks and events
- Bootstrap Client: Fetches user-specific agent configurations
- Agent Clients: Interfaces with different agent backends (Lambda/Docker)
- Session Manager: PostgreSQL-based thread-to-session mapping
- Service Layer: Orchestrates the flow between components
- HTTP Server Mode: Standalone server receiving Slack webhooks
- Lambda Function Mode: Serverless deployment with API Gateway integration
- Docker Agent Mode: Local Docker container execution for development
- Go 1.24.3 or higher
- PostgreSQL database
- Slack App with Events API configured
- AWS credentials (for Lambda mode)
- Docker (for Docker agent mode)
- Clone the repository:
git clone https://github.com/pbdeuchler/agentcontainers-proxy
cd agentcontainers-proxy- Install dependencies:
go mod download- Set up the database:
# Run migrations using goose
goose -dir migrations postgres "$DATABASE_URL" up- Configure environment variables (see Configuration section)
| Variable | Description | Required | Default |
|---|---|---|---|
DATABASE_URL |
PostgreSQL connection string | Yes | - |
BOOTSTRAP_SERVER_URL |
Bootstrap server endpoint for user configs | Yes | - |
AGENT_LAMBDA_ARN |
ARN of the Claude Code Lambda function | Conditional* | - |
DOCKER_IMAGE_NAME |
Docker image for agent execution | Conditional* | - |
SLACK_BOT_TOKEN |
Slack Bot OAuth token | Yes | - |
SLACK_BOT_USER_ID |
Slack bot's user ID (to ignore self-messages) | No | - |
SLACK_SIGNING_SECRET |
Slack app signing secret | No | - |
PORT |
HTTP server port | No | 2010 |
ANTHROPIC_API_KEY |
API key for Claude (Docker mode) | Conditional** | - |
*Either AGENT_LAMBDA_ARN or DOCKER_IMAGE_NAME must be set
**Required when using Docker agent mode
Copy .env.example to .env and update with your values:
cp .env.example .env
# Edit .env with your configuration# Using go run
go run main.go
# Or build and run
go build -o agentcontainers-proxy
./agentcontainers-proxyThe service automatically detects Lambda environment:
- Build for Lambda:
GOOS=linux GOARCH=amd64 go build -o bootstrap main.go
zip function.zip bootstrap- Deploy to AWS Lambda with appropriate environment variables
To use Docker containers as the agent backend:
export DOCKER_IMAGE_NAME="your-agent-image:tag"
export ANTHROPIC_API_KEY="your-api-key"
go run main.gosequenceDiagram
participant Slack
participant Proxy
participant Bootstrap
participant Database
participant Agent
Slack->>Proxy: POST /slack/webhook
Proxy->>Bootstrap: GET ?slack_id={user_id}
Bootstrap-->>Proxy: User config
Proxy->>Database: Check thread_id mapping
Database-->>Proxy: session_id (if exists)
Proxy->>Agent: Invoke with prompt + session
Agent-->>Proxy: Response + session_id
Proxy->>Database: Store session mapping
Proxy->>Slack: Post reply to thread
Proxy-->>Slack: 200 OK
agentcontainers-proxy/
├── agentclients/ # Agent backend interfaces
│ ├── docker/ # Docker container client
│ ├── lambda/ # AWS Lambda client
│ └── types.go # Shared types
├── bootstrap/ # Bootstrap server client
├── cmd/ # Application entry points
│ ├── common.go # Shared initialization
│ ├── config.go # Configuration management
│ ├── lambda.go # Lambda handler
│ └── server.go # HTTP server
├── dao/ # Database access layer
├── migrations/ # Database migrations
├── service/ # Business logic layer
├── slack/ # Slack integration
│ ├── client.go # Slack API client
│ └── handler.go # Webhook handler
└── main.go # Main entry point
The service uses PostgreSQL to maintain session continuity:
CREATE TABLE session_mappings (
id SERIAL PRIMARY KEY,
thread_id VARCHAR(255) UNIQUE NOT NULL,
session_id VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_thread_id ON session_mappings(thread_id);- Create a new Slack App at https://api.slack.com/apps
- Enable Event Subscriptions
- Add Bot Token Scopes:
chat:writeapp_mentions:readmessages.channelsmessages.groupsmessages.immessages.mpim
- Subscribe to bot events:
message.channelsmessage.groupsmessage.immessage.mpim
- Set Request URL to your proxy endpoint:
- HTTP Server:
https://your-domain.com/slack/webhook - Lambda: Your API Gateway URL
- HTTP Server:
The bootstrap server must implement the following endpoint:
GET /bootstrap?slack_id={slack_user_id}
Response format:
{
"user": {...},
"prompt": "Initial system prompt",
"append_system_prompt": "Additional context",
"allowed_tools": ["tool1", "tool2"],
"disallowed_tools": ["tool3"],
"env": {...}
}{
"user": {...},
"prompt": "User message with context",
"append_system_prompt": "Additional instructions",
"allowed_tools": ["Read", "Write"],
"disallowed_tools": ["Delete"],
"env": {...},
"resume_session_id": "previous-session-id"
}{
"type": "result",
"subtype": "success",
"is_error": false,
"result": "Agent response text",
"session_id": "new-or-continued-session-id"
}go test ./...# Local build
go build -o agentcontainers-proxy
# Linux build for Lambda
GOOS=linux GOARCH=amd64 go build -o bootstrapEnable verbose logging by setting:
export DEBUG=trueThe service logs important events including:
- Incoming Slack messages
- Bootstrap server calls
- Agent invocations
- Database operations
- Error conditions
- Store sensitive environment variables securely
- Use HTTPS for all external communications
- Validate Slack requests using signing secret
- Implement rate limiting for production deployments
- Regularly rotate API keys and tokens
- Use least-privilege IAM roles for Lambda execution
- Database Connection Errors: Verify
DATABASE_URLformat and network access - Slack Not Responding: Check bot token permissions and webhook URL
- Agent Timeout: Increase Lambda timeout or check Docker resource limits
- Bootstrap Server Errors: Verify server URL and authentication
- Session Continuity Loss: Check database connectivity and migrations
# Test database connection
psql "$DATABASE_URL" -c "SELECT 1"
# Verify Slack token
curl -H "Authorization: Bearer $SLACK_BOT_TOKEN" https://slack.com/api/auth.test
# Check Lambda function
aws lambda get-function --function-name $AGENT_LAMBDA_ARN- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the GNU GPLv3 License with the Commons Clause License Condition v1.0.
For issues and questions, please open an issue on GitHub.