Skip to content

Latest commit

 

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Eigendark Agent MCP

eigendark-agent-mcp is a hardened stdio and hosted MCP server that lets an AI agent play Eigendark through the public, seat-scoped Agent API.

The server can self-onboard a short-lived sandbox identity, create a house-bot match or enter public matchmaking, read a seat-redacted state, submit one legal action, and create a read-only replay link. Its public ChatGPT app starts cold: the user can say “play Eigendark” without an Eigendark account, key, invite, or setup.

OpenAI Build Week 2026

This repository is the public agent-entry layer for Eigendark: The Living Champions League, a human-authored trading-card world played by autonomous agents. People create the cards—including their mechanics, statistics, art direction, and lore. Agents search that shared corpus, construct legal decks, and compete under an authoritative rules engine. The MCP server is what lets an outside agent safely join that world.

The core card game, Python rules engine, and an installable stdio MCP prototype existed before Build Week. The submitted work begins after commit ee67fbc; the complete implementation diff is permanently pinned as ee67fbc...0f82fcf.

What was built during Build Week

  • a zero-setup hosted ChatGPT/MCP app that can start and finish a real match from “play Eigendark”;
  • a public Streamable HTTP endpoint that works with any MCP-capable client, including Codex CLI;
  • a Custom GPT Action bridge with an opaque, bounded game-session model;
  • anonymous sandbox onboarding and rules-enforced starter decks, with credentials retained only by the service or the relevant MCP session;
  • safe action, state, matchmaking, ladder, and read-only replay flows;
  • atomic capability handling, recursive output sanitization, and token redaction;
  • layered request, response, concurrency, memory, session, and onboarding budgets; and
  • deployment hardening, threat-model documentation, and regression gates for the public entry points.

How Codex and GPT-5.6 were used

Codex with GPT-5.6 Sol was the primary development environment for the Build Week extension. It inspected the existing client, hosted service, deployment configuration, and upstream Agent API as one end-to-end capability flow. It then helped design and implement the hosted MCP transport, ChatGPT tool surface, Custom GPT bridge, per-session secret storage, sandbox-key persistence, schema validation, redaction boundaries, resource budgets, and failure-safe match orchestration.

Codex was also used to threat-model the anonymous public surface, trace failures in live deployments, write regression tests for each violated invariant, review the resulting pull requests, and verify the deployed connector with real rules-enforced matches. The human author retained the product and security decisions: the game engine remains authoritative, credentials never enter model-visible tool payloads, public agent speech is not chain-of-thought, and anonymous access stays bounded.

GPT-5.6 was used to build and verify this integration; it is not being presented as the default runtime model for Eigendark's league champions. Runtime provenance is reported separately by the game so spectators can distinguish the builder from the models that actually played.

Try the submitted integration

The fastest path requires no account, key, or local installation:

https://api.eigendark.com/mcp/public

The canonical transport chooser and custom-deck handoff are maintained at https://www.eigendark.com/agent-launch.md. It documents the GET-only link protocol, sandbox POST API, public MCP tools, and the boundary between one-off card-ref decks and account-owned saved decks.

For Codex CLI:

codex mcp add eigendark --url https://api.eigendark.com/mcp/public

Then ask Codex to Play Eigendark. The returned URL is a public, read-only record of the real engine match. For source verification, local installation, and the complete quality gate, see Install and Contributing.

Security model

API keys, matchmaking tickets, seat tokens, review keys, and spectator tokens are never MCP tool arguments or results. In stdio mode they enter the process only through environment configuration or trusted Eigendark responses. The hosted mode refuses process-wide credentials and allocates a distinct bounded in-memory store for each MCP session. Match capabilities are cleared on restart. A single sandbox onboarding key is shared only for match creation and persisted in a service-owned 0600 state file so restart loops cannot exhaust the upstream onboarding quota.

Remote card text, event text, player names, and deck names are untrusted data. Every remote result is labeled accordingly, recursively sanitized, bounded, and redacted. A known or obvious credential cannot be copied into a public API field such as an agent ID, deck name, match ID, or action argument.

Other enforced boundaries include:

  • the official MCP Python SDK and newline-delimited stdio framing;
  • finite inbound MCP, HTTP request, HTTP response, nesting, and concurrency limits;
  • exact JSON Schemas for every tool and action family;
  • HTTPS and destination allowlisting, with all redirects rejected;
  • no credentials in URLs, including match-state reads;
  • loopback requests that bypass environment proxy settings; and
  • sanitized errors that never include remote HTML or raw exception details.

See SECURITY.md for reporting and Security controls for the automated regression gates.

Hosted connector (no install)

Any MCP-capable chat client can attach the hosted server directly — no install, key, or account:

https://api.eigendark.com/mcp/public
  • Claude (claude.ai / desktop): Settings → Connectors → Add custom connector → paste the URL above. Then say "play eigendark" in any chat.
  • ChatGPT: Settings → Apps & Connectors → developer mode → add the same URL (the curated Eigendark app on /mcp remains the reviewed listing).
  • IDE / other MCP clients: add a streamable-http server with that URL.

The hosted endpoint is anonymous by design: the service uses one short-lived, server-held sandbox identity to create isolated matches, plays rules-enforced starter decks against the house bot, and returns a public spectator link. Match capabilities stay scoped to each protocol session. Global, per-client-session, request, and body budgets are enforced at nginx and in the app; no credentials are ever accepted from or exposed to the client.

Install

Python 3.11 or newer is required. Run the published package without installing it globally:

uvx --from eigendark-agent-mcp==0.5.0 eigendark-agent-mcp

Or install the exact release with pipx:

pipx install eigendark-agent-mcp==0.5.0

For development from a checkout, follow CONTRIBUTING.md.

MCP client configuration

Self-onboarding needs no secret configuration:

{
  "mcpServers": {
    "eigendark": {
      "command": "uvx",
      "args": [
        "--from",
        "eigendark-agent-mcp==0.5.0",
        "eigendark-agent-mcp"
      ]
    }
  }
}

To use a pre-provisioned identity or a seat capability supplied by a match host, inject it through the MCP process environment. Configure only the capability that this one agent needs:

{
  "mcpServers": {
    "eigendark": {
      "command": "uvx",
      "args": [
        "--from",
        "eigendark-agent-mcp==0.5.0",
        "eigendark-agent-mcp"
      ],
      "env": {
        "EIGENDARK_API_KEY": "REDACTED_API_KEY",
        "EIGENDARK_SEAT_TOKEN": "REDACTED_SEAT_TOKEN"
      }
    }
  }
}

Do not place real credentials in committed configuration, prompts, transcripts, issues, logs, screenshots, or shared agent context.

ChatGPT app

The public app uses Streamable HTTP at https://api.eigendark.com/mcp/public. It exposes only three no-auth tools: play_eigendark, get_eigendark_game, and take_eigendark_turn. play_eigendark performs anonymous sandbox onboarding, creates a bot match, retains all capabilities only in that MCP session, and drives that match to an authoritative terminal result before its single tool call returns. The response includes a public read-only live/replay URL and explicitly identifies the deterministic server fallback that chose the delegated moves. The state and turn tools remain available for deliberate manual play and recovery.

The hosted process binds to loopback. Production nginx verifies ChatGPT's mTLS client certificate and overwrites the forwarded certificate headers; the Python service independently checks the expected SAN, client-auth usage, and validity. Requests, sessions, bodies, workers, and memory are bounded. The installable plugin source and deployment configuration live in plugin/eigendark and deploy.

Custom GPT Action

The same service exposes an OpenAPI schema at https://api.eigendark.com/gpt/openapi.json for the no-setup Eigendark Custom GPT. The Action endpoints retain sandbox and seat credentials only in a bounded, 30-minute in-memory game session. ChatGPT receives a random opaque game_id, public seat-redacted state, and the read-only review link; it never receives an Eigendark credential. The normal /gpt/play response is already terminal, and its ephemeral handle is erased immediately. The recovery/turn routes remain bounded for older running sessions.

Production nginx permits Action calls only from OpenAI's published ChatGPT Actions egress ranges, refreshed and validated during deployment. Every Action call must also present a randomly generated builder-managed bearer credential; end users never configure or receive it. The public schema remains readable for editor validation. The Action API is separately rate-, body-, timeout-, connection-, session-, response-, and concurrency-bounded.

Play flow

  1. Call onboard_sandbox unless EIGENDARK_API_KEY is already configured.
  2. Call create_bot_match, or call join_matchmaking and poll matchmaking_status after poll_after_ms.
  3. For a house-bot match that should finish without client orchestration, call the authenticated Agent API autoplay operation once. The public play_eigendark tool performs this automatically.
  4. For deliberate manual play, call get_match_state with only the returned match_id and seat. The seat credential is resolved internally. Bot advancement defaults to enabled.
  5. When your_turn is true, copy one kind/args pair from legal_actions into submit_action.
  6. Repeat until match_status is complete.
  7. Optionally call share_replay to create a read-only human link.

Custom decks

The full stdio server accepts card_ids when joining matchmaking. Use the public card search and the Agent API resolver first, then pass the exact image_url references; the upstream engine remains authoritative on whole-deck legality. The public one-call play_eigendark tool intentionally uses server starters. Persistent saved decks and public decklists remain account-key features of the HTTP Agent API.

The backend remains authoritative for legality. Supported action schemas cover play, pool, activate_source, attack, block, recall, activate, attach, ritual, join_ritual, resolve_ritual, sustain_ritual, choose_prompt_target, choose_prompt_distribution, draw, and pass.

Tools

Tool Purpose
agent_protocol_guide Return the safe play flow and exact action vocabulary.
onboard_sandbox Mint and remember an expiring sandbox key without returning it.
create_bot_match Create a house-bot match and remember the seat capability.
join_matchmaking Enter public matchmaking and remember the private ticket.
matchmaking_status Poll the remembered ticket and retain delivered match credentials.
leave_matchmaking Cancel a waiting ticket and erase it from memory.
get_match_state POST a credential-bearing state read without putting secrets in a URL.
submit_action Submit one schema-validated legal action.
summarize_state Condense a state result locally.
share_replay Create a read-only spectator link with an internal capability.
get_standing Read one public ladder standing.

Environment

Variable Required Default Notes
EIGENDARK_API_KEY / ED_API_KEY No None Pre-provisioned API key; otherwise call onboard_sandbox.
EIGENDARK_SEAT_TOKEN / ED_SEAT_TOKEN No None One externally supplied seat capability.
EIGENDARK_BASE_URL / ED_BASE_URL No https://www.eigendark.com Production and loopback are allowlisted.
EIGENDARK_TIMEOUT_SECONDS / ED_TIMEOUT_SECONDS No 20 Finite positive value, capped at 120 seconds.
EIGENDARK_MCP_ALLOW_UNTRUSTED_BASE_URL No Unset Explicit test-only opt-in; remote overrides still require HTTPS.

Sandbox keys are rate-limited and expire automatically. For a durable full identity, a human can issue a key at https://www.eigendark.com/agent-keys and configure it outside the model boundary.

About

Hardened Eigendark MCP server for AI agents: self-onboard, play seat-scoped matches, and share replays.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages