Install agent skills and MCPs with one API.
Works with Claude Code, Cursor, Codex, OpenCode, and 40+ other coding agents. Writes to each one's native config (skills directory, MCP JSON/JSONC/YAML/TOML, AGENTS.md) so your CLI or build script doesn't have to learn ten different formats. A small agent-install CLI is also included for one-off use.
Every agent has its own format for skills, MCP, and AGENTS.md. agent-install writes to all of them so you don't ship the 15th. (xkcd 927)
As a library:
npm install agent-installOr use the CLI directly without installing:
npx agent-install@latest --helpnpx agent-install@latest skill add owner/repo -a cursor
npx agent-install@latest mcp add https://mcp.context7.com/mcp -a cursor
npx agent-install@latest agents-md set-section "Testing" --body "Run pnpm test"Same three actions from the Node API:
import { skill, mcp, agentsMd } from "agent-install";
await skill.add({ source: "owner/repo", agents: ["cursor"] });
mcp.add({ source: "https://mcp.context7.com/mcp", agents: ["cursor"], name: "context7" });
agentsMd.setSection({ heading: "Testing", body: "Run pnpm test" });The Node API is namespaced by surface (skill, mcp, agentsMd) using verbs that match the CLI (add, list, remove, setSection, removeSection, read).
A thin wrapper around the Node API for one-off installs, scripts, and CI.
npx agent-install@latest skill add ./skills/react-grab
npx agent-install@latest skill add owner/repo
npx agent-install@latest skill add https://github.com/owner/repo/tree/main/skills/foo
npx agent-install@latest skill init [name] # create a new SKILL.md
npx agent-install@latest skill list # list installed skills
npx agent-install@latest skill remove [skills] # remove installed skillsnpx agent-install@latest mcp add https://mcp.context7.com/mcp -a cursor
npx agent-install@latest mcp add @modelcontextprotocol/server-postgres -a claude-code --env "DATABASE_URL=..."
npx agent-install@latest mcp list # list installed MCP servers
npx agent-install@latest mcp remove <name> # remove by server namenpx agent-install@latest agents-md init
npx agent-install@latest agents-md set-section "Testing" --body "Run pnpm test"
npx agent-install@latest agents-md remove-section "Testing"
npx agent-install@latest agents-md symlink-claude
npx agent-install@latest agents-md readYou can also import each surface from its own subpath:
import * as skill from "agent-install/skill";
import * as mcp from "agent-install/mcp";
import * as agentsMd from "agent-install/agents-md";A skill is a SKILL.md file that an agent picks up to trigger behavior. skill.add parses a source (local path, GitHub repo, or URL), fetches it, and installs every discovered SKILL.md into each selected agent.
import { skill } from "agent-install";
const result = await skill.add({
source: "./skills/react-grab",
agents: ["claude-code", "cursor"],
});
result.installed; // InstalledSkillRecord[]
result.failed; // FailedSkillRecord[]Other useful exports:
skill.discover(dir); // find SKILL.md files in a directory
skill.parseSource(spec); // parse a source string into a ParsedSkillSource
skill.detectInstalledSkillAgents();
skill.installSkillForAgent(skill, agent, opts);mcp.add parses a source (remote URL, npm package, or raw command), builds an McpServerConfig, and writes it into each selected agent's native config file (JSON, JSONC, YAML, or TOML). JSONC writes preserve existing comments.
import { mcp } from "agent-install";
mcp.add({
source: "https://mcp.context7.com/mcp",
agents: ["cursor", "claude-code"],
name: "context7",
});
mcp.add({
source: "@modelcontextprotocol/server-postgres",
agents: ["claude-code"],
name: "postgres",
env: { DATABASE_URL: process.env.DATABASE_URL ?? "" },
});
mcp.list({ agents: ["cursor"] });
mcp.remove({ name: "context7", agents: ["cursor"] });Other useful exports:
mcp.parseSource(spec);
mcp.buildMcpServerConfig(parsed, opts);
mcp.installMcpServerForAgent(name, config, agent, opts);agentsMd reads, upserts, and removes sections in AGENTS.md and its per-agent variants (CLAUDE.md, GEMINI.md, .cursor/rules/, .windsurfrules, etc.) without losing surrounding content.
import { agentsMd } from "agent-install";
agentsMd.setSection({
heading: "React Grab",
body: "Run `npx grab@latest` to set up React Grab.",
placement: "append",
});
agentsMd.removeSection({ heading: "Old section" });
await agentsMd.symlinkClaude();Other useful exports:
agentsMd.read({ agent: "cursor" });
agentsMd.write({ content: "..." });
agentsMd.parseSections(content);
agentsMd.findSection(sections, "Testing");
agentsMd.resolveAgentsMdFilePath({ agent: "claude-code" });| Import | Surface |
|---|---|
agent-install |
All three surfaces as skill, mcp, agentsMd namespaces (+ flat skill exports) |
agent-install/skill |
Skill surface only |
agent-install/mcp |
MCP surface only |
agent-install/agents-md |
AGENTS.md surface (kebab-case path, import as agentsMd) |
Every short-name verb has a long-form alias if you prefer it: skill.add is skill.installSkillsFromSource, mcp.add is mcp.installMcpServer, agentsMd.setSection is agentsMd.upsertAgentsMdSection, and so on.
skill.add accepts a wide range of sources. Anything that resolves to a git URL is shallow-cloned into a temp directory, scanned for SKILL.md files, and installed.
# Local
./skills/my-skill # local path
/abs/path/to/skill # absolute path
# GitHub
owner/repo # shorthand
owner/repo/path/to/skill # with subpath
owner/repo@skill-name # with skill filter
owner/repo#branch # with git ref
github:owner/repo # explicit prefix
https://github.com/owner/repo # full URL
https://github.com/owner/repo/tree/main/skills/foo
# GitLab
gitlab:owner/repo # shorthand
gitlab:owner/repo/path/to/skill # with subpath
https://gitlab.com/owner/repo # full URL
https://gitlab.com/owner/repo/-/tree/main/skills/foo
# SSH (preserves SSH URL for clone, useful for private repos)
git@github.com:owner/repo.git
git@gitlab.com:owner/repo.git
git@github.com:owner/repo.git#main@my-skill # with ref + skill filter
# Any other git remote (Bitbucket, self-hosted, etc.)
https://git.example.com/owner/repo.git
git@bitbucket.org:owner/repo.git
# Direct SKILL.md URL
https://example.com/path/SKILL.md
https://mcp.context7.com/mcp # remote HTTP
https://mcp.example.com/sse (+ transport: "sse")
@modelcontextprotocol/server-postgres # npm package (wrapped in npx -y)
"node /path/to/server.js --port 3000" # raw command
| Surface | Agents |
|---|---|
| Skills | Claude Code, Cursor, Codex, OpenCode, Gemini CLI, GitHub Copilot, Goose, Windsurf, Roo, Cline, Kilo, universal |
| MCP | Claude Code, Claude Desktop, Cursor, Codex, Cline (ext + CLI), VS Code, GitHub Copilot CLI, Gemini CLI, Goose, OpenCode, Zed, Antigravity, MCPorter |
| AGENTS.md | Universal, Claude Code (CLAUDE.md), Gemini CLI (GEMINI.md), Cursor (.cursor/rules), Windsurf (.windsurfrules), Codex, OpenCode, Aider |
pnpm install
pnpm build
pnpm test
pnpm lint
pnpm typecheckSingle package at packages/agent-install.
Found a bug? Open an issue on the issue tracker. Pull requests welcome.
agent-install is MIT-licensed open-source software.