llms.txt@docs/public · git:20260930.b15f139 · 2026-09-30 · sha256 78d1d8b4ba8f80ff
llms.txt@docs/public git:20260930.b15f139A
Immutable. This exact content never changes and is served at /api/v1/blob/78d1d8b4ba8f80ff.
# dotagents
> Shared tooling for coding agents
dotagents manages agent skills, MCP servers, hooks, subagents, and plugins declared in `agents.toml`, and handles symlinks and config generation so tools like Claude Code, Cursor, Codex, GitHub Copilot CLI, Grok, VS Code, and OpenCode are configured from a single source of truth.
Install: `npm install -g @sentry/dotagents`
Run without installing: `npx @sentry/dotagents <command>`
## Quick Start (Global by Default)
```bash
# Initialize global state under ~/.agents/ (interactive TUI)
npx @sentry/dotagents init
# Add a single skill from GitHub
npx @sentry/dotagents add getsentry/skills find-bugs
# Add multiple skills at once
npx @sentry/dotagents add getsentry/skills find-bugs code-review commit
# Add all skills from a repo
npx @sentry/dotagents add getsentry/skills --all
# Add a plugin
npx @sentry/dotagents add getsentry/agent-plugins review-tools
# Install or refresh all declared dependencies
npx @sentry/dotagents install
```
These unqualified commands create and use `~/.agents/agents.toml`, even when run inside a repository. To manage repository-local state, make project intent explicit:
```bash
npx @sentry/dotagents --project init
npx @sentry/dotagents --project add getsentry/skills find-bugs
npx @sentry/dotagents --project install
npx @sentry/dotagents --project doctor --fix
```
The selected config contains entries such as:
```toml
version = 1
agents = ["claude"]
[[skills]]
name = "find-bugs"
source = "getsentry/skills"
```
And a lockfile (`agents.lock`) tracking which skills, subagents, and plugins are managed. In project scope, `agents.lock` and `.agents/.gitignore` are automatically added to the root `.gitignore`.
## How It Works
1. Declare global dependencies in `~/.agents/agents.toml`, or project dependencies in `<project>/agents.toml`
2. `install` clones or refreshes sources and copies skills, subagents, and plugins into the selected scope's managed directories
3. `agents.lock` tracks which skills, subagents, and plugins are managed (automatically gitignored in project scope)
4. Managed project skills, canonical installed subagents, and managed plugin bundles under `.agents/` are gitignored. Collaborators run `npx @sentry/dotagents --project install` after cloning. Custom skills in `.agents/skills/` and project-authored plugin source directories in `.agents/plugins/` are tracked by git normally when they are not installed dependencies.
5. Symlinks connect `.agents/skills/` to each agent's expected location (`.claude/skills/` for Claude and Cursor)
6. MCP, hook, subagent, and plugin configs are generated for each declared agent where supported
## Configuration (agents.toml)
Full example with all sections:
```toml
version = 1
agents = ["claude", "cursor", "codex", "copilot", "grok", "opencode", "pi"]
minimum_release_age = 60
minimum_release_age_exclude = ["getsentry/*"]
[project]
name = "my-project"
# Trust policy (optional -- restricts allowed sources)
[trust]
github_orgs = ["getsentry"]
github_repos = ["external-org/specific-repo"]
git_domains = ["git.corp.example.com"]
# Individual skill
[[skills]]
name = "find-bugs"
source = "getsentry/skills"
# Pinned to a ref
[[skills]]
name = "review"
source = "getsentry/skills@v1.0.0"
# Non-GitHub git
[[skills]]
name = "internal"
source = "git:https://git.corp.dev/repo"
# Well-known HTTPS source
[[skills]]
name = "error-tracking"
source = "https://cli.sentry.dev"
# Local directory
[[skills]]
name = "local"
source = "path:./my-skills/local-skill"
# Wildcard: all skills from a repo
[[skills]]
name = "*"
source = "getsentry/skills"
exclude = ["deprecated-skill"]
# Stdio MCP server
[[mcp]]
name = "github"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
env = ["GITHUB_TOKEN"]
# Streamable HTTP MCP server
[[mcp]]
name = "remote-api"
url = "https://mcp.example.com/mcp"
# Streamable HTTP server with secrets via env vars
[[mcp]]
name = "authed-api"
url = "https://${API_HOST}/mcp"
headers = { X-Api-Key = "${API_KEY}" }
# Hooks
[[hooks]]
event = "PreToolUse"
matcher = "Bash"
command = "my-lint-check"
[[hooks]]
event = "Stop"
command = "notify-done"
# Custom subagent
[[subagents]]
name = "code-reviewer"
source = "getsentry/agent-pack"
targets = ["claude", "codex", "opencode"]
# Plugin bundle
[[plugins]]
name = "review-tools"
source = "getsentry/agent-plugins"
path = "plugins/review-tools"
targets = ["claude", "cursor", "codex", "copilot", "grok", "opencode", "pi"]
```
### Top-level Fields
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `version` | integer | Yes | -- | Schema version. Always `1`. |
| `defaultRepositorySource` | string | No | `github` | Host used for shorthand `owner/repo` skill sources. Valid values: `github`, `gitlab`. |
| `agents` | string[] | No | `[]` | Agent tool IDs: `claude`, `cursor`, `codex`, `copilot`, `grok`, `vscode`, `opencode`, `pi`. Creates symlinks and config files for each where supported. `grok` and `pi` are plugin-only targets. |
| `subagents` | table[] | No | `[]` | Custom subagent declarations. Generates runtime-specific files for Claude, Cursor, Codex, and OpenCode. |
| `plugins` | table[] | No | `[]` | Plugin declarations. Installs canonical bundles into `.agents/plugins/` and generates runtime plugin outputs for Claude, Cursor, Codex, Copilot, Grok, OpenCode, and Pi skill projection where supported. |
| `minimum_release_age` | integer | No | -- | Minimum commit age, in minutes, before a git skill, subagent, or plugin can install. |
| `minimum_release_age_exclude` | string[] | No | `[]` | Sources that bypass the minimum release age gate. Supports org names, `org/repo`, and `org/*`. |
### Skills
Each `[[skills]]` entry requires `name` and `source`. Optional fields: `ref` (git ref), `path` (subdirectory override).
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Skill name. Pattern: `^[a-zA-Z0-9][a-zA-Z0-9._-]*$`. Use `"*"` for wildcard. |
| `source` | string | Yes | `owner/repo` (resolved via `defaultRepositorySource`), `owner/repo@ref`, `https://github.com/owner/repo`, `https://gitlab.com/group/repo`, `https://<domain>` (well-known), `git:<url>`, or `path:<relative>` |
| `ref` | string | No | Git ref (tag, branch, or SHA). Also supported inline: `owner/repo@ref`. |
| `path` | string | No | Named skills: explicit skill directory when auto-discovery fails. Wildcards: contained source subtree to scan recursively. |
| `exclude` | string[] | No | Skills to skip. Wildcard entries only. |
Source formats:
- `owner/repo` -- shorthand resolved by `defaultRepositorySource` (defaults to GitHub)
- `owner/repo@ref` -- shorthand pinned to a tag/branch/commit
- `https://github.com/owner/repo` -- explicit GitHub URL
- `https://gitlab.com/group/repo` -- explicit GitLab URL
- `https://<domain>` -- Well-known HTTP skill source (discovers skills via `.well-known/skills/index.json`)
- `git:<url>` -- Non-GitHub git (requires https://, git://, ssh://, git@, file://, or absolute path)
- `path:<relative>` -- Local filesystem path (relative to the selected scope root)
### Wildcard Skills
Set `name = "*"` to install all skills from a source. Use `exclude` to skip specific skills.
```toml
[[skills]]
name = "*"
source = "getsentry/skills"
exclude = ["deprecated-skill"]
```
Wildcards are expanded during `install`. Each discovered skill gets its own lockfile entry.
### MCP Servers
Each `[[mcp]]` entry requires `name` and either `command` (stdio) or `url` (Streamable HTTP), not both.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Unique server identifier |
| `command` | string | Stdio only | Command to execute |
| `args` | string[] | No | Command arguments |
| `url` | string | HTTP only | Server URL |
| `headers` | table | No | HTTP headers (url servers only). Supports `${VAR}` syntax for env var interpolation. |
| `env` | string[] | No | Environment variable names to pass through |
Use `${VAR}` in header values and `url` to reference secrets from the environment. Write `${VAR}` in `agents.toml`. Dotagents keeps this syntax for Claude and GitHub Copilot. Cursor and VS Code use `${env:VAR}`, OpenCode uses `{env:VAR}`, and Codex moves pure references to `env_http_headers`. Mixed Codex values such as `"Bearer ${TOKEN}"` stay as literals.
Config files generated per agent:
- Claude: `.mcp.json` (JSON)
- Cursor: `.cursor/mcp.json` (JSON)
- Codex: `.codex/config.toml` (TOML, shared with other Codex config)
- VS Code: `.vscode/mcp.json` (JSON)
- OpenCode: `.opencode/opencode.jsonc` by default (JSONC, shared). Existing `.opencode/opencode.json`, `opencode.jsonc`, or `opencode.json` files are reused in precedence order.
- GitHub Copilot: `.mcp.json` by default (JSON). An existing `.github/mcp.json` is reused when `.mcp.json` is absent.
Copilot accepts both bare server maps and `mcpServers` documents. Global MCP uses `$COPILOT_HOME/mcp-config.json` (default `~/.copilot/mcp-config.json`).
### Hooks
Each `[[hooks]]` entry requires `event` and `command`. Optional: `matcher` to filter by tool name.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `event` | string | Yes | `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop` |
| `matcher` | string | No | Tool name filter (e.g. `Bash`, `Write`) |
| `command` | string | Yes | Shell command to run |
Hook config files per agent:
- Claude: `.claude/settings.json` (merged into existing file)
- Cursor: `.cursor/hooks.json` (dedicated file, events mapped to Cursor equivalents)
- VS Code: `.claude/settings.json` (same file as Claude)
- Codex/OpenCode: not supported
Cursor event mapping:
- `PreToolUse` -> `beforeShellExecution` + `beforeMCPExecution`
- `PostToolUse` -> `afterFileEdit`
- `UserPromptSubmit` -> `beforeSubmitPrompt`
- `Stop` -> `stop`
### Subagents
Each `[[subagents]]` entry requires `name` and `source`. Optional: `ref`, `path`, and `targets`. When `targets` is absent or empty, dotagents attempts every agent listed in `agents` and warns for agents that do not support custom subagents.
dotagents treats subagents as best-effort portable dependencies, not a universal behavior schema. Runtime-specific behavior such as model routing, tool permissions, read-only modes, background execution, and reasoning effort stays in each tool's native artifact.
dotagents discovers portable subagent Markdown from `agents/` and `.agents/agents/`. It also imports native runtime artifacts from `.claude/agents/*.md`, `.cursor/agents/*.md`, `.codex/agents/*.toml`, and `.opencode/agents/*.md`. Root-level source files require an explicit `path`. Multiple portable matches for the same subagent are rejected as ambiguous, while matching native runtime artifacts are merged. When the source format matches a target runtime, dotagents reuses the native source content for that runtime and only adds its managed-file marker. Other runtimes are generated from the portable `name`, `description`, and instructions.
Accepted source/output formats:
| Format | Source path | Matching output path | Required source fields |
|--------|-------------|----------------------|------------------------|
| Portable Markdown | `agents/*.md`, `.agents/agents/*.md` | `.agents/agents/<name>.md` | YAML `name`, `description`; Markdown body |
| Claude Markdown | `.claude/agents/*.md` | `.claude/agents/<name>.md` | YAML `name`, `description`; Markdown body |
| Cursor Markdown | `.cursor/agents/*.md` | `.cursor/agents/<name>.md` | YAML `description`; Markdown body; `name` optional |
| Codex TOML | `.codex/agents/*.toml` | `.codex/agents/<name>.toml` | TOML `name`, `description`, `developer_instructions` |
| OpenCode Markdown | `.opencode/agents/*.md` | `.opencode/agents/<name>.md` | YAML `description`; Markdown body |
Codex native `name` may use Codex-specific naming; dotagents uses the `agents.toml` name or filename as the portable ID when needed. Cursor native Markdown may omit `name`; dotagents uses the filename in that case. OpenCode native Markdown always uses the filename as the subagent name.
```md
---
name: code-reviewer
description: Review code for correctness, security, and missing tests.
---
Review the current diff and return findings with file references.
```
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Lowercase subagent identifier to discover. Pattern: `^[a-z][a-z0-9-]*$`. |
| `source` | string | Yes | Source repository or local directory. Supports GitHub/GitLab shorthands, git URLs, and `path:` sources; HTTPS well-known skill indexes are not supported for subagents. |
| `ref` | string | No | Optional git ref override. |
| `path` | string | No | Optional explicit subagent file path inside the source. Markdown paths are portable or native Markdown; `.toml` paths are Codex native artifacts. |
| `targets` | string[] | No | Optional subset of agent IDs. When absent or empty, defaults to every configured agent in `agents`; unsupported configured agents produce warnings. |
Generated subagent files:
- Claude: `.claude/agents/<name>.md`, or `~/.claude/agents/<name>.md` for global scope
- Cursor: `.cursor/agents/<name>.md`, or `~/.cursor/agents/<name>.md` for global scope
- Codex: `.codex/agents/<name>.toml`, or `~/.codex/agents/<name>.toml` for global scope
- OpenCode: `.opencode/agents/<name>.md`, or `~/.config/opencode/agents/<name>.md` for global scope
Generated files include a dotagents header marker. `install` and `sync` overwrite stale managed files and prune removed managed files, but they do not overwrite hand-written files without the generated header marker. They also avoid creating duplicate runtime identities when an unmanaged file in the same agent directory already declares the same subagent. The deprecated `--frozen` flag is a warned compatibility no-op.
### Plugins
Each `[[plugins]]` entry requires `name` and `source`. Optional: `ref`, `path`, and `targets`. When `targets` is absent or empty, dotagents targets every agent listed in `agents`.
dotagents installs canonical plugin bundles under `.agents/plugins/<name>/`. New bundles use Agent Plugins v1: required `plugin.json`, optional `skills/`, optional `mcp.json`, and reverse-domain client extensions. Portable source files are preserved and target JSON remains client-native. OpenCode receives portable MCP servers under managed `plugin.<plugin>.<server>` keys, with `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` expanded into installed and persistent managed paths. Generated JSON uses adjacent ownership sidecars; component symlinks use marker files in reserved `.dotagents-managed/` directories. Native Claude/Cursor/Codex bundles may be imported conservatively. A valid standard root may coexist with authored Claude, Cursor, or Codex manifests as a hybrid compatibility bundle: the portable root remains the source of truth, reproducible native manifests are ignored in favor of portable generation, and manifests with unrepresentable behavior are retained byte-for-byte only as matching-client fallbacks. Generated adapters are disposable and never become portable or fallback input. Native commands, agents, hooks, MCP, and other resources are not guessed or cross-translated. A malformed fallback fails preflight only when its client is selected; unselected fallbacks remain inert with warnings. Invalid standard roots never downgrade to native or generalized legacy parsing.
For bundles with native manifests but no root `plugin.json`, Codex, Claude, then Cursor order determines the primary manifest. All native manifests are preserved for their matching clients. The primary manifest must be valid; errors in additional manifests block installation only when their client is selected.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | 1-64 character lowercase plugin identifier with alphanumeric ends, only letters, numbers, hyphens, and dots, and no `--` or `..`. |
| `source` | string | Yes | Source repository or local directory. Supports GitHub/GitLab shorthands, git URLs, and `path:` sources; HTTPS well-known skill indexes are not supported for plugins. |
| `ref` | string | No | Optional git ref override. |
| `path` | string | No | Optional explicit plugin directory path inside the source. |
| `targets` | string[] | No | Optional subset of configured agent IDs. When absent or empty, defaults to every configured agent in `agents`; targets not listed in top-level `agents` are skipped with a warning. |
Generated project-scope plugin outputs:
- Claude: `.claude-plugin/marketplace.json` and `.agents/plugins/<name>/.claude-plugin/plugin.json`
- GitHub Copilot: `.github/plugin/marketplace.json`; Copilot consumes the canonical `.agents/plugins/<name>/plugin.json`
- Cursor: `.cursor-plugin/marketplace.json` and `.agents/plugins/<name>/.cursor-plugin/plugin.json`
- Codex: `.agents/plugins/marketplace.json` and `.agents/plugins/<name>/.codex-plugin/plugin.json`
- Grok: `.grok/plugins/<name>/` managed copy
- OpenCode: plugin `skills/` symlinked into `.opencode/skills/`; portable `mcp.json` servers merged into `.opencode/opencode.jsonc` under `plugin.<plugin>.<server>` keys; generalized legacy plugin Markdown `agents/` symlinked into `.opencode/agents/`. Standard extension agents are preserved but not projected yet.
- Pi: plugin `skills/` symlinked into `.agents/skills/` when `pi` is a configured plugin target
Generated plugin JSON is deterministic: object keys and plugin entries are sorted, output is two-space indented, and files end with one trailing newline. Generated marketplaces and Claude, Cursor, and Codex manifests use adjacent `.dotagents-managed` sidecars so client-owned JSON remains schema-native; legacy `metadata.managedBy` output remains recognizable during migration. Managed Grok copies and OpenCode and Pi component symlinks are pruned when their plugin or target is removed. Plugin sources that resolve to this project's `.agents/plugins/<name>/` install destination are rejected so dotagents never installs a same-repo plugin onto itself. Existing plugin install destinations are overwritten only when their on-disk `.dotagents-managed` marker proves ownership.
Global plugins install under `~/.agents/plugins/`. Claude and Cursor marketplaces are generated below `~/.agents/`. Copilot uses `~/.agents/.github/plugin/marketplace.json`. Codex uses `~/.agents/plugins/marketplace.json` with paths rooted at the user's home. Grok plugins are copied into `~/.grok/plugins/`. OpenCode skills use `~/.config/opencode/skills/`, portable plugin MCP servers use `~/.config/opencode/opencode.json`, and Pi skill projections use `~/.agents/skills/`.
### Trust
Optional `[trust]` section to restrict allowed skill, subagent, and plugin sources.
| Field | Type | Description |
|-------|------|-------------|
| `allow_all` | boolean | Allow all sources (overrides other fields) |
| `github_orgs` | string[] | Allowed GitHub org/user names |
| `github_repos` | string[] | Allowed exact `owner/repo` pairs |
| `git_domains` | string[] | Allowed domains or domain path prefixes for `git:` and well-known `https://` URLs (e.g., `gitlab.com/myorg`, `cli.sentry.dev`) |
Rules:
- No `[trust]` section = all sources allowed (backward compatible)
- `allow_all = true` = all sources allowed (explicit intent)
- `[trust]` present without `allow_all` = allowlist mode (source must match at least one rule)
- Local `path:` sources are always allowed
- Trust is validated before any network operations in `add` for dependencies and `install` for configured skills, subagents, and plugins
## CLI Commands
Global flags (accepted before or after the command name):
- no scope flag -- Operate on global scope (`DOTAGENTS_HOME` or `~/.agents/`); this is the default in every directory
- `--project` -- Operate on the containing Git repository, or the current directory outside Git
- `--global` -- Explicitly select global scope
- `--user` -- Compatibility alias for `--global`
- `--help`, `-h` -- Show help
- `--version`, `-V` -- Show version
`--global` and `--user` may be combined because they are equivalent. Combining `--project` with either global alias is an error before any command executes or scope is bootstrapped. Project commands other than `init` require `agents.toml`; they never fall back to or mutate global state. dotagents does not copy, merge, rename, or delete files between scopes.
### init
```
npx @sentry/dotagents init [--force] [--agents claude,cursor]
```
Create the selected scope's `agents.toml` and managed directories. Automatically includes the `dotagents` skill from `getsentry/dotagents` for CLI guidance. Interactive project init inside Git prompts for agent targets, trust policy, and optionally sets up a git `post-merge` hook to auto-run `npx @sentry/dotagents --project install` on pull (defaults to no). Both direct and npx fallback hook commands include `--project`. Project init outside Git uses the current directory and skips Git-only hook setup. Project init upgrades legacy marker-delimited hooks while preserving unrelated content and executable permissions.
| Flag | Description |
|------|-------------|
| `--agents <list>` | Comma-separated agent targets |
| `--force` | Overwrite existing `agents.toml` |
### install
```
npx @sentry/dotagents install
```
Install and refresh dependencies from `agents.toml`. Resolves sources, copies skills, installs subagents and plugins in the active scope, writes the lockfile, creates symlinks, and generates MCP, hook, subagent, and plugin configs. Project-managed paths must resolve inside the project root; traversal and outward-pointing symlinks are rejected, while in-project symlink aliases are allowed. There is no separate update command. The deprecated `--frozen` flag prints a warning and performs the same normal install; use explicit `ref` values to pin sources.
### add
```
npx @sentry/dotagents add <source> [<name>...] [--name <name>...] [--ref <ref>] [--all]
```
Add and install plugins or skills. Git and local sources are classified once: if any valid plugin is found, the entire source is plugin-only and skills in it are ignored; otherwise normal skill discovery runs. Malformed plugin-shaped content fails without falling back to skills. Local plugin sources that overlap the project's managed `.agents/plugins` directory are rejected before configuration changes. Well-known HTTPS catalogs remain skill-only.
| Flag | Description |
|------|-------------|
| `<name>...` | Positional plugin or skill names to add |
| `--name <name>` | Specify dependencies to add (repeatable) |
| `--skill <name>` | Compatibility alias for `--name`; does not force skill mode |
| `--ref <ref>` | Pin to a specific tag, branch, or commit |
| `--all` | Add every current plugin explicitly, or all skills as a wildcard (`name = "*"`) |
When a source has one dependency of the selected kind, it is added automatically. Multiple dependencies use a picker in a TTY or are listed with selection guidance in non-interactive mode. Plugin adds support project and global scope.
When adding multiple dependencies, names already declared for that kind are skipped with a warning. Exact repeats leave `agents.toml` unchanged and refresh installation; conflicting declarations still error. Positional names and `--name`/`--skill` flags cannot be mixed. Plugin `--all` is a snapshot of current candidates; skill `--all` remains a wildcard that can include future upstream skills.
Plugin declarations persist the exact discovered source path (`.` for a source-root plugin), preventing later source inventory changes from changing selection. If config mutation or installation fails, `add` restores the previous `agents.toml` content so the failed dependency is not left declared.
### remove
```
npx @sentry/dotagents remove <name|source> [-y]
```
Remove a skill or plugin from `agents.toml`, delete files from the selected scope's managed directories, update the lockfile, and prune generated plugin outputs when needed. In project scope, also regenerate `.agents/.gitignore`. For skills sourced from a wildcard entry, prompts to add the skill to the `exclude` list instead of removing the entire wildcard.
If a skill and plugin share the same name, name-based removal is rejected. When their sources differ, pass the dependency's source to disambiguate.
When the argument is a source specifier (e.g. `owner/repo`, a URL) instead of a dependency name, removes all skills and plugins from that source. Confirms before removing unless `-y` is passed.
### sync
```
npx @sentry/dotagents sync
```
Reconcile the selected scope without network access: adopt truly local orphaned skills, prune stale managed skills/subagents/plugins removed from config, regenerate managed ignore state, check for missing skills and plugins, repair symlinks, and verify/repair MCP, hook, subagent, and plugin configs. Reports issues as warnings or errors.
### mcp add
```
npx @sentry/dotagents mcp add <name> --command "<cmd> [args...]" [--env <VAR>...]
npx @sentry/dotagents mcp add <name> --url <url> [--header <Key:Value>...] [--env <VAR>...]
```
Add an MCP server declaration to `agents.toml` and run `install` to generate agent configs. Specify exactly one transport: `--command` for stdio or `--url` for Streamable HTTP.
Put stdio command arguments inside the `--command` string. dotagents splits that string into `command` and `args` in `agents.toml`.
| Flag | Description |
|------|-------------|
| `--command "<cmd> [args...]"` | Command string to execute (stdio transport) |
| `--url <url>` | Server URL (Streamable HTTP transport) |
| `--header <Key:Value>` | HTTP header (repeatable, url servers only) |
| `--env <VAR>` | Environment variable name to pass through (repeatable) |
### mcp remove
```
npx @sentry/dotagents mcp remove <name>
```
Remove an MCP server declaration from `agents.toml` and run `install` to regenerate agent configs.
### mcp list
```
npx @sentry/dotagents mcp list [--json]
```
Show declared MCP servers. Use `--json` for machine-readable output.
### trust add
```
npx @sentry/dotagents trust add <source>
```
Add a trusted source to `[trust]` in `agents.toml`. The source type is inferred automatically: contains `/` → `github_repos`, contains `.` → `git_domains`, otherwise → `github_orgs`. When `defaultRepositorySource = "gitlab"`, shorthand sources are expanded to `gitlab.com/...` and stored in `git_domains`. Creates the `[trust]` section if absent. Duplicates (case-insensitive) are rejected.
### trust remove
```
npx @sentry/dotagents trust remove <source>
```
Remove a trusted source from `[trust]` in `agents.toml`. Matching is case-insensitive. Removes the field line if the array becomes empty.
### trust list
```
npx @sentry/dotagents trust list [--json]
```
Show trusted sources with their type. Use `--json` for machine-readable output. When `allow_all = true`, reports that all sources are trusted.
### list
```
npx @sentry/dotagents list [--json]
```
Show declared skills, plugins, and status. Hybrid compatibility diagnostics appear as indented warning lines. JSON output is an object with `skills` and `plugins` arrays; plugin entries include a `warnings` array when diagnostics exist.
| Status | Meaning |
|--------|---------|
| `✓` | Installed and present in lockfile |
| `✗` | In config but not installed |
| `?` | Installed but not in lockfile |
Skills from wildcard entries are marked with a wildcard indicator.
### doctor
```
npx @sentry/dotagents doctor [--fix]
```
Check selected-scope health: gitignore setup where applicable, installed skills and plugins, hybrid plugin compatibility diagnostics, plugin runtime projections, symlinks, legacy config fields, and legacy managed project hooks. Compatibility is reported as the `plugin compatibility` check. Use `--fix` to auto-repair issues; project hook repair is `npx @sentry/dotagents --project doctor --fix`. Use `sync` in the same scope to repair generated runtime config drift.
| Flag | Description |
|------|-------------|
| `--fix` | Auto-fix issues where possible |
## Agent Targets
| ID | Tool | Config Dir | Skills Symlink | MCP Config | Hooks | Subagents |
|----|------|-----------|----------------|------------|-------|-----------|
| `claude` | Claude Code | `.claude` | `.claude/skills/` -> `.agents/skills/` | `.mcp.json` | `.claude/settings.json` | `.claude/agents/*.md` |
| `cursor` | Cursor | `.cursor` | `.claude/skills/` -> `.agents/skills/` | `.cursor/mcp.json` | `.cursor/hooks.json` | `.cursor/agents/*.md` |
| `codex` | Codex | `.codex` | (reads `.agents/skills/` natively) | `.codex/config.toml` | Not supported | `.codex/agents/*.toml` |
| `copilot` | GitHub Copilot CLI | `.copilot` | Project: reads `.agents/skills/`; global: `$COPILOT_HOME/skills/` symlink | `.mcp.json` or `.github/mcp.json` | Not supported | Not supported |
| `vscode` | VS Code Copilot | `.vscode` | (reads `.agents/skills/` natively) | `.vscode/mcp.json` | `.claude/settings.json` | Not supported |
| `opencode` | OpenCode | `.opencode` | (reads `.agents/skills/` natively) | `.opencode/opencode.jsonc` by default | Not supported | `.opencode/agents/*.md` |
Claude uses `.claude/skills/`, and Cursor shares the same Claude-compatible skills symlink. Codex, VS Code, and OpenCode read `.agents/skills/` directly.
[Pi](https://github.com/badlogic/pi-mono) reads `.agents/skills/` natively. Normal skills need no Pi-specific target or symlink configuration; plugin bundles can target `pi` when their `skills/` components should be exposed there.
## Scopes
### Global Scope (default)
Operates on `DOTAGENTS_HOME` when set and otherwise `~/.agents/`, regardless of the current directory.
- Config: `~/.agents/agents.toml`
- Skills: `~/.agents/skills/`
- Lockfile: `~/.agents/agents.lock`
- Plugins: `~/.agents/plugins/`
- Override location: `DOTAGENTS_HOME` environment variable
- Explicit spellings: `--global`, or compatibility alias `--user`
Global-scope symlinks include `~/.claude/skills/` for Claude and Cursor.
### Project Scope (`--project`)
Operates on the containing Git repository root, or the current directory outside Git. Commands other than `init` require `agents.toml`.
- Config: `<project>/agents.toml`
- Skills: `<project>/.agents/skills/`
- Lockfile: `<project>/agents.lock`
- Plugins: `<project>/.agents/plugins/`
## Skill Discovery
After cloning a repo, dotagents scans these locations for skills:
1. `<name>/SKILL.md` (root-level directory)
2. `./SKILL.md` (root-level SKILL.md for single-skill repos, matched by frontmatter `name`)
3. `skills/<name>/SKILL.md`
4. `.agents/skills/<name>/SKILL.md`
5. `.claude/skills/<name>/SKILL.md`
6. `plugins/*/skills/<name>/SKILL.md` (marketplace format, requires `.claude-plugin/` marker)
Single-skill repos with SKILL.md at the root are supported — the skill name is derived from the frontmatter `name` field. Child-directory skills take priority over root-level SKILL.md when names conflict.
Use the `path` field for explicit overrides when auto-discovery does not find the skill.
A valid skill directory contains a `SKILL.md` file with YAML frontmatter:
```markdown
---
name: my-skill
description: What this skill does
---
# Skill instructions here
```
Required frontmatter fields: `name` (string), `description` (string). Frontmatter values must recursively contain only mappings, arrays, strings, finite numbers, booleans, null, or valid timestamps.
## Lockfile (agents.lock)
Auto-generated TOML file. Do not edit manually. In project scope it is gitignored automatically (`npx @sentry/dotagents --project init` adds it to `.gitignore`).
```toml
# Auto-generated by dotagents. Do not edit.
version = 1
[skills.find-bugs]
source = "getsentry/skills"
resolved_url = "https://github.com/getsentry/skills.git"
resolved_path = "plugins/sentry-skills/skills/find-bugs"
resolved_commit = "0123456789abcdef0123456789abcdef01234567"
[subagents.code-reviewer]
source = "getsentry/agent-pack"
resolved_url = "https://github.com/getsentry/agent-pack.git"
resolved_path = "agents/code-reviewer.md"
resolved_commit = "fedcba9876543210fedcba9876543210fedcba98"
[plugins.review-tools]
source = "getsentry/agent-plugins"
resolved_url = "https://github.com/getsentry/agent-plugins.git"
resolved_path = "plugins/review-tools"
resolved_commit = "0123456789abcdef0123456789abcdef01234567"
```
| Field | Present For | Description |
|-------|-------------|-------------|
| `source` | All | Original source from `agents.toml` |
| `resolved_url` | Git and well-known sources | Resolved git clone URL or HTTP base URL |
| `resolved_path` | Git sources | Subdirectory within repo where skill was found |
| `resolved_ref` | Git sources (optional) | Resolved ref name (omitted for default branch) |
| `resolved_commit` | Git sources (optional) | Full commit SHA that was installed. Informational only; install does not use it for locking. |
Local `path:` skills, subagents, and plugins have `source` only. Subagent entries use the same fields under `[subagents.<name>]`; `resolved_path` points to the subagent file inside a git source. Plugin entries use the same fields under `[plugins.<name>]`; `resolved_path` points to the plugin directory inside a git source.
## Caching
Location: `~/.local/dotagents/` (override: `DOTAGENTS_STATE_DIR`)
- Git sources use shallow clones and refresh on every install
- Well-known HTTPS sources refresh after a 24-hour TTL
- All git operations are non-interactive (`GIT_TERMINAL_PROMPT=0`)
## Environment Variables
| Variable | Description |
|----------|-------------|
| `DOTAGENTS_STATE_DIR` | Override cache location (default: `~/.local/dotagents`) |
| `DOTAGENTS_HOME` | Override global-scope location (default: `~/.agents`) |
| `COPILOT_HOME` | Override Copilot's global skill and MCP location with a non-empty absolute path (default when unset: `~/.copilot`) |
## Gitignore
In project scope, dotagents manages Git ignore state. Global scope does not modify repository Git files. Two project files are gitignored automatically:
- `agents.lock` -- tracks managed skills, subagents, and plugins
- `.agents/.gitignore` -- excludes managed skill directories, canonical installed subagent files, and managed plugin bundles from git
`npx @sentry/dotagents --project init` adds both to the root `.gitignore`. If they're missing, project `install` and `sync` warn. Run `npx @sentry/dotagents --project doctor --fix` to add them.
Custom skills created directly in `.agents/skills/` and project-authored plugin source directories in `.agents/plugins/` are not gitignored unless they are managed installed dependencies. They're tracked by git normally.
`.agents/.gitignore` is regenerated by project `install`, `add`, `remove`, and `sync` commands.
## Refresh Strategy
Run `npx @sentry/dotagents --project install` after cloning or pulling project changes. Use unqualified `npx @sentry/dotagents install` to refresh global dependencies. Install fetches or refreshes managed skills, subagents, and plugins unless a ref is pinned. There is no separate update command.
## Links
- Source: https://github.com/getsentry/dotagents
- npm: https://www.npmjs.com/package/@sentry/dotagents