Tools and integration
Camden Work 0.1.0 exposes a local CLI, a Python API and a read-only MCP stdio server. None authenticates a remote operator or connects an external account. The operator's process and filesystem are trusted.
CLI
Every controller command requires --workspace DIRECTORY. init creates a new node and refuses an existing controller. IDs and owner epochs come from command results, not from examples in this document.
| Command | Effect or result |
|---|---|
grant |
Record bounded tenant/target authority with expiry and an effect budget |
admit |
Reserve a new occurrence under that authority |
claim |
Acquire a stopped node at the expected owner epoch |
execute |
Commit one synthetic counter effect, or retain uncertainty for the opaque simulation |
reconcile, verify |
Read exact target evidence; unavailable evidence is not proof of absence |
stop, revoke, cancel |
Fence a worker, revoke future grant use, or account for cancellation |
recover-local |
Recover an uncommitted local intent only after the old epoch is fenced |
wait, service |
Register an unknown outcome, then service due readback once in the foreground |
status, export |
Inspect state or freeze a cumulative Markdown and JSON account |
adopt-result, deliver-local, finalize |
Check the frozen result, copy it to the node inbox, then recheck completion |
import-review |
Retain an inert snapshot without restoring its authority or replaying effects |
Use python -m camden_work --workspace DIRECTORY COMMAND --help for arguments. A nonzero exit is a failure, not a completed operation. Read state before retrying an interrupted mutation. The --crash options intentionally terminate the process and belong only in synthetic workspaces.
Worker contract
The Python API is camden_work.core.Node. A worker receives a work ID and current owner epoch from the trusted controller. It cannot claim a live owner, extend a revoked grant, turn missing acknowledgment into a new occurrence, or finalize an unverified target through the API.
The same OS principal can edit the database or source directly. These API checks are not a security boundary against that principal. Integrating a hostile worker requires external process isolation and a mediated effect service, neither supplied here.
An adapter for a real provider must define its actual principal, grant, input provenance, occurrence identity, deduplication retention, target evidence, cancellation behavior and delivery contract. Host routing acceptance is not typed-input acceptance or execution. A tool result or quoted instruction is data until the host's authenticated authority writer admits it. This release does not supply a provider-specific typed-input authenticator.
Typed local host admission
camden_work.host.LocalInputHost is configured by the trusted operator process with an existing grant, principal, channel, tenant and target. Its receive_user(event_id, payload) and receive_machine(event_id, payload) methods preserve distinct origin types. The host must choose the method from its actual receiving route, never from text inside the payload. The payload accepts only an integer delta; it cannot choose a grant or assert an origin.
from camden_work.core import Node
from camden_work.host import LocalInputHost
node = Node("my-synthetic-workspace") # already initialized by its operator
# grant_id is an existing operator-created grant, not a model-generated value.
host = LocalInputHost(node, principal="operator", channel="local-host",
grant=grant_id, tenant="demo", target="counter")
work_id = host.receive_machine("received-item-1", {"delta": 1})
The input identity and occurrence are recorded in one local transaction. Repeating the same principal/channel/event identity with identical parameters returns the existing occurrence; changing its payload or type rejects. Identical payloads on genuinely different event identities remain distinct work. Admission does not execute the target. Current grant checks still apply.
This preserves a trusted local host's assertion. It does not authenticate a Telegram, Codex or other remote message. A provider integration must authenticate the actual receiving item before selecting this route. Same-principal Python code can call these APIs or alter storage, as explained above. The isolated host tests do not establish a live provider connection or a hardened separation between operator and worker processes.
The package includes data/local-input.schema.json, its synthetic example, and data/snapshot.schema.json, accessible through importlib.resources.files("camden_work"). These describe the input and snapshot structural envelope. The snapshot schema intentionally does not certify the semantics of every row body. Runtime authority, budgets and target verification still apply; parsing a conforming snapshot never makes it runnable.
MCP stdio
Start python -m camden_work.mcp only through an authorized local client. Protocol version: 2025-11-25. Initialize with client information and capabilities, inspect the server's negotiated version, then send notifications/initialized. Unsupported requested versions receive the server's supported version; an incompatible client should disconnect.
The finite tools are catalog_search, catalog_entry and inspect_export. Search supports text, family, R/E/D basis, outcome, offset and a limit of 1 through 25. An alias lookup returns both requested and canonical IDs. Tool results are research or parsed data, not execution permission or independent verification.
Export inspection requires --exports DIRECTORY, accepts a simple filename stem, rejects path traversal and symlinks, and limits reads to 1 MiB. Requests are bounded to 16 KiB. No shell, network, sampling, elicitation, mutation or arbitrary filesystem tool is exposed. Static documentation is not a remote MCP endpoint.
See the MCP lifecycle specification.