Skip to main content

macp-sdk-python

Python SDK for the MACP Rust runtime.

What this package does

  • Connects to the Rust runtime over gRPC
  • Provides typed session helpers for all 5 standard coordination modes
  • Maintains in-process projections for local state tracking
  • Supports envelope builders, retry helpers, and structured logging

Important runtime boundary

This SDK calls the Rust runtime. The runtime does not call into this Python package. If you need runtime-driven business logic, run a Python agent/orchestrator as a separate process and let it communicate with the runtime over MACP transport.

HTTP/JSON

This SDK talks to the runtime over gRPC only; it has no HTTP client. To reach a runtime's HTTP/JSON listener instead, see RFC-MACP-0006 §4 and the curl section of the spec quickstart.

A2A

macp_sdk.a2a is a codec for the A2A extension binding (RFC-MACP-0014): it turns Envelopes, Acks and session states into A2A 1.0 Messages, Artifacts and Task metadata (plain dicts) and back, with no A2A SDK dependency. See docs/guides/a2a-binding.md.

Install

pip install macp-sdk-python

Requires Python >= 3.11 (requires-python in pyproject.toml); CI runs the unit suite on Python 3.11, 3.12 and 3.13.

Quick start

1. Start a local runtime

docker run -p 50051:50051 -e MACP_ALLOW_INSECURE=1 -e MACP_MEMORY_ONLY=1 ghcr.io/multiagentcoordinationprotocol/macp-runtime:0.12.0

This is the runtime image CI pins. MACP_ALLOW_INSECURE=1 permits plaintext and dev-agent auth (local development only); MACP_MEMORY_ONLY=1 skips on-disk persistence. Since runtime v0.5.0, a runtime with no authentication configured (MACP_AUTH_TOKENS_* / MACP_AUTH_ISSUER unset) refuses to start unless MACP_ALLOW_INSECURE=1 is set, and the image does not bake it in.

2. Connect

Local dev (the runtime above)

from macp_sdk import AuthConfig, DecisionSession, MacpClient

client = MacpClient(
    target="127.0.0.1:50051",
    allow_insecure=True,                                # dev only
    auth=AuthConfig.for_dev_agent("coordinator"),
)

Dev-agent auth rides the standard Authorization: Bearer header — the runtime's dev_authenticate fallback binds the token value verbatim as the sender.

Production (Bearer + TLS)

from macp_sdk import AuthConfig, DecisionSession, MacpClient

# TLS is the default; Bearer + expected_sender binds the session to this identity.
client = MacpClient(
    target="runtime.example.com:50051",
    auth=AuthConfig.for_bearer("tok-coord", expected_sender="coordinator"),
)

3. Drive a decision

session = DecisionSession(client)
session.start(
    intent="pick a deployment plan",
    participants=["coordinator", "alice", "bob"],
    ttl_ms=60_000,
)
session.propose("p1", "deploy v2.1", rationale="tests passed")
session.evaluate(
    "p1", "approve", confidence=0.94, reason="low risk",
    sender="alice", auth=AuthConfig.for_dev_agent("alice"),
)
session.vote(
    "p1", "approve", reason="ship it",
    sender="bob", auth=AuthConfig.for_dev_agent("bob"),
)

winner = session.decision_projection.majority_winner()
if winner and not session.decision_projection.has_blocking_objection(winner):
    session.commit(
        action="deployment.approved",
        authority_scope="release-management",
        reason=f"winner={winner}",
    )

4. Async (asyncio)

AsyncMacpClient is a grpc.aio client with the same methods, auth and errors as MacpClient. RPCs and session actions are coroutines, watch_* RPCs are async iterators, and every mode has an Async*Session helper. Here is the quickstart session, async (examples/async_first_session.py):

import asyncio

from macp.v1.envelope_pb2 import SessionState

from macp_sdk import AsyncDecisionSession, AsyncMacpClient, AuthConfig


