An MCP server that provides AI agent pattern expertise to AI coding agents. Analyses requirements, selects from a curated catalog of 61 agent patterns (ReAct, supervisor-worker, reflexion, self-RAG, LLMCompiler, …), generates concrete agent system designs with agents, relationships, and tool contracts, and evaluates them against quality attributes.
This Docker image contains a complete MCP (Model Context Protocol) server that brings agent design expertise to your AI coding agents. Given a requirements string and a domain, it:
final_quality_score (0–100) plus per-attribute scores (1–10)npx fetch; the deployed stacks set REASONING_FAIL_FAST=true so the server refuses to start when they are unreachable┌───────────────────────────────────────────────────────────────────┐
│ OpenCode / Claude Code / VS Code / any MCP client │
│ ────────── HTTP ──────────► :8061/mcp (Path A, compose) │
│ or :8051/mcp (Path B, systemd) │
│ │
│ ┌──────────────────────────────┐ │
│ │ agent-pattern-mcp │ │
│ │ container port 8051 │ │
│ └───────────────┬──────────────┘ │
│ │ │
│ ┌───────────────────┼────────────────────┐ │
│ │ pattern-tei-embed │ pattern-tei-rerank │ ← own copies (A) / │
│ │ :8080 (TEI) │ :8080 (TEI) │ pattern-tei-infra │
│ └───────────────────┴────────────────────┘ shared stack (B) │
└───────────────────────────────────────────────────────────────────┘
This image is the MCP server only. The TEI embedder and TEI reranker are separate infrastructure (published from the pattern-tei-infra project) as olkowa/pattern-tei-embed and olkowa/pattern-tei-rerank.
They connect via Docker DNS using the hostnames pattern-tei-embed and
pattern-tei-rerank on a shared Docker network — those are the defaults baked
into this image (EMBEDDER_BASE_URL=http://pattern-tei-embed:8080/v1,
RERANKER_BASE_URL=http://pattern-tei-rerank:8080), so no URL overrides are
required.
Two deployment paths (see INSTALL.md):
| Path A — Compose stack | Path B — systemd stack | |
|---|---|---|
| Use when | evaluating / developing; no sudo | persistent host service, starts at boot |
| Host port | 8061 | 8051 |
| TEI sidecars | own copies in the compose project | shared pattern-tei-infra stack via pattern-tei-shared network |
| Survives reboot | no (manual up -d) | yes (systemd unit, project agpmcp-systemd) |
The MCP server itself runs as a non-root user and serves StreamableHTTP on
container port 8051 (path /mcp). Startup takes up to ~40 s: retrieval
indexes (FAISS + BM25) are built at startup, and the server refuses to start
when the TEI sidecars are unreachable or the embedded reasoning MCPs cannot be
spawned (REASONING_FAIL_FAST=true in both deployed stacks).
| Tool | Description |
|---|---|
design_agent_system | Full pipeline (analyze → generate → evaluate → refine, up to 3 attempts). 5–10 min — use this unless your client has a short request timeout. Long-running (LLM call). Not idempotent. |
analyze_agent_system | Analyse requirements → recommended topology, patterns, quality metrics. Long-running (LLM call). Not idempotent. |
generate_agent_system | Generate an agent system design from requirements, topology, domain, and selected patterns. Long-running (LLM call). Not idempotent. |
evaluate_agent_system | Score an existing design against quality attributes. Long-running (LLM call). Not idempotent. |
submit_agent_design_job | Start a background job, get job_id immediately — for clients with short request timeouts |
get_agent_design_status | Poll job status every 10–30 s; returns the full design when completed |
cancel_agent_design | Cancel a running job (best-effort; takes effect at the next pipeline stage boundary) |
list_agent_patterns | List all 61 patterns; filter by category and/or domain |
get_agent_pattern | Get full JSON for a specific pattern by name |
Example call:
Call design_agent_system with:
requirements: "Research assistant combining web search with sandboxed code execution for multi-hop questions"
domain: "tool-use-tasks"
Patterns are also exposed as MCP resources: pattern:// (catalog list),
pattern://{name} (full pattern JSON), template://{name} (curated design
templates: react, supervisor-worker, multi-agent-debate, agentic-rag) and
component://{type} (component blueprints).
Note: where the sibling
architecture-pattern-mcpserver is also connected,pattern://{name}is ambiguous (both servers register the scheme) — the tool route (get_agent_pattern) is authoritative.
| Prompt | Args | What it does |
|---|---|---|
/design_agent_system_workflow | requirements* | Full analyze → generate → evaluate pipeline |
/explore_pattern_catalog | domain, category | Live catalog discovery with embedded pattern names |
/evaluate_my_agent_system | focus | Guide evaluation criteria + prioritisation |
/compare_agent_topologies | topology_a*, topology_b*, requirements* | Two designs side-by-side (~2× token cost) |
* = required
In tool-only clients the prompts are also callable as tools via FastMCP's
PromptsAsTools transform — the server then exposes list_prompts and
get_prompt alongside the nine domain tools above.
test -f docker/docker-compose.yml); config template is config/config.jsondocker compose version) + membership in the docker groupMINIMAXAI_API_KEY); any LiteLLM-compatible provider works (OpenAI, Anthropic, DeepSeek, Ollama, vLLM, OpenRouter, … — see Switching the generator LLM)make docker-build-alldesign_agent_system runs multi-stage LLM pipelines that can take 5–10 minutes — the generator LLM processes the selected pattern definitions, your requirements, and the full output of every previous stage across 9+ round trips.
MCP clients implement client-side idle timeouts (typically 30–120 s). If no data is received, the client aborts — even though the server is still working correctly.
| Client | Timeout | Notes |
|---|---|---|
| Claude Desktop (TS-SDK) | 60 s | Hardcoded; does not reset on progress |
| Cursor (TS-SDK) | 60 s | Same as Claude Desktop |
| Claude Code | ~300 s | Heartbeat every 30 s resets idle timer |
| OpenCode | ~300 s | Heartbeat every 30 s resets idle timer |
| Codex CLI | ~300 s | Heartbeat every 30 s resets idle timer |
Heartbeat defence (default) — The server emits progress notifications every 30 s (TASKS_HEARTBEAT_INTERVAL_SECONDS), resetting idle timers for most HTTP clients. TS-SDK clients (Claude Desktop, Cursor) do not reset on progress.
Async job trio — For timeout-constrained clients (Claude Desktop, Cursor), use submit_agent_design_job + get_agent_design_status + cancel_agent_design. Returns a job_id immediately; poll every 10–30 s.
Direct HTTP client — The repo's example client (examples/agent_client.py, make client) bypasses the MCP SDK entirely with no idle timeout.
Prebuilt images from Docker Hub — but install runs from a repo clone (compose files and config template live there). Pick one path; both can run concurrently (distinct container names and ports).
Path A — Compose stack (:8061, no sudo, own TEI copies):
git clone https://github.com/olk/agent-pattern-mcp.git && cd agent-pattern-mcp
# TEI images release rarely, currently 1.9.4)
VERSION=$(grep -m 1 '^version' pyproject.toml | sed -E 's/.*"([^"]+)".*/\1/')
TEI_VERSION=1.9.4
docker pull "olkowa/agent-pattern-mcp:${VERSION}"
docker pull "olkowa/pattern-tei-embed:${TEI_VERSION}"
docker pull "olkowa/pattern-tei-rerank:${TEI_VERSION}"
# Env file for compose interpolation
cat > docker/.env <<EOF
MCP_IMAGE=olkowa/agent-pattern-mcp:${VERSION}
TEI_IMAGE=olkowa/pattern-tei-embed:${TEI_VERSION}
TEI_RERANK_IMAGE=olkowa/pattern-tei-rerank:${TEI_VERSION}
MINIMAXAI_API_KEY=sk-REPLACE-ME
MCP_HOST_PORT=8061
EOF
docker compose --env-file docker/.env -f docker/docker-compose.yml up -d
# Wait until all three report "healthy" (TEI cold start ~2 min, MCP ≤ ~40 s after)
docker inspect -f '{{.Name}} {{.State.Health.Status}}' \
agent-pattern-tei-dev agent-pattern-tei-rerank-dev agent-pattern-mcp-dev
# Probe — must print 200 (GET /health is 404 by design; the POST is the probe)
curl -s -o /dev/null -w '%{http_code}\n' -X POST "http://localhost:8061/mcp" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"probe","version":"0.0.0"}},"id":1}'
Installed endpoint: http://localhost:8061/mcp (streamable-http).
Path B — systemd stack (:8051, persistent, needs sudo): shared
pattern-tei-infra TEI stack plus a systemd unit (agpmcp-systemd, config at
/etc/agent-pattern-mcp/). Full runbook with verification probes:
INSTALL.md Path B.
Reproducibility tip: the MCP and TEI images release independently — pin both (
MCP_IMAGE=…:1.0.4,TEI_*=…:1.9.4);latestalso exists. GHCR mirrors are not anonymously pullable — use Docker Hub.
Config: Path A reads the repo file
config/config.json(mounted at/app/config); restart the container after editing. Path B uses/etc/agent-pattern-mcp/config/config.json.
Both compose files hardcode the MiniMax generator block (deployed
default). To use another LiteLLM provider, edit the four GENERATOR_* lines
in the installed compose file and put the key in the env file, then restart:
| Provider | Compose GENERATOR_* block |
|---|---|
| MiniMax (deployed default) | GENERATOR_PROVIDER=minimax · GENERATOR_MODEL=minimax/MiniMax-M2.7 · GENERATOR_BASE_URL=https://api.minimax.io/v1 · GENERATOR_API_KEY=${MINIMAXAI_API_KEY} |
| OpenAI | GENERATOR_PROVIDER=openai · GENERATOR_MODEL=openai/gpt-4o-mini · GENERATOR_BASE_URL=https://api.openai.com/v1 · GENERATOR_API_KEY=${OPENAI_API_KEY} |
| Anthropic | GENERATOR_PROVIDER=anthropic · GENERATOR_MODEL=claude-sonnet-4-5 · GENERATOR_API_KEY=${ANTHROPIC_API_KEY} |
| DeepSeek | GENERATOR_PROVIDER=deepseek · GENERATOR_MODEL=deepseek-chat · GENERATOR_BASE_URL=https://api.deepseek.com/v1 · GENERATOR_API_KEY=${DEEPSEEK_API_KEY} |
| Ollama / vLLM / OpenRouter / any OpenAI-compatible | GENERATOR_BASE_URL=http://host:11434/v1 · GENERATOR_MODEL=... · GENERATOR_API_KEY=... |
The generator LLM is accessed through the LlamaIndex LiteLLM integration
(llama-index-llms-litellm).
All provider settings follow LiteLLM's model syntax: <provider>/<model>
(e.g. openai/gpt-4o-mini, anthropic/claude-sonnet-4-5,
openrouter/minimax/minimax-m2).
The server composes the LiteLLM model string from your configuration as
generator.provider + generator.config.model (a contained provider prefix is stripped and replaced):
| Config / env | Example | Resulting LiteLLM model string |
|---|---|---|
provider: "openai", model: "gpt-4o-mini" | GENERATOR_PROVIDER=openai, GENERATOR_MODEL=gpt-4o-mini | openai/gpt-4o-mini |
provider: "anthropic", model: "claude-sonnet-4-5" | GENERATOR_PROVIDER=anthropic, GENERATOR_MODEL=claude-sonnet-4-5 | anthropic/claude-sonnet-4-5 |
provider: "openrouter", model: "minimax/minimax-m2" | GENERATOR_PROVIDER=openrouter, GENERATOR_MODEL=minimax/minimax-m2 | openrouter/minimax/minimax-m2 |
<provider>/<model> syntax: LiteLLM Providers documentationGENERATOR_BASE_URL — it is passed as the LiteLLM api_baseGENERATOR_API_KEY is passed as the LiteLLM api_key; GENERATOR_TEMPERATURE, GENERATOR_TOP_P, GENERATOR_TOP_K, and GENERATOR_STREAM map to the corresponding LiteLLM parametersThe MCP server connects to the TEI embedder at
http://pattern-tei-embed:8080/v1 and the TEI reranker at
http://pattern-tei-rerank:8080 by default (Docker DNS names). Override if
your setup differs:
| Variable | Default | Description |
|---|---|---|
EMBEDDER_BASE_URL | http://pattern-tei-embed:8080/v1 | TEI embedder URL |
RERANKER_BASE_URL | http://pattern-tei-rerank:8080 | TEI reranker URL |
RERANKER_TIMEOUT | 30 | Reranker request timeout (seconds) |
The embedder (olkowa/pattern-tei-embed) carries
Qwen3-Embedding-0.6B (ONNX fp32) and the reranker
(olkowa/pattern-tei-rerank) carries gte-reranker-modernbert-base — both
baked into their images, fully offline (HF_HUB_OFFLINE=1, no downloads, no
API keys at runtime).
Deployed-stack overrides (differ from config.json defaults): per-leg
stage-1 caps RETRIEVAL_BM25_TOP_K=20 / RETRIEVAL_DENSE_TOP_K=20 (0 = full
corpus in config), RETRIEVAL_MIN_FUSION_SCORE=0.015, and
RETRIEVAL_USE_LEAN_WIRE_SCHEMA=true (omits free-form contract lists — the
deployed MiniMax model emits unquoted JS-style keys otherwise).
Full env var reference: GitHub README → Configuration
The image bakes two Node-based reasoning MCP servers — shannonthinking
([email protected]) and code-reasoning
(@mettamatt/[email protected]) — into /usr/local/lib/node_modules. The
pipeline invokes them directly via node (no runtime npx fetch outside
Docker it falls back to npx -y); they act as structured scratchpads that
validate and number the thoughts the pipeline's own LLM authors.
Per-phase defaults (src/reasoning/config.py::_default_per_phase): analyze
["code", "shannon"] × 4 thoughts, generate ["code"] × 3, evaluate
["shannon"] × 3, refine ["code", "shannon"] × 2 — up to 24 serial
subprocess calls per full design run (minutes, not seconds).
| Variable | Default | Description |
|---|---|---|
REASONING_ENABLED | true | Enable the embedded reasoning MCPs |
REASONING_FAIL_FAST | true | Exit at startup if the reasoning tools are unreachable, instead of continuing degraded |
REASONING_SPAWN_TIMEOUT_SECONDS | 10 | Process spawn timeout |
REASONING_STEP_TIMEOUT_SECONDS | 20 | Per-thought tool-call timeout |
REASONING_MAX_TOTAL_STEPS | 8 | Max thoughts per phase |
Set REASONING_ENABLED=false to opt out (loses the structured-reasoning
cross-validation; pipeline output stays valid).
Add to ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"agent-pattern-mcp": {
"type": "remote",
"url": "http://localhost:8061/mcp",
"enabled": true
}
}
}
(Use port 8051 for the systemd stack.)
Add to .vscode/mcp.json:
{
"servers": {
"agent-pattern-mcp": {
"url": "http://localhost:8061/mcp",
"type": "http"
}
}
}
Add to ~/.codex/config.toml:
[mcp_servers.agent-pattern-mcp]
url = "http://localhost:8061/mcp"
Stdio transport — this section is for Claude Code subprocess mode. It requires a local
git clone(one-time setup). If you want HTTP transport (recommended for Docker Hub users), use the Quick start above instead.
# Install (one-time)
git clone https://github.com/olk/agent-pattern-mcp.git && cd agent-pattern-mcp
uv pip install -e .
# Add to your agent
claude mcp add agent-pattern \
-e GENERATOR_API_KEY=your_key \
-e GENERATOR_PROVIDER=openai \
-- agent-pattern-mcp --transport stdio
The repo also ships an OMP skill (skills/agent-pattern-mcp/) teaching
deadline-aware entry-point selection (async job trio by default under OMP's
30 s MCP deadline).
Ask your agent:
Use design_agent_system to design a research assistant that combines web search with sandboxed code execution for multi-hop questions. Domain: tool-use-tasks.
This should call design_agent_system with:
requirements: "Research assistant combining web search with sandboxed code execution for multi-hop questions"domain: "tool-use-tasks"The tool runs the full pipeline — analyze (pattern retrieval + requirements-weighted scoring) → generate (LLM structured output) → evaluate (metric scoring) → refine (bounded retry loop) — and returns a complete design with agents, relationships, tool contracts, and quality scores.
# Path A: upgrade (re-pull pins, restart)
VERSION=$(grep -m 1 '^version' pyproject.toml | sed -E 's/.*"([^"]+)".*/\1/')
docker pull "olkowa/agent-pattern-mcp:${VERSION}"
docker compose --env-file docker/.env -f docker/docker-compose.yml up -d
# View logs
docker compose --env-file docker/.env -f docker/docker-compose.yml logs -f agent-pattern-mcp
# Stop / remove
docker compose --env-file docker/.env -f docker/docker-compose.yml down
# rm docker/.env # contains the API key — remove or keep as you prefer
# Path B: day-2 (systemd)
sudo systemctl stop|start agent-pattern-mcp # compose down / up -d
sudo systemctl reload agent-pattern-mcp # recreate after editing compose/.env
journalctl -u agent-pattern-mcp -n 50
On Linux with a shared host, restrict your env file (chmod 600 docker/.env;
Path B uses root:docker 640 at /etc/agent-pattern-mcp/.env).
Async jobs are ephemeral in Docker. The jobs store lives at
~/.config/agent-pattern-mcp/jobs.dbinside the container and is lost on restart. To persist it, mount a volume and setAGENT_PATTERN_JOBS_DBto a path inside it.
| Symptom | Fix |
|---|---|
GET /health returns 404 | Expected — probe POST /mcp with the initialize payload (Quick start) instead |
401/502 from LLM on design calls | Generator key wrong/missing in the env file, or provider env block mismatched — see BYO LLM |
| Tools not visible in the client | Verify the client URL matches http://localhost:8061/mcp (Path A) or :8051/mcp (Path B) — note the /mcp path; check container logs |
| TEI connection errors / MCP unhealthy | TEI still cold-starting (start_period 120 s) — recheck after ~2 min; verify both sidecars healthy; Path B: sudo systemctl start pattern-tei-infra.service (network pattern-tei-shared not found) |
| Startup exits with reasoning errors | Embedded reasoning MCPs could not be spawned; check logs, or set REASONING_ENABLED=false to run degraded |
| Unit fails reading environment file (Path B) | Recreate /etc/agent-pattern-mcp/.env per INSTALL B2 (root:docker 640, user in docker group) |
start request repeated too quickly (Path B) | Inspect journalctl -u agent-pattern-mcp -n 50, fix, systemctl reset-failed agent-pattern-mcp, start again |
| Port already in use | Path A: MCP_HOST_PORT=8062 in docker/.env, then update your client URL |
design_agent_system times out in the client | Expected for 60 s TS-SDK clients — use the async job trio (submit_agent_design_job + get_agent_design_status) |
Content type
Image
Digest
sha256:b77cd9450…
Size
250.6 MB
Last updated
9 days ago
docker pull olkowa/agent-pattern-mcp