Deterministic structured handoff-card codec + MCP translator server for agent handoffs, session compaction, and instruction compilation (client-side sampling for semantics; zero server-side LLM cost).
Project description
handoffpack — MCP structured-card translator
Deterministic codec + guards + MCP server for HP1 structured handoff cards. Turns agent handoffs, session logs, and recurring-instruction files into compact structured cards. All deterministic work runs locally; the server never calls an LLM API and holds no API keys.
Install
Python 3.11+ required.
# From PyPI (once published):
pip install handoffpack
# Pre-publish / local: from the package directory
pip install .
# or editable, with test deps:
pip install -e .[dev]
Core codec/guards tests run with stdlib + pytest only; the mcp package
is needed only to run server.py.
Register the MCP server (Claude Code)
python -m handoffpack.server # stdio transport, run directly
claude mcp add handoffpack -- python -m handoffpack.server
Other clients (Cursor, etc.): use the same command in their MCP server
registration UI. A handoffpack console script is also installed as an
alias for python -m handoffpack.server.
License key (paid add-ons only)
The 4 MCP tools (encode / decode / compact_to_l2l / verify) are
FREE and unlimited. Only paid add-ons (e.g. the full hp-instructions
conversion run) require a key. The verifier is fully offline (embedded
Ed25519 public key, no phone-home). Key discovery precedence:
export HP_LICENSE=HP1.xxxxx... # macOS/Linux
set HP_LICENSE=HP1.xxxxx... # Windows
# or place the key on the first line of ~/.handoffpack/license
# or pass --license <KEY> to hp-instructions
hp-instructions --check (drift scan) is free; a full conversion run
requires a plus-tier key.
Layout
mcp-translator/
├── pyproject.toml
├── src/handoffpack/
│ ├── legend.json # public card schema (typed slots + kv pairs)
│ ├── codec.py # assemble/parse/validate + chars/4 token estimator
│ ├── guards.py # breakeven passthrough, BAN-field rule, nuance heuristic
│ ├── license.py # offline Ed25519 license verifier (paid add-ons)
│ ├── adapter_instructions.py # hp-instructions CLI (CLAUDE.md -> HP1 cards)
│ └── server.py # MCP server: encode / decode / compact_to_l2l / verify
└── tests/
Run tests
pytest # 114 tests
Build & publish (maintainer)
python -m build # produces dist/*.whl + dist/*.tar.gz
python -m twine upload dist/*
If build is unavailable offline, an equivalent wheel can be produced
with python -m pip wheel . -w dist --no-deps --no-build-isolation.
Architecture notes (caller-does-semantics)
- Deterministic work (card assembly, parsing, schema validation, guards, token estimation) is local and pure. The server never calls an LLM API and holds no API keys (zero-server-cost invariant).
- Semantic work (slot extraction, compaction keep/drop judgment) belongs
to the CALLING model:
encode(slots={...})— the caller extracts TASK/ROLE/IN/DO/OUT/LIM/BAN from its own context and passes them directly (mode: "slots",confidence: "caller"). Passtexttoo for token metrics.compact_to_l2l— two-call protocol. Call 1 (session_textonly) returns a per-segmentscaffold+fill_slots_and_recall+ a crude deterministic fallback. Call 2 addssegment_slots={"<seg>": {slots} | "TASK string"}.decode/verify— deterministic.
- Freeform
encode(text=...)without caller slots returns a deterministic skeleton card plusfill_slots_and_recallguidance for a second call. - MCP sampling (
session.create_message) survives only as an OPTIONAL, capability-detected upgrade path (deprecated upstream: MCP 2026-07-28 spec RC, SEP-2577; replaced by Multi Round-Trip Requests, SEP-2322; Claude Code never implemented it, anthropics/claude-code#1785). It is OFF unless the operator setsHP_ENABLE_SAMPLING=1AND the client advertises the capability; results are always deterministically re-validated. Nothing depends on sampling. - Token estimates use ceil(chars/4). Crude by design; never used for claims or billing.
Guard behavior
- Inputs under ~70 estimated tokens are returned unchanged with a reason (encoding overhead exceeds savings below breakeven).
- BAN slots accept plain forbidden actions only. Conditional negation ("X unless Y", "only outside Z") is rejected; express the condition as a positive LIM constraint instead.
- Prose with high conditional-clause density gets an advise-skip verdict instead of a lossy card.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file handoffpack-0.1.0.tar.gz.
File metadata
- Download URL: handoffpack-0.1.0.tar.gz
- Upload date:
- Size: 38.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6dcc51da4b83e76032d93f6a04641fe55a1dd7c8cfb93e9a9666a82f30b3753e
|
|
| MD5 |
d72aa8591fb398299d9ab957056df528
|
|
| BLAKE2b-256 |
441e8eeaa8d57ed9231c43bfdc1bb3c50a3c53fd5641f5d3c99e75565617ffbe
|
File details
Details for the file handoffpack-0.1.0-py3-none-any.whl.
File metadata
- Download URL: handoffpack-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e6d81ba8711583c1cbf5c8dd8d335dd8b9cb3e063da1118edd0b6aeba8ffa86
|
|
| MD5 |
4fc0bca083fdbe2fa5bb06d106190cbf
|
|
| BLAKE2b-256 |
5ffbf276e0f325340e388700b2e37e7fdeb51d775fe2907739117630f18402ab
|