Skip to content

feat: add HTTP transport with OAuth flow including token exchange#21

Draft
tomassurin wants to merge 29 commits intomainfrom
tomas/mcp-server-auth
Draft

feat: add HTTP transport with OAuth flow including token exchange#21
tomassurin wants to merge 29 commits intomainfrom
tomas/mcp-server-auth

Conversation

@tomassurin
Copy link

@tomassurin tomassurin commented Mar 11, 2026

Resolves https://nutrient.atlassian.net/browse/SERVER-2408

Summary

Upgrades the MCP server from stdio-only with static API key auth to also support HTTP transport with production-grade authentication:

  • Streamable HTTP transport at /mcp with session binding, alongside the existing stdio mode
  • JWT authentication via JWKS (AUTH_MODE=jwt) with validation of aud, scope, exp, iss claims, plus static bearer token mode (AUTH_MODE=static) for local dev
  • RFC 8693 token exchange — exchanges MCP access tokens for short-lived DWS API credentials with per-principal caching
    • Built it when I still considered having this MCP hosted. Since we go with local MCP only now, it's not practical (MCP needs to be confidential client but we will be publishing it so can't really do secrets).
  • Protected Resource Metadata endpoint (/.well-known/oauth-protected-resource) per RFC 9728
  • Session-scoped DwsApiClient replacing the module-level API function, enabling per-user token resolution
  • Request logging middleware with structured logger
  • CI setup Github action to run tests and lint

Stdio mode is fully preserved — all new behavior is opt-in via environment variables (MCP_TRANSPORT=http).

tomassurin and others added 8 commits March 11, 2026 13:54
Design for Track B of Co-work DWS Connector — upgrading the MCP server
from stdio-only/static-API-key to HTTP transport with JWT auth via JWKS,
RFC 8693 token exchange, and RFC 9728 Protected Resource Metadata.
Six implementation phases covering transport, auth, token exchange,
and environment configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tomassurin tomassurin changed the title feat: add HTTP transport with JWT auth and token exchange feat: add HTTP transport with OAuth flow including token exchange Mar 11, 2026
tomassurin and others added 15 commits March 12, 2026 18:47
Remove callNutrientApi legacy helper and inline axios fallbacks. All
perform* functions now require an explicit DwsApiClient parameter,
eliminating hidden coupling to environment variables and global state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove TokenExchangeClient and token exchange mechanism
- DWS API now accepts OAuth access tokens directly
- Simplify JWT mode environment validation to only require JWKS_URL
- Remove CLIENT_ID, CLIENT_SECRET, CLIENT_ASSERTION_* requirements for JWT mode
- Delete unused src/http/tokenExchange.ts
- Update tokenExchange.test.ts to skip (no longer applicable)
- Update environment.ts to remove token exchange validation
- Update documentation (README.md, docs/testing.md, .env.example)
- Update environment tests to reflect new behavior
JWKS_URL now defaults to https://api.nutrient.io/.well-known/jwks.json
so JWT mode only requires AUTH_MODE=jwt. Remove redundant environment
tests and the empty tokenExchange test file. Update testing.md with
minimal JWT config, localhost DWS debug build section, and current
common failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removes duplicate implementations from bearerAuth.ts and jwtAuth.ts
into a single src/http/authUtils.ts module to avoid drift.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- isInitializeRequest now checks array bodies for batch JSON-RPC
- Add comment noting CORS wildcard is intentional for local use

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tomassurin tomassurin marked this pull request as draft March 16, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant