Skip to content

Configure script behavior with special comments at the top of your file. No code changes, no config files, no environment variables. Change a comment, behavior changes instantly.

// @mode worker
// @cors reflective
// @timeout 5000
// @log-level standard
// @ai true
// Your code starts here...
return { hello: 'world' };

Magic comments are parsed at script load time. They must be placed at the very top of your file, before any code.

Rules:

  • Start with // followed by a space and @
  • Must be at the top of the file — before any code, imports, or expressions
  • One comment per line
  • Validated via the validation API
  • Take precedence over default values
  • Case-sensitive for comment names

Validation example:

Terminal window
# Validate magic comments in a script
hoody exec validate magic-comments \
--code "// @mode worker\n// @cors reflective\n// @timeout 5000\nreturn {};"

CommentValuesDefaultDescription
@modeworker | serverlessserverlessChoose execution mode — Worker for stateful persistent VM, Serverless for isolated fresh VM per request
@enabledtrue | falsetrueEnable or disable script execution — a disabled script does not run
@timeoutms | 90s/5m/2h | 0 | unlimited3600000Soft request timeout (default 1 hour). Bare number = ms; unit suffixes (s/m/h/d) accepted. Past the deadline an un-started response gets 504; an already-streaming response is not interrupted and in-flight VM work is not killed. 0/unlimited = no timeout
@await-promisestrue | falsetrueAuto-await returned promises before sending response
@concurrentnumber | true | falsetrueMax concurrent executions (applies in both worker and serverless mode, and to cron). true = unlimited, false = single serial execution, N = at most N in parallel
@schedulecron expressionRun the script on a cron schedule (e.g., 0 9 * * *). See Scheduling

Examples:

// @mode worker // Persistent VM, shared state
// @timeout 60000 // 60 second timeout
// @concurrent false // Serverless: process one at a time
// @timeout 0 // No timeout (use carefully!)
// @timeout unlimited // Same as @timeout 0

