Skip to content

feat: agent abstraction & MCP config generation#2

Merged
gricha merged 4 commits intomainfrom
feat/agent-abstraction-mcp
Feb 14, 2026
Merged

feat: agent abstraction & MCP config generation#2
gricha merged 4 commits intomainfrom
feat/agent-abstraction-mcp

Conversation

@gricha
Copy link
Member

@gricha gricha commented Feb 13, 2026

Summary

  • Adds first-class agent support (agents = ["claude", "cursor"] in agents.toml) so dotagents knows which AI tools consume skills
  • Adds [[mcp]] declarations in agents.toml for universal MCP server config
  • During install and sync, generates tool-specific MCP config files (.mcp.json, .cursor/mcp.json, .codex/config.toml, .vscode/mcp.json, opencode.json) with each tool's expected format
  • Creates agent-specific skills symlinks automatically (e.g. .claude/skills/ → .agents/skills/)
  • init --agents claude,cursor scaffolds the config with agents pre-populated
  • Fully backward compatible — existing configs without agents/mcp fields still parse

Supported agents

ID Tool MCP Config File Format
claude Claude Code .mcp.json JSON
cursor Cursor .cursor/mcp.json JSON
codex Codex .codex/config.toml TOML (shared)
vscode VS Code Copilot .vscode/mcp.json JSON
opencode OpenCode opencode.json JSON (shared)

Example agents.toml

version = 1
agents = ["claude", "cursor"]

[[skills]]
name = "find-bugs"
source = "getsentry/skills"

[[mcp]]
name = "github"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
env = ["GITHUB_TOKEN"]

New files

  • src/agents/types.ts — interfaces
  • src/agents/registry.ts — agent registry with per-tool serializers
  • src/agents/mcp-writer.ts — config file generation (JSON/TOML, shared/dedicated)
  • src/agents/index.ts — re-exports

Test plan

  • Registry serializer tests for all 5 agents (stdio + HTTP) — 15 tests
  • MCP writer tests (write/verify/merge/idempotent/skip) — 15 tests
  • Schema tests for new fields (agents, mcp, backward compat) — 11 tests
  • Loader tests for agent ID validation — 2 tests
  • Init integration: --agents flag, symlink creation, unknown ID rejection — 3 tests
  • Install integration: agent symlinks + MCP config writing — 2 tests
  • Sync integration: MCP repair + agent symlink repair — 2 tests
  • pnpm check passes (lint + typecheck + 185 tests)

Introduce first-class agent support so dotagents can generate tool-specific
MCP config files and skills symlinks for Claude Code, Cursor, Codex,
VS Code Copilot, and OpenCode.

New `agents` and `[[mcp]]` fields in agents.toml let users declare which
AI tools they use and which MCP servers to configure. During install/sync,
dotagents translates universal MCP declarations into each tool's expected
format and writes the config files automatically.
mergeWrite was doing `existing[rootKey] = servers` which would wipe any
user-configured servers in shared config files (codex, opencode). Now
spreads existing servers first so user additions are preserved.

Adds regression test with a pre-populated opencode.json.
- Deduplicate serializeCodex (was copy-paste of serializeClaude, now alias)
- Extract toMcpDeclarations() helper to eliminate duplicate mapping in
  install.ts and sync.ts
- Fix early return in runInstall that skipped agent symlinks and MCP
  config generation when no skills were declared — agents + MCP should
  work independently of skills
- Add regression test for MCP-only install (no skills)
Agents like claude and opencode share `.claude` as their
skillsParentDir. Track processed dirs in a Set to avoid duplicate
symlink operations and inflated repair counts.

Also extract envRecord results into locals to avoid redundant
double invocations in serializers.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

if (s.url) {
return [s.name, { type: "sse", url: s.url, ...(s.headers && { headers: s.headers }) }];
}
const env = envRecord(s.env, (k) => `\${input:${k}}`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VS Code env vars use wrong substitution syntax

High Severity

The VS Code serializer generates ${input:KEY} references for environment variables, but this pattern requires a corresponding inputs array in the mcp.json file that is never generated. The freshWrite function only outputs { "servers": {...} } with no inputs section, and since VS Code's config is shared: false, the file is overwritten entirely on each run. VS Code cannot resolve ${input:...} references without the inputs definitions, so MCP servers with env vars will fail to start. The intent here is to reference system environment variables, for which VS Code uses ${env:KEY} syntax (no inputs section needed).

Fix in Cursor Fix in Web

@gricha gricha merged commit d58a975 into main Feb 14, 2026
5 checks passed
@gricha gricha deleted the feat/agent-abstraction-mcp branch February 14, 2026 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant