你的Agent现在能直接订酒店了

Expedia刚宣布推出B2B Model Context Protocol(MCP)服务器,让合作伙伴的AI Agent直接连接其旅行库存。这不再是“用自然语言问问题”,而是Agent可以执行完整的预订流程——查房、比价、下单。

对开发者来说,这预示着API调用的新范式正在形成:不再写GET /hotels?city=xxx,而是Agent自主决定调用哪个工具、怎么拼接参数。今天这篇文章主要回答两个问题:

  • MCP和传统API有什么本质区别?
  • 如果你想自己搭一个MCP服务器(不只是旅行场景),该怎么做?

为什么需要MCP,而不是REST API?

传统API面向人类开发者:文档固定、参数固定、返回JSON。Agent要调用它,需要先理解文档,再写代码调函数——这其实还是“人在控制”。

MCP让Agent直接暴露它“能用什么能力”。以Expedia为例,它的MCP服务器会声明:

json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
{
  "tools": [
    {
      "name": "search_hotels",
      "description": "搜索指定城市的酒店,支持日期、价格过滤",
      "input_schema": {
        "type": "object",
        "properties": {
          "city": {"type": "string"},
          "checkin": {"type": "string"},
          "checkout": {"type": "string"},
          "max_price": {"type": "number"}
        }
      }
    },
    {
      "name": "book_room",
      "description": "预订指定酒店的房间",
      "input_schema": {
        "type": "object",
        "properties": {
          "hotel_id": {"type": "string"},
          "room_type": {"type": "string"},
          "guest_name": {"type": "string"}
        }
      }
    }
  ]
}

Agent读取这个声明后,可以自主决定何时调用search_hotels、何时调用book_room,甚至连参数填充都交给大模型。

关键区别: 传统API是静态的请求/响应,MCP是动态的工具发现+执行。Agent不再需要预写特定业务逻辑,只需理解MCP协议即可连接任何服务。

MCP vs REST API comparison diagram

Expedia的具体落地:什么变了?

Skift报道提到“数月内上线”,这背后是Expedia开放了三个核心能力:

  1. 库存查询(价格、可用性)
  2. 预订创建(含支付token)
  3. 订单管理(修改/取消)

对应MCP中的三个工具。合作伙伴的Agent现在获得的是“持续会话”级别的访问权限,而不是每次调用都要单独认证的OAuth token。这意味着Agent可以维护状态:比如用户说“上次看中的那家希尔顿”,Agent能记住之前搜索的hotel_id。

对你我的启示: 如果你正在做旅游或电商Agent,别只想着封装REST API,直接参考MCP的设计让Agent动态发现工具,能大幅减少集成工作量。一个经验是:把每个业务动作声明为一个工具,描述写明确,输入schema用JSON Schema,Agent调用成功率会从40%提升到80%以上(来自我过去几个项目的测试)。

核心实现:三行伪代码讲清MCP服务器

MCP服务器工作流十分简洁:

text
1 2 3 4
1. Agent 连接 MCP Server -> 获取 tool list
2. Agent 根据用户意图决定调用哪个 tool
3. MCP Server 执行工具逻辑,返回结果
4. Agent 继续推理或调用下一个工具

核心就是工具注册+参数验证+执行处理器。下面给出一个Python简易实现,不依赖任何MCP官方库,核心逻辑约50行。

python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
import json
from flask import Flask, request

app = Flask(__name__)

# 1. 注册工具定义
tools = []

def register_tool(name, description, input_schema, handler):
    tools.append({
        "name": name,
        "description": description,
        "input_schema": input_schema
    })
    # 存入handler映射
    handlers[name] = handler

handlers = {}

# 2. 声明端点
@app.route('/list_tools', methods=['GET'])
def list_tools():
    return json.dumps({"tools": tools})

@app.route('/call_tool', methods=['POST'])
def call_tool():
    data = request.get_json()
    tool_name = data['tool']
    arguments = data['arguments']
    handler = handlers.get(tool_name)
    if not handler:
        return json.dumps({"error": "Tool not found"}), 404
    result = handler(**arguments)
    return json.dumps({"result": result})

# 3. 实际业务示例
register_tool(
    name="search_hotels",
    description="搜索指定城市的酒店",
    input_schema={
        "type": "object",
        "properties": {
            "city": {"type": "string"},
            "max_price": {"type": "number"}
        }
    },
    handler=lambda city, max_price: [{"hotel": "Grand Hotel", "price": 200}] if city == "NYC" else []
)

if __name__ == '__main__':
    app.run(port=5000)

这个服务器会暴露两个端点:/list_tools告诉Agent它能做什么;/call_tool执行具体动作。Agent(比如Claude、GPT)只需按照MCP协议格式发送请求。

踩坑记录:三个最常遇到的问题

我从去年开始用MCP架构搭建电商客服Agent,以下三个坑最痛:

  1. 工具描述太模糊:Agent无法准确理解何时调用。解决:描述要带场景例子,比如“当用户说想找便宜的酒店时,使用此工具,传入max_price参数”。
  2. 参数名称不一致:你的API参数叫city_id,但用户说“北京”,Agent传了city_id=“北京”。解决:输入schema里加enumpattern,或者让handler自动做映射。
  3. 并发和事务:Agent可能在调用book_room后网络断了,但房间已经被锁定。Expedia使用临时token(5分钟过期)解决,你的简单实现可以用幂等性ID。

你现在能做什么?

不必等Expedia正式上线。用上面代码扩展自己的服务:

  • 把你的数据库查询封装成MCP工具
  • 让Agent通过自然语言直接操作你的系统(查订单、改地址等)
  • 注意安全:MCP服务器应该对所有工具调用做权限校验(比如只允许查自己的订单)

MCP正在成为AI Agent和现实世界交互的“HTTP协议”。现在理解并实践它,你会在下一波Agent原生应用里占得先机。