An MCP server for applying strategy practice frameworks — Wardley Maps first (value chain, evolution, climates, doctrines, the full study cycle). It exposes a small set of MCP tools backed by a pluggable strategy registry orchestrated by a recipe runner.
It runs as a local server that an MCP client — Claude Code / the Claude Agent SDK, or any MCP-capable client — launches over stdio. An HTTP daemon transport is also available (SaaS-ready by design).
- Node.js ≥ 20
- An LLM provider configured via
llm.config.json(see LLM configuration). Most tools call an LLM; without a provider they degrade rather than crash, but produce no analysis.
Add the server to your project's .mcp.json (or ~/.claude.json). Claude Code spawns the process itself — there is no daemon to keep running:
{
"mcpServers": {
"labre-mcp": {
"command": "npx",
"args": ["-y", "@formicoidea/labre-mcp"],
"env": {
"WARDLEY_LLM_CONFIG": "C:\\path\\to\\your\\llm.config.json"
}
}
}
}Windows note: if
npxfails to start the server, wrap it as"command": "cmd","args": ["/c", "npx", "-y", "@formicoidea/labre-mcp"].
The WARDLEY_LLM_CONFIG env var is optional — if omitted, the server looks for llm.config.json in the client's working directory (your workspace root).
| Tool | Purpose |
|---|---|
estimateEvolution |
Estimate the Wardley evolution position of a component (runs the estimate-component-evolution recipe). |
runCommand |
Invoke a single strategy directly by its 5-segment methodId → CommandResult + JSON-labre envelope. |
runRecipe |
Run a multi-step recipe by <domain>:<tool>:<name> reference → JSON-labre envelope + final AST + artifact path. |
__ping__ |
Smoke tool — echoes its input. Validates the transport. |
The full methodId catalogue lives in docs/architecture/ast-schema.md; recipes in docs/architecture/recipes.md.
Copy llm.config.example.json to llm.config.json and point WARDLEY_LLM_CONFIG at it (or place it in your workspace root). Three provider kinds are supported:
agent-sdk— the Claude Agent SDK (claude).http-api— an OpenAI-compatible gateway (e.g. OpenCode/Kimi with logprobs).copilot-sdk— GitHub Copilot.
Per-strategy provider/model/effort overrides are declared under strategies in the same file.
Some strategies use external services and degrade gracefully when their config is absent:
- BigQuery patent analysis (CPC evolution):
BIGQUERY_PROJECT_ID,GOOGLE_APPLICATION_CREDENTIALS. - Web search (Agent SDK):
ANTHROPIC_API_KEY.
Each recipe run writes a verbose, analysis-ready JSON artifact to ~/.labre-mcp/runs/<projectId>/<runId>.json.
For local development or a SaaS-style deployment, the server can run as an HTTP daemon instead of stdio:
npm run build
npm run mcp:prod # node dist/core/transport/labre-daemon.mjsIt listens on 127.0.0.1:6767 (override with LABRE_HTTP_PORT / LABRE_HTTP_HOST — set LABRE_HTTP_HOST=0.0.0.0 behind a PaaS router). Point the client at it with:
{ "mcpServers": { "labre-mcp": { "type": "http", "url": "http://127.0.0.1:6767/mcp" } } }See docs/architecture/transport.md for the transport model.
The daemon can run as a stateless, authenticated server. All features below are opt-in via environment variables read at boot only; without them the daemon behaves exactly like the local dev setup above. The stdio transport is never affected.
| Variable | Effect |
|---|---|
LABRE_AUTH |
Comma-separated list of the auth doors to open — any of supabase, oidc, api-key (order-independent). Every accepted credential family is named explicitly; unset / none / empty → no auth (local dev). Each listed door fails closed on its own env (boot refuses, naming the door + missing var). Invalid/missing bearer → HTTP 401 (JSON-RPC -32001). Examples: supabase,oidc,api-key (all), oidc (federated JWT only, no static secret), api-key (static lab_ keys only). |
door supabase |
Supabase session JWTs (Authorization: Bearer) verified against the project JWKS. Requires SUPABASE_URL. The only door whose tokens pass Supabase RLS, so the only one that can refresh remote bundles. |
door oidc |
Bearer verification against any OIDC IdP (Okta, Auth0, Clerk, Entra, Keycloak, … and the labre OAuth AS). Requires AUTH_JWKS_URL + AUTH_AUDIENCE; optional AUTH_ISSUER (recommended) and AUTH_ROLE_CLAIM (default role). GitHub sign-in is supported by federating GitHub through the IdP (GitHub's own user tokens are opaque and cannot be JWKS-verified). Remote bundles stay off for this population (they are Supabase-RLS-bound). When supabase is also listed, each bearer is routed on its iss claim. |
door api-key |
lab_ personal keys (created in the labre UI), validated by the validate_api_key RPC — not a JWT. Requires SUPABASE_URL + SUPABASE_ANON_KEY. Composes alongside the JWT doors, or stands alone. |
SUPABASE_URL |
Supabase project URL (JWKS endpoint derivation + bundle source). |
SUPABASE_JWT_AUD |
Expected aud claim (default authenticated). |
SUPABASE_ANON_KEY |
Enables the remote strategy-bundle source: declarative bundles (recipes + prompts, no code) published by the labre admin are fetched lazily with the caller's own token (RLS authorizes; the daemon holds no privileged credential) and verified file-by-file against their recorded sha256 before registration. |
LABRE_BUNDLES_TTL_S |
Bundle refresh throttle in seconds (default 300). |
LABRE_MCP_ADMIN_TOKEN |
Enables the read-only GET /config/llm ops endpoint (Labre admin console, Framework-MCP section). A shared ops secret sent as Authorization: Bearer <token>, distinct from the per-user /mcp auth above. Unset → endpoint returns 503; missing/wrong token → 401. Returns the live LLM config with a per-provider hasKey boolean — never secret values. |
POSTHOG_API_KEY |
Enables recipe rollout flags (mcp-recipe-<domain>-<tool>-<name>, fail-open) and metadata-only run telemetry (mcp_boot, mcp_run_end, mcp_step_error — never payloads or prompts). |
POSTHOG_HOST |
PostHog ingestion host (default US cloud). |
Secrets never ship with this package and are never required by the stdio transport. The anon key is Supabase's public client key; the service-role key is never used by this server.
npm install
npm run mcp:stdio # stdio server via tsx (dev)
npm run mcp # HTTP daemon via tsx (dev)
npm run typecheck
npm run test # unit tests (some integration tests call real LLMs — see AGENT.md)Architecture and decision records are under docs/architecture/ — start with ast-schema.md and decisions.md.
ISC