Core Concepts

Overview

The handful of ideas behind every NitroStack server, and how they fit together.

A NitroStack server is a set of classes that the framework wires together at startup. Once you know a few ideas, you can read any NitroStack project and know where to make a change.

AI client
AppModule
Products moduleTools, resources, promptsServices
Orders moduleTools, resources, promptsServices
The root module imports feature modules. Each one holds its MCP primitives and the services they use.

Core architecture

Designed for enterprise applications, NitroStack enforces architectural best practices. Your codebase stays clean, testable, and adaptable as it scales from a single tool to a complex distributed system. Both SDKs share the same mental model (modules, controllers, providers, and a request pipeline), each with idiomatic APIs for its language.

Decorator-based design. NitroStack utilizes a descriptive, decorator-based architecture. This approach reduces boilerplate and improves readability by keeping configuration close to the implementation. Behavior such as authentication, caching, and rate limiting is applied through composable decorators, and schemas give you end-to-end type safety and runtime validation.

@Tool({
  name: 'search_products',
  description: 'Search product catalog with advanced filtering specification',
  inputSchema: z.object({
    query: z.string(),
    category: z.string().optional(),
    filters: z.object({
      minPrice: z.number().optional(),
      maxPrice: z.number().optional(),
    }).optional(),
    pagination: z.object({
      page: z.number().default(1),
      limit: z.number().default(20)
    }).default({})
  })
})
@UseGuards(JwtAuthGuard)
@UseMiddleware(AuditLoggingMiddleware)
@Cache({ ttl: 600, key: (input) => `search:${input.query}` })
@RateLimit({ requests: 100, window: '1h' })
@Widget('product-grid-view')
async searchProducts(input: any, ctx: ExecutionContext) {
  ctx.logger.info('Executing product search', { query: input.query });
  return await this.productService.executeSearch(input);
}

This single declaration encapsulates API definition, validation, security, observability, performance optimization, and UI presentation layer association.

from nitrostack import injectable, tool, ExecutionContext
from pydantic import BaseModel, Field

class AddInput(BaseModel):
    a: float = Field(description="First number")
    b: float = Field(description="Second number")

@injectable(deps=[])
class CalculatorService:
    def add(self, a: float, b: float) -> float:
        return a + b

@injectable(deps=[CalculatorService])
class CalculatorController:
    def __init__(self, service: CalculatorService):
        self.service = service

    @tool(name="add", description="Add two numbers", input_schema=AddInput)
    async def add(self, input: AddInput, context: ExecutionContext) -> float:
        return self.service.add(input.a, input.b)

The Python SDK uses Pydantic models as input schemas. See the Python introduction.

Concepts

Decorators at a glance

Most of NitroStack is expressed through decorators. This table maps each one to the concept it belongs to.

DecoratorWhat it doesLearn more
@McpAppConfigures the server: name, version, transport, loggingProject Structure
@ModuleGroups a feature's classesModules
@Tool, @Resource, @PromptExpose a method to MCP clientsMCP Basics
@InjectableMakes a class available for injectionDependency Injection
@UseGuards, @UseMiddleware, @UseInterceptors, @UsePipes, @UseFiltersAttach pipeline steps to a handlerRequest Lifecycle
@WidgetAttaches a React UI to a toolWidgets

For every option on every decorator, see the Decorators reference.

On this page