目录

状态:草案 用途:官网「MCP 对接」示例文档源稿,交前端渲染为官网单页 待定项:正式服务域名(本文以 <your-sse-url> 占位)、API Key 申请入口(见 7.7) 最后核对:2026-09-20

本文档面向希望通过 MCP 协议调用法律数据服务的用户,说明如何把本服务接入你正在使用的 AI 客户端(Cursor、Claude Desktop、Cherry Studio 等)或自研应用。

服务当前通过 SSE 模式对外提供 MCP 工具,鉴权使用请求头 x-api-key。

一、服务概述

1. 服务信息

项目 内容
传输模式 MCP over SSE
SSE 地址 <your-sse-url>
鉴权方式 请求头 x-api-key: <your-api-key>
健康检查 GET <your-service-host>/health

健康检查正常时返回:

{
  "status": "ok",
  "service": "legal-mcp"
}

API Key 仅通过请求头传递,不要拼接在 URL 中。申请正式 API Key 的入口见 7. 如何申请 API Key。

2. 数据域全景

服务覆盖 5 个法律数据域,每个数据域提供「检索 + 详情」两个工具,共 10 个 MCP 工具:

数据域 数据范围
法律法规 法律、行政法规、司法解释、部门规章及规范性文件
裁判文书 相似案件、裁判理由、争议焦点及裁判尺度
行政处罚 行政处罚决定、违法事实认定、处罚依据及处罚尺度
金融监管规则 证券、银行、保险等金融监管规则与合规口径
金融监管案例 金融监管处罚、执法案例及合规实践

二、快速接入:通用 MCP 客户端(推荐)

如果你使用支持 MCP 的 AI 客户端,不需要写任何代码,配置一次即可在对话中直接检索法律数据。三类客户端的接入方式如下,其它支持 SSE 传输的客户端配置要点相同:传输类型选 SSE、地址填 <your-sse-url>、请求头加 x-api-key。

1. Cursor

编辑 MCP 配置文件(全局配置位于 ~/.cursor/mcp.json,也可以放在项目下的 .cursor/mcp.json),加入:

{
  "mcpServers": {
    "legal-mcp": {
      "url": "<your-sse-url>",
      "headers": {
        "x-api-key": "<your-api-key>"
      }
    }
  }
}

保存后重启 Cursor,在 Settings → MCP 服务器列表中看到 legal-mcp 点亮、工具列表可见即接入成功。参考:Cursor MCP 官方文档。

2. Cherry Studio

打开 设置 → MCP 服务器 → 添加服务器:

  1. 类型选择 SSE。
  2. URL 填写 <your-sse-url>。
  3. 在「请求头」中添加一条:键 x-api-key,值 <your-api-key>。
  4. 保存并启用。

注意:部分旧版本存在「保存失败后请求头被清空」的问题,启用后建议重新打开编辑页确认请求头仍然存在。配置细节可参考 Cherry Studio 官方文档。

3. Claude Desktop

Claude Desktop 的配置文件原生只支持 stdio 传输,接入远程 SSE 服务有两种方式。

方式 A(推荐,新版本):在 Settings → Connectors(自定义连接器)中添加远程 MCP 服务,地址填 <your-sse-url>,并在请求头中配置 x-api-key。

方式 B(通用,需本机安装 Node.js):使用 mcp-remote 桥接。编辑配置文件(Windows:%APPDATA%\Claude\claude_desktop_config.json;macOS:~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "legal-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "<your-sse-url>",
        "--header",
        "x-api-key: <your-api-key>"
      ]
    }
  }
}

保存后重启 Claude Desktop,在工具图标中确认服务已连接。

4. 接入自检

配置完成后,可以在对话里直接验证:

用 search_law 检索"劳动合同法 经济补偿金",返回前 2 条结果

客户端正常时会自动调用工具并展示法规列表;如果没有任何工具被调用,检查 API Key 与 SSE 地址是否配置正确。

三、工具总览

1. 工具清单

工具名 数据域 用途
search_law 法律法规 检索法律法规、司法解释、部门规章
get_law 法律法规 按 ID 获取法规全文
search_judgment 裁判文书 检索相似案件、裁判理由
get_judgment 裁判文书 按 ID 获取裁判文书全文
search_penalty 行政处罚 检索行政处罚决定、违法事实
get_penalty 行政处罚 按 ID 获取处罚决定全文
search_financial_law 金融监管规则 检索证券、金融监管规则
get_financial_law 金融监管规则 按 ID 获取金融监管规则全文
search_financial_case 金融监管案例 检索金融监管处罚、合规案例
get_financial_case 金融监管案例 按 ID 获取金融监管案例全文

2. 通用调用链路

所有数据域遵循同一条「先检索、后取详情」链路:

search_*(query 检索)  ->  取 results[].id  ->  get_*(按 ID 取全文)
  • search_* 工具适合检索、召回和列表展示;
  • get_* 工具适合在用户选中某条结果后获取完整内容,避免一次性拉取过多全文。

3. 参数与返回的通用约定

search_* 工具入参一致:

参数 类型 必填 默认值 说明
query string 是 无 查询内容,支持自然语言问题、名称、文号或业务关键词,不能为空。
top_n integer 否 10 返回条数,范围 1-50;演示与首屏建议 2-5,生产按页面大小设置。

get_* 工具只需一个 ID 参数,各数据域参数名不同:get_law 用 article_id,get_financial_law 用 law_id,get_judgment / get_penalty / get_financial_case 用 case_id。ID 必须来自对应 search_* 返回的 results[].id。

工具返回为 JSON 文本:检索类返回 {"total": ..., "results": [...]};详情类返回文档字段与 content 全文。业务错误同样以 JSON 返回,结构见第六章。

说明:金融监管两个数据域的字段表已与线上服务核对;法律法规、裁判文书、行政处罚三个数据域的字段表基于服务返回结构整理,正式上线前以实际调用返回为准。

四、工具详解

1. 法律法规

search_law

检索法律、行政法规、司法解释、部门规章及规范性文件。查询词可以是法规名称、文号、主题或自然语言问题。

参数示例:

{
  "query": "劳动合同法 经济补偿金",
  "top_n": 2
}

常见查询词示例:

劳动合同法 经济补偿金
民法典 合同编 违约责任
未成年人网络保护条例
最高人民法院关于民事诉讼证据的若干规定

返回字段说明:

字段 说明
total 本次返回结果数量。
results 法规结果列表。
results[].id 法规唯一 ID,用于调用 get_law。
results[].title 法规标题。
results[].document_no 文号。
results[].publish_date 发布日期。
results[].enforce_date 施行日期。
results[].status 效力状态,例如现行有效。
results[].level 法规层级。
results[].snippet 命中的摘要片段。
results[].rerank_score 相关性重排序分数。

get_law

根据法规 ID 获取法规全文和详情字段。article_id 必须来自 search_law 返回的 results[].id。

参数示例:

{
  "article_id": "<search_law 返回的 id>"
}

返回字段说明:

字段 说明
id 法规唯一 ID。
title 法规标题。
document_no 文号。
publish_date 发布日期。
enforce_date 施行日期。
status 效力状态。
level 法规层级。
content 法规全文内容。

2. 裁判文书

search_judgment

检索相似案件、裁判理由、争议焦点及裁判尺度。查询词支持案由、争议类型、自然语言描述。

参数示例:

{
  "query": "民间借贷纠纷 利率 上限",
  "top_n": 2
}

常见查询词示例:

民间借贷纠纷 利率 上限
机动车交通事故 责任认定
离婚 抚养权 举证
劳动合同 违法解除 赔偿金

返回字段说明:

字段 说明
total 本次返回结果数量。
results 案件结果列表。
results[].id 案件唯一 ID,用于调用 get_judgment。
results[].title 案件标题。
results[].case_no 案号。
results[].action_cause 案由。
results[].court_name 审理法院。
results[].publish_date 裁判日期。
results[].snippet 命中的摘要片段。
results[].rerank_score 相关性重排序分数。

get_judgment

根据案件 ID 获取裁判文书全文和详情字段。case_id 必须来自 search_judgment 返回的 results[].id。

参数示例:

{
  "case_id": "<search_judgment 返回的 id>"
}

返回字段说明:

字段 说明
id 案件唯一 ID。
title 案件标题。
case_no 案号。
action_cause 案由。
court_name 审理法院。
publish_date 裁判日期。
content 裁判文书全文内容。

3. 行政处罚

search_penalty

检索行政处罚决定、违法事实认定、处罚依据及处罚尺度。查询词支持违法类型、处罚主题、主体名称。

参数示例:

{
  "query": "食品安全 行政处罚",
  "top_n": 2
}

常见查询词示例:

食品安全 行政处罚
无证经营 处罚决定
虚假宣传 市场监管处罚
行政处罚裁量基准

返回字段说明:

字段 说明
total 本次返回结果数量。
results 处罚结果列表。
results[].id 处罚记录唯一 ID,用于调用 get_penalty。
results[].title 处罚决定标题。
results[].doc_no 处罚决定书文号。
results[].publish_date 发布日期。
results[].violate_name 违法类型。
results[].snippet 命中的摘要片段。
results[].rerank_score 相关性重排序分数。

get_penalty

根据处罚记录 ID 获取处罚决定全文和详情字段。case_id 必须来自 search_penalty 返回的 results[].id。

参数示例:

{
  "case_id": "<search_penalty 返回的 id>"
}

返回字段说明:

字段 说明
id 处罚记录唯一 ID。
title 处罚决定标题。
doc_no 处罚决定书文号。
publish_date 发布日期。
publish_org_name 处罚机关名称。
violate_name 违法类型。
content 处罚决定全文内容。

4. 金融监管规则

search_financial_law

检索证券、银行、保险等金融监管规则与合规口径。查询词支持法规名称、文号、监管主题或自然语言问题。

参数示例:

{
  "query": "上市公司信息披露监管规则",
  "top_n": 2
}

常见查询词示例:

上市公司信息披露监管规则
证券发行承销规则
私募基金监督管理办法
内幕信息知情人登记制度
证监会令第182号

返回字段说明:

字段 说明
total 本次返回结果数量。
results 法规结果列表。
results[].id 法规唯一 ID,用于调用 get_financial_law。
results[].title 法规标题。
results[].document_no 文号。
results[].publish_date 发布日期。
results[].enforce_date 施行日期。
results[].valid_date 有效日期。
results[].status 状态,例如现行有效。
results[].add_status 增补状态。
results[].level 法规层级。
results[].department_label 机构标签。
results[].business_label 业务标签。
results[].rank_label 位阶标签。
results[].snippet 命中的摘要片段。
results[].rerank_score 相关性重排序分数。

get_financial_law

根据法规 ID 获取金融监管规则全文和详情字段。law_id 必须来自 search_financial_law 返回的 results[].id。

参数示例:

{
  "law_id": "<search_financial_law 返回的 id>"
}

返回字段说明:

字段 说明
id 法规唯一 ID。
title 法规标题。
document_no 文号。
publish_date 发布日期。
enforce_date 施行日期。
valid_date 有效日期。
law_number 法规编号。
status 状态。
add_status 增补状态。
have_change 是否存在变更。
level 法规层级。
ref_url 原文链接。
content 法规全文内容。
visit_total 访问量。
rank_label 位阶标签。
department_label 机构标签。
business_label 业务标签。

5. 金融监管案例

search_financial_case

检索证券、金融监管处罚、执法案例及合规实践。查询词支持违规类型、处罚主题、主体名称或自然语言问题。

参数示例:

{
  "query": "虚假陈述 信息披露违法 监管处罚案例",
  "top_n": 2
}

常见查询词示例:

虚假陈述 信息披露违法 监管处罚案例
内幕交易 行政处罚 案例
操纵证券市场 处罚
上市公司财务造假 监管案例
未按规定披露重大事项

返回字段说明:

字段 说明
total 本次返回结果数量。
results 案例结果列表。
results[].id 案例唯一 ID,用于调用 get_financial_case。
results[].title 案例标题。
results[].doc_no 文号。
results[].publish_date 发布日期。
results[].enforce_date 执行日期。
results[].publish_org_name 发布机构名称。
results[].short_name 主体简称。
results[].person_name 主体名称。
results[].violate_name 违规类型。
results[].snippet 命中的摘要片段。
results[].rerank_score 相关性重排序分数。

get_financial_case

根据案例 ID 获取金融监管案例全文和详情字段。case_id 必须来自 search_financial_case 返回的 results[].id。

参数示例:

{
  "case_id": "<search_financial_case 返回的 id>"
}

返回字段说明:

字段 说明
id 案例唯一 ID。
title 案例标题。
doc_no 文号。
violatemanage_id 违规管理 ID。
publish_date 发布日期。
enforce_date 执行日期。
publish_org 发布机构编码。
publish_org_name 发布机构名称。
company_code 公司代码。
short_name 主体简称。
person_name 主体名称。
violate_name 违规类型。
publish_name 发布名称。
content 案例全文内容。

6. 业务使用建议

  • 列表检索只调用 search_*,用户选中某条结果后再调用对应 get_* 获取全文,避免一次拉取过多内容。
  • 演示场景建议 top_n=2,响应更快;生产场景按页面大小设置,例如 5、10 或 20。
  • query 不能为空字符串,否则服务返回参数错误。
  • 跨数据域交叉核验时(例如先查法规依据、再查类案裁判尺度),分别调用对应数据域的 search_*,不要把多个问题混在一个 query 里。

五、Python 开发接入

如果你的应用需要在自己的代码里调用这些工具,按本章接入。

1. 安装依赖

建议 Python 3.10 或 3.11。

pip install mcp

Poetry 项目中:

poetry add mcp

2. 调用流程

Python 客户端不需要手写 JSON-RPC,也不需要自己处理 /messages 地址。标准流程:

  1. 使用 sse_client() 连接 <your-sse-url>,请求头带 x-api-key。
  2. 创建 ClientSession(read, write)。
  3. 调用 await session.initialize() 初始化 MCP 会话。
  4. 调用 await session.list_tools() 获取工具列表,推荐用于自检。
  5. 调用 await session.call_tool(tool_name, arguments) 执行工具。
  6. 从 result.content 中解析工具返回的 JSON 文本。

3. 最小可运行示例

保存为 client_example.py:

import asyncio
import json

from mcp import ClientSession
from mcp.client.sse import sse_client


SSE_URL = "<your-sse-url>"
API_KEY = "<your-api-key>"


def parse_tool_result(result):
    for content in result.content:
        text = getattr(content, "text", None)
        if not text:
            continue
        return json.loads(text)
    return {}


async def main():
    headers = {"x-api-key": API_KEY}

    async with sse_client(SSE_URL, headers=headers) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            result = await session.call_tool(
                "search_law",
                {
                    "query": "劳动合同法 经济补偿金",
                    "top_n": 2,
                },
            )

            data = parse_tool_result(result)
            print(json.dumps(data, ensure_ascii=False, indent=2))


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

运行:

python client_example.py

4. 完整业务链示例

下面的示例展示跨数据域的完整链路:先检索法规并取全文,再检索类案并取全文。

import asyncio
import json

from mcp import ClientSession
from mcp.client.sse import sse_client


SSE_URL = "<your-sse-url>"
API_KEY = "<your-api-key>"


def parse_tool_result(result):
    for content in result.content:
        text = getattr(content, "text", None)
        if text:
            return json.loads(text)
    return {}


def require_success(tool_name, data):
    if data.get("error"):
        raise RuntimeError(f"{tool_name} failed: {data}")
    return data


def first_id(search_data):
    results = search_data.get("results") or []
    if not results:
        return None
    return results[0].get("id")


async def call_json_tool(session, name, arguments):
    result = await session.call_tool(name, arguments)
    data = parse_tool_result(result)
    return require_success(name, data)


async def main():
    headers = {"x-api-key": API_KEY}

    async with sse_client(SSE_URL, headers=headers) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            law_search = await call_json_tool(
                session,
                "search_law",
                {"query": "劳动合同法 经济补偿金", "top_n": 2},
            )
            law_id = first_id(law_search)
            print("law search:", json.dumps(law_search, ensure_ascii=False, indent=2))

            if law_id:
                law_detail = await call_json_tool(
                    session,
                    "get_law",
                    {"article_id": law_id},
                )
                print("law detail:", json.dumps(law_detail, ensure_ascii=False, indent=2))

            judgment_search = await call_json_tool(
                session,
                "search_judgment",
                {"query": "违法解除劳动合同 赔偿金", "top_n": 2},
            )
            case_id = first_id(judgment_search)
            print(
                "judgment search:",
                json.dumps(judgment_search, ensure_ascii=False, indent=2),
            )

            if case_id:
                judgment_detail = await call_json_tool(
                    session,
                    "get_judgment",
                    {"case_id": case_id},
                )
                print(
                    "judgment detail:",
                    json.dumps(judgment_detail, ensure_ascii=False, indent=2),
                )


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

5. 获取工具列表

开发调试时建议先调用一次 list_tools(),确认服务端工具可见:

tools_result = await session.list_tools()

for tool in tools_result.tools:
    print(tool.name, tool.description)

6. 同步框架如何调用

MCP Python 客户端是异步接口:

  • 普通同步入口使用 data = asyncio.run(your_async_function())。
  • FastAPI、aiohttp 等本身就是异步框架的应用直接 await,不要在事件循环内部再调用 asyncio.run()。

六、返回结果解析与错误处理

MCP 客户端的工具返回对象不是直接的 dict,而是包含 content 列表。本服务的工具结果通常在第一个文本内容块中:

result = await session.call_tool("search_law", {"query": "劳动合同法", "top_n": 2})
text = result.content[0].text
data = json.loads(text)

更稳妥的写法:

def parse_tool_result(result):
    for content in result.content:
        text = getattr(content, "text", None)
        if text:
            return json.loads(text)
    return {}

业务错误以 JSON 结构返回,例如:

{
  "error": true,
  "code": "INVALID_API_KEY",
  "message": "API Key invalid or expired"
}

建议客户端统一判断:

if data.get("error"):
    raise RuntimeError(data)

七、常见问题

1. 为什么不能直接 POST <your-sse-url>

SSE 模式下,/sse 是建立事件流的入口,HTTP 方法是 GET。MCP 客户端会自动处理 SSE 连接和后续消息发送,不要自己用 requests.post 之类的普通 HTTP 调用去请求它。

2. 返回认证错误

检查 API Key 是否通过请求头正确传入:

headers = {"x-api-key": "<your-api-key>"}

3. 连接超时或连接失败

先用健康检查确认服务状态:

curl <your-service-host>/health

健康检查正常但 MCP 连接失败时,确认客户端选择的传输类型是 SSE,地址是 <your-sse-url>。

4. 检索结果为空

换更宽泛的查询词重试,例如把 "劳动合同法 第四十七条 经济补偿金标准" 简化为 "劳动合同 经济补偿";跨域问题(查法规查不到)可以改查对应主题的裁判文书或处罚数据域。

5. Agent 没有自动调用工具

在提示词里明确指向工具和数据域,例如「用 search_law 检索……」「帮我找民间借贷纠纷的类案判决」。查询词越具体,工具选择和检索效果越好。

6. 全文太长导致上下文溢出

get_* 返回的是全文。在 Agent 场景建议:列表阶段只用 search_* 的 snippet,用户明确需要时再取全文,并对 content 做长度截断(例如首屏仅保留前 2000 字符)。

7. 如何申请 API Key

正式 API Key 申请入口待上线(占位:控制台入口或联系商务,由产品侧确认后更新本文档)。获取 Key 后替换本文所有 <your-api-key> 占位符即可。

变更记录

版本 日期 说明
v0.1 2026-09-20 初稿(草案)。金融监管两域字段表与线上核对;法律法规/裁判文书/行政处罚三域字段表待服务恢复后实测复核。