@nitrostack/cli 1.0.10 → 1.0.13

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 (36) hide show
  1. package/README.md +38 -52
  2. package/dist/commands/build.d.ts.map +1 -1
  3. package/dist/commands/build.js +13 -1
  4. package/dist/commands/cursor.d.ts +11 -0
  5. package/dist/commands/cursor.d.ts.map +1 -0
  6. package/dist/commands/cursor.js +238 -0
  7. package/dist/commands/generate.d.ts.map +1 -1
  8. package/dist/commands/generate.js +5 -6
  9. package/dist/commands/init.js +3 -3
  10. package/dist/commands/start.d.ts.map +1 -1
  11. package/dist/commands/start.js +2 -0
  12. package/dist/commands/upgrade.d.ts +12 -0
  13. package/dist/commands/upgrade.d.ts.map +1 -1
  14. package/dist/commands/upgrade.js +144 -106
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +13 -0
  18. package/package.json +4 -4
  19. package/templates/typescript-oauth/.env.example +75 -14
  20. package/templates/typescript-oauth/README.md +37 -51
  21. package/templates/typescript-oauth/package.json +2 -1
  22. package/templates/typescript-oauth/src/app.module.ts +7 -0
  23. package/templates/typescript-oauth/src/guards/oauth.guard.ts +19 -0
  24. package/templates/typescript-oauth/src/index.ts +9 -11
  25. package/templates/typescript-oauth/src/modules/flights/flights.prompts.ts +19 -1
  26. package/templates/typescript-oauth/src/services/duffel.service.ts +4 -2
  27. package/templates/typescript-oauth/src/widgets/package.json +2 -1
  28. package/templates/typescript-pizzaz/.env.example +14 -0
  29. package/templates/typescript-pizzaz/README.md +35 -60
  30. package/templates/typescript-pizzaz/package.json +2 -1
  31. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.tools.ts +17 -3
  32. package/templates/typescript-pizzaz/src/widgets/package.json +1 -0
  33. package/templates/typescript-starter/.env.example +11 -5
  34. package/templates/typescript-starter/README.md +28 -68
  35. package/templates/typescript-starter/package.json +2 -1
  36. package/templates/typescript-starter/src/widgets/package.json +2 -1
@@ -41,6 +41,25 @@ export class OAuthGuard implements Guard {
41
41
  } else if (metaToken) {
42
42
  token = metaToken as string;
43
43
  }
44
+
45
+ // Enforcement gate: when OAuth is not required (OAUTH_REQUIRED not "true"),
46
+ // do not reject. Best-effort: if a valid token happens to be present, attach
47
+ // its identity; otherwise allow the request through unauthenticated.
48
+ if (!OAuthModule.isAuthRequired()) {
49
+ if (token) {
50
+ const result = await OAuthModule.validateToken(token);
51
+ if (result.valid) {
52
+ const payload = result.payload as OAuthTokenPayload;
53
+ context.auth = {
54
+ subject: payload.sub,
55
+ scopes: this.extractScopes(payload),
56
+ clientId: payload.client_id,
57
+ tokenPayload: payload,
58
+ };
59
+ }
60
+ }
61
+ return true;
62
+ }
44
63
 
