Skip to main content
Glama
sspcodeflix

woodpecker-mcp

by sspcodeflix

woodpecker-mcp

CI license python backend

woodpecker-mcp exposes a materialized service dependency graph as an MCP toolset. It provides an LLM-based agent such as HolmesGPT with a capability those agents do not retain on their own: a persistent, queryable graph of how services depend on one another. Root-cause analysis therefore becomes a deterministic graph traversal rather than a conclusion re-derived on each investigation.

HolmesGPT remains unmodified. It launches woodpecker-mcp as a subprocess (or connects over HTTP) and discovers the tools it exposes - no fork, custom image, or plugin is required.


Why this exists

HolmesGPT markets a "Runtime Dependency Graph", yet its source holds no graph data structure, no graph database, and no graph-traversal code. Each investigation infers the relationships on the fly - from traces, Kubernetes owner-refs, and metric labels - then discards them, and root cause is whatever the model concludes through a "five whys" prompt. That design is deliberate - it buys freshness, statelessness, and breadth - but it carries costs that a materialized graph removes:

Holmes (inferred)

woodpecker-mcp (materialized)

Where relationships live

model context, one investigation

a graph database (FalkorDB)

Root cause

reasoned per run (non-deterministic)

deepest-failing-service, one Cypher query (exact, repeatable)

Blast radius

re-derived each time

variable-length path traversal

Explore it yourself

no

yes (browser UI + Cypher)

Blind-spot detection

no

yes


Related MCP server: procurement-graph

How it works

flowchart TD
    H["MCP client (e.g. HolmesGPT)"] -->|stdio or HTTP| S["server.py - FastMCP tools"]
    S -->|refresh| B[build.refresh]
    S -->|diagnose| D[diagnose.py]
    B -->|reads live state| C["sources/<br/>topology: docker / k8s / traces<br/>metrics: prometheus / datadog"]
    B -->|materializes| G[("FalkorDB<br/>dependency graph")]
    D -->|"Cypher: roots, blast radius, paths"| G

The graph is rebuilt from live sources on each query (or from a static topology file), then all reasoning runs as Cypher against the store.


Quickstart

HolmesGPT already ships the MCP client, so wiring is config-only - no fork, image, or plugin to build. Install, then let woodpecker-mcp configure itself:

pip install holmesgpt woodpecker-mcp
woodpecker-mcp init        # guided Q&A -> writes a filled-in .env
woodpecker-mcp setup       # starts the graph backend, waits until ready, registers the toolset
holmes ask "find the root cause of the current incident"

init asks a few questions (graph backend, topology, metrics) and writes a .env. setup starts FalkorDB and merges the woodpecker-graph toolset into ~/.holmes/config.yaml, so holmes ask picks it up automatically - no -t flag needed.

Other setups, all in the integration guide: no Docker or air-gapped (the embedded Kuzu backend), wiring the toolset YAML by hand, in-cluster over HTTP for the Holmes Operator, and the full configuration reference.


Tools

Tool

Returns

woodpecker_get_topology

the materialized graph (services, status, deps)

woodpecker_diagnose_root_cause

deepest-failing-service + causal chains + blast radius + blind spots + page verdict

woodpecker_get_blast_radius(service, direction)

transitive upstream/downstream closure

woodpecker_get_service_health(service)

per-service drill-down

woodpecker_detect_blind_spots

healthy-but-unmonitored services


Explore the graph

FalkorDB ships a browser. Open http://localhost:3000, pick the woodpecker graph, and run OpenCypher visually, e.g. the blast radius of db:

MATCH (a:Service)-[:DEPENDS_ON*1..20]->(:Service {name:'db'}) RETURN a

Or from Python:

from falkordb import FalkorDB
g = FalkorDB(host="localhost", port=6379).select_graph("woodpecker")
g.query("MATCH (a:Service)-[:DEPENDS_ON*1..20]->(:Service {name:'db'}) "
        "RETURN a.name").result_set

