You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/reference/file-formats.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1056,17 +1056,17 @@ Goose configures MCP servers in two locations depending on scope:
1056
1056
- **Global (`--global`):** MCP servers are written as **extensions** in the shared user config `~/.config/goose/config.yaml`. The schema is non-standard, so Rulesync maps canonical MCP fields to Goose's: `command` → `cmd` (an array `command` folds its tail into `args`), `env` → `envs`, `url`/`httpUrl` → `uri`, and `disabled: true` → `enabled: false`. The `type` is derived — `command` ⇒ `stdio`, a remote `url` ⇒ `streamable_http` (or `sse` when the canonical `type` is `sse`). Each extension also carries its own `name`. A canonical server with no `command` and no `url` is **skipped with a warning** rather than written as a `stdio` extension with no `cmd`, which Goose cannot start. Generation merges the `extensions:` block into the existing `config.yaml`, preserving other Goose settings (model, provider, ...), and the file is never deleted. The `extensions:` map itself is co-owned: Goose's own `builtin`/`platform`/`frontend`/`inline_python` extensions (`developer`, `memory`, ...) live there alongside MCP servers and are **carried over untouched**, as is any entry Rulesync cannot read as an MCP server, while every entry it positively identifies as one (`stdio`/`streamable_http`/`sse`) is Rulesync-owned, so a server deleted from `.rulesync/.mcp.json` is retracted with a warning naming it. Import mirrors this: a non-MCP extension type is skipped with a warning instead of being imported as a server (importing a `builtin` used to strip the type that makes it work). This location supports **both stdio and remote** (http/sse) servers.
1057
1057
-**Project:** Goose v1.39.0+ discovers MCP extensions in **open plugins** at `<project>/.agents/plugins/<name>/.mcp.json` (and `~/.agents/plugins/<name>/.mcp.json` at user scope). Rulesync emits `.agents/plugins/rulesync/.mcp.json`, reusing the same `.agents/plugins/rulesync/` tree already used for Goose hooks. The manifest uses the **Claude-style**`{ "mcpServers": { "<name>": { "command", "args", "env", "cwd" } } }` shape. This manifest is **stdio-only** — it cannot express `url`/`headers`, so **remote (http/sse) servers are skipped with a warning** in project mode; sync them with `--global` to `~/.config/goose/config.yaml` instead. The `.mcp.json` manifest is owned by Rulesync and is deleted when no servers remain.
1058
1058
1059
-
See the [Goose extensions docs](https://block.github.io/goose/docs/getting-started/using-extensions/) and [open-plugins MCP PR #9471](https://github.com/block/goose/pull/9471).
1059
+
See the [Goose extensions docs](https://goose-docs.ai/docs/getting-started/using-extensions/) and [open-plugins MCP PR #9471](https://github.com/aaif-goose/goose/pull/9471).
1060
1060
1061
1061
### Goose-specific: commands as recipes, subagents as custom agents
1062
1062
1063
-
Goose [recipes](https://block.github.io/goose/docs/guides/recipes/recipe-reference/) are reusable YAML workflow files. **Commands** map to top-level recipes at `.goose/recipes/<name>.yaml` (project) and `~/.config/goose/recipes/<name>.yaml` (global); the command body becomes the recipe `prompt`, `title` defaults to the file name and `description` to the rulesync `description` (falling back to `title`), `version` defaults to `1.0.0`, and any other recipe field round-trips through the rulesync `goose` section of a command.
1063
+
Goose [recipes](https://goose-docs.ai/docs/guides/recipes/recipe-reference/) are reusable YAML workflow files. **Commands** map to top-level recipes at `.goose/recipes/<name>.yaml` (project) and `~/.config/goose/recipes/<name>.yaml` (global); the command body becomes the recipe `prompt`, `title` defaults to the file name and `description` to the rulesync `description` (falling back to `title`), `version` defaults to `1.0.0`, and any other recipe field round-trips through the rulesync `goose` section of a command.
1064
1064
1065
1065
A recipe on disk is not invocable as `/name` on its own: Goose resolves slash commands from the `slash_commands` list in the user config (`~/.config/goose/config.yaml`), whose entries are `{ command, recipe_path }` pairs. In **global mode** Rulesync therefore registers every generated recipe there. `recipe_path` is written as an **absolute** path, because Goose resolves it with a bare `PathBuf::from(...)` on this code path (the tilde expansion used by `goose run --recipe` does not apply, so a `~/…` registration would never resolve), and the command name is lowercased, because Goose lowercases the typed command and compares it against the stored value verbatim. There is no project-level registration surface upstream, so project-scope recipes must still be run with `goose run --recipe`.
1066
1066
1067
-
The list is co-owned: entries whose `recipe_path` points outside `~/.config/goose/recipes/` — and sub-recipes under `recipes/subagents/` — are carried over untouched, while **every** entry pointing directly into that directory is Rulesync-owned and recomputed on each `--global` generate. That retracts a deleted command's registration and drops the key once nothing is registered, but it also means a slash command you registered yourself (via Goose's own UI or `goose recipe`) for a recipe living in that directory is removed on the next generate — keep such recipes elsewhere, or author them in `.rulesync/commands/`. Command names must be unique, contain no spaces, and must not shadow a built-in command such as `/recipe`, `/compact`, or `/help`; Rulesync does not check the built-in names for you. See the [slash-command mapping in the Goose source](https://github.com/block/goose/blob/main/crates/goose/src/slash_commands/recipe_slash_command.rs).
1067
+
The list is co-owned: entries whose `recipe_path` points outside `~/.config/goose/recipes/` — and sub-recipes under `recipes/subagents/` — are carried over untouched, while **every** entry pointing directly into that directory is Rulesync-owned and recomputed on each `--global` generate. That retracts a deleted command's registration and drops the key once nothing is registered, but it also means a slash command you registered yourself (via Goose's own UI or `goose recipe`) for a recipe living in that directory is removed on the next generate — keep such recipes elsewhere, or author them in `.rulesync/commands/`. Command names must be unique, contain no spaces, and must not shadow a built-in command such as `/recipe`, `/compact`, or `/help`; Rulesync does not check the built-in names for you. See the [slash-command mapping in the Goose source](https://github.com/aaif-goose/goose/blob/main/crates/goose/src/slash_commands/recipe_slash_command.rs).
1068
1068
1069
-
**Subagents** map to Goose's [custom agents](https://block.github.io/goose/docs/guides/context-engineering/custom-agents/) (v1.34.0+): Markdown files with `name` (required) / `description` / `model` frontmatter whose body is the agent instructions, invocable via `@name` or delegation. They are emitted to the goose-specific discovery dirs `.goose/agents/<name>.md` (project) and `~/.config/goose/agents/<name>.md` (global), so the output cannot collide with a future shared `.agents/agents/` target; `model` and unknown future fields round-trip through the rulesync `goose` subagent section. Earlier rulesync versions emitted subagents as sub-recipe YAML under `.goose/recipes/subagents/` — a location Goose's agent discovery never scans, so those files were inert; they are no longer generated (stale outputs stay gitignored but are not cleaned up automatically).
1069
+
**Subagents** map to Goose's [custom agents](https://goose-docs.ai/docs/guides/context-engineering/custom-agents/) (v1.34.0+): Markdown files with `name` (required) / `description` / `model` frontmatter whose body is the agent instructions, invocable via `@name` or delegation. They are emitted to the goose-specific discovery dirs `.goose/agents/<name>.md` (project) and `~/.config/goose/agents/<name>.md` (global), so the output cannot collide with a future shared `.agents/agents/` target; `model` and unknown future fields round-trip through the rulesync `goose` subagent section. Earlier rulesync versions emitted subagents as sub-recipe YAML under `.goose/recipes/subagents/` — a location Goose's agent discovery never scans, so those files were inert; they are no longer generated (stale outputs stay gitignored but are not cleaned up automatically).
1070
1070
1071
1071
### Vibe-specific: stdio `cwd` and MCP `[auth]` block
0 commit comments