概述

默认情况下,Codex 并未提供类似 Claude Code 的丰富功能集。本文将介绍如何通过开源项目 MakingMcp 提供的 MCP (Model Context Protocol) 能力来增强 Codex 的功能。

前置要求

在开始配置之前,请确保您已完成以下准备工作:

1. 安装 .NET 10 SDK

下载并安装 .NET 10 SDK

2. 安装 Codex 最新版本

确保您已安装最新版本的 Codex AI 编程助手。

3. 下载 MakingMcp 服务端

GitHub Releases 页面下载 MakingMcp-Web-win-x64.zip 文件,并解压至指定目录。

配置步骤

1. 配置 MakingMcp 服务

将下载的可执行文件放置到合适的位置:
在这里插入图片描述

编辑 appsettings.json 配置文件,按照以下模板修改配置项:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Urls": "http://localhost:6511",
  "OPENAI_API_KEY": "Your_API_Key_Here",
  "OPENAI_ENDPOINT": "https://api.token-ai.cn/v1",
  "TASK_MODEL": "gpt-4.1",
  "EMBEDDING_MODEL": null,
  "TAVILY_API_KEY": ""
}

配置说明:

  • TASK_MODEL: 指定 Task 功能使用的默认模型
  • OPENAI_API_KEY: 必须填写有效的 API 密钥
  • OPENAI_ENDPOINT: 推荐使用 https://api.token-ai.cn/v1 以获得更优惠的价格
  • TAVILY_API_KEY: 填写后可启用 Web 搜索功能,密钥获取地址:https://app.tavily.com/home

2. 配置 Codex 客户端

打开 C:\Users\[当前用户]\.codex\config.toml 文件,添加以下配置内容:

model = "gpt-5-codex"
model_provider = "token-ai"
disable_response_storage = true

sandbox_mode = "danger-full-access"
approval_policy = "never"
windows_wsl_setup_acknowledged = true

experimental_use_rmcp_client = true
[mcp_servers.agent]
url = "http://localhost:6511/mcp"

[model_providers.token-ai]
name = "Token AI Response"
base_url = "https://api.token-ai.cn/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"

注意事项:

  • 如果不需要使用 Task 或 Web 功能,可以删除对应的环境变量
  • 未提供相应环境变量时,对应功能将不会被启用

功能验证

完成配置后,启动 MakingMcp 服务并测试功能。系统将提供类似于 Claude Code 的 MCP 能力:
在这里插入图片描述

Task 功能测试

通过 Task 功能可以实现更复杂的工作流程,提升 Codex 的持续工作能力:

在这里插入图片描述

第三方客户端集成

如果您希望在 Trae 或 Cherry Studio 等其他 MCP 客户端中使用此服务,请使用以下配置:

前提条件: 确保已安装 .NET 10 SDK

{
  "mcpServers": {
    "AgentMcp": {
      "type": "streamableHttp",
      "url": "http://localhost:6511/mcp"
    }
  }
}

集成效果如下:

在这里插入图片描述

MakingMcp 技术架构深度分析

核心架构概览

MakingMcp 是一个基于 .NET 的 Model Context Protocol (MCP) 服务实现,其核心价值在于提供了一套完整的 Agent/SubAgent 架构,使 AI 助手能够像 Claude Code 一样执行复杂的多步骤任务。

Task 功能的 Agent/SubAgent 实现机制

1. 整体架构设计

MakingMcp 采用了分层的 Agent 架构:

主 Agent (MCP Client)
    ↓ 调用 Task Tool
    ↓
SubAgent (Semantic Kernel)
    ↓ 拥有完整工具集
    ↓
执行层 (Bash, Read, Write, Edit, Glob, Web 等工具)
2. 核心实现细节 (TaskTool.cs)

入口方法 - TaskAsync 方法 (TaskTool.cs:281-392)

[McpServerTool(Name = "Task"), KernelFunction("Task")]
public static async Task<TextContent> TaskAsync(
    McpServer mcpServer,
    string description,
    string prompt)

这个方法作为 MCP 工具暴露给主 Agent,接收任务描述和详细提示词。

SubAgent 创建流程 (TaskTool.cs:309-315)

关键步骤:

  1. 创建一个 TaskCompletionSource 用于接收 SubAgent 的最终结果
  2. 调用 CreateKernelForAgent 创建独立的 Semantic Kernel 实例
  3. 为 SubAgent 注入 CompleteTool 工具,允许其主动报告任务完成
var completionSource = new TaskCompletionSource<string>();

var kernel = CreateKernelForAgent(result =>
{
    completionResult = result;
    completionSource.SetResult(result);
    return Task.CompletedTask;
}, taskId);

SubAgent Kernel 配置 (TaskTool.cs:394-441)

SubAgent 使用独立的 OpenAI 客户端配置:

private static Kernel CreateKernelForAgent(Func<string, Task> completeTaskFunc, string taskId)
{
    var kernelBuilder = Kernel.CreateBuilder();

    // 配置独立的 HTTP 客户端
    var httpClient = new HttpClient(new HttpClientHandler {
        ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
        AutomaticDecompression = DecompressionMethods.GZip | ...
    });

    // 添加 OpenAI 聊天完成服务
    kernelBuilder.AddOpenAIChatCompletion(
        OpenAIOptions.TASK_MODEL,
        new Uri(OpenAIOptions.OPENAI_ENDPOINT),
        OpenAIOptions.API_KEY,
        httpClient: httpClient
    );

    // 注册所有工具到 SubAgent
    AddToolsToKernel(kernelBuilder, AgentTools.All, taskId);

    // 注入完成回调工具
    var completeTool = new CompleteTool(completeTaskFunc);
    kernelBuilder.Plugins.AddFromObject(completeTool);

    return kernelBuilder.Build();
}

工具动态注册机制 (TaskTool.cs:443-499)

SubAgent 支持灵活的工具集配置:

private static void AddToolsToKernel(IKernelBuilder kernelBuilder, AgentTools tools, string taskId)
{
    if (tools.HasFlag(AgentTools.All))
    {
        kernelBuilder.Plugins.AddFromType<BashTool>();
        kernelBuilder.Plugins.AddFromType<ReadTool>();
        kernelBuilder.Plugins.AddFromType<WriteTool>();
        kernelBuilder.Plugins.AddFromType<EditTool>();
        kernelBuilder.Plugins.AddFromType<GlobTool>();
        // ... 更多工具
    }
}

工具配置通过 AgentTools 枚举实现 (AgentConfiguration.cs:12-27):

[Flags]
public enum AgentTools
{
    None = 0,
    Read = 1 << 0,
    Write = 1 << 1,
    Edit = 1 << 2,
    Glob = 1 << 3,
    Grep = 1 << 4,
    Bash = 1 << 5,
    Web = 1 << 6,
    All = Read | Write | Edit | Glob | Grep | Bash | Web
}
3. SubAgent 执行流程

初始化阶段 (TaskTool.cs:319-323)

var chatHistory = new ChatHistory();
chatHistory.AddSystemMessage(SystemPrompt);  // 注入系统提示词
chatHistory.AddUserMessage(prompt);          // 注入用户任务

系统提示词 (TaskTool.cs:15-245) 包含完整的任务执行指南:

  • 工具使用策略
  • 代码规范
  • 安全约束
  • 任务管理 (TodoWrite)
  • Git 操作流程
  • 任务完成报告规范

流式执行与进度通知 (TaskTool.cs:329-356)

SubAgent 采用流式响应模式,实时向主 Agent 报告进度:

var agentTask = Task.Run(async () =>
{
    var settings = new OpenAIPromptExecutionSettings
    {
        FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(),
        MaxTokens = OpenAIOptions.MAX_OUTPUT_TOKENS
    };

    await foreach (var response in chatCompletionService
        .GetStreamingChatMessageContentsAsync(chatHistory, settings, kernel))
    {
        if (!string.IsNullOrEmpty(response.Content))
        {
            sb.Append(response.Content);

            // 发送 MCP 进度通知
            await mcpServer.SendNotificationAsync("notifications/progress", new
            {
                message = response.Content,
                progress = 0,
                progressToken
            });
        }
    }
});

超时控制与结果收集 (TaskTool.cs:358-385)

系统实现了多重完成机制:

var timeoutTask = Task.Delay(TimeSpan.FromMinutes(10));
var completedTask = await Task.WhenAny(
    completionSource.Task,  // SubAgent 主动调用 CompleteTool
    agentTask,              // SubAgent 自然结束
    timeoutTask             // 超时保护
);

if (completedTask == timeoutTask)
{
    return Error("Agent execution timed out after 10 minutes.");
}

// 优先使用 CompleteTool 返回的结果
if (completionResult != null)
{
    return completionResult;
}

// 否则使用流式输出的全部内容
var result = completionResult ?? sb.ToString();
return result;
4. CompleteTool - SubAgent 的完成信号

CompleteTool (CompleteTool.cs:6-19) 是 SubAgent 的关键工具:

public class CompleteTool(Func<string, Task> completeTaskFunc)
{
    [KernelFunction("complete_task"),
     Description("Use this tool when you have completed the task to provide your final answer")]
    public async Task<string> CompleteTask(
        [Description("The final result of the task")]
        string result)
    {
        await completeTaskFunc.Invoke(result);
        return "Task completed.";
    }
}

当 SubAgent 完成任务时,它会主动调用 complete_task 工具,触发回调函数,将结果传递回主 Agent。

5. 函数调用追踪与日志

系统实现了完整的函数调用追踪 (TaskTool.cs:417-438):

kernel.FunctionInvoking += (sender, e) =>
{
    Log.Information("[Task {TaskId}] Invoking function: {PluginName}.{FunctionName}",
        taskId, e.Function.PluginName, e.Function.Name);

    // 记录所有参数
    foreach (var arg in e.Arguments)
    {
        var value = arg.Value?.ToString();
        var truncated = value?.Length > 200 ? value.Substring(0, 200) + "..." : value;
        Log.Debug("[Task {TaskId}] Function argument - {Key}: {Value}",
            taskId, arg.Key, truncated);
    }
};

