HACKATHON.md•7.47 kB
# BYOB MCP Server - Bring Your Own Binary
A proof-of-concept MCP (Model Context Protocol) server that enables dynamic tool registration using Cloudflare Containers. This demonstrates the architecture for allowing AI agents to invoke arbitrary containerized tools securely at scale.
## Architecture
```
┌─────────────┐
│ AI Agent │
│ (Claude) │
└──────┬──────┘
│ MCP Protocol
▼
┌─────────────────────────────────────────┐
│ Cloudflare Worker (MCP Server) │
│ ┌─────────────────────────────────┐ │
│ │ Dynamic Tool Registry (D1) │ │
│ │ - Tool metadata & schemas │ │
│ └─────────────────────────────────┘ │
└──────┬──────────────────────────────────┘
│ HTTP Fetch
▼
┌─────────────────────────────────────────┐
│ Cloudflare Containers (Durable Objects)│
│ ┌──────────┐ ┌──────────┐ │
│ │ Echo │ │ JQ │ │
│ │Container │ │Container │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────┘
```
## Key Components
### 1. D1 Tool Registry
Stores tool definitions with:
- Name & description
- JSON Schema for inputs
- Container class reference
- Runtime configuration
### 2. MCP Server (Worker)
- `/mcp` - MCP protocol endpoint (dynamically lists tools from D1)
- `/api/register-tool` - Register new tools via HTTP
- `/api/tools` - List all registered tools
### 3. Containers
Standardized HTTP interface on port 8080:
- **POST /execute** - Accepts JSON input, returns JSON output
- **Echo Container** - Simple echo service
- **JQ Container** - JSON query processor using jq
## Quick Start
### 1. Start Development Server
```bash
npm run dev
```
### 2. Test Health Check
```bash
curl http://localhost:8787/
```
### 3. List Available Tools
```bash
curl http://localhost:8787/api/tools
```
### 4. Register a New Tool
```bash
curl -X POST http://localhost:8787/api/register-tool \
-H "Content-Type: application/json" \
-d '{
"name": "custom_echo",
"description": "Custom echo tool with prefix",
"containerClass": "echo",
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Message to echo"
}
},
"required": ["message"]
}
}'
```
## Testing the MCP Server
### Option 1: Claude Desktop
Add to your Claude Desktop config:
```json
{
"mcpServers": {
"byob-server": {
"url": "http://localhost:8787/mcp"
}
}
}
```
### Option 2: HTTP Testing
Use the MCP Inspector or test via raw HTTP:
```bash
# Initialize MCP connection
curl -X POST http://localhost:8787/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
```
## Example Tools
### Echo Message
```json
{
"tool": "echo_message",
"args": {
"message": "Hello from BYOB!"
}
}
```
### Query JSON with jq
```json
{
"tool": "query_json",
"args": {
"filter": ".users[0].name",
"data": {
"users": [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25}
]
}
}
}
```
## Deployment
### 1. Run Migrations on Remote Database
```bash
npx wrangler d1 execute byob-tools-registry --remote --file=./migrations/0001_initial_schema.sql
npx wrangler d1 execute byob-tools-registry --remote --file=./migrations/0002_seed_example_tools.sql
```
### 2. Deploy to Cloudflare
```bash
npm run deploy
```
Note: First deployment may take several minutes for container images to build and deploy.
### 3. Test Deployment
```bash
curl https://byob-mcp-server.YOUR_ACCOUNT.workers.dev/api/tools
```
## Adding New Containers
### 1. Create Container Directory
```bash
mkdir -p containers/my-tool
```
### 2. Create Dockerfile
```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY server.js .
EXPOSE 8080
CMD ["node", "server.js"]
```
### 3. Implement HTTP Server
Must expose POST /execute endpoint that accepts and returns JSON.
See `containers/echo-server/` and `containers/jq-processor/` for examples.
### 4. Update wrangler.jsonc
Add container configuration:
```json
{
"containers": [
{
"class_name": "MyTool",
"image": "./containers/my-tool/Dockerfile",
"instance_type": "lite"
}
],
"durable_objects": {
"bindings": [
{
"name": "MY_TOOL_CONTAINER",
"class_name": "MyTool"
}
]
}
}
```
### 5. Add Container Class
In `src/containers.ts`:
```typescript
export class MyTool extends Container {
defaultPort = 8080;
sleepAfter = "10m";
}
```
### 6. Register Binding
In `src/containers.ts`, update `getContainerBinding()`:
```typescript
const bindingMap: Record<string, DurableObjectNamespace> = {
echo: env.ECHO_CONTAINER,
jq: env.JQ_CONTAINER,
mytool: env.MY_TOOL_CONTAINER, // Add this
};
```
## Architecture Highlights
### Dynamic Tool Discovery
- MCP server queries D1 on every connection
- Tools can be registered without redeploying the Worker
- Each tool invocation creates ephemeral container instance
### Stateless Containers
- Containers scale to zero when idle
- Each request may use a different container instance
- No state persisted between invocations
### Security
- Containers run in isolated sandboxes
- Resource limits enforced by instance type
- Ephemeral filesystems prevent state attacks
## Limitations & Future Work
### Current Limitations
1. **Static Container Classes**: Must redeploy Worker to add new container types
2. **No Image Registry**: Container images are built at deploy time
3. **Simplified Schema Validation**: Uses z.any() for dynamic schemas
4. **No Authentication**: Registration API is open
### Future Enhancements
1. **R2 Image Storage**: Store container images in R2 for true BYOB
2. **Dynamic Container Loading**: Load containers from registry at runtime
3. **Schema Validation**: Proper JSON Schema to Zod conversion
4. **Auth & Rate Limiting**: Secure the registration API
5. **Streaming Support**: WebSocket connections for long-running tools
6. **Tool Marketplace**: Public registry of community tools
## Technology Stack
- **Runtime**: Cloudflare Workers (V8 Isolates)
- **MCP Implementation**: mcp-lite (not @modelcontextprotocol/sdk)
- **Web Framework**: Hono
- **Database**: Cloudflare D1 (SQLite)
- **Containers**: Cloudflare Containers (via Durable Objects)
- **Schema Validation**: Zod
- **Deployment**: Wrangler CLI
## Resources
- [Cloudflare Containers Docs](https://developers.cloudflare.com/containers/)
- [MCP Protocol Spec](https://modelcontextprotocol.io/)
- [mcp-lite GitHub](https://github.com/fiberplane/mcp-lite)
- [Containers Examples](https://github.com/cloudflare/containers-demos)
## License
MIT - Built for hackathon purposes