@asermax/pi-cc-plugins
v2.0.0
Published
Use Claude Code plugins (skills & agents) directly in Pi
Readme
pi-cc-plugins
Use Claude Code plugins (skills, agents, and MCP servers) directly in Pi.
This extension bridges Claude Code's plugin ecosystem into Pi. It reads source references from your settings, clones remote repos into a local cache, and exposes the skills, agents, and MCP configs found inside them so Pi loads them natively.
Install
pi install npm:@asermax/pi-cc-pluginsOr from git:
pi install git:[email protected]:asermax/pi-cc-plugins.gitSources
Resources can come from two kinds of sources: plugins (remote or local repos) and standalone .claude directories (global or per-project). Both are configured in your Pi settings.
Plugins
Add a ccPlugins array to your Pi settings (~/.pi/agent/settings.json for global, or .pi/settings.json for project-level):
{
"ccPlugins": [
// Clone a GitHub repo and use its skills/, agents/, and MCP configs
"github:pleaseai/claude-code-plugins",
// Clone a repo but use a specific subdirectory as the plugin root
"github:pleaseai/claude-code-plugins#subpath=plugins/vue",
// Full git URL
"git:github.com/user/custom-cc-plugin",
// Local path (great for development)
"local:~/my-plugins/dev-plugin"
]
}Source Formats
| Format | Example | Description |
|--------|---------|-------------|
| github:owner/repo | github:pleaseai/claude-code-plugins | Clones from GitHub |
| github:owner/repo#subpath=dir | github:foo/bar#subpath=plugins/vue | Clones from GitHub, uses subdirectory as plugin root |
| git:<url> | git:github.com/user/repo | Clones from any git URL |
| local:<path> | local:~/my-plugins/dev-plugin | Uses a local directory directly (no cloning) |
Expected Plugin Structure
Plugins follow Claude Code's standard layout:
my-plugin/
├── .claude-plugin/
│ └── plugin.json # manifest with "name" field
├── skills/
│ ├── code-reviewer/
│ │ └── SKILL.md
│ └── pdf-processor/
│ └── SKILL.md
├── agents/
│ └── security-scanner.md
└── mcp.json # optional MCP server configIf plugin.json declares custom paths, they are respected:
{
"name": "my-plugin",
"skills": "./custom-skills-dir",
"agents": "./custom-agents-dir",
"mcp": "./custom-mcp.json"
}Standalone .claude Directories
In addition to plugins, the extension can load resources from your global or project .claude directories. Enable them in settings:
// ~/.pi/agent/settings.json or .pi/settings.json
{
"ccClaudeGlobal": true, // load ~/.claude/skills/ and ~/.claude/agents/
"ccClaudeProject": true // load <project>/.claude/skills/ and <project>/.claude/agents/
}Both default to false (opt-in). This avoids conflicts with Pi's native skills setting if you're already pointing it at .claude/skills.
Directory Structure
~/.claude/skills/ # global (ccClaudeGlobal)
my-global-skill/
SKILL.md
~/.claude/agents/ # global (ccClaudeGlobal)
my-global-agent.md
<project>/.claude/skills/ # project (ccClaudeProject)
my-project-skill/
SKILL.md
<project>/.claude/agents/ # project (ccClaudeProject)
my-project-agent.mdSkills
Skills are SKILL.md files that teach Pi how to handle specific tasks. They are discovered automatically from all configured sources.
Discovery
- On startup, the extension reads your
ccPluginsand theccClaudeGlobal/ccClaudeProjectsettings - Remote plugins are shallow-cloned into
~/.cache/pi-cc-plugins/(if not already cached) - Each source is scanned for
skills/directories containingSKILL.mdfiles - Skill directories are copied into
~/.cache/pi-cc-plugins/skills/with normalized frontmatter - Cached skill paths are contributed to Pi via the
resources_discoverevent - Pi loads them as native skills — they appear in
/skillsand work like any other Pi skill
Frontmatter Sanitization
Claude Code SKILL.md files often use loose YAML (unquoted strings with colons, underscores in names) that Pi's stricter YAML parser rejects. The extension normalizes frontmatter during caching so skills load reliably.
Because of this, use ccClaudeGlobal/ccClaudeProject instead of Pi's native skills setting when you want to load skills from .claude/skills. Pi's native skills setting loads files as-is without sanitization:
{
// ❗ Use this (with sanitization):
"ccClaudeGlobal": true,
// ⚠️ Not this (no sanitization, may fail to parse):
"skills": ["~/.claude/skills"]
}Agents
Plugin agents and standalone .claude/agents are converted to pi-subagents format and made available as project-level agents.
Requirements
pi-subagents must be installed. If it's not in your Pi packages list, agent loading is skipped with a warning.
pi install npm:pi-subagentsDiscovery
- On
session_start, the extension checks thatpi-subagentsis installed - It scans each plugin's
agents/directory and enabled.claude/agents/directories for.mdfiles - Each agent is parsed from Claude Code format and converted to pi-subagents format
- Converted agents are cached in
~/.cache/pi-cc-plugins/agents/ - Symlinks are created in
{project}/.pi/agents/cc-plugins/pointing to the cached files - pi-subagents discovers them via its recursive
.pi/agents/scan (it follows symlinks) - On
session_shutdown, symlinks are cleaned up (reference-counted for concurrent sessions)
Format Conversion
Claude Code agents use YAML frontmatter. The converter maps fields to pi-subagents format:
| CC field | pi-subagents field | Notes |
|----------|--------------------|-------|
| name | name | Direct |
| — | package | Set to plugin name (namespacing) |
| description | description | Direct |
| model | — | Dropped — CC model names don't reliably match Pi identifiers |
| tools | — | Dropped — CC tool names don't reliably match Pi tool identifiers |
| skills | skills | Pass-through |
| — | systemPromptMode | Default append |
| — | inheritProjectContext | Default true |
| — | inheritSkills | Default true |
Example
---
name: security-scanner
description: Scans code for security vulnerabilities
model: sonnet
tools: read, grep, find
skills: security-review
---
You are a security scanner. Analyze the code for vulnerabilities...Using Agents
Once loaded, converted agents appear in pi-subagents:
subagent({ action: "list" })Plugin agents show up as {plugin-name}.{agent-name}. Standalone Claude agents use claude-global.{agent-name} or claude-project.{agent-name}.
Reference Counting
If multiple Pi sessions are open in the same project, agent symlinks are reference-counted. A .cc-plugins-refcount file in .pi/agents/cc-plugins/ tracks active sessions. Symlinks and the directory are only removed when the count reaches 0 on session_shutdown.
MCP Servers
Plugin MCP configs are registered with pi's built-in MCP support for the duration of the session. MCP configs are only loaded from plugins — standalone .claude directories are not scanned for MCP.
Requirements
Pi's built-in MCP support (the mcp built-in extension, enabled by default). pi-mcp-adapter must not be installed: it replaces the built-in support, and pi then connects no servers. Remove it if present:
pi uninstall npm:pi-mcp-adapterConfig Locations
For each plugin, the extension checks these files in order:
mcp.json.mcp.json- The path from
.claude-plugin/plugin.json'smcpfield, resolved relative to the plugin root
If multiple files define the same server name, later files in that order win before namespacing.
How It Works
- On
session_start, the extension scans plugin MCP configs after resolvingccPlugins - Only object-shaped
mcpServers/mcp-serversentries are imported (top-levelsettings,imports, and unknown fields are ignored) - Servers are registered in-session via
pi.registerMcpServer()— nothing is written to the project's.pi/mcp.json
Server names are namespaced as {plugin-name}__{server-name}. For example, a chrome-devtools server from my-plugin becomes my-plugin__chrome-devtools.
Registrations are session-scoped: they disappear when the session ends, so there is no stale state to clean up. A server with the same name in mcp.json takes precedence over the registered plugin server. Server definitions pi cannot validate (for example type: "sse") are skipped with a warning.
Migration from pi-mcp-adapter
Versions ≤ 1.6 wrote managed entries into {project}/.pi/mcp.json and tracked them in {project}/.pi/mcp.cc-plugins.json. On the next session_start, those managed entries are removed from .pi/mcp.json and the sidecar file is deleted. User-owned entries are preserved.
Cache
All cached data lives under ~/.cache/pi-cc-plugins/ (respects $XDG_CACHE_HOME):
| Path | Contents |
|------|----------|
| {owner}--{repo}/ | Cloned plugin repos (shallow clones) |
| skills/{namespace}/{hash}/{slug}/ | Materialized skills with normalized frontmatter |
| agents/{slug}/ | Converted agent files |
Plugins are cloned once — subsequent sessions reuse the cached clone.
Updating Cached Plugins
To pull the latest version of every cached remote plugin without wiping the cache manually, start Pi with the --cc-plugins-update flag:
pi --cc-plugins-updateThis runs git fetch + git reset --hard origin/HEAD on each cached remote plugin before loading. Local plugins are unaffected, and plugins that aren't cached yet are cloned as usual. To force a full re-clone instead, delete the plugin's directory from the cache.
Removing Plugins
Remove the entry from your ccPlugins array in settings. On the next session start, stale agent symlinks and managed MCP entries are cleaned up, and skills will no longer be discovered. The cached clone remains on disk until you delete it manually.
Development
# Run tests
npm test
# Watch tests
npm run test:watchRelease
This package uses semantic-release. Push conventional commits to main:
feat:→ minor bumpfix:→ patch bumpfeat!:orBREAKING CHANGE:in footer → major bump
No manual versioning or tagging needed — the CI handles it all.
