Configuration

CLI and project configuration options

NitroStack uses a zero-config-file approach for tooling, paired with declarative TypeScript modules and standard .env environment variables for application runtime settings.

There is no proprietary configuration file (such as nitrostack.config.ts). Everything is configured via:

  1. CLI Flags: For development ports, build targets, and scaffolding options.
  2. package.json: For project scripts, dependencies, and agent skills tracking.
  3. Environment Variables (.env): For application secrets, server ports, and third-party credentials.
  4. ConfigModule: For type-safe in-code configuration management in @nitrostack/core.

CLI Configuration

CLI commands accept command-line options directly:

# Set production server port
nitrostack-cli start --port 3000

# Custom build output directory
nitrostack-cli build --output dist

# Cursor integration options
nitrostack-cli cursor --type streamable-http --url http://localhost:3000/mcp

# Packaging options
nitrostack-cli pack --include-env --output release.zip

Environment Variables (.env)

NitroStack applications read runtime configuration from .env files in the project root:

# Server Port (default: 3000)
PORT=3000

# MCP Protocol Era ('auto' | '2026-07-28' | 'legacy')
NITRO_MCP_PROTOCOL_VERSION=auto

# Application Mode ('universal' | 'openai' | 'mcp-app')
# Default: 'universal' (concurrently serves Claude Desktop via MCP Apps and ChatGPT via OpenAI Apps SDK)
APP_MODE=universal
NITROSTACK_APP_MODE=universal

# Logging Level ('debug' | 'info' | 'warn' | 'error')
LOG_LEVEL=info

# OAuth 2.1 Configuration (for typescript-oauth template)
RESOURCE_URI=http://localhost:3000
AUTH_SERVER_URL=https://auth.example.com
OAUTH_REQUIRED=false
JWKS_URI=https://auth.example.com/.well-known/jwks.json

# API Key Authentication (for ApiKeyModule)
API_KEY_1=<YOUR_API_KEY>
API_KEY_2=<TEST_API_KEY>

# External Service Credentials
DUFFEL_API_KEY=duffel_test_xyz
MAPBOX_ACCESS_TOKEN=pk.eyJ1...

Application Mode (APP_MODE)

NitroStack allows you to dynamically control widget protocol conventions for different AI host environments:

ModeTarget HostsTool _metaWidget Resource MIME
universal (default)Claude Desktop & ChatGPTDual keys (openai/outputTemplate + _meta.ui)text/html;profile=mcp-app
openaiOpenAI ChatGPTopenai/outputTemplate, ui/templatetext/html
mcp-appClaude Desktop / MCP Hosts_meta.ui (resourceUri, visibility, CSP)text/html;profile=mcp-app

Utilities exported from @nitrostack/core:

  • getAppMode(): Returns the active mode parsed from APP_MODE or NITROSTACK_APP_MODE.
  • isOpenAiMode(): Returns true if mode is openai or universal.
  • isMcpAppMode(): Returns true if mode is mcp-app or universal.
  • getWidgetMimeType(): Returns the resolved MIME type string for widget HTTP handlers.

Type-Safe In-Code Configuration (ConfigModule)

For structured, validated access to environment variables within your services and tools, use ConfigModule.forRoot() and inject ConfigService. See SDK Configuration for the full ConfigModule and ConfigService reference.

Project Metadata (package.json)

Project scripts and skills metadata are maintained in package.json:

{
  "name": "my-mcp-server",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "nitrostack-cli dev",
    "build": "nitrostack-cli build",
    "start": "nitrostack-cli start",
    "upgrade": "nitrostack-cli upgrade",
    "install:all": "nitrostack-cli install"
  },
  "dependencies": {
    "@nitrostack/core": "^1.0.16"
  },
  "nitrostack": {
    "skillsVersion": "1.0.0"
  }
}

Python configuration

A Python project has no nitro.yaml either. It is configured with a .env file, the process environment, and ServerConfig. For type-safe access in code, use ConfigModule.for_root(env_file_path=".env", defaults={...}) and read values with ConfigService.get or get_or_throw; see Python Configuration.

Ports

--port and --widget on init, dev, and start set the MCP and widget ports. If you don't pass them, the CLI uses PORT or MCP_SERVER_PORT, and WIDGETS_DEV_PORT, from the environment, then the project's .env, and finally the defaults, 3000 and 3001.

Environment variables

VariableDescription
HOSTBind address (default 127.0.0.1). Use 0.0.0.0 in containers.
PORT / MCP_SERVER_PORTHTTP port (default 3000). Overridden by --port.
WIDGETS_DEV_PORTWidget port (default 3001). Overridden by --widget.
MCP_TRANSPORT_TYPEstdio, http, or dual
NODE_ENVproduction makes the transport default to dual unless overridden
MCP_STATELESStrue forces modern, stateless HTTP; false forces sessions
NITRO_MCP_PROTOCOL_VERSIONProtocol era (auto, modern, legacy, and so on)
MCP_MAX_SESSIONSConcurrent Streamable HTTP sessions; extra sessions get HTTP 429
MCP_SESSION_TIMEOUT_MSIdle timeout for stateful HTTP sessions
MCP_GRACEFUL_SHUTDOWN_TIMEOUT_MSHow long in-flight requests may finish on shutdown (default 10000)
MCP_ALLOWED_HOSTS / MCP_ALLOWED_ORIGINSDNS-rebinding allow-lists when CORS is off
TRUSTED_PROXIES / MCP_TRUSTED_PROXIESWho may send X-Forwarded-Host and X-Forwarded-Proto
NITROSTACK_APP_MODEWidget mode: universal, openai, or mcp-app
NITROSTACK_LOG_FILE / NITROSTACK_LOG_LEVEL / NITROSTACK_LOG_TO_STDOUTLogging
NITROSTACK_HTTP_DEBUG1 logs every HTTP request to stderr
OAUTH_REQUIREDWhen unset, OAuthGuard may allow calls with no token
API_KEY / API_KEY_*API key authentication
JWT_SECRETSecret for HS256 JWTs

ServerConfig

The same settings can be made in code with ServerConfig. ServerConfig.protocol_era is used only when MCP_STATELESS and NITRO_MCP_PROTOCOL_VERSION are both unset.

from nitrostack import ServerConfig

server = ServerConfig(
    name="my-server",
    version="1.0.0",
    transport_type="http",
    max_sessions=100,
    session_timeout_ms=1_800_000,
)

Next steps

On this page