loading…
Search for a command to run...
loading…
Run YAML workflows as MCP tools so agents can automate real tasks with one server.
Run YAML workflows as MCP tools so agents can automate real tasks with one server.
Run YAML workflows as MCP tools so agents can automate real tasks with one server.
workflows-mcp gives MCP clients a reusable automation layer:
Prompt blocks) with pause/resume.WORKFLOW_SECRET_* with redacted outputs.Requires Python 3.12+.
uv pip install workflows-mcp
or:
pip install workflows-mcp
Example (claude_desktop_config.json):
{
"mcpServers": {
"workflows": {
"command": "uvx",
"args": ["workflows-mcp"],
"env": {
"WORKFLOWS_TEMPLATE_PATHS": "/path/to/your/workflows",
"WORKFLOWS_LOG_LEVEL": "INFO",
"WORKFLOW_SECRET_API_KEY": "your-secret-value"
}
}
}
}
If installed with pip:
{
"mcpServers": {
"workflows": {
"command": "workflows-mcp",
"env": {
"WORKFLOWS_TEMPLATE_PATHS": "/path/to/your/workflows",
"WORKFLOWS_LOG_LEVEL": "INFO",
"WORKFLOW_SECRET_API_KEY": "your-secret-value"
}
}
}
}
list_workflowsget_workflow_infoexecute_workflowUse this call order for reliable results:
list_workflows.get_workflow_info for required inputs.execute_workflow.mode="async"): call get_job_status (or list_jobs).resume_workflow only for paused jobs (typically from Prompt blocks).reload_workflows.When authoring workflows, validate first:
validate_workflow_yaml before execute_inline_workflow.get_workflow_schema for current schema details.docs/llm/block-reference.md.Async mini-flow example:
execute_workflow(workflow="python-ci-pipeline", inputs={...}, mode="async")
→ returns job_id
→ get_job_status(job_id="job_...") until completed/failed/paused
→ if paused, resume_workflow(job_id="job_...", response="...")
| Tool | When to call | Typical call pattern |
|---|---|---|
list_workflows |
List registered workflows | list_workflows(tags=[], format="json") |
get_workflow_info |
Exploratory to confirm inputs/outputs | get_workflow_info(workflow="name", format="json") |
execute_workflow |
Run a registered workflow | execute_workflow(workflow="name", inputs={...}, mode="sync") |
execute_inline_workflow |
Test one-off YAML without registering | execute_inline_workflow(workflow_yaml="...", inputs={...}) |
reload_workflows |
After editing workflow YAML files on disk | reload_workflows() |
| Tool | When to call | Typical call pattern |
|---|---|---|
get_workflow_schema |
Debugging only. Retrieve full JSON schema for authoring | get_workflow_schema() |
validate_workflow_yaml |
Validate YAML before execution | validate_workflow_yaml(yaml_content="...") |
| Tool | When to call | Typical call pattern |
|---|---|---|
get_job_status |
Poll a specific async job | get_job_status(job_id="job_...") |
list_jobs |
Find jobs by status (especially paused) | list_jobs(status="paused", limit=100) |
cancel_job |
Stop queued/running jobs | cancel_job(job_id="job_...") |
get_queue_stats |
Monitor queue health/capacity | get_queue_stats() |
resume_workflow |
Continue paused Prompt workflows |
resume_workflow(job_id="job_...", response="...") |
| Tool | When to call | Typical call pattern |
|---|---|---|
memory |
Unified memory query/ingest/maintenance/graph operations | memory(operation="query", scope={...}, query={...}) |
project_onboard |
Current memory onboarding flow with checkpoints | project_onboard(scope={...}, ingest={...}, max_operations=1) |
project_sync |
Current memory checkpoint resume/continuation | project_sync(checkpoint={...}, max_operations=3) |
IMPORTANT: The memory tool is registered only when memory DB setup is available and valid at startup (see below)
Memory contract highlights:
operation + optional scope/query/record/graph/maintenance/response.scope accepts only palace, wing, room, compartment.scope → scope_token → context_id (per-field merge).scope_token resolves from execution context memory_scope_tokens; context_id resolves from memory_context_scopes.resolved_scope and scope_source when available.query: all four fields must resolve.ingest: all four fields must resolve (including compartment).graph_upsert with graph.kind="place": all four fields must resolve.validate|supersede|archive|maintain|graph_delete|graph_upsert(kind="link"): scope is optional.operation="query" supports either query.as_of OR interval query.from/query.to (mutually exclusive).query.mode="graph" supports query.as_of only; query.from/query.to are rejected.operation="ingest" with record.format="raw" supports record.valid_from and record.valid_to with ordering validation (valid_from <= valid_to).operation="ingest" is direct-only (record.memory_tier must be direct).record.categories fail deterministically with MEM_UNKNOWN_CATEGORY when record.allow_create_categories=false (default behavior).record.allow_create_categories=true opts into category creation and allows ingest to proceed when categories are otherwise valid.maintenance.mode="community_refresh").query.mode="communities" uses the dedicated communities strategy.operation="supersede" requires record.superseded_by.operation="archive" maps to forget semantics; repeating archive on already archived records is safe/idempotent.operation="graph_upsert" with graph.kind="link" is idempotent.operation="graph_delete" returns compact delete counters (deleted_places for kind="place", deleted_links for kind="link"); optional debug output adds diagnostics metadata.Validation note: this ingest category behavior (MEM_UNKNOWN_CATEGORY with create disabled, successful ingest with allow_create_categories=true) was live-validated on 2026-04-21 via production-like direct MCP memory calls.
Direct-call JSON examples:
query:
{
"operation": "query",
"scope": {"palace": "acme", "wing": "workflows", "room": "memory-engine", "compartment": "contract-r2"},
"query": {"mode": "search", "text": "schema epoch", "as_of": "2026-04-20T00:00:00Z", "radius": 1}
}
ingest:
{
"operation": "ingest",
"scope": {"palace": "acme", "wing": "workflows", "room": "memory-engine", "compartment": "contract-r2"},
"record": {"format": "raw", "content": "Memory active", "memory_tier": "direct"}
}
validate:
{
"operation": "validate",
"record": {"ids": ["11111111-1111-1111-1111-111111111111"]}
}
supersede:
{
"operation": "supersede",
"record": {
"ids": ["11111111-1111-1111-1111-111111111111"],
"superseded_by": "22222222-2222-2222-2222-222222222222"
}
}
archive:
{
"operation": "archive",
"record": {"ids": ["11111111-1111-1111-1111-111111111111"]}
}
maintain:
{
"operation": "maintain",
"maintenance": {"mode": "community_refresh"}
}
graph_upsert (kind=place):
{
"operation": "graph_upsert",
"scope": {"palace": "acme", "wing": "workflows", "room": "memory-engine", "compartment": "contract-r2"},
"graph": {"kind": "place", "place_name": "Memory API (current)", "place_type": "feature"}
}
graph_upsert (kind=link):
{
"operation": "graph_upsert",
"graph": {
"kind": "link",
"from": "11111111-1111-1111-1111-111111111111",
"to": "22222222-2222-2222-2222-222222222222",
"link_type": "depends_on"
}
}
graph_delete:
{
"operation": "graph_delete",
"graph": {"kind": "place", "ids": ["33333333-3333-3333-3333-333333333333"]}
}
project_onboard:
{
"scope": {"palace": "acme", "wing": "workflows", "room": "memory-engine", "compartment": "contract-r2"},
"ingest": {"format": "raw", "content": "Initial baseline", "memory_tier": "direct"},
"supersede": {"ids": ["11111111-1111-1111-1111-111111111111"], "superseded_by": "22222222-2222-2222-2222-222222222222"},
"archive": {"ids": ["33333333-3333-3333-3333-333333333333"]},
"maintain": {"mode": "community_refresh"},
"max_operations": 1
}
project_sync:
{
"checkpoint": {
"version": "oss-r2",
"scope": {"palace": "acme", "wing": "workflows", "room": "memory-engine", "compartment": "contract-r2"},
"plan": [{"operation": "ingest", "payload": {"format": "raw", "content": "Initial baseline", "memory_tier": "direct"}}],
"next_index": 0,
"completed": []
},
"max_operations": 3
}
Invalid (mutually exclusive temporal filters):
{
"operation": "query",
"scope": {"palace": "acme", "wing": "workflows", "room": "memory-engine", "compartment": "contract-r2"},
"query": {
"mode": "search",
"text": "maintenance",
"as_of": "2026-04-20T00:00:00Z",
"from": "2026-04-01T00:00:00Z",
"to": "2026-04-20T00:00:00Z"
}
}
Invalid (graph query rejects interval filters):
{
"operation": "query",
"scope": {"palace": "acme", "wing": "workflows", "room": "memory-engine", "compartment": "contract-r2"},
"query": {
"mode": "graph",
"text": "service graph",
"from": "2026-04-01T00:00:00Z",
"to": "2026-04-20T00:00:00Z"
}
}
Invalid (legacy taxonomy key):
{
"operation": "query",
"scope": {"palace": "acme", "wing": "svc", "room": "component", "hall": "legacy"},
"query": {"text": "find this", "mode": "search"}
}
Invalid (supersede missing required superseded_by):
{
"operation": "supersede",
"record": {
"ids": ["11111111-1111-1111-1111-111111111111"]
}
}
WORKFLOWS_TEMPLATE_PATHS: Comma-separated workflow directories to load.WORKFLOWS_MAX_RECURSION_DEPTH: Max workflow composition depth (default: 50).WORKFLOWS_LOG_LEVEL: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL; default: INFO).WORKFLOWS_IO_QUEUE_ENABLED: Enable serialized I/O queue (default: true).WORKFLOWS_JOB_QUEUE_ENABLED: Enable async job queue (default: true).WORKFLOWS_JOB_QUEUE_WORKERS: Queue workers (default: 3).WORKFLOWS_MAX_CONCURRENT_JOBS: Max active + queued jobs (default: 500).WORKFLOWS_JOB_TIMEOUT: Default async timeout in seconds (default: 3600).WORKFLOWS_JOB_HISTORY_MAX: Max retained job records (default: 1000).WORKFLOWS_JOB_HISTORY_TTL: Job retention TTL in seconds (default: 86400).WORKFLOW_SECRET_<NAME>: Secret value exposed as {{secrets.NAME}}.WORKFLOWS_LLM_CONFIG: Optional path override for LLM config.Memory is an optional persistent storage feature that lets agents and workflows record, retrieve, and organize information across sessions. It is backed by PostgreSQL and gives each agent a structured, scoped, and temporally-aware knowledge store.
memory MCP tool — direct call interface for LLM agents to store and query information without writing workflow YAML.project_onboard / project_sync MCP tools — Current memory contract helpers for checkpointed onboarding/sync sequences.Memory workflow block — use inside YAML workflows to automate memory operations as part of larger pipelines.palace → wing → room → compartment) — current memory scope keys are strict and legacy keys (for example hall) are rejected. Scope can be supplied directly and/or resolved from context (scope_token, context_id) using deterministic precedence.valid_from / valid_to timestamps supporting point-in-time and interval queries.Current memory behavior exposes query modes that map to retrieval strategies internally:
| Query mode / trigger | Effective strategy | Behavior |
|---|---|---|
query.mode="search" + radius=0 |
palace |
Strict scoped retrieval lane (no companion lane). |
query.mode="search" + radius>=1 |
auto |
Scoped lane + optional S2 companion lane (s2_enabled=true by default). |
query.mode="hybrid" |
auto |
Same retrieval family as auto with fused ranking. |
query.mode="context" |
context |
Context assembly retrieval path. |
query.mode="graph" |
graph |
Graph traversal/path/stats retrieval. |
query.mode="communities" |
communities |
Community-focused retrieval strategy. |
Every query call still requires a fully resolved current memory scope (palace/wing/room/compartment) resolved from request and/or context sources.
Scope fields can be passed directly and/or resolved from scope_token / context_id:
{
"operation": "query",
"scope": {"palace": "acme", "wing": "my-service"},
"scope_token": "st_auth",
"context_id": "ctx_default",
"query": {"text": "refresh token lifetime", "mode": "context"}
}
Resolution precedence is scope → scope_token → context_id for each field.
CREATE DATABASE rights on the admin database (typically postgres) if auto-create is enabled, or a pre-existing database that the user can connect to.| Variable | Default | Required | Description |
|---|---|---|---|
MEMORY_DB_HOST |
— | Yes | PostgreSQL hostname or IP. Setting this variable enables memory features. |
MEMORY_DB_PORT |
5432 |
No | PostgreSQL port. |
MEMORY_DB_NAME |
memory_db |
No | Target database name. |
MEMORY_DB_USER |
— | Yes | Database username. |
MEMORY_DB_PASSWORD |
— | Yes | Database password. |
MEMORY_DB_AUTO_CREATE |
true |
No | Auto-create the target database on first boot if it does not exist. Requires the user to have CREATE DATABASE rights on the admin database. |
MEMORY_DB_ADMIN_DATABASE |
postgres |
No | Admin database used to issue the CREATE DATABASE statement when auto-create is enabled. |
AUDIT_FAIL_CLOSED |
false |
No | When true, audit-logging failures abort the entire memory operation (compliance mode). Default is log-and-continue. |
Add the following variables to your MCP client config:
{
"mcpServers": {
"workflows": {
"command": "uvx",
"args": ["workflows-mcp"],
"env": {
"MEMORY_DB_HOST": "localhost",
"MEMORY_DB_PORT": "5432",
"MEMORY_DB_NAME": "memory_db",
"MEMORY_DB_USER": "postgres",
"MEMORY_DB_PASSWORD": "your-password"
}
}
}
}
On first boot with MEMORY_DB_AUTO_CREATE=true (the default), the server creates the target database and applies the schema automatically. Restart your MCP client after adding the variables.
list_workflows — confirm the server started without errors in the client logs.memory tool appears in the available tool list.{
"operation": "ingest",
"scope": {"palace": "acme", "wing": "test", "room": "setup", "compartment": "smoke"},
"record": {"format": "raw", "content": "Memory is working.", "memory_tier": "direct"}
}
If the tool is absent, check server logs for MEMORY_DB_* startup errors — the most common causes are an unreachable host, incorrect credentials, or a schema epoch mismatch.
Memory schema versions are tracked by epoch. If the epoch in the database does not match the server version:
MEMORY_SCHEMA_RESET_MODE only if you intend a one-time destructive reset on a non-production instance.Use registered workflows for repeatable automation, and inline workflows for experiments.
Author workflow YAML with exact block input names from:
docs/llm/block-reference.mdExample block families include Shell, ReadFiles, HttpCall, LLMCall, Sql, Workflow, Prompt, and Memory.
README.md: install, usage, and tool catalog.docs/guides/memory-tools-cheatsheet.md: Current memory contract quick reference, detailed guide, and examples.docs/llm/block-reference.md: exact block inputs/outputs for workflow authoring.docs/TESTING.md: test strategy and test commands.ARCHITECTURE.md: architecture overview.docs/adr/: design decisions and rationale.CHANGELOG.md: release history.uv run pytest
uv run ruff check src/workflows_mcp/
uv run mypy src/workflows_mcp/
AGPL-3.0-or-later. See LICENSE.
Run in your terminal:
claude mcp add workflows-mcp -- npx Security
Low riskAutomated heuristic from public metadata — not a security guarantee.