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.
Files changed (73) hide show
  1. package/README.md +111 -0
  2. package/docs/constructs/assets/hierarchy.js +1 -1
  3. package/docs/constructs/assets/navigation.js +1 -1
  4. package/docs/constructs/assets/search.js +1 -1
  5. package/docs/constructs/classes/McpAuth.html +43 -0
  6. package/docs/constructs/classes/McpCognitoAuth.html +43 -0
  7. package/docs/constructs/classes/RestApi.html +6 -3
  8. package/docs/constructs/classes/SingleTableDatastore.html +1 -1
  9. package/docs/constructs/classes/Workflow.html +1 -1
  10. package/docs/constructs/hierarchy.html +1 -1
  11. package/docs/constructs/index.html +112 -1
  12. package/docs/constructs/interfaces/McpAuthCognitoOptions.html +17 -0
  13. package/docs/constructs/interfaces/McpAuthFunctions.html +14 -0
  14. package/docs/constructs/interfaces/McpAuthGenericOptions.html +11 -0
  15. package/docs/constructs/interfaces/McpAuthOptions.html +33 -0
  16. package/docs/constructs/interfaces/McpAuthProps.html +43 -0
  17. package/docs/constructs/interfaces/McpCognitoAuthProps.html +49 -0
  18. package/docs/constructs/interfaces/RestApiProps.html +24 -6
  19. package/docs/constructs/modules.html +1 -1
  20. package/docs/lambda/index.html +112 -1
  21. package/docs/projen/index.html +112 -1
  22. package/lib/constructs/index.d.ts +2 -0
  23. package/lib/constructs/index.js +3 -1
  24. package/lib/constructs/mcp-auth.d.ts +117 -0
  25. package/lib/constructs/mcp-auth.js +127 -0
  26. package/lib/constructs/mcp-cognito-auth.d.ts +110 -0
  27. package/lib/constructs/mcp-cognito-auth.js +76 -0
  28. package/lib/constructs/rest-api.d.ts +136 -0
  29. package/lib/constructs/rest-api.js +159 -1
  30. package/lib/mcp-auth/config.d.ts +39 -0
  31. package/lib/mcp-auth/config.js +3 -0
  32. package/lib/mcp-auth/handlers/authorization-server.d.ts +7 -0
  33. package/lib/mcp-auth/handlers/authorization-server.js +34 -0
  34. package/lib/mcp-auth/handlers/authorize.d.ts +8 -0
  35. package/lib/mcp-auth/handlers/authorize.js +32 -0
  36. package/lib/mcp-auth/handlers/index.d.ts +7 -0
  37. package/lib/mcp-auth/handlers/index.js +24 -0
  38. package/lib/mcp-auth/handlers/protected-resource.d.ts +7 -0
  39. package/lib/mcp-auth/handlers/protected-resource.js +26 -0
  40. package/lib/mcp-auth/handlers/register.d.ts +7 -0
  41. package/lib/mcp-auth/handlers/register.js +68 -0
  42. package/lib/mcp-auth/handlers/token.d.ts +8 -0
  43. package/lib/mcp-auth/handlers/token.js +74 -0
  44. package/lib/mcp-auth/handlers/types.d.ts +21 -0
  45. package/lib/mcp-auth/handlers/types.js +3 -0
  46. package/lib/mcp-auth/handlers/validate-redirect-uris.d.ts +10 -0
  47. package/lib/mcp-auth/handlers/validate-redirect-uris.js +22 -0
  48. package/lib/mcp-auth/index.d.ts +3 -0
  49. package/lib/mcp-auth/index.js +20 -0
  50. package/lib/mcp-auth/lambda-handlers/authorization-server.handler.d.ts +2 -0
  51. package/lib/mcp-auth/lambda-handlers/authorization-server.handler.js +23 -0
  52. package/lib/mcp-auth/lambda-handlers/authorize.handler.d.ts +2 -0
  53. package/lib/mcp-auth/lambda-handlers/authorize.handler.js +23 -0
  54. package/lib/mcp-auth/lambda-handlers/env-config.d.ts +7 -0
  55. package/lib/mcp-auth/lambda-handlers/env-config.js +37 -0
  56. package/lib/mcp-auth/lambda-handlers/protected-resource.handler.d.ts +2 -0
  57. package/lib/mcp-auth/lambda-handlers/protected-resource.handler.js +23 -0
  58. package/lib/mcp-auth/lambda-handlers/register.handler.d.ts +2 -0
  59. package/lib/mcp-auth/lambda-handlers/register.handler.js +23 -0
  60. package/lib/mcp-auth/lambda-handlers/token.handler.d.ts +2 -0
  61. package/lib/mcp-auth/lambda-handlers/token.handler.js +23 -0
  62. package/lib/mcp-auth/mcp/errors.d.ts +8 -0
  63. package/lib/mcp-auth/mcp/errors.js +20 -0
  64. package/lib/mcp-auth/mcp/index.d.ts +4 -0
  65. package/lib/mcp-auth/mcp/index.js +21 -0
  66. package/lib/mcp-auth/mcp/jsonrpc.d.ts +21 -0
  67. package/lib/mcp-auth/mcp/jsonrpc.js +56 -0
  68. package/lib/mcp-auth/mcp/server.d.ts +9 -0
  69. package/lib/mcp-auth/mcp/server.js +107 -0
  70. package/lib/mcp-auth/mcp/types.d.ts +32 -0
  71. package/lib/mcp-auth/mcp/types.js +3 -0
  72. package/llm.md +214 -0
  73. package/package.json +1 -1
@@ -55,6 +55,117 @@
55
55
  <pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-4">IntegTestUtil</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&#39;cdk-serverless/tests/integ-test-util&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-6">// Initialize with your stack outputs</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">test</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">IntegTestUtil</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-4">region:</span><span class="hl-1"> </span><span class="hl-2">&#39;us-east-1&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">apiOptions:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">baseURL:</span><span class="hl-1"> </span><span class="hl-2">&#39;https://api.example.com&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">authOptions:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">userPoolId:</span><span class="hl-1"> </span><span class="hl-2">&#39;us-east-1_xxxxx&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">userPoolClientId:</span><span class="hl-1"> </span><span class="hl-2">&#39;xxxxxxxx&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">identityPoolId:</span><span class="hl-1"> </span><span class="hl-2">&#39;us-east-1:xxxxxxxx&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">datastoreOptions:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">tableName:</span><span class="hl-1"> </span><span class="hl-2">&#39;MyTable&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-6">// Create and authenticate a test user</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">createUser</span><span class="hl-1">(</span><span class="hl-2">&#39;test@example.com&#39;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">&#39;custom:attribute&#39;</span><span class="hl-4">:</span><span class="hl-1"> </span><span class="hl-2">&#39;value&#39;</span><span class="hl-1">,</span><br/><span class="hl-1">}, [</span><span class="hl-2">&#39;admin&#39;</span><span class="hl-1">]);</span><br/><br/><span class="hl-6">// Get an authenticated API client</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">client</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">getAuthenticatedClient</span><span class="hl-1">(</span><span class="hl-2">&#39;test@example.com&#39;</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// Make API calls</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">response</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">client</span><span class="hl-1">.</span><span class="hl-0">get</span><span class="hl-1">(</span><span class="hl-2">&#39;/items&#39;</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// Clean up test data</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">cleanupItems</span><span class="hl-1">();</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">removeUser</span><span class="hl-1">(</span><span class="hl-2">&#39;test@example.com&#39;</span><span class="hl-1">);</span>
56
56
  </code><button type="button">Copy</button></pre>
57
57
 
58
+ <h2 id="mcp-auth" class="tsd-anchor-link">MCP Auth<a href="#mcp-auth" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
59
+ <p>CDK Serverless includes built-in support for adding <a href="https://spec.modelcontextprotocol.io">Model Context Protocol (MCP)</a> OAuth authentication to your API. This enables MCP clients like Claude and ChatGPT to authenticate with your API using standard OAuth 2.0 flows.</p>
60
+ <p>When activated, the following endpoints are automatically added to your OpenAPI spec:</p>
61
+ <table>
62
+ <thead>
63
+ <tr>
64
+ <th>Endpoint</th>
65
+ <th>Method</th>
66
+ <th>RFC</th>
67
+ <th>Purpose</th>
68
+ </tr>
69
+ </thead>
70
+ <tbody>
71
+ <tr>
72
+ <td><code>/.well-known/oauth-protected-resource</code></td>
73
+ <td>GET</td>
74
+ <td>RFC 9728</td>
75
+ <td>Resource metadata discovery</td>
76
+ </tr>
77
+ <tr>
78
+ <td><code>/.well-known/oauth-authorization-server</code></td>
79
+ <td>GET</td>
80
+ <td>RFC 8414</td>
81
+ <td>Authorization server metadata</td>
82
+ </tr>
83
+ <tr>
84
+ <td><code>/oauth/authorize</code></td>
85
+ <td>GET</td>
86
+ <td>—</td>
87
+ <td>Authorize proxy (redirect to upstream)</td>
88
+ </tr>
89
+ <tr>
90
+ <td><code>/oauth/token</code></td>
91
+ <td>POST</td>
92
+ <td>—</td>
93
+ <td>Token proxy (forward to upstream)</td>
94
+ </tr>
95
+ <tr>
96
+ <td><code>/oauth/register</code></td>
97
+ <td>POST</td>
98
+ <td>RFC 7591</td>
99
+ <td>Dynamic client registration</td>
100
+ </tr>
101
+ </tbody>
102
+ </table>
103
+ <p>All MCP auth endpoints are anonymous (no API authorizer applied).</p>
104
+ <h3 id="with-cognito" class="tsd-anchor-link">With Cognito<a href="#with-cognito" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
105
+ <p>MCP clients like Claude enforce that all OAuth endpoints (discovery, authorize, token, register) live on the <strong>same origin</strong> as the API itself. Cognito's hosted UI lives on a different domain (<code>auth.example.com</code>), so MCP clients cannot talk to it directly. Additionally:</p>
106
+ <ul>
107
+ <li>Cognito Managed Login v2 requires the RFC 8707 <code>resource</code> parameter for custom scopes in authorize requests — MCP clients do not send this parameter.</li>
108
+ <li>MCP clients construct the token endpoint URL from the OAuth metadata <code>issuer</code> field rather than using the explicit <code>token_endpoint</code> — so the token exchange must be proxied through the API domain.</li>
109
+ <li>Dynamic Client Registration (RFC 7591) is not natively supported by Cognito.</li>
110
+ </ul>
111
+ <p>The MCP auth proxy solves all three problems: it serves discovery metadata on the API domain, strips unsupported parameters before forwarding to Cognito, and implements a simplified registration endpoint that returns a pre-provisioned client ID.</p>
112
+ <p>If your API already uses <code>CognitoAuthentication</code>, add MCP auth with minimal config — a dedicated user pool client is created automatically:</p>
113
+ <pre><code class="typescript"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">api</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">TestApiRestApi</span><span class="hl-1">(</span><span class="hl-5">this</span><span class="hl-1">, </span><span class="hl-2">&#39;Api&#39;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-4">stageName:</span><span class="hl-1"> </span><span class="hl-2">&#39;dev&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">domainName:</span><span class="hl-1"> </span><span class="hl-2">&#39;example.com&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">apiHostname:</span><span class="hl-1"> </span><span class="hl-2">&#39;api&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">authentication:</span><span class="hl-1"> </span><span class="hl-4">cognitoAuth</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">cors:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">mcpAuth:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">cognito:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">auth:</span><span class="hl-1"> </span><span class="hl-4">cognitoAuth</span><span class="hl-1">, </span><span class="hl-6">// your CognitoAuthentication construct</span><br/><span class="hl-1"> </span><span class="hl-4">authDomain:</span><span class="hl-1"> </span><span class="hl-2">&#39;auth.example.com&#39;</span><span class="hl-1">, </span><span class="hl-6">// Cognito custom/hosted domain (required)</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">serverInfo:</span><span class="hl-1"> { </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-mcp-server&#39;</span><span class="hl-1">, </span><span class="hl-4">version:</span><span class="hl-1"> </span><span class="hl-2">&#39;1.0.0&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span>
114
+ </code><button type="button">Copy</button></pre>
115
+
116
+ <p>The <code>apiDomain</code> is derived from the RestApi's own domain config (<code>apiHostname</code> + <code>domainName</code>), and <code>stageName</code> is reused — no duplication needed.</p>
117
+ <h3 id="with-any-oauth2-provider" class="tsd-anchor-link">With any OAuth2 provider<a href="#with-any-oauth2-provider" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
118
+ <p>For non-Cognito providers, use <code>generic</code> mode with explicit endpoint URLs:</p>
119
+ <pre><code class="typescript"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">api</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">TestApiRestApi</span><span class="hl-1">(</span><span class="hl-5">this</span><span class="hl-1">, </span><span class="hl-2">&#39;Api&#39;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-6">// ...</span><br/><span class="hl-1"> </span><span class="hl-4">mcpAuth:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">generic:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">authorizeEndpoint:</span><span class="hl-1"> </span><span class="hl-2">&#39;https://auth.example.com/authorize&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">tokenEndpoint:</span><span class="hl-1"> </span><span class="hl-2">&#39;https://auth.example.com/token&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">clientId:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-pre-provisioned-client-id&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">serverInfo:</span><span class="hl-1"> { </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-mcp-server&#39;</span><span class="hl-1">, </span><span class="hl-4">version:</span><span class="hl-1"> </span><span class="hl-2">&#39;1.0.0&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span>
120
+ </code><button type="button">Copy</button></pre>
121
+
122
+ <h3 id="configuration-options" class="tsd-anchor-link">Configuration options<a href="#configuration-options" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
123
+ <table>
124
+ <thead>
125
+ <tr>
126
+ <th>Option</th>
127
+ <th>Default</th>
128
+ <th>Description</th>
129
+ </tr>
130
+ </thead>
131
+ <tbody>
132
+ <tr>
133
+ <td><code>serverInfo</code></td>
134
+ <td>(required)</td>
135
+ <td><code>{ name, version }</code> returned in MCP initialize</td>
136
+ </tr>
137
+ <tr>
138
+ <td><code>allowedRedirectUris</code></td>
139
+ <td>Claude + ChatGPT callbacks</td>
140
+ <td>Allowlist for dynamic registration</td>
141
+ </tr>
142
+ <tr>
143
+ <td><code>protocolVersions</code></td>
144
+ <td><code>['2025-11-25', '2025-03-26', '2024-11-05']</code></td>
145
+ <td>Supported MCP versions</td>
146
+ </tr>
147
+ <tr>
148
+ <td><code>scopes</code></td>
149
+ <td><code>['openid', 'email', 'profile']</code></td>
150
+ <td>Advertised OAuth scopes</td>
151
+ </tr>
152
+ <tr>
153
+ <td><code>stripParameters</code></td>
154
+ <td><code>['resource']</code></td>
155
+ <td>Params stripped from authorize/token proxying</td>
156
+ </tr>
157
+ <tr>
158
+ <td><code>lambdaOptions</code></td>
159
+ <td>—</td>
160
+ <td>Lambda config for MCP auth handlers</td>
161
+ </tr>
162
+ </tbody>
163
+ </table>
164
+ <h3 id="mcp-server-runtime" class="tsd-anchor-link">MCP Server runtime<a href="#mcp-server-runtime" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
165
+ <p>The <code>cdk-serverless/mcp-auth</code> module also exports a JSON-RPC server for implementing the MCP tool endpoint itself:</p>
166
+ <pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-4">createMcpServer</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&#39;cdk-serverless/mcp-auth&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">server</span><span class="hl-1"> = </span><span class="hl-0">createMcpServer</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-4">serverInfo:</span><span class="hl-1"> { </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-server&#39;</span><span class="hl-1">, </span><span class="hl-4">version:</span><span class="hl-1"> </span><span class="hl-2">&#39;1.0.0&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">protocolVersions:</span><span class="hl-1"> [</span><span class="hl-2">&#39;2025-11-25&#39;</span><span class="hl-1">],</span><br/><span class="hl-1"> </span><span class="hl-4">resolver:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">async</span><span class="hl-1"> </span><span class="hl-0">resolve</span><span class="hl-1">(</span><span class="hl-4">headers</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-6">// Validate Bearer token, return principal or throw McpUnauthorizedError</span><br/><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">token</span><span class="hl-1"> = </span><span class="hl-4">headers</span><span class="hl-1">.</span><span class="hl-4">authorization</span><span class="hl-1">?.</span><span class="hl-0">replace</span><span class="hl-1">(</span><span class="hl-2">&#39;Bearer &#39;</span><span class="hl-1">, </span><span class="hl-2">&#39;&#39;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (!</span><span class="hl-4">token</span><span class="hl-1">) </span><span class="hl-3">throw</span><span class="hl-1"> </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">McpUnauthorizedError</span><span class="hl-1">(</span><span class="hl-2">&#39;Bearer&#39;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">return</span><span class="hl-1"> </span><span class="hl-0">verifyToken</span><span class="hl-1">(</span><span class="hl-4">token</span><span class="hl-1">);</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">tools:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;search&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">description:</span><span class="hl-1"> </span><span class="hl-2">&#39;Search documents&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">inputSchema:</span><span class="hl-1"> { </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-2">&#39;object&#39;</span><span class="hl-1">, </span><span class="hl-4">properties:</span><span class="hl-1"> { </span><span class="hl-4">query:</span><span class="hl-1"> { </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-2">&#39;string&#39;</span><span class="hl-1"> } } },</span><br/><span class="hl-1"> </span><span class="hl-5">async</span><span class="hl-1"> </span><span class="hl-0">invoke</span><span class="hl-1">(</span><span class="hl-4">principal</span><span class="hl-1">, </span><span class="hl-4">args</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">results</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">search</span><span class="hl-1">(</span><span class="hl-4">principal</span><span class="hl-1">, (</span><span class="hl-4">args</span><span class="hl-1"> </span><span class="hl-3">as</span><span class="hl-1"> </span><span class="hl-8">any</span><span class="hl-1">).</span><span class="hl-4">query</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">return</span><span class="hl-1"> { </span><span class="hl-4">content:</span><span class="hl-1"> [{ </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-2">&#39;text&#39;</span><span class="hl-1">, </span><span class="hl-4">text:</span><span class="hl-1"> </span><span class="hl-7">JSON</span><span class="hl-1">.</span><span class="hl-0">stringify</span><span class="hl-1">(</span><span class="hl-4">results</span><span class="hl-1">) }] };</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> ],</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-6">// In your Lambda handler:</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">response</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">server</span><span class="hl-1">.</span><span class="hl-0">handle</span><span class="hl-1">(</span><span class="hl-4">parsedBody</span><span class="hl-1">, </span><span class="hl-4">event</span><span class="hl-1">.</span><span class="hl-4">headers</span><span class="hl-1">);</span>
167
+ </code><button type="button">Copy</button></pre>
168
+
58
169
  <h2 id="breaking-change-removed" class="tsd-anchor-link">Breaking Change: <code>axios</code> Removed<a href="#breaking-change-removed" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
59
170
  <p>CDK Serverless no longer depends on <code>axios</code>. The library now uses the
60
171
  platform-native <code>fetch</code> API (stable in Node.js 18+; the Lambda functions
@@ -136,4 +247,4 @@ issue.</p>
136
247
  </ul>
137
248
  <h2 id="authors" class="tsd-anchor-link">Authors<a href="#authors" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
138
249
  <p>Brought to you by <a href="https://taimos.de">Taimos</a></p>
139
- </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#cdk-serverless"><span>CDK <wbr/>Serverless</span></a><ul><li><ul><li><a href="#features"><span>Features</span></a></li></ul></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#adding-projen-constructs"><span>Adding projen constructs</span></a></li><li><a href="#using-the-cdk-serverless-l3-constructs"><span>Using the <wbr/>CDK serverless <wbr/>L3 constructs</span></a></li></ul></li><li><a href="#testing-utilities"><span>Testing <wbr/>Utilities</span></a></li><li><ul><li><a href="#lambdatestutil"><span>Lambda<wbr/>Test<wbr/>Util</span></a></li><li><ul><li><a href="#rest-api-testing"><span>REST <wbr/>API <wbr/>Testing</span></a></li><li><a href="#graphql-testing"><span>Graph<wbr/>QL <wbr/>Testing</span></a></li></ul></li><li><a href="#integtestutil"><span>Integ<wbr/>Test<wbr/>Util</span></a></li></ul></li><li><a href="#breaking-change-removed"><span>Breaking <wbr/>Change: <wbr/>Removed</span></a></li><li><ul><li><a href="#impact-on-lambda-handlers-"><span>Impact on <wbr/>Lambda handlers ()</span></a></li><li><a href="#impact-on-"><span>Impact on ()</span></a></li></ul></li><li><a href="#contribute"><span>Contribute</span></a></li><li><ul><li><a href="#how-to-contribute-to-cdk-serverless"><span>How to contribute to <wbr/>CDK <wbr/>Serverless</span></a></li><li><ul><li><a href="#did-you-find-a-bug"><span>Did you find a bug?</span></a></li><li><a href="#did-you-write-a-patch-that-fixes-a-bug"><span>Did you write a patch that fixes a bug?</span></a></li><li><a href="#did-you-fix-whitespace-format-code-or-make-a-purely-cosmetic-patch"><span>Did you fix whitespace, format code, or make a purely cosmetic patch?</span></a></li><li><a href="#do-you-intend-to-add-a-new-feature-or-change-an-existing-one"><span>Do you intend to add a new feature or change an existing one?</span></a></li><li><a href="#do-you-want-to-contribute-to-the-cdk-serverless-documentation"><span>Do you want to contribute to the <wbr/>CDK <wbr/>Serverless documentation?</span></a></li></ul></li></ul></li><li><a href="#authors"><span>Authors</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">cdk-serverless</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
250
+ </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#cdk-serverless"><span>CDK <wbr/>Serverless</span></a><ul><li><ul><li><a href="#features"><span>Features</span></a></li></ul></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#adding-projen-constructs"><span>Adding projen constructs</span></a></li><li><a href="#using-the-cdk-serverless-l3-constructs"><span>Using the <wbr/>CDK serverless <wbr/>L3 constructs</span></a></li></ul></li><li><a href="#testing-utilities"><span>Testing <wbr/>Utilities</span></a></li><li><ul><li><a href="#lambdatestutil"><span>Lambda<wbr/>Test<wbr/>Util</span></a></li><li><ul><li><a href="#rest-api-testing"><span>REST <wbr/>API <wbr/>Testing</span></a></li><li><a href="#graphql-testing"><span>Graph<wbr/>QL <wbr/>Testing</span></a></li></ul></li><li><a href="#integtestutil"><span>Integ<wbr/>Test<wbr/>Util</span></a></li></ul></li><li><a href="#mcp-auth"><span>MCP <wbr/>Auth</span></a></li><li><ul><li><a href="#with-cognito"><span>With <wbr/>Cognito</span></a></li><li><a href="#with-any-oauth2-provider"><span>With any <wbr/>O<wbr/>Auth2 provider</span></a></li><li><a href="#configuration-options"><span>Configuration options</span></a></li><li><a href="#mcp-server-runtime"><span>MCP <wbr/>Server runtime</span></a></li></ul></li><li><a href="#breaking-change-removed"><span>Breaking <wbr/>Change: <wbr/>Removed</span></a></li><li><ul><li><a href="#impact-on-lambda-handlers-"><span>Impact on <wbr/>Lambda handlers ()</span></a></li><li><a href="#impact-on-"><span>Impact on ()</span></a></li></ul></li><li><a href="#contribute"><span>Contribute</span></a></li><li><ul><li><a href="#how-to-contribute-to-cdk-serverless"><span>How to contribute to <wbr/>CDK <wbr/>Serverless</span></a></li><li><ul><li><a href="#did-you-find-a-bug"><span>Did you find a bug?</span></a></li><li><a href="#did-you-write-a-patch-that-fixes-a-bug"><span>Did you write a patch that fixes a bug?</span></a></li><li><a href="#did-you-fix-whitespace-format-code-or-make-a-purely-cosmetic-patch"><span>Did you fix whitespace, format code, or make a purely cosmetic patch?</span></a></li><li><a href="#do-you-intend-to-add-a-new-feature-or-change-an-existing-one"><span>Do you intend to add a new feature or change an existing one?</span></a></li><li><a href="#do-you-want-to-contribute-to-the-cdk-serverless-documentation"><span>Do you want to contribute to the <wbr/>CDK <wbr/>Serverless documentation?</span></a></li></ul></li></ul></li><li><a href="#authors"><span>Authors</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">cdk-serverless</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
@@ -55,6 +55,117 @@
55
55
  <pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-4">IntegTestUtil</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&#39;cdk-serverless/tests/integ-test-util&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-6">// Initialize with your stack outputs</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">test</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">IntegTestUtil</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-4">region:</span><span class="hl-1"> </span><span class="hl-2">&#39;us-east-1&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">apiOptions:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">baseURL:</span><span class="hl-1"> </span><span class="hl-2">&#39;https://api.example.com&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">authOptions:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">userPoolId:</span><span class="hl-1"> </span><span class="hl-2">&#39;us-east-1_xxxxx&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">userPoolClientId:</span><span class="hl-1"> </span><span class="hl-2">&#39;xxxxxxxx&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">identityPoolId:</span><span class="hl-1"> </span><span class="hl-2">&#39;us-east-1:xxxxxxxx&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">datastoreOptions:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">tableName:</span><span class="hl-1"> </span><span class="hl-2">&#39;MyTable&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-6">// Create and authenticate a test user</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">createUser</span><span class="hl-1">(</span><span class="hl-2">&#39;test@example.com&#39;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">&#39;custom:attribute&#39;</span><span class="hl-4">:</span><span class="hl-1"> </span><span class="hl-2">&#39;value&#39;</span><span class="hl-1">,</span><br/><span class="hl-1">}, [</span><span class="hl-2">&#39;admin&#39;</span><span class="hl-1">]);</span><br/><br/><span class="hl-6">// Get an authenticated API client</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">client</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">getAuthenticatedClient</span><span class="hl-1">(</span><span class="hl-2">&#39;test@example.com&#39;</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// Make API calls</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">response</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">client</span><span class="hl-1">.</span><span class="hl-0">get</span><span class="hl-1">(</span><span class="hl-2">&#39;/items&#39;</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// Clean up test data</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">cleanupItems</span><span class="hl-1">();</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">test</span><span class="hl-1">.</span><span class="hl-0">removeUser</span><span class="hl-1">(</span><span class="hl-2">&#39;test@example.com&#39;</span><span class="hl-1">);</span>
56
56
  </code><button type="button">Copy</button></pre>
57
57
 
58
+ <h2 id="mcp-auth" class="tsd-anchor-link">MCP Auth<a href="#mcp-auth" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
59
+ <p>CDK Serverless includes built-in support for adding <a href="https://spec.modelcontextprotocol.io">Model Context Protocol (MCP)</a> OAuth authentication to your API. This enables MCP clients like Claude and ChatGPT to authenticate with your API using standard OAuth 2.0 flows.</p>
60
+ <p>When activated, the following endpoints are automatically added to your OpenAPI spec:</p>
61
+ <table>
62
+ <thead>
63
+ <tr>
64
+ <th>Endpoint</th>
65
+ <th>Method</th>
66
+ <th>RFC</th>
67
+ <th>Purpose</th>
68
+ </tr>
69
+ </thead>
70
+ <tbody>
71
+ <tr>
72
+ <td><code>/.well-known/oauth-protected-resource</code></td>
73
+ <td>GET</td>
74
+ <td>RFC 9728</td>
75
+ <td>Resource metadata discovery</td>
76
+ </tr>
77
+ <tr>
78
+ <td><code>/.well-known/oauth-authorization-server</code></td>
79
+ <td>GET</td>
80
+ <td>RFC 8414</td>
81
+ <td>Authorization server metadata</td>
82
+ </tr>
83
+ <tr>
84
+ <td><code>/oauth/authorize</code></td>
85
+ <td>GET</td>
86
+ <td>—</td>
87
+ <td>Authorize proxy (redirect to upstream)</td>
88
+ </tr>
89
+ <tr>
90
+ <td><code>/oauth/token</code></td>
91
+ <td>POST</td>
92
+ <td>—</td>
93
+ <td>Token proxy (forward to upstream)</td>
94
+ </tr>
95
+ <tr>
96
+ <td><code>/oauth/register</code></td>
97
+ <td>POST</td>
98
+ <td>RFC 7591</td>
99
+ <td>Dynamic client registration</td>
100
+ </tr>
101
+ </tbody>
102
+ </table>
103
+ <p>All MCP auth endpoints are anonymous (no API authorizer applied).</p>
104
+ <h3 id="with-cognito" class="tsd-anchor-link">With Cognito<a href="#with-cognito" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
105
+ <p>MCP clients like Claude enforce that all OAuth endpoints (discovery, authorize, token, register) live on the <strong>same origin</strong> as the API itself. Cognito's hosted UI lives on a different domain (<code>auth.example.com</code>), so MCP clients cannot talk to it directly. Additionally:</p>
106
+ <ul>
107
+ <li>Cognito Managed Login v2 requires the RFC 8707 <code>resource</code> parameter for custom scopes in authorize requests — MCP clients do not send this parameter.</li>
108
+ <li>MCP clients construct the token endpoint URL from the OAuth metadata <code>issuer</code> field rather than using the explicit <code>token_endpoint</code> — so the token exchange must be proxied through the API domain.</li>
109
+ <li>Dynamic Client Registration (RFC 7591) is not natively supported by Cognito.</li>
110
+ </ul>
111
+ <p>The MCP auth proxy solves all three problems: it serves discovery metadata on the API domain, strips unsupported parameters before forwarding to Cognito, and implements a simplified registration endpoint that returns a pre-provisioned client ID.</p>
112
+ <p>If your API already uses <code>CognitoAuthentication</code>, add MCP auth with minimal config — a dedicated user pool client is created automatically:</p>
113
+ <pre><code class="typescript"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">api</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">TestApiRestApi</span><span class="hl-1">(</span><span class="hl-5">this</span><span class="hl-1">, </span><span class="hl-2">&#39;Api&#39;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-4">stageName:</span><span class="hl-1"> </span><span class="hl-2">&#39;dev&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">domainName:</span><span class="hl-1"> </span><span class="hl-2">&#39;example.com&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">apiHostname:</span><span class="hl-1"> </span><span class="hl-2">&#39;api&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">authentication:</span><span class="hl-1"> </span><span class="hl-4">cognitoAuth</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">cors:</span><span class="hl-1"> </span><span class="hl-5">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">mcpAuth:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">cognito:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">auth:</span><span class="hl-1"> </span><span class="hl-4">cognitoAuth</span><span class="hl-1">, </span><span class="hl-6">// your CognitoAuthentication construct</span><br/><span class="hl-1"> </span><span class="hl-4">authDomain:</span><span class="hl-1"> </span><span class="hl-2">&#39;auth.example.com&#39;</span><span class="hl-1">, </span><span class="hl-6">// Cognito custom/hosted domain (required)</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">serverInfo:</span><span class="hl-1"> { </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-mcp-server&#39;</span><span class="hl-1">, </span><span class="hl-4">version:</span><span class="hl-1"> </span><span class="hl-2">&#39;1.0.0&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span>
114
+ </code><button type="button">Copy</button></pre>
115
+
116
+ <p>The <code>apiDomain</code> is derived from the RestApi's own domain config (<code>apiHostname</code> + <code>domainName</code>), and <code>stageName</code> is reused — no duplication needed.</p>
117
+ <h3 id="with-any-oauth2-provider" class="tsd-anchor-link">With any OAuth2 provider<a href="#with-any-oauth2-provider" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
118
+ <p>For non-Cognito providers, use <code>generic</code> mode with explicit endpoint URLs:</p>
119
+ <pre><code class="typescript"><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">api</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">TestApiRestApi</span><span class="hl-1">(</span><span class="hl-5">this</span><span class="hl-1">, </span><span class="hl-2">&#39;Api&#39;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-6">// ...</span><br/><span class="hl-1"> </span><span class="hl-4">mcpAuth:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">generic:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">authorizeEndpoint:</span><span class="hl-1"> </span><span class="hl-2">&#39;https://auth.example.com/authorize&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">tokenEndpoint:</span><span class="hl-1"> </span><span class="hl-2">&#39;https://auth.example.com/token&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">clientId:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-pre-provisioned-client-id&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">serverInfo:</span><span class="hl-1"> { </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-mcp-server&#39;</span><span class="hl-1">, </span><span class="hl-4">version:</span><span class="hl-1"> </span><span class="hl-2">&#39;1.0.0&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">});</span>
120
+ </code><button type="button">Copy</button></pre>
121
+
122
+ <h3 id="configuration-options" class="tsd-anchor-link">Configuration options<a href="#configuration-options" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
123
+ <table>
124
+ <thead>
125
+ <tr>
126
+ <th>Option</th>
127
+ <th>Default</th>
128
+ <th>Description</th>
129
+ </tr>
130
+ </thead>
131
+ <tbody>
132
+ <tr>
133
+ <td><code>serverInfo</code></td>
134
+ <td>(required)</td>
135
+ <td><code>{ name, version }</code> returned in MCP initialize</td>
136
+ </tr>
137
+ <tr>
138
+ <td><code>allowedRedirectUris</code></td>
139
+ <td>Claude + ChatGPT callbacks</td>
140
+ <td>Allowlist for dynamic registration</td>
141
+ </tr>
142
+ <tr>
143
+ <td><code>protocolVersions</code></td>
144
+ <td><code>['2025-11-25', '2025-03-26', '2024-11-05']</code></td>
145
+ <td>Supported MCP versions</td>
146
+ </tr>
147
+ <tr>
148
+ <td><code>scopes</code></td>
149
+ <td><code>['openid', 'email', 'profile']</code></td>
150
+ <td>Advertised OAuth scopes</td>
151
+ </tr>
152
+ <tr>
153
+ <td><code>stripParameters</code></td>
154
+ <td><code>['resource']</code></td>
155
+ <td>Params stripped from authorize/token proxying</td>
156
+ </tr>
157
+ <tr>
158
+ <td><code>lambdaOptions</code></td>
159
+ <td>—</td>
160
+ <td>Lambda config for MCP auth handlers</td>
161
+ </tr>
162
+ </tbody>
163
+ </table>
164
+ <h3 id="mcp-server-runtime" class="tsd-anchor-link">MCP Server runtime<a href="#mcp-server-runtime" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3>
165
+ <p>The <code>cdk-serverless/mcp-auth</code> module also exports a JSON-RPC server for implementing the MCP tool endpoint itself:</p>
166
+ <pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-4">createMcpServer</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&#39;cdk-serverless/mcp-auth&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">server</span><span class="hl-1"> = </span><span class="hl-0">createMcpServer</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-4">serverInfo:</span><span class="hl-1"> { </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;my-server&#39;</span><span class="hl-1">, </span><span class="hl-4">version:</span><span class="hl-1"> </span><span class="hl-2">&#39;1.0.0&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">protocolVersions:</span><span class="hl-1"> [</span><span class="hl-2">&#39;2025-11-25&#39;</span><span class="hl-1">],</span><br/><span class="hl-1"> </span><span class="hl-4">resolver:</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">async</span><span class="hl-1"> </span><span class="hl-0">resolve</span><span class="hl-1">(</span><span class="hl-4">headers</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-6">// Validate Bearer token, return principal or throw McpUnauthorizedError</span><br/><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">token</span><span class="hl-1"> = </span><span class="hl-4">headers</span><span class="hl-1">.</span><span class="hl-4">authorization</span><span class="hl-1">?.</span><span class="hl-0">replace</span><span class="hl-1">(</span><span class="hl-2">&#39;Bearer &#39;</span><span class="hl-1">, </span><span class="hl-2">&#39;&#39;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (!</span><span class="hl-4">token</span><span class="hl-1">) </span><span class="hl-3">throw</span><span class="hl-1"> </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-0">McpUnauthorizedError</span><span class="hl-1">(</span><span class="hl-2">&#39;Bearer&#39;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">return</span><span class="hl-1"> </span><span class="hl-0">verifyToken</span><span class="hl-1">(</span><span class="hl-4">token</span><span class="hl-1">);</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> </span><span class="hl-4">tools:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;search&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">description:</span><span class="hl-1"> </span><span class="hl-2">&#39;Search documents&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-4">inputSchema:</span><span class="hl-1"> { </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-2">&#39;object&#39;</span><span class="hl-1">, </span><span class="hl-4">properties:</span><span class="hl-1"> { </span><span class="hl-4">query:</span><span class="hl-1"> { </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-2">&#39;string&#39;</span><span class="hl-1"> } } },</span><br/><span class="hl-1"> </span><span class="hl-5">async</span><span class="hl-1"> </span><span class="hl-0">invoke</span><span class="hl-1">(</span><span class="hl-4">principal</span><span class="hl-1">, </span><span class="hl-4">args</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">results</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">search</span><span class="hl-1">(</span><span class="hl-4">principal</span><span class="hl-1">, (</span><span class="hl-4">args</span><span class="hl-1"> </span><span class="hl-3">as</span><span class="hl-1"> </span><span class="hl-8">any</span><span class="hl-1">).</span><span class="hl-4">query</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">return</span><span class="hl-1"> { </span><span class="hl-4">content:</span><span class="hl-1"> [{ </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-2">&#39;text&#39;</span><span class="hl-1">, </span><span class="hl-4">text:</span><span class="hl-1"> </span><span class="hl-7">JSON</span><span class="hl-1">.</span><span class="hl-0">stringify</span><span class="hl-1">(</span><span class="hl-4">results</span><span class="hl-1">) }] };</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> ],</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-6">// In your Lambda handler:</span><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-7">response</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-4">server</span><span class="hl-1">.</span><span class="hl-0">handle</span><span class="hl-1">(</span><span class="hl-4">parsedBody</span><span class="hl-1">, </span><span class="hl-4">event</span><span class="hl-1">.</span><span class="hl-4">headers</span><span class="hl-1">);</span>
167
+ </code><button type="button">Copy</button></pre>
168
+
58
169
  <h2 id="breaking-change-removed" class="tsd-anchor-link">Breaking Change: <code>axios</code> Removed<a href="#breaking-change-removed" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
59
170
  <p>CDK Serverless no longer depends on <code>axios</code>. The library now uses the
60
171
  platform-native <code>fetch</code> API (stable in Node.js 18+; the Lambda functions
@@ -136,4 +247,4 @@ issue.</p>
136
247
  </ul>
137
248
  <h2 id="authors" class="tsd-anchor-link">Authors<a href="#authors" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2>
138
249
  <p>Brought to you by <a href="https://taimos.de">Taimos</a></p>
139
- </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#cdk-serverless"><span>CDK <wbr/>Serverless</span></a><ul><li><ul><li><a href="#features"><span>Features</span></a></li></ul></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#adding-projen-constructs"><span>Adding projen constructs</span></a></li><li><a href="#using-the-cdk-serverless-l3-constructs"><span>Using the <wbr/>CDK serverless <wbr/>L3 constructs</span></a></li></ul></li><li><a href="#testing-utilities"><span>Testing <wbr/>Utilities</span></a></li><li><ul><li><a href="#lambdatestutil"><span>Lambda<wbr/>Test<wbr/>Util</span></a></li><li><ul><li><a href="#rest-api-testing"><span>REST <wbr/>API <wbr/>Testing</span></a></li><li><a href="#graphql-testing"><span>Graph<wbr/>QL <wbr/>Testing</span></a></li></ul></li><li><a href="#integtestutil"><span>Integ<wbr/>Test<wbr/>Util</span></a></li></ul></li><li><a href="#breaking-change-removed"><span>Breaking <wbr/>Change: <wbr/>Removed</span></a></li><li><ul><li><a href="#impact-on-lambda-handlers-"><span>Impact on <wbr/>Lambda handlers ()</span></a></li><li><a href="#impact-on-"><span>Impact on ()</span></a></li></ul></li><li><a href="#contribute"><span>Contribute</span></a></li><li><ul><li><a href="#how-to-contribute-to-cdk-serverless"><span>How to contribute to <wbr/>CDK <wbr/>Serverless</span></a></li><li><ul><li><a href="#did-you-find-a-bug"><span>Did you find a bug?</span></a></li><li><a href="#did-you-write-a-patch-that-fixes-a-bug"><span>Did you write a patch that fixes a bug?</span></a></li><li><a href="#did-you-fix-whitespace-format-code-or-make-a-purely-cosmetic-patch"><span>Did you fix whitespace, format code, or make a purely cosmetic patch?</span></a></li><li><a href="#do-you-intend-to-add-a-new-feature-or-change-an-existing-one"><span>Do you intend to add a new feature or change an existing one?</span></a></li><li><a href="#do-you-want-to-contribute-to-the-cdk-serverless-documentation"><span>Do you want to contribute to the <wbr/>CDK <wbr/>Serverless documentation?</span></a></li></ul></li></ul></li><li><a href="#authors"><span>Authors</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">cdk-serverless</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
250
+ </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#cdk-serverless"><span>CDK <wbr/>Serverless</span></a><ul><li><ul><li><a href="#features"><span>Features</span></a></li></ul></li><li><a href="#quick-start"><span>Quick <wbr/>Start</span></a></li><li><ul><li><a href="#adding-projen-constructs"><span>Adding projen constructs</span></a></li><li><a href="#using-the-cdk-serverless-l3-constructs"><span>Using the <wbr/>CDK serverless <wbr/>L3 constructs</span></a></li></ul></li><li><a href="#testing-utilities"><span>Testing <wbr/>Utilities</span></a></li><li><ul><li><a href="#lambdatestutil"><span>Lambda<wbr/>Test<wbr/>Util</span></a></li><li><ul><li><a href="#rest-api-testing"><span>REST <wbr/>API <wbr/>Testing</span></a></li><li><a href="#graphql-testing"><span>Graph<wbr/>QL <wbr/>Testing</span></a></li></ul></li><li><a href="#integtestutil"><span>Integ<wbr/>Test<wbr/>Util</span></a></li></ul></li><li><a href="#mcp-auth"><span>MCP <wbr/>Auth</span></a></li><li><ul><li><a href="#with-cognito"><span>With <wbr/>Cognito</span></a></li><li><a href="#with-any-oauth2-provider"><span>With any <wbr/>O<wbr/>Auth2 provider</span></a></li><li><a href="#configuration-options"><span>Configuration options</span></a></li><li><a href="#mcp-server-runtime"><span>MCP <wbr/>Server runtime</span></a></li></ul></li><li><a href="#breaking-change-removed"><span>Breaking <wbr/>Change: <wbr/>Removed</span></a></li><li><ul><li><a href="#impact-on-lambda-handlers-"><span>Impact on <wbr/>Lambda handlers ()</span></a></li><li><a href="#impact-on-"><span>Impact on ()</span></a></li></ul></li><li><a href="#contribute"><span>Contribute</span></a></li><li><ul><li><a href="#how-to-contribute-to-cdk-serverless"><span>How to contribute to <wbr/>CDK <wbr/>Serverless</span></a></li><li><ul><li><a href="#did-you-find-a-bug"><span>Did you find a bug?</span></a></li><li><a href="#did-you-write-a-patch-that-fixes-a-bug"><span>Did you write a patch that fixes a bug?</span></a></li><li><a href="#did-you-fix-whitespace-format-code-or-make-a-purely-cosmetic-patch"><span>Did you fix whitespace, format code, or make a purely cosmetic patch?</span></a></li><li><a href="#do-you-intend-to-add-a-new-feature-or-change-an-existing-one"><span>Do you intend to add a new feature or change an existing one?</span></a></li><li><a href="#do-you-want-to-contribute-to-the-cdk-serverless-documentation"><span>Do you want to contribute to the <wbr/>CDK <wbr/>Serverless documentation?</span></a></li></ul></li></ul></li><li><a href="#authors"><span>Authors</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">cdk-serverless</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
@@ -3,6 +3,8 @@ export * from './authentication';
3
3
  export * from './base-api';
4
4
  export * from './func';
5
5
  export * from './graphql';
6
+ export * from './mcp-auth';
7
+ export * from './mcp-cognito-auth';
6
8
  export * from './rest-api';
7
9
  export * from './table';
8
10
  export * from './workflow';
@@ -19,7 +19,9 @@ __exportStar(require("./authentication"), exports);
19
19
  __exportStar(require("./base-api"), exports);
20
20
  __exportStar(require("./func"), exports);
21
21
  __exportStar(require("./graphql"), exports);
22
+ __exportStar(require("./mcp-auth"), exports);
23
+ __exportStar(require("./mcp-cognito-auth"), exports);
22
24
  __exportStar(require("./rest-api"), exports);
23
25
  __exportStar(require("./table"), exports);
24
26
  __exportStar(require("./workflow"), exports);
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsOENBQTRCO0FBQzVCLG1EQUFpQztBQUNqQyw2Q0FBMkI7QUFDM0IseUNBQXVCO0FBQ3ZCLDRDQUEwQjtBQUMxQiw2Q0FBMkI7QUFDM0IsMENBQXdCO0FBQ3hCLDZDQUEyQiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYXNzZXQtY2RuJztcbmV4cG9ydCAqIGZyb20gJy4vYXV0aGVudGljYXRpb24nO1xuZXhwb3J0ICogZnJvbSAnLi9iYXNlLWFwaSc7XG5leHBvcnQgKiBmcm9tICcuL2Z1bmMnO1xuZXhwb3J0ICogZnJvbSAnLi9ncmFwaHFsJztcbmV4cG9ydCAqIGZyb20gJy4vcmVzdC1hcGknO1xuZXhwb3J0ICogZnJvbSAnLi90YWJsZSc7XG5leHBvcnQgKiBmcm9tICcuL3dvcmtmbG93JzsiXX0=
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsOENBQTRCO0FBQzVCLG1EQUFpQztBQUNqQyw2Q0FBMkI7QUFDM0IseUNBQXVCO0FBQ3ZCLDRDQUEwQjtBQUMxQiw2Q0FBMkI7QUFDM0IscURBQW1DO0FBQ25DLDZDQUEyQjtBQUMzQiwwQ0FBd0I7QUFDeEIsNkNBQTJCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9hc3NldC1jZG4nO1xuZXhwb3J0ICogZnJvbSAnLi9hdXRoZW50aWNhdGlvbic7XG5leHBvcnQgKiBmcm9tICcuL2Jhc2UtYXBpJztcbmV4cG9ydCAqIGZyb20gJy4vZnVuYyc7XG5leHBvcnQgKiBmcm9tICcuL2dyYXBocWwnO1xuZXhwb3J0ICogZnJvbSAnLi9tY3AtYXV0aCc7XG5leHBvcnQgKiBmcm9tICcuL21jcC1jb2duaXRvLWF1dGgnO1xuZXhwb3J0ICogZnJvbSAnLi9yZXN0LWFwaSc7XG5leHBvcnQgKiBmcm9tICcuL3RhYmxlJztcbmV4cG9ydCAqIGZyb20gJy4vd29ya2Zsb3cnO1xuIl19
@@ -0,0 +1,117 @@
1
+ import { Construct } from 'constructs';
2
+ import { LambdaFunction, LambdaOptions } from './func';
3
+ /**
4
+ * Configuration for the MCP Auth CDK construct.
5
+ * Service-agnostic: works with any OAuth2/OIDC provider.
6
+ */
7
+ export interface McpAuthProps {
8
+ /**
9
+ * The API domain that acts as the MCP OAuth issuer.
10
+ * All OAuth discovery endpoints will reference this domain.
11
+ * Example: 'api.example.com'
12
+ */
13
+ readonly apiDomain: string;
14
+ /**
15
+ * The upstream OAuth authorize endpoint URL.
16
+ * The authorize Lambda proxies (302 redirects) to this URL.
17
+ * Example: 'https://auth.example.com/oauth2/authorize'
18
+ */
19
+ readonly authorizeEndpoint: string;
20
+ /**
21
+ * The upstream OAuth token endpoint URL.
22
+ * The token Lambda proxies POST requests to this URL.
23
+ * Example: 'https://auth.example.com/oauth2/token'
24
+ */
25
+ readonly tokenEndpoint: string;
26
+ /**
27
+ * Allowed redirect URIs for dynamic client registration.
28
+ * Clients registering with URIs not in this list are rejected.
29
+ */
30
+ readonly allowedRedirectUris: string[];
31
+ /**
32
+ * The pre-provisioned OAuth client ID returned by the register endpoint.
33
+ */
34
+ readonly clientId: string;
35
+ /**
36
+ * MCP server info returned in the 'initialize' response.
37
+ */
38
+ readonly serverInfo: {
39
+ readonly name: string;
40
+ readonly version: string;
41
+ };
42
+ /**
43
+ * Supported MCP protocol versions (newest first).
44
+ * @default ['2025-11-25', '2025-03-26', '2024-11-05']
45
+ */
46
+ readonly protocolVersions?: string[];
47
+ /**
48
+ * OAuth scopes to advertise in discovery metadata.
49
+ * @default ['openid', 'email', 'profile']
50
+ */
51
+ readonly scopes?: string[];
52
+ /**
53
+ * Parameters to strip from authorize/token proxy requests.
54
+ * @default ['resource']
55
+ */
56
+ readonly stripParameters?: string[];
57
+ /**
58
+ * Additional environment variables to inject into all MCP auth Lambda functions.
59
+ */
60
+ readonly additionalEnv?: Record<string, string>;
61
+ /**
62
+ * Lambda function options for MCP auth handlers.
63
+ */
64
+ readonly lambdaOptions?: LambdaOptions;
65
+ /**
66
+ * Stage name for function naming and tagging.
67
+ */
68
+ readonly stageName: string;
69
+ }
70
+ /**
71
+ * Provides the Lambda function references for MCP OAuth endpoints.
72
+ * These can be wired into API Gateway (via RestApi integration)
73
+ * or used standalone.
74
+ */
75
+ export interface McpAuthFunctions {
76
+ /** GET /.well-known/oauth-protected-resource */
77
+ readonly protectedResource: LambdaFunction;
78
+ /** GET /.well-known/oauth-authorization-server */
79
+ readonly authorizationServer: LambdaFunction;
80
+ /** GET /oauth/authorize */
81
+ readonly authorize: LambdaFunction;
82
+ /** POST /oauth/token */
83
+ readonly token: LambdaFunction;
84
+ /** POST /oauth/register */
85
+ readonly register: LambdaFunction;
86
+ }
87
+ /**
88
+ * CDK construct that creates Lambda functions for the MCP OAuth façade.
89
+ * Service-agnostic — proxies authorize/token requests to any upstream
90
+ * OAuth2/OIDC provider.
91
+ *
92
+ * Use with `RestApi` by passing `mcpAuth` prop, which auto-injects the
93
+ * required paths into the OpenAPI spec and wires Lambda integrations.
94
+ *
95
+ * @example
96
+ * const mcpAuth = new McpAuth(this, 'McpAuth', {
97
+ * apiDomain: 'api.example.com',
98
+ * authorizeEndpoint: 'https://auth.example.com/oauth2/authorize',
99
+ * tokenEndpoint: 'https://auth.example.com/oauth2/token',
100
+ * allowedRedirectUris: ['https://claude.ai/oauth/callback'],
101
+ * clientId: 'my-client-id',
102
+ * serverInfo: { name: 'my-mcp-server', version: '1.0.0' },
103
+ * stageName: 'dev',
104
+ * });
105
+ */
106
+ export declare class McpAuth extends Construct {
107
+ /**
108
+ * The Lambda functions created for the OAuth endpoints.
109
+ */
110
+ readonly functions: McpAuthFunctions;
111
+ /**
112
+ * The environment variables map that should be injected into the MCP RPC
113
+ * handler Lambda (if you have one) so it can read MCP config at runtime.
114
+ */
115
+ readonly mcpEnvVars: Record<string, string>;
116
+ constructor(scope: Construct, id: string, props: McpAuthProps);
117
+ }