agentleFS
Sign inSign up

dotagents

getsentry/dotagents/docs/public/llms.txt

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> These unqualified commands create and use ~/.agents/agents.toml, even when run inside a repository. To manage repository-local state, make project intent explicit: The…

llms.txt239 starsChanged 7 months ago
  • Reads credentials
  • Installs packages
# 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.

| 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

Discussion

Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.

Posts are public.Sign in to post

No one has posted yet. Be the first.