-
Notifications
You must be signed in to change notification settings - Fork 22
feat: add support for claude code as an MCP client #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,66 @@ | ||||||||||||||||||||||||||||||
| import { DefaultMCPClient } from '../MCPClient'; | ||||||||||||||||||||||||||||||
| import { DefaultMCPClientConfig, getDefaultServerConfig } from '../defaults'; | ||||||||||||||||||||||||||||||
| import { z } from 'zod'; | ||||||||||||||||||||||||||||||
| import { execSync } from 'child_process'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export const ClaudeCodeMCPConfig = DefaultMCPClientConfig; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export type ClaudeCodeMCPConfig = z.infer<typeof DefaultMCPClientConfig>; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export class ClaudeCodeMCPClient extends DefaultMCPClient { | ||||||||||||||||||||||||||||||
| name = 'Claude Code'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| constructor() { | ||||||||||||||||||||||||||||||
| super(); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| isClientSupported(): Promise<boolean> { | ||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||
| execSync('claude --version', { stdio: 'ignore' }); | ||||||||||||||||||||||||||||||
| return Promise.resolve(true); | ||||||||||||||||||||||||||||||
| } catch { | ||||||||||||||||||||||||||||||
| return Promise.resolve(false); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| isServerInstalled(): Promise<boolean> { | ||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||
| // check if posthog in output | ||||||||||||||||||||||||||||||
| const output = execSync('claude mcp list', { | ||||||||||||||||||||||||||||||
| stdio: 'pipe', | ||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (output.toString().includes('posthog')) { | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
| if (output.toString().includes('posthog')) { | |
| if (output.toString().includes(this.serverName)) { |
Copilot
AI
Aug 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getConfigPath method throws 'Not implemented' but this method is part of the MCPClient interface. Either implement this method or mark it as optional in the interface if it's not needed for Claude Code.
| throw new Error('Not implemented'); | |
| // Assuming Claude Code stores config at ~/.claude/config.json | |
| const configPath = `${process.env.HOME || process.env.USERPROFILE}/.claude/config.json`; | |
| return Promise.resolve(configPath); |
Copilot
AI
Aug 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard-coding 'posthog' as the server name in the command makes this client specific to PostHog servers. Consider parameterizing the server name to make this more generic.
| const command = `claude mcp add-json posthog -s user '${JSON.stringify( | |
| const command = `claude mcp add-json ${this.serverName} -s user '${JSON.stringify( |
Copilot
AI
Aug 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using execSync with a command that includes JSON.stringify(config) could be vulnerable to command injection if the config contains malicious content. Consider using safer command execution methods or proper escaping.
| // Use argument array to avoid command injection | |
| execSync( | |
| 'claude', | |
| [ | |
| 'mcp', | |
| 'add-json', | |
| 'posthog', | |
| '-s', | |
| 'user', | |
| JSON.stringify(config), | |
| ], | |
| { stdio: 'ignore', shell: false } | |
| ); |
Copilot
AI
Aug 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard-coding 'posthog' as the server name in the remove command creates the same maintainability issue as in addServer. Consider making the server name configurable.
| const command = `claude mcp remove --scope user posthog`; | |
| const command = `claude mcp remove --scope user ${this.serverName}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the default server type from 'streamable-http' to 'sse' is a breaking change that affects all existing MCP clients. This should be documented and may require version migration logic.