Skip to content

MCP auth has no non-interactive grant, locking out headless/CI clients #30

Description

@shbernal

Metering usage is fair — serving an embedding index costs money, and the README is clear that sign-in exists to control usage. But the mechanism chosen to do it locks out a big share of MCP clients.

https://api.ooxml.dev/.well-known/oauth-authorization-server advertises:

"grant_types_supported": ["authorization_code", "refresh_token"]

No client_credentials, and no device_authorization_endpoint (RFC 8628). With magic-link sign-in, that means there is no path from an account to a token without a human at a browser — no password, no API key, nothing that can go in a CI secret.

So CI jobs, cron agents, containers with no browser, and sub-agents spawned inside an orchestration run can all register a client (POST /oauth/register returns 400, not 401), but none of them can complete the authorization step.

refresh_token is supported, so signing in once and persisting the refresh token works in principle — but the lifetime and rotation behaviour aren't documented, so it's a guess rather than something to build on.

Any of these would fix it while keeping per-account metering:

  1. Account-issued API keys — simplest, and a stable per-integration identity is arguably better telemetry than OAuth sessions.
  2. client_credentials grant — standards-pure version of the same thing.
  3. Device authorization flow (RFC 8628) — built for exactly this case, keeps the account tie.

Two small extras: document the token lifetime / refresh rotation, and emit RateLimit-* headers so clients can self-regulate instead of discovering the limit by hitting it.

Happy to test whichever you pick against a real headless workload.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions