auth-security
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.
Claude Code
$ npx -y skills add nitrocloudofficial/nitrostack --skill middleware-pipeline --agent claude-code
Codex
$ npx skills add nitrocloudofficial/nitrostack --skill middleware-pipeline -a codex -y
Cursor
$ npx skills add nitrocloudofficial/nitrostack --skill middleware-pipeline -a cursor -y
Gemini CLI
$ npx skills add nitrocloudofficial/nitrostack --skill middleware-pipeline -a gemini-cli -y
GitHub Copilot
$ npx skills add nitrocloudofficial/nitrostack --skill middleware-pipeline -a github-copilot -y
OpenCode
$ npx skills add nitrocloudofficial/nitrostack --skill middleware-pipeline -a opencode -y
Windsurf
$ npx skills add nitrocloudofficial/nitrostack --skill middleware-pipeline -a windsurf -y
name: nitrostack-middleware-pipeline description: Best practices for implementing and applying Guards, Interceptors, Middleware, Pipes, and Exception Filters in the NitroStack SDK.
Use this skill when implementing request validation, authorization checks, response mapping, logging, error handling, or performance tracking on NitroStack tool methods.
---
Guards determine if a request should be processed by a tool handler based on authentication, authorization, or other conditions.
import { Guard, ExecutionContext } from '@nitrostack/core';
export interface Guard {
canActivate(context: ExecutionContext): boolean | Promise<boolean>;
}import { Guard, ExecutionContext, Injectable } from '@nitrostack/core';
@Injectable()
export class RolesGuard implements Guard {
async canActivate(context: ExecutionContext): Promise<boolean> {
const userRoles = context.clientMetadata?.roles || [];
return userRoles.includes('admin');
}
}Apply the guard using `@UseGuards(...)`:
import { Tool, UseGuards, z } from '@nitrostack/core';
import { RolesGuard } from './roles.guard.js';
export class AdminTools {
@Tool({
name: 'delete_system_logs',
description: 'Delete all system logs from the server.',
inputSchema: z.object({}),
})
@UseGuards(RolesGuard)
async deleteLogs() {
return { success: true };
}
}---
Interceptors can transform/intercept input arguments or mapped output from a tool method execution.
import { ExecutionContext } from '@nitrostack/core';
export interface InterceptorInterface {
intercept(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown>;
}import { InterceptorInterface, ExecutionContext, Injectable } from '@nitrostack/core';
@Injectable()
export class TimingInterceptor implements InterceptorInterface {
async intercept(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown> {
const start = Date.now();
const result = await next();
const duration = Date.now() - start;
context.logger.info(`Execution took ${duration}ms`);
return {
...result,
_meta: { durationMs: duration }
};
}
}---
Exception filters catch any errors thrown within guards, interceptors, or the tool handlers themselves, mapping them into user-friendly JSON payloads.
import { ExecutionContext } from '@nitrostack/core';
export interface ExceptionFilterInterface {
catch(exception: unknown, context: ExecutionContext): unknown | Promise<unknown>;
}import { ExceptionFilterInterface, ExecutionContext, Injectable } from '@nitrostack/core';
@Injectable()
export class CustomExceptionFilter implements ExceptionFilterInterface {
catch(exception: unknown, context: ExecutionContext) {
const message = exception instanceof Error ? exception.message : 'Unknown error';
return {
error: true,
message,
timestamp: new Date().toISOString()
};
}
}Apply the filter using `@UseFilters(...)` on a tool method:
import { Tool, UseFilters, z } from '@nitrostack/core';
import { CustomExceptionFilter } from './custom-exception.filter.js';
export class LoggingTools {
@Tool({
name: 'generate_report',
description: 'Generates system usage reports.',
inputSchema: z.object({}),
})
@UseFilters(CustomExceptionFilter)
async generateReport() {
throw new Error('Report generation is not implemented yet.');
}
}---
Middleware executes before the request reaches the tool handler, and can wrap the handler execution by invoking `next()`.
import { ExecutionContext } from '@nitrostack/core';
export interface MiddlewareInterface {
use(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown>;
}import { Middleware, MiddlewareInterface, ExecutionContext } from '@nitrostack/core';
@Middleware()
export class LoggingMiddleware implements MiddlewareInterface {
async use(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown> {
context.logger.info(`Entering tool: ${context.toolName}`);
try {
const result = await next();
context.logger.info(`Exiting tool: ${context.toolName}`);
return result;
} catch (error) {
context.logger.error(`Error in tool: ${error}`);
throw error;
}
}
}Apply the middleware using `@UseMiddleware(...)` on a tool method:
import { Tool, UseMiddleware, z } from '@nitrostack/core';
import { LoggingMiddleware } from './logging.middleware.js';
export class StationTools {
@Tool({
name: 'fetch_logs',
description: 'Fetch station operations logs.',
inputSchema: z.object({}),
})
@UseMiddleware(LoggingMiddleware)
async fetchLogs() {
return { status: 'operational' };
}
}---
Pipes are used to transform or validate input arguments before they reach the tool handler method.
import { ArgumentMetadata } from '@nitrostack/core';
export interface PipeInterface<T = unknown, R = unknown> {
transform(value: T, metadata: ArgumentMetadata): R | Promise<R>;
}import { Pipe, PipeInterface, ArgumentMetadata } from '@nitrostack/core';
@Pipe()
export class TrimPipe implements PipeInterface<Record<string, unknown>, Record<string, unknown>> {
transform(value: Record<string, unknown>, metadata: ArgumentMetadata) {
const trimmed: Record<string, unknown> = {};
for (const [The full-stack TypeScript framework to build, test, and deploy production-ready MCP servers and AI-native apps.
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…
Guidelines and patterns for defining Tools, Resources, and Prompts in a NitroStack application with schema validation via Zod,…
Best practices for linking tools to interactive frontend widgets using @Widget and @nitrostack/widgets SDK (including state sync,…
Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, studio, validate, format, debug, and mcp. Use for…
Prisma Client API reference covering model queries, filters, operators, and client methods. Use when writing database queries,…
SpacetimeDB CLI reference for initializing projects, building modules, publishing databases, querying data, and managing servers