MCP Middleware Integration
Add DRS verification to an MCP server. The Go middleware handles all verification — your tool handler code does not change.
How it works
MCP Client
│ POST /mcp/tools/call
│ X-DRS-Bundle: <base64url bundle>
▼
drs-verify middleware
│ parse bundle
│ run verify_chain (blocks A–F)
▼ VALID
Your tool handler
▼
Response + drs:tool-call event emitted
If verification fails, the middleware returns 403 with a JSON error body before your handler is called.
Option A: Go middleware (native)
If your MCP server is in Go, import the middleware package directly:
package main
import (
"net/http"
"time"
"github.com/yourorg/drs/drs-verify/pkg/middleware"
"github.com/yourorg/drs/drs-verify/pkg/resolver"
"github.com/yourorg/drs/drs-verify/pkg/verify"
)
func main() {
res, _ := resolver.New(10_000, time.Hour)
verifier := verify.New(res)
mcp := middleware.NewMCP(verifier, middleware.MCPConfig{
RequireBundle: true, // 403 on missing X-DRS-Bundle header
EmitEvents: true, // emit drs:tool-call events
})
mux := http.NewServeMux()
mux.Handle("/mcp/", mcp.Wrap(yourMCPHandler))
http.ListenAndServe(":8080", mux)
}
Option B: Sidecar (any language)
Run drs-verify as a sidecar in front of your server. It listens on :8081 and proxies verified requests to your server on :8080:
docker run -d \
--name drs-verify \
--network host \
-e DRS_LISTEN_ADDR=:8081 \
-e DRS_UPSTREAM=http://localhost:8080 \
-e DRS_REQUIRE_BUNDLE=true \
ghcr.io/okeyamy/drs-verify:latest
Point your MCP client at :8081. Your server on :8080 only receives requests that have passed full verification.
Option C: TypeScript VerifyClient
For TypeScript MCP servers that need fine-grained control:
import { VerifyClient, parseBundle } from '@drs/sdk';
const drs = new VerifyClient({ baseUrl: process.env.DRS_VERIFY_URL! });
app.post('/mcp/tools/call', async (req, res) => {
const bundleHeader = req.headers['x-drs-bundle'] as string;
if (!bundleHeader) {
return res.status(403).json({ error: 'DRS bundle required' });
}
const result = await drs.verify(bundleHeader);
if (!result.valid) {
return res.status(403).json({
error: result.error,
block: result.block,
message: result.message,
});
}
// result.context contains:
// root_principal, subject, chain_depth, policy_result
return executeTool(req.body, result.context);
});
Testing your integration
# Valid bundle — expect 200
DRS_VERIFY_URL=http://localhost:8081 pnpm exec drs verify bundle.json
# Missing bundle — expect 403
curl -X POST http://localhost:8081/mcp/tools/call \
-H "Content-Type: application/json" \
-d '{"tool":"web_search","query":"test"}'
# {"error":"DRS bundle required"}
# Tampered bundle — expect 403
curl -X POST http://localhost:8081/mcp/tools/call \
-H "X-DRS-Bundle: $(echo 'corrupt' | base64)" \
-H "Content-Type: application/json" \
-d '{"tool":"web_search","query":"test"}'
# {"error":"BUNDLE_INCOMPLETE","block":"A","message":"..."}