Skip to content

Commit 9a964d2

Browse files
Merge remote-tracking branch 'origin/fweinberger/v2-bc-server-auth-legacy' into fweinberger/v2-bc-d1-base
2 parents 749254e + 2fc7351 commit 9a964d2

41 files changed

Lines changed: 4976 additions & 13 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@modelcontextprotocol/server-auth-legacy': patch
3+
---
4+
5+
Add `@modelcontextprotocol/server-auth-legacy`, a deprecated, frozen copy of the v1 SDK's `src/server/auth/` Authorization Server helpers (`mcpAuthRouter`, `ProxyOAuthServerProvider`, OAuth handlers/middleware/errors). Provided solely for v1 → v2 migration; new code should use a dedicated IdP plus the Resource Server helpers in `@modelcontextprotocol/express`.

.changeset/pre.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@modelcontextprotocol/hono": "2.0.0-alpha.0",
1818
"@modelcontextprotocol/node": "2.0.0-alpha.0",
1919
"@modelcontextprotocol/server": "2.0.0-alpha.0",
20+
"@modelcontextprotocol/server-auth-legacy": "2.0.0-alpha.2",
2021
"@modelcontextprotocol/test-conformance": "2.0.0-alpha.0",
2122
"@modelcontextprotocol/test-helpers": "2.0.0-alpha.0",
2223
"@modelcontextprotocol/test-integration": "2.0.0-alpha.0"

.github/workflows/publish.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ jobs:
4141
run:
4242
pnpm dlx pkg-pr-new publish --packageManager=npm --pnpm './packages/server' './packages/client'
4343
'./packages/middleware/express' './packages/middleware/fastify' './packages/middleware/hono' './packages/middleware/node'
44+
'./packages/server-auth-legacy'

docs/faq.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ The [server quickstart](./server-quickstart.md) walks you through building a wea
7171

7272
### Where are the server auth helpers?
7373

74-
Resource Server helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `OAuthTokenVerifier`) are first-class in `@modelcontextprotocol/express`. The Authorization Server helpers (`mcpAuthRouter`, `ProxyOAuthServerProvider`, etc.) have been removed from the core SDK; new code should use a dedicated IdP/OAuth library. Example packages provide a demo with `better-auth`.
74+
Resource Server helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `OAuthTokenVerifier`) are first-class in `@modelcontextprotocol/express`. Authorization Server helpers (`mcpAuthRouter`, `ProxyOAuthServerProvider`, etc.) remain available as a frozen v1 copy in the deprecated `@modelcontextprotocol/server-auth-legacy` package; new code should use a dedicated IdP/OAuth library. Example packages provide a demo with `better-auth`.
7575

7676
### Why did we remove `server` SSE transport?
7777

docs/migration-SKILL.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Replace all `@modelcontextprotocol/sdk/...` imports using this table.
5454
| `@modelcontextprotocol/sdk/server/stdio.js` | `@modelcontextprotocol/server/stdio` |
5555
| `@modelcontextprotocol/sdk/server/streamableHttp.js` | `@modelcontextprotocol/node` (class renamed to `NodeStreamableHTTPServerTransport`) OR `@modelcontextprotocol/server` (web-standard `WebStandardStreamableHTTPServerTransport` for Cloudflare Workers, Deno, etc.) |
5656
| `@modelcontextprotocol/sdk/server/sse.js` | REMOVED (migrate to Streamable HTTP) |
57-
| `@modelcontextprotocol/sdk/server/auth/*` | RS helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `OAuthTokenVerifier`) → `@modelcontextprotocol/express`; AS helpers removed (use external IdP/OAuth library) |
57+
| `@modelcontextprotocol/sdk/server/auth/*` | RS helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `OAuthTokenVerifier`) → `@modelcontextprotocol/express`; AS helpers `@modelcontextprotocol/server-auth-legacy` (deprecated; frozen v1 copy) |
5858
| `@modelcontextprotocol/sdk/server/middleware.js` | `@modelcontextprotocol/express` (signature changed, see section 8) |
5959

6060
### Types / shared imports
@@ -194,6 +194,8 @@ Individual OAuth error classes replaced with single `OAuthError` class and `OAut
194194

195195
Removed: `OAUTH_ERRORS` constant.
196196

197+
For server-side Authorization-Server implementations, the v1 subclass hierarchy (and `OAUTH_ERRORS`) is still available from `@modelcontextprotocol/server-auth-legacy` (frozen v1 copy). For client-side error handling, use `OAuthError` + `OAuthErrorCode` as below.
198+
197199
Update OAuth error handling:
198200

199201
```typescript
@@ -323,7 +325,7 @@ new URL(ctx.http?.req?.url).searchParams.get('debug')
323325

324326
### Server-side auth
325327

