How to use
Start with one tool. Protect its full lifecycle.
Mycelium is open-source and self-hosted. Python applications use the engine directly; other languages use the same engine through its HTTP/JSON sidecar. Run one sidecar locally or coordinate multiple sidecars through shared PostgreSQL. No Mycelium cloud account or hosted endpoint is required.
Start
Install
Requires Python 3.10 or later.
pip install mycelium-runtime pip install 'mycelium-runtime[langgraph]' # automatic ToolRuntime IDs pip install 'mycelium-runtime[redis]' # optional pip install 'mycelium-runtime[postgres]' mycelium init # on-ramp (transition + one ledgered tool) mycelium init --full # reference: all guards (fill TODOs; not default) mycelium init --minimal # smaller multi-guard scaffold mycelium demo # feature tour: unguarded vs ledgered + gates / hard-block / release mycelium demo --redis # optional Cloud-style 2-worker Redis proof mycelium run --config mycelium.yaml -- python -m my_agent
TypeScript, Go, and other languages
The engine is Python, but the doorway into it is language-neutral. Run Mycelium as a self-hosted sidecar beside your application. Your application sends action details and results over HTTP/JSON; the sidecar owns identity, claims, leases, fencing, transitions, and recovery.
pip install mycelium-runtime umask 077 python -c 'import secrets; print(secrets.token_urlsafe(32))' > /absolute/path/sidecar.token
# /absolute/path/sidecar.yaml
kind: mycelium-sidecar
protocol_version: "v1alpha1"
identity_namespace: identity-v1
tenant_id: tenant-a
application_id: app-a
bearer_token_file: /absolute/path/sidecar.token
ledger: {type: file, path: /absolute/path/sidecar-ledger.json}
outcome_storage: {type: file, path: /absolute/path/sidecar-outcomes.ndjson}
server: {host: 127.0.0.1, port: 8787}
mycelium sidecar serve --config /absolute/path/sidecar.yaml # TypeScript / Node.js npm install @mycelium-labs/sidecar-client@experimental # Go go get github.com/mycelium-labs/mycelium/clients/go@v0.1.1
For multiple sidecars, use the repository's shared PostgreSQL Docker Compose profile:
git clone https://github.com/mycelium-labs/mycelium.git cd mycelium export MYCELIUM_POSTGRES_PASSWORD="$(openssl rand -hex 24)" export MYCELIUM_SIDECAR_TOKEN="$(openssl rand -hex 32)" docker compose -f docker-compose.sidecar.yml up --build
Complete self-hosting guide ↗ · TypeScript package ↗ · Go module ↗ · HTTP/OpenAPI protocol ↗
Java, Rust, C#, Ruby, and other runtimes can call the same authenticated OpenAPI contract directly. The language clients are thin helpers; they do not duplicate Mycelium's Python state machine. The v1alpha1 development and shared PostgreSQL profiles are experimental and self-hosted, not a public multi-tenant service.
Agent-assisted setup
The repository includes a $mycelium-setup skill for coding agents. Ask the agent to use it in your project. It inventories tool entry points, proposes side-effect classifications, writes or updates mycelium.yaml, wires supported runtimes, adds focused tests, and runs Doctor and Verify.
Use $mycelium-setup to protect this project.
The skill does not invent signing keys, provider credentials, business request IDs, production namespaces, or approval policy. Review consequential tool classifications and supply those host-owned values yourself. The generated YAML remains ordinary project configuration that you can inspect and edit.
How it fits
Mycelium sits between the agent loop and your tools after the LLM returns tool_calls. At that boundary it composes input and authority checks, run controls, safe execution, outcome resolution, and evidence. Its execution ledger proves run-or-not and enforces at-most-once when retries or crashes occur.
What it does
Mycelium makes tool actions reliable before, during, and after execution. mycelium init / mycelium run begin with durable execution control for one tool; configure the other control areas that match your workflow.
Execution & recovery
Action execution
Transition ledger for safe execution: the default mycelium init / mycelium run path. Each ledgered tool gets a side_effect_class and transition_key. Repeated dispatches resolve through gates, not blind re-execution. Read the prevention page →
from mycelium import load_config
config = load_config("mycelium.yaml")
@config.apply
def send_payment(amount: float, recipient: str) -> dict:
return gateway.charge(amount, recipient)
# payment: duplicate resolves existing transition; won't charge twice
send_payment(amount=100.0, recipient="acct_123", tool_call_id="call_pay")
See Resolution for gate semantics and the SDK README for the full reference.
Durable composite recovery
Python applications can wrap an unchanged straight-line function whose consequential child calls are already protected by Mycelium. The opt-in @composite decorator pins the child-call manifest, returns stored child results during replay, and runs only children that have not already completed. Every retry must provide the same stable, host-owned operation ID.
This is a bounded Python-runtime feature, not a general workflow engine or a sidecar endpoint. It supports local file and SQLite composite-control storage; it is not available through the language-neutral API or the shared PostgreSQL sidecar profile. Conditions, loops, dynamic dispatch, nested composites, opaque calls, and hidden direct provider effects are rejected or remain outside its protection.
Resolution
Invariant: do not redispatch unless the previous transition is proven terminal or safely recoverable. See the resolution gates →
Envelope fields
The transition envelope is the identity and recovery record for one external effect. Seven fields help Mycelium decide whether a retry is safe or must stop:
side_effect_class— what kind of action this is.capability— whether retry is intrinsically safe, queryable, or blind.spendability— whether the same intent may execute more than once.side_effect_boundary— whether the provider call was not crossed, may have crossed, or crossed.terminal_outcome— whether the prior attempt completed, failed, expired, or remains unknown.external_operation_ref— the provider handle used for read-only reconciliation.retry_permission— whether another attempt is permitted.
Python applications configure these semantics through the runtime. Non-Python applications send the same lifecycle over the experimental v1alpha1 protocol. Read the language-neutral specification ↗
YAML
transition: agent_id: payment-agent policy_version: "2026.07.1" lease_ttl: 3600 action_ledger: storage: file path: ./mycelium-ledger.json
Provider adapter conformance
A reconciler decides whether an ambiguous operation completed. A false NOT_EXECUTED permits another attempt, so every adapter needs adversarial tests. Gmail is the only adapter currently shipped. Other providers implement the same conformance fixture and supply provider-specific scripted observations.
export MYCELIUM_ADAPTER_REPORT_SIGNING_KEY='from-your-secret-manager' mycelium providers verify gmail \ --key-id provider-ci-2026-01 \ --output gmail-adapter-report.json mycelium providers verify-report gmail-adapter-report.json --json
The key signs the report with HMAC-SHA256 so CI or an operator can detect edits and verify which adapter source passed. Mycelium itself works without this key; it is required only when creating or checking an adapter-verification report. The report proves the synthetic suite passed and the source still matches. It does not prove live credentials are read-only, so enforce provider scopes separately.
Additional controls
Context (opt-in)
TTL cache and message/history helpers.
Tool boundaries (opt-in)
Input/output/scope validation and allowlists.
Loop guard (opt-in)
Detects identical tool+args across new tool_call_ids.
Completion contract (opt-in)
Refuses terminal while required subtasks are pending.
Scope guard (opt-in)
Freezes the run tool allowlist and re-checks every step.
Secret-in-args (opt-in)
Blocks raw credentials before claim. Pass secret:// references instead of API keys. Fail-closed pre-execution blocking is the primary protection; redaction is defense-in-depth. Mycelium cannot sanitize logs created inside application or provider code.
Outcome telemetry & DTTR (v1.20+)
Opt-in flat append-only outcome rows for production observability.
Reference
Failure-mode catalog
Stable IDs used in the SDK README, changelogs, and this handbook. The public story leads with outcomes, not a guardrail count. Browse the prevention catalog →
API
See the SDK README for Python exports. Non-Python clients use the authenticated OpenAPI 3.1 contract served at GET /v1/openapi.json; see other languages.
Common searches
FAQ content for production reliability, action validation, scope, context, LangGraph duplicates, and idempotency. Read about Verify →