Windsurf
Windsurf adapter contract
Overview
@stax/windsurf is the canonical stax adapter for Windsurf (formerly Codeium).
Windsurf's Cascade agent uses .windsurf/rules/*.md for rules, .windsurf/workflows/*.md for workflows, and AGENTS.md for always-on instructions. MCP is configured at the user level only via ~/.codeium/windsurf/mcp_config.json.
This adapter targets the documented Windsurf file contract described in 17 — Runtime File Contracts.
Scope model
| Scope | Typical files |
|---|---|
| Project | .windsurf/rules/*.md, .windsurf/workflows/*.md, AGENTS.md |
| User | ~/.codeium/windsurf/memories/global_rules.md, ~/.codeium/windsurf/global_workflows/*.md, ~/.codeium/windsurf/mcp_config.json |
| Legacy | .windsurfrules (project root, deprecated in favor of .windsurf/rules/) |
| System (enterprise) | /Library/Application Support/Windsurf/rules/*.md (macOS), /etc/windsurf/rules/*.md (Linux) |
In stax 1.0.0, @stax/windsurf SHOULD default to project scope.
Adapter interface
interface WindsurfAdapterOptions {
model?: string;
modelParams?: Record<string, unknown>;
scope?: "project" | "user";
exact?: boolean;
writeRules?: boolean; // default: true
writeWorkflows?: boolean; // default: false — workflows are user-authored
writeMcp?: boolean; // default: true
writeInstructions?: boolean; // default: true
legacyWindsurfrules?: boolean; // default: false — emit .windsurfrules instead of .windsurf/rules/
config?: Record<string, unknown>; // Windsurf-specific settings
}The compiled adapter config SHOULD use:
{
"type": "windsurf",
"runtime": "windsurf",
"adapterVersion": "1.0.0"
}Exact target mapping
Project scope
| stax source | Target |
|---|---|
surfaces/instructions.md or composed prompt | AGENTS.md |
| rules | .windsurf/rules/*.md |
| skills (as workflows) | .windsurf/workflows/*.md |
User scope
| stax source | Target |
|---|---|
surfaces/instructions.md or composed prompt | ~/.codeium/windsurf/memories/global_rules.md |
| MCP layer | ~/.codeium/windsurf/mcp_config.json |
| skills (as workflows) | ~/.codeium/windsurf/global_workflows/*.md |
AGENTS.md generation
Windsurf supports AGENTS.md at the project root as an always-on instruction file. Subdirectory AGENTS.md files are auto-scoped to their directory.
The adapter SHOULD choose the first available source in this order:
surfaces/instructions.mdprompt- synthesized composition
In exact mode, if composition is required because no exact source document exists, the consumer MUST warn or fail according to policy.
Rules mapping
Windsurf uses .md files in .windsurf/rules/ with YAML frontmatter.
Rule translation
Each canonical stax rule SHOULD be translated to a .windsurf/rules/<rule-id>.md file with the following frontmatter mapping:
| stax rule field | Windsurf frontmatter field |
|---|---|
scope: 'always' | trigger: always_on |
scope: 'auto' | trigger: model_decision + description (required) |
scope: 'glob' | trigger: glob + globs |
scope: 'manual' | trigger: manual |
globs | globs |
id | filename stem |
Example output
---
trigger: model_decision
description: "Enforce TypeScript naming conventions"
---
Use PascalCase for types and interfaces.
Use camelCase for variables and functions.Character limits
- individual rule files: 12,000 characters
- combined global + workspace rules budget: 12,000 characters in prompt
The adapter SHOULD warn when a translated rule exceeds the 12,000 character limit.
Lossy translations
- stax
priorityandseverityhave no Windsurf equivalent and MUST be dropped with a warning - stax
triggershave no Windsurf equivalent beyond the trigger mode and MUST be dropped with a warning
MCP mapping
Windsurf stores MCP configuration at the user level only in ~/.codeium/windsurf/mcp_config.json.
There is no project-level MCP configuration in Windsurf. This is a significant difference from other runtimes.
Output format
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${env:GITHUB_TOKEN}"
}
},
"remote-server": {
"serverUrl": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer ${env:AUTH_TOKEN}"
}
}
}
}Key differences from other runtimes
- MCP is user-scoped only — no project-level
.windsurf/mcp.json - remote HTTP transport uses
serverUrl(noturl) - SSE transport uses
url - environment variable interpolation uses
${env:VARIABLE_NAME}syntax - tool limit: 100 total tools across all MCP servers
Mapping rules
- stdio servers map to
command,args, and optionalenv - remote HTTP servers map to
serverUrland optionalheaders - SSE servers map to
urland optionalheaders - secret values SHOULD use
${env:VARIABLE}syntax - the adapter MUST warn that MCP config is user-scoped and not project-portable
- unsupported canonical MCP fields MUST trigger warnings
Skills-to-workflows mapping
Windsurf does not have a native skill format. Instead, it uses workflows — Markdown files invoked via /workflow-name.
stax skills MAY be translated to .windsurf/workflows/<skill-name>.md:
- workflow files do not use YAML frontmatter
- the skill content SHOULD be adapted to workflow format (numbered steps)
- workflows are manual-only (never auto-invoked by Cascade)
- 12,000 character limit per workflow file
This translation is inherently lossy because:
- skill frontmatter fields (
argument-hint,user-invocable, etc.) have no workflow equivalent - skills may be auto-invocable; workflows are manual-only
The adapter MUST warn when translating skills to workflows.
Legacy .windsurfrules support
When legacyWindsurfrules: true is set, the adapter SHOULD:
- compose all rules and instructions into a single
.windsurfrulesfile at the project root - warn that this is a deprecated path and has a 6,000 character limit
- not emit
.windsurf/rules/files
Feature map
{
"prompt": "native",
"persona": "embedded",
"rules": "translated",
"skills": "translated",
"mcp": "translated",
"surfaces": "embedded",
"secrets": "consumer-only",
"toolPermissions": "unsupported",
"modelConfig": "unsupported",
"exactMode": true
}What the adapter MUST NOT own
~/.codeium/windsurf/memories/(auto-generated memories, per-workspace state)~/Library/Application Support/Windsurf/(app state, caches, auth)~/.codeium/.codeiumignore(enterprise-specific)- auth tokens, credential files
- session state, logs, caches
Exactness requirements
An implementation claiming exact Windsurf support SHOULD:
- write
.windsurf/rules/*.mdwith correct trigger frontmatter - write
AGENTS.mdwhen source instructions exist - warn that MCP config is user-scoped only
- warn when skills are translated to workflows
- respect the 12,000 character limit per rule file
- avoid writing state, auth, or app-level settings
- warn or fail when lossy translations occur in
exactmode