diff --git a/README.md b/README.md
index ea5dcdec..42da1b8b 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,19 @@
 
 [Deep Code](https://github.com/lessweb/deepcode-cli) 是专为 `deepseek-v4` 模型优化的终端 AI 编码助手，支持深度思考、推理强度控制以及 Agent Skills。
 
+## 🚀 新增功能（本 Fork）
+
+### `/mcp` Skill 与 MCP 实现
+
+本 Fork 新增了 `/mcp` 命令和 MCP（Model Context Protocol）集成，让 Deep Code CLI 能够连接外部工具和服务：
+
+- **`/mcp` Skill**：一键管理 MCP 服务器连接，支持添加、移除、列出已配置的 MCP 服务。
+- **MCP 协议实现**：支持与 GitHub、文件系统、数据库等多种外部服务的标准化集成，大幅扩展 AI 助手的操作能力。
+
+通过 MCP，你现在可以让 Deep Code 直接操作 GitHub 仓库、读取文件、查询数据库等，而无需离开终端。
+
+📖 **详细配置指南：** [docs/mcp.md](docs/mcp.md)
+
 ## 安装
 
 ```bash
@@ -98,6 +111,10 @@ Deep Code自带免费的、且大部分情况够用的Web Search工具。如果
 }
 ```
 
+### 如何配置 MCP？
+
+Deep Code CLI 支持 MCP（Model Context Protocol），可以连接 GitHub、浏览器、文件系统等外部服务。配置方法请查看：[docs/mcp.md](docs/mcp.md)
+
 ## 获取帮助
 
 - 在 GitHub Issues 上报告错误或请求功能 (https://github.com/lessweb/deepcode-cli/issues)
diff --git a/docs/mcp.md b/docs/mcp.md
new file mode 100644
index 00000000..09df8cc2
--- /dev/null
+++ b/docs/mcp.md
@@ -0,0 +1,205 @@
+# Deep Code CLI MCP 配置指南
+
+Deep Code CLI 支持 MCP（Model Context Protocol），让 AI 助手能够连接外部工具和服务，如 GitHub、浏览器、数据库等。
+
+## 概述
+
+配置 MCP 后，Deep Code 可以：
+
+- 操作 GitHub 仓库（查看 Issues、创建 PR、搜索代码等）
+- 操控浏览器（截图、点击、填表单等）
+- 访问文件系统
+- 连接数据库和 API
+- ...以及任何兼容 MCP 协议的外部服务
+
+MCP 工具在 Deep Code 中的命名格式为 `mcp__<服务名>__<工具名>`，例如 `mcp__github__search_code`。
+
+## 配置 MCP 服务器
+
+编辑 `~/.deepcode/settings.json`，添加 `mcpServers` 字段：
+
+```json
+{
+  "env": {
+    "MODEL": "deepseek-v4-pro",
+    "BASE_URL": "https://api.deepseek.com",
+    "API_KEY": "sk-..."
+  },
+  "thinkingEnabled": true,
+  "reasoningEffort": "max",
+  "mcpServers": {
+    "<服务名称>": {
+      "command": "<可执行文件>",
+      "args": ["<参数1>", "<参数2>"],
+      "env": {
+        "<环境变量>": "<值>"
+      }
+    }
+  }
+}
+```
+
+### 配置项说明
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `command` | string | 是 | MCP 服务器的可执行文件路径或命令（如 `npx`、`node`、`python`） |
+| `args` | string[] | 否 | 传递给命令的参数列表 |
+| `env` | object | 否 | 传递给 MCP 服务器进程的环境变量（如 API Key） |
+
+## 常用 MCP 示例
+
+### GitHub MCP
+
+让 Deep Code 直接操作 GitHub 仓库（搜索代码、管理 Issue/PR、读写文件等）：
+
+```json
+{
+  "mcpServers": {
+    "github": {
+      "command": "npx",
+      "args": ["-y", "@modelcontextprotocol/server-github"],
+      "env": {
+        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
+      }
+    }
+  }
+}
+```
+
+> GitHub Personal Access Token 可在 [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens) 生成。
+
+### 浏览器控制（Playwright）
+
+让 Deep Code 操控浏览器进行截图、页面操作等：
+
+```json
+{
+  "mcpServers": {
+    "playwright": {
+      "command": "npx",
+      "args": ["@playwright/mcp@latest"]
+    }
+  }
+}
+```
+
+### 文件系统
+
+让 Deep Code 在指定目录中读写文件：
+
+```json
+{
+  "mcpServers": {
+    "filesystem": {
+      "command": "npx",
+      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
+    }
+  }
+}
+```
+
+### 自定义 Python MCP
+
+```json
+{
+  "mcpServers": {
+    "my-tool": {
+      "command": "python",
+      "args": ["-m", "my_mcp_server"],
+      "env": {
+        "API_KEY": "xxx"
+      }
+    }
+  }
+}
+```
+
+## 完整配置示例
+
+以下是一个配置了 GitHub 和 Playwright 两个 MCP 服务器的完整 `~/.deepcode/settings.json`：
+
+```json
+{
+  "env": {
+    "MODEL": "deepseek-v4-pro",
+    "BASE_URL": "https://api.deepseek.com",
+    "API_KEY": "sk-xxxxxxxxxxxx"
+  },
+  "thinkingEnabled": true,
+  "reasoningEffort": "max",
+  "mcpServers": {
+    "github": {
+      "command": "npx",
+      "args": ["-y", "@modelcontextprotocol/server-github"],
+      "env": {
+        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxxxxxxxxx"
+      }
+    },
+    "playwright": {
+      "command": "npx",
+      "args": ["@playwright/mcp@latest"]
+    }
+  }
+}
+```
+
+## 使用 MCP
+
+配置完成后，启动 `deepcode`，使用 `/mcp` 命令管理 MCP 连接：
+
+- `/mcp` — 查看已配置的 MCP 服务器状态
+- `/mcp add` — 添加新的 MCP 服务器
+- `/mcp remove` — 移除 MCP 服务器
+- `/mcp list` — 列出所有已连接的 MCP 服务器及其工具
+
+在对话中直接使用 MCP 工具名称即可调用，例如：
+
+```
+帮我搜索 GitHub 上 deepcode-cli 仓库的 issues
+```
+
+AI 会自动调用 `mcp__github__search_issues` 工具完成操作。
+
+## 工具命名规则
+
+MCP 工具名称由三部分组成：`mcp__<服务名>__<工具名>`
+
+| 服务名 | 工具名 | 完整调用名 |
+|--------|--------|-----------|
+| github | search_code | `mcp__github__search_code` |
+| github | create_pull_request | `mcp__github__create_pull_request` |
+| playwright | browser_navigate | `mcp__playwright__browser_navigate` |
+| playwright | browser_take_screenshot | `mcp__playwright__browser_take_screenshot` |
+
+你可以通过 `/mcp list` 查看每个服务器提供的具体工具列表。
+
+## 故障排查
+
+### 启动失败
+
+如果 MCP 服务器无法启动，检查：
+
+1. `command` 是否已安装（如 `npx` 需要 Node.js）
+2. `env` 中的环境变量是否正确（如 `GITHUB_PERSONAL_ACCESS_TOKEN`）
+3. 运行 `deepcode` 的终端是否有网络访问权限
+
+### 工具不显示
+
+1. 确认 `settings.json` 中的 `mcpServers` 字段格式正确
+2. 启动 deepcode 后使用 `/mcp` 查看服务器状态
+3. 如果服务器状态显示错误，根据错误信息排查
+
+### Windows 用户
+
+在 Windows 上，Deep Code CLI 会自动为 `.cmd` 命令添加 shell 支持。如果你的 MCP 命令是批处理脚本，确保文件名以 `.cmd` 结尾。
+
+## 编写你自己的 MCP 服务器
+
+MCP 服务器遵循 [Model Context Protocol](https://modelcontextprotocol.io/) 规范，使用 JSON-RPC 2.0 通信。你可以用任何语言编写 MCP 服务器，只要实现以下协议即可：
+
+1. `initialize` — 握手和协议协商
+2. `tools/list` — 返回可用工具列表
+3. `tools/call` — 执行工具调用
+
+更多参考：[MCP 官方文档](https://modelcontextprotocol.io/)
diff --git a/src/prompt.ts b/src/prompt.ts
index e1def61b..f2573ff1 100644
--- a/src/prompt.ts
+++ b/src/prompt.ts
@@ -419,7 +419,7 @@ export type ToolDefinition = {
   };
 };
 
-export function getTools(_options: PromptToolOptions = {}): ToolDefinition[] {
+export function getTools(_options: PromptToolOptions = {}, externalTools: ToolDefinition[] = []): ToolDefinition[] {
   const tools: ToolDefinition[] = [
     {
       type: "function",
@@ -610,5 +610,9 @@ export function getTools(_options: PromptToolOptions = {}): ToolDefinition[] {
     },
   });
 
+  for (const tool of externalTools) {
+    tools.push(tool);
+  }
+
   return tools;
 }
diff --git a/src/session.ts b/src/session.ts
index 0116fbd4..a3d6a3ea 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -9,8 +9,9 @@ import type { ChatCompletionMessageParam, ChatCompletionContentPart } from "open
 import { launchNotifyScript } from "./notify";
 import { buildThinkingRequestOptions } from "./openai-thinking";
 import { DEEPSEEK_V4_MODELS } from "./model-capabilities";
-import { getCompactPrompt, getSystemPrompt, getTools, AGENT_DRIFT_GUARD_SKILL } from "./prompt";
+import { getCompactPrompt, getSystemPrompt, getTools, AGENT_DRIFT_GUARD_SKILL, type ToolDefinition } from "./prompt";
 import { ToolExecutor, type CreateOpenAIClient } from "./tools/executor";
+import { McpManager } from "./tools/mcp-manager";
 import { logApiError } from "./error-logger";
 import { logOpenAIChatCompletionDebug, normalizeDebugError } from "./debug-logger";
 
@@ -180,6 +181,8 @@ export class SessionManager {
   private activePromptController: AbortController | null = null;
   private readonly sessionControllers = new Map<string, AbortController>();
   private readonly toolExecutor: ToolExecutor;
+  private readonly mcpManager = new McpManager();
+  private mcpToolDefinitions: ToolDefinition[] = [];
 
   constructor(options: SessionManagerOptions) {
     this.projectRoot = options.projectRoot;
@@ -188,7 +191,18 @@ export class SessionManager {
     this.onAssistantMessage = options.onAssistantMessage;
     this.onSessionEntryUpdated = options.onSessionEntryUpdated;
     this.onLlmStreamProgress = options.onLlmStreamProgress;
-    this.toolExecutor = new ToolExecutor(this.projectRoot, this.createOpenAIClient);
+    this.toolExecutor = new ToolExecutor(this.projectRoot, this.createOpenAIClient, this.mcpManager);
+  }
+
+  async initMcpServers(
+    servers?: Record<string, { command: string; args?: string[]; env?: Record<string, string> }>
+  ): Promise<void> {
+    await this.mcpManager.initialize(servers);
+    this.mcpToolDefinitions = this.mcpManager.getMcpToolDefinitions();
+  }
+
+  getMcpStatus() {
+    return this.mcpManager.getStatus();
   }
 
   private estimateStreamTokens(text: string): number {
@@ -999,7 +1013,7 @@ ${skillMd}
           {
             model,
             messages,
-            tools: getTools(this.getPromptToolOptions()),
+            tools: getTools(this.getPromptToolOptions(), this.mcpToolDefinitions),
             ...thinkingOptions,
           },
           { signal: sessionController.signal },
diff --git a/src/settings.ts b/src/settings.ts
index e1a9b09d..3c046b46 100644
--- a/src/settings.ts
+++ b/src/settings.ts
@@ -9,6 +9,12 @@ export type DeepcodingEnv = {
 
 export type ReasoningEffort = "high" | "max";
 
+export type McpServerConfig = {
+  command: string;
+  args?: string[];
+  env?: Record<string, string>;
+};
+
 export type DeepcodingSettings = {
   env?: DeepcodingEnv;
   model?: string;
@@ -17,6 +23,7 @@ export type DeepcodingSettings = {
   debugLogEnabled?: boolean;
   notify?: string;
   webSearchTool?: string;
+  mcpServers?: Record<string, McpServerConfig>;
 };
 
 export type ResolvedDeepcodingSettings = {
@@ -28,6 +35,7 @@ export type ResolvedDeepcodingSettings = {
   debugLogEnabled: boolean;
   notify?: string;
   webSearchTool?: string;
+  mcpServers?: Record<string, McpServerConfig>;
 };
 
 export type ModelConfigSelection = {
@@ -63,6 +71,8 @@ export function resolveSettings(
   const notify = typeof settings?.notify === "string" ? settings.notify.trim() : "";
   const webSearchTool = typeof settings?.webSearchTool === "string" ? settings.webSearchTool.trim() : "";
 
+  const mcpServers = settings?.mcpServers;
+
   return {
     apiKey: env.API_KEY?.trim(),
     baseURL: env.BASE_URL?.trim() || defaults.baseURL,
@@ -72,6 +82,7 @@ export function resolveSettings(
     debugLogEnabled: settings?.debugLogEnabled === true,
     notify: notify || undefined,
     webSearchTool: webSearchTool || undefined,
+    mcpServers,
   };
 }
 
diff --git a/src/tests/slashCommands.test.ts b/src/tests/slashCommands.test.ts
index 7d9510a4..45b6fdfb 100644
--- a/src/tests/slashCommands.test.ts
+++ b/src/tests/slashCommands.test.ts
@@ -19,7 +19,7 @@ test("buildSlashCommands prefixes skills before built-ins", () => {
   assert.equal(items[0].kind, "skill");
   assert.equal(items[0].name, "skill-writer");
   const builtinNames = items.filter((i) => i.kind !== "skill").map((i) => i.name);
-  assert.deepEqual(builtinNames, ["skills", "model", "new", "init", "resume", "exit"]);
+  assert.deepEqual(builtinNames, ["skills", "model", "new", "init", "resume", "mcp", "exit"]);
 });
 
 test("filterSlashCommands matches partial prefixes", () => {
diff --git a/src/tools/executor.ts b/src/tools/executor.ts
index eec0b206..d857ad71 100644
--- a/src/tools/executor.ts
+++ b/src/tools/executor.ts
@@ -6,6 +6,7 @@ import { handleEditTool } from "./edit-handler";
 import { handleReadTool } from "./read-handler";
 import { handleWebSearchTool } from "./web-search-handler";
 import { handleWriteTool } from "./write-handler";
+import type { McpManager } from "./mcp-manager";
 
 export type CreateOpenAIClient = () => {
   client: OpenAI | null;
@@ -73,11 +74,13 @@ export type ToolCallExecution = {
 export class ToolExecutor {
   private readonly projectRoot: string;
   private readonly createOpenAIClient?: CreateOpenAIClient;
+  private readonly mcpManager?: McpManager;
   private readonly toolHandlers = new Map<string, ToolHandler>();
 
-  constructor(projectRoot: string, createOpenAIClient?: CreateOpenAIClient) {
+  constructor(projectRoot: string, createOpenAIClient?: CreateOpenAIClient, mcpManager?: McpManager) {
     this.projectRoot = projectRoot;
     this.createOpenAIClient = createOpenAIClient;
+    this.mcpManager = mcpManager;
     this.registerToolHandlers();
   }
 
@@ -161,6 +164,12 @@ export class ToolExecutor {
     const toolName = toolCall.function.name;
     const handler = this.toolHandlers.get(toolName);
     if (!handler) {
+      // Try MCP tools
+      if (toolName.startsWith("mcp__") && this.mcpManager) {
+        const parsedArgs = this.parseToolArguments(toolCall.function.arguments);
+        const args = parsedArgs.ok ? parsedArgs.args : {};
+        return this.mcpManager.executeMcpTool(toolName, args);
+      }
       return {
         ok: false,
         name: toolName,
diff --git a/src/tools/mcp-client.ts b/src/tools/mcp-client.ts
new file mode 100644
index 00000000..89b0c2c2
--- /dev/null
+++ b/src/tools/mcp-client.ts
@@ -0,0 +1,181 @@
+import { spawn, type ChildProcess } from "child_process";
+import { createInterface, type Interface } from "readline";
+import * as os from "os";
+
+type JsonRpcRequest = {
+  jsonrpc: "2.0";
+  id: number;
+  method: string;
+  params?: Record<string, unknown>;
+};
+
+type JsonRpcResponse = {
+  jsonrpc: "2.0";
+  id: number;
+  result?: unknown;
+  error?: { code: number; message: string; data?: unknown };
+};
+
+export type McpToolDefinition = {
+  name: string;
+  description?: string;
+  inputSchema: {
+    type: "object";
+    properties: Record<string, unknown>;
+    required?: string[];
+  };
+};
+
+type ListToolsResult = {
+  tools: McpToolDefinition[];
+};
+
+type CallToolResult = {
+  content: Array<{ type: string; text?: string }>;
+  isError?: boolean;
+};
+
+export class McpClient {
+  private process: ChildProcess | null = null;
+  private reader: Interface | null = null;
+  private nextId = 1;
+  private pendingRequests = new Map<number, { resolve: (value: unknown) => void; reject: (error: Error) => void }>();
+  private buffer = "";
+
+  constructor(
+    private readonly serverName: string,
+    private readonly command: string,
+    private readonly args: string[] = [],
+    private readonly env?: Record<string, string>
+  ) {}
+
+  async connect(): Promise<void> {
+    return new Promise((resolve, reject) => {
+      const childEnv = {
+        ...process.env,
+        ...this.env,
+      };
+
+      const isWindows = os.platform() === "win32";
+
+      if (isWindows) {
+        // On Windows, .cmd files require shell: true to be spawned.
+        // Build a single command string so cmd.exe handles quoting correctly.
+        const cmd = [this.command + ".cmd", ...this.args].join(" ");
+        this.process = spawn(cmd, [], {
+          stdio: ["pipe", "pipe", "pipe"],
+          env: childEnv,
+          shell: true,
+          windowsHide: true,
+        });
+      } else {
+        this.process = spawn(this.command, this.args, {
+          stdio: ["pipe", "pipe", "pipe"],
+          env: childEnv,
+        });
+      }
+
+      this.process.on("error", (err) => {
+        reject(new Error(`Failed to start MCP server "${this.serverName}" (${this.command}): ${err.message}`));
+      });
+
+      this.process.on("exit", (code) => {
+        const error = new Error(`MCP server "${this.serverName}" exited with code ${code}`);
+        for (const [, pending] of this.pendingRequests) {
+          pending.reject(error);
+        }
+        this.pendingRequests.clear();
+      });
+
+      if (this.process.stderr) {
+        this.process.stderr.on("data", (data: Buffer) => {
+          // MCP servers log to stderr; we ignore for now
+        });
+      }
+
+      this.reader = createInterface({ input: this.process.stdout! });
+      this.reader.on("line", (line: string) => {
+        this.handleLine(line);
+      });
+
+      // Send initialize request (MCP protocol handshake)
+      this.sendRequest("initialize", {
+        protocolVersion: "2024-11-05",
+        capabilities: {},
+        clientInfo: { name: "deepcode-cli", version: "0.1.0" },
+      })
+        .then(() => {
+          // Send initialized notification
+          this.sendNotification("notifications/initialized");
+          resolve();
+        })
+        .catch(reject);
+    });
+  }
+
+  async listTools(): Promise<McpToolDefinition[]> {
+    const result = (await this.sendRequest("tools/list", {})) as ListToolsResult;
+    return result.tools ?? [];
+  }
+
+  async callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult> {
+    return (await this.sendRequest("tools/call", { name, arguments: args })) as CallToolResult;
+  }
+
+  disconnect(): void {
+    if (this.reader) {
+      this.reader.close();
+      this.reader = null;
+    }
+    if (this.process) {
+      this.process.kill();
+      this.process = null;
+    }
+  }
+
+  private sendRequest(method: string, params: Record<string, unknown>): Promise<unknown> {
+    return new Promise((resolve, reject) => {
+      const id = this.nextId++;
+      const request: JsonRpcRequest = {
+        jsonrpc: "2.0",
+        id,
+        method,
+        params,
+      };
+      this.pendingRequests.set(id, { resolve, reject });
+      this.writeLine(JSON.stringify(request));
+    });
+  }
+
+  private sendNotification(method: string, params?: Record<string, unknown>): void {
+    const notification = {
+      jsonrpc: "2.0" as const,
+      method,
+      params,
+    };
+    this.writeLine(JSON.stringify(notification));
+  }
+
+  private writeLine(data: string): void {
+    if (this.process?.stdin) {
+      this.process.stdin.write(data + "\n");
+    }
+  }
+
+  private handleLine(line: string): void {
+    try {
+      const message = JSON.parse(line) as JsonRpcResponse;
+      if (message.id !== undefined && this.pendingRequests.has(message.id)) {
+        const pending = this.pendingRequests.get(message.id)!;
+        this.pendingRequests.delete(message.id);
+        if (message.error) {
+          pending.reject(new Error(`MCP error: ${message.error.message}`));
+        } else {
+          pending.resolve(message.result);
+        }
+      }
+    } catch {
+      // Ignore unparseable lines
+    }
+  }
+}
diff --git a/src/tools/mcp-manager.ts b/src/tools/mcp-manager.ts
new file mode 100644
index 00000000..4bac5e9b
--- /dev/null
+++ b/src/tools/mcp-manager.ts
@@ -0,0 +1,145 @@
+import { McpClient, type McpToolDefinition } from "./mcp-client";
+import type { McpServerConfig } from "../settings";
+
+type McpToolEntry = {
+  serverName: string;
+  originalName: string;
+  namespacedName: string;
+  definition: McpToolDefinition;
+  client: McpClient;
+};
+
+export type McpServerStatus = {
+  name: string;
+  connected: boolean;
+  error?: string;
+  toolCount: number;
+  tools: string[];
+};
+
+export class McpManager {
+  private clients: McpClient[] = [];
+  private tools: McpToolEntry[] = [];
+  private initialized = false;
+  private serverStatuses: McpServerStatus[] = [];
+
+  async initialize(servers?: Record<string, McpServerConfig>): Promise<void> {
+    if (this.initialized) return;
+    this.initialized = true;
+
+    if (!servers || Object.keys(servers).length === 0) return;
+
+    const entries = Object.entries(servers);
+    for (const [name, config] of entries) {
+      try {
+        const client = new McpClient(name, config.command, config.args ?? [], config.env);
+        await client.connect();
+        this.clients.push(client);
+
+        const serverTools = await client.listTools();
+        const toolNames: string[] = [];
+        for (const tool of serverTools) {
+          const namespacedName = `mcp__${name}__${tool.name}`;
+          this.tools.push({
+            serverName: name,
+            originalName: tool.name,
+            namespacedName,
+            definition: tool,
+            client,
+          });
+          toolNames.push(tool.name);
+        }
+        this.serverStatuses.push({
+          name,
+          connected: true,
+          toolCount: serverTools.length,
+          tools: toolNames,
+        });
+      } catch (err) {
+        const message = err instanceof Error ? err.message : String(err);
+        process.stderr.write(`[deepcode] MCP server "${name}" failed to initialize: ${message}\n`);
+        this.serverStatuses.push({
+          name,
+          connected: false,
+          error: message,
+          toolCount: 0,
+          tools: [],
+        });
+      }
+    }
+  }
+
+  getStatus(): McpServerStatus[] {
+    return this.serverStatuses;
+  }
+
+  getMcpToolDefinitions(): Array<{
+    type: "function";
+    function: {
+      name: string;
+      description: string;
+      parameters: {
+        type: "object";
+        properties: Record<string, unknown>;
+        required?: string[];
+        additionalProperties?: boolean;
+      };
+    };
+  }> {
+    return this.tools.map((t) => ({
+      type: "function" as const,
+      function: {
+        name: t.namespacedName,
+        description: t.definition.description ?? `${t.serverName}: ${t.originalName}`,
+        parameters: {
+          type: "object" as const,
+          properties: t.definition.inputSchema.properties,
+          required: t.definition.inputSchema.required,
+          additionalProperties: false,
+        },
+      },
+    }));
+  }
+
+  isMcpTool(name: string): boolean {
+    return name.startsWith("mcp__");
+  }
+
+  async executeMcpTool(
+    name: string,
+    args: Record<string, unknown>
+  ): Promise<{ ok: boolean; name: string; output?: string; error?: string }> {
+    const tool = this.tools.find((t) => t.namespacedName === name);
+    if (!tool) {
+      return { ok: false, name, error: `Unknown MCP tool: ${name}` };
+    }
+
+    try {
+      const result = await tool.client.callTool(tool.originalName, args);
+      const text = result.content
+        .filter((c) => c.type === "text" && c.text)
+        .map((c) => c.text)
+        .join("\n");
+      return {
+        ok: !result.isError,
+        name,
+        output: text || JSON.stringify(result.content),
+      };
+    } catch (err) {
+      return {
+        ok: false,
+        name,
+        error: err instanceof Error ? err.message : String(err),
+      };
+    }
+  }
+
+  disconnect(): void {
+    for (const client of this.clients) {
+      client.disconnect();
+    }
+    this.clients = [];
+    this.tools = [];
+    this.initialized = false;
+  }
+}
diff --git a/src/ui/App.tsx b/src/ui/App.tsx
index 4c13909b..beab530e 100644
--- a/src/ui/App.tsx
+++ b/src/ui/App.tsx
@@ -126,6 +126,11 @@ export function App({ projectRoot, version = "", onRestart }: AppProps): React.R
     void refreshSkills();
   }, [refreshSessionsList, refreshSkills]);
 
+  useEffect(() => {
+    const settings = resolveCurrentSettings();
+    void sessionManager.initMcpServers(settings.mcpServers);
+  }, [sessionManager]);
+
   const writeRef = useRef(write);
   writeRef.current = write;
   const handlePrompt = useCallback(
@@ -174,6 +179,38 @@ export function App({ projectRoot, version = "", onRestart }: AppProps): React.R
         setView("session-list");
         return;
       }
+      if (submission.command === "mcp") {
+        process.stdout.write("\n");
+        process.stdout.write(chalk.bold.cyan("MCP Server Status\n"));
+        process.stdout.write(chalk.dim("─────────────────\n"));
+        const statuses = sessionManager.getMcpStatus();
+        if (statuses.length === 0) {
+          process.stdout.write(chalk.dim("  No MCP servers configured.\n"));
+        } else {
+          for (const s of statuses) {
+            const icon = s.connected ? chalk.green("✔") : chalk.red("✖");
+            process.stdout.write(`  ${icon} ${chalk.bold(s.name)}`);
+            if (s.connected) {
+              process.stdout.write(chalk.dim(`  (${s.toolCount} tools)`));
+            } else {
+              process.stdout.write(chalk.dim(`  — ${s.error ?? "failed"}`));
+            }
+            process.stdout.write("\n");
+            if (s.connected && s.tools.length > 0) {
+              for (const tool of s.tools) {
+                process.stdout.write(chalk.dim(`    - mcp__${s.name}__${tool}\n`));
+              }
+            }
+          }
+        }
+        process.stdout.write(chalk.dim("─────────────────\n"));
+        process.stdout.write(
+          chalk.dim(`  Total: ${statuses.filter((s) => s.connected).length} connected, `) +
+            chalk.dim(`${statuses.filter((s) => !s.connected).length} failed\n`)
+        );
+        process.stdout.write("\n");
+        return;
+      }
 
       const prompt: UserPromptContent = {
         text: submission.text,
diff --git a/src/ui/PromptInput.tsx b/src/ui/PromptInput.tsx
index 74c38d57..24560e21 100644
--- a/src/ui/PromptInput.tsx
+++ b/src/ui/PromptInput.tsx
@@ -40,7 +40,7 @@ export type PromptSubmission = {
   text: string;
   imageUrls: string[];
   selectedSkills?: SkillInfo[];
-  command?: "new" | "resume" | "exit";
+  command?: "new" | "resume" | "mcp" | "exit";
 };
 
 type Props = {
@@ -570,6 +570,14 @@ export const PromptInput = React.memo(function PromptInput({
       setShowSkillsDropdown(false);
       return;
     }
+    if (item.kind === "mcp") {
+      onSubmit({ text: "/mcp", imageUrls: [], command: "mcp" });
+      setBuffer(EMPTY_BUFFER);
+      setImageUrls([]);
+      setSelectedSkills([]);
+      setShowSkillsDropdown(false);
+      return;
+    }
     if (item.kind === "exit") {
       onSubmit({ text: "/exit", imageUrls: [], command: "exit" });
       setBuffer(EMPTY_BUFFER);
diff --git a/src/ui/slashCommands.ts b/src/ui/slashCommands.ts
index c7721240..c5656061 100644
--- a/src/ui/slashCommands.ts
+++ b/src/ui/slashCommands.ts
@@ -1,6 +1,6 @@
 import type { SkillInfo } from "../session";
 
-export type SlashCommandKind = "skill" | "skills" | "model" | "new" | "init" | "resume" | "exit";
+export type SlashCommandKind = "skill" | "skills" | "model" | "new" | "init" | "resume" | "mcp" | "exit";
 
 export type SlashCommandItem = {
   kind: SlashCommandKind;
@@ -41,6 +41,12 @@ export const BUILTIN_SLASH_COMMANDS: SlashCommandItem[] = [
     label: "/resume",
     description: "Pick a previous conversation to continue",
   },
+  {
+    kind: "mcp",
+    name: "mcp",
+    label: "/mcp",
+    description: "Show MCP server status and available tools",
+  },
   {
     kind: "exit",
     name: "exit",
