Skip to main content
Glama

Ploidy

Context-asymmetric structured debate for difficult decisions.

CI Docs PyPI License: MIT

Ploidy gives one side of a debate project context and keeps the other side fresh, then records positions before either side can anchor on the other. It ships as a Python 3.11+ MCP server with SQLite persistence.

Install

pip install ploidy

Add the API extra only when the server itself will generate an automatic debate:

pip install "ploidy[api]"

Related MCP server: consensus-mcp

stdio is the default transport. One MCP client starts one server on demand, so there is no port or background process to manage.

{
  "mcpServers": {
    "ploidy": {
      "type": "stdio",
      "command": "python3",
      "args": ["-m", "ploidy"]
    }
  }
}

The primary tool is debate:

  • mode="solo": the caller supplies independently generated Deep and Fresh positions. No external model API is required.

  • mode="auto": the server generates both sides through an OpenAI-compatible API. Non-empty context_documents are required so the Deep and Fresh sides are actually asymmetric.

Example auto call:

await debate(
    prompt="Should we split the ingestion service?",
    mode="auto",
    context_documents=["Current topology, incident history, and constraints…"],
    context_sources=["architecture-notes"],
)

Configure the API backend before using auto mode:

export PLOIDY_API_BASE_URL=https://api.openai.com/v1
export PLOIDY_API_KEY=...
export PLOIDY_API_MODEL=your-model

Shared server: Streamable HTTP

Use HTTP when multiple MCP clients must share one debate or when Ploidy is deployed as a service:

PLOIDY_TRANSPORT=streamable-http python3 -m ploidy
export PLOIDY_URL=http://127.0.0.1:8765

Configure each client with ${PLOIDY_URL}/mcp (substitute the value; JSON does not expand shell variables):

{
  "mcpServers": {
    "ploidy": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:8765/mcp"
    }
  }
}

PLOIDY_URL is the base URL used by ploidy-ask and other HTTP clients. The MCP endpoint is /mcp, and the live HTTP/SSE endpoint is /v1/debate/stream.

MCP tools

Ploidy 0.4.0 exposes exactly 13 tools. New integrations should use the unified debate tool. The other 12 remain available for explicit two-client, phase-by-phase, history, cancellation, and HITL workflows.

Tool

Purpose

debate

Unified auto or solo debate

debate_start

Create a Deep session

debate_join

Join as Fresh or Semi-Fresh

debate_position

Submit an independent position

debate_challenge

Submit a semantic challenge

debate_converge

Produce the convergence result

debate_cancel

Cancel an active debate

debate_delete

Permanently delete a debate

debate_status

Read current state

debate_history

List visible debate history

debate_solo

Legacy alias for caller-supplied debate

debate_auto

Legacy alias for API-generated debate

debate_review

Approve, override, or reject a paused auto debate

Service configuration

Common environment variables:

PLOIDY_TRANSPORT=stdio             # stdio (default) or streamable-http
PLOIDY_PORT=8765
PLOIDY_DB_PATH=~/.ploidy/ploidy.db
PLOIDY_MAX_CONTEXT_TOKENS=20000    # recommended for hosted auto mode
PLOIDY_RATE_CAPACITY=20
PLOIDY_RATE_PER_SEC=1
PLOIDY_RETENTION_DAYS=30

Authentication modes and their limits:

  • Admission-controlled self-hosting: PLOIDY_AUTH_MODE=bearer with PLOIDY_TOKENS='{"token":"tenant"}'.

  • OAuth interoperability: PLOIDY_AUTH_MODE=oauth and an exact public PLOIDY_OAUTH_ISSUER; v0.4.0 auto-approves clients and therefore is not user login or public admission control.

  • Migration only: PLOIDY_AUTH_MODE=both adds the static-token fallback.

Bearer mode without a configured token is intentionally unauthenticated and is suitable only for loopback development. Public services need a private ingress/gateway or controlled static tokens until OAuth gains resource-owner login and consent.

Container

The published image is immutable by release version:

docker run --rm \
  -p 127.0.0.1:8765:8765 \
  -v ploidy-data:/data \
  ghcr.io/heznpc/ploidy:0.4.0

Or run the checked-in Compose configuration:

docker compose up --build

The image defaults to streamable-http and contains the API, dashboard, metrics, Redis, and CLI runtime extras.

Documentation

License

MIT

Available Tools

13 tools
debateA
Destructive

Run a context-asymmetric debate in a single call.

One canonical entry point. Pick a mode:

  • auto (default): Ploidy generates both sides via the configured OpenAI-compatible API endpoint and returns the convergence result. Requires non-empty context_documents plus a configured API endpoint. HITL pause/resume is available via pause_at; resume with the legacy debate_review tool.

  • solo: you supply both positions (and optionally both challenges) and Ploidy persists + converges them. No external API key needed — the recommended single-terminal flow when the caller (e.g. Claude Code itself) writes both sides locally.

The older 12-tool surface (debate_start / debate_join / debate_position / ...) remains available for two-terminal and HITL workflows but is now deprecated; new integrations should use this tool.

Args: prompt: The decision question to debate. mode: "auto" or "solo". deep_position: (solo only) Deep side's stance. fresh_position: (solo only) Fresh side's stance. deep_challenge: (solo only) Optional deep-side critique. fresh_challenge: (solo only) Optional fresh-side critique. deep_label / fresh_label: (solo) display labels for roles. fresh_role: (auto) "fresh" or "semi_fresh". delivery_mode: (auto + semi_fresh) "passive", "active", or "selective". pause_at: (auto) Optional "challenge" or "convergence" HITL pause point. deep_n / fresh_n: (auto) Ploidy level per side. effort: (auto) "low", "medium", "high", "max". injection_mode: (auto) Context formatting mode. context_pct: (auto) Percentage of context to retain. language: (auto) Output language code. deep_model / fresh_model: (auto) Model override. Supplying either applies it to both sides; if both are supplied they must match. context_documents: Documents attached only to the Deep side. Required and non-empty in auto mode; optional provenance in solo mode. context_sources: Optional provenance labels, one per context document. blocked_sources: Optional strings that must not appear in source labels or context documents. target_lease: Optional target identifier that pins this debate's scope. allowed_sources: Optional source-label allowlist; defaults to target_lease when a target lease is set.

Returns: Convergence result dict, or paused state (auto + pause_at).

Inputs: prompt (required), mode, deep_n, effort, +20 more.

debate_autoA
Destructive

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Run a complete debate automatically in a single command.

Requires non-empty context_documents and a configured API endpoint. Generates positions and one independent challenge per seat with one resolved model, runs the protocol, and returns the convergence result.

Inputs: prompt (required), deep_n, effort, fresh_n, +13 more.

debate_cancelA
DestructiveIdempotent

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Cancel a debate in progress.

Inputs: debate_id (required).

debate_challengeA

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Submit a challenge to another session's position.

Inputs: content (required), session_id (required), action.

debate_convergeA

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Trigger convergence analysis for a debate.

Inputs: debate_id (required).

debate_deleteA
DestructiveIdempotent

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Permanently delete a debate and all its data.

Inputs: debate_id (required).

debate_historyA
Read-onlyIdempotent

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Retrieve past debates and their outcomes.

Inputs: limit.

debate_joinA

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Join an existing debate as a fresh or semi-fresh session.

Inputs: debate_id (required), role, delivery_mode.

debate_positionA

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Submit a position from a session.

Inputs: content (required), session_id (required).

debate_reviewA

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Review and resume a paused auto-debate (HITL).

Call after debate_auto with pause_at paused the run. Action is one of 'approve', 'override', or 'reject'.

Inputs: debate_id (required), action, override_content.

debate_soloA
Destructive

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Run a complete debate from caller-supplied positions in one call.

Single-terminal entry point: the caller generates both sides locally and submits the texts here. No external API key required.

Inputs: prompt (required), deep_position (required), fresh_position (required), deep_label, +8 more.

debate_startA
Destructive

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Begin a new debate session with a decision prompt.

Creates a debate and a Deep (full-context) session. Share the returned debate_id with the fresh session so it can join.

Inputs: prompt (required), target_lease, allowed_sources, blocked_sources, +2 more.

debate_statusA
Read-onlyIdempotent

DEPRECATED (v0.4) — prefer debate(prompt, mode=...).

Get current state of a debate.

Inputs: debate_id (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 13 tools

    Disambiguation4/5

    The set includes one canonical tool and 12 deprecated tools that are explicitly marked as superseded. While each deprecated tool has a distinct action, they overlap with the canonical tool's modes, so an agent must read the deprecation notices carefully. The guidance is clear, so most ambiguity is resolved.

    Naming Consistency4/5

    The deprecated tools follow a consistent 'debate_' prefix with verb suffixes, but the canonical 'debate' and two mode-based tools ('debate_solo', 'debate_auto') deviate from the verb pattern. Overall the consistency is good, with only minor deviations.

    Tool Count2/5

    The tool count is bloated: 12 of 13 tools are deprecated legacy surface, while the entire functionality is available through the single 'debate' tool. This duplication inflates the count unnecessarily, making the set feel much heavier than its actual scope.

    Completeness5/5

    The debate lifecycle is fully covered: starting, joining, submitting positions, challenging, converging, canceling, deleting, status, history, and HITL review. The canonical tool subsumes all of these, so there are no obvious gaps.

    Maintenance

    ActivityStale
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers