feat(mcp): add doctor command
Add the MCP doctor subcommand with text and JSON output, config-only mode, and scope filtering so users can diagnose MCP issues from the CLI. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
19
src/commands/mcp/doctorCommand.test.ts
Normal file
19
src/commands/mcp/doctorCommand.test.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import test from 'node:test'
|
||||||
|
|
||||||
|
import { Command } from '@commander-js/extra-typings'
|
||||||
|
|
||||||
|
import { registerMcpDoctorCommand } from './doctorCommand.js'
|
||||||
|
|
||||||
|
test('registerMcpDoctorCommand adds the doctor subcommand with expected options', () => {
|
||||||
|
const mcp = new Command('mcp')
|
||||||
|
|
||||||
|
registerMcpDoctorCommand(mcp)
|
||||||
|
|
||||||
|
const doctor = mcp.commands.find(command => command.name() === 'doctor')
|
||||||
|
assert.ok(doctor)
|
||||||
|
assert.equal(doctor?.usage(), '[options] [name]')
|
||||||
|
|
||||||
|
const optionFlags = doctor?.options.map(option => option.long)
|
||||||
|
assert.deepEqual(optionFlags, ['--scope', '--config-only', '--json'])
|
||||||
|
})
|
||||||
25
src/commands/mcp/doctorCommand.ts
Normal file
25
src/commands/mcp/doctorCommand.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* MCP doctor CLI subcommand.
|
||||||
|
*/
|
||||||
|
import { type Command } from '@commander-js/extra-typings'
|
||||||
|
|
||||||
|
export function registerMcpDoctorCommand(mcp: Command): void {
|
||||||
|
mcp
|
||||||
|
.command('doctor [name]')
|
||||||
|
.description(
|
||||||
|
'Diagnose MCP configuration, precedence, disabled/pending state, and connection health. ' +
|
||||||
|
'Note: unless --config-only is used, stdio servers may be spawned and remote servers may be contacted. ' +
|
||||||
|
'Only use this command in directories you trust.',
|
||||||
|
)
|
||||||
|
.option('-s, --scope <scope>', 'Restrict config analysis to a specific scope (local, project, user, or enterprise)')
|
||||||
|
.option('--config-only', 'Skip live connection checks and only analyze configuration state')
|
||||||
|
.option('--json', 'Output the diagnostics report as JSON')
|
||||||
|
.action(async (name: string | undefined, options: {
|
||||||
|
scope?: string
|
||||||
|
configOnly?: boolean
|
||||||
|
json?: boolean
|
||||||
|
}) => {
|
||||||
|
const { mcpDoctorHandler } = await import('../../cli/handlers/mcp.js')
|
||||||
|
await mcpDoctorHandler(name, options)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -139,6 +139,7 @@ import { validateUuid } from './utils/uuid.js';
|
|||||||
// Plugin startup checks are now handled non-blockingly in REPL.tsx
|
// Plugin startup checks are now handled non-blockingly in REPL.tsx
|
||||||
|
|
||||||
import { registerMcpAddCommand } from 'src/commands/mcp/addCommand.js';
|
import { registerMcpAddCommand } from 'src/commands/mcp/addCommand.js';
|
||||||
|
import { registerMcpDoctorCommand } from 'src/commands/mcp/doctorCommand.js';
|
||||||
import { registerMcpXaaIdpCommand } from 'src/commands/mcp/xaaIdpCommand.js';
|
import { registerMcpXaaIdpCommand } from 'src/commands/mcp/xaaIdpCommand.js';
|
||||||
import { logPermissionContextForAnts } from 'src/services/internalLogging.js';
|
import { logPermissionContextForAnts } from 'src/services/internalLogging.js';
|
||||||
import { fetchClaudeAIMcpConfigsIfEligible } from 'src/services/mcp/claudeai.js';
|
import { fetchClaudeAIMcpConfigsIfEligible } from 'src/services/mcp/claudeai.js';
|
||||||
@@ -3887,6 +3888,7 @@ async function run(): Promise<CommanderCommand> {
|
|||||||
|
|
||||||
// Register the mcp add subcommand (extracted for testability)
|
// Register the mcp add subcommand (extracted for testability)
|
||||||
registerMcpAddCommand(mcp);
|
registerMcpAddCommand(mcp);
|
||||||
|
registerMcpDoctorCommand(mcp);
|
||||||
if (isXaaEnabled()) {
|
if (isXaaEnabled()) {
|
||||||
registerMcpXaaIdpCommand(mcp);
|
registerMcpXaaIdpCommand(mcp);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user