Skip to content
Conduit

mcp server

Calane

Inspectable execution kernel for recurring analytical LLM workflows: versioned, schema-validated, multi-model pipelines with traceable run bundles

odadroca/Calanecommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 24, 2026

llm-pipeline-kernel

A small, inspectable execution kernel for recurring analytical LLM workflows.

It runs versioned, schema-validated, multi-model analysis pipelines and exports traceable run bundles. The core defensible artifact is a traceable, versioned, schema-validated reasoning run.

This is a kernel, not a platform. See the non-goals below.

What it is

A caller — a human, an LLM, an agent, an MCP client, a REST client, or an OpenAI-style tool caller — can:

  1. execute a named pipeline,
  2. resolve its prompts/specs (filesystem or Git registry),
  3. run channels across providers or delegated agents,
  4. validate structured outputs against JSON Schema,
  5. store the run (metadata, raw + parsed outputs, validation reports),
  6. emit telemetry (pluggable; no-op by default),
  7. synthesize results (synthesis is just another channel),
  8. optionally recurse (bounded, explicit — never model-decided), and
  9. export the full, reproducible run bundle.

Non-goals (binding)

  • No visual builder.
  • No hosted SaaS.
  • No authentication UI.
  • No billing.
  • No marketplace.
  • No general-purpose agent framework.
  • No LangGraph clone.
  • No Langfuse clone.
  • No prompt-management product.
  • No enterprise policy engine.

Plus, for the first implementation: no UI, no multi-tenant SaaS, no enterprise auth.

What's new since the initial public snapshot

Calane is a single-author project: it is developed in a private working repository and published here — this public repo is the canonical release surface, not a fork of third-party work. Each item below is visible as a commit in this repo's git log.

  1. security — vitest patched (GHSA-5xrq-8626-4rwp / CVE-2026-47429). Bumps the test runner to vitest@^4.1.0 (resolved to 4.1.8) and adds packages/core/tests/security-pins.test.ts — a regression guard that resolves the installed vitest/package.json and asserts >= 4.1.0, so any future downgrade fails the suite instead of silently re-introducing the vuln.
  2. examples — multi-model distillation pipelines. examples/pipelines/distillation.pipeline.yaml distils a subject across Claude / GPT / Mistral / Gemini in parallel, then synthesises on Anthropic with bounded depth-2 recursion (synthesis_only carry-forward). examples/pipelines/distillation_2key.pipeline.yaml is a trimmed variant that completes end-to-end with only MISTRAL_API_KEY + GEMINI_API_KEY (synthesis on Mistral, free-tier Gemini model). Shared prompts under examples/prompts/distillation/, schemas under examples/schemas/distillation.*.schema.json.
  3. docker — multi-stage Dockerfile + .dockerignore for the combined entrypoint. Mirrors render.yaml byte-for-byte (same port, same env defaults, same volume, same boot model) so the two deployment paths share one boot story. See docs/deploy-docker.md.
  4. fix — Node engine range aligned with vitest. package.json engines.node and render.yaml NODE_VERSION originally claimed Node 20, but the pinned pnpm@11.3.0 requires Node ≥22.13 (it imports node:sqlite, a Node-22 built-in) — a from-scratch pnpm install on Node 20 failed immediately. Discovered while running the first independent docker build of the pre-publication development tree. Both are now declared as "^22.0.0 || >=24.0.0" / "22", matching vitest@4.1.8's own engines range and dropping the non-LTS Node 23 line (EOL 2026-06-01) from the support matrix.

Architecture

Caller
  -> Gateway (CLI | REST | MCP | openai.json)
  -> PipelineExecutor
  -> PromptRegistryPlugin           (filesystem | git)
  -> ExecutionPlan                  (explicit channels, providers, depth, synthesis)
  -> ChannelExecutor                (direct_provider | delegated_agent)
  -> ProviderAdapter / DelegatedAgent
  -> JsonSchemaValidator (Ajv)
  -> ResultStorePlugin              (filesystem)
  -> TelemetrySink                  (no-op by default)
  -> RunBundleExporter

See docs/architecture.md for detail, and docs/plugin-model.md for the functional vs. observational plugin split.

Monorepo layout