kernel.FunctionInvoked += (sender, e) =>
{
    var resultStr = e.Result?.ToString();
    var truncated = resultStr?.Length > 200 ? resultStr.Substring(0, 200) + "..." : resultStr;
    Log.Information("[Task {TaskId}] Function invoked: {PluginName}.{FunctionName}, Result length: {Length}",
        taskId, e.Function.PluginName, e.Function.Name, resultStr?.Length ?? 0);
};

MCP 协议集成细节

1. 工具注册机制

MakingMcp 使用反射和特性标记自动发现并注册工具 (Program.cs:136-160):

static McpServerTool[] GetToolsForType<T>()
{
    var tools = new List<McpServerTool>();
    var toolType = typeof(T);

    // 查找所有标记了 McpServerToolAttribute 的静态方法
    var methods = toolType.GetMethods(BindingFlags.Public | BindingFlags.Static)
        .Where(m => m.GetCustomAttributes(typeof(McpServerToolAttribute), false).Any());

    foreach (var method in methods)
    {
        try
        {
            var tool = McpServerTool.Create(method, target: null,
                new McpServerToolCreateOptions());
            tools.Add(tool);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to add tool {toolType.Name}.{method.Name}: {ex.Message}");
        }
    }

    return tools.ToArray();
}

每个工具使用双重标记暴露功能:

  • [McpServerTool] - 暴露给 MCP 客户端
  • [KernelFunction] - 暴露给 Semantic Kernel (SubAgent)
2. 两种部署模式

Stdio 模式 (MakingMcp/Program.cs:63-77)

var stdio = builder.Services
    .AddMcpServer((options =>
    {
        options.ServerInfo = new Implementation
        {
            Name = "MakingMcp",
            Version = "0.2.1",
        };
    }))
    .WithStdioServerTransport();  // 标准输入输出传输

foreach (var tool in toolDictionary)
{
    stdio.WithTools(tool.Value);
}

Web 服务模式 (MakingMcp.Web/Program.cs:49-123)

支持 HTTP 传输和动态工具过滤:

builder.Services.AddMcpServer()
    .WithHttpTransport(options =>
    {
        options.ConfigureSessionOptions = async (httpContext, mcpOptions, _) =>
        {
            // 从查询参数获取工具类别
            var toolCategory = httpContext.Request.Query["tools"].ToString()?.ToLower();

            // 动态配置工具集
            var selectedTools = FilterToolsByCategory(toolCategory);

            mcpOptions.ServerInfo = new Implementation()
            {
                Version = "1.0.0",
                Name = "MakingMcp Web Service",
            };

            // 注册工具集合
            var toolCollection = mcpOptions.ToolCollection =
                new McpServerPrimitiveCollection<McpServerTool>();

            foreach (var tool in selectedTools)
            {
                toolCollection.Add(tool);
            }
        };
    });

工具实现示例

BashTool - 持久化 Shell 会话 (BashTool.cs)

支持后台执行和输出流式读取:

if (run_in_background)
{
    var process = CreateProcess(command);
    var session = new BashSession(command, description, process);

    process.Start();
    session.BeginCapture();
    Sessions[session.Id] = session;  // 存储会话供后续访问

    return $"Started background bash session with id: {session.Id}";
}
ReadTool - 智能文件读取 (ReadTool.cs)

支持分页读取和路径规范化:

public static async Task<string> Read(
    string file_path,
    int limit = 2000,  // 默认最多读取 2000 行
    int offset = 0
)
{
    var lines = await File.ReadAllLinesAsync(normalizedPath);
    var slice = lines.Skip(offset).Take(limit).ToList();

    // 返回 JSON 格式的结构化结果
    return JsonSerializer.Serialize(new
    {
        file_path = normalizedPath,
        content = formattedContent,
        total_lines = lines.Length,
        lines_returned = slice.Count,
        offset,
        limit
    });
}

技术栈总结

  1. Microsoft.SemanticKernel - 核心 AI 编排框架,支持函数调用和流式响应
  2. ModelContextProtocol.Server - MCP 协议实现库
  3. Serilog - 结构化日志记录
  4. .NET 8.0+ - 现代 C# 特性 (file-scoped namespaces, records, nullable reference types)

关键设计优势

  1. 隔离性:每个 SubAgent 拥有独立的 Kernel 实例和工具集
  2. 可追踪性:完整的函数调用日志和任务 ID 追踪
  3. 灵活性:通过 AgentTools 枚举动态配置工具权限
  4. 可扩展性:基于反射的工具注册机制,易于添加新工具
  5. 安全性:超时控制、证书验证、路径规范化等多重保护
  6. 实时反馈:MCP 进度通知机制让主 Agent 能实时了解 SubAgent 状态

这种架构使得 Codex 等 AI 助手能够通过 Task 工具启动具备完整能力的 SubAgent,实现类似 Claude Code 的持续工作能力和复杂任务处理能力。

技术支持

如需加入 Codex 技术交流群,请扫描下方二维码:

通过以上配置,您已成功为 Codex 集成了强大的 MCP 能力,可以享受类似 Claude Code 的增强功能体验。

开源地址:https://github.com/AIDotNet/MakingMcp

Logo

更多推荐