feat: add MCP server support for AI agents

Add Model Context Protocol (MCP) server integration to extend AI agent
capabilities with external tools. This allows users to configure MCP
servers (stdio, SSE, HTTP) in global settings and have agents use them.

Note: MCP servers are currently configured globally. Per-project MCP
server configuration is planned for a future update.

Features:
- New MCP Servers settings section with full CRUD operations
- Import/Export JSON configs (Claude Code format compatible)
- Configurable permission settings:
  - Auto-approve MCP tools (bypass permission prompts)
  - Unrestricted tools (allow all tools when MCP enabled)
- Refresh button to reload from settings file

Implementation:
- Added MCPServerConfig and MCPToolInfo types
- Added store actions for MCP server management
- Updated claude-provider to use configurable MCP permissions
- Updated sdk-options factory functions for MCP support
- Added settings helpers for loading MCP configs
This commit is contained in:
M Zubair
2025-12-28 00:51:50 +01:00
parent f7a0365bee
commit 5f328a4c13
20 changed files with 1375 additions and 43 deletions

View File

@@ -7,6 +7,7 @@ import type {
AgentModel,
PlanningMode,
AIProfile,
MCPServerConfig,
} from '@automaker/types';
// Re-export ThemeMode for convenience
@@ -482,6 +483,11 @@ export interface AppState {
autoLoadClaudeMd: boolean; // Auto-load CLAUDE.md files using SDK's settingSources option
enableSandboxMode: boolean; // Enable sandbox mode for bash commands (may cause issues on some systems)
// MCP Servers
mcpServers: MCPServerConfig[]; // List of configured MCP servers for agent use
mcpAutoApproveTools: boolean; // Auto-approve MCP tool calls without permission prompts
mcpUnrestrictedTools: boolean; // Allow unrestricted tools when MCP servers are enabled
// Project Analysis
projectAnalysis: ProjectAnalysis | null;
isAnalyzing: boolean;
@@ -758,6 +764,8 @@ export interface AppActions {
// Claude Agent SDK Settings actions
setAutoLoadClaudeMd: (enabled: boolean) => Promise<void>;
setEnableSandboxMode: (enabled: boolean) => Promise<void>;
setMcpAutoApproveTools: (enabled: boolean) => Promise<void>;
setMcpUnrestrictedTools: (enabled: boolean) => Promise<void>;
// AI Profile actions
addAIProfile: (profile: Omit<AIProfile, 'id'>) => void;
@@ -766,6 +774,12 @@ export interface AppActions {
reorderAIProfiles: (oldIndex: number, newIndex: number) => void;
resetAIProfiles: () => void;
// MCP Server actions
addMCPServer: (server: Omit<MCPServerConfig, 'id'>) => void;
updateMCPServer: (id: string, updates: Partial<MCPServerConfig>) => void;
removeMCPServer: (id: string) => void;
reorderMCPServers: (oldIndex: number, newIndex: number) => void;
// Project Analysis actions
setProjectAnalysis: (analysis: ProjectAnalysis | null) => void;
setIsAnalyzing: (analyzing: boolean) => void;
@@ -932,6 +946,9 @@ const initialState: AppState = {
validationModel: 'opus', // Default to opus for GitHub issue validation
autoLoadClaudeMd: false, // Default to disabled (user must opt-in)
enableSandboxMode: true, // Default to enabled for security (can be disabled if issues occur)
mcpServers: [], // No MCP servers configured by default
mcpAutoApproveTools: true, // Default to enabled - bypass permission prompts for MCP tools
mcpUnrestrictedTools: true, // Default to enabled - don't filter allowedTools when MCP enabled
aiProfiles: DEFAULT_AI_PROFILES,
projectAnalysis: null,
isAnalyzing: false,
@@ -1570,6 +1587,18 @@ export const useAppStore = create<AppState & AppActions>()(
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
setMcpAutoApproveTools: async (enabled) => {
set({ mcpAutoApproveTools: enabled });
// Sync to server settings file
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
setMcpUnrestrictedTools: async (enabled) => {
set({ mcpUnrestrictedTools: enabled });
// Sync to server settings file
const { syncSettingsToServer } = await import('@/hooks/use-settings-migration');
await syncSettingsToServer();
},
// AI Profile actions
addAIProfile: (profile) => {
@@ -1611,6 +1640,29 @@ export const useAppStore = create<AppState & AppActions>()(
set({ aiProfiles: [...DEFAULT_AI_PROFILES, ...userProfiles] });
},
// MCP Server actions
addMCPServer: (server) => {
const id = `mcp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
set({ mcpServers: [...get().mcpServers, { ...server, id, enabled: true }] });
},
updateMCPServer: (id, updates) => {
set({
mcpServers: get().mcpServers.map((s) => (s.id === id ? { ...s, ...updates } : s)),
});
},
removeMCPServer: (id) => {
set({ mcpServers: get().mcpServers.filter((s) => s.id !== id) });
},
reorderMCPServers: (oldIndex, newIndex) => {
const servers = [...get().mcpServers];
const [movedServer] = servers.splice(oldIndex, 1);
servers.splice(newIndex, 0, movedServer);
set({ mcpServers: servers });
},
// Project Analysis actions
setProjectAnalysis: (analysis) => set({ projectAnalysis: analysis }),
setIsAnalyzing: (analyzing) => set({ isAnalyzing: analyzing }),
@@ -2716,6 +2768,10 @@ export const useAppStore = create<AppState & AppActions>()(
validationModel: state.validationModel,
autoLoadClaudeMd: state.autoLoadClaudeMd,
enableSandboxMode: state.enableSandboxMode,
// MCP settings
mcpServers: state.mcpServers,
mcpAutoApproveTools: state.mcpAutoApproveTools,
mcpUnrestrictedTools: state.mcpUnrestrictedTools,
// Profiles and sessions
aiProfiles: state.aiProfiles,
chatSessions: state.chatSessions,