45
64
  if (!token) {
46
65
  throw new Error(
@@ -28,26 +28,24 @@ async function bootstrap() {
28
28
  try {
29
29
  console.error('šŸ” Starting Calculator MCP Server with OAuth 2.1...\\n');
30
30
 
31
- // Validate required environment variables for OAuth
32
- const requiredEnvVars = ['RESOURCE_URI', 'AUTH_SERVER_URL'];
33
- const missing = requiredEnvVars.filter(v => !process.env[v]);
34
-
35
- if (missing.length > 0) {
36
- console.error('āŒ Missing required OAuth environment variables:');
37
- missing.forEach(v => console.error(` - ${v}`));
38
- console.error('\\nšŸ’” Copy .env.example to .env and configure your OAuth provider');
39
- console.error(' Or check the test-oauth/.env for reference\\n');
40
- process.exit(1);
31
+ // Validate required environment variables for OAuth, set defaults if missing
32
+ if (!process.env.RESOURCE_URI || !process.env.AUTH_SERVER_URL) {
33
+ console.error('āš ļø Warning: Missing RESOURCE_URI or AUTH_SERVER_URL environment variables.');
34
+ console.error(' Defaulting to local test endpoints. Copy .env.example to .env to configure.\n');
35
+ process.env.RESOURCE_URI = process.env.RESOURCE_URI || 'http://localhost:3000';
36
+ process.env.AUTH_SERVER_URL = process.env.AUTH_SERVER_URL || 'http://localhost:8080/auth';
41
37
  }
42
38
 
43
39
  // Create the MCP application
44
40
  const server = await McpApplicationFactory.create(AppModule);
45
41
 
42
+ const authEnforced = process.env.OAUTH_REQUIRED === 'true';
46
43
  console.error('āœ… OAuth 2.1 Module configured');
47
44
  console.error(` Resource URI: ${process.env.RESOURCE_URI}`);
48
45
  console.error(` Auth Server: ${process.env.AUTH_SERVER_URL}`);
49
46
  console.error(` Scopes: read, write, admin`);
50
- console.error(` Audience: ${process.env.TOKEN_AUDIENCE || process.env.RESOURCE_URI}\\n`);
47
+ console.error(` Audience: ${process.env.TOKEN_AUDIENCE || process.env.RESOURCE_URI}`);
48
+ console.error(` Enforcement: ${authEnforced ? 'ON (OAUTH_REQUIRED=true)' : 'OFF (dev mode — set OAUTH_REQUIRED=true to enforce)'}\\n`);
51
49
 
52
50
  // Start the server
53
51
  await server.start();
@@ -79,8 +79,26 @@ Respond to EXACTLY what the user asked - nothing more.`;
79
79
  ]
80
80
  })
81
81
  async flightComparison(input: any, ctx: ExecutionContext) {
82
+ let ids: string[] = [];
83
+ if (Array.isArray(input.offerIds)) {
84
+ ids = input.offerIds;
85
+ } else if (typeof input.offerIds === 'string') {
86
+ const trimmed = input.offerIds.trim();
87
+ if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
88
+ try {
89
+ const parsed = JSON.parse(trimmed);
90
+ ids = Array.isArray(parsed) ? parsed : [parsed];
91
+ } catch {
92
+ ids = trimmed.split(',').map((s: string) => s.trim());
93
+ }
94
+ } else {
95
+ ids = trimmed.split(',').map((s: string) => s.trim());
96
+ }
97
+ }
98
+ ids = ids.filter(Boolean);
99
+
82
100
  const offers = await Promise.all(
83
- input.offerIds.map((id: string) => this.duffelService.getOffer(id))
101
+ ids.map((id: string) => this.duffelService.getOffer(id))
84
102
  );
85
103
 
86
104
  const comparisonData = offers.map((offer: any) => {
@@ -12,9 +12,11 @@ export class DuffelService {
12
12
  private duffel: Duffel;
13
13
 
14
14
  constructor() {
15
- const apiKey = process.env.DUFFEL_API_KEY;
15
+ let apiKey = process.env.DUFFEL_API_KEY;
16
16
  if (!apiKey) {
17
- throw new Error('DUFFEL_API_KEY environment variable is required');
17
+ console.error('āš ļø Warning: DUFFEL_API_KEY environment variable is missing.');
18
+ console.error(' Running with a dummy key for testing/dry-run mode.\n');
19
+ apiKey = 'duffel_test_dummy_key';
18
20
  }
19
21
 
20
22
  this.duffel = new Duffel({
@@ -12,7 +12,8 @@
12
12
  "next": "^14.2.5",
13
13
  "react": "^18.3.1",
14
14
  "react-dom": "^18.3.1",
15
- "@nitrostack/widgets": "^1"
15
+ "@nitrostack/widgets": "^1",
16
+ "@modelcontextprotocol/ext-apps": ">=0.1.0"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@types/node": "^20",
@@ -1,3 +1,17 @@
1
+ # NitroStack Configuration
2
+ NITRO_LOG_LEVEL=info
3
+ NITROSTACK_APP_MODE=openai
4
+
5
+ # Server Transport Configuration (Optional)
6
+ # =============================================================================
7
+ # MCP_TRANSPORT_TYPE: Toggles transport mode. Values: stdio | http | dual.
8
+ # Defaults to 'stdio' in development and 'dual' in production/NODE_ENV=production.
9
+ # =============================================================================
10
+ # MCP_TRANSPORT_TYPE=stdio
11
+ # PORT=3000
12
+ # HOST=localhost
13
+ # ENABLE_CORS=true
14
+
1
15
  # Mapbox Configuration (Optional)
2
16
  # =============================================================================
3
17
  # The map widget uses Mapbox GL for interactive maps.
@@ -1,79 +1,54 @@
1
- # šŸ• NitroStack Pizza Shop Finder
1
+ # NitroStack Pizzaz Template
2
2
 
3
- A high-performance interactive template showcasing discovery with maps, lists, and detailed views. This template demonstrates the **NitroStack Widget SDK** for building beautiful, tool-driven visual experiences.
3
+ Template focused on rich, interactive widget experiences (map/list/detail flows)
4
+ using the NitroStack widget SDK patterns.
4
5
 
5
- ## ✨ Features
6
+ ## What This Template Includes
6
7
 
7
- - **Mapbox Integration** — Interactive maps with custom markers.
8
- - **Real-time State** — Shared state between server and widgets.
9
- - **Responsive Layouts** — Auto-adapting heights and display modes (Inline, PiP, Fullscreen).
10
- - **Interactive UI** — Sorting, filtering, and favorites persistence.
8
+ - Widget-heavy module and UI structure
9
+ - Interactive examples for advanced frontends
10
+ - Optional map provider integration pattern
11
+ - Studio-friendly development workflow
11
12
 
12
- ---
13
-
14
- ## šŸš€ Quick Start
15
-
16
- ### 1. Initialize Your Project
17
-
18
- ```bash
19
- npx nitrostack init my-pizza-app --template typescript-pizzaz
20
- cd my-pizza-app
21
- ```
22
-
23
- ### 2. Install Dependencies
13
+ ## Quick Start
24
14
 
25
15
  ```bash
26
- npm run install:all
16
+ npx @nitrostack/cli init my-pizzaz-app --template typescript-pizzaz
17
+ cd my-pizzaz-app
18
+ npm run dev
27
19
  ```
28
20
 
29
- ### 3. Step Up NitroStudio
30
-
31
- NitroStudio provides the best experience for visual testing of widgets and maps.
32
-
33
- ![NitroStudio](../../../../assets/gif/nitrostudio-main.gif)
34
-
35
- 1. **Download NitroStudio**: [nitrostack.ai/studio](https://nitrostack.ai/studio)
36
- 2. **Open Project**: Launch NitroStudio and select your project folder.
37
- 3. **View Maps**: Use the chat or visual tools to explore your pizza shops.
38
-
39
- ---
21
+ ## Optional Configuration
40
22
 
41
- ## āš™ļø Configuration
23
+ If this project uses a map provider, configure API tokens in widget `.env` files
24
+ as documented in the template source.
42
25
 
43
- ### Mapbox (Optional)
44
-
45
- To enable the interactive map, add your Mapbox token:
46
-
47
- 1. Get a free token at [mapbox.com](https://www.mapbox.com/).
48
- 2. Create `src/widgets/.env` and add:
49
- ```env
50
- NEXT_PUBLIC_MAPBOX_TOKEN=pk.your_token_here
51
- ```
52
-
53
- ---
54
-
55
- ## šŸ› ļø Commands
26
+ ## Common Commands
56
27
 
57
28
  ```bash
58
- # Start dev server with Studio integration
59
29
  npm run dev
60
-
61
- # Build for production
62
30
  npm run build
63
-
64
- # Manage widgets directly
31
+ npm start
65
32
  npm run widget <command>
66
33
  ```
67
34
 
68
- ## šŸ“ Structure
35
+ ## NitroStudio
36
+
37
+ NitroStudio is the fastest way to test and debug interactive widget output.
38
+
39
+ - Download: <https://nitrostack.ai/studio>
40
+ - Studio: <https://nitrostack.ai/studio>
41
+
42
+ ## Links
43
+
44
+ - Docs: <https://docs.nitrostack.ai>
45
+ - Widgets docs: <https://docs.nitrostack.ai/sdk/typescript/ui/widgets>
46
+ - Main repository: <https://github.com/nitrocloudofficial/nitrostack>
69
47
 
70
- - `src/modules/pizzaz/` — Core logic and pizza shop data.
71
- - `src/widgets/app/pizza-map/` — Next.js Map widget.
72
- - `src/widgets/app/pizza-list/` — Filterable shop list.
73
- - `src/widgets/app/pizza-shop/` — Detail view with actions.
48
+ ## Community
74
49
 
75
- ---
76
- **Official Resources**
77
- - [Website](https://nitrostack.ai)
78
- - [Docs](https://docs.nitrostack.ai)
79
- - [Download Studio](https://nitrostack.ai/studio)
50
+ - Discord: <https://discord.gg/uVWey6UhuD>
51
+ - X: <https://x.com/nitrostackai>
52
+ - YouTube: <https://www.youtube.com/@nitrostackai>
53
+ - LinkedIn: <https://linkedin.com/company/nitrostack-ai/>
54
+ - GitHub: <https://github.com/nitrostackai>
@@ -25,7 +25,8 @@
25
25
  "dependencies": {
26
26
  "@nitrostack/core": "^1",
27
27
  "zod": "^3.22.4",
28
- "dotenv": "^16.3.1"
28
+ "dotenv": "^16.3.1",
29
+ "@modelcontextprotocol/ext-apps": ">=0.1.0"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@nitrostack/cli": "^1",
@@ -1,6 +1,20 @@
1
1
  import { ToolDecorator as Tool, Widget, ExecutionContext, Injectable, z } from '@nitrostack/core';
2
2
  import { PizzazService } from './pizzaz.service.js';
3
3
 
4
+ /**
5
+ * Pizzaz widget metadata for ChatGPT / MCP Apps (CSP for Unsplash images, optional border).
6
+ * For production ChatGPT submission, set `domain` to your app HTTPS origin per OpenAI Apps SDK docs.
7
+ */
8
+ function pizzazWidget(route: string) {
9
+ return {
10
+ route,
11
+ prefersBorder: true,
12
+ csp: {
13
+ resourceDomains: ['https://images.unsplash.com'],
14
+ },
15
+ };
16
+ }
17
+
4
18
  const ShowMapSchema = z.object({
5
19
  filter: z.enum(['open_now', 'top_rated', 'all']).optional().describe('Filter to apply'),
6
20
  });
@@ -67,7 +81,7 @@ export class PizzazTools {
67
81
  }
68
82
  }
69
83
  })
70
- @Widget('pizza-map')
84
+ @Widget(pizzazWidget('pizza-map'))
71
85
  async showPizzaMap(args: z.infer<typeof ShowMapSchema>, ctx: ExecutionContext) {
72
86
  let shops;
73
87
 
@@ -122,7 +136,7 @@ export class PizzazTools {
122
136
  }
123
137
  }
124
138
  })
125
- @Widget('pizza-list')
139
+ @Widget(pizzazWidget('pizza-list'))
126
140
  async showPizzaList(args: z.infer<typeof ShowListSchema>, ctx: ExecutionContext) {
127
141
  const shops = this.pizzazService.getShopsFiltered(args);
128
142
 
@@ -180,7 +194,7 @@ export class PizzazTools {
180
194
  }
181
195
  }
182
196
  })
183
- @Widget('pizza-shop')
197
+ @Widget(pizzazWidget('pizza-shop'))
184
198
  async showPizzaShop(args: z.infer<typeof ShowShopSchema>, ctx: ExecutionContext) {
185
199
  const shop = this.pizzazService.getShopById(args.shopId);
186
200
 
@@ -13,6 +13,7 @@
13
13
  "react": "^18.3.1",
14
14
  "react-dom": "^18.3.1",
15
15
  "@nitrostack/widgets": "^1",
16
+ "@modelcontextprotocol/ext-apps": ">=0.1.0",
16
17
  "mapbox-gl": "^3.0.1",
17
18
  "framer-motion": "^10.16.16",
18
19
  "lucide-react": "^0.294.0"
@@ -1,7 +1,13 @@
1
- # NitroStack Starter Environment
1
+ # NitroStack Configuration
2
+ NITRO_LOG_LEVEL=info
3
+ NITROSTACK_APP_MODE=openai
4
+
5
+ # Server Transport Configuration (Optional)
2
6
  # =============================================================================
3
- # Add your environment variables here.
7
+ # MCP_TRANSPORT_TYPE: Toggles transport mode. Values: stdio | http | dual.
8
+ # Defaults to 'stdio' in development and 'dual' in production/NODE_ENV=production.
4
9
  # =============================================================================
5
-
6
- # Example:
7
- # API_KEY=your_api_key_here
10
+ # MCP_TRANSPORT_TYPE=stdio
11
+ # PORT=3000
12
+ # HOST=localhost
13
+ # ENABLE_CORS=true
@@ -1,89 +1,49 @@
1
- # ⚔ NitroStack Starter Template
1
+ # NitroStack Starter Template
2
2
 
3
- **The definitive starter template** — Learn the fundamentals of the NitroStack MCP framework with a clean, well-documented calculator example.
3
+ Minimal template for learning NitroStack fundamentals with a calculator-focused
4
+ MCP server and basic widgets.
4
5
 
5
- ## šŸŽÆ What's Inside
6
+ ## What This Template Includes
6
7
 
7
- This template is designed to showcase core NitroStack features with zero friction:
8
+ - `calculator` module with tools, resources, and prompts
9
+ - TypeScript + Zod validation setup
10
+ - Widget-ready project structure
11
+ - Production-friendly npm scripts
8
12
 
9
- - **Modular Architecture** — Clean separation of concerns with a dedicated Calculator module.
10
- - **Interactive Tools** — A `calculate` tool for performing arithmetic operations.
11
- - **Dynamic Resources** — A `calculator://operations` resource for discovering capabilities.
12
- - **Prompt Library** — Context-aware prompts for guiding users.
13
- - **Pre-built UI Widgets** — Beautiful, high-performance UI components for results and listings.
14
- - **Production-Ready** — Uses TypeScript, Zod for validation, and best-in-class logging.
15
-
16
- ---
17
-
18
- ## šŸš€ Quick Start
19
-
20
- ### 1. Initialize Your Project
21
-
22
- If you haven't already, scaffold your project using the NitroStack CLI:
13
+ ## Quick Start
23
14
 
24
15
  ```bash
25
- npx nitrostack init my-server --template typescript-starter
16
+ npx @nitrostack/cli init my-server --template typescript-starter
26
17
  cd my-server
18
+ npm run dev
27
19
  ```
28
20
 
29
- ### 2. Install Dependencies
30
-
31
- Install all project dependencies (including the visual widget SDK) in one step:
32
-
33
- ```bash
34
- npm run install:all
35
- ```
36
-
37
- ### 3. Get NitroStudio
38
-
39
- NitroStudio is the recommended visual client for running, testing, and managing your NitroStack projects.
40
-
41
- ![NitroStudio](../../../../assets/gif/nitrostudio-main.gif)
42
-
43
- 1. **Download NitroStudio**: [nitrostack.ai/studio](https://nitrostack.ai/studio)
44
- 2. **Open Project**: Launch NitroStudio and open this project folder.
45
- 3. **Run**: NitroStudio handles the rest!
46
-
47
- ---
48
-
49
- ## šŸ› ļø Development
50
-
51
- If you prefer using the command line:
21
+ ## Common Commands
52
22
 
53
23
  ```bash
54
- # Start development server (Server + Widgets + Studio)
55
24
  npm run dev
56
-
57
- # Build for production
58
25
  npm run build
59
-
60
- # Start production server
61
26
  npm start
62
27
  ```
63
28
 
64
- ## šŸ“ Project Structure
29
+ ## NitroStudio
65
30
 
66
- ```text
67
- src/
68
- ā”œā”€ā”€ modules/
69
- │ └── calculator/
70
- │ ā”œā”€ā”€ calculator.module.ts # @Module definition
71
- │ ā”œā”€ā”€ calculator.tools.ts # @Tool implementations
72
- │ ā”œā”€ā”€ calculator.resources.ts # @Resource definitions
73
- │ └── calculator.prompts.ts # @Prompt templates
74
- ā”œā”€ā”€ widgets/ # Visual SDK UI components
75
- ā”œā”€ā”€ app.module.ts # Root application module
76
- └── index.ts # Server entry point
77
- ```
31
+ NitroStudio is the recommended way to test and debug this template during
32
+ development.
33
+
34
+ - Download: <https://nitrostack.ai/studio>
35
+ - Studio: <https://nitrostack.ai/studio>
78
36
 
79
- ## šŸŽØ Next Generation MCP
37
+ ## Links
80
38
 
81
- NitroStack is more than just a server; it's a full-stack MCP ecosystem.
39
+ - Docs: <https://docs.nitrostack.ai>
40
+ - Templates docs: <https://docs.nitrostack.ai/templates/01-starter-template>
41
+ - Main repository: <https://github.com/nitrocloudofficial/nitrostack>
82
42
 
83
- - **Website**: [nitrostack.ai](https://nitrostack.ai)
84
- - **Documentation**: [docs.nitrostack.ai](https://docs.nitrostack.ai)
85
- - **Discord**: [Join our community](https://nitrostack.ai/discord)
43
+ ## Community
86
44
 
87
- ---
88
- **Happy Coding! šŸŽ‰**
89
- Build something amazing with NitroStack.
45
+ - Discord: <https://discord.gg/uVWey6UhuD>
46
+ - X: <https://x.com/nitrostackai>
47
+ - YouTube: <https://www.youtube.com/@nitrostackai>
48
+ - LinkedIn: <https://linkedin.com/company/nitrostack-ai/>
49
+ - GitHub: <https://github.com/nitrostackai>
@@ -16,7 +16,8 @@
16
16
  "dependencies": {
17
17
  "dotenv": "^16.3.1",
18
18
  "@nitrostack/core": "^1",
19
- "zod": "^3.22.4"
19
+ "zod": "^3.22.4",
20
+ "@modelcontextprotocol/ext-apps": ">=0.1.0"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@nitrostack/cli": "^1",
@@ -12,7 +12,8 @@
12
12
  "next": "^14.2.5",
13
13
  "react": "^18.3.1",
14
14
  "react-dom": "^18.3.1",
15
- "@nitrostack/widgets": "^1"
15
+ "@nitrostack/widgets": "^1",
16
+ "@modelcontextprotocol/ext-apps": ">=0.1.0"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@types/node": "^20",