CLI (standalone)

woodpecker-mcp topology      # rebuild + print the service graph
woodpecker-mcp diagnose      # rebuild + print root-cause analysis
woodpecker-mcp refresh       # rebuild the graph only
woodpecker-mcp serve [--http] [--port 8000]   # run the MCP server

# study a topology offline, no live infra:
woodpecker-mcp ingest examples/topology.example.json
WP_AUTO_REFRESH=0 woodpecker-mcp diagnose

Configuration

Everything has a working default; set only what points at your infra. Run woodpecker-mcp init to generate a .env from a guided Q&A (or start from the fully-commented .env.sample - same content init --defaults writes), or put the WP_* vars in the toolset's env: block. Three independent seams, mixed and matched:

  • graph (WP_GRAPH_BACKEND): falkordb (server, default) or kuzu (embedded, no Docker - good for air-gapped)

  • topology (WP_TOPOLOGY): docker, k8s, or traces (Jaeger)

  • metrics (WP_METRICS_BACKEND): prometheus (or any PromQL-compatible backend) or datadog

Either graph backend sits behind one GraphStore interface (Neo4j/Memgraph drop in the same way). Every variable, with per-backend deep-dives, validation commands, and troubleshooting, is in docs/CONFIGURATION.md.


Layout

woodpecker_mcp/
  server.py      FastMCP tools, stdio + HTTP
  store.py       GraphStore interface; FalkorGraphStore (default), KuzuGraphStore
  build.py       rebuild the graph from sources, or ingest a static topology
  diagnose.py    deterministic root-cause verdict from store queries
  sources/       TopologySource (docker, k8s, traces) + MetricsSource (prometheus, datadog)
  schema.py      status vocabulary
  snapshot.py    timestamped diagnose snapshots (postmortem/audit trail)
  topomem.py     topology memory - deleted services stay visible as down
  cli.py         init | setup | serve | topology | diagnose | refresh | ingest
  scaffold.py    init/setup helpers (.env, FalkorDB, Holmes config)
examples/        holmesgpt-toolset.yaml, k8s-deployment.yaml, topology.example.json
docs/            CONFIGURATION.md
benchmark/       Holmes-vs-Holmes+woodpecker benchmark: harness, raw logs, EVIDENCE.md
tests/           unit tests (test_*.py) + smoke_mcp.py (integration)

Development

pip install -e ".[dev]"                      # pytest + ruff
pre-commit install                           # ruff lint on every commit
pre-commit install --hook-type pre-push      # unit tests before every push

pytest                                       # unit tests - no services needed
ruff check .                                 # lint  (ruff format . to auto-format)

Unit tests (tests/test_*.py) run offline against fakes; the graph-store suite is parametrized over both backends (Kuzu embedded, FalkorDB via a live server) and skips whichever is unavailable - set WP_TEST_REQUIRE_BACKENDS=1 (CI does) to hard-fail instead of skipping. The stdio integration check needs a live FalkorDB:

docker run -d -p 127.0.0.1:6379:6379 -p 127.0.0.1:3000:3000 falkordb/falkordb:v4.18.11
python tests/smoke_mcp.py

License

woodpecker-mcp is licensed under Apache-2.0. It connects to FalkorDB as a client and does not redistribute it; FalkorDB itself is SSPL-licensed (source-available) - fine for self-hosting, relevant only if you offer FalkorDB as a managed service.

Available Tools

5 tools
woodpecker_detect_blind_spotsA

