摘要
在 AI 原生应用蓬勃发展的今天,大模型“外挂”工具、数据与算力已成为刚需。Anthropic 提出的 Model Context Protocol(MCP) 正迅速成为“LLM ↔ 外部世界”的事实标准。本文将基于 LangChain4j 最新实现,手把手带你跑通 HTTP/stdio 两种传输模式,封装自定义 ToolProvider,并用 Docker 一键拉起 GitHub MCP Server,实现“三分钟给大模型装上 GitHub 操作系统的”丝滑体验。附完整 Java 源码与踩坑指南,建议收藏!


1. MCP 是什么?为什么需要它?

传统方式 MCP 方式
每接入一个工具都要写一套客户端、鉴权、序列化 统一协议,一次接入,处处调用
工具描述五花八门,Prompt 拼装靠硬编码 标准化 ToolSpecification,模型自动理解
资源/日志/提示词无统一管理 原生支持 Resource、Prompt、Logging 三大能力

一句话:MCP = HTTP + JSON-RPC 语义层 + 工具/资源/提示词描述规范,让大模型和外部系统说同一种语言。


2. LangChain4j 的 MCP 架构速览

核心 3 个接口即可跑通:

  1. McpTransport:负责底层通信

    • StdioMcpTransport:本地子进程(推荐调试)
    • HttpMcpTransport:SSE + HTTP POST(跨机器)
  2. McpClient:协议层封装,自动心跳、重连、日志回调。

  3. McpToolProvider:把 MCP Server 暴露的工具转成 LangChain4j 的 ToolSpecification,一键注入 AiServices


3. 5 分钟上手:stdio 版“Hello GitHub”

3.1 准备 Docker 镜像

git clone https://github.com/modelcontextprotocol/servers.git
cd servers
docker build -t mcp/github -f src/github/Dockerfile .

镜像仅 173 MB,内置 @modelcontextprotocol/server-github,开箱即用。

3.2 Java 示例代码

public class McpGithubToolsExample {
    public static void main(String[] args) throws Exception {
        ChatModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .build();

        // 1. 构造 stdio 传输层(Docker 容器)
        McpTransport transport = new StdioMcpTransport.Builder()
                .command(List.of(
                        "/usr/local/bin/docker", "run", "-i",
                        "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
                        "mcp/github"))
                .logEvents(true)
                .build();

        // 2. 创建 MCP Client
        McpClient mcpClient = new DefaultMcpClient.Builder()
                .transport(transport)
                .build();

        // 3. 工具提供者
        McpToolProvider toolProvider = McpToolProvider.builder()
                .mcpClients(mcpClient)
                .build();

        // 4. AI 服务
        Bot bot = AiServices.builder(Bot.class)
                .chatModel(model)
                .toolProvider(toolProvider)
                .build();

        String answer = bot.chat(
                "Summarize the last 3 commits of the LangChain4j GitHub repository");
        System.out.println(answer);

        mcpClient.close(); // 优雅关闭
    }

    interface Bot {
        String chat(String userMessage);
    }
}

运行输出示例:

1. Commit 36951f9 — 更新 upload-pages-artifact 至 v3  
2. Commit 6fcd19f — 批量升级 Action 至 v4  
3. Commit 2e74049 — setup-node & configure-pages 同步升级

踩坑提示
Windows 请将 /usr/local/bin/docker 改为 docker.exe 绝对路径;若用 Podman,同名替换即可。


4. HTTP/SSE 模式:跨机器调用

McpTransport httpTransport = new HttpMcpTransport.Builder()
        .sseUrl("http://remote-host:3001/sse")
        .logRequests(true)
        .logResponses(true)
        .build();

配合云托管的 MCP Server,可实现“无 Docker”部署。


5. 高阶玩法

5.1 工具白名单 & 冲突解决

McpToolProvider toolProvider = McpToolProvider.builder()
        .mcpClients(client1, client2)
        .filterToolNames("get_issue", "list_issues")   // 仅暴露读接口
        .filter((client, tool) ->                      // 同名工具优先级
                !tool.name().equals("echoInteger") ||
                client.key().equals("numeric-mcp"))
        .build();

5.2 动态热插拔

toolProvider.addMcpClient(newClient);      // 运行期动态接入
toolProvider.removeMcpClient("oldClient"); // 优雅下线

5.3 资源自动暴露

把 MCP Server 的文件、数据库等资源映射成 LLM 可调用的 list_resources / get_resource 工具,只需:

McpToolProvider.builder()
        .mcpClients(mcpClient)
        .resourcesAsTools(new DefaultMcpResourcesAsToolsPresenter())
        .build();

6. 与 Spring Boot 集成示例(片段)

@Configuration
public class McpConfig {

    @Bean
    public McpClient mcpClient() {
        return new DefaultMcpClient.Builder()
                .transport(new StdioMcpTransport.Builder()
                        .command(List.of("npx", "@modelcontextprotocol/server-filesystem", "/data"))
                        .build())
                .build();
    }

    @Bean
    public McpToolProvider toolProvider(McpClient client) {
        return McpToolProvider.builder().mcpClients(client).build();
    }

    @Bean
    public Bot bot(ChatModel model, McpToolProvider provider) {
        return AiServices.builder(Bot.class)
                .chatModel(model)
                .toolProvider(provider)
                .build();
    }
}

7. 小结 & 展望

LangChain4j 通过 零侵入 的 MCP 支持,把 Java 生态瞬间拉进了“工具自由”时代:

  • 开发者:不用关心底层协议,专注业务 Tool/Prompt/Resource 定义
  • 架构师:多 Server 可插拔,灰度、熔断、限流都交给 LangChain4j
  • DevOps:同一套 Docker 镜像,本地调试、K8s 部署无缝切换

后续可继续深挖:

  • 自定义 McpLogMessageHandler 对接 ELK
  • 基于 McpPrompt 的“动态少样本提示”
  • 将传统 REST/RPC 服务快速封装成 MCP Server,实现存量系统 AI 化

源码地址
https://github.com/langchain4j/langchain4j-examples/tree/main/mcp-example


如果本文对你有帮助,记得点赞、收藏、关注三连!评论区一起聊聊你打算用 MCP 给大模型接入哪些“外挂”吧~

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