aibridge is an HTTP gateway that sits between AI clients and upstream AI providers (Anthropic, OpenAI). It intercepts requests to record token usage, prompts, and tool invocations per user. Optionally supports centralized MCP tool injection with allowlist/denylist filtering.
┌─────────────────┐ ┌───────────────────────────────────────────┐
│ AI Client │ │ aibridge │
│ (Claude Code, │────▶│ ┌─────────────────┐ ┌─────────────┐ │
│ Cursor, etc.) │ │ │ RequestBridge │───▶│ Providers │ │
└─────────────────┘ │ │ (http.Handler) │ │ (Anthropic │ │
│ └─────────────────┘ │ OpenAI) │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │ ┌─────────────┐
│ ┌─────────────────┐ ┌─────────────┐ │ │ Upstream │
│ │ Recorder │◀───│ Interceptor │─── ───▶│ API │
│ │ (tokens, tools, │ │ (streaming/ │ │ │ (Anthropic │
│ │ prompts) │ │ blocking) │ │ │ OpenAI) │
│ └────────┬────────┘ └──────┬──────┘ │ └─────────────┘
│ │ │ │
│ ▼ ┌──────▼──────┐ │
│ ┌ ─ ─ ─ ─ ─ ─ ─ ┐ │ MCP Proxy │ │
│ │ Database │ │ (tools) │ │
│ └ ─ ─ ─ ─ ─ ─ ─ ┘ └─────────────┘ │
└───────────────────────────────────────────┘
http.Handler that routes requests to providers/anthropic/v1/messages or /openai/v1/chat/completionsAsActor()).With MCP enabled: Tools from configured MCP servers are centrally defined and injected into requests (prefixed bmcp_). Allowlist/denylist regex patterns control which tools are available. When the model selects an injected tool, the gateway invokes it in an inner agentic loop, and continues the conversation loop until complete.
Passthrough routes (/v1/models, /v1/messages/count_tokens) are reverse-proxied directly.
Create metrics with NewMetrics(prometheus.Registerer):
| Metric | Type | Description |
|---|---|---|
interceptions_total |
Counter | Intercepted request count |
interceptions_inflight |
Gauge | Currently processing requests |
interceptions_duration_seconds |
Histogram | Request duration |
tokens_total |
Counter | Token usage (input/output) |
prompts_total |
Counter | User prompt count |
injected_tool_invocations_total |
Counter | MCP tool invocations |
passthrough_total |
Counter | Non-intercepted requests |
Implement Recorder to persist usage data to your database. The example uses SQLite (example/recorder.go):
aibridge_interceptions - request metadata (provider, model, initiator, timestamps)aibridge_token_usages - input/output token counts per responseaibridge_user_prompts - user promptsaibridge_tool_usages - tool invocations (injected and client-defined)type Recorder interface {
RecordInterception(ctx context.Context, req *InterceptionRecord) error
RecordInterceptionEnded(ctx context.Context, req *InterceptionRecordEnded) error
RecordTokenUsage(ctx context.Context, req *TokenUsageRecord) error
RecordPromptUsage(ctx context.Context, req *PromptUsageRecord) error
RecordToolUsage(ctx context.Context, req *ToolUsageRecord) error
}
See example/ for a complete runnable example with SQLite persistence and DeepWiki MCP integration.
OpenAI: https://platform.openai.com/api-keys
Set environment variables:
bash
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
Run the example:
bash
cd example && go run .
Test with curl:
bash
curl -X POST http://localhost:8080/anthropic/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}'
Test with Claude Code:
Claude Code allows a base URL override via ANTHROPIC_BASE_URL.

| Provider | Route | Type |
|---|---|---|
| Anthropic | /anthropic/v1/messages |
Bridged (intercepted) |
| Anthropic | /anthropic/v1/models |
Passthrough |
| Anthropic | /anthropic/v1/messages/count_tokens |
Passthrough |
| OpenAI | /openai/v1/chat/completions |
Bridged (intercepted) |
| OpenAI | /openai/v1/models |
Passthrough |
$ claude mcp add aibridge \
-- python -m otcore.mcp_server <graph>