cdk-serverless 3.2.1 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -0
- package/docs/constructs/assets/hierarchy.js +1 -1
- package/docs/constructs/assets/navigation.js +1 -1
- package/docs/constructs/assets/search.js +1 -1
- package/docs/constructs/classes/McpAuth.html +43 -0
- package/docs/constructs/classes/McpCognitoAuth.html +43 -0
- package/docs/constructs/classes/RestApi.html +6 -3
- package/docs/constructs/classes/SingleTableDatastore.html +1 -1
- package/docs/constructs/classes/Workflow.html +1 -1
- package/docs/constructs/hierarchy.html +1 -1
- package/docs/constructs/index.html +112 -1
- package/docs/constructs/interfaces/McpAuthCognitoOptions.html +17 -0
- package/docs/constructs/interfaces/McpAuthFunctions.html +14 -0
- package/docs/constructs/interfaces/McpAuthGenericOptions.html +11 -0
- package/docs/constructs/interfaces/McpAuthOptions.html +33 -0
- package/docs/constructs/interfaces/McpAuthProps.html +43 -0
- package/docs/constructs/interfaces/McpCognitoAuthProps.html +49 -0
- package/docs/constructs/interfaces/RestApiProps.html +24 -6
- package/docs/constructs/modules.html +1 -1
- package/docs/lambda/index.html +112 -1
- package/docs/projen/index.html +112 -1
- package/lib/constructs/index.d.ts +2 -0
- package/lib/constructs/index.js +3 -1
- package/lib/constructs/mcp-auth.d.ts +117 -0
- package/lib/constructs/mcp-auth.js +127 -0
- package/lib/constructs/mcp-cognito-auth.d.ts +110 -0
- package/lib/constructs/mcp-cognito-auth.js +76 -0
- package/lib/constructs/rest-api.d.ts +136 -0
- package/lib/constructs/rest-api.js +159 -1
- package/lib/mcp-auth/config.d.ts +39 -0
- package/lib/mcp-auth/config.js +3 -0
- package/lib/mcp-auth/handlers/authorization-server.d.ts +7 -0
- package/lib/mcp-auth/handlers/authorization-server.js +34 -0
- package/lib/mcp-auth/handlers/authorize.d.ts +8 -0
- package/lib/mcp-auth/handlers/authorize.js +32 -0
- package/lib/mcp-auth/handlers/index.d.ts +7 -0
- package/lib/mcp-auth/handlers/index.js +24 -0
- package/lib/mcp-auth/handlers/protected-resource.d.ts +7 -0
- package/lib/mcp-auth/handlers/protected-resource.js +26 -0
- package/lib/mcp-auth/handlers/register.d.ts +7 -0
- package/lib/mcp-auth/handlers/register.js +68 -0
- package/lib/mcp-auth/handlers/token.d.ts +8 -0
- package/lib/mcp-auth/handlers/token.js +74 -0
- package/lib/mcp-auth/handlers/types.d.ts +21 -0
- package/lib/mcp-auth/handlers/types.js +3 -0
- package/lib/mcp-auth/handlers/validate-redirect-uris.d.ts +10 -0
- package/lib/mcp-auth/handlers/validate-redirect-uris.js +22 -0
- package/lib/mcp-auth/index.d.ts +3 -0
- package/lib/mcp-auth/index.js +20 -0
- package/lib/mcp-auth/lambda-handlers/authorization-server.handler.d.ts +2 -0
- package/lib/mcp-auth/lambda-handlers/authorization-server.handler.js +23 -0
- package/lib/mcp-auth/lambda-handlers/authorize.handler.d.ts +2 -0
- package/lib/mcp-auth/lambda-handlers/authorize.handler.js +23 -0
- package/lib/mcp-auth/lambda-handlers/env-config.d.ts +7 -0
- package/lib/mcp-auth/lambda-handlers/env-config.js +37 -0
- package/lib/mcp-auth/lambda-handlers/protected-resource.handler.d.ts +2 -0
- package/lib/mcp-auth/lambda-handlers/protected-resource.handler.js +23 -0
- package/lib/mcp-auth/lambda-handlers/register.handler.d.ts +2 -0
- package/lib/mcp-auth/lambda-handlers/register.handler.js +23 -0
- package/lib/mcp-auth/lambda-handlers/token.handler.d.ts +2 -0
- package/lib/mcp-auth/lambda-handlers/token.handler.js +23 -0
- package/lib/mcp-auth/mcp/errors.d.ts +8 -0
- package/lib/mcp-auth/mcp/errors.js +20 -0
- package/lib/mcp-auth/mcp/index.d.ts +4 -0
- package/lib/mcp-auth/mcp/index.js +21 -0
- package/lib/mcp-auth/mcp/jsonrpc.d.ts +21 -0
- package/lib/mcp-auth/mcp/jsonrpc.js +56 -0
- package/lib/mcp-auth/mcp/server.d.ts +9 -0
- package/lib/mcp-auth/mcp/server.js +107 -0
- package/lib/mcp-auth/mcp/types.d.ts +32 -0
- package/lib/mcp-auth/mcp/types.js +3 -0
- package/llm.md +214 -0
- package/package.json +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.McpAuth = void 0;
|
|
37
|
+
const path = __importStar(require("node:path"));
|
|
38
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
39
|
+
const constructs_1 = require("constructs");
|
|
40
|
+
const func_1 = require("./func");
|
|
41
|
+
/**
|
|
42
|
+
* CDK construct that creates Lambda functions for the MCP OAuth façade.
|
|
43
|
+
* Service-agnostic — proxies authorize/token requests to any upstream
|
|
44
|
+
* OAuth2/OIDC provider.
|
|
45
|
+
*
|
|
46
|
+
* Use with `RestApi` by passing `mcpAuth` prop, which auto-injects the
|
|
47
|
+
* required paths into the OpenAPI spec and wires Lambda integrations.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const mcpAuth = new McpAuth(this, 'McpAuth', {
|
|
51
|
+
* apiDomain: 'api.example.com',
|
|
52
|
+
* authorizeEndpoint: 'https://auth.example.com/oauth2/authorize',
|
|
53
|
+
* tokenEndpoint: 'https://auth.example.com/oauth2/token',
|
|
54
|
+
* allowedRedirectUris: ['https://claude.ai/oauth/callback'],
|
|
55
|
+
* clientId: 'my-client-id',
|
|
56
|
+
* serverInfo: { name: 'my-mcp-server', version: '1.0.0' },
|
|
57
|
+
* stageName: 'dev',
|
|
58
|
+
* });
|
|
59
|
+
*/
|
|
60
|
+
class McpAuth extends constructs_1.Construct {
|
|
61
|
+
constructor(scope, id, props) {
|
|
62
|
+
super(scope, id);
|
|
63
|
+
const env = {
|
|
64
|
+
MCP_API_DOMAIN: props.apiDomain,
|
|
65
|
+
MCP_AUTHORIZE_ENDPOINT: props.authorizeEndpoint,
|
|
66
|
+
MCP_TOKEN_ENDPOINT: props.tokenEndpoint,
|
|
67
|
+
MCP_CLIENT_ID: props.clientId,
|
|
68
|
+
MCP_SERVER_NAME: props.serverInfo.name,
|
|
69
|
+
MCP_SERVER_VERSION: props.serverInfo.version,
|
|
70
|
+
MCP_PROTOCOL_VERSIONS: (props.protocolVersions ?? ['2025-11-25', '2025-03-26', '2024-11-05']).join(','),
|
|
71
|
+
MCP_SCOPES: (props.scopes ?? ['openid', 'email', 'profile']).join(','),
|
|
72
|
+
MCP_ALLOWED_REDIRECT_URIS: props.allowedRedirectUris.join(','),
|
|
73
|
+
MCP_STRIP_PARAMETERS: (props.stripParameters ?? ['resource']).join(','),
|
|
74
|
+
...props.additionalEnv,
|
|
75
|
+
};
|
|
76
|
+
this.mcpEnvVars = env;
|
|
77
|
+
const handlersDir = path.join(__dirname, '..', 'mcp-auth', 'lambda-handlers');
|
|
78
|
+
const baseLambdaOptions = {
|
|
79
|
+
timeout: aws_cdk_lib_1.Duration.seconds(15),
|
|
80
|
+
...props.lambdaOptions,
|
|
81
|
+
};
|
|
82
|
+
const protectedResource = new func_1.LambdaFunction(this, 'ProtectedResourceFn', {
|
|
83
|
+
stageName: props.stageName,
|
|
84
|
+
entry: path.join(handlersDir, 'protected-resource.handler.js'),
|
|
85
|
+
description: `[${props.stageName}] MCP OAuth Protected Resource`,
|
|
86
|
+
additionalEnv: env,
|
|
87
|
+
lambdaOptions: baseLambdaOptions,
|
|
88
|
+
});
|
|
89
|
+
const authorizationServer = new func_1.LambdaFunction(this, 'AuthorizationServerFn', {
|
|
90
|
+
stageName: props.stageName,
|
|
91
|
+
entry: path.join(handlersDir, 'authorization-server.handler.js'),
|
|
92
|
+
description: `[${props.stageName}] MCP OAuth Authorization Server`,
|
|
93
|
+
additionalEnv: env,
|
|
94
|
+
lambdaOptions: baseLambdaOptions,
|
|
95
|
+
});
|
|
96
|
+
const authorize = new func_1.LambdaFunction(this, 'AuthorizeFn', {
|
|
97
|
+
stageName: props.stageName,
|
|
98
|
+
entry: path.join(handlersDir, 'authorize.handler.js'),
|
|
99
|
+
description: `[${props.stageName}] MCP OAuth Authorize Proxy`,
|
|
100
|
+
additionalEnv: env,
|
|
101
|
+
lambdaOptions: baseLambdaOptions,
|
|
102
|
+
});
|
|
103
|
+
const token = new func_1.LambdaFunction(this, 'TokenFn', {
|
|
104
|
+
stageName: props.stageName,
|
|
105
|
+
entry: path.join(handlersDir, 'token.handler.js'),
|
|
106
|
+
description: `[${props.stageName}] MCP OAuth Token Proxy`,
|
|
107
|
+
additionalEnv: env,
|
|
108
|
+
lambdaOptions: baseLambdaOptions,
|
|
109
|
+
});
|
|
110
|
+
const register = new func_1.LambdaFunction(this, 'RegisterFn', {
|
|
111
|
+
stageName: props.stageName,
|
|
112
|
+
entry: path.join(handlersDir, 'register.handler.js'),
|
|
113
|
+
description: `[${props.stageName}] MCP OAuth Register`,
|
|
114
|
+
additionalEnv: env,
|
|
115
|
+
lambdaOptions: baseLambdaOptions,
|
|
116
|
+
});
|
|
117
|
+
this.functions = {
|
|
118
|
+
protectedResource,
|
|
119
|
+
authorizationServer,
|
|
120
|
+
authorize,
|
|
121
|
+
token,
|
|
122
|
+
register,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.McpAuth = McpAuth;
|
|
127
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLWF1dGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9tY3AtYXV0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnREFBa0M7QUFDbEMsNkNBQXVDO0FBQ3ZDLDJDQUF1QztBQUN2QyxpQ0FBdUQ7QUFnR3ZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxNQUFhLE9BQVEsU0FBUSxzQkFBUztJQWFwQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW1CO1FBQzNELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxHQUFHLEdBQTJCO1lBQ2xDLGNBQWMsRUFBRSxLQUFLLENBQUMsU0FBUztZQUMvQixzQkFBc0IsRUFBRSxLQUFLLENBQUMsaUJBQWlCO1lBQy9DLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ3ZDLGFBQWEsRUFBRSxLQUFLLENBQUMsUUFBUTtZQUM3QixlQUFlLEVBQUUsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJO1lBQ3RDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsT0FBTztZQUM1QyxxQkFBcUIsRUFBRSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ3ZHLFVBQVUsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUN0RSx5QkFBeUIsRUFBRSxLQUFLLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUM5RCxvQkFBb0IsRUFBRSxDQUFDLEtBQUssQ0FBQyxlQUFlLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7WUFDdkUsR0FBRyxLQUFLLENBQUMsYUFBYTtTQUN2QixDQUFDO1FBRUYsSUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUM7UUFFdEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBRTlFLE1BQU0saUJBQWlCLEdBQWtCO1lBQ3ZDLE9BQU8sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDN0IsR0FBRyxLQUFLLENBQUMsYUFBYTtTQUN2QixDQUFDO1FBRUYsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLHFCQUFjLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFO1lBQ3hFLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztZQUMxQixLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsK0JBQStCLENBQUM7WUFDOUQsV0FBVyxFQUFFLElBQUksS0FBSyxDQUFDLFNBQVMsZ0NBQWdDO1lBQ2hFLGFBQWEsRUFBRSxHQUFHO1lBQ2xCLGFBQWEsRUFBRSxpQkFBaUI7U0FDakMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLHFCQUFjLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQzVFLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztZQUMxQixLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsaUNBQWlDLENBQUM7WUFDaEUsV0FBVyxFQUFFLElBQUksS0FBSyxDQUFDLFNBQVMsa0NBQWtDO1lBQ2xFLGFBQWEsRUFBRSxHQUFHO1lBQ2xCLGFBQWEsRUFBRSxpQkFBaUI7U0FDakMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxTQUFTLEdBQUcsSUFBSSxxQkFBYyxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUU7WUFDeEQsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1lBQzFCLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxzQkFBc0IsQ0FBQztZQUNyRCxXQUFXLEVBQUUsSUFBSSxLQUFLLENBQUMsU0FBUyw2QkFBNkI7WUFDN0QsYUFBYSxFQUFFLEdBQUc7WUFDbEIsYUFBYSxFQUFFLGlCQUFpQjtTQUNqQyxDQUFDLENBQUM7UUFFSCxNQUFNLEtBQUssR0FBRyxJQUFJLHFCQUFjLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUNoRCxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7WUFDMUIsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLGtCQUFrQixDQUFDO1lBQ2pELFdBQVcsRUFBRSxJQUFJLEtBQUssQ0FBQyxTQUFTLHlCQUF5QjtZQUN6RCxhQUFhLEVBQUUsR0FBRztZQUNsQixhQUFhLEVBQUUsaUJBQWlCO1NBQ2pDLENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLElBQUkscUJBQWMsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO1lBQ3RELFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztZQUMxQixLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUscUJBQXFCLENBQUM7WUFDcEQsV0FBVyxFQUFFLElBQUksS0FBSyxDQUFDLFNBQVMsc0JBQXNCO1lBQ3RELGFBQWEsRUFBRSxHQUFHO1lBQ2xCLGFBQWEsRUFBRSxpQkFBaUI7U0FDakMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNmLGlCQUFpQjtZQUNqQixtQkFBbUI7WUFDbkIsU0FBUztZQUNULEtBQUs7WUFDTCxRQUFRO1NBQ1QsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXZGRCwwQkF1RkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgTGFtYmRhRnVuY3Rpb24sIExhbWJkYU9wdGlvbnMgfSBmcm9tICcuL2Z1bmMnO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBNQ1AgQXV0aCBDREsgY29uc3RydWN0LlxuICogU2VydmljZS1hZ25vc3RpYzogd29ya3Mgd2l0aCBhbnkgT0F1dGgyL09JREMgcHJvdmlkZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWNwQXV0aFByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBBUEkgZG9tYWluIHRoYXQgYWN0cyBhcyB0aGUgTUNQIE9BdXRoIGlzc3Vlci5cbiAgICogQWxsIE9BdXRoIGRpc2NvdmVyeSBlbmRwb2ludHMgd2lsbCByZWZlcmVuY2UgdGhpcyBkb21haW4uXG4gICAqIEV4YW1wbGU6ICdhcGkuZXhhbXBsZS5jb20nXG4gICAqL1xuICByZWFkb25seSBhcGlEb21haW46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHVwc3RyZWFtIE9BdXRoIGF1dGhvcml6ZSBlbmRwb2ludCBVUkwuXG4gICAqIFRoZSBhdXRob3JpemUgTGFtYmRhIHByb3hpZXMgKDMwMiByZWRpcmVjdHMpIHRvIHRoaXMgVVJMLlxuICAgKiBFeGFtcGxlOiAnaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tL29hdXRoMi9hdXRob3JpemUnXG4gICAqL1xuICByZWFkb25seSBhdXRob3JpemVFbmRwb2ludDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdXBzdHJlYW0gT0F1dGggdG9rZW4gZW5kcG9pbnQgVVJMLlxuICAgKiBUaGUgdG9rZW4gTGFtYmRhIHByb3hpZXMgUE9TVCByZXF1ZXN0cyB0byB0aGlzIFVSTC5cbiAgICogRXhhbXBsZTogJ2h0dHBzOi8vYXV0aC5leGFtcGxlLmNvbS9vYXV0aDIvdG9rZW4nXG4gICAqL1xuICByZWFkb25seSB0b2tlbkVuZHBvaW50OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFsbG93ZWQgcmVkaXJlY3QgVVJJcyBmb3IgZHluYW1pYyBjbGllbnQgcmVnaXN0cmF0aW9uLlxuICAgKiBDbGllbnRzIHJlZ2lzdGVyaW5nIHdpdGggVVJJcyBub3QgaW4gdGhpcyBsaXN0IGFyZSByZWplY3RlZC5cbiAgICovXG4gIHJlYWRvbmx5IGFsbG93ZWRSZWRpcmVjdFVyaXM6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgcHJlLXByb3Zpc2lvbmVkIE9BdXRoIGNsaWVudCBJRCByZXR1cm5lZCBieSB0aGUgcmVnaXN0ZXIgZW5kcG9pbnQuXG4gICAqL1xuICByZWFkb25seSBjbGllbnRJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBNQ1Agc2VydmVyIGluZm8gcmV0dXJuZWQgaW4gdGhlICdpbml0aWFsaXplJyByZXNwb25zZS5cbiAgICovXG4gIHJlYWRvbmx5IHNlcnZlckluZm86IHsgcmVhZG9ubHkgbmFtZTogc3RyaW5nOyByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmcgfTtcblxuICAvKipcbiAgICogU3VwcG9ydGVkIE1DUCBwcm90b2NvbCB2ZXJzaW9ucyAobmV3ZXN0IGZpcnN0KS5cbiAgICogQGRlZmF1bHQgWycyMDI1LTExLTI1JywgJzIwMjUtMDMtMjYnLCAnMjAyNC0xMS0wNSddXG4gICAqL1xuICByZWFkb25seSBwcm90b2NvbFZlcnNpb25zPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIE9BdXRoIHNjb3BlcyB0byBhZHZlcnRpc2UgaW4gZGlzY292ZXJ5IG1ldGFkYXRhLlxuICAgKiBAZGVmYXVsdCBbJ29wZW5pZCcsICdlbWFpbCcsICdwcm9maWxlJ11cbiAgICovXG4gIHJlYWRvbmx5IHNjb3Blcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBQYXJhbWV0ZXJzIHRvIHN0cmlwIGZyb20gYXV0aG9yaXplL3Rva2VuIHByb3h5IHJlcXVlc3RzLlxuICAgKiBAZGVmYXVsdCBbJ3Jlc291cmNlJ11cbiAgICovXG4gIHJlYWRvbmx5IHN0cmlwUGFyYW1ldGVycz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byBpbmplY3QgaW50byBhbGwgTUNQIGF1dGggTGFtYmRhIGZ1bmN0aW9ucy5cbiAgICovXG4gIHJlYWRvbmx5IGFkZGl0aW9uYWxFbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBMYW1iZGEgZnVuY3Rpb24gb3B0aW9ucyBmb3IgTUNQIGF1dGggaGFuZGxlcnMuXG4gICAqL1xuICByZWFkb25seSBsYW1iZGFPcHRpb25zPzogTGFtYmRhT3B0aW9ucztcblxuICAvKipcbiAgICogU3RhZ2UgbmFtZSBmb3IgZnVuY3Rpb24gbmFtaW5nIGFuZCB0YWdnaW5nLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhZ2VOYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIExhbWJkYSBmdW5jdGlvbiByZWZlcmVuY2VzIGZvciBNQ1AgT0F1dGggZW5kcG9pbnRzLlxuICogVGhlc2UgY2FuIGJlIHdpcmVkIGludG8gQVBJIEdhdGV3YXkgKHZpYSBSZXN0QXBpIGludGVncmF0aW9uKVxuICogb3IgdXNlZCBzdGFuZGFsb25lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1jcEF1dGhGdW5jdGlvbnMge1xuICAvKiogR0VUIC8ud2VsbC1rbm93bi9vYXV0aC1wcm90ZWN0ZWQtcmVzb3VyY2UgKi9cbiAgcmVhZG9ubHkgcHJvdGVjdGVkUmVzb3VyY2U6IExhbWJkYUZ1bmN0aW9uO1xuICAvKiogR0VUIC8ud2VsbC1rbm93bi9vYXV0aC1hdXRob3JpemF0aW9uLXNlcnZlciAqL1xuICByZWFkb25seSBhdXRob3JpemF0aW9uU2VydmVyOiBMYW1iZGFGdW5jdGlvbjtcbiAgLyoqIEdFVCAvb2F1dGgvYXV0aG9yaXplICovXG4gIHJlYWRvbmx5IGF1dGhvcml6ZTogTGFtYmRhRnVuY3Rpb247XG4gIC8qKiBQT1NUIC9vYXV0aC90b2tlbiAqL1xuICByZWFkb25seSB0b2tlbjogTGFtYmRhRnVuY3Rpb247XG4gIC8qKiBQT1NUIC9vYXV0aC9yZWdpc3RlciAqL1xuICByZWFkb25seSByZWdpc3RlcjogTGFtYmRhRnVuY3Rpb247XG59XG5cbi8qKlxuICogQ0RLIGNvbnN0cnVjdCB0aGF0IGNyZWF0ZXMgTGFtYmRhIGZ1bmN0aW9ucyBmb3IgdGhlIE1DUCBPQXV0aCBmYcOnYWRlLlxuICogU2VydmljZS1hZ25vc3RpYyDigJQgcHJveGllcyBhdXRob3JpemUvdG9rZW4gcmVxdWVzdHMgdG8gYW55IHVwc3RyZWFtXG4gKiBPQXV0aDIvT0lEQyBwcm92aWRlci5cbiAqXG4gKiBVc2Ugd2l0aCBgUmVzdEFwaWAgYnkgcGFzc2luZyBgbWNwQXV0aGAgcHJvcCwgd2hpY2ggYXV0by1pbmplY3RzIHRoZVxuICogcmVxdWlyZWQgcGF0aHMgaW50byB0aGUgT3BlbkFQSSBzcGVjIGFuZCB3aXJlcyBMYW1iZGEgaW50ZWdyYXRpb25zLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtY3BBdXRoID0gbmV3IE1jcEF1dGgodGhpcywgJ01jcEF1dGgnLCB7XG4gKiAgIGFwaURvbWFpbjogJ2FwaS5leGFtcGxlLmNvbScsXG4gKiAgIGF1dGhvcml6ZUVuZHBvaW50OiAnaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tL29hdXRoMi9hdXRob3JpemUnLFxuICogICB0b2tlbkVuZHBvaW50OiAnaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tL29hdXRoMi90b2tlbicsXG4gKiAgIGFsbG93ZWRSZWRpcmVjdFVyaXM6IFsnaHR0cHM6Ly9jbGF1ZGUuYWkvb2F1dGgvY2FsbGJhY2snXSxcbiAqICAgY2xpZW50SWQ6ICdteS1jbGllbnQtaWQnLFxuICogICBzZXJ2ZXJJbmZvOiB7IG5hbWU6ICdteS1tY3Atc2VydmVyJywgdmVyc2lvbjogJzEuMC4wJyB9LFxuICogICBzdGFnZU5hbWU6ICdkZXYnLFxuICogfSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBNY3BBdXRoIGV4dGVuZHMgQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogVGhlIExhbWJkYSBmdW5jdGlvbnMgY3JlYXRlZCBmb3IgdGhlIE9BdXRoIGVuZHBvaW50cy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbnM6IE1jcEF1dGhGdW5jdGlvbnM7XG5cbiAgLyoqXG4gICAqIFRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgbWFwIHRoYXQgc2hvdWxkIGJlIGluamVjdGVkIGludG8gdGhlIE1DUCBSUENcbiAgICogaGFuZGxlciBMYW1iZGEgKGlmIHlvdSBoYXZlIG9uZSkgc28gaXQgY2FuIHJlYWQgTUNQIGNvbmZpZyBhdCBydW50aW1lLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1jcEVudlZhcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE1jcEF1dGhQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICBNQ1BfQVBJX0RPTUFJTjogcHJvcHMuYXBpRG9tYWluLFxuICAgICAgTUNQX0FVVEhPUklaRV9FTkRQT0lOVDogcHJvcHMuYXV0aG9yaXplRW5kcG9pbnQsXG4gICAgICBNQ1BfVE9LRU5fRU5EUE9JTlQ6IHByb3BzLnRva2VuRW5kcG9pbnQsXG4gICAgICBNQ1BfQ0xJRU5UX0lEOiBwcm9wcy5jbGllbnRJZCxcbiAgICAgIE1DUF9TRVJWRVJfTkFNRTogcHJvcHMuc2VydmVySW5mby5uYW1lLFxuICAgICAgTUNQX1NFUlZFUl9WRVJTSU9OOiBwcm9wcy5zZXJ2ZXJJbmZvLnZlcnNpb24sXG4gICAgICBNQ1BfUFJPVE9DT0xfVkVSU0lPTlM6IChwcm9wcy5wcm90b2NvbFZlcnNpb25zID8/IFsnMjAyNS0xMS0yNScsICcyMDI1LTAzLTI2JywgJzIwMjQtMTEtMDUnXSkuam9pbignLCcpLFxuICAgICAgTUNQX1NDT1BFUzogKHByb3BzLnNjb3BlcyA/PyBbJ29wZW5pZCcsICdlbWFpbCcsICdwcm9maWxlJ10pLmpvaW4oJywnKSxcbiAgICAgIE1DUF9BTExPV0VEX1JFRElSRUNUX1VSSVM6IHByb3BzLmFsbG93ZWRSZWRpcmVjdFVyaXMuam9pbignLCcpLFxuICAgICAgTUNQX1NUUklQX1BBUkFNRVRFUlM6IChwcm9wcy5zdHJpcFBhcmFtZXRlcnMgPz8gWydyZXNvdXJjZSddKS5qb2luKCcsJyksXG4gICAgICAuLi5wcm9wcy5hZGRpdGlvbmFsRW52LFxuICAgIH07XG5cbiAgICB0aGlzLm1jcEVudlZhcnMgPSBlbnY7XG5cbiAgICBjb25zdCBoYW5kbGVyc0RpciA9IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICdtY3AtYXV0aCcsICdsYW1iZGEtaGFuZGxlcnMnKTtcblxuICAgIGNvbnN0IGJhc2VMYW1iZGFPcHRpb25zOiBMYW1iZGFPcHRpb25zID0ge1xuICAgICAgdGltZW91dDogRHVyYXRpb24uc2Vjb25kcygxNSksXG4gICAgICAuLi5wcm9wcy5sYW1iZGFPcHRpb25zLFxuICAgIH07XG5cbiAgICBjb25zdCBwcm90ZWN0ZWRSZXNvdXJjZSA9IG5ldyBMYW1iZGFGdW5jdGlvbih0aGlzLCAnUHJvdGVjdGVkUmVzb3VyY2VGbicsIHtcbiAgICAgIHN0YWdlTmFtZTogcHJvcHMuc3RhZ2VOYW1lLFxuICAgICAgZW50cnk6IHBhdGguam9pbihoYW5kbGVyc0RpciwgJ3Byb3RlY3RlZC1yZXNvdXJjZS5oYW5kbGVyLmpzJyksXG4gICAgICBkZXNjcmlwdGlvbjogYFske3Byb3BzLnN0YWdlTmFtZX1dIE1DUCBPQXV0aCBQcm90ZWN0ZWQgUmVzb3VyY2VgLFxuICAgICAgYWRkaXRpb25hbEVudjogZW52LFxuICAgICAgbGFtYmRhT3B0aW9uczogYmFzZUxhbWJkYU9wdGlvbnMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBhdXRob3JpemF0aW9uU2VydmVyID0gbmV3IExhbWJkYUZ1bmN0aW9uKHRoaXMsICdBdXRob3JpemF0aW9uU2VydmVyRm4nLCB7XG4gICAgICBzdGFnZU5hbWU6IHByb3BzLnN0YWdlTmFtZSxcbiAgICAgIGVudHJ5OiBwYXRoLmpvaW4oaGFuZGxlcnNEaXIsICdhdXRob3JpemF0aW9uLXNlcnZlci5oYW5kbGVyLmpzJyksXG4gICAgICBkZXNjcmlwdGlvbjogYFske3Byb3BzLnN0YWdlTmFtZX1dIE1DUCBPQXV0aCBBdXRob3JpemF0aW9uIFNlcnZlcmAsXG4gICAgICBhZGRpdGlvbmFsRW52OiBlbnYsXG4gICAgICBsYW1iZGFPcHRpb25zOiBiYXNlTGFtYmRhT3B0aW9ucyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGF1dGhvcml6ZSA9IG5ldyBMYW1iZGFGdW5jdGlvbih0aGlzLCAnQXV0aG9yaXplRm4nLCB7XG4gICAgICBzdGFnZU5hbWU6IHByb3BzLnN0YWdlTmFtZSxcbiAgICAgIGVudHJ5OiBwYXRoLmpvaW4oaGFuZGxlcnNEaXIsICdhdXRob3JpemUuaGFuZGxlci5qcycpLFxuICAgICAgZGVzY3JpcHRpb246IGBbJHtwcm9wcy5zdGFnZU5hbWV9XSBNQ1AgT0F1dGggQXV0aG9yaXplIFByb3h5YCxcbiAgICAgIGFkZGl0aW9uYWxFbnY6IGVudixcbiAgICAgIGxhbWJkYU9wdGlvbnM6IGJhc2VMYW1iZGFPcHRpb25zLFxuICAgIH0pO1xuXG4gICAgY29uc3QgdG9rZW4gPSBuZXcgTGFtYmRhRnVuY3Rpb24odGhpcywgJ1Rva2VuRm4nLCB7XG4gICAgICBzdGFnZU5hbWU6IHByb3BzLnN0YWdlTmFtZSxcbiAgICAgIGVudHJ5OiBwYXRoLmpvaW4oaGFuZGxlcnNEaXIsICd0b2tlbi5oYW5kbGVyLmpzJyksXG4gICAgICBkZXNjcmlwdGlvbjogYFske3Byb3BzLnN0YWdlTmFtZX1dIE1DUCBPQXV0aCBUb2tlbiBQcm94eWAsXG4gICAgICBhZGRpdGlvbmFsRW52OiBlbnYsXG4gICAgICBsYW1iZGFPcHRpb25zOiBiYXNlTGFtYmRhT3B0aW9ucyxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlZ2lzdGVyID0gbmV3IExhbWJkYUZ1bmN0aW9uKHRoaXMsICdSZWdpc3RlckZuJywge1xuICAgICAgc3RhZ2VOYW1lOiBwcm9wcy5zdGFnZU5hbWUsXG4gICAgICBlbnRyeTogcGF0aC5qb2luKGhhbmRsZXJzRGlyLCAncmVnaXN0ZXIuaGFuZGxlci5qcycpLFxuICAgICAgZGVzY3JpcHRpb246IGBbJHtwcm9wcy5zdGFnZU5hbWV9XSBNQ1AgT0F1dGggUmVnaXN0ZXJgLFxuICAgICAgYWRkaXRpb25hbEVudjogZW52LFxuICAgICAgbGFtYmRhT3B0aW9uczogYmFzZUxhbWJkYU9wdGlvbnMsXG4gICAgfSk7XG5cbiAgICB0aGlzLmZ1bmN0aW9ucyA9IHtcbiAgICAgIHByb3RlY3RlZFJlc291cmNlLFxuICAgICAgYXV0aG9yaXphdGlvblNlcnZlcixcbiAgICAgIGF1dGhvcml6ZSxcbiAgICAgIHRva2VuLFxuICAgICAgcmVnaXN0ZXIsXG4gICAgfTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { aws_cognito } from 'aws-cdk-lib';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { CognitoAuthentication } from './authentication';
|
|
4
|
+
import { LambdaOptions } from './func';
|
|
5
|
+
import { McpAuth } from './mcp-auth';
|
|
6
|
+
/**
|
|
7
|
+
* Props for creating an McpAuth backed by a Cognito User Pool.
|
|
8
|
+
* This is a convenience wrapper — use McpAuth directly for non-Cognito providers.
|
|
9
|
+
*/
|
|
10
|
+
export interface McpCognitoAuthProps {
|
|
11
|
+
/**
|
|
12
|
+
* The CognitoAuthentication construct that manages the user pool.
|
|
13
|
+
* A dedicated user pool client will be created for MCP connectors.
|
|
14
|
+
*/
|
|
15
|
+
readonly auth: CognitoAuthentication;
|
|
16
|
+
/**
|
|
17
|
+
* The API domain that acts as the MCP OAuth issuer.
|
|
18
|
+
* All discovery endpoints will reference this domain.
|
|
19
|
+
* Example: 'api.example.com'
|
|
20
|
+
*/
|
|
21
|
+
readonly apiDomain: string;
|
|
22
|
+
/**
|
|
23
|
+
* The Cognito auth domain (custom domain or Cognito-hosted domain).
|
|
24
|
+
* Authorize and token requests are proxied here.
|
|
25
|
+
* Example: 'auth.example.com' or 'myapp.auth.eu-central-1.amazoncognito.com'
|
|
26
|
+
*/
|
|
27
|
+
readonly authDomain: string;
|
|
28
|
+
/**
|
|
29
|
+
* Allowed redirect URIs for dynamic client registration.
|
|
30
|
+
* @default ['https://claude.ai/oauth/callback', 'https://claude.ai/api/mcp/auth_callback', 'https://chatgpt.com/oauth/callback']
|
|
31
|
+
*/
|
|
32
|
+
readonly allowedRedirectUris?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* MCP server info returned in the 'initialize' response.
|
|
35
|
+
*/
|
|
36
|
+
readonly serverInfo: {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly version: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Supported MCP protocol versions (newest first).
|
|
42
|
+
* @default ['2025-11-25', '2025-03-26', '2024-11-05']
|
|
43
|
+
*/
|
|
44
|
+
readonly protocolVersions?: string[];
|
|
45
|
+
/**
|
|
46
|
+
* OAuth scopes to advertise in discovery metadata.
|
|
47
|
+
* Note: Do NOT include custom resource server scopes here —
|
|
48
|
+
* Cognito Managed Login v2 requires RFC 8707 resource parameter
|
|
49
|
+
* for custom scopes which MCP clients cannot supply.
|
|
50
|
+
* @default ['openid', 'email', 'profile']
|
|
51
|
+
*/
|
|
52
|
+
readonly scopes?: string[];
|
|
53
|
+
/**
|
|
54
|
+
* Additional environment variables for MCP auth Lambda functions.
|
|
55
|
+
*/
|
|
56
|
+
readonly additionalEnv?: Record<string, string>;
|
|
57
|
+
/**
|
|
58
|
+
* Lambda function options for MCP auth handlers.
|
|
59
|
+
*/
|
|
60
|
+
readonly lambdaOptions?: LambdaOptions;
|
|
61
|
+
/**
|
|
62
|
+
* Stage name for function naming and tagging.
|
|
63
|
+
*/
|
|
64
|
+
readonly stageName: string;
|
|
65
|
+
/**
|
|
66
|
+
* Construct ID for the user pool client (affects CloudFormation logical ID).
|
|
67
|
+
* @default 'mcpConnector'
|
|
68
|
+
*/
|
|
69
|
+
readonly clientConstructId?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Additional OAuth callback URLs to configure on the Cognito client
|
|
72
|
+
* beyond the allowedRedirectUris. Useful if the Cognito client needs
|
|
73
|
+
* URLs that aren't in the MCP registration allowlist.
|
|
74
|
+
*/
|
|
75
|
+
readonly additionalCallbackUrls?: string[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Convenience construct that creates an McpAuth backed by Amazon Cognito.
|
|
79
|
+
*
|
|
80
|
+
* It creates a dedicated Cognito user pool client configured for the
|
|
81
|
+
* authorization code + PKCE flow and wires it into the generic McpAuth
|
|
82
|
+
* construct. Use this when your authentication is managed by Cognito;
|
|
83
|
+
* use McpAuth directly for other OAuth2/OIDC providers.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* const mcpAuth = new McpCognitoAuth(this, 'McpAuth', {
|
|
87
|
+
* auth: cognitoAuthentication,
|
|
88
|
+
* apiDomain: 'api.example.com',
|
|
89
|
+
* authDomain: 'auth.example.com',
|
|
90
|
+
* serverInfo: { name: 'my-mcp-server', version: '1.0.0' },
|
|
91
|
+
* stageName: 'dev',
|
|
92
|
+
* });
|
|
93
|
+
*
|
|
94
|
+
* const api = new MyApiRestApi(this, 'Api', {
|
|
95
|
+
* mcpAuth: mcpAuth.mcpAuth,
|
|
96
|
+
* // ...
|
|
97
|
+
* });
|
|
98
|
+
*/
|
|
99
|
+
export declare class McpCognitoAuth extends Construct {
|
|
100
|
+
/**
|
|
101
|
+
* The underlying service-agnostic McpAuth construct.
|
|
102
|
+
* Pass this to RestApi's `mcpAuth` prop.
|
|
103
|
+
*/
|
|
104
|
+
readonly mcpAuth: McpAuth;
|
|
105
|
+
/**
|
|
106
|
+
* The Cognito user pool client created for MCP connectors.
|
|
107
|
+
*/
|
|
108
|
+
readonly userPoolClient: aws_cognito.UserPoolClient;
|
|
109
|
+
constructor(scope: Construct, id: string, props: McpCognitoAuthProps);
|
|
110
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.McpCognitoAuth = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const constructs_1 = require("constructs");
|
|
6
|
+
const mcp_auth_1 = require("./mcp-auth");
|
|
7
|
+
/**
|
|
8
|
+
* Convenience construct that creates an McpAuth backed by Amazon Cognito.
|
|
9
|
+
*
|
|
10
|
+
* It creates a dedicated Cognito user pool client configured for the
|
|
11
|
+
* authorization code + PKCE flow and wires it into the generic McpAuth
|
|
12
|
+
* construct. Use this when your authentication is managed by Cognito;
|
|
13
|
+
* use McpAuth directly for other OAuth2/OIDC providers.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const mcpAuth = new McpCognitoAuth(this, 'McpAuth', {
|
|
17
|
+
* auth: cognitoAuthentication,
|
|
18
|
+
* apiDomain: 'api.example.com',
|
|
19
|
+
* authDomain: 'auth.example.com',
|
|
20
|
+
* serverInfo: { name: 'my-mcp-server', version: '1.0.0' },
|
|
21
|
+
* stageName: 'dev',
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* const api = new MyApiRestApi(this, 'Api', {
|
|
25
|
+
* mcpAuth: mcpAuth.mcpAuth,
|
|
26
|
+
* // ...
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
class McpCognitoAuth extends constructs_1.Construct {
|
|
30
|
+
constructor(scope, id, props) {
|
|
31
|
+
super(scope, id);
|
|
32
|
+
const clientId = props.clientConstructId ?? 'mcpConnector';
|
|
33
|
+
const allowedRedirectUris = props.allowedRedirectUris ?? [
|
|
34
|
+
'https://claude.ai/oauth/callback',
|
|
35
|
+
'https://claude.ai/api/mcp/auth_callback',
|
|
36
|
+
'https://chatgpt.com/oauth/callback',
|
|
37
|
+
];
|
|
38
|
+
// Create a Cognito user pool client with auth code grant + PKCE
|
|
39
|
+
this.userPoolClient = props.auth.addUserPoolClient(clientId, {
|
|
40
|
+
generateSecret: false,
|
|
41
|
+
oAuth: {
|
|
42
|
+
flows: {
|
|
43
|
+
authorizationCodeGrant: true,
|
|
44
|
+
},
|
|
45
|
+
scopes: [
|
|
46
|
+
aws_cdk_lib_1.aws_cognito.OAuthScope.OPENID,
|
|
47
|
+
aws_cdk_lib_1.aws_cognito.OAuthScope.EMAIL,
|
|
48
|
+
aws_cdk_lib_1.aws_cognito.OAuthScope.PROFILE,
|
|
49
|
+
],
|
|
50
|
+
callbackUrls: [
|
|
51
|
+
...allowedRedirectUris,
|
|
52
|
+
...(props.additionalCallbackUrls ?? []),
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
authFlows: {
|
|
56
|
+
userSrp: true,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
// Create the generic McpAuth, deriving endpoints from authDomain
|
|
60
|
+
this.mcpAuth = new mcp_auth_1.McpAuth(this, 'McpAuth', {
|
|
61
|
+
apiDomain: props.apiDomain,
|
|
62
|
+
authorizeEndpoint: `https://${props.authDomain}/oauth2/authorize`,
|
|
63
|
+
tokenEndpoint: `https://${props.authDomain}/oauth2/token`,
|
|
64
|
+
allowedRedirectUris,
|
|
65
|
+
clientId: this.userPoolClient.userPoolClientId,
|
|
66
|
+
serverInfo: props.serverInfo,
|
|
67
|
+
protocolVersions: props.protocolVersions,
|
|
68
|
+
scopes: props.scopes,
|
|
69
|
+
additionalEnv: props.additionalEnv,
|
|
70
|
+
lambdaOptions: props.lambdaOptions,
|
|
71
|
+
stageName: props.stageName,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.McpCognitoAuth = McpCognitoAuth;
|
|
76
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWNwLWNvZ25pdG8tYXV0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25zdHJ1Y3RzL21jcC1jb2duaXRvLWF1dGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQTBDO0FBQzFDLDJDQUF1QztBQUd2Qyx5Q0FBcUM7QUFrRnJDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFDSCxNQUFhLGNBQWUsU0FBUSxzQkFBUztJQWEzQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTBCO1FBQ2xFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixJQUFJLGNBQWMsQ0FBQztRQUUzRCxNQUFNLG1CQUFtQixHQUFHLEtBQUssQ0FBQyxtQkFBbUIsSUFBSTtZQUN2RCxrQ0FBa0M7WUFDbEMseUNBQXlDO1lBQ3pDLG9DQUFvQztTQUNyQyxDQUFDO1FBRUYsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUU7WUFDM0QsY0FBYyxFQUFFLEtBQUs7WUFDckIsS0FBSyxFQUFFO2dCQUNMLEtBQUssRUFBRTtvQkFDTCxzQkFBc0IsRUFBRSxJQUFJO2lCQUM3QjtnQkFDRCxNQUFNLEVBQUU7b0JBQ04seUJBQVcsQ0FBQyxVQUFVLENBQUMsTUFBTTtvQkFDN0IseUJBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSztvQkFDNUIseUJBQVcsQ0FBQyxVQUFVLENBQUMsT0FBTztpQkFDL0I7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLEdBQUcsbUJBQW1CO29CQUN0QixHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixJQUFJLEVBQUUsQ0FBQztpQkFDeEM7YUFDRjtZQUNELFNBQVMsRUFBRTtnQkFDVCxPQUFPLEVBQUUsSUFBSTthQUNkO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsaUVBQWlFO1FBQ2pFLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDMUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO1lBQzFCLGlCQUFpQixFQUFFLFdBQVcsS0FBSyxDQUFDLFVBQVUsbUJBQW1CO1lBQ2pFLGFBQWEsRUFBRSxXQUFXLEtBQUssQ0FBQyxVQUFVLGVBQWU7WUFDekQsbUJBQW1CO1lBQ25CLFFBQVEsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLGdCQUFnQjtZQUM5QyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7WUFDNUIsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQjtZQUN4QyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07WUFDcEIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNsQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7U0FDM0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBN0RELHdDQTZEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGF3c19jb2duaXRvIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBDb2duaXRvQXV0aGVudGljYXRpb24gfSBmcm9tICcuL2F1dGhlbnRpY2F0aW9uJztcbmltcG9ydCB7IExhbWJkYU9wdGlvbnMgfSBmcm9tICcuL2Z1bmMnO1xuaW1wb3J0IHsgTWNwQXV0aCB9IGZyb20gJy4vbWNwLWF1dGgnO1xuXG4vKipcbiAqIFByb3BzIGZvciBjcmVhdGluZyBhbiBNY3BBdXRoIGJhY2tlZCBieSBhIENvZ25pdG8gVXNlciBQb29sLlxuICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIHdyYXBwZXIg4oCUIHVzZSBNY3BBdXRoIGRpcmVjdGx5IGZvciBub24tQ29nbml0byBwcm92aWRlcnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWNwQ29nbml0b0F1dGhQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgQ29nbml0b0F1dGhlbnRpY2F0aW9uIGNvbnN0cnVjdCB0aGF0IG1hbmFnZXMgdGhlIHVzZXIgcG9vbC5cbiAgICogQSBkZWRpY2F0ZWQgdXNlciBwb29sIGNsaWVudCB3aWxsIGJlIGNyZWF0ZWQgZm9yIE1DUCBjb25uZWN0b3JzLlxuICAgKi9cbiAgcmVhZG9ubHkgYXV0aDogQ29nbml0b0F1dGhlbnRpY2F0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgQVBJIGRvbWFpbiB0aGF0IGFjdHMgYXMgdGhlIE1DUCBPQXV0aCBpc3N1ZXIuXG4gICAqIEFsbCBkaXNjb3ZlcnkgZW5kcG9pbnRzIHdpbGwgcmVmZXJlbmNlIHRoaXMgZG9tYWluLlxuICAgKiBFeGFtcGxlOiAnYXBpLmV4YW1wbGUuY29tJ1xuICAgKi9cbiAgcmVhZG9ubHkgYXBpRG9tYWluOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBDb2duaXRvIGF1dGggZG9tYWluIChjdXN0b20gZG9tYWluIG9yIENvZ25pdG8taG9zdGVkIGRvbWFpbikuXG4gICAqIEF1dGhvcml6ZSBhbmQgdG9rZW4gcmVxdWVzdHMgYXJlIHByb3hpZWQgaGVyZS5cbiAgICogRXhhbXBsZTogJ2F1dGguZXhhbXBsZS5jb20nIG9yICdteWFwcC5hdXRoLmV1LWNlbnRyYWwtMS5hbWF6b25jb2duaXRvLmNvbSdcbiAgICovXG4gIHJlYWRvbmx5IGF1dGhEb21haW46IHN0cmluZztcblxuICAvKipcbiAgICogQWxsb3dlZCByZWRpcmVjdCBVUklzIGZvciBkeW5hbWljIGNsaWVudCByZWdpc3RyYXRpb24uXG4gICAqIEBkZWZhdWx0IFsnaHR0cHM6Ly9jbGF1ZGUuYWkvb2F1dGgvY2FsbGJhY2snLCAnaHR0cHM6Ly9jbGF1ZGUuYWkvYXBpL21jcC9hdXRoX2NhbGxiYWNrJywgJ2h0dHBzOi8vY2hhdGdwdC5jb20vb2F1dGgvY2FsbGJhY2snXVxuICAgKi9cbiAgcmVhZG9ubHkgYWxsb3dlZFJlZGlyZWN0VXJpcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBNQ1Agc2VydmVyIGluZm8gcmV0dXJuZWQgaW4gdGhlICdpbml0aWFsaXplJyByZXNwb25zZS5cbiAgICovXG4gIHJlYWRvbmx5IHNlcnZlckluZm86IHsgcmVhZG9ubHkgbmFtZTogc3RyaW5nOyByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmcgfTtcblxuICAvKipcbiAgICogU3VwcG9ydGVkIE1DUCBwcm90b2NvbCB2ZXJzaW9ucyAobmV3ZXN0IGZpcnN0KS5cbiAgICogQGRlZmF1bHQgWycyMDI1LTExLTI1JywgJzIwMjUtMDMtMjYnLCAnMjAyNC0xMS0wNSddXG4gICAqL1xuICByZWFkb25seSBwcm90b2NvbFZlcnNpb25zPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIE9BdXRoIHNjb3BlcyB0byBhZHZlcnRpc2UgaW4gZGlzY292ZXJ5IG1ldGFkYXRhLlxuICAgKiBOb3RlOiBEbyBOT1QgaW5jbHVkZSBjdXN0b20gcmVzb3VyY2Ugc2VydmVyIHNjb3BlcyBoZXJlIOKAlFxuICAgKiBDb2duaXRvIE1hbmFnZWQgTG9naW4gdjIgcmVxdWlyZXMgUkZDIDg3MDcgcmVzb3VyY2UgcGFyYW1ldGVyXG4gICAqIGZvciBjdXN0b20gc2NvcGVzIHdoaWNoIE1DUCBjbGllbnRzIGNhbm5vdCBzdXBwbHkuXG4gICAqIEBkZWZhdWx0IFsnb3BlbmlkJywgJ2VtYWlsJywgJ3Byb2ZpbGUnXVxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGVzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgZW52aXJvbm1lbnQgdmFyaWFibGVzIGZvciBNQ1AgYXV0aCBMYW1iZGEgZnVuY3Rpb25zLlxuICAgKi9cbiAgcmVhZG9ubHkgYWRkaXRpb25hbEVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgLyoqXG4gICAqIExhbWJkYSBmdW5jdGlvbiBvcHRpb25zIGZvciBNQ1AgYXV0aCBoYW5kbGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGxhbWJkYU9wdGlvbnM/OiBMYW1iZGFPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBTdGFnZSBuYW1lIGZvciBmdW5jdGlvbiBuYW1pbmcgYW5kIHRhZ2dpbmcuXG4gICAqL1xuICByZWFkb25seSBzdGFnZU5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogQ29uc3RydWN0IElEIGZvciB0aGUgdXNlciBwb29sIGNsaWVudCAoYWZmZWN0cyBDbG91ZEZvcm1hdGlvbiBsb2dpY2FsIElEKS5cbiAgICogQGRlZmF1bHQgJ21jcENvbm5lY3RvcidcbiAgICovXG4gIHJlYWRvbmx5IGNsaWVudENvbnN0cnVjdElkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIE9BdXRoIGNhbGxiYWNrIFVSTHMgdG8gY29uZmlndXJlIG9uIHRoZSBDb2duaXRvIGNsaWVudFxuICAgKiBiZXlvbmQgdGhlIGFsbG93ZWRSZWRpcmVjdFVyaXMuIFVzZWZ1bCBpZiB0aGUgQ29nbml0byBjbGllbnQgbmVlZHNcbiAgICogVVJMcyB0aGF0IGFyZW4ndCBpbiB0aGUgTUNQIHJlZ2lzdHJhdGlvbiBhbGxvd2xpc3QuXG4gICAqL1xuICByZWFkb25seSBhZGRpdGlvbmFsQ2FsbGJhY2tVcmxzPzogc3RyaW5nW107XG59XG5cbi8qKlxuICogQ29udmVuaWVuY2UgY29uc3RydWN0IHRoYXQgY3JlYXRlcyBhbiBNY3BBdXRoIGJhY2tlZCBieSBBbWF6b24gQ29nbml0by5cbiAqXG4gKiBJdCBjcmVhdGVzIGEgZGVkaWNhdGVkIENvZ25pdG8gdXNlciBwb29sIGNsaWVudCBjb25maWd1cmVkIGZvciB0aGVcbiAqIGF1dGhvcml6YXRpb24gY29kZSArIFBLQ0UgZmxvdyBhbmQgd2lyZXMgaXQgaW50byB0aGUgZ2VuZXJpYyBNY3BBdXRoXG4gKiBjb25zdHJ1Y3QuIFVzZSB0aGlzIHdoZW4geW91ciBhdXRoZW50aWNhdGlvbiBpcyBtYW5hZ2VkIGJ5IENvZ25pdG87XG4gKiB1c2UgTWNwQXV0aCBkaXJlY3RseSBmb3Igb3RoZXIgT0F1dGgyL09JREMgcHJvdmlkZXJzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtY3BBdXRoID0gbmV3IE1jcENvZ25pdG9BdXRoKHRoaXMsICdNY3BBdXRoJywge1xuICogICBhdXRoOiBjb2duaXRvQXV0aGVudGljYXRpb24sXG4gKiAgIGFwaURvbWFpbjogJ2FwaS5leGFtcGxlLmNvbScsXG4gKiAgIGF1dGhEb21haW46ICdhdXRoLmV4YW1wbGUuY29tJyxcbiAqICAgc2VydmVySW5mbzogeyBuYW1lOiAnbXktbWNwLXNlcnZlcicsIHZlcnNpb246ICcxLjAuMCcgfSxcbiAqICAgc3RhZ2VOYW1lOiAnZGV2JyxcbiAqIH0pO1xuICpcbiAqIGNvbnN0IGFwaSA9IG5ldyBNeUFwaVJlc3RBcGkodGhpcywgJ0FwaScsIHtcbiAqICAgbWNwQXV0aDogbWNwQXV0aC5tY3BBdXRoLFxuICogICAvLyAuLi5cbiAqIH0pO1xuICovXG5leHBvcnQgY2xhc3MgTWNwQ29nbml0b0F1dGggZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuXG4gIC8qKlxuICAgKiBUaGUgdW5kZXJseWluZyBzZXJ2aWNlLWFnbm9zdGljIE1jcEF1dGggY29uc3RydWN0LlxuICAgKiBQYXNzIHRoaXMgdG8gUmVzdEFwaSdzIGBtY3BBdXRoYCBwcm9wLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1jcEF1dGg6IE1jcEF1dGg7XG5cbiAgLyoqXG4gICAqIFRoZSBDb2duaXRvIHVzZXIgcG9vbCBjbGllbnQgY3JlYXRlZCBmb3IgTUNQIGNvbm5lY3RvcnMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdXNlclBvb2xDbGllbnQ6IGF3c19jb2duaXRvLlVzZXJQb29sQ2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBNY3BDb2duaXRvQXV0aFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IGNsaWVudElkID0gcHJvcHMuY2xpZW50Q29uc3RydWN0SWQgPz8gJ21jcENvbm5lY3Rvcic7XG5cbiAgICBjb25zdCBhbGxvd2VkUmVkaXJlY3RVcmlzID0gcHJvcHMuYWxsb3dlZFJlZGlyZWN0VXJpcyA/PyBbXG4gICAgICAnaHR0cHM6Ly9jbGF1ZGUuYWkvb2F1dGgvY2FsbGJhY2snLFxuICAgICAgJ2h0dHBzOi8vY2xhdWRlLmFpL2FwaS9tY3AvYXV0aF9jYWxsYmFjaycsXG4gICAgICAnaHR0cHM6Ly9jaGF0Z3B0LmNvbS9vYXV0aC9jYWxsYmFjaycsXG4gICAgXTtcblxuICAgIC8vIENyZWF0ZSBhIENvZ25pdG8gdXNlciBwb29sIGNsaWVudCB3aXRoIGF1dGggY29kZSBncmFudCArIFBLQ0VcbiAgICB0aGlzLnVzZXJQb29sQ2xpZW50ID0gcHJvcHMuYXV0aC5hZGRVc2VyUG9vbENsaWVudChjbGllbnRJZCwge1xuICAgICAgZ2VuZXJhdGVTZWNyZXQ6IGZhbHNlLFxuICAgICAgb0F1dGg6IHtcbiAgICAgICAgZmxvd3M6IHtcbiAgICAgICAgICBhdXRob3JpemF0aW9uQ29kZUdyYW50OiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBzY29wZXM6IFtcbiAgICAgICAgICBhd3NfY29nbml0by5PQXV0aFNjb3BlLk9QRU5JRCxcbiAgICAgICAgICBhd3NfY29nbml0by5PQXV0aFNjb3BlLkVNQUlMLFxuICAgICAgICAgIGF3c19jb2duaXRvLk9BdXRoU2NvcGUuUFJPRklMRSxcbiAgICAgICAgXSxcbiAgICAgICAgY2FsbGJhY2tVcmxzOiBbXG4gICAgICAgICAgLi4uYWxsb3dlZFJlZGlyZWN0VXJpcyxcbiAgICAgICAgICAuLi4ocHJvcHMuYWRkaXRpb25hbENhbGxiYWNrVXJscyA/PyBbXSksXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAgYXV0aEZsb3dzOiB7XG4gICAgICAgIHVzZXJTcnA6IHRydWUsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gQ3JlYXRlIHRoZSBnZW5lcmljIE1jcEF1dGgsIGRlcml2aW5nIGVuZHBvaW50cyBmcm9tIGF1dGhEb21haW5cbiAgICB0aGlzLm1jcEF1dGggPSBuZXcgTWNwQXV0aCh0aGlzLCAnTWNwQXV0aCcsIHtcbiAgICAgIGFwaURvbWFpbjogcHJvcHMuYXBpRG9tYWluLFxuICAgICAgYXV0aG9yaXplRW5kcG9pbnQ6IGBodHRwczovLyR7cHJvcHMuYXV0aERvbWFpbn0vb2F1dGgyL2F1dGhvcml6ZWAsXG4gICAgICB0b2tlbkVuZHBvaW50OiBgaHR0cHM6Ly8ke3Byb3BzLmF1dGhEb21haW59L29hdXRoMi90b2tlbmAsXG4gICAgICBhbGxvd2VkUmVkaXJlY3RVcmlzLFxuICAgICAgY2xpZW50SWQ6IHRoaXMudXNlclBvb2xDbGllbnQudXNlclBvb2xDbGllbnRJZCxcbiAgICAgIHNlcnZlckluZm86IHByb3BzLnNlcnZlckluZm8sXG4gICAgICBwcm90b2NvbFZlcnNpb25zOiBwcm9wcy5wcm90b2NvbFZlcnNpb25zLFxuICAgICAgc2NvcGVzOiBwcm9wcy5zY29wZXMsXG4gICAgICBhZGRpdGlvbmFsRW52OiBwcm9wcy5hZGRpdGlvbmFsRW52LFxuICAgICAgbGFtYmRhT3B0aW9uczogcHJvcHMubGFtYmRhT3B0aW9ucyxcbiAgICAgIHN0YWdlTmFtZTogcHJvcHMuc3RhZ2VOYW1lLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
|
|
@@ -1,8 +1,103 @@
|
|
|
1
1
|
import { aws_apigateway } from 'aws-cdk-lib';
|
|
2
2
|
import { Construct } from 'constructs';
|
|
3
3
|
import { OpenAPI3, OperationObject } from 'openapi-typescript';
|
|
4
|
+
import { CognitoAuthentication } from './authentication';
|
|
4
5
|
import { BaseApi, BaseApiProps } from './base-api';
|
|
5
6
|
import { LambdaFunction, LambdaOptions } from './func';
|
|
7
|
+
import { McpAuth } from './mcp-auth';
|
|
8
|
+
/**
|
|
9
|
+
* Cognito-specific MCP auth configuration.
|
|
10
|
+
* Creates a dedicated user pool client for MCP connectors automatically.
|
|
11
|
+
*/
|
|
12
|
+
export interface McpAuthCognitoOptions {
|
|
13
|
+
/**
|
|
14
|
+
* The CognitoAuthentication construct managing the user pool.
|
|
15
|
+
* A dedicated client with auth code + PKCE will be created.
|
|
16
|
+
*/
|
|
17
|
+
readonly auth: CognitoAuthentication;
|
|
18
|
+
/**
|
|
19
|
+
* The Cognito auth domain (custom or Cognito-hosted).
|
|
20
|
+
* Required — never inferred from apiDomain.
|
|
21
|
+
* Example: 'auth.example.com'
|
|
22
|
+
*/
|
|
23
|
+
readonly authDomain: string;
|
|
24
|
+
/**
|
|
25
|
+
* Construct ID for the user pool client (affects CloudFormation logical ID).
|
|
26
|
+
* @default 'mcpConnector'
|
|
27
|
+
*/
|
|
28
|
+
readonly clientConstructId?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Additional OAuth callback URLs for the Cognito client beyond the allowedRedirectUris.
|
|
31
|
+
*/
|
|
32
|
+
readonly additionalCallbackUrls?: string[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generic (non-Cognito) MCP auth configuration.
|
|
36
|
+
* Requires explicit authorize and token endpoint URLs.
|
|
37
|
+
*/
|
|
38
|
+
export interface McpAuthGenericOptions {
|
|
39
|
+
/**
|
|
40
|
+
* The upstream OAuth authorize endpoint URL.
|
|
41
|
+
* Example: 'https://auth.example.com/oauth2/authorize'
|
|
42
|
+
*/
|
|
43
|
+
readonly authorizeEndpoint: string;
|
|
44
|
+
/**
|
|
45
|
+
* The upstream OAuth token endpoint URL.
|
|
46
|
+
* Example: 'https://auth.example.com/oauth2/token'
|
|
47
|
+
*/
|
|
48
|
+
readonly tokenEndpoint: string;
|
|
49
|
+
/**
|
|
50
|
+
* The pre-provisioned OAuth client ID returned by the register endpoint.
|
|
51
|
+
*/
|
|
52
|
+
readonly clientId: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* MCP auth configuration for the RestApi.
|
|
56
|
+
* Provide either `cognito` (for Cognito-backed auth) or `generic` (for any OAuth2 provider).
|
|
57
|
+
*/
|
|
58
|
+
export interface McpAuthOptions {
|
|
59
|
+
/**
|
|
60
|
+
* Cognito-specific configuration. Mutually exclusive with `generic`.
|
|
61
|
+
* Creates a user pool client and derives endpoints automatically.
|
|
62
|
+
*/
|
|
63
|
+
readonly cognito?: McpAuthCognitoOptions;
|
|
64
|
+
/**
|
|
65
|
+
* Generic OAuth2 provider configuration. Mutually exclusive with `cognito`.
|
|
66
|
+
* Requires explicit endpoint URLs and client ID.
|
|
67
|
+
*/
|
|
68
|
+
readonly generic?: McpAuthGenericOptions;
|
|
69
|
+
/**
|
|
70
|
+
* MCP server info returned in the 'initialize' response.
|
|
71
|
+
*/
|
|
72
|
+
readonly serverInfo: {
|
|
73
|
+
readonly name: string;
|
|
74
|
+
readonly version: string;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Allowed redirect URIs for dynamic client registration.
|
|
78
|
+
* @default ['https://claude.ai/oauth/callback', 'https://claude.ai/api/mcp/auth_callback', 'https://chatgpt.com/oauth/callback']
|
|
79
|
+
*/
|
|
80
|
+
readonly allowedRedirectUris?: string[];
|
|
81
|
+
/**
|
|
82
|
+
* Supported MCP protocol versions (newest first).
|
|
83
|
+
* @default ['2025-11-25', '2025-03-26', '2024-11-05']
|
|
84
|
+
*/
|
|
85
|
+
readonly protocolVersions?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* OAuth scopes to advertise in discovery metadata.
|
|
88
|
+
* @default ['openid', 'email', 'profile']
|
|
89
|
+
*/
|
|
90
|
+
readonly scopes?: string[];
|
|
91
|
+
/**
|
|
92
|
+
* Parameters to strip from authorize/token proxy requests.
|
|
93
|
+
* @default ['resource']
|
|
94
|
+
*/
|
|
95
|
+
readonly stripParameters?: string[];
|
|
96
|
+
/**
|
|
97
|
+
* Lambda function options for MCP auth handlers.
|
|
98
|
+
*/
|
|
99
|
+
readonly lambdaOptions?: LambdaOptions;
|
|
100
|
+
}
|
|
6
101
|
export interface RestApiProps<OPS> extends BaseApiProps {
|
|
7
102
|
/**
|
|
8
103
|
* Generate routes for all endpoints configured in the openapi.yaml file
|
|
@@ -56,6 +151,26 @@ export interface RestApiProps<OPS> extends BaseApiProps {
|
|
|
56
151
|
* @default 'token'
|
|
57
152
|
*/
|
|
58
153
|
jwtAuthorizerType?: 'token' | 'request';
|
|
154
|
+
/**
|
|
155
|
+
* MCP Auth configuration to wire into this API.
|
|
156
|
+
* When provided, the following paths are automatically added to the OpenAPI spec
|
|
157
|
+
* with Lambda proxy integrations:
|
|
158
|
+
*
|
|
159
|
+
* - GET /.well-known/oauth-protected-resource
|
|
160
|
+
* - GET /.well-known/oauth-authorization-server
|
|
161
|
+
* - GET /oauth/authorize
|
|
162
|
+
* - POST /oauth/token
|
|
163
|
+
* - POST /oauth/register
|
|
164
|
+
*
|
|
165
|
+
* All MCP auth endpoints are anonymous (no authorizer).
|
|
166
|
+
* The API domain is derived from the RestApi's own domain configuration.
|
|
167
|
+
*
|
|
168
|
+
* Provide either `cognito` (creates a Cognito client automatically) or
|
|
169
|
+
* `generic` (for any OAuth2 provider with explicit endpoint URLs).
|
|
170
|
+
*
|
|
171
|
+
* @default - no MCP auth
|
|
172
|
+
*/
|
|
173
|
+
mcpAuth?: McpAuthOptions;
|
|
59
174
|
/**
|
|
60
175
|
* Global OAuth2 scopes required by the Cognito authorizer.
|
|
61
176
|
*
|
|
@@ -135,6 +250,11 @@ export declare class RestApi<PATHS, OPS> extends BaseApi {
|
|
|
135
250
|
* @private
|
|
136
251
|
*/
|
|
137
252
|
private _authorizerFn?;
|
|
253
|
+
/**
|
|
254
|
+
* The MCP auth construct, if mcpAuth options were provided.
|
|
255
|
+
* @private
|
|
256
|
+
*/
|
|
257
|
+
private _mcpAuth?;
|
|
138
258
|
/**
|
|
139
259
|
* Set of operationIds that should have security disabled (security: []).
|
|
140
260
|
* @private
|
|
@@ -222,6 +342,22 @@ export declare class RestApi<PATHS, OPS> extends BaseApi {
|
|
|
222
342
|
* For JWT: creates a Lambda authorizer function and adds a token authorizer referencing its ARN.
|
|
223
343
|
*/
|
|
224
344
|
protected patchSecuritySchemes(spec: OpenAPI3): void;
|
|
345
|
+
/**
|
|
346
|
+
* Returns the MCP auth construct if mcpAuth was configured.
|
|
347
|
+
* Useful for accessing the created Lambda functions or env vars.
|
|
348
|
+
*/
|
|
349
|
+
getMcpAuth(): McpAuth | undefined;
|
|
350
|
+
/**
|
|
351
|
+
* Creates the McpAuth construct from the provided options.
|
|
352
|
+
* Derives apiDomain from the RestApi's own domain config.
|
|
353
|
+
* For Cognito, creates a user pool client automatically.
|
|
354
|
+
*/
|
|
355
|
+
private createMcpAuth;
|
|
356
|
+
/**
|
|
357
|
+
* Injects MCP OAuth paths into the OpenAPI spec with Lambda proxy integrations
|
|
358
|
+
* pointing to the MCP auth construct's functions. All paths are anonymous (security: []).
|
|
359
|
+
*/
|
|
360
|
+
private injectMcpAuthPaths;
|
|
225
361
|
/**
|
|
226
362
|
* Returns the security-scheme container for the spec, creating it if needed.
|
|
227
363
|
* OpenAPI 3.x stores schemes under `components.securitySchemes`; Swagger 2.0
|