Files
artcraft/mcp
Tanish Manku afd2d0d6a9 mcp: UpstreamClient — typed openapi-fetch client gated by allowlist, use, origin, and credential
src/upstream/client.ts is the only way this service talks to the Artcraft
API. Middleware refuses, before anything leaves the Worker: routes not
allowlisted for the client's `use` (tools = read, sign-in/out = auth),
per-request baseUrl overrides to any other origin, and concrete URLs that
do not match the allowlisted template (independent second check). The
credential is attached last, so a rejected request never carries it.
Read clients require a credential; auth clients may sign in without one.

Tests (13): headers and URL of a good request, path substitution, array
query params as repeated keys (what actix_web_lab parses), 401 passed
through as a result not an exception, credential required for read,
sign-in without and sign-out with a credential, and the gate firing —
auth route from read client, read route from auth client, unlisted
path, foreign baseUrl — each with fetch provably not called; path
parameters are percent-encoded so they cannot escape their segment; the
rejection message never contains the credential.

CLAUDE.md layout updated for the upstream module and generated files.

pnpm check: typecheck, eslint, prettier, 77 tests passing.

Claude-Session: https://claude.ai/code/session_01H3gfN2NCx3hBXSrZXYHUQ3
2026-08-24 20:15:40 -07:00
..

Artcraft MCP server

Cloudflare Worker at mcp.getartcraft.com. Read CLAUDE.md first — it holds the constraints, the architecture, and the working method; this file is only how to run things.

Run locally

corepack enable            # once; provides the pinned pnpm
pnpm install
cp .dev.vars.example .dev.vars

pnpm --filter @artcraft/mcp-fake-upstream dev   # fake API on http://localhost:12345
pnpm dev                                        # MCP server on http://localhost:8787

Local never talks to production: wrangler.toml's top-level block points at the fake, and src/config.ts refuses to start otherwise.

Check everything

pnpm check     # typecheck (regenerates Worker types) · lint · format · test
pnpm test      # vitest, inside workerd with the local bindings

Deploy

Deploys run from .github/workflows/mcp.yml on main once the Cloudflare secrets exist (docs/infra-request.md). Manual deploys, when needed:

pnpm deploy:preview       # workers.dev, talks to the deployed fake
pnpm deploy:production    # mcp.getartcraft.com, talks to api.storyteller.ai

Layout

See CLAUDE.md → Layout.