The Mittwald MCP server exposes 116 tools that let MCP clients (Claude, ChatGPT, MCP Inspector, Cursor, Codex CLI) manage Mittwald hosting infrastructure on behalf of a user. Authentication flows through an OAuth bridge that fronts Mittwald's OAuth 2.1 endpoints using Authorization Code + PKCE only. Mittwald treats the bridge as a public client: there is no Mittwald-issued client secret to manage. The bridge mints its own secrets for downstream confidential MCP clients (e.g. Claude Desktop) and verifies them before issuing JWTs.
Mittwald remains authoritative for scopes and consent — the bridge renders no consent page of its own, and the scope string inside each issued JWT comes straight from Mittwald's token response. Clients register their redirect URI through /register (Dynamic Client Registration); see ARCHITECTURE.md for why that is mandatory.
| Service | URL | Image | Source |
|---|---|---|---|
| MCP server | https://mcp.mittwald.de | mittwald/mcp-server-http |
Dockerfile + src/ |
| OAuth bridge | https://auth.mcp.mittwald.de | mittwald/mcp-server-oauth |
packages/oauth-bridge/ |
Both run as containers in one mittwald container stack alongside a managed Redis, described by the
Terraform config in deploy/. Pushing a v* tag builds both images and applies that config — see
DEPLOY.md.
Connect a client with:
claude mcp add --transport http mittwald https://mcp.mittwald.de/mcpsrc/ # MCP server (JWT validation, sessions, tool handlers + definitions)
packages/
oauth-bridge/ # OAuth 2.1 proxy to Mittwald OAuth (Koa)
mittwald-cli-core/ # Mittwald CLI business logic as an importable library
deploy/ # Terraform config for the production container stack
docs/ # Operator runbooks and the two documentation sites
tests/ # Unit, integration, e2e, security, smoke, functional suites
evals/ # Agent-native E2E harness and prompt corpus
Prerequisite: Node.js 24.11.0 or higher (see
.nvmrc/.node-version). Earlier LTS releases (e.g. Node 18, Node 20) cannot run@mittwald/cli@1.12.0because its dependencies require the new/vregular-expression flag.
This is a monorepo with workspace packages that must be built in order.
-
Install all dependencies:
npm ci
-
Build the project (including all workspace dependencies):
npm run build:all
Or build workspace packages individually:
cd packages/mittwald-cli-core && npm run build && cd ../.. cd packages/oauth-bridge && npm run build && cd ../.. npm run build
OR use Docker (recommended for production builds):
docker build --no-cache -t mittwald/mcp .For local HTTPS development, generate certificates using mkcert:
# Install mkcert (macOS)
brew install mkcert
mkcert -install
# Generate certificates
mkdir -p ssl
mkcert -key-file ssl/localhost+2-key.pem -cert-file ssl/localhost+2.pem localhost 127.0.0.1 ::1The server uses these paths by default, or set SSL_KEY_PATH and SSL_CERT_PATH to override.
-
Configure scopes and Mittwald OAuth details:
export MITTWALD_ISSUER=https://id.mittwald.de export MITTWALD_CLIENT_ID=mittwald-mcp-server export MITTWALD_REDIRECT_URI=https://your-local-proxy/mittwald/callback
The OAuth and MCP services both read their scope catalogue from
config/mittwald-scopes.json. Update that file (or pointMITTWALD_SCOPE_CONFIG_PATHat an override) to change supported or default scopes—no code changes required. -
Run the OAuth bridge:
npm run --workspace=packages/oauth-bridge dev
-
Run the MCP server:
npm run build && node build/index.jsUse
npm run watchin a second shell to recompile on change.
Each service exposes health and debugging endpoints; consult ARCHITECTURE.md for flow diagrams and environment specifics.
Both the MCP Server and OAuth Bridge expose Prometheus-compatible metrics at /metrics.
| Variable | Description | Default |
|---|---|---|
METRICS_ENABLED |
Enable/disable metrics collection and /metrics endpoint |
true |
METRICS_USER |
Basic auth username for /metrics | (none - no auth) |
METRICS_PASS |
Basic auth password for /metrics | (none - no auth) |
Set METRICS_ENABLED=false to completely disable metrics collection and the /metrics endpoint.
When both METRICS_USER and METRICS_PASS are set, Basic Authentication is required to access the metrics endpoint.
| Metric | Type | Labels | Description |
|---|---|---|---|
mcp_tool_calls_total |
Counter | tool_name, status |
Total MCP tool invocations |
mcp_tool_duration_seconds |
Histogram | tool_name |
Tool execution duration |
mcp_tool_memory_delta_mb |
Histogram | tool_name |
Heap growth across a tool call |
mcp_active_connections |
Gauge | - | Current active MCP connections |
mcp_memory_pressure_percent |
Gauge | - | Heap used as a percentage of the limit |
mcp_cli_inflight |
Gauge | - | mw subprocesses currently running |
mcp_cli_queue_depth |
Gauge | - | Calls waiting for a CLI slot |
mcp_cli_queue_wait_seconds |
Histogram | - | Time spent waiting for a CLI slot |
mcp_client_versions_total |
Counter | - | Connecting client names/versions |
mcp_client_capabilities_total / _active |
Counter / Gauge | - | Capabilities negotiated by clients |
mcp_experimental_features_total |
Counter | - | Experimental capability usage |
mittwald_cli_calls_total |
Counter | command, status |
Mittwald CLI invocations |
| Metric | Type | Labels | Description |
|---|---|---|---|
oauth_authorization_requests_total |
Counter | client_id, status |
Authorization requests |
oauth_token_requests_total |
Counter | grant_type, status |
Token exchange requests |
oauth_dcr_registrations_total |
Counter | status |
DCR registrations |
oauth_pending_authorizations |
Gauge | - | Pending authorization requests |
oauth_pending_grants |
Gauge | - | Pending grants |
oauth_registered_clients |
Gauge | - | Registered OAuth clients |
oauth_state_store_size |
Gauge | - | Total Redis state store entries |
oauth_forced_reauth_total |
Counter | - | Flows that forced a re-authentication |
oauth_mittwald_token_refresh_total |
Counter | status |
Upstream token refreshes |
oauth_mittwald_token_refresh_duration_seconds |
Histogram | - | Upstream refresh duration |
Both services also expose default Node.js metrics (nodejs_*, process_*).
In production both containers require Basic auth (METRICS_USER / METRICS_PASS are set by
Terraform). Ports are 8080 for the MCP server and 3000 for the bridge:
scrape_configs:
- job_name: 'mittwald-mcp-server'
static_configs:
- targets: ['mcp-server:8080']
basic_auth:
username: metrics
password: your-secret
- job_name: 'mittwald-oauth-bridge'
static_configs:
- targets: ['oauth-bridge:3000']
basic_auth:
username: metrics
password: your-secret# Tool call rate per minute
rate(mcp_tool_calls_total[1m])
# Tool error rate
sum(rate(mcp_tool_calls_total{status="error"}[5m])) / sum(rate(mcp_tool_calls_total[5m]))
# 95th percentile tool latency
histogram_quantile(0.95, rate(mcp_tool_duration_seconds_bucket[5m]))
# OAuth token success rate
sum(rate(oauth_token_requests_total{status="success"}[5m])) / sum(rate(oauth_token_requests_total[5m]))
- Revoke access in mStudio to force downstream clients to re-authorize.
- The OAuth bridge logs the loaded scope configuration (counts, defaults, config file path). Any mismatch between Mittwald discovery and the configured list is surfaced there.
- Ensure Redis is available to both the bridge and MCP server (
BRIDGE_STATE_STORE=redis, shared session store).
- Run
npm run lint,npm run type-check, andnpm run test:unitfor fast local feedback. npm run test:integrationexercises Redis-backed session flows and bridge JWT verification.npm run test:e2e:mcpdrives a full OAuth + MCP tool cycle against the mock stack.- See
tests/README.mdfor the complete matrix and environment requirements.
This repository uses GitHub's native security features:
- Dependabot: Automatically creates PRs for vulnerable dependencies (configured in
.github/dependabot.yml) - CodeQL: Static analysis for security vulnerabilities on PRs and weekly scans (
.github/workflows/codeql.yml) - Secret Scanning: Prevents accidental commit of secrets (enable in repository Settings → Security)
- npm audit:
.github/workflows/security-check.ymlfails PRs with high/critical advisories
- Dependabot alerts: Review and merge dependency update PRs promptly. Security updates are grouped and labeled for easy identification.
- CodeQL findings: Address issues before merging PRs. The workflow blocks PRs with HIGH/CRITICAL severity findings.
- Secret scanning alerts: Rotate any compromised secrets immediately and revoke associated access.
mw-cli-coverage.jsoncontains machine-readable coverage stats for the Mittwald CLI.- Validate the artifact with
config/mw-cli-coverage.schema.json(e.g.npx ajv validate -s config/mw-cli-coverage.schema.json -d mw-cli-coverage.json). - Regenerate with
npm run coverage:generateand commit both the JSON anddocs/mittwald-cli-coverage.md. Only rerun when tool metadata, exclusion lists, or the Mittwald CLI version change—routine commits that don’t touch those inputs can skip regeneration. - Intentional gaps live in
config/mw-cli-exclusions.json. Update this allowlist (with rationale) whenever a missing CLI command is acceptable—CI fails ifstats.missingCountis greater than zero. - Quick commands:
npm run coverage:generate– rebuild artifacts when coverage inputs change.npm run check:cli-version– warn when Dockerfile pins drift from npm.
- See
docs/coverage.mdfor the full runbook covering CI guards and allowlist policy.
End-user docs are split across two static sites:
- Setup & Guides in
docs/setup-and-guides/(human-perspective onboarding, how-to, tutorials, runbooks, explainers) - Tool Reference in
docs/reference/(tool-by-tool reference pages and API-level details)
The Tool Reference is generated from the tool registry; see docs/reference/README.md before
editing it.
Operator runbooks:
docs/OPERATIONS-START-HERE.md(operator entrypoint)docs/DOCS-SITES-OPERATIONS.md(build and verify both documentation sites)docs/FUNCTIONAL-TESTING-OPERATIONS.md(run functional MCP testing in real agents against deployed endpoints)
One-command build for both sites:
cd docs
./build-all.sh localFor deployment-specific details, see DEPLOY.md.
For questions or onboarding guidance, start with ARCHITECTURE.md and docs/INDEX.md (docs navigation). LLM/agent operators should read docs/LLM-AGENTS.md.
For developer documentation on integrating with Mittwald MCP, see the setup guides in docs/setup-and-guides/ or visit the deployed documentation site.