List observability blind spots: services that are healthy but have no live Prometheus scrape target (lost visibility, NOT an outage - do not page).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full behavioral burden. It explains what the tool does (lists blind spots) and adds context that these are not outages, avoiding misinterpretation. It could be improved by noting if it only lists current state or historical data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the action 'List observability blind spots' and then provides clarifying context. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters and no output schema, the description is largely complete. It defines what blind spots are and the condition (no live scrape target). However, it does not specify output format or how results are ordered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so schema coverage is 100%. Per calibration, zero-parameter tools get a baseline of 4. The description does not need to add parameter info.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool lists observability blind spots, defined as healthy services without Prometheus scrape targets. It uses a specific verb-resource combination and distinguishes from sibling tools like diagnose_root_cause or get_service_health.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by clarifying that blind spots are not outages and should not trigger pages, but does not explicitly say when to use this tool versus alternatives. No direct mention of sibling tools or when-not-to-use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

woodpecker_diagnose_root_causeA

Localize the ROOT CAUSE deterministically: the DEEPEST failing service, the unhealthy one whose own dependencies are all healthy. Everything unhealthy above it is cascading fallout. Returns root cause(s), the causal chain per cascading symptom, blast radius, blind spots, and a page/no-page verdict, distinguishing a real outage from an observability blind spot (metrics missing but the service responds). Exact and repeatable, unlike per-investigation inference.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must fully disclose behavioral traits. While it explains what the tool returns and that it is deterministic, it fails to mention that the tool takes no input parameters (schema has zero properties). This omission may confuse an AI agent about how the tool is invoked or what context it requires. The description claims it 'localizes' root cause but does not state the implicit input or state it operates on.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, informative paragraph that front-loads the main purpose. It is concise yet covers key outcomes. Minor improvement could be breaking into bullet points, but overall it is well-structured and not verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the absence of an output schema, the description does explain return values partially. However, it lacks critical context: how the tool determines which services to analyze without parameters, and how it fits with sibling tools. The completeness suffers because the input mechanism is undefined, making it unclear for an AI agent to know when to call this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the schema provides 100% coverage by default. According to the rules, a baseline of 4 is appropriate when there are no parameters. The description does not need to add parameter semantics, but it lacks an explanation of how the tool operates without explicit input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: to deterministically localize the root cause by identifying the deepest failing service. It specifies what it returns (root cause, causal chain, blast radius, etc.) and distinguishes its deterministic nature from typical inference. This makes the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context of use is clear: it is for diagnosing root cause when services are failing. However, it does not explicitly state when to use this tool versus its siblings (e.g., woodpecker_get_service_health for health checks) or when it would be inappropriate. The description implies its use for root cause but lacks explicit exclusionary guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

woodpecker_get_blast_radiusA

Transitive dependency closure of a service over DEPENDS_ON edges. direction='upstream': services that transitively depend on this one (its blast radius if it fails). direction='downstream': everything it relies on (trace toward a deeper root cause).

ParametersJSON Schema
NameRequiredDescriptionDefault
serviceYes
directionNoupstream

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It explains the core operation but does not disclose any side effects, limitations, authorization needs, or whether it is read-only. It is safe to assume read-only, but not stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, first defines the tool's function, second explains the two directions. No redundant words, efficient and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of transitive dependency closure, the description is mostly complete. However, it lacks details about the return format (e.g., list of service names). With no output schema, this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so description compensates. It adds meaning for the 'direction' parameter (upstream vs downstream) beyond the schema's title and default. However, 'service' is not elaborated beyond its name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it computes transitive dependency closure over DEPENDS_ON edges, distinguishes upstream (blast radius) and downstream (deeper root cause) directions. It is specific and differentiates from sibling tools like woodpecker_diagnose_root_cause which is a different operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context on when to use each direction but does not explicitly tell when to use this tool versus alternatives like woodpecker_get_topology or woodpecker_diagnose_root_cause. The implicit guidance is through the blast radius concept.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

woodpecker_get_service_healthA

Detailed health snapshot for one service: status, container state/health, restarts, 5xx error rate, db pg_up, scrape health, and blind-spot flag.

ParametersJSON Schema
NameRequiredDescriptionDefault
serviceYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the output fields (status, container state, restarts, error rate, etc.), suggesting a read-only health check. It does not mention side effects or hidden behaviors, but the information given is sufficient for basic transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that efficiently lists key output fields. It is front-loaded with the purpose and avoids extraneous detail. However, it could be slightly more structured for readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity (1 parameter, no output schema, no annotations), the description adequately covers the tool's function and output. It lists the fields returned, which compensates for the lack of output schema. The missing param semantics reduce completeness slightly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter 'service' is a string with 0% schema description coverage. The description does not explain what format or values 'service' expects (e.g., service name or ID), leaving the agent to guess. This is a significant gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it provides a 'detailed health snapshot for one service' and enumerates specific fields (status, container state/health, restarts, etc.), which distinguishes it from sibling tools like 'woodpecker_detect_blind_spots' or 'woodpecker_diagnose_root_cause'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for obtaining health details of a single service, but it does not provide explicit when-to-use or when-not-to-use guidance relative to siblings. The context is clear enough for a simple tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

woodpecker_get_topologyA

Return the materialized service dependency graph: every service, its current status, and the services it depends on. Call first to establish the causal structure before diagnosing. status in {healthy, erroring, unhealthy, restarting, hung, down}; monitoring='MISSING' flags a possible blind spot.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the output content (graph of services, statuses, dependencies), the status enum, and the meaning of monitoring='MISSING'. This provides good behavioral insight without hiding important details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: the first clearly states the function and output, the second adds usage guidance and additional detail on status values. No extraneous words; every sentence earns its place. Well-structured and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has zero parameters, no annotations, and no output schema, the description is thorough. It explains what is returned (graph with status and dependencies), key fields (status enum, monitoring flag), and when to use it. This is complete for an agent to understand and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so the schema description coverage is 100% by default. Per guidelines, baseline for 0 params is 4. The description does not need to add parameter semantics, and it does not mention any parameters (correctly).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool returns the materialized service dependency graph with each service's status and dependencies. It lists status enum values and mentions the monitoring='MISSING' flag, providing specific detail beyond a generic statement. This clearly distinguishes it from siblings by positioning it as the first call for causal structure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description advises 'Call first to establish the causal structure before diagnosing,' which gives clear when-to-use guidance relative to other diagnostic tools. It does not explicitly mention when not to use or name alternatives, but the context with sibling tools implies the flow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.2.0
    • First observedwoodpecker_detect_blind_spots
    • First observedwoodpecker_diagnose_root_cause
    • First observedwoodpecker_get_blast_radius
    • First observedwoodpecker_get_service_health
    • First observedwoodpecker_get_topology

TDQS

A4.2/5.0

Scored across 5 tools

Disambiguation5/5

Each tool serves a distinct role: detecting blind spots, diagnosing root causes, computing blast radius, providing service health, and retrieving topology. Minimal overlap, clear boundaries.

Naming Consistency5/5

All tools follow a consistent 'woodpecker_verb_noun' pattern using snake_case, e.g., woodpecker_detect_blind_spots, woodpecker_get_topology. No deviations.

Tool Count5/5

With 5 tools covering topology, health, blind spots, root cause, and blast radius, the set is well-scoped for diagnostic purposes without being excessive or thin.

Completeness5/5

The set provides a complete workflow for service dependency analysis: establish topology, check health, detect blind spots, find root cause, and compute blast radius. No obvious gaps for the intended domain.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server for Neo4j graph database operations, enabling Cypher queries, node/relationship management, and schema discovery.
    1
    BSD 3-Clause
  • A
    license
    A
    quality
    D
    maintenance
    Exposes a dependency graph of strategic sourcing artifacts and analyses as an MCP server, enabling navigation of phases, analyses, deliverables, and graph traversal for impact analysis and build order.
    16
    Apache 2.0
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables querying cross-repo code dependencies, HTTP routes, database tables, and queues via an MCP server using Cypher queries.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Exposes a Neo4j graph database as MCP tools, enabling AI agents to run read and write Cypher queries.
    -