Skip to content

Repository files navigation

plexus: toolchain wiring discovery. Point it at your tools and it computes how they plug together.

plexus

Capability discovery and auto-wiring for agent toolchains. Point it at a set of tools and it discovers what each one emits and consumes, then wires producer to consumer into a runnable pipeline. Zero runtime dependencies.

MCP tells an agent that tools exist. plexus tells it how their outputs plug into each other's inputs: the layer above a flat tool list.

GitHub-only release install for 0.2.1 on Bash/macOS/Linux:

set -euo pipefail
VERSION=0.2.1
BASE="https://github.com/HarperZ9/plexus/releases/download/v0.2.1"
WHEEL="plexus_mesh-${VERSION}-py3-none-any.whl"
SDIST="plexus_mesh-${VERSION}.tar.gz"
SUMS="SHA256SUMS.txt"
curl -fL -o "$WHEEL" "${BASE}/${WHEEL}"
curl -fL -o "$SDIST" "${BASE}/${SDIST}"
curl -fL -o "$SUMS" "${BASE}/${SUMS}"
python - "$WHEEL" "$SDIST" "$SUMS" <<'PY'
import hashlib
import re
import sys
from pathlib import Path

required = list(sys.argv[1:3])
sums = Path(sys.argv[3])
expected = {}
for line_number, raw_line in enumerate(sums.read_text(encoding="utf-8").splitlines(), 1):
    line = raw_line.strip()
    if not line:
        continue
    parts = line.split(maxsplit=1)
    if len(parts) != 2:
        raise SystemExit(f"malformed checksum line {line_number}")
    digest, name = parts[0].lower(), parts[1].lstrip("*")
    if not re.fullmatch(r"[0-9a-f]{64}", digest):
        raise SystemExit(f"invalid checksum for {name}")
    if Path(name).name != name:
        raise SystemExit(f"unexpected checksum path: {name}")
    if name not in required:
        raise SystemExit(f"unexpected checksum entry: {name}")
    if name in expected:
        raise SystemExit(f"duplicate checksum entry: {name}")
    expected[name] = digest
missing = [name for name in required if name not in expected]
if missing:
    raise SystemExit(f"missing checksum entry: {', '.join(missing)}")
for name in required:
    got = hashlib.sha256(Path(name).read_bytes()).hexdigest()
    if got != expected[name]:
        raise SystemExit(f"{name}: expected {expected[name]}, got {got}")
PY
python -m pip install "$WHEEL"

GitHub-only release install for 0.2.1 on native PowerShell:

& {
    $ErrorActionPreference = "Stop"
    $Version = "0.2.1"
    $Base = "https://github.com/HarperZ9/plexus/releases/download/v0.2.1"
    $Wheel = "plexus_mesh-$Version-py3-none-any.whl"
    $Sdist = "plexus_mesh-$Version.tar.gz"
    $Sums = "SHA256SUMS.txt"
    $Files = @($Wheel, $Sdist, $Sums)
    foreach ($Name in $Files) {
        Invoke-WebRequest -Uri "$Base/$Name" -OutFile $Name
    }
    $Required = @($Wheel, $Sdist)
    $Expected = @{}
    $LineNumber = 0
    Get-Content -LiteralPath $Sums | ForEach-Object {
        $LineNumber += 1
        $Line = $_.Trim()
        if (-not $Line) { return }
        $Parts = $Line -split '\s+', 2
        if ($Parts.Count -ne 2) { throw "malformed checksum line $LineNumber" }
        $Digest = $Parts[0].ToLowerInvariant()
        $Name = $Parts[1].TrimStart("*")
        if ($Digest -notmatch '^[0-9a-f]{64}$') { throw "invalid checksum for $Name" }
        if ([IO.Path]::GetFileName($Name) -ne $Name) { throw "unexpected checksum path: $Name" }
        if ($Required -notcontains $Name) { throw "unexpected checksum entry: $Name" }
        if ($Expected.ContainsKey($Name)) { throw "duplicate checksum entry: $Name" }
        $Expected[$Name] = $Digest
    }
    foreach ($Name in $Required) {
        if (-not $Expected.ContainsKey($Name)) { throw "missing checksum entry: $Name" }
        $Got = (Get-FileHash -Algorithm SHA256 -Path $Name).Hash.ToLowerInvariant()
        if ($Got -ne $Expected[$Name]) {
            throw "${Name}: expected $($Expected[$Name]), got $Got"
        }
    }
    python -m pip install $Wheel
}

