Production MCP (Model Context Protocol) server exposing 30 DevOps tools for AI agents with a user approval system that prevents unauthorized write/destructive operations.
Exposes 29 tools + 1 approve_action tool across 4 services, guarded by a risk-based permission gate:
| Service | Tools | Read (Auto) | Write (Gated) | Destructive (Double Approval) |
|---|---|---|---|---|
| GitHub | 7 | All 7 | — | — |
| Calendar | 8 | 4 (list_calendars, query_events, get_event_details, find_free_slots) |
3 (create_event, update_event, add_attendee) |
1 (delete_event) |
| Database | 9 | 3 (execute_query, list_tables, describe_table) |
2 auto + 1 gated (insert_row, update_rows auto; delete_rows gated) |
3 (truncate_table, drop_table, migrate_schema) |
| Slack | 5 | 3 (list_channels, get_thread, get_channel_history) |
2 (send_message, send_thread_reply) |
— |
The permission gate intercepts medium+ risk tool calls and returns pending_approval instead of executing. The agent presents a structured request to the user, who confirms via the approve_action tool.
- Low risk → Auto-execute (reads)
- Medium/High → Single approval required
- Critical → Double approval required (two separate confirms)
- Timeout → Stale approvals auto-expire after 5 minutes
┌──────────────────────────────────────────────────┐
│ CLIENTS │
│ Claude Desktop (stdio) │ Custom Client (HTTP) │
└────────────┬─────────────────────┬───────────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────┐
│ MCP SERVER │
│ ┌────────────────────────────────────────────┐ │
│ │ Transport: stdio | Streamable HTTP │ │
│ │ Rate Limiter: 100 req/min user, 1000/hr IP│ │
│ │ Permission Gate: Risk → Pending/Execute │ │
│ │ Validation: Zod schemas on all inputs │ │
│ └────────────────────────────────────────────┘ │
└────────────┬─────────────────────┬───────────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────────┐
│ EXTERNAL APIs │
│ GitHub │ Google Calendar │ PostgreSQL │ Slack │
└──────────────────────────────────────────────────┘
npm install
npm run dev # stdio mode (default)
TRANSPORT=http PORT=3099 npm run dev # HTTP modeAdd to claude_desktop_config.json:
{
"mcpServers": {
"opsbridge": {
"command": "npx",
"args": ["tsx", "src/cli.ts"],
"env": {
"GITHUB_TOKEN": "ghp_...",
"DATABASE_URL": "postgresql://...",
"SLACK_TOKEN": "xoxb-...",
"CALENDAR_TOKEN": "ya29..."
}
}
}
}cp .env.example .env
# Edit .env with your tokens
docker compose up -d| Variable | Required | Description |
|---|---|---|
GITHUB_TOKEN |
No* | GitHub token (*required for private repos; public repos work without) |
DATABASE_URL |
No* | PostgreSQL connection string (*required for DB tools) |
SLACK_TOKEN |
No* | Slack bot token (xoxb-...) (*required for Slack tools) |
CALENDAR_TOKEN |
No* | Google Calendar OAuth token (*required for Calendar tools) |
TRANSPORT |
No | stdio (default) or http |
PORT |
No | HTTP port (default: 3002) |
- Permission gate: Risk-based approval for write/destructive operations; critical ops require double approval
- Read-only database: PostgreSQL session set to
READ ONLY+ write keyword blocklist - Rate limiting: LRU cache, 100 requests/minute per user, 1000/hour per IP
- Scoped tokens: Each service requires its own token
- Input validation: All tool inputs validated with Zod schemas
- No secrets in code: All tokens loaded from environment variables
- 5-minute approval timeout: Stale pending approvals auto-expire
npm run build # Compile TypeScript
npm run dev # Start dev server (stdio)
npm test # Run Vitest (71 tests)
npm run lint # Type check
npm run format # Prettier format- TypeScript 5.5+
@modelcontextprotocol/sdkv1.29 (MCP protocol)- Zod (input validation)
@octokit/rest(GitHub API)pg(PostgreSQL)lru-cache(rate limiting + approval store)- Vitest (testing)
MIT