async def main() -> None:
    async with AsyncMacpClient(
        target="127.0.0.1:50051",
        allow_insecure=True,  # local dev only
        auth=AuthConfig.for_dev_agent("coordinator"),
    ) as client:
        session = AsyncDecisionSession(client)
        await session.start(
            intent="pick a deployment plan",
            participants=["coordinator", "alice", "bob"],
            ttl_ms=60_000,
        )
        await session.propose("p1", "deploy v2.1", rationale="tests passed")
        await session.evaluate(
            "p1", "APPROVE", confidence=0.94, reason="low risk",
            sender="alice", auth=AuthConfig.for_dev_agent("alice"),
        )
        await session.vote(
            "p1", "APPROVE", reason="ship it",
            sender="bob", auth=AuthConfig.for_dev_agent("bob"),
        )

        winner = session.decision_projection.majority_winner()
        await session.commit(
            action="deployment.approved",
            authority_scope="release-management",
            reason=f"winner={winner}",
        )

        meta = (await session.metadata()).metadata
        print("winner:", winner)
        print("state:", SessionState.Name(meta.state), "mode:", meta.mode)


asyncio.run(main())
winner: p1
state: SESSION_STATE_RESOLVED mode: macp.mode.decision.v1

Create the client inside the running loop: grpc.aio channels bind to the loop that is current when they are created. See docs/guides/async.md for streaming, watches and concurrency.

Decision receipts

A decision receipt (macp-receipt/1, RFC-MACP-0013 Appendix A) is a portable JSON record of one Commitment that anyone can check offline: integrity (the recorded commitment has the recorded commitment_hash) needs no keys, and authenticity comes from an Ed25519 JWS attestation by a key the verifier trusts. Signing and signature checks need the receipts extra:

pip install 'macp-sdk-python[receipts]'
from macp_sdk import ReceiptSigner, build_receipt, verify_receipt

receipt = build_receipt(
    commitment,                      # the session's CommitmentPayload
    session_id=session.session_id,
    mode="macp.mode.decision.v1",
    issuer="runtime:example",
    issued_at="2026-10-24T12:00:00Z",
    semantics_rev={"implementation": "macp-runtime", "rev": 4},
    signer=ReceiptSigner("example-1", private_key=seed),  # 32-byte seed, or sign=callback
)

result = verify_receipt(receipt, {"example-1": public_key_x})  # kid -> JWK x (base64url)
# {"integrity": "match", "attestations": ["valid"], "verdict": "attested"}

verify_receipt never raises on a malformed receipt; it returns one of the verdicts attested, integrity_only, unverified or refused (unknown receipt_format), in the same shape as the spec's vectors, which the unit tests replay from tests/vectors/receipt/. Pass commitment_wire= (the payload's Protobuf bytes) to record commitment_wire_b64; build_receipt raises if it is not the wire encoding of commitment. commitment_from_projection() turns a receipt's snake_case commitment back into a CommitmentPayload.

A runtime that advertises capabilities.decision_receipt issues receipts itself (RFC-MACP-0013 §13). client.get_decision_receipt(session_id) returns the receipt parsed and verbatim, and trusted_keys_from_jwks(client.get_receipt_keys()) gives the keys to verify it with. See Core Protocol.

Tracing (OpenTelemetry)

pip install "macp-sdk-python[otel]" enables OpenTelemetry instrumentation. With a configured TracerProvider, each send() emits a CLIENT span named send {mode}, and RPCs made inside an active span carry W3C trace context (traceparent/tracestate) to the runtime. Spans record identifiers only, never payloads or reasons. Without the extra, nothing changes. See Observability.

Framework integrations

Separate packages, each with its own version and release tag, living under integrations/:

Package Install What it adds
langgraph-macp pip install langgraph-macp MacpConsensusNode: a LangGraph node that settles a Decision or Quorum session and writes the Commitment to graph state
claude-agent-sdk-macp pip install claude-agent-sdk-macp macp_consensus and the mcp__macp__consensus tool: Claude Agent SDK subagents evaluate and vote in a Decision or Quorum session, and you get the Commitment back

An OpenAI Agents SDK adapter (handoffs mapped to Handoff mode) is next.

Supported modes

Mode Session Helper Projection Example
Decision DecisionSession DecisionProjection examples/decision_smoke.py
Proposal ProposalSession ProposalProjection examples/proposal_negotiation.py
Task TaskSession TaskProjection examples/task_delegation.py
Handoff HandoffSession HandoffProjection examples/handoff_escalation.py
Quorum QuorumSession QuorumProjection examples/quorum_approval.py
Multi-round (ext.multi_round.v1, extension) MultiRoundSession MultiRoundProjection docs/modes/multi-round.md

Each helper has an asyncio twin (AsyncDecisionSession, AsyncProposalSession, AsyncTaskSession, AsyncHandoffSession, AsyncQuorumSession, AsyncMultiRoundSession) for use with AsyncMacpClient.

Multi-round is a runtime-shipped extension, not a standards-track mode. Its helper sends Contribute as canonical protobuf and still decodes legacy JSON.

Development

# Setup
make setup              # pip install -e ".[dev,docs]"

# Quality
make lint               # ruff check + ruff format --check
make fmt                # ruff format
make typecheck          # mypy strict
make test               # unit tests + coverage gate (85% branch, from pyproject)
make test-integration   # integration tests (auto-skip without a running runtime)
make test-all           # lint + typecheck + all tests
make coverage           # HTML + terminal coverage report

# Build
make build              # build sdist + wheel, then twine check

# Proto definitions (provided by macp-proto package)
make dev-link-protos    # link local proto package for development

make test-integration-docker starts the same pinned runtime image as the quick start, runs tests/integration/, and cleans up.

Documentation

Full docs available in docs/ — build with mkdocs serve after make setup.

Runtime compatibility

SDK Runtime macp-proto
0.17.x 0.9.x (semantics_rev 4) 0.1.11

CI runs tests/integration/ against the pinned runtime image on every PR (make test-integration-docker runs the same suite locally). Runtimes older than 0.9.0 are best-effort: the wire stays compatible, but the mode helpers model the 0.9.0 rules (task rule 2a, handoff rule 3a, quorum threshold overrides, Decision casing), so a session on an older runtime may diverge from what the projections predict.

Architecture boundary

This SDK is a thin typed client library. It provides:

  • Typed state models and action builders
  • Session helpers (propose(), vote(), commit())
  • Local state projections (because GetSession returns metadata only)

Business logic — voting rules, AI decision heuristics, policy enforcement — belongs in the orchestrator/agent layer above the SDK.

Known runtime limitations

  • GetSession returns metadata only (not mode state/transcript) — hence the local projection pattern; use StreamSession + send_subscribe for the full transcript
  • StreamSession is scoped to one session per stream; use MacpStream.send_subscribe(session_id) (RFC-MACP-0006-A1, since SDK 0.2.3 / macp-proto 0.1.2) to replay accepted history before live broadcast
  • For cross-session observability, use MacpClient.list_sessions() and SessionLifecycleWatcher (SDK 0.3.0) to enumerate active sessions and stream CREATED / RESOLVED / EXPIRED / CANCELLED / SUSPENDED / RESUMED lifecycle events
  • Pause and cancel sessions with MacpClient.suspend_session() / resume_session() / cancel_session() (SDK 0.4.0 / macp-proto 0.1.3). A suspended session is non-terminal and rejects messages until resumed; an accepted cancel_session() now terminates as CANCELLED (previously surfaced as EXPIRED)
  • ListRoots currently returns an empty list and WatchRoots idles — the runtime does not yet populate roots
  • Business policy (majority, quorum, veto) belongs in your orchestrator/policy layer

Metadata

Release files for macp-sdk-python 0.23.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for macp-sdk-python 0.23.0
File Size Uploaded Provenance Actions
macp_sdk_python-0.23.0.tar.gz 158.9 kB With provenance Details for macp_sdk_python-0.23.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for macp-sdk-python 0.23.0
File Interpreter ABI Platform Actions
macp_sdk_python-0.23.0-py3-none-any.whl Python 3 none any Details for macp_sdk_python-0.23.0-py3-none-any.whl

Total release size: 329.1 kB

Release files / macp_sdk_python-0.23.0.tar.gz

Download URL macp_sdk_python-0.23.0.tar.gz
Size 158.9 kB
Tags Source
SHA-256 checksum
How to use checksums
8d2641d9425dfcd4724d0ce023e4bd6dbc65b0f1187d378c35661eaa61ad866b
BLAKE2b-256 checksum
How to use checksums
e059bd9de03ec24009fc10950998c91198be9c1c6606e62391babba69f19c263
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / macp_sdk_python-0.23.0-py3-none-any.whl

Download URL macp_sdk_python-0.23.0-py3-none-any.whl
Size 170.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
048463f557db5d3b2bf1ef62f69016ab864bbfa079c971a8a4e556a980e73f07
BLAKE2b-256 checksum
How to use checksums
b4337d047e149e88e49aff8053e77d7a9b42f89844a71b5e5b307ec6a29b9840
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Security for macp-sdk-python 0.23.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for macp_sdk_python-0.23.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.23.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page