Compare commits

...

1 Commits

Author SHA1 Message Date
Max Paulus 🥪 855a75c711 add basic mcp support to cli
- able to set custom mcp path with -c flag (mCp)
- defaults to ClineConfig/cline_mcp_settings.json
- TODO: add an mcp subcommand to cline for more fine grain mcp
operations
2025-12-05 15:41:56 -08:00
5 changed files with 70 additions and 13 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
cline cli able to use mcp servers
+18 -5
View File
@@ -408,15 +408,15 @@ func startClineCore(corePort, hostPort int) (*exec.Cmd, error) {
// This handles the case where we're running from cli/bin/cline
devClineCorePath := path.Join(binDir, "..", "..", "dist-standalone", "cline-core.js")
devInstallDir := path.Join(binDir, "..", "..", "dist-standalone")
if Config.Verbose {
fmt.Printf("Primary location not found, trying development path: %s\n", devClineCorePath)
}
if _, err := os.Stat(devClineCorePath); os.IsNotExist(err) {
return nil, fmt.Errorf("cline-core.js not found at '%s' or '%s'. Please ensure you're running from the correct location or reinstall with 'npm install -g cline'", clineCorePath, devClineCorePath)
}
finalClineCorePath = devClineCorePath
finalInstallDir = devInstallDir
if Config.Verbose {
@@ -475,15 +475,28 @@ func startClineCore(corePort, hostPort int) (*exec.Cmd, error) {
realNodeModules := path.Join(finalInstallDir, "node_modules")
fakeNodeModules := path.Join(finalInstallDir, "fake_node_modules")
nodePath := fmt.Sprintf("%s%c%s", realNodeModules, os.PathListSeparator, fakeNodeModules)
env = append(env,
fmt.Sprintf("NODE_PATH=%s", nodePath),
"GRPC_TRACE=all",
"GRPC_VERBOSITY=DEBUG",
"NODE_ENV=development",
)
mcpConfigPath := filepath.Join(Config.ConfigPath, "data", "settings", common.DEFAULT_CLINE_MCP_SETTINGS_FILE)
if _, err := os.Stat(mcpConfigPath); os.IsNotExist(err) {
if Config.Verbose {
fmt.Printf("MCP settings file not found at: %s. Continuing with no MCP config...\n", mcpConfigPath)
}
} else {
if Config.Verbose {
fmt.Printf("MCP settings file found at: %s. Setting MCP_SETTINGS_PATH env variable...\n", mcpConfigPath)
}
env = append(env, fmt.Sprintf("MCP_SETTINGS_PATH=%s", mcpConfigPath))
}
cmd.Env = env
if Config.Verbose {
fmt.Printf("NODE_PATH set to: %s\n", nodePath)
}
+34 -7
View File
@@ -975,14 +975,41 @@ func (m *Manager) processStateUpdate(stateUpdate *cline.State, coordinator *Stre
coordinator.MarkProcessedInCurrentTurn(msgKey)
}
case msg.Say == string(types.SayTypeMcpServerRequestStarted):
msgKey := fmt.Sprintf("%d", msg.Timestamp)
if !coordinator.IsProcessedInCurrentTurn(msgKey) {
fmt.Println()
m.displayMessage(msg, false, false, i)
case msg.Say == string(types.SayTypeMcpServerRequestStarted):
msgKey := fmt.Sprintf("%d", msg.Timestamp)
if !coordinator.IsProcessedInCurrentTurn(msgKey) {
fmt.Println()
m.displayMessage(msg, false, false, i)
coordinator.MarkProcessedInCurrentTurn(msgKey)
}
coordinator.MarkProcessedInCurrentTurn(msgKey)
}
case msg.Say == string(types.SayTypeMcpServerResponse):
msgKey := fmt.Sprintf("%d", msg.Timestamp)
if !coordinator.IsProcessedInCurrentTurn(msgKey) {
fmt.Println()
m.displayMessage(msg, false, false, i)
coordinator.MarkProcessedInCurrentTurn(msgKey)
}
case msg.Say == string(types.SayTypeMcpNotification):
msgKey := fmt.Sprintf("%d", msg.Timestamp)
if !coordinator.IsProcessedInCurrentTurn(msgKey) {
fmt.Println()
m.displayMessage(msg, false, false, i)
coordinator.MarkProcessedInCurrentTurn(msgKey)
}
case msg.Say == string(types.SayTypeUseMcpServer):
msgKey := fmt.Sprintf("%d", msg.Timestamp)
if !coordinator.IsProcessedInCurrentTurn(msgKey) {
fmt.Println()
m.displayMessage(msg, false, false, i)
coordinator.MarkProcessedInCurrentTurn(msgKey)
}
case msg.Say == string(types.SayTypeCheckpointCreated):
msgKey := fmt.Sprintf("%d", msg.Timestamp)
+2
View File
@@ -4,3 +4,5 @@ package common
const SETTINGS_SUBFOLDER = "data"
const DEFAULT_CLINE_CORE_PORT = 50052
const DEFAULT_CLINE_MCP_SETTINGS_FILE = "cline_mcp_settings.json"
+11 -1
View File
@@ -162,9 +162,19 @@ export class Controller {
this.startRemoteConfigTimer()
})
// Create McpHub with custom settings directory if MCP_SETTINGS_PATH is set (CLI mode)
const mcpSettingsPathOverride = process.env.MCP_SETTINGS_PATH
const getSettingsDirectory = mcpSettingsPathOverride
? async () => path.dirname(mcpSettingsPathOverride)
: () => ensureSettingsDirectoryExists()
if (mcpSettingsPathOverride) {
console.log(`[Controller] Using custom MCP settings path: ${mcpSettingsPathOverride}`)
}
this.mcpHub = new McpHub(
() => ensureMcpServersDirectoryExists(),
() => ensureSettingsDirectoryExists(),
getSettingsDirectory,
ExtensionRegistryInfo.version,
telemetryService,
)