PackagePurpose
packages/coreSpecs (TypeBox), executor, renderer, validator, bundle exporter, plugin interfaces
packages/providers/mockDeterministic mock provider (offline/tests)
packages/providers/anthropicAnthropic Messages API provider via the official SDK
packages/providers/openai-compatibleFetch-based OpenAI-compatible provider + delegated-agent placeholder
packages/registries/filesystemFilesystem prompt/pipeline/schema registry
packages/registries/gitMinimal Git registry (records commit SHA)
packages/stores/filesystemFilesystem result store
packages/stores/sqliteSQLite result store with relational schema
packages/telemetry/otelOpenTelemetry sink (no-op by default)
packages/clillm-pipe CLI
packages/serverFastify REST API + public/openai.json + OAuth discovery + /mcp
packages/mcp-serverMCP server (stdio + Streamable HTTP), 8-tool surface

Getting started

Requires Node 22 LTS (or 24+) and pnpm — the engine range is "^22.0.0 || >=24.0.0". The pinned pnpm@11.3.0 requires Node ≥22.13 (it imports node:sqlite); vitest@4.1.8 declares the same engines range. See "What's added" §4 above for the discovery story.

pnpm install
pnpm build
pnpm test

Run the example SWOT pipeline (offline, mock provider)

node packages/cli/dist/index.js run swot_recursive \
  examples/inputs/sample-topic.md --providers mock --depth 1 --export run_bundles

Other CLI commands:

node packages/cli/dist/index.js list-pipelines
node packages/cli/dist/index.js validate-pipeline swot_recursive
node packages/cli/dist/index.js get-run <run-id>
node packages/cli/dist/index.js export-run <run-id> --out run_bundles

By default the CLI reads pipelines from examples/ (override with --registry or $LLM_PIPE_REGISTRY) and writes runs to .runs/ (override with --store or $LLM_PIPE_STORE).

Every CLI command, flag, and exit code is documented in docs/cli-reference.md.

REST server

PORT=8787 node packages/server/dist/server.js
curl localhost:8787/pipelines
curl localhost:8787/openai.json

Every HTTP route (params, responses, status codes, auth) is documented in docs/rest-reference.md.

MCP server

node packages/mcp-server/dist/server.js   # speaks MCP over stdio

See docs/mcp.md and docs/openai-json.md.

Docker (combined entrypoint)

docker build -t calane:latest .
docker run --rm -p 8787:8787 \
  -e ANTHROPIC_API_KEY -e OPENAI_API_KEY \
  -v calane-data:/data calane:latest
# then: curl http://localhost:8787/health

Same boot model as render.yaml (runs packages/server/dist/combined.js — REST + OpenAPI + OAuth discovery + MCP Streamable HTTP at /mcp — on one port, with persistent state on /data). Full setup, env vars, smoke tests, and known issues in docs/deploy-docker.md.

End-to-end scenarios

Practical, runnable walkthroughs that pair the per-surface references with real use-cases (run → sign → verify; resume/diff/replay/stats; REST/MCP/A2A; connecting an external or GitHub registry) live in docs/scenarios/. Each runnable block is exercised by pnpm test (via packages/cli/tests/scenarios.test.ts) so the docs can't silently rot.

The 8-tool surface

To respect the OpenAI tool/action surface limit (~30 tools), both MCP and openai.json expose exactly 8 coarse-grained tools — never one tool per internal function: run_pipeline, get_run_result, list_pipelines, validate_pipeline, export_run_bundle, rerun_channel, list_runs, get_pipeline_spec.

Schema rule

TypeBox is the single source of truth; Ajv validates. No Zod anywhere in the codebase. See docs/schema-rule.md.

Providers

Shipped:

  • mock — deterministic, schema-synthesizing (offline + tests).
  • anthropic — Anthropic Messages API via the official SDK; forces structured output through a single emit_structured_output tool when an outputSchema is set. Pricing table bundled (USD / 1M tokens); costUsd is null for unknown models, never silently 0.
  • openai-compatible — any OpenAI-style /chat/completions endpoint; key from the env var named by apiKeyEnv (default OPENAI_API_KEY). Used for OpenAI itself and for Mistral, Gemini's OpenAI-compatible endpoint, Groq, Together, OpenRouter, local Ollama, etc. — set baseUrl per provider.
  • delegated-agent — placeholder for delegated_agent execution mode.

The adapter interface is designed to admit future Ollama-native, LiteLLM, Portkey, MCP-agent, and custom HTTP providers without core changes.

Run bundles

See docs/run-bundle.md for the exact bundle layout.

↑↓ navigate openesc close