Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/cli/src/__tests__/install-file-locations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ Follow TypeScript best practices.
return tarball;
}

it('installs MCP server (subtype: server) to .codex/config.toml with --editor codex', async () => {
it('installs MCP server (subtype: server) to .codex/config.toml with --as codex (via editor option)', async () => {
const mockPackage = {
id: '@test/mcp-server',
name: '@test/mcp-server',
Expand All @@ -893,7 +893,7 @@ Follow TypeScript best practices.
expect(codexConfig).toContain('command = "npx"');
});

it('installs MCP tool (subtype: tool) to .codex/config.toml with --editor codex', async () => {
it('installs MCP tool (subtype: tool) to .codex/config.toml with --as codex (via editor option)', async () => {
const mockPackage = {
id: '@test/mcp-tool',
name: '@test/mcp-tool',
Expand Down
17 changes: 12 additions & 5 deletions packages/cli/src/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1942,20 +1942,27 @@ export function createInstallCommand(): Command {
.option('--eager', 'Force skill/agent to always activate (not on-demand)')
.option('--lazy', 'Use default on-demand activation (overrides package eager setting)')
.option('--global', 'Install MCP servers to global config (e.g., ~/.claude/settings.json, ~/.codex/config.toml, ~/.cursor/mcp.json, ~/.kiro/settings/mcp.json)')
.option('--editor <editor>', 'Target editor for MCP server installation (claude, codex, cursor, windsurf, vscode, gemini, opencode, kiro, trae, amp, zed)', 'claude')
.option('--editor <editor>', '[Deprecated: use --as] Target editor for MCP server installation')
.action(async (packageSpec: string | undefined, options: { version?: string; as?: string; format?: string; subtype?: string; hookMapping?: string; frozenLockfile?: boolean; yes?: boolean; location?: string; noAppend?: boolean; manifestFile?: string; eager?: boolean; lazy?: boolean; global?: boolean; editor?: string }) => {
// Support both --as and --format (format is alias for as)
const convertTo = (options.format || options.as) as Format | undefined;
const rawAs = (options.format || options.as) as string | undefined;
const validFormats = FORMATS;

// If --as value is an MCP editor but not a valid format, treat it as editor-only
const isMCPEditorOnly = rawAs && !validFormats.includes(rawAs as Format) && MCP_EDITORS.includes(rawAs as MCPEditor);
const convertTo = isMCPEditorOnly ? undefined : rawAs as Format | undefined;

if (convertTo && !validFormats.includes(convertTo)) {
throw new CLIError(`❌ Format must be one of: ${validFormats.join(', ')}\n\nπŸ’‘ Examples:\n prpm install my-package --as cursor # Convert to Cursor format\n prpm install my-package --format claude # Convert to Claude format\n prpm install my-package --format claude.md # Convert to Claude.md format\n prpm install my-package --format kiro # Convert to Kiro format\n prpm install my-package --format agents.md # Convert to Agents.md format\n prpm install my-package --format gemini.md # Convert to Gemini format\n prpm install my-package # Install in native format`, 1);
throw new CLIError(`❌ Format must be one of: ${validFormats.join(', ')}\n\nπŸ’‘ Examples:\n prpm install my-package --as cursor # Convert to Cursor format\n prpm install my-package --format claude # Convert to Claude format\n prpm install my-package --format claude.md # Convert to Claude.md format\n prpm install my-package --format kiro # Convert to Kiro format\n prpm install my-package --format agents.md # Convert to Agents.md format\n prpm install my-package --format gemini.md # Convert to Gemini format\n prpm install my-mcp-server --as codex # Install MCP server to Codex\n prpm install my-package # Install in native format`, 1);
}

// Resolve MCP editor: --editor (deprecated) takes precedence, then --as
const mcpEditor = (options.editor || rawAs) as MCPEditor | undefined;

// Validate editor for MCP server installation
if (options.editor && !MCP_EDITORS.includes(options.editor as MCPEditor)) {
throw new CLIError(
`Invalid MCP editor: ${options.editor}\n\nSupported editors: ${MCP_EDITORS.join(', ')}\n\nπŸ’‘ Examples:\n prpm install my-mcp-server --editor claude # Install to .mcp.json\n prpm install my-mcp-server --editor codex # Install to .codex/config.toml\n prpm install my-mcp-server --editor cursor # Install to .cursor/mcp.json\n prpm install my-mcp-server --editor windsurf # Install to ~/.codeium/windsurf/mcp_config.json\n prpm install my-mcp-server --editor vscode # Install to .vscode/mcp.json\n prpm install my-mcp-server --editor gemini # Install to .gemini/settings.json\n prpm install my-mcp-server --editor opencode # Install to opencode.json\n prpm install my-mcp-server --editor kiro # Install to .kiro/settings/mcp.json\n prpm install my-mcp-server --editor trae # Install to .trae/mcp.json\n prpm install my-mcp-server --editor amp # Install to .amp/settings.json\n prpm install my-mcp-server --editor zed # Install to ~/.config/zed/settings.json`
`Invalid MCP editor: ${options.editor}\n\nSupported editors: ${MCP_EDITORS.join(', ')}\n\nπŸ’‘ Examples:\n prpm install my-mcp-server --as claude # Install to .mcp.json\n prpm install my-mcp-server --as codex # Install to .codex/config.toml\n prpm install my-mcp-server --as cursor # Install to .cursor/mcp.json\n prpm install my-mcp-server --as windsurf # Install to ~/.codeium/windsurf/mcp_config.json\n prpm install my-mcp-server --as vscode # Install to .vscode/mcp.json\n prpm install my-mcp-server --as gemini # Install to .gemini/settings.json\n prpm install my-mcp-server --as opencode # Install to opencode.json\n prpm install my-mcp-server --as kiro # Install to .kiro/settings/mcp.json\n prpm install my-mcp-server --as trae # Install to .trae/mcp.json\n prpm install my-mcp-server --as amp # Install to .amp/settings.json\n prpm install my-mcp-server --as zed # Install to ~/.config/zed/settings.json`
);
}

Expand Down Expand Up @@ -1993,7 +2000,7 @@ export function createInstallCommand(): Command {
hookMapping: options.hookMapping as HookMappingStrategy | undefined,
eager,
global: options.global,
editor: options.editor as MCPEditor | undefined,
editor: mcpEditor as MCPEditor | undefined,
});
});

Expand Down
10 changes: 9 additions & 1 deletion public-documentation/cli/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,11 @@ prpm install <package-name> [additional-packages...] [options]

**Options:**
- `--version <version>` - Install a specific version
- `--as <format>` - Convert and install in specific format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, canonical)
- `--as <format>` - Convert and install in specific format (cursor, claude, continue, windsurf, copilot, kiro, agents.md, canonical). For MCP servers, specifies the target editor (claude, codex, cursor, windsurf, vscode, gemini, opencode, kiro, trae, amp, zed)
- `--format <format>` - Alias for `--as`
- `--subtype <subtype>` - Specify subtype when converting (skill, agent, rule, etc.)
- `--location <path>` - Custom installation location (Cursor and agents.md only)
- `--global` - Install MCP servers to global config (e.g., `~/.claude/settings.json`)
- `--frozen-lockfile` - Fail if lock file needs to be updated (for CI)
- `--eager` - Force skill/agent to always activate at session start (not on-demand)
- `--lazy` - Use default on-demand activation (overrides package eager setting)
Expand Down Expand Up @@ -356,6 +357,13 @@ prpm install @username/code-style --as agents.md --eager

# Install with lazy activation (on-demand, default)
prpm install @username/debugging-helper --as agents.md --lazy

# Install MCP server for a specific editor
prpm install @org/my-mcp-server --as cursor
prpm install @org/my-mcp-server --as codex

# Install MCP server globally
prpm install @org/my-mcp-server --as vscode --global
```

**What happens during installation:**
Expand Down
6 changes: 3 additions & 3 deletions public-documentation/guides/mcp-servers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ prpm install @org/my-mcp-server
prpm install @org/my-mcp-server --global

# Install for a specific editor
prpm install @org/my-mcp-server --editor cursor
prpm install @org/my-mcp-server --editor vscode --global
prpm install @org/my-mcp-server --as cursor
prpm install @org/my-mcp-server --as vscode --global
Comment on lines +142 to +143
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: In the MCP servers guide, the "Install for a specific editor" examples now use --as to choose the editor, but the CLI still uses the --editor option for MCP editor selection and --as causes conversion of mcp packages, so these commands will not behave as documented. [possible bug]

Severity Level: Major ⚠️
- ❌ MCP installs using documented --as example fail with CLIError.
- ⚠️ Users following guide cannot install MCP servers per docs.
- ⚠️ Confusion between MCP editor selection and format conversion.
Suggested change
prpm install @org/my-mcp-server --as cursor
prpm install @org/my-mcp-server --as vscode --global
prpm install @org/my-mcp-server --editor cursor
prpm install @org/my-mcp-server --editor vscode --global
Steps of Reproduction βœ…
1. Open the MCP servers guide at `public-documentation/guides/mcp-servers.mdx:136-143`
(Final File State) and follow the documented example under "Install for a specific
editor", which tells you to run `prpm install @org/my-mcp-server --as cursor`.

2. Run that command via the CLI, which is wired to the `install` subcommand created by
`createInstallCommand()` in `packages/cli/src/commands/install.ts:1926-2000`. The action
handler computes `convertTo = (options.format || options.as)` and passes both `as:
convertTo` and `editor: mcpEditor` into `handleInstall()` at lines 1946-1957 and
1987-2000.

3. Inside `handleInstall()` (same file, lines 264-285 and 483-509), for a typical MCP
server package (`pkg.format === 'mcp'`, subtype `server` or `tool`), `isMCPServerPackage`
is true, `options.as` is `'cursor'`, and `format` is set to `'cursor'`. Later, the
conversion block at lines 528-540 sees `options.as` defined and `format !== pkg.format`
(`'cursor'` vs `'mcp'`), so it enters the conversion path.

4. In the conversion path (lines 653-690), `sourceFormat` becomes `'mcp'`. The switch
statement lacks a `case 'mcp'`, so it falls through to the `default` branch at lines
688-690 and throws `new CLIError(\`Unsupported source format for conversion:
${pkg.format}\`)`, causing the install command to fail instead of installing the MCP
server, contradicting the documentation's implied behavior for `--as`.
Prompt for AI Agent πŸ€–
This is a comment left during a code review.

**Path:** public-documentation/guides/mcp-servers.mdx
**Line:** 142:143
**Comment:**
	*Possible Bug: In the MCP servers guide, the "Install for a specific editor" examples now use `--as` to choose the editor, but the CLI still uses the `--editor` option for MCP editor selection and `--as` causes conversion of `mcp` packages, so these commands will not behave as documented.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
πŸ‘ | πŸ‘Ž

```

## MCP Servers + PRPM Collections
Expand Down Expand Up @@ -185,7 +185,7 @@ If you're looking for existing MCP servers to use (not publish), these catalogs
</Accordion>

<Accordion title="Which editors are supported?">
PRPM can install MCP server configs for Claude Code, Cursor, VS Code, Codex, Windsurf, Gemini, Kiro, OpenCode, Trae, Amp, and Zed. Use the `--editor` flag to target a specific editor.
PRPM can install MCP server configs for Claude Code, Cursor, VS Code, Codex, Windsurf, Gemini, Kiro, OpenCode, Trae, Amp, and Zed. Use the `--as` flag to target a specific editor (e.g., `--as cursor`).
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The FAQ answer now tells users to "Use the --as flag to target a specific editor", but for MCP servers the CLI still relies on the --editor option and using only --as with mcp packages will attempt an unsupported format conversion and fail, so this guidance is incorrect. [possible bug]

Severity Level: Major ⚠️
- ❌ FAQ directs users to failing MCP install command.
- ⚠️ MCP server users face errors despite following documentation.
- ⚠️ Inconsistent guidance between CLI help and FAQ text.
Suggested change
PRPM can install MCP server configs for Claude Code, Cursor, VS Code, Codex, Windsurf, Gemini, Kiro, OpenCode, Trae, Amp, and Zed. Use the `--as` flag to target a specific editor (e.g., `--as cursor`).
PRPM can install MCP server configs for Claude Code, Cursor, VS Code, Codex, Windsurf, Gemini, Kiro, OpenCode, Trae, Amp, and Zed. Use the `--editor` flag to target a specific editor (e.g., `--editor cursor`).
Steps of Reproduction βœ…
1. Read the FAQ in `public-documentation/guides/mcp-servers.mdx:187-189` (Final File
State). The "Which editors are supported?" answer explicitly instructs: "Use the `--as`
flag to target a specific editor (e.g., `--as cursor`)."

2. Following this guidance, run an MCP server install such as `prpm install
@org/my-mcp-server --as cursor`. This invokes the `install` command defined in
`packages/cli/src/commands/install.ts:1926-2000`, where the action handler derives
`convertTo = (options.format || options.as)` and passes `as: convertTo` and `editor:
mcpEditor` into `handleInstall()` (lines 1946-1957 and 1987-2000).

3. In `handleInstall()` (same file, lines 483-509), for an MCP package (`pkg.format ===
'mcp'`), `isMCPServerPackage` is true, `options.as` is `'cursor'`, and `format` is set to
`'cursor'`. The conversion block at lines 528-540 then sees `options.as` set and `format
!== pkg.format` and proceeds to perform format conversion.

4. The conversion logic (lines 653-690) computes `sourceFormat = 'mcp'`, but the switch
has no branch for `'mcp'`, so it hits the `default` clause at 688-690, throwing
`CLIError("Unsupported source format for conversion: mcp")`. As a result, using `--as`
exactly as the FAQ recommends causes MCP installs to fail, while using `--editor` (which
avoids setting `options.as`) allows the special MCP server path at lines 939-1001 to run
successfully.
Prompt for AI Agent πŸ€–
This is a comment left during a code review.

**Path:** public-documentation/guides/mcp-servers.mdx
**Line:** 188:188
**Comment:**
	*Possible Bug: The FAQ answer now tells users to "Use the `--as` flag to target a specific editor", but for MCP servers the CLI still relies on the `--editor` option and using only `--as` with `mcp` packages will attempt an unsupported format conversion and fail, so this guidance is incorrect.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
πŸ‘ | πŸ‘Ž

</Accordion>

<Accordion title="Do I need MCP servers to use PRPM?">
Expand Down
Loading