326-
Resource Server helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `getOAuthProtectedResourceMetadataUrl`, `OAuthTokenVerifier`) are first-class in `@modelcontextprotocol/express`. Authorization Server helpers (`mcpAuthRouter`, `OAuthServerProvider`, `ProxyOAuthServerProvider`, `authenticateClient`, `allowedMethods`, etc.) are removed from the core SDK; use an external IdP/OAuth library. See `examples/server/src/` for demos.
328+
Resource Server helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `getOAuthProtectedResourceMetadataUrl`, `OAuthTokenVerifier`) are first-class in `@modelcontextprotocol/express`. Authorization Server helpers (`mcpAuthRouter`, `OAuthServerProvider`, `ProxyOAuthServerProvider`, `authenticateClient`, `allowedMethods`, etc.) remain available as a frozen v1 copy in the deprecated `@modelcontextprotocol/server-auth-legacy` package; new code should use an external IdP/OAuth library. See `examples/server/src/` for demos.
327329

328330
### Host header validation (Express)
329331

@@ -534,6 +536,6 @@ Access validators explicitly:
534536
6. Replace plain header objects with `new Headers({...})` and bracket access (`headers['x']`) with `.get()` calls per section 7
535537
7. If using `hostHeaderValidation` from server, update import and signature per section 8
536538
8. If using server SSE transport, migrate to Streamable HTTP
537-
9. If using server auth from the SDK: RS helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`) → `@modelcontextprotocol/express`; AS helpers → external IdP/OAuth library
539+
9. If using server auth from the SDK: RS helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`) → `@modelcontextprotocol/express`; AS helpers → `@modelcontextprotocol/server-auth-legacy` (deprecated; frozen v1 copy) or an external IdP/OAuth library
538540
10. If relying on `listTools()`/`listPrompts()`/etc. throwing on missing capabilities, set `enforceStrictCapabilities: true`
539541
11. Verify: build with `tsc` / run tests

docs/migration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ const transport = new StreamableHTTPClientTransport(new URL('http://localhost:30
137137

138138
Resource Server helpers (`requireBearerAuth`, `mcpAuthMetadataRouter`, `getOAuthProtectedResourceMetadataUrl`, `OAuthTokenVerifier`) are now first-class in `@modelcontextprotocol/express`.
139139

140-
Authorization Server helpers (`mcpAuthRouter`, `OAuthServerProvider`, `ProxyOAuthServerProvider`, `authenticateClient`, `allowedMethods`, etc.) have been removed from the core SDK; new code should use a dedicated IdP/OAuth library. See the [examples](../examples/server/src/) for a working demo with `better-auth`.
140+
Authorization Server helpers (`mcpAuthRouter`, `OAuthServerProvider`, `ProxyOAuthServerProvider`, `authenticateClient`, `allowedMethods`, etc.) remain available as a frozen v1 copy in the deprecated `@modelcontextprotocol/server-auth-legacy` package. New code should use a dedicated IdP/OAuth library. See the [examples](../examples/server/src/) for a working demo with `better-auth`.
141141

142142
Note: `AuthInfo` has moved from `server/auth/types.ts` to the core types and is now re-exported by `@modelcontextprotocol/client` and `@modelcontextprotocol/server`.
143143

@@ -811,6 +811,8 @@ The following individual error classes have been removed in favor of `OAuthError
811811

812812
The `OAUTH_ERRORS` constant has also been removed.
813813

814+
> **Server-side Authorization-Server code:** the v1 subclass hierarchy (and `OAUTH_ERRORS`) is still exported from `@modelcontextprotocol/server-auth-legacy` (frozen v1 copy). Use that package if you implement an OAuth Authorization Server. For client-side error handling, use `OAuthError` + `OAuthErrorCode` as below.
815+
814816
**Before (v1):**
815817

816818
```typescript
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# @modelcontextprotocol/server-auth-legacy
2+
3+
<!-- prettier-ignore -->
4+
> [!WARNING]
5+
> **Deprecated.** This package is a frozen copy of the v1 SDK's `src/server/auth/` Authorization Server helpers (`mcpAuthRouter`, `ProxyOAuthServerProvider`, etc.). It exists solely to ease migration from `@modelcontextprotocol/sdk` v1 and will not receive new features or non-critical bug fixes.
6+
7+
The v2 SDK no longer ships an OAuth Authorization Server implementation. MCP servers are Resource Servers; running your own AS is an anti-pattern for most deployments.
8+
9+
## Migration
10+
11+
- **Resource Server glue** (`requireBearerAuth`, `mcpAuthMetadataRouter`, Protected Resource Metadata): use the first-class helpers in `@modelcontextprotocol/express`.
12+
- **Authorization Server**: use a dedicated IdP (Auth0, Keycloak, Okta, etc.) or a purpose-built OAuth library.
13+
14+
## Usage (legacy)
15+
16+
```ts
17+
import express from 'express';
18+
import { mcpAuthRouter, ProxyOAuthServerProvider } from '@modelcontextprotocol/server-auth-legacy';
19+
20+
const app = express();
21+
app.use(mcpAuthRouter({ provider, issuerUrl: new URL('https://example.com') }));
22+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @ts-check
2+
3+
import baseConfig from '@modelcontextprotocol/eslint-config';
4+
5+
export default [
6+
...baseConfig,
7+
{
8+
settings: {
9+
'import/internal-regex': '^@modelcontextprotocol/core'
10+
}
11+
}
12+
];
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"name": "@modelcontextprotocol/server-auth-legacy",
3+
"private": false,
4+
"version": "2.0.0-alpha.2",
5+
"description": "Frozen v1 OAuth Authorization Server helpers (mcpAuthRouter, ProxyOAuthServerProvider) for the Model Context Protocol TypeScript SDK. Deprecated; use a dedicated OAuth server in production.",
6+
"deprecated": "The MCP SDK no longer ships an Authorization Server implementation. This package is a frozen copy of the v1 src/server/auth helpers for migration purposes only and will not receive new features. Use a dedicated OAuth Authorization Server (e.g. an IdP) and the Resource Server helpers in @modelcontextprotocol/express instead.",
7+
"license": "MIT",
8+
"author": "Anthropic, PBC (https://anthropic.com)",
9+
"homepage": "https://modelcontextprotocol.io",
10+
"bugs": "https://github.com/modelcontextprotocol/typescript-sdk/issues",
11+
"type": "module",
12+
"repository": {
13+
"type": "git",
14+
"url": "git+https://github.com/modelcontextprotocol/typescript-sdk.git"
15+
},
16+
"engines": {
17+
"node": ">=20"
18+
},
19+
"keywords": [
20+
"modelcontextprotocol",
21+
"mcp",
22+
"oauth",
23+
"express",
24+
"legacy"
25+
],
26+
"types": "./dist/index.d.mts",
27+
"exports": {
28+
".": {
29+
"types": "./dist/index.d.mts",
30+
"import": "./dist/index.mjs"
31+
}
32+
},
33+
"files": [
34+
"dist"
35+
],
36+
"scripts": {
37+
"typecheck": "tsgo -p tsconfig.json --noEmit",
38+
"build": "tsdown",
39+
"build:watch": "tsdown --watch",
40+
"prepack": "npm run build",
41+
"lint": "eslint src/ && prettier --ignore-path ../../.prettierignore --check .",
42+
"lint:fix": "eslint src/ --fix && prettier --ignore-path ../../.prettierignore --write .",
43+
"check": "pnpm run typecheck && pnpm run lint",
44+
"test": "vitest run",
45+
"test:watch": "vitest"
46+
},
47+
"dependencies": {
48+
"cors": "catalog:runtimeServerOnly",
49+
"express-rate-limit": "^8.2.1",
50+
"pkce-challenge": "catalog:runtimeShared",
51+
"zod": "catalog:runtimeShared"
52+
},
53+
"peerDependencies": {
54+
"express": "catalog:runtimeServerOnly"
55+
},
56+
"devDependencies": {
57+
"@modelcontextprotocol/core": "workspace:^",
58+
"@modelcontextprotocol/tsconfig": "workspace:^",
59+
"@modelcontextprotocol/vitest-config": "workspace:^",
60+
"@modelcontextprotocol/eslint-config": "workspace:^",
61+
"@eslint/js": "catalog:devTools",
62+
"@types/cors": "catalog:devTools",
63+
"@types/express": "catalog:devTools",
64+
"@types/express-serve-static-core": "catalog:devTools",
65+
"@types/supertest": "catalog:devTools",
66+
"@typescript/native-preview": "catalog:devTools",
67+
"eslint": "catalog:devTools",
68+
"eslint-config-prettier": "catalog:devTools",
69+
"eslint-plugin-n": "catalog:devTools",
70+
"express": "catalog:runtimeServerOnly",
71+
"prettier": "catalog:devTools",
72+
"supertest": "catalog:devTools",
73+
"tsdown": "catalog:devTools",
74+
"typescript": "catalog:devTools",
75+
"typescript-eslint": "catalog:devTools",
76+
"vitest": "catalog:devTools"
77+
}
78+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { OAuthClientInformationFull } from '@modelcontextprotocol/core';
2+
3+
/**
4+
* Stores information about registered OAuth clients for this server.
5+
*/
6+
export interface OAuthRegisteredClientsStore {
7+
/**
8+
* Returns information about a registered client, based on its ID.
9+
*/
10+
getClient(clientId: string): OAuthClientInformationFull | undefined | Promise<OAuthClientInformationFull | undefined>;
11+
12+
/**
13+
* Registers a new client with the server. The client ID and secret will be automatically generated by the library. A modified version of the client information can be returned to reflect specific values enforced by the server.
14+
*
15+
* NOTE: Implementations should NOT delete expired client secrets in-place. Auth middleware provided by this library will automatically check the `client_secret_expires_at` field and reject requests with expired secrets. Any custom logic for authenticating clients should check the `client_secret_expires_at` field as well.
16+
*
17+
* If unimplemented, dynamic client registration is unsupported.
18+
*/
19+
registerClient?(
20+
client: Omit<OAuthClientInformationFull, 'client_id' | 'client_id_issued_at'>
21+
): OAuthClientInformationFull | Promise<OAuthClientInformationFull>;
22+
}

0 commit comments

Comments
 (0)