Skip to main content

MCP server that turns planning conversations into ordered feature plans

Project description

Planner API

HTTP wrapper over the personal-stack planner. Two modes: subscription (the host's claude CLI thinks on a Claude subscription via CLAUDE_CODE_OAUTH_TOKEN, no API key) or BYOK (the caller sends X-Anthropic-Key). A public deployment locks every non-health endpoint behind a shared secret (X-Planner-Token).

Endpoints

  • GET /health — liveness. Always open (Railway healthcheck).
  • POST /plan{conversation, person} → ordered, LLM-labeled, personalized plan with analytics.planId. Auth: X-Planner-Token if PLANNER_ACCESS_TOKEN is set; LLM via the subscription (subscription mode) or X-Anthropic-Key (BYOK).
  • POST /feedback{person, plan_id, liked, comment?} → records acceptance or dislike without changing weights.
  • POST /correct{person, plan_id?, corrected_plan? | corrected_order?, proposed_order?} → tunes the layer preference immediately and banks decomposition ground truth. No key (offline).
  • POST /analytics/event{person, kind, payload} → internal redirect events for plan.delivered and invoker.redirect.disabled.
  • GET /analytics/{person}?limit=&kind= — reads recent unified analytics events. Drop-off is plan.delivered with no later feedback.* for the same planId.
  • GET /profile/{person} — the person's current preference graph. No key.

Run locally

pip install -r service/requirements-service.txt
uvicorn service.app:app --reload
curl localhost:8000/health
curl -X POST localhost:8000/plan -H 'X-Anthropic-Key: sk-ant-...' \
  -H 'content-type: application/json' \
  -d '{"conversation":"...","person":"edbert"}'

Deploy (Railway, subscription mode, key-free)

The API runs on Railway at api.invoker-control.dev from service/Dockerfile, which bakes in the claude CLI. The static landing page is a separate repo on Vercel at invoker-control.dev (serverless is a poor fit for /plan — it makes many sequential LLM calls and exceeds function time limits).

Railway auto-deploys on every push to main (GitHub integration). Set these env vars in Railway (never commit them):

  • ANALYTICS_ENABLED=1 — mirrors local JSONL events to PostHog.
  • ANALYTICS_VENDOR=posthog — the only outbound vendor currently supported.
  • POSTHOG_PROJECT_TOKEN — PostHog project token (phc_...).
  • POSTHOG_HOST=https://us.i.posthog.com — or your EU/self-hosted PostHog host.
  • CLAUDE_CODE_OAUTH_TOKEN — from claude setup-token; lets the container's claude CLI think on your Claude subscription, so no Anthropic API key is needed.
  • PLANNER_SUBSCRIPTION_MODE=1/plan skips BYOK and uses that CLI.
  • PLANNER_ACCESS_TOKEN — a shared secret; required as X-Planner-Token on every non-health endpoint so the public URL can't spend your subscription.

The MCP redirect (integrations/invoker_planner) defaults PLANNER_URL to https://api.invoker-control.dev and forwards X-Planner-Token when PLANNER_ACCESS_TOKEN is set in its env (see install.py --access-token).

BYOK still works: if PLANNER_SUBSCRIPTION_MODE is unset, /plan requires X-Anthropic-Key and uses the caller's Anthropic API key instead.

Scaling later (subscription → API key)

The container is the unit of scale; Railway can run N replicas and autoscale on load (Railway → service → Settings → enable replicas/autoscaling). No code change.

The subscription path (CLAUDE_CODE_OAUTH_TOKEN + PLANNER_SUBSCRIPTION_MODE) is for one person / low volume — a Max plan has rate limits and isn't meant to back a multi-user service, so it won't scale to many concurrent users. To scale for real users:

  1. In Railway, remove PLANNER_SUBSCRIPTION_MODE (and CLAUDE_CODE_OAUTH_TOKEN).
  2. Either set a server-side ANTHROPIC_API_KEY (metered, you pay), or have each caller send their own X-Anthropic-Key (BYOK — complete_json already prefers the request-scoped key). Keep PLANNER_ACCESS_TOKEN as the endpoint lock either way.
  3. Then turn up Railway autoscaling; each request is metered per token, so it scales cleanly.

How the key flows (security)

X-Anthropic-Key → set on a request-scoped contextvar in _byok → read by registry/.../llm.py::complete_json for that request's Anthropic calls → reset in a finally. It is excluded from the disk cache (cache key = model+prompt only) and never logged.

Not yet (next milestones)

  • State → managed Postgres + real auth. Profiles/learned/corrections are still file-based here, keyed by person. For multi-user production this must move to a per-user database (also where the moat lives).
  • Rate limiting / quotas, accounts, the frontend.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drafter_mcp-0.1.0.tar.gz (50.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

drafter_mcp-0.1.0-py3-none-any.whl (66.3 kB view details)

Uploaded Python 3

File details

Details for the file drafter_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: drafter_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 50.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for drafter_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 594327c3b42ed7104e460bc4f414baa90b1540aff7c9c9fd1051666af4f1abe8
MD5 27ef9918cba739e813f65647c2f0a8f1
BLAKE2b-256 1b29611dbab932a869192389707d394e5b10bb58a7d4466c791a61e1053d7e22

See more details on using hashes here.

Provenance

The following attestation bundles were made for drafter_mcp-0.1.0.tar.gz:

Publisher: publish-python.yml on Neko-Catpital-Labs/Drafter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file drafter_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: drafter_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 66.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for drafter_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 84841768e78d5e8b52a6779c6e216f0ce56cc15d7b4b8f28bbc304d098214008
MD5 d8302d638d208e7ad2e41fd289a69840
BLAKE2b-256 def893f021ee731ca833584a0d9c71c2362bdbc1cde9c6b75c00fb5fa84efb73

See more details on using hashes here.

Provenance

The following attestation bundles were made for drafter_mcp-0.1.0-py3-none-any.whl:

Publisher: publish-python.yml on Neko-Catpital-Labs/Drafter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page