auth-security
Best practices for implementing JWT, API Keys, OAuth 2.1, and RBAC in a NitroStack application.
Best practices and guidelines for bootstrapping, defining modules, using dependency injection, managing server lifecycles, and handling events in the NitroStack SDK.
$ npx -y skills add nitrocloudofficial/nitrostack --skill mcp-app-architecture --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/mcp-app-architectureContext preview
The summary Claude sees to decide when to auto-load this skill.
Best practices and guidelines for bootstrapping, defining modules, using dependency injection, managing server lifecycles, and handling events in the NitroStack SDK.
name: nitrostack-mcp-app-architecture description: Best practices and guidelines for bootstrapping, defining modules, using dependency injection, managing server lifecycles, and handling events in the NitroStack SDK.
Use this skill whenever you are bootstrapping a new NitroStack MCP server, creating modules, injecting services, or handling application lifecycle events.
A NitroStack application is initialized with the `@McpApp` decorator on a root class, accompanied by a root `@Module`.
import { McpApp, Module } from '@nitrostack/core';
import { DatabaseModule } from './database/database.module.js';
import { UsersModule } from './users/users.module.js';
@McpApp({
module: AppModule,
server: {
name: 'user-management-server',
version: '1.0.0',
},
})
@Module({
imports: [DatabaseModule, UsersModule],
})
export class AppModule {}Modules organize your application structure. Use the `@Module` decorator to define imports, exports, and providers.
import { Module } from '@nitrostack/core';
import { UsersService } from './users.service.js';
import { UsersTools } from './users.tools.js';
@Module({
providers: [UsersService, UsersTools],
exports: [UsersService],
})
## Controllers
Use the `@ControllerDecorator` (or alias it as `@Controller`) to group tools, resources, and prompts together. Controllers are automatically registered as singletons in the DI container.
### Key Controller Options:
* **`prefix`**: A string prefix applied to every `@Tool` defined in this controller. For example, `@ControllerDecorator('github')` prefixing a tool named `create_issue` exposes it to MCP clients as `github_create_issue`.
```typescript
import { ControllerDecorator as Controller, Tool, ExecutionContext } from '@nitrostack/core';
@Controller('github')
export class GitHubController {
@Tool({
name: 'create_issue',
description: 'Create an issue in a repository',
inputSchema: z.object({ /* ... */ })
})
async createIssue(input: any, ctx: ExecutionContext) {
// Exposed to clients as "github_create_issue"
}
}NitroStack uses a robust dependency injection container to manage class instances and lifecycles.
1. **Singleton (Default)**: A single instance is shared across the entire application. 2. **Transient**: A new instance is created every time it is resolved/injected. 3. **Scoped**: A new instance is created per incoming request or context.
import { Injectable, Scope } from '@nitrostack/core';
@Injectable({ scope: Scope.SINGLETON })
export class UsersService {
constructor(private readonly db: DatabaseService) {}
async getUser(id: string) {
return this.db.query('SELECT * FROM users WHERE id = $1', [id]);
}
}Implement NestJS-style lifecycle interfaces on modules, controllers, or providers to hook into application state changes:
import {
Injectable,
OnModuleInit,
OnApplicationBootstrap,
OnModuleDestroy,
BeforeApplicationShutdown,
OnApplicationShutdown
} from '@nitrostack/core';
@Injectable()
export class DatabaseService
implements OnModuleInit, OnApplicationBootstrap, OnModuleDestroy, BeforeApplicationShutdown, OnApplicationShutdown
{
async onModuleInit() {
await this.connect();
}
async onApplicationBootstrap() {
console.log('App ready to handle connections.');
}
async onModuleDestroy() {
await this.cleanupPendingQueries();
}
async beforeApplicationShutdown(signal?: string) {
console.log(`Shutting down soon (signal: ${signal}).`);
}
async onApplicationShutdown(signal?: string) {
await this.disconnect();
}
}---
NitroStack includes an internal eventing system to decouple components. A service or tool can emit an event using `emitEvent`, and any injectable class (like a handler service or controller) can subscribe using the `@OnEvent` decorator.
Call `emitEvent` to dispatch an event payload asynchronously.
import { Injectable, emitEvent } from '@nitrostack/core';
@Injectable()
export class SpaceShipService {
async launchShip(shipId: string) {
// Process launch...
// Dispatch event
emitEvent('ship.launched', {
shipId,
timestamp: new Date().toISOString(),
});
}
}Decorate a method inside any `@Injectable()` class with `@OnEvent('event_pattern')` to register it as an event handler.
import { Injectable, OnEvent } from '@nitrostack/core';
@Injectable({ deps: [] })
export class FlightLogHandler {
@OnEvent('ship.launched')
async logLaunch(data: { shipId: string; timestamp: string }) {
console.error(`🚀 [EVENT] Ship ${data.shipId} was successfully launched at ${data.timestamp}`);
}
}> [!NOTE] > For the `@OnEvent` decorator to register properly, th
The full-stack TypeScript framework to build, test, and deploy production-ready MCP servers and AI-native apps.
Repo: nitrocloudofficial/nitrostack
Best practices for implementing JWT, API Keys, OAuth 2.1, and RBAC in a NitroStack application.
Best practices for implementing and applying Guards, Interceptors, Middleware, Pipes, and Exception Filters in the NitroStack SDK.
Guidelines and patterns for defining Tools, Resources, and Prompts in a NitroStack application with schema validation via Zod, including caching,…
Best practices for linking tools to interactive frontend widgets using @Widget and @nitrostack/widgets SDK (including state sync, tool calling, display modes,…
Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, studio, validate, format, debug, and mcp. Use for ORM/database CLI workflows, not…
Prisma Client API reference covering model queries, filters, operators, and client methods. Use when writing database queries, using CRUD operations, filtering…