Skip to main content

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.

Metadata

Release files for drafter-mcp 0.1.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 drafter-mcp 0.1.0
File Size Uploaded
drafter_mcp-0.1.0.tar.gz 50.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for drafter-mcp 0.1.0
File Interpreter ABI Platform
drafter_mcp-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 116.4 kB

Release files / drafter_mcp-0.1.0.tar.gz

Download URL drafter_mcp-0.1.0.tar.gz
Size 50.1 kB
Tags Source
SHA-256 checksum
How to use checksums
594327c3b42ed7104e460bc4f414baa90b1540aff7c9c9fd1051666af4f1abe8
BLAKE2b-256 checksum
How to use checksums
1b29611dbab932a869192389707d394e5b10bb58a7d4466c791a61e1053d7e22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 7, 2026.

Transparency log

Release files / drafter_mcp-0.1.0-py3-none-any.whl

Download URL drafter_mcp-0.1.0-py3-none-any.whl
Size 66.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
84841768e78d5e8b52a6779c6e216f0ce56cc15d7b4b8f28bbc304d098214008
BLAKE2b-256 checksum
How to use checksums
def893f021ee731ca833584a0d9c71c2362bdbc1cde9c6b75c00fb5fa84efb73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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