pm4py-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pm4py-mcp Discover a Petri net from the running example log."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pm4py-mcp
An AGPL-licensed, stdio-first Model Context Protocol server that wraps PM4Py behind a small handle-based tool surface — making research-grade process mining available to Claude and any MCP-capable agent, locally and on open standards (XES, OCEL 2.0, BPMN, PNML).
Status: Phase 2 Part 2 complete —
pm4py-mcp 0.4.1ships 67 workflow-shaped tools + 7 curated prompts spanning I/O, discovery (traditional + DECLARE + log skeleton + POWL + temporal profile), conformance, filtering, statistics, visualization (Graphviz + matplotlib), OCEL 2.0, textual abstractions, domain-context injection, model conversions, organizational mining, simulation, and Markdown report rendering. Installable viauvx pm4py-mcp. (0.4.1 adds 5 organizational-mining discovery tools +abstract_sna+simulate_log+visualize_dotted_chart+visualize_performance_spectrum+/organizational_analysisprompt.)
Today — load XES / CSV / Parquet logs or OCEL 2.0 (JSON / XML / SQLite), discover Petri nets / process trees / BPMN / DFGs / object-centric Petri nets / OC-DFGs, run token-replay or alignment conformance, filter chains, render dual-channel PNG + SVG — and now turn every artifact into a textual abstraction the LLM can read directly, register domain SOPs that prompts respect across the session, and render a final Markdown report from accumulated findings. 48 natural-language tools + 6 slash-command prompts, fully local, nothing leaves your machine.
Next (0.4.0) — advanced discovery (DECLARE, POWL, log skeleton, organizational mining), model conversions (Petri ↔ BPMN ↔ Process Tree ↔ POWL), simulation (play_out), dotted chart + performance spectrum, plus the matching abstract_declare / abstract_log_skeleton / abstract_temporal_profile tools. Team deployment via Streamable HTTP lands in Phase 4.
Why
No open-source MCP server for process mining exists today. Celonis, SAP Signavio, and Microsoft Power Automate Process Mining all ship closed, SaaS-bound equivalents — and none of them support OCEL 2.0. pm4py-mcp fills the open, local, Python-native quadrant: event logs never leave the machine, algorithms are research-grade (Inductive Miner variants, alignments, OCEL 2.0, object-centric Petri nets), and the server composes cleanly into LangGraph / CrewAI / AutoGen crews.
Related MCP server: Claude-LMStudio-Bridge
Install
Prerequisites
Python 3.10–3.13 via
uvGraphviz —
dotmust be on PATH for visualization tools.Windows:
winget install Graphviz.GraphvizmacOS:
brew install graphvizUbuntu:
sudo apt install graphviz
Optional
[ocel]extra — only needed for relational (parquet-backed) OCELs.pip install 'pm4py-mcp[ocel]'oruvx --with 'pm4py-mcp[ocel]' pm4py-mcp. JSON-OCEL, XML-OCEL, and SQLite-OCEL work without it.
Claude Desktop / Claude Code configuration
MCP users configure servers via JSON, not via pip install. Add this to claude_desktop_config.json (or your Claude Code MCP settings):
{
"mcpServers": {
"pm4py": {
"command": "uvx",
"args": ["pm4py-mcp@latest"],
"env": {
// Optional but strongly recommended — resolves relative paths (e.g.
// "examples/benchmarks/sepsis.xes.gz") against your project root when the
// server's own CWD isn't under it. Works in Claude Code / Desktop / most IDEs.
"PM4PY_MCP_CWD_HINT": "${workspaceFolder}"
}
}
}
}Quit Claude Desktop from the system tray (not just close the window) and relaunch. The server auto-downloads on first use.
Once the MCP client picks up the config, pm4py shows up as a connected server:

Walking examples
Traditional log — examples/running-example.xes
"Load the log at
<path>/examples/running-example.xes. Describe it. Discover a Petri net with 0.2 noise threshold. Check conformance with token replay. Show me the diagram."
Claude will chain load_event_log → describe_log → discover_petri_net → conformance_token_replay → visualize_petri_net, returning an inline Petri-net PNG plus the fitness number and absolute file paths for the PNG + SVG. The bundled example log is an 8-case hospital-admission process with two variants:

Token-replay conformance against this model returns mean_trace_fitness = 1.0 (8/8 fit cases).
Object-centric log — examples/order-management.jsonocel
"Load
<path>/examples/order-management.jsonocel. What object types are in it? Flatten it byorderand discover a Petri net from that view. Now discover the object-centric Petri net across all object types and show me the diagram."
Claude chains load_ocel → describe_ocel → flatten_ocel(object_type="order") → discover_petri_net (Phase 1 tool on the flattened log) → discover_oc_petri_net → visualize_oc_petri_net. The OCPN shows three color-separated flows (order, item, delivery) sharing the Pick Item and Ship transitions — multi-object interactions that a flattened log would lose:

The bundled OCEL is a 3.7 KB synthetic order-management process with 3 object types (order, item, delivery), 10 events, 8 objects.
Try it on a real log
The bundled examples are tiny by design. To try pm4py-mcp on real-sized public logs, run the downloader script once (stdlib-only, no extra deps):
uv run python scripts/download_benchmark_logs.py --list # show available benchmarks
uv run python scripts/download_benchmark_logs.py sepsis # ~200 KB — hospital sepsis pathway (default)
uv run python scripts/download_benchmark_logs.py bpi2012 # ~3 MB — loan applications
uv run python scripts/download_benchmark_logs.py bpi2017 # ~28 MB — richer loan-application log
uv run python scripts/download_benchmark_logs.py all # all threeFiles land in examples/benchmarks/ (gitignored — the script is idempotent and MD5-verifies on download). Then in Claude:
"Load the log at
examples/benchmarks/sepsis.xes.gz. Describe it, then discover a Petri net and show me the diagram."
Sepsis is the canonical teaching log: 1050 cases, 15214 events, 16 activities of a real hospital sepsis pathway from 2013–2015 (Mannhardt 2016).
Prompt-driven: /new_log_onboarding on a real log
Once a benchmark log is downloaded, the fastest way to see 0.3.0's agentic layer is a slash command:
/new_log_onboarding examples/benchmarks/sepsis.xes.gz
Claude chains load_event_log → describe_log → abstract_log_features → abstract_log_attributes → abstract_variants and writes a ≤300-word first-impression summary covering case count, activity spread, dominant variants, and anomalies — in one turn, no manual tool chaining. This is the same prompt library 0.3.0 ships six canonical entries for: /new_log_onboarding, /conformance_workflow, /bottleneck_analysis, /variant_exploration, /ocel_flattening_workflow, /executive_summary.
Tool catalog (Phase 1 + 2 + 3 + 2 Part 2 — 67 tools)
All tools accept a handle (log_id, petri_id, ocel_id, …) or — for load_* tools — a file path. None returns the log itself; responses are always compact summaries plus new handles.
Traditional log I/O (4)
Tool | Purpose |
| Read XES / CSV / Parquet; returns |
| Recompute the summary for a loaded log. |
| Write XES or CSV back out. |
| Enumerate derived artifacts in |
OCEL 2.0 I/O + the flatten bridge (4)
Tool | Purpose |
| Read JSON-OCEL / XML-OCEL / SQLite-OCEL; returns |
| Object types, per-type event counts, activities preview, time range. |
| Composability bridge — projects to a traditional |
| Write JSON-OCEL / XML-OCEL / SQLite back out. |
Statistics (5)
Tool | Purpose |
| Most-common trace variants and counts. |
| First/last activity frequency dicts. |
| Min/max/mean/median + p50/p75/p90/p95/p99. |
| Average inter-completion delay. |
| Sample case IDs ( |
Traditional discovery (4)
Tool | Purpose |
| Directly-follows graph. |
| Inductive / Heuristics / Alpha miner. |
| Process tree via Inductive Miner. |
| BPMN via Inductive Miner + conversion. |
Advanced discovery (4) (0.4.0)
Tool | Purpose |
| DECLARE model: 17 constraint templates (response, precedence, succession, ...). |
| 6-family behavioral skeleton (equivalence, always_after, ...). |
| POWL (Partially Ordered Workflow Language) model. |
| Per-activity-pair mean + stddev sojourn times. |
Model conversions (1) (0.4.0)
Tool | Purpose |
| Convert between |
Organizational mining (5) (0.4.1)
Each tool requires an org:resource attribute in the log. All 4 network tools store under the "sna" kind; discover_organizational_roles under "org_roles". Use with abstract_sna for prose descriptions.
Tool | Purpose |
| Directed work-handoff network between resources. |
| Undirected collaboration (same-case participation). |
| "A hands briefly to B and resumes" patterns. |
| Skill overlap via activity profiles. |
| Cluster resources by activity sharing. |
Simulation (1) (0.4.1)
Tool | Purpose |
|
|
OCEL discovery (2)
Tool | Purpose |
| Object-centric directly-follows graph. |
| Object-centric Petri net. |
Conformance (2)
Tool | Purpose |
| Fast token-based fitness check. |
| Alignment-based fitness. Async; emits progress for long runs. |
Traditional filtering (5)
All filter tools mint a new log_id — the original is untouched, so filter chains keep every intermediate handle.
Tool | Purpose |
| Keep/drop by variant. |
| ISO-8601 time window with 7 mode options. |
| Event- or case-level attribute filter. |
| By event count per case. |
| By end-to-end case duration. |
OCEL filtering (4 — consolidated)
Four tools wrap 7 PM4Py filter functions via level / strategy dispatch. Each mints a fresh ocel_id.
Tool | Purpose |
| Time-window filter; accepts ISO-8601. |
|
|
| Keep or drop whole object types. |
| Connected-component filter. |
Traditional visualization (5)
Each viz tool saves both PNG and SVG to ~/.pm4py-mcp/workspace/, returns a caption with absolute paths, and embeds the PNG inline when it fits under ~700 KB.
Tool | Purpose |
| Render a Petri net. |
| Render a DFG. |
| Render a process tree. |
| Render a BPMN diagram. |
| Render a POWL model — partial-order edges between sub-workflows. (0.4.0) |
Advanced visualization (2) (0.4.1)
PNG-only (single-channel). Graphviz/neato-backed under the hood — requires the dot/neato binaries like other viz tools.
Tool | Purpose |
| Time-vs-value scatter. Default |
| Duration-per-case across an ordered activity subset. |
OCEL visualization (2)
Tool | Purpose |
| Render an OC-DFG — edges colored per object type. |
| Render an OCPN — per-type places and cross-type shared transitions. |
Textual abstractions (13)
Every abstraction returns {content, approx_tokens, truncated, source_handle, tool} so Claude can reason over the text instead of a PNG it can't read. Uses pm4py.algo.querying.llm.abstractions.*_to_descr under the hood.
Tool | Purpose |
| Log-level feature description (concurrency, skeleton, timing). |
| Case/event attribute distributions. |
| Ranked variants with durations. |
| DFG in prose with sojourn times. |
| Single-case walk-through; NaN-attrs dropped by default (0.3.2). |
| Reverse-chronological event tail. |
| Structural description of places/transitions/markings. |
| Per-object-type event description for an OCEL. |
| Object-centric DFG in prose. |
| Prose description of a DECLARE model's constraints. (0.4.0) |
| Prose description of a log skeleton's 6 constraint types. (0.4.0) |
| Prose description of per-pair mean/stddev sojourn times. (0.4.0) |
| Top-k strongest connections + sink/source resources from a social-network handle. (0.4.1) |
Domain context (2)
Register a once-per-session SOP or glossary — every prompt template prepends it automatically.
Tool | Purpose |
| Store inline text or read from file. Capped at 20 KB × 16 entries. |
| Retrieve a stored context for inspection. |
Reports (1)
Tool | Purpose |
| Assemble Markdown with embedded images, timestamped, version-footered. |
Health check (1)
Tool | Purpose |
| Returns |
Prompt library (7 slash commands)
User-invoked via @mcp.prompt. Each seeds a canonical investigation and respects set_domain_context.
Prompt | Arguments | What it does |
|
| ≤300-word first-impression summary. |
|
| Discover + token replay + alignments + explain. |
|
| Slowest variants + bottleneck DFG edges + hypothesis. |
|
| Top-k variants; drill into the dominant one. |
|
| Compare object-type perspectives on an OCEL. |
|
| Map team structure + handoff patterns + roles from |
|
| Consolidate findings into |
Roadmap
Phase | Scope | Status |
0 | Walking skeleton: packaging, | ✅ shipped (0.0.1) |
1 | Core traditional-log toolkit: load / discover / conform / filter / visualize | ✅ shipped (0.1.0) |
2 Part 1 | OCEL 2.0 namespace + the flatten bridge | ✅ shipped (0.2.0) |
3 | Agentic layer: textual abstractions, prompt library, domain context, reports | ✅ shipped (0.3.0) |
2 Part 2 (first half) | Advanced discovery (DECLARE, log skeleton, POWL, temporal profile), 3 new abstractions, POWL viz, model conversions | ✅ shipped (0.4.0) |
2 Part 2 (second half) | Organizational mining (5 tools), simulation ( | ✅ shipped (0.4.1) |
3.1 |
| planned |
4 | Hardening: Streamable HTTP, sandboxed | planned |
See Roadmap of development.pdf for the architectural rationale.
Architecture highlights
Handle-based state. Event logs (10 MB – 1 GB) stay server-side in an LRU
LogRegistry(8 entries, 1-hour TTL). Tools exchange short typed handles (log-,pn-,bpmn-,pt-,dfg-,ocel-,ocdfg-,ocpn-) — never the logs themselves. Claude Desktop's ~1 MB response cap makes this mandatory.The flatten bridge.
flatten_ocel(ocel_id, object_type) → log_idis what makes the parallel OCEL namespace composable with the traditional-log namespace. Phase 2 didn't duplicate Phase 1's 20+ tools for OCEL; it exposed one tool that projects OCELs onto any object-type perspective and hands the result back into Phase 1.Dual-channel visualizations. Every render tool writes both PNG and SVG to the workspace, returns text + absolute paths, and attaches inline PNG only when it fits under ~700 KB.
Tools raise exceptions, never return error strings. FastMCP converts raised exceptions into
isError=trueresponses the LLM can recover from.Long-running tools emit progress via
ctx.report_progress— alignments on a 500 MB log can exceed five minutes and need client timeout resets.Aggressive consolidation over API-mirroring. OCEL filtering wraps 7 PM4Py functions behind 4 tools via
strategy/leveldispatch; 4 CC variants share a single verb. Smaller tool surface → smaller prompt → cleaner LLM choices.Tool surface stays focused. 67 workflow-shaped verbs — not 1:1 with PM4Py's ~200-function API.
Abstract-then-prompt. Phase 3 adds textual abstractions alongside every visual one: instead of handing the LLM a PNG it can't read, pm4py-mcp exposes
abstract_*tools that return the same artifact as prose. The prompt library then guides Claude through the abstract-then-reason loop so answers cite numbers and activity names instead of generalities.
License
AGPL-3.0-or-later, matching PM4Py's upstream license. Contributions require a DCO sign-off (git commit -s); no CLA.
Contributing
See CONTRIBUTING.md for dev setup, testing instructions, and architectural guardrails. Issues and discussions are open at https://github.com/azizketata/pm4py-mcp.
Available Tools
67 toolsabstract_caseA
Describe one case as a natural-language walkthrough of its events.
case_id must match a value in the log's case:concept:name column.
pm4py's case_to_descr has no MAX_LEN parameter — the full case
description is always returned, so truncated is always False.
drop_nan_attrs (default True, new in 0.3.2) strips
<attr> = nan substrings from the output, cutting token use by ~70%
on real logs without losing any non-NaN signal. Pass False for the
exact pre-0.3.2 verbose output.
Inputs: log_id (required), case_id (required), drop_nan_attrs, include_event_attributes. Returns: object
abstract_declareA
Natural-language description of a discovered DECLARE model.
Takes the handle returned by discover_declare. Wraps
declare_to_descr.apply. pm4py's descriptor has no MAX_LEN knob, so
truncated is always False and the full constraint set is
described.
Inputs: declare_id (required). Returns: object
abstract_dfgA
Directly-follows graph rendered as text.
Note: takes log_id, not dfg_id. pm4py computes the DFG
internally for description. For the rendered PNG/SVG, use Phase 1's
discover_dfg → visualize_dfg pair instead.
Inputs: log_id (required), max_len, include_performance. Returns: object
abstract_log_attributesB
Textual description of attribute distributions (value frequencies, quantiles).
Wraps log_to_cols_descr.apply. Useful for the LLM to understand what
slicing dimensions exist in the log.
Inputs: log_id (required), max_len. Returns: object
abstract_log_featuresC
Textual description of log-level features (activity set, concurrency, timing).
Wraps pm4py.algo.querying.llm.abstractions.log_to_fea_descr.apply.
Truncated at max_len characters (pm4py's native limit).
Inputs: log_id (required), max_len. Returns: object
abstract_log_skeletonA
Natural-language description of a discovered log skeleton.
Takes the handle returned by discover_log_skeleton. Wraps
logske_to_descr.apply. No MAX_LEN parameter; always returns the
full skeleton in prose.
Inputs: log_skeleton_id (required). Returns: object
abstract_ocdfgA
Object-centric directly-follows graph as text.
Note: takes ocel_id, not ocdfg_id. pm4py computes the OCDFG
internally for description. For the rendered version, use Phase 2's
discover_ocdfg → visualize_ocdfg pair.
Inputs: ocel_id (required), max_len, include_performance. Returns: object
abstract_ocelA
Textual description of OCEL features for a single object type.
object_type must be one of the OCEL's object types (see describe_ocel).
Wraps ocel_fea_descr.apply(ocel, object_type). Useful before deciding
which object type to flatten_ocel on.
Inputs: ocel_id (required), object_type (required), max_len. Returns: object
abstract_petri_netA
Describe a Petri net (from discover_petri_net) in natural language.
Wraps net_to_descr.apply(net, im, fm). Enumerates places, transitions,
arcs, and the initial / final markings. pm4py's net_to_descr has no
MAX_LEN parameter — the full description is always returned, so
truncated is always False.
Inputs: petri_id (required). Returns: object
abstract_snaA
Describe the top-k connections of a social-network (SNA) model in prose.
pm4py's LLM abstractions do NOT ship an sna_to_descr; this tool is
hand-written. It reports:
total resource / connection counts
the
top_kstrongest connections by weight (source → target, weight)resources with no outgoing connections (network sinks — common endpoints)
resources with no incoming connections (network sources — unusual entry points)
Works on any handle produced by discover_handover_network,
discover_working_together_network, discover_subcontracting_network,
or discover_activity_based_resource_similarity. truncated is always
False since top_k bounds the output.
Inputs: sna_id (required), top_k. Returns: object
abstract_streamA
Tail of events in reverse-chronological order.
Answers "what happened recently in this log?" without computing variants
or discovering a model. Wraps stream_to_descr.apply.
Inputs: log_id (required), max_len. Returns: object
abstract_temporal_profileA
Natural-language description of a discovered temporal profile.
Takes the handle returned by discover_temporal_profile. Wraps
tempprofile_to_descr.apply. The profile dict is keyed by
Tuple[str, str] activity pairs; the descriptor internally formats
these and never surfaces the raw tuples to JSON serialization.
No MAX_LEN parameter; full profile is described.
Inputs: temporal_profile_id (required). Returns: object
abstract_variantsB
Trace variants + frequencies + (optionally) per-variant performance.
Wraps log_to_variants_descr.apply. Variants are auto-ranked by
frequency internally; truncation happens when the combined description
hits max_len characters — not via a top_k parameter.
Inputs: log_id (required), max_len, include_performance. Returns: object
conformance_alignmentsA
Alignment-based conformance check.
More accurate than token replay but slower — can take minutes on large
logs. multi_processing=True parallelizes across cores (disabled by
default since Windows multiprocessing has spawn-restrictions that can
interact badly with the stdio transport).
Emits progress events so the client keeps the request alive past its default timeout.
Inputs: log_id (required), petri_id (required), multi_processing. Returns: object
conformance_token_replayA
Token-based replay conformance check.
Returns mean trace fitness (0.0..1.0) and the count of perfectly-fit
traces. For detailed per-trace diagnostics, re-run the PM4Py
conformance_diagnostics_token_based_replay directly — we keep the
MCP response compact on purpose.
Inputs: log_id (required), petri_id (required). Returns: object
convert_modelA
Convert a process model from one representation to another.
source_id is any model handle (Petri net, BPMN, process tree, POWL).
target_kind is one of "petri_net", "bpmn", "process_tree".
Supported pairs:
→ petri_net: from bpmn, process_tree, powl
→ bpmn: from petri_net, process_tree
→ process_tree: from petri_net, bpmn, powl
Unsupported combinations raise InvalidKind. The new handle records
source_handle=source_id so lineage is debuggable.
Inputs: source_id (required), target_kind (required). Returns: object
describe_logA
Return the compact summary for a previously loaded log.
Exact same shape as the summary attached to load_event_log's
response, re-computed on demand. Raises :class:HandleNotFound if
the registry has evicted the log (1-hour TTL or LRU overflow).
Inputs: log_id (required). Returns: object
describe_ocelA
Return the compact summary for a previously loaded OCEL.
Exact same shape as the summary attached to load_ocel's response,
re-computed on demand. Raises :class:HandleNotFound if the registry
evicted the OCEL (1-hour TTL or LRU overflow).
Inputs: ocel_id (required). Returns: object
discover_activity_based_resource_similarityA
Discover the activity-based resource-similarity network.
An edge A ↔ B weighted by how similar the activity profiles of A and B are. Captures "who does similar kinds of work" — complements handover by showing skill/role overlap.
Inputs: log_id (required), activity_key, resource_key. Returns: object
discover_bpmnC
Discover a BPMN diagram via the Inductive Miner.
Convenience wrapper over discover_process_tree_inductive + BPMN
conversion. Returns a handle plus node/flow counts.
Inputs: log_id (required), noise_threshold. Returns: object
discover_declareB
Discover a DECLARE model from an event log.
DECLARE is a declarative constraint notation capturing patterns like "response" (if A then eventually B) or "precedence" (B requires A earlier). PM4Py returns a nested dict: template → (activity-tuple → {"support": N, "confidence": N}).
min_support_ratio / min_confidence_ratio prune weak constraints
(both in [0, 1]; default None uses pm4py's internal defaults).
Returns a handle plus counts of templates covered and constraints found.
Inputs: log_id (required), min_support_ratio, min_confidence_ratio. Returns: object
discover_dfgA
Discover the directly-follows graph (DFG) of an event log.
Returns a handle for later rendering via visualize_dfg plus a
shape summary (edge count, start/end activity counts).
Inputs: log_id (required). Returns: object
discover_handover_networkB
Discover the handover-of-work network.
An edge A → B means resource A's activity was directly followed by
resource B's activity within the same case. beta controls distance
decay (0 = direct handover only; larger values weigh indirect handoffs).
Returns a handle under the "sna" kind plus resource / connection counts.
Inputs: log_id (required), beta, resource_key. Returns: object
discover_log_skeletonB
Discover a log skeleton — a set of behavioral constraints per activity pair.
The log skeleton captures six constraint types (equivalence, always_after, always_before, never_together, directly_follows, activ_freq). Useful as a declarative complement to Petri-net / process-tree discovery.
noise_threshold in [0, 1] prunes infrequent patterns.
Inputs: log_id (required), noise_threshold. Returns: object
discover_ocdfgA
Discover an object-centric directly-follows graph (OC-DFG).
Returns a handle for later rendering via visualize_ocdfg plus a
shape summary: activity count, object types, and per-object-type edge
counts (the "how many distinct activity pairs does this object type
induce" signal).
Inputs: ocel_id (required). Returns: object
discover_oc_petri_netA
Discover an object-centric Petri net (OCPN).
variant dispatches the underlying Inductive Miner:
"im"(default) — classical Inductive Miner on each per-type projection"imd"— Inductive Miner Directly-Follows (faster, less precise)
Returns a handle to the OCPN plus per-object-type structural counts.
Inputs: ocel_id (required), variant. Returns: object
discover_organizational_rolesB
Discover organizational roles — activity-sharing clusters of resources.
pm4py returns a List[Role] where each role has:
activities: list of activities that cluster togetheroriginator_importance: dict mapping resource → weight within the role
Returns a handle under "org_roles" plus counts and a preview of the
top 5 roles by importance sum.
Inputs: log_id (required), activity_key, resource_key. Returns: object
discover_petri_netA
Discover a Petri net from an event log.
algorithm dispatches to one of three PM4Py miners:
"inductive"(default) — Inductive Miner, sound-by-construction. Acceptsnoise_thresholdin [0, 1] to prune infrequent behavior."heuristics"— Heuristics Miner, robust to noise."alpha"— classical Alpha Miner.
Returns a handle to the (net, initial_marking, final_marking) triple
plus structural counts. The model is stored with kind petri_net.
Inputs: log_id (required), algorithm, noise_threshold. Returns: object
discover_powlA
Discover a POWL model (Partially Ordered Workflow Language).
POWL generalizes process trees by letting siblings have partial-order dependencies rather than strict sequence / concurrency / choice. Useful when the discovered model has unclear sibling ordering.
variant is pm4py's default (dynamic variant selection). Returns a
handle plus the root operator name and top-level child count.
Inputs: log_id (required). Returns: object
discover_process_treeA
Discover a process tree via the Inductive Miner.
Process trees compose cleanly and convert to Petri nets / BPMN. Returns a handle to the tree plus its structural shape.
Inputs: log_id (required), noise_threshold. Returns: object
discover_subcontracting_networkC
Discover the subcontracting network.
An edge A → B means: A did something, then within n events B did
something, then A resumed. Captures "A hands off briefly to B and takes
over again" patterns.
Inputs: log_id (required), n, resource_key. Returns: object
discover_temporal_profileA
Discover a temporal profile — per-activity-pair mean + stddev of sojourn time.
For every ordered activity pair (A, B) seen in any case, the profile
records (mean_seconds, std_seconds). Useful for anomaly detection:
an execution where a pair is much slower than its profile mean is flagged.
Returns a handle plus the number of pairs observed.
Inputs: log_id (required). Returns: object
discover_working_together_networkB
Discover the working-together network.
An edge A ↔ B means resources A and B participated in the same case at least once. Captures collaboration patterns independent of order.
Inputs: log_id (required), resource_key. Returns: object
export_logA
Write a log from the registry to disk.
format must be "xes" or "csv". If path has no directory
component, the file lands in the workspace; otherwise the given path
(absolute or relative to CWD) is used verbatim.
Inputs: path (required), format (required), log_id (required). Returns: object
export_ocelA
Write an OCEL from the registry to disk.
format must be one of "jsonocel", "xmlocel", "sqlite". If
path has no directory component, the file lands in the workspace;
otherwise the given path (absolute or relative to CWD) is used verbatim.
Inputs: path (required), format (required), ocel_id (required). Returns: object
filter_attribute_valuesA
Filter a log by event or case attribute values.
level='event' removes individual events; level='case' removes
entire cases. retain=True keeps the matching rows; False drops
them. The level parameter is passed explicitly to avoid PM4Py's
deprecation warning when it defaults to None.
Inputs: log_id (required), values (required), attribute (required), level, +1 more. Returns: object
filter_case_performanceA
Keep only cases whose total elapsed time is in [min_seconds, max_seconds].
Performance is measured as last_event_timestamp - first_event_timestamp
of each case, in seconds. Useful for isolating slow or fast cases.
Inputs: log_id (required), max_seconds (required), min_seconds (required). Returns: object
filter_case_sizeB
Keep only cases with an event count in [min_size, max_size].
Useful for removing outlier cases (very short or very long traces) before discovery / conformance.
Inputs: log_id (required), max_size (required), min_size (required). Returns: object
filter_ocel_attributeA
Filter an OCEL by event or object attribute values.
level='event' dispatches to pm4py.filter_ocel_event_attribute;
level='object' dispatches to pm4py.filter_ocel_object_attribute.
retain=True keeps the matching rows, False drops them — this
maps to PM4Py's positive parameter.
Inputs: values (required), ocel_id (required), attribute (required), level, +1 more. Returns: object
filter_ocel_ccA
Connected-component filtering — the OCEL-specific power feature.
Dispatches on strategy:
"activity"— keep events in the connected component containing any object touched by activityvalue(string).retainis ignored."object"— keep events in the connected component containing the object with idvalue(string).retainis ignored."otype"— filter by the connected component of an object type.valueis a string;retaincontrols keep-vs-drop."length"— keep CCs whose size is in[min, max].valueis a two-element integer list[min, max].retainis ignored.
PM4Py's CC filters are marked experimental; expect occasional edge-case failures on malformed OCELs.
Inputs: value (required), ocel_id (required), strategy (required), retain. Returns: object
filter_ocel_object_typesA
Keep or drop entire object types (and every event that only touched them).
types=['order', 'delivery'] with retain=True keeps only events/objects
related to orders and deliveries; with retain=False drops them.
Inputs: types (required), ocel_id (required), retain. Returns: object
filter_ocel_time_rangeB
Keep only events whose timestamp falls in [start, end].
start and end accept ISO-8601 strings (2024-01-01T08:00:00).
pm4py's underlying filter parses with '%Y-%m-%d %H:%M:%S', so we
normalize via pandas first.
Inputs: end (required), start (required), ocel_id (required). Returns: object
filter_time_rangeA
Filter a log by a time window.
start and end are ISO-8601 datetime strings. mode chooses
which notion of "within the window" applies:
"events"(default) — keep individual events inside the window."traces_contained"— keep traces entirely within the window."traces_intersecting"— keep traces with any event in the window."traces_starting_in"/"traces_completing_in"— keep traces whose first/last event falls in the window.
Inputs: end (required), start (required), log_id (required), mode. Returns: object
filter_variantsA
Filter a log by trace variant.
Exactly one of top_k and variants must be given:
top_k=N— keep (or remove, ifretain=False) the N most frequent variants. Useful for ignoring rare noise.variants=[[act1, act2, ...], ...]— keep/remove specific variants by their full activity sequence.
Inputs: log_id (required), top_k, retain, variants. Returns: object
flatten_ocelA
Project an OCEL onto a single object type and return a traditional log handle.
This is the Phase 2 composability bridge. The resulting log_id works
with every Phase 1 tool — discover, conform, filter, visualize.
Raises :class:UnsupportedFormat if object_type is not present in the OCEL.
Inputs: ocel_id (required), object_type (required). Returns: object
get_case_durationsA
Return summary statistics for per-case durations (seconds).
Returns count, min, max, mean, median, and the
50/75/90/95/99 percentiles. The full per-case list is NOT returned —
it can be 100k+ floats on a real log and blow the response cap.
Inputs: log_id (required). Returns: object
get_cycle_timeA
Return the average cycle time (seconds between case completions).
Unlike get_case_durations (which measures elapsed time per case),
cycle time measures throughput — inter-completion delay at the process
level. Useful for capacity planning.
Inputs: log_id (required). Returns: object
get_domain_contextB
Retrieve a previously-stored domain context.
Raises :class:ContextNotFound if the name is not registered.
Inputs: name. Returns: object
get_start_end_activitiesA
Return the frequency of start and end activities across all cases.
Two dicts keyed by activity name → count. Useful for spotting unexpected entry / exit points in a process.
Inputs: log_id (required). Returns: object
get_variantsB
Return the most-common trace variants and their counts.
Caps output at top_k variants (default 20) and includes the total
variant count so the caller knows if the list was truncated.
Inputs: log_id (required), top_k. Returns: object
list_workspaceA
List files currently in the workspace directory.
Reports each entry's name, absolute path, size, and modification time. Subdirectories are included by name but not recursed into.
Inputs: no named parameters. Returns: object
load_event_logA
Read an event log from disk and store it under a fresh log_id handle.
Format is inferred from the file extension when format is not passed.
Supported: XES (.xes, .xes.gz), CSV (.csv), Parquet (.parquet).
For CSV and Parquet, the three *_key parameters tell pm4py which
columns to treat as case id / activity / timestamp. Defaults assume the
pm4py-standard column names.
Returns a dict with log_id plus a compact summary (case/event counts,
activities preview, time range, top 5 variants). Never returns the log
itself — subsequent tools retrieve it by handle.
Inputs: path (required), format, case_id_key, activity_key, +1 more. Returns: object
load_ocelA
Read an OCEL 2.0 file from disk and store it under a fresh ocel_id handle.
Format is inferred from the file extension:
.jsonocel/.json— JSON-OCEL (the most common format).xmlocel/.xml— XML-OCEL.sqlite— SQLite-OCEL
Returns a dict with ocel_id plus a compact summary (object types + per-type
event counts, activities preview, time range). Never returns the OCEL itself;
subsequent tools retrieve it by handle.
Use flatten_ocel to project the OCEL onto a single object type and obtain
a traditional log_id that composes with every Phase 1 tool.
Inputs: path (required). Returns: object
pingA
Health-check tool. Returns the server name and version.
Used by the testing pyramid and by humans verifying that a freshly installed server is reachable from their MCP client (Claude Desktop, Claude Code, MCP Inspector).
Inputs: no named parameters. Returns: result
render_reportA
Assemble a Markdown executive report from prose findings + artifact links.
Parameters
title
Report heading. Rendered as an H1.
findings
Markdown-formatted narrative. Pass the prose the LLM wrote after
calling abstract_* / get_* tools — bullet points, tables,
paragraphs all work. Leading/trailing whitespace is stripped.
artifact_paths
Optional list of absolute paths to PNG/SVG/CSV files produced
earlier in the session (e.g. by visualize_petri_net or
export_log). Images are embedded inline; other files are
listed as links.
output_path
Optional. Bare filename lands in the workspace; a path with
separators is honored as-is. When omitted, writes to a unique
file like report-abc123.md in the workspace.
Returns
dict
{"path": str, "size_bytes": int, "num_artifacts": int}.
Inputs: title (required), findings (required), output_path, artifact_paths. Returns: object
sample_case_idsA
Return a small sample of case IDs from a log.
Useful for picking a concrete case_id to pass to abstract_case
without having to export the log to disk first.
Strategies:
"first": IDs in original order (cheap; no sort)."longest": thencases with the most events."shortest": thencases with the fewest events.
For longest / shortest, the response includes an event_counts
dict so callers can see the sort key; first omits it.
Inputs: log_id (required), n, strategy. Returns: object
set_domain_contextA
Register a domain context (SOP, glossary, process description) under name.
text_or_path is treated as a file path if it resolves to an existing
readable file; otherwise as inline text. Subsequent calls with the same
name overwrite the stored value. Subsequent prompt invocations prepend
the stored context to their instructions.
Limits: 20 KB per context (raises WorkspaceError if exceeded),
16 named contexts max.
Inputs: text_or_path (required), name. Returns: object
simulate_logA
Simulate an event log by replaying a discovered model.
Accepts Petri net (tuple) or process tree handles. BPMN and POWL are NOT
supported by pm4py.play_out directly — convert them first via
convert_model(bpmn_id, target_kind="petri_net").
The returned log_id is a regular "log" kind, so the simulated log
composes with every Phase 1 tool. source_handle points at the source
model for lineage.
num_traces is capped at 10_000 to protect against runaway generation
on cyclic models.
Inputs: model_id (required), num_traces. Returns: object
visualize_bpmnA
Render a BPMN diagram (from discover_bpmn) as PNG + SVG.
Inputs: bpmn_id (required).
visualize_dfgC
Render a directly-follows graph (from discover_dfg) as PNG + SVG.
Inputs: dfg_id (required).
visualize_dotted_chartA
Render a dotted chart (Graphviz/neato, PNG-only output via our helper).
Dotted charts project events onto a time-vs-value scatter using the
provided attributes. Default ["concept:name", "time:timestamp"]
plots activity versus event time — the most useful view on an unfamiliar
log. Pass other attribute names (e.g. ["org:resource", "time:timestamp"])
to see resource timelines or any numeric/categorical column.
Requires the dot / neato binaries from Graphviz (same dependency
as the Phase 1 visualization tools).
Inputs: log_id (required), attributes.
visualize_ocdfgA
Render an OC-DFG (from discover_ocdfg) as PNG + SVG.
PM4Py colors the edges by object type, so the inline PNG visually separates the per-type flows. Frequency annotations are included by default.
Inputs: ocdfg_id (required).
visualize_oc_petri_netA
Render an object-centric Petri net (from discover_oc_petri_net) as PNG + SVG.
Inputs: ocpn_id (required).
visualize_performance_spectrumA
Render a performance spectrum (Graphviz/neato, PNG-only output via our helper).
Plots the duration of each case along an ordered activity list, revealing
bottleneck segments visually. activities is required — the chart is
only meaningful when the caller picks a subset of activities to track.
Typically the activities of interest from the dominant variant(s).
Requires the dot / neato binaries from Graphviz.
Inputs: log_id (required), activities (required).
visualize_petri_netA
Render a Petri net (from discover_petri_net) as PNG + SVG.
Inputs: petri_id (required).
visualize_powlA
Render a POWL model (from discover_powl) as PNG + SVG.
Graphviz-backed. POWL diagrams show partial-order edges between sub-workflows; the root operator is reported in the caption.
Inputs: powl_id (required).
visualize_process_treeA
Render a process tree (from discover_process_tree) as PNG + SVG.
Inputs: tree_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 67 tools
Each tool has a clearly distinct purpose, targeting different artifacts (logs, models, graphs, abstractions) and actions (discover, visualize, filter, abstract). Even similar tools like abstract_dfg vs discover_dfg+visualize_dfg are clearly separated by output type (text vs graph). Overlap is minimal and well-documented.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., discover_petri_net, abstract_log_features, filter_variants). There is no mixing of camelCase or other conventions, and the verbs are semantically grouped by function (discover_, abstract_, filter_, etc.).
With 67 tools, the server is far above the typical 3-15 range. While the domain (process mining) is broad, many tools could be consolidated (e.g., multiple social network discovery tools into one with a parameter). This large surface likely overwhelms LLM agents and increases selection errors.
The tool set covers the full lifecycle of process mining: loading, describing, filtering, discovering (many model types), visualizing, abstracting, conformance checking, simulation, model conversion, and export. There are no significant gaps for the intended analytical workflow.
Maintenance
Related MCP Connectors
MCP server for progressive tool usage at any scale (see https://klavis.ai)
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server for log file analysis. Gives LLMs the ability to efficiently analyze large log files without loading them into context.7101MIT
- AlicenseNot gradedqualityFmaintenanceA simple MCP server that enables Claude to communicate with locally running LLM models via LM Studio.9MIT
- AlicenseNot gradedqualityCmaintenanceLocal MCP server for Claude Code providing persistent memory, task planning, and agent coordination with full transparency and no network calls.2MIT
- AlicenseNot gradedqualityCmaintenanceMCP server that lets Claude Code delegate mechanical tasks to a local LLM for summarization, classification, extraction, and drafting.19 npm15MIT