CommentValuesDefaultDescription
@corsreflective | * | URL | nonereflectiveOrigin policy for the actual response. Omitting @cors keeps the server’s global reflective CORS; none strips CORS headers; reflective/*/URL set the allowed origin
@cors-credentialstrue | falsefalseAllow credentials (cookies, auth headers). Never combined with @cors *
@cors-methodsGET,POST,...(server default)Access-Control-Allow-Methods is preflight-only — the browser reads it from the OPTIONS response, which is answered globally, so the per-script value is not applied (server default is used)
@cors-headersAuthorization,...(server default)Access-Control-Allow-Headers is preflight-only (server-answered, not applied per-script); the per-script value drives Access-Control-Expose-Headers on the actual response
@cors-max-agenumber (seconds)(server default)Preflight cache hint. Not applied per-script — the OPTIONS preflight is answered globally by the server

Examples:

// @cors reflective // Mirror request origin (development)
// @cors * // Allow any origin (testing)
// @cors https://app.example.com // Specific origin (production)
// @cors none // No CORS headers
// @cors-credentials true // Allow cookies
// @cors-methods GET,POST // Only allow GET and POST

CommentValuesDefaultDescription
@log-levelnone | minimal | standard | full | debugstandardLogging verbosity
@debugtrue | falsefalseShortcut for @log-level debug
@log-request-bodyfull | redacted | off | true | falsefullLog incoming request bodies
@log-response-bodyfull | redacted | off | true | falsefullLog response bodies
@log-max-body-sizebytes | 512kb/1mb1048576Max body size to log. Bare number = bytes; unit suffixes (kb/mb/gb) accepted
@log-exclude-headersheader namesauthorization cookie x-tokenHeaders to exclude from logs (e.g., authorization cookie)
@log-retention-days0365014Days to keep log files (values above the 3650-day cap are clamped)
@debug-instrumenttrue | falsefalseEnable code instrumentation for detailed tracing

Examples:

// @log-level full // Maximum logging
// @log-request-body true // Log request payloads
// @log-response-body true // Log response payloads
// @log-exclude-headers authorization cookie // Hide sensitive headers
// @log-retention-days 30 // Keep logs for 30 days
// @debug-instrument true // Detailed code tracing

Log levels explained:

  • none — No logging
  • minimal — Request line and final status/duration only (skips the detailed request/response logs)
  • standard — Request metadata and headers (default)
  • full — Standard plus request/response bodies (body capture still gated by @log-request-body / @log-response-body)
  • debug — Full plus internal execution details (VM creation, module loading, etc.)

CommentValuesDefaultDescription
@aitrue | falsetrueEnable AI helpers — injects model, openai, ai, generateText, streamText, generateObject
@ai-modelmodel namegoogle/gemini-2.5-flash-liteAI model to use — overrides the server default (e.g., anthropic/claude-sonnet-4.5)
@ai-temperature0 - 2AI temperature parameter (provider default when unset)
@ai-max-tokensnumberMax tokens for AI response (provider default when unset)
@ai-keystringserver-configuredAI API key override (default uses the server’s --ai-key flag)

Example:

// @mode serverless
// @ai true
// @ai-model anthropic/claude-sonnet-4.5
// @ai-temperature 0.3
const { text } = await generateText({
model,
prompt: `Summarize this: ${req.body.content}`
});
return { summary: text };

CommentValuesDefaultDescription
@tokenstringPer-endpoint shared secret. Requests must provide the token via one of four methods

Add @token to protect any endpoint — no middleware, no auth library, no config:

// @token my-secret-key-123
// @cors reflective
return { data: 'only authenticated requests see this' };

Clients authenticate using any of these methods (checked in priority order):

PriorityMethodExample
1aAuthorization: Bearer <token>curl -H "Authorization: Bearer my-secret-key-123" ...
1bAuthorization: Basic (password field)curl -u user:my-secret-key-123 ... or curl -u :my-secret-key-123 ...
2X-Token headercurl -H "X-Token: my-secret-key-123" ...
3?token= query parametercurl "https://...?token=my-secret-key-123"

Security details:

  • Constant-time comparison (SHA-256 + timingSafeEqual) — immune to timing attacks
  • Token is redacted in all API responses, logs, and access logs ([REDACTED])
  • ?token= is stripped from req.url and metadata.parameters before your script runs
  • CORS preflight (OPTIONS) returns 204 without requiring auth (spec-correct behavior)
  • WebSocket upgrade requests are also gated — pass the token via header or ?token=
  • Empty or whitespace-only values are ignored (endpoint stays public)

See Authentication for the complete guide with examples.


CommentValuesDefaultDescription
@websocket(flag)Requires worker mode — Enable WebSocket support
@rawBody(flag)Skip the request-body auto-parser — req stays a raw Node Readable stream (for large uploads, streaming, or passthrough). Accepts @rawBody, @rawBody true, or @rawBody false
@labelstringScript classification label for filtering and organization
@return-typeTypeScript typeTypeScript type definition for the script’s return value
@return-type-modestrict | warn | devstrictEnforcement mode for @return-type validation. strict rejects on mismatch, warn logs only, dev enforces only outside production
@descriptiontextAPI documentation description
@tagsTag1, Tag2Categorization tags for API documentation

Examples:

// @mode worker
// @websocket // Enable WebSocket handlers
// @label user-api // Classify this script
// @return-type { id: string, name: string, email: string }
// @return-type-mode strict // Enforce return-type at runtime
// @description User profile API
// @tags Users, Profile

Manage magic comments programmatically via API endpoints:

EndpointDescription
GET /api/v1/exec/magic-comments/schemaGet the canonical schema of all supported magic comments
GET /api/v1/exec/magic-comments/readRead magic comments from a script
PUT /api/v1/exec/magic-comments/updateUpdate magic comments on a script
POST /api/v1/exec/magic-comments/bulk-updateBulk update magic comments across multiple scripts
Terminal window
# Read magic comments from a specific script
hoody exec magic-comments read --path "api/hello.ts"

All magic comments at a glance:

CategoryComments
Execution@mode, @enabled, @timeout, @await-promises, @concurrent, @schedule
Authentication@token
CORS@cors, @cors-credentials, @cors-methods, @cors-headers, @cors-max-age
Logging@log-level, @debug, @log-request-body, @log-response-body, @log-max-body-size, @log-exclude-headers, @log-retention-days, @debug-instrument
AI@ai, @ai-model, @ai-temperature, @ai-max-tokens, @ai-key
Advanced@websocket, @rawBody, @label, @return-type, @return-type-mode, @description, @tags