@@ -4,38 +4,43 @@ import { tokenHandler, TokenHandlerOptions } from "./handlers/token.js";
4
4
import { authorizationHandler , AuthorizationHandlerOptions } from "./handlers/authorize.js" ;
5
5
import { revocationHandler , RevocationHandlerOptions } from "./handlers/revoke.js" ;
6
6
import { metadataHandler } from "./handlers/metadata.js" ;
7
+ import { OAuthServerProvider } from "./provider.js" ;
7
8
8
- export type MetadataOptions = {
9
- metadata : {
10
- /**
11
- * The authorization server's issuer identifier, which is a URL that uses the "https" scheme and has no query or fragment components.
12
- */
13
- issuerUrl : URL ;
14
-
15
- /**
16
- * An optional URL of a page containing human-readable information that developers might want or need to know when using the authorization server.
17
- */
18
- serviceDocumentationUrl ?: URL ;
19
- } ;
20
- } ;
9
+ export type AuthRouterOptions = {
10
+ /**
11
+ * A provider implementing the actual authorization logic for this router.
12
+ */
13
+ provider : OAuthServerProvider ;
14
+
15
+ /**
16
+ * The authorization server's issuer identifier, which is a URL that uses the "https" scheme and has no query or fragment components.
17
+ */
18
+ issuerUrl : URL ;
21
19
22
- export type AuthRouterOptions =
23
- & AuthorizationHandlerOptions
24
- & Omit < ClientRegistrationHandlerOptions , "clientsStore" >
25
- & MetadataOptions
26
- & RevocationHandlerOptions
27
- & TokenHandlerOptions ;
20
+ /**
21
+ * An optional URL of a page containing human-readable information that developers might want or need to know when using the authorization server.
22
+ */
23
+ serviceDocumentationUrl ?: URL ;
24
+
25
+ // Individual options per route
26
+ authorizationOptions ?: Omit < AuthorizationHandlerOptions , "provider" > ;
27
+ clientRegistrationOptions ?: Omit < ClientRegistrationHandlerOptions , "clientsStore" > ;
28
+ revocationOptions ?: Omit < RevocationHandlerOptions , "provider" > ;
29
+ tokenOptions ?: Omit < TokenHandlerOptions , "provider" > ;
30
+ } ;
28
31
29
32
/**
30
33
* Installs standard MCP authorization endpoints, including dynamic client registration and token revocation (if supported). Also advertises standard authorization server metadata, for easier discovery of supported configurations by clients.
31
34
*
35
+ * By default, rate limiting is applied to all endpoints to prevent abuse.
36
+ *
32
37
* This router MUST be installed at the application root, like so:
33
38
*
34
39
* const app = express();
35
40
* app.use(mcpAuthRouter(...));
36
41
*/
37
42
export function mcpAuthRouter ( options : AuthRouterOptions ) : RequestHandler {
38
- const issuer = options . metadata . issuerUrl ;
43
+ const issuer = options . issuerUrl ;
39
44
40
45
// Technically RFC 8414 does not permit a localhost HTTPS exemption, but this will be necessary for ease of testing
41
46
if ( issuer . protocol !== "https:" && issuer . hostname !== "localhost" && issuer . hostname !== "127.0.0.1" ) {
@@ -55,7 +60,7 @@ export function mcpAuthRouter(options: AuthRouterOptions): RequestHandler {
55
60
56
61
const metadata = {
57
62
issuer : issuer . href ,
58
- service_documentation : options . metadata . serviceDocumentationUrl ?. href ,
63
+ service_documentation : options . serviceDocumentationUrl ?. href ,
59
64
60
65
authorization_endpoint : new URL ( authorization_endpoint , issuer ) . href ,
61
66
response_types_supported : [ "code" ] ,
@@ -72,16 +77,34 @@ export function mcpAuthRouter(options: AuthRouterOptions): RequestHandler {
72
77
} ;
73
78
74
79
const router = express . Router ( ) ;
75
- router . use ( authorization_endpoint , authorizationHandler ( options ) ) ;
76
- router . use ( token_endpoint , tokenHandler ( options ) ) ;
80
+
81
+ router . use (
82
+ authorization_endpoint ,
83
+ authorizationHandler ( { provider : options . provider , ...options . authorizationOptions } )
84
+ ) ;
85
+
86
+ router . use (
87
+ token_endpoint ,
88
+ tokenHandler ( { provider : options . provider , ...options . tokenOptions } )
89
+ ) ;
90
+
77
91
router . use ( "/.well-known/oauth-authorization-server" , metadataHandler ( metadata ) ) ;
78
92
79
93
if ( registration_endpoint ) {
80
- router . use ( registration_endpoint , clientRegistrationHandler ( { clientsStore : options . provider . clientsStore , ...options } ) ) ;
94
+ router . use (
95
+ registration_endpoint ,
96
+ clientRegistrationHandler ( {
97
+ clientsStore : options . provider . clientsStore ,
98
+ ...options ,
99
+ } )
100
+ ) ;
81
101
}
82
102
83
103
if ( revocation_endpoint ) {
84
- router . use ( revocation_endpoint , revocationHandler ( options ) ) ;
104
+ router . use (
105
+ revocation_endpoint ,
106
+ revocationHandler ( { provider : options . provider , ...options . revocationOptions } )
107
+ ) ;
85
108
}
86
109
87
110
return router ;
0 commit comments