Tool Frontmatter Schemas
Managed-file marker — per format (single source of truth)
Every file written by setup-agents starts with a managed-file marker so upgrade and add can detect whether a file is safe to overwrite. The syntax is format-dependent:
| Target file | Marker (line 1) |
|---|---|
.github/agents/*.agent.md | <!-- generated by platform-skills --> |
.cursor/rules/*.mdc | <!-- generated by platform-skills --> |
AGENTS.md, .windsurfrules | <!-- generated by platform-skills --> |
agents/openai.yaml | # generated by platform-skills |
.vscode/settings.json, .claude/settings.json | No marker — JSON has no comment syntax. These files are merge-only, never full-write. They never need an overwrite guard because the mode always merges into the existing document. |
CLAUDE.md | No marker — append-only. Never overwrite. |
Overwrite guard (apply before writing any pre-existing agent file):
managed() { head -1 "$1" 2>/dev/null | grep -q 'generated by platform-skills'; }
# Usage: if [ -f "$target" ] && ! managed "$target"; then
# echo "⚠️ $target exists and is hand-authored — skipping. Inspect manually."
# fi
This check works across both comment styles (<!-- and #) because it greps for the common substring.
References: generate mode Step 7, add mode Step 3. The rule lives here — do not re-state it in mode files.
GitHub Copilot .agent.md
Agent files go in .github/agents/<role>.agent.md.
VS Code custom agent (target: vscode)
---
description: <one sentence — shown in agent picker and @mention tooltip>
model: <chosen in Step 6b — see generate mode>
target: vscode
tools:
- read
- execute
- edit
- search
---
MCP servers for VS Code are configured in .vscode/settings.json (see MCP wiring section below), not in .agent.md frontmatter — mcp-servers is ignored by the VS Code Copilot Chat runtime for custom agents.
Copilot cloud agent (target: github-copilot)
---
description: <one sentence — shown in agent picker and @mention tooltip>
model: <chosen in Step 6b — see generate mode>
target: github-copilot
tools:
- read
- execute
- edit
- search
mcp-servers:
github:
type: 'http'
url: 'https://api.githubcopilot.com/mcp/'
tools:
- github/create_pull_request
- github/get_file_contents
- github/list_commits
# Scope to only the tools this agent actually needs — avoid tools: ["*"]
---
mcp-servers is only used in cloud (worktree) agent profiles. Omit target entirely to generate a single file that applies to both VS Code and Copilot App — in that case, omit mcp-servers (VS Code ignores it, but it is dead config and confusing).
Built-in tool aliases: read (file reading), execute (shell), edit (file modification), search (codebase/text), web (URL/fetch). MCP server tools are referenced as <server-name>/<tool> or <server-name>/*.
Read-only agents (reviewer, navigator): omit execute, edit from tools.
Cursor .mdc
---
description: <one sentence — shown in Cursor UI>
globs: <e.g. "src/**/*.py,tests/**/*.py">
alwaysApply: false
---
Coordinator: alwaysApply: true or broad globs. Navigator: globs: "**/*" with alwaysApply: false — broad coverage without forcing activation on every file open.
Windsurf .windsurfrules
Add if .windsurfrules exists in the repo or developer uses Windsurf:
<!-- generated by platform-skills -->
# <repo> — Windsurf Rules
AGENTS.md is the source of truth. Read it first.
## Agents
| Agent | Owns | Invoke when |
|-------|------|-------------|
| coordinator | routing, planning | start of any multi-step task |
| [role] | [paths] | [trigger] |
## Off-limits
<from AGENTS.md off-limits section>
Add to verify.sh: test -f .windsurfrules && check "Windsurf rules present" "grep -q 'generated by platform-skills' .windsurfrules" || info "Windsurf rules"
Claude Code CLAUDE.md section
Append — never replace existing content:
## Agent Context
> AGENTS.md is the source of truth. Start every session by reading it.
| Agent | Owns | Handoff trigger |
|-------|------|----------------|
| coordinator | routing, AGENTS.md | always first |
| app | src/, tests/ | code/test requests |
| reviewer | read-only | pre-merge reviews |
| navigator | read-only, any file | "help me understand" |
Codex agents/openai.yaml
The file must preserve the interface: and policy: top-level keys — tests/validate-skill.sh checks them.
# generated by platform-skills
interface:
display_name: "<repo display name>"
short_description: "<one sentence>"
default_prompt: "<default prompt>"
policy:
allow_implicit_invocation: true
agents:
coordinator:
description: Lead orchestrator. Source of truth is AGENTS.md.
model: <model chosen in Step 6b>
app:
description: App agent — src/, tests/, Dockerfile
model: <model chosen in Step 6b>
navigator:
description: Read-only guide — helps understand the codebase
model: <model chosen in Step 6b>
Do not hardcode a model name — use the placeholder and populate from Step 6b. Stale model IDs (o3-mini, gpt-4o) rot silently.
copilot-setup-steps.yml
Generated when Copilot App detected. Use the asset template — do not regenerate inline:
bash assets/render.sh assets/copilot-setup-steps.template.yml \
CHECKOUT_SHA="<fetch>" CHECKOUT_VERSION="4" \
SETUP_TERRAFORM_SHA="<fetch>" SETUP_TERRAFORM_VERSION="3" TERRAFORM_VERSION="<detected>" \
CONFIGURE_AWS_SHA="<fetch>" CONFIGURE_AWS_VERSION="4" \
> .github/workflows/copilot-setup-steps.yml
Remove blocks for runtimes not present in the repo (Node, Python, Java/Kotlin). Keep only what the repo actually uses.
SHA pins: fetch the commit SHA for the release tag — never use
heads/main.gh api repos/actions/checkout/git/ref/tags/v4 --jq '.object.sha'gh api repos/hashicorp/setup-terraform/git/ref/tags/v3 --jq '.object.sha'If the tag is annotated (
object.type == "tag"), follow the dereference URL to get the commit SHA.
MCP wiring
VS Code — merge, do not overwrite
Use https://api.githubcopilot.com/mcp/ for the GitHub MCP server in VS Code. This endpoint authenticates via the developer's existing Copilot OAuth session — no PAT to create, rotate, or store. The old npx @modelcontextprotocol/server-github + GITHUB_PERSONAL_ACCESS_TOKEN approach is deprecated in favour of this.
.vscode/mcp.json (current VS Code-native format):
{
"servers": {
"filesystem": { "type": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "."] },
"github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/" }
}
}
.vscode/settings.json (older Copilot-specific key — kept for compatibility):
{
"github.copilot.chat.mcpServers": {
"filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "."] },
"github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/" }
}
}
Claude Code (.claude/settings.json)
Claude Code has no Copilot OAuth session, so api.githubcopilot.com/mcp/ does not work here. Use gh auth token piped into the env var — avoids a stored PAT:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
}
}
}
${GITHUB_TOKEN} resolves from the shell environment. Populate it with export GITHUB_TOKEN=$(gh auth token) in the developer's shell profile — no long-lived secret required.