plexus-mesh is not published on PyPI in this release track. A source branch or CI run is not a release; install from the GitHub v0.2.1 assets only after the wheel, sdist, and SHA256SUMS.txt are attached to that release.

$ plexus discover --builtin
$ plexus plan --goal crucible
$ plexus route --from gather --to crucible
$ plexus graph --format mermaid       # a diagram of the whole mesh
$ plexus run --goal crucible          # a runnable pipeline script
$ plexus mcp                          # stdio MCP server for agents to query live

An agent (Claude Code or any MCP client) can point at plexus mcp and call plexus_discover / plexus_plan / plexus_route while it works, so the mesh is consumable mid-task, not just from a human's terminal.

How it compares to MCP / LangGraph / Dagster / CrewAI: see COMPARISON.md. plexus is the discovery layer that sits above an executor, not another executor.

Eight stages from manifest to verify, ending in still holds or drifted.

The problem

You wire up a set of tools. Each one produces artifacts and accepts inputs, but nothing knows how they connect, so you hand-wire A | B | C every time and rediscover the plumbing on every new task. plexus makes the toolchain self-describing: each tool ships a small manifest of what it emits and consumes, and plexus computes the wiring graph: which tool's output is which tool's input.

What you get

Discover the mesh. Producer-to-consumer edges by capability, shown here as an excerpt:

$ plexus wiring --builtin
{
  "canon.capsule/v1":                  [["canon","canon"]],
  "canon.record/v1":                   [["canon","canon"]],
  "crucible.replay-pack/1":           [["mneme", "crucible"]],
  "crucible.replay-template/1":       [["crucible", "mneme"]],
  "crucible.thesis/1":                [["mneme", "crucible"]],
  "gather.digest/1":                  [["gather", "crucible"]],
  "gather.items/1":                   [["gather", "mneme"]],
  "index.verification/1":             [["index", "crucible"]],
  "project-telos.flagship-action/v1": [["crucible","index"],["forum","index"],["gather","index"]],
  "relay.rvc/v1":                     [["relay","relay"]],
  "relay.session-ledger/1":           [["relay","relay"]]
}

The Mneme/Crucible replay loop is bidirectional and schema-exact: Crucible emits crucible.replay-template/1 for Mneme to consume, and Mneme emits crucible.replay-pack/1 for Crucible to consume. The existing crucible.thesis/1 Mneme→Crucible route remains a separate declared edge, satisfied by Mneme's native mneme.crucible-export/2 export.

Plan a pipeline. "I want to feed crucible. What produces its inputs?"

$ plexus plan --goal crucible
  order:   forum -> gather -> crucible -> index -> learn -> mneme -> telos
  sources: forum, gather
  cyclic:  crucible, index, learn, mneme, telos  # feedback loops, reported not hidden

Route between two tools. "I have gather output and want a crucible verdict. How do they connect?"

$ plexus route --from gather --to crucible
  [gather -> crucible via gather.digest/1]

A plan you can re-verify. Every plan and route carries a receipt that binds the wiring to the exact manifests it came from: the content hash of every organ, plus a hash over the derived plan. Save a plan, and later re-check it against the live mesh:

$ plexus plan --goal crucible --builtin > plan.json
$ plexus verify --plan plan.json --builtin     # exit 0 if it still holds, 1 if it drifted

