Files
artcraft/mcp
Tanish Manku 4f810e44d6 mcp: UpstreamCredential interface with the session implementation
src/upstream/credential.ts defines what this service holds on a user's
behalf and how it reaches an upstream request. The only kind today is an
Artcraft session (the signed_session JWT from sign-in) sent as the
`session` header; `kind` is stored in grant props from the start so a
backend-issued credential can replace it later without touching tools or
the client (swap point 2 in mcp/CLAUDE.md).

The contract includes non-leaking toString/toJSON: accidental string or
JSON conversion yields describe(), never the secret (the secret lives in
a private field). Sign-in values are rejected if empty, non-ASCII, or
containing whitespace/CRLF (header injection). Unknown prop kinds are an
error, not a fallthrough.

Tests (9): header attached exactly once and nothing else set, replace
semantics, props round-trip, no leak via describe/String/JSON/keys, and
validation firing on empty, injection, unknown kind, missing secret,
non-object props.

Claude-Session: https://claude.ai/code/session_01H3gfN2NCx3hBXSrZXYHUQ3
2026-08-24 20:12:08 -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.