nitrostack 1.0.54 → 1.0.56

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 (220) hide show
  1. package/dist/cli/commands/init.d.ts.map +1 -1
  2. package/dist/cli/commands/init.js +14 -9
  3. package/dist/cli/commands/init.js.map +1 -1
  4. package/dist/widgets/hooks/index.d.ts +7 -0
  5. package/dist/widgets/hooks/index.d.ts.map +1 -0
  6. package/dist/widgets/hooks/index.js +7 -0
  7. package/dist/widgets/hooks/index.js.map +1 -0
  8. package/dist/widgets/hooks/use-display-mode.d.ts +11 -0
  9. package/dist/widgets/hooks/use-display-mode.d.ts.map +1 -0
  10. package/dist/widgets/hooks/use-display-mode.js +13 -0
  11. package/dist/widgets/hooks/use-display-mode.js.map +1 -0
  12. package/dist/widgets/hooks/use-max-height.d.ts +10 -0
  13. package/dist/widgets/hooks/use-max-height.d.ts.map +1 -0
  14. package/dist/widgets/hooks/use-max-height.js +13 -0
  15. package/dist/widgets/hooks/use-max-height.js.map +1 -0
  16. package/dist/widgets/hooks/use-openai-global.d.ts +12 -0
  17. package/dist/widgets/hooks/use-openai-global.d.ts.map +1 -0
  18. package/dist/widgets/hooks/use-openai-global.js +32 -0
  19. package/dist/widgets/hooks/use-openai-global.js.map +1 -0
  20. package/dist/widgets/hooks/use-theme.d.ts +10 -0
  21. package/dist/widgets/hooks/use-theme.d.ts.map +1 -0
  22. package/dist/widgets/hooks/use-theme.js +12 -0
  23. package/dist/widgets/hooks/use-theme.js.map +1 -0
  24. package/dist/widgets/hooks/use-widget-state.d.ts +18 -0
  25. package/dist/widgets/hooks/use-widget-state.d.ts.map +1 -0
  26. package/dist/widgets/hooks/use-widget-state.js +27 -0
  27. package/dist/widgets/hooks/use-widget-state.js.map +1 -0
  28. package/dist/widgets/hooks/useWidgetSDK.d.ts +47 -0
  29. package/dist/widgets/hooks/useWidgetSDK.d.ts.map +1 -0
  30. package/dist/widgets/hooks/useWidgetSDK.js +67 -0
  31. package/dist/widgets/hooks/useWidgetSDK.js.map +1 -0
  32. package/dist/widgets/index.d.ts +7 -1
  33. package/dist/widgets/index.d.ts.map +1 -1
  34. package/dist/widgets/index.js +11 -1
  35. package/dist/widgets/index.js.map +1 -1
  36. package/dist/widgets/runtime/WidgetLayout.d.ts +32 -0
  37. package/dist/widgets/runtime/WidgetLayout.d.ts.map +1 -0
  38. package/dist/widgets/runtime/WidgetLayout.js +143 -0
  39. package/dist/widgets/runtime/WidgetLayout.js.map +1 -0
  40. package/dist/widgets/runtime/widget-polyfill.d.ts +1 -0
  41. package/dist/widgets/runtime/widget-polyfill.d.ts.map +1 -0
  42. package/dist/widgets/runtime/widget-polyfill.js +28 -0
  43. package/dist/widgets/runtime/widget-polyfill.js.map +1 -0
  44. package/dist/widgets/sdk.d.ts +109 -0
  45. package/dist/widgets/sdk.d.ts.map +1 -0
  46. package/dist/widgets/sdk.js +221 -0
  47. package/dist/widgets/sdk.js.map +1 -0
  48. package/dist/widgets/types.d.ts +89 -0
  49. package/dist/widgets/types.d.ts.map +1 -0
  50. package/dist/widgets/types.js +8 -0
  51. package/dist/widgets/types.js.map +1 -0
  52. package/dist/widgets/utils/media-queries.d.ts +34 -0
  53. package/dist/widgets/utils/media-queries.d.ts.map +1 -0
  54. package/dist/widgets/utils/media-queries.js +42 -0
  55. package/dist/widgets/utils/media-queries.js.map +1 -0
  56. package/package.json +2 -2
  57. package/src/studio/app/chat/page.tsx +274 -137
  58. package/src/studio/app/globals.css +140 -64
  59. package/src/studio/branding.md +807 -0
  60. package/src/studio/components/WidgetRenderer.tsx +222 -16
  61. package/src/studio/lib/llm-service.ts +39 -39
  62. package/templates/typescript-oauth/.env.example +27 -0
  63. package/templates/typescript-oauth/README.md +226 -306
  64. package/templates/typescript-oauth/package-lock.json +4253 -0
  65. package/templates/typescript-oauth/package.json +10 -5
  66. package/templates/typescript-oauth/src/app.module.ts +39 -36
  67. package/templates/typescript-oauth/src/guards/oauth.guard.ts +0 -1
  68. package/templates/typescript-oauth/src/index.ts +22 -30
  69. package/templates/typescript-oauth/src/modules/flights/booking.tools.ts +323 -0
  70. package/templates/typescript-oauth/src/modules/flights/flights.module.ts +14 -0
  71. package/templates/typescript-oauth/src/modules/flights/flights.prompts.ts +231 -0
  72. package/templates/typescript-oauth/src/modules/flights/flights.resources.ts +215 -0
  73. package/templates/typescript-oauth/src/modules/flights/flights.tools.ts +457 -0
  74. package/templates/typescript-oauth/src/services/duffel.service.ts +285 -0
  75. package/templates/typescript-oauth/src/widgets/app/airport-search/page.tsx +270 -0
  76. package/templates/typescript-oauth/src/widgets/app/flight-details/page.tsx +261 -0
  77. package/templates/typescript-oauth/src/widgets/app/flight-search-results/page.tsx +378 -0
  78. package/templates/typescript-oauth/src/widgets/app/globals.css +167 -0
  79. package/templates/typescript-oauth/src/widgets/app/layout.tsx +6 -2
  80. package/templates/typescript-oauth/src/widgets/app/order-cancellation/page.tsx +207 -0
  81. package/templates/typescript-oauth/src/widgets/app/order-summary/page.tsx +245 -0
  82. package/templates/typescript-oauth/src/widgets/app/payment-confirmation/page.tsx +152 -0
  83. package/templates/typescript-oauth/src/widgets/app/seat-selection/page.tsx +486 -0
  84. package/templates/typescript-oauth/src/widgets/next-env.d.ts +5 -0
  85. package/templates/typescript-oauth/src/widgets/package-lock.json +155 -126
  86. package/templates/typescript-oauth/src/widgets/widget-manifest.json +374 -27
  87. package/templates/typescript-pizzaz/IMPLEMENTATION.md +98 -0
  88. package/templates/typescript-pizzaz/README.md +233 -0
  89. package/templates/typescript-pizzaz/package.json +31 -0
  90. package/templates/typescript-pizzaz/src/app.module.ts +28 -0
  91. package/templates/typescript-pizzaz/src/index.ts +30 -0
  92. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.data.ts +106 -0
  93. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.module.ts +11 -0
  94. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.service.ts +60 -0
  95. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.tools.ts +197 -0
  96. package/templates/typescript-pizzaz/src/widgets/app/layout.tsx +18 -0
  97. package/templates/typescript-pizzaz/src/widgets/app/pizza-list/page.tsx +272 -0
  98. package/templates/typescript-pizzaz/src/widgets/app/pizza-map/page.tsx +216 -0
  99. package/templates/typescript-pizzaz/src/widgets/app/pizza-shop/page.tsx +374 -0
  100. package/templates/typescript-pizzaz/src/widgets/components/CompactShopCard.tsx +144 -0
  101. package/templates/typescript-pizzaz/src/widgets/components/PizzaCard.tsx +191 -0
  102. package/templates/typescript-pizzaz/src/widgets/package.json +30 -0
  103. package/templates/typescript-pizzaz/src/widgets/widget-manifest.json +253 -0
  104. package/templates/typescript-pizzaz/tsconfig.json +30 -0
  105. package/templates/typescript-starter/src/modules/calculator/calculator.resources.ts +0 -1
  106. package/templates/typescript-starter/src/widgets/app/calculator-result/page.tsx +102 -56
  107. package/templates/typescript-starter/src/widgets/app/layout.tsx +6 -2
  108. package/templates/typescript-auth/AI_AGENT_CLI_REFERENCE.md +0 -702
  109. package/templates/typescript-auth/AI_AGENT_SDK_REFERENCE.md +0 -1260
  110. package/templates/typescript-auth/README.md +0 -402
  111. package/templates/typescript-auth/package.json +0 -36
  112. package/templates/typescript-auth/src/app.module.ts +0 -103
  113. package/templates/typescript-auth/src/db/database.ts +0 -160
  114. package/templates/typescript-auth/src/db/seed.ts +0 -374
  115. package/templates/typescript-auth/src/db/setup.ts +0 -87
  116. package/templates/typescript-auth/src/events/analytics.service.ts +0 -52
  117. package/templates/typescript-auth/src/events/notification.service.ts +0 -40
  118. package/templates/typescript-auth/src/filters/global-exception.filter.ts +0 -28
  119. package/templates/typescript-auth/src/guards/README.md +0 -75
  120. package/templates/typescript-auth/src/guards/jwt.guard.ts +0 -105
  121. package/templates/typescript-auth/src/health/database.health.ts +0 -41
  122. package/templates/typescript-auth/src/index.ts +0 -29
  123. package/templates/typescript-auth/src/interceptors/transform.interceptor.ts +0 -24
  124. package/templates/typescript-auth/src/middleware/logging.middleware.ts +0 -42
  125. package/templates/typescript-auth/src/modules/addresses/addresses.module.ts +0 -16
  126. package/templates/typescript-auth/src/modules/addresses/addresses.prompts.ts +0 -114
  127. package/templates/typescript-auth/src/modules/addresses/addresses.resources.ts +0 -40
  128. package/templates/typescript-auth/src/modules/addresses/addresses.tools.ts +0 -284
  129. package/templates/typescript-auth/src/modules/auth/auth.module.ts +0 -16
  130. package/templates/typescript-auth/src/modules/auth/auth.prompts.ts +0 -147
  131. package/templates/typescript-auth/src/modules/auth/auth.resources.ts +0 -84
  132. package/templates/typescript-auth/src/modules/auth/auth.tools.ts +0 -139
  133. package/templates/typescript-auth/src/modules/cart/cart.module.ts +0 -16
  134. package/templates/typescript-auth/src/modules/cart/cart.prompts.ts +0 -95
  135. package/templates/typescript-auth/src/modules/cart/cart.resources.ts +0 -44
  136. package/templates/typescript-auth/src/modules/cart/cart.tools.ts +0 -277
  137. package/templates/typescript-auth/src/modules/orders/orders.module.ts +0 -16
  138. package/templates/typescript-auth/src/modules/orders/orders.prompts.ts +0 -88
  139. package/templates/typescript-auth/src/modules/orders/orders.resources.ts +0 -48
  140. package/templates/typescript-auth/src/modules/orders/orders.tools.ts +0 -303
  141. package/templates/typescript-auth/src/modules/products/products.module.ts +0 -16
  142. package/templates/typescript-auth/src/modules/products/products.prompts.ts +0 -146
  143. package/templates/typescript-auth/src/modules/products/products.resources.ts +0 -98
  144. package/templates/typescript-auth/src/modules/products/products.tools.ts +0 -266
  145. package/templates/typescript-auth/src/pipes/validation.pipe.ts +0 -42
  146. package/templates/typescript-auth/src/services/database.service.ts +0 -90
  147. package/templates/typescript-auth/src/widgets/app/add-to-cart/page.tsx +0 -122
  148. package/templates/typescript-auth/src/widgets/app/address-added/page.tsx +0 -116
  149. package/templates/typescript-auth/src/widgets/app/address-deleted/page.tsx +0 -105
  150. package/templates/typescript-auth/src/widgets/app/address-list/page.tsx +0 -139
  151. package/templates/typescript-auth/src/widgets/app/address-updated/page.tsx +0 -153
  152. package/templates/typescript-auth/src/widgets/app/cart-cleared/page.tsx +0 -86
  153. package/templates/typescript-auth/src/widgets/app/cart-updated/page.tsx +0 -116
  154. package/templates/typescript-auth/src/widgets/app/categories/page.tsx +0 -134
  155. package/templates/typescript-auth/src/widgets/app/layout.tsx +0 -21
  156. package/templates/typescript-auth/src/widgets/app/login-result/page.tsx +0 -129
  157. package/templates/typescript-auth/src/widgets/app/order-confirmation/page.tsx +0 -231
  158. package/templates/typescript-auth/src/widgets/app/order-details/page.tsx +0 -225
  159. package/templates/typescript-auth/src/widgets/app/order-history/page.tsx +0 -218
  160. package/templates/typescript-auth/src/widgets/app/product-card/page.tsx +0 -121
  161. package/templates/typescript-auth/src/widgets/app/products-grid/page.tsx +0 -198
  162. package/templates/typescript-auth/src/widgets/app/shopping-cart/page.tsx +0 -187
  163. package/templates/typescript-auth/src/widgets/app/whoami/page.tsx +0 -165
  164. package/templates/typescript-auth/src/widgets/next.config.js +0 -38
  165. package/templates/typescript-auth/src/widgets/package.json +0 -18
  166. package/templates/typescript-auth/src/widgets/styles/ecommerce.ts +0 -169
  167. package/templates/typescript-auth/src/widgets/tsconfig.json +0 -28
  168. package/templates/typescript-auth/src/widgets/types/tool-data.ts +0 -141
  169. package/templates/typescript-auth/src/widgets/widget-manifest.json +0 -464
  170. package/templates/typescript-auth/tsconfig.json +0 -27
  171. package/templates/typescript-auth-api-key/AI_AGENT_CLI_REFERENCE.md +0 -701
  172. package/templates/typescript-auth-api-key/AI_AGENT_SDK_REFERENCE.md +0 -1260
  173. package/templates/typescript-auth-api-key/README.md +0 -485
  174. package/templates/typescript-auth-api-key/package.json +0 -21
  175. package/templates/typescript-auth-api-key/src/app.module.ts +0 -38
  176. package/templates/typescript-auth-api-key/src/guards/apikey.guard.ts +0 -47
  177. package/templates/typescript-auth-api-key/src/guards/multi-auth.guard.ts +0 -157
  178. package/templates/typescript-auth-api-key/src/index.ts +0 -47
  179. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.module.ts +0 -12
  180. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.prompts.ts +0 -73
  181. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.resources.ts +0 -60
  182. package/templates/typescript-auth-api-key/src/modules/calculator/calculator.tools.ts +0 -71
  183. package/templates/typescript-auth-api-key/src/modules/demo/demo.module.ts +0 -18
  184. package/templates/typescript-auth-api-key/src/modules/demo/demo.tools.ts +0 -155
  185. package/templates/typescript-auth-api-key/src/modules/demo/multi-auth.tools.ts +0 -123
  186. package/templates/typescript-auth-api-key/src/widgets/app/calculator-operations/page.tsx +0 -133
  187. package/templates/typescript-auth-api-key/src/widgets/app/calculator-result/page.tsx +0 -134
  188. package/templates/typescript-auth-api-key/src/widgets/app/layout.tsx +0 -14
  189. package/templates/typescript-auth-api-key/src/widgets/package.json +0 -24
  190. package/templates/typescript-auth-api-key/src/widgets/widget-manifest.json +0 -48
  191. package/templates/typescript-auth-api-key/tsconfig.json +0 -23
  192. package/templates/typescript-oauth/OAUTH_SETUP.md +0 -592
  193. package/templates/typescript-oauth/src/modules/demo/demo.module.ts +0 -16
  194. package/templates/typescript-oauth/src/modules/demo/demo.tools.ts +0 -190
  195. package/templates/typescript-oauth/src/widgets/app/calculator-operations/page.tsx +0 -133
  196. package/templates/typescript-oauth/src/widgets/app/calculator-result/page.tsx +0 -134
  197. package/templates/typescript-oauth/src/widgets/out/404.html +0 -1
  198. package/templates/typescript-oauth/src/widgets/out/_next/static/WU9THacVqL52RZbrZOLS1/_buildManifest.js +0 -1
  199. package/templates/typescript-oauth/src/widgets/out/_next/static/WU9THacVqL52RZbrZOLS1/_ssgManifest.js +0 -1
  200. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/117-eb57c7ef86f964a4.js +0 -2
  201. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/app/_not-found/page-dcb83ba3e4d0aafd.js +0 -1
  202. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/app/calculator-operations/page-b8913a740073ea8a.js +0 -1
  203. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/app/calculator-result/page-ddaaab2fce95dea2.js +0 -1
  204. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/app/layout-cbd3ebdc4ecc5247.js +0 -1
  205. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/fd9d1056-749e5812300142af.js +0 -1
  206. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
  207. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/main-76df43fcef3db344.js +0 -1
  208. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/main-app-f9c40224d04023c5.js +0 -1
  209. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
  210. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
  211. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  212. package/templates/typescript-oauth/src/widgets/out/_next/static/chunks/webpack-100b9e646d9c912e.js +0 -1
  213. package/templates/typescript-oauth/src/widgets/out/calculator-operations.html +0 -1
  214. package/templates/typescript-oauth/src/widgets/out/calculator-operations.txt +0 -7
  215. package/templates/typescript-oauth/src/widgets/out/calculator-result.html +0 -1
  216. package/templates/typescript-oauth/src/widgets/out/calculator-result.txt +0 -7
  217. package/templates/typescript-starter/src/widgets/app/calculator-operations/page.tsx +0 -133
  218. /package/templates/{typescript-auth-api-key → typescript-oauth}/src/health/system.health.ts +0 -0
  219. /package/templates/{typescript-auth-api-key → typescript-pizzaz}/src/widgets/next.config.js +0 -0
  220. /package/templates/{typescript-auth-api-key → typescript-pizzaz}/src/widgets/tsconfig.json +0 -0
@@ -1,485 +0,0 @@
1
- # API Key Authentication MCP Server
2
-
3
- A complete example of building an MCP server with **API key authentication** using NitroStack.
4
-
5
- ## 🎯 What You'll Learn
6
-
7
- - ✅ How to add API key authentication to your MCP server
8
- - ✅ How to create public and protected tools
9
- - ✅ How to use `ApiKeyModule` and `ApiKeyGuard`
10
- - ✅ How to test API key auth in NitroStack Studio
11
- - ✅ How to combine JWT and API key authentication (multi-auth)
12
-
13
- ## 🔑 Test API Keys
14
-
15
- This template provides **test API keys** for immediate testing:
16
-
17
- ```
18
- sk_test_public_demo_key_12345
19
- sk_test_admin_demo_key_67890
20
- ```
21
-
22
- ⚠️ **Important**: These are demo keys only. Never use them in production!
23
-
24
- ## 📦 Installation
25
-
26
- ```bash
27
- # Install dependencies
28
- npm install
29
-
30
- # Build the project
31
- npm run build
32
-
33
- # Run in development mode
34
- npm run dev
35
- ```
36
-
37
- ## 🚀 Quick Start
38
-
39
- ### 1. Start the Server
40
-
41
- ```bash
42
- npm run build
43
- nitrostack dev
44
- ```
45
-
46
- The server will start with API key authentication enabled in dual transport mode (STDIO + HTTP on port 3002).
47
-
48
- > 💡 **Dual Transport**: Your server exposes tools via both STDIO (for direct connections) and HTTP (for remote access on port 3002). Switch between transports in Studio → Settings.
49
-
50
- ### 2. Open NitroStack Studio
51
-
52
- Navigate to `http://localhost:3000` (Studio should auto-open)
53
-
54
- ### 3. Set Your API Key
55
-
56
- 1. Go to **Auth** tab in Studio
57
- 2. Find the **API Key** section
58
- 3. Paste one of the test keys:
59
- ```
60
- sk_test_public_demo_key_12345
61
- ```
62
- 4. Click **Set Key**
63
-
64
- ### 4. Test the Tools
65
-
66
- #### Try a Public Tool (No Auth Required)
67
- 1. Go to **Tools** tab
68
- 2. Select `get_public_info`
69
- 3. Enter any topic
70
- 4. Execute ✓ - Works without API key!
71
-
72
- #### Try a Protected Tool (Auth Required)
73
- 1. Select `get_protected_data`
74
- 2. Choose data type: `user`, `account`, or `settings`
75
- 3. Execute ✓ - Works with valid API key!
76
- 4. Try clearing your API key → You'll get an authentication error
77
-
78
- ## 🏗️ Project Structure
79
-
80
- ```
81
- typescript-auth-api-key/
82
- ├── src/
83
- │ ├── guards/
84
- │ │ └── apikey.guard.ts # API key validation guard
85
- │ ├── modules/
86
- │ │ └── demo/
87
- │ │ ├── demo.module.ts # Demo module
88
- │ │ └── demo.tools.ts # Example tools
89
- │ ├── app.module.ts # Root module
90
- │ └── index.ts # Main entry point (ApiKeyModule setup)
91
- ├── .env # Test API keys
92
- ├── package.json
93
- ├── tsconfig.json
94
- └── README.md
95
- ```
96
-
97
- ## 🛡️ How API Key Auth Works
98
-
99
- ### 1. Configure ApiKeyModule
100
-
101
- In `src/index.ts`:
102
-
103
- ```typescript
104
- const app = await McpApplicationFactory.create(AppModule, {
105
- // Enable API key authentication
106
- apiKey: ApiKeyModule.forRoot({
107
- keysEnvPrefix: 'API_KEY', // Reads API_KEY_1, API_KEY_2, etc.
108
- headerName: 'x-api-key',
109
- metadataField: 'apiKey',
110
- }),
111
- });
112
- ```
113
-
114
- ### 2. Create an API Key Guard
115
-
116
- In `src/guards/apikey.guard.ts`:
117
-
118
- ```typescript
119
- export class ApiKeyGuard implements Guard {
120
- async canActivate(context: ExecutionContext): Promise<boolean> {
121
- const apiKey = context.metadata?.apiKey;
122
-
123
- if (!apiKey) {
124
- throw new Error('API key required');
125
- }
126
-
127
- const isValid = await ApiKeyModule.validate(apiKey);
128
-
129
- if (!isValid) {
130
- throw new Error('Invalid API key');
131
- }
132
-
133
- context.auth = {
134
- subject: `apikey_${apiKey.substring(0, 12)}`,
135
- scopes: ['*'],
136
- };
137
-
138
- return true;
139
- }
140
- }
141
- ```
142
-
143
- ### 3. Protect Your Tools
144
-
145
- ```typescript
146
- @Injectable()
147
- export class DemoTools {
148
-
149
- // PUBLIC: Anyone can call
150
- @Tool({ name: 'get_public_info' })
151
- async getPublicInfo() {
152
- return { data: 'public' };
153
- }
154
-
155
- // PROTECTED: Requires API key
156
- @Tool({ name: 'get_protected_data' })
157
- @UseGuards(ApiKeyGuard) // 🔒 Protected!
158
- async getProtectedData() {
159
- return { data: 'protected' };
160
- }
161
- }
162
- ```
163
-
164
- ## 🔐 API Key Management
165
-
166
- ### Environment Variables
167
-
168
- API keys are loaded from environment variables:
169
-
170
- ```bash
171
- # .env
172
- API_KEY_1=sk_test_public_demo_key_12345
173
- API_KEY_2=sk_test_admin_demo_key_67890
174
- API_KEY_3=your_custom_key_here
175
- ```
176
-
177
- The `ApiKeyModule` automatically reads all `API_KEY_*` variables.
178
-
179
- ### Studio Integration
180
-
181
- NitroStack Studio provides a **dedicated API Key UI**:
182
-
183
- 1. **Auth Tab** → **API Key** section
184
- 2. Enter your API key
185
- 3. It's automatically included in all tool calls
186
- 4. Persists across page refreshes
187
- 5. Clear button to reset
188
-
189
- ### How Keys Are Sent
190
-
191
- When you execute a tool in Studio, the API key is sent in the `_meta` field:
192
-
193
- ```javascript
194
- {
195
- args: { /* your tool arguments */ },
196
- _meta: {
197
- apiKey: "sk_test_public_demo_key_12345",
198
- "x-api-key": "sk_test_public_demo_key_12345"
199
- }
200
- }
201
- ```
202
-
203
- The guard extracts it and validates it.
204
-
205
- ## 🔄 Multi-Auth Example (JWT + API Key)
206
-
207
- You can use **both JWT and API key** authentication together!
208
-
209
- ### Example: JWT Guard + API Key Guard
210
-
211
- ```typescript
212
- // Guard that accepts EITHER JWT OR API Key
213
- export class MultiAuthGuard implements Guard {
214
- async canActivate(context: ExecutionContext): Promise<boolean> {
215
- // Try JWT first
216
- const jwt = context.metadata?._jwt || context.metadata?.authorization;
217
- if (jwt) {
218
- // Validate JWT...
219
- return true;
220
- }
221
-
222
- // Try API key
223
- const apiKey = context.metadata?.apiKey;
224
- if (apiKey) {
225
- const isValid = await ApiKeyModule.validate(apiKey);
226
- return isValid;
227
- }
228
-
229
- throw new Error('Either JWT or API key required');
230
- }
231
- }
232
-
233
- // Use on a tool
234
- @Tool({ name: 'multi_auth_tool' })
235
- @UseGuards(MultiAuthGuard)
236
- async multiAuthTool() {
237
- // Accessible with JWT OR API key
238
- }
239
- ```
240
-
241
- ### Example: Both Required
242
-
243
- ```typescript
244
- @Tool({ name: 'double_auth_tool' })
245
- @UseGuards(JWTGuard, ApiKeyGuard) // Both required!
246
- async doubleAuthTool() {
247
- // Requires BOTH JWT token AND API key
248
- }
249
- ```
250
-
251
- ## 🧪 Testing Your Tools
252
-
253
- ### In NitroStack Studio
254
-
255
- 1. **Set API Key** in Auth tab
256
- 2. Navigate to **Tools** tab
257
- 3. Test public tools (work without key)
258
- 4. Test protected tools (work with key)
259
- 5. Test `check_api_key_status` to verify your setup
260
-
261
- ### Programmatically (TypeScript Client)
262
-
263
- ```typescript
264
- import { McpClient } from 'nitrostack';
265
-
266
- const client = new McpClient({
267
- transport: 'stdio',
268
- command: 'node',
269
- args: ['dist/index.js'],
270
- });
271
-
272
- await client.connect();
273
-
274
- // Call protected tool with API key
275
- const result = await client.callTool('get_protected_data', {
276
- dataType: 'user',
277
- _meta: {
278
- apiKey: 'sk_test_public_demo_key_12345'
279
- }
280
- });
281
-
282
- console.log(result);
283
- ```
284
-
285
- ### In Claude Desktop or Cline
286
-
287
- Add to your MCP settings:
288
-
289
- ```json
290
- {
291
- "mcpServers": {
292
- "api-key-auth": {
293
- "command": "node",
294
- "args": ["/path/to/dist/index.js"],
295
- "env": {
296
- "API_KEY_1": "sk_test_public_demo_key_12345"
297
- }
298
- }
299
- }
300
- }
301
- ```
302
-
303
- ## 🔒 Production Best Practices
304
-
305
- ### 1. Use Hashed Keys
306
-
307
- ```typescript
308
- apiKey: ApiKeyModule.forRoot({
309
- keysEnvPrefix: 'API_KEY',
310
- hashed: true, // Store keys as SHA-256 hashes
311
- })
312
- ```
313
-
314
- Then hash your keys before storing:
315
-
316
- ```typescript
317
- import { ApiKeyModule } from 'nitrostack';
318
-
319
- const apiKey = 'sk_prod_real_secret_key';
320
- const hashed = ApiKeyModule.hashKey(apiKey);
321
- console.log('Store this in .env:', hashed);
322
- // API_KEY_1=<hash>
323
- ```
324
-
325
- ### 2. Use Strong Keys
326
-
327
- ```typescript
328
- import { ApiKeyModule } from 'nitrostack';
329
-
330
- // Generate cryptographically secure keys
331
- const newKey = ApiKeyModule.generateKey('sk');
332
- console.log(newKey);
333
- // sk_vK8mQ2xPnL...
334
- ```
335
-
336
- ### 3. Store Keys Securely
337
-
338
- - ✅ Use environment variables
339
- - ✅ Use secret management (AWS Secrets Manager, Vault, etc.)
340
- - ❌ Never commit keys to git
341
- - ❌ Never hardcode keys in source
342
-
343
- ### 4. Custom Validation
344
-
345
- ```typescript
346
- apiKey: ApiKeyModule.forRoot({
347
- keysEnvPrefix: 'API_KEY',
348
- customValidation: async (key) => {
349
- // Check against database, rate limits, expiration, etc.
350
- const keyRecord = await db.apiKeys.findOne({ key });
351
- return keyRecord && !keyRecord.expired;
352
- },
353
- })
354
- ```
355
-
356
- ## 📚 Available Tools
357
-
358
- ### Public Tools (No Auth)
359
-
360
- #### `get_public_info`
361
- Get public information without authentication.
362
-
363
- **Arguments:**
364
- - `topic` (string): The topic to get information about
365
-
366
- **Example:**
367
- ```json
368
- {
369
- "topic": "weather"
370
- }
371
- ```
372
-
373
- ### Protected Tools (API Key Required)
374
-
375
- #### `get_protected_data`
376
- Retrieve protected data (requires API key).
377
-
378
- **Arguments:**
379
- - `dataType` (enum): `user`, `account`, or `settings`
380
-
381
- **Example:**
382
- ```json
383
- {
384
- "dataType": "user"
385
- }
386
- ```
387
-
388
- #### `perform_protected_action`
389
- Perform a protected action (requires API key).
390
-
391
- **Arguments:**
392
- - `action` (enum): `create`, `update`, or `delete`
393
- - `resourceType` (string): Type of resource
394
- - `resourceId` (string, optional): Resource ID for update/delete
395
-
396
- **Example:**
397
- ```json
398
- {
399
- "action": "create",
400
- "resourceType": "post"
401
- }
402
- ```
403
-
404
- #### `check_api_key_status`
405
- Verify your API key is working correctly.
406
-
407
- **Arguments:** None
408
-
409
- ## 🐛 Troubleshooting
410
-
411
- ### "API key required" Error
412
-
413
- **Solution**: Set your API key in Studio Auth tab:
414
- 1. Go to **Auth** tab
415
- 2. Find **API Key** section
416
- 3. Paste: `sk_test_public_demo_key_12345`
417
- 4. Click **Set Key**
418
-
419
- ### "Invalid API key" Error
420
-
421
- **Causes:**
422
- - Wrong key format
423
- - Key not in `.env` file
424
- - Environment variables not loaded
425
-
426
- **Solution:**
427
- 1. Check `.env` has the key
428
- 2. Restart the dev server: `npm run dev`
429
- 3. Verify key in Studio matches `.env`
430
-
431
- ### Public Tools Not Working
432
-
433
- Public tools should work without authentication. If they fail:
434
- 1. Check server logs for errors
435
- 2. Ensure no guards are accidentally applied
436
- 3. Test in Studio Tools tab
437
-
438
- ## 🎓 Next Steps
439
-
440
- 1. ✅ Explore the code in `src/`
441
- 2. ✅ Add your own protected tools
442
- 3. ✅ Combine with JWT auth (see `typescript-auth` template)
443
- 4. ✅ Add custom validation logic
444
- 5. ✅ Deploy to production with secure keys
445
-
446
- ## 📖 Related Resources
447
-
448
- - **NitroStack Docs**: Full documentation
449
- - **typescript-auth Template**: JWT authentication example
450
- - **typescript-starter Template**: Basic MCP server
451
- - **ApiKeyModule API**: Core API key functionality
452
-
453
- ## 💡 Tips
454
-
455
- - 🔑 Use `sk_` prefix for secret keys (standard convention)
456
- - 🔐 Enable hashing in production
457
- - 🎯 Mix public and protected tools in the same server
458
- - 🔄 Support multiple auth methods (JWT + API Key)
459
- - 📊 Add logging to track API key usage
460
-
461
- ## ❓ FAQ
462
-
463
- **Q: Can I use both JWT and API key auth?**
464
- A: Yes! See the Multi-Auth Example section above.
465
-
466
- **Q: How do I rotate API keys?**
467
- A: Add new keys to `.env`, deploy, then remove old keys after clients update.
468
-
469
- **Q: Can I have per-key permissions?**
470
- A: Yes! Use `customValidation` to check permissions in your database.
471
-
472
- **Q: Is this production-ready?**
473
- A: Yes, but enable `hashed: true` and use secure key storage.
474
-
475
- **Q: How do I integrate with my existing auth system?**
476
- A: Use `customValidation` to validate against your auth API/database.
477
-
478
- ---
479
-
480
- ## 🎉 You're Ready!
481
-
482
- You now have a fully functional MCP server with API key authentication. Try it out, modify it, and build something amazing!
483
-
484
- **Happy coding! 🚀**
485
-
@@ -1,21 +0,0 @@
1
- {
2
- "name": "typescript-auth-api-key",
3
- "version": "1.0.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "nitrostack dev",
8
- "build": "nitrostack build",
9
- "start": "npm run build && nitrostack start",
10
- "start:prod": "nitrostack start",
11
- "widget": "npm --prefix src/widgets"
12
- },
13
- "dependencies": {
14
- "dotenv": "^16.4.5",
15
- "nitrostack": "^1",
16
- "zod": "^3.23.8"
17
- },
18
- "devDependencies": {
19
- "typescript": "^5.3.3"
20
- }
21
- }
@@ -1,38 +0,0 @@
1
- import { McpApp, Module, ApiKeyModule } from 'nitrostack';
2
- import { DemoModule } from './modules/demo/demo.module.js';
3
-
4
- /**
5
- * App Module - Root module for the API Key Auth MCP Server
6
- *
7
- * This module demonstrates how to build an MCP server with API key authentication.
8
- */
9
- @McpApp({
10
- module: AppModule,
11
- server: {
12
- name: 'API Key Auth MCP Server',
13
- version: '1.0.0',
14
- },
15
- logging: {
16
- level: 'info',
17
- },
18
- })
19
- @Module({
20
- name: 'app',
21
- description: 'Root application module with API key authentication',
22
- imports: [
23
- // Enable API key authentication
24
- ApiKeyModule.forRoot({
25
- keysEnvPrefix: 'API_KEY', // Reads API_KEY_1, API_KEY_2, etc.
26
- headerName: 'x-api-key',
27
- metadataField: 'apiKey',
28
- hashed: false, // Set to true in production
29
- }),
30
-
31
- // Feature modules
32
- DemoModule,
33
- ],
34
- controllers: [],
35
- providers: [],
36
- })
37
- export class AppModule {}
38
-
@@ -1,47 +0,0 @@
1
- import { Guard, ExecutionContext, ApiKeyModule, ApiKeyMetadata } from 'nitrostack';
2
-
3
- /**
4
- * API Key Guard
5
- *
6
- * Validates API keys for tool access.
7
- * Keys are extracted from context.metadata.apiKey or context.metadata['x-api-key']
8
- *
9
- * Usage:
10
- * ```typescript
11
- * @Tool({
12
- * name: 'protected_tool',
13
- * description: 'A protected tool that requires API key'
14
- * })
15
- * @UseGuards(ApiKeyGuard)
16
- * async protectedTool() {
17
- * // Only accessible with valid API key
18
- * }
19
- * ```
20
- */
21
- export class ApiKeyGuard implements Guard {
22
- async canActivate(context: ExecutionContext): Promise<boolean> {
23
- // Extract API key from metadata (sent by Studio or client)
24
- const apiKey = context.metadata?.apiKey || context.metadata?.['x-api-key'];
25
-
26
- if (!apiKey) {
27
- throw new Error('API key required. Please set your API key in the Studio Auth tab (OAuth 2.1 page).');
28
- }
29
-
30
- // Validate API key using ApiKeyModule
31
- const isValid = await ApiKeyModule.validate(apiKey as string);
32
-
33
- if (!isValid) {
34
- throw new Error('Invalid API key. Please check your API key in the Studio Auth tab.');
35
- }
36
-
37
- // Populate context.auth with API key metadata
38
- context.auth = {
39
- subject: `apikey_${(apiKey as string).substring(0, 12)}`,
40
- scopes: ['*'], // API keys typically have full access
41
- };
42
-
43
- return true;
44
- }
45
- }
46
-
47
-