CLI & MCP

Lint BPMN outside the app

The deterministic BPMN logic inspector is exposed two ways outside the web app — a CLI for local use and CI gates, and an MCP server so AI agents and IDEs can lint BPMN.

Both reuse @claril/logic-inspector (the rules) and @claril/bpmn-parse (headless BPMN 2.0 XML → ProcessGraph via bpmn-moddle, no browser or DOM). No AI key is required — this is pure Tier-1 deterministic analysis, so CLI / MCP findings match the editor exactly.

Install

In the monorepo, the claril binary loads the packages via tsx:

pnpm install

# run directly:
node packages/cli/bin/claril.js lint path/to/model.bpmn

# or, once linked:
pnpm --filter @claril/cli exec claril lint path/to/model.bpmn

CLI usage

claril lint <file.bpmn|glob...> [--json] [--quiet]
claril mcp
claril --help | --version

lint options:

  • --json — emit machine-readable findings (an array of { source, findings, parseWarnings }).
  • --quiet — text mode, but only print files that have findings.

Multiple files and globs are supported (claril lint "diagrams/**/*.bpmn"). Quote globs so your shell does not expand them first. Colors are emitted only on a TTY and are disabled when NO_COLOR is set.

Example output

$ claril lint bad.bpmn
bad.bpmn
  error    structural/missing-end-event  Process has no end event.
      fix: Add an end event so the process can complete.
  error    structural/unreachable-node   "Never reached" is unreachable. (Orphan)
      fix: Connect it from the main flow, or remove it.
  warning  best-practice/unlabeled-gateway  Decision gateway "Gw_1" is unlabeled.

1 file: 2 error, 4 warning, 0 info

Exit-code contract (CI gate)

  • 0 — no error-severity findings (warnings / info are allowed).
  • 1 — at least one error-severity finding. Use this as the CI gate.
  • 2 — usage error: no files matched, a file could not be read, or the XML is not BPMN.
CI step
- run: node packages/cli/bin/claril.js lint "diagrams/**/*.bpmn"
  # fails the job on exit 1 (errors) or 2 (usage problems)

MCP server

claril mcp starts a stdio MCP server (@modelcontextprotocol/sdk) named claril-lint, exposing one tool.

lint_bpmn

  • Input: { xml?: string, path?: string } — provide inline BPMN XML or an absolute file path (one is required).
  • Output: structuredContent (also mirrored as JSON text): { source, ok, counts: { error, warning, info }, findings[], parseWarnings[] }, where ok is true when there are no error-severity findings. Each finding is { ruleId, severity, message, elementId?, quickFix? }.

Client config

Claude Desktop / any MCP client (an entry in the client's server list):

mcpServers entry
{
  "mcpServers": {
    "claril": {
      "command": "node",
      "args": ["/abs/path/to/claril/packages/cli/bin/claril.js", "mcp"]
    }
  }
}

Once the CLI is published / linked on your PATH, this simplifies to:

{
  "mcpServers": {
    "claril": { "command": "claril", "args": ["mcp"] }
  }
}
The parser mirrors the browser canvas: start / end / intermediate events, tasks (and typed tasks), gateways, sub-processes (flattened), and sequence flows as edges. Container elements (process, collaboration, participant, lanes) are skipped — so the same rule set runs as in the editor.

Next: connect a model for the AI co-editor in AI providers.