verify re-derives the plan from the manifests (it never trusts the saved body), so a tampered plan is caught, and a tool whose manifest changed since the plan makes the wiring drift visible instead of letting it silently shift under you. Exit non-zero on drift, so it works as a CI check over your toolchain's wiring.

Two things make that check worth running. verify rebuilds the receipt from the plan it just re-derived, not from the one saved in the file, so editing the saved body cannot make it agree with itself. And the receipt carries a method version that has to match before anything else is compared, so a plan written by an older plexus is reported as failing rather than silently re-interpreted under new rules.

How a tool plugs in

A manifest is plain JSON. A tool ships one and it joins the mesh. Drop *.interop.json files in a directory and plexus discover --dir DIR reads them:

{
  "organ": "mytool",
  "invoke": {"cli": "mytool", "mcp_server": "mytool.mcp:serve", "python_import": "mytool"},
  "emits": [
    {"capability": "mytool.report/1", "title": "analysis report",
     "module": "src/mytool/report.py:build", "consumable_as": ["crucible.thesis/1"]}
  ],
  "consumes": [
    {"capability": "gather.digest/1", "title": "evidence intake",
     "module": "src/mytool/intake.py:load"}
  ]
}

An edge A -> B forms when B consumes a capability that A emits (directly, or via consumable_as, the way a producer declares "my output is also consumable as X"). Matching is by capability string, so an edge exists wherever the tools DECLARE compatible capabilities. Declarative discovery does not run the tools, so the edge is a declared claim, not a probed result.

Plexus commits the built-in registry's exported JSON manifests under manifests/. Discovery from these Plexus-side files produces the same declared mesh as the built-in registry, as checked by a round-trip test. Their presence here does not establish that each tool publishes its own manifest or that a declared route has been exercised.

Extended manifests (September 2026)

The registry now covers ten organs. Canon and Relay are the two visible flagship roles for context and connectivity; Index, mneme, and Plexus keep their component boundaries instead of being collapsed into a database or executor.

  • canon: context and continuity flagship. It declares the shipped record envelope, continuity capsule, readiness probe, bootstrap witness, and read-only MCP surface. It does not declare universal context capture or shared preflight as shipped.
  • relay: connectivity and execution flagship. It declares the endpoint ladder, MCP run request/result surfaces, hash-chained session ledgers, Relay-Verified-Correctness certificates, and remote MCP endpoint. It does not declare Canon capsules or Plexus route receipts as consumed until Relay ships that adapter.
  • mneme: memory recall, provenance chain, and drift component. It remains a component under the context role, with its CLI/MCP compatibility intact.
  • index: gatherer and source-context component. It still owns workspace scanning, context envelopes, freshness, and verification outputs; those are derived evidence, not authoritative memory.
  • learn: tutor credential/mastery ledger entries, proof lessons, misconceptions. Consumes crucible theses for proof-lesson derivation.
  • telos: room summary, golden workflow verification, workbench status. Consumes flagship-action envelopes for cross-tool reconciliation.
  • flywheel-infra: 10 capabilities from the Flywheel infrastructure controls (egress, lesson, tool-call-receipt, TADR classification, governance envelope, credential scan, correlated event, isolation test, kill switch, run BOM). Consumes accountable-surface actuation outcomes, mneme drift reports, and learn misconceptions for lesson derivation.

Probe mode

probe_lane(name) actually spawns a lane's MCP server and calls tools/list + status, returning {reachable, tools, error}. Unlike the declared manifest (which cites source files without running them), the probe verifies the lane is live. probe_all() probes every registered lane.

from plexus.registry import probe_all
results = probe_all(timeout=10)
for r in results:
    print(f"{r['name']:20} reachable={r['reachable']} tools={len(r['tools'])}")

Declared, not probed

The six keys plexus discover returns for one wiring edge, one to a row, each with what settled it. Four are computed by discovery: the producing organ, the consuming organ, the capability that matched, and whether both ends are the same organ. One is copied out of a manifest without being read: via, the producer's own pointer at the code behind the port. One is a constant: evidence, always the word declared. The via row is accented, because it is the field that looks like a citation and is the one plexus never follows.

Every edge is tagged evidence: "declared" and cites the module its producer names as the source (file:function). Declarative discovery does not import, resolve, or run that pointer, so the citation is a self-reported claim to check, not a verified receipt. The running tool re-checks none of the built-in manifests, so treat every edge as declared until you follow the pointer yourself. Mneme's contract was refreshed from public main on 2026-09-14, including mneme.crucible-export/2 and mneme.local-origin-recheck/1. Canon and Relay were added from public origin-main source on 2026-09-16, and their manifests use only repo-relative public paths. They intentionally leave Canon-to-Relay and Relay-to-Plexus routes disconnected until a public shipped consumer exists.

plexus is also honest about what does not connect:

  • orphans().unmet_inputs: capabilities something consumes that nothing in the set emits (an external or human input).
  • orphans().unconsumed_outputs: artifacts nobody downstream consumes (terminal outputs).
  • plan(...).cyclic: feedback loops, surfaced instead of forced into a false linear order.
  • discover().collisions: organ ids declared by more than one manifest, named rather than silently resolved last-writer-wins.

Eight stages from a tool set to a report, ending in wired, colliding, or unmet.

An unmet input is a capability something consumes that nothing in the set emits, and an unconsumed output is the mirror of it. Both fall out of the same comparison, so neither is a special case someone remembered to write. The set is also exactly what you handed it: plexus reads the manifests present and reasons about nothing else, which is why an unmet input means only that no manifest here produces it, not that no such tool exists.

Receipt

plexus discover stamps a receipt on its output: the plexus version, a UTC timestamp, and for every manifest read its source (builtin:registry or the file path) plus a sha256 over the manifest's canonical content. The hash binds what was declared, so a stranger can recompute it from the same bytes and pin the mesh to exactly the manifests that produced it.

Install

python -m pip install plexus_mesh-0.2.1-py3-none-any.whl

Use the GitHub release asset and verify it against SHA256SUMS.txt first. This repository does not claim a PyPI publication for plexus-mesh in the 0.2.1 track. The installed package covers declared and synthetic mesh workflows; it does not prove that real external lanes are live or that probe_lane() has been run against owned services.

Library

from plexus import (builtin_manifests, discover, plan_to, route,
                    to_mermaid, pipeline_script)

mesh = discover(builtin_manifests())
mesh.edges                      # every producer -> consumer edge, each tagged declared
mesh.wiring()                   # capability -> [(producer, consumer)]
mesh.orphans()                  # unmet inputs / unconsumed outputs
plan_to(mesh, "crucible")       # the upstream pipeline (+ any cycles)
route(mesh, "gather", "crucible")   # the capability path between two tools
to_mermaid(mesh)                # a Mermaid diagram of the mesh
pipeline_script(mesh, "crucible")   # a runnable shell pipeline

License

Plexus is fair-source: open to read, run, and build on, with commercial use reserved so the project can fund its own development. See LICENSE.

What this believes

This tool is one part of a family that holds a single belief steady across every surface: knowledge open to anyone who can attain the means; acceptance decided by external checks, never reputation; every result re-runnable; honest nulls first-class; ownership earned by comprehension; learning woven into the work. The full text lives in CREDO.md. The long form of this belief: The Unbundling.


Zentropy Labs · order out of entropy. An independent lab building evidence-first tools that leave a re-checkable artifact behind. Built by Zain Dana Harper in Seattle. The full workbench is at Project Telos.

About

Capability discovery + auto-wiring for agent toolchains: discover what each tool emits/consumes, then wire producer to consumer into a runnable pipeline. Every edge cites its evidence. Zero deps.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages