Step by Step Writing An Entitle Data Quality Skill

Step by step build a complete Data Quality Skill from scratch.
“Please analyze this Excel file and give me a data quality report.”
we will build skill like this.

data-quality-skill/
│
├── SKILL.md
│
├── scripts/
│   ├── profile_excel.py
│   ├── check_nulls.py
│   ├── check_duplicates.py
│   └── generate_report.py
│
├── references/
│   └── data-quality-rules.md
│
└── resources/
    └── report_template.md

2. Design the capability first, then the workflow, and then the scripts.

3. Agent 到底要完成什么任务?

Agent should do:

  • Identify the input file – 找到输入文件
  • Profile the dataset – Profile 数据集
  • Check NULL values – 检查 NULL
  • Check duplicate rows – 检查重复
  • Check basic schema – 检查基本 Schema
  • Interpret the results – 解释结果
  • Generate a report – 生成报告

4. Design Workflow

User Request   用户请求
     ↓
Identify Input   确定输入
     ↓
Profile Dataset   分析数据集
     ↓
Run Quality Checks   执行质量检查
     ├── NULL check   NULL 检查
     ├── Duplicate check   重复检查
     └── Schema check   Schema 检查
     ↓
Interpret Results   解释结果
     ↓
Generate Report   生成报告

5. 第一步:创建目录

</> Bash

mkdir -p data-quality-skill/scripts
mkdir -p data-quality-skill/references
mkdir -p data-quality-skill/resources

## looks this (SKILL.md is file rather than directory)

data-quality-skill/
├── SKILL.md
├── scripts/
├── references/
└── resources/

6. 第二步:profile_excel.py

我们先做第一个真正的执行工具, 它负责:获取数据事实。

</> Python

"""
profile_excel.py

Purpose / 目的:
    Profile an Excel dataset and return deterministic statistics.
    对 Excel 数据集进行 Profile,并返回确定性的统计结果。

Why this script exists / 为什么需要这个脚本:
    The LLM should reason about data-quality results,
    but it should NOT manually calculate dataset statistics.

    LLM 应该负责解释数据质量结果,
    而不是自己手工计算数据统计信息。
"""

from pathlib import Path
import json
import sys

import pandas as pd


def profile_excel(file_path: str) -> dict:
    """
    Read an Excel file and calculate basic profiling information.

    读取 Excel 文件并计算基础 Profile 信息。
    """

    # ---------------------------------------------------------
    # Validate the input path.
    # 验证输入文件路径。
    # ---------------------------------------------------------
    path = Path(file_path)

    if not path.exists():
        raise FileNotFoundError(
            f"File does not exist: {file_path}"
        )

    # ---------------------------------------------------------
    # Read the Excel file.
    # 读取 Excel 文件。
    #
    # pandas performs deterministic data processing.
    # pandas 执行确定性的数据处理。
    # ---------------------------------------------------------
    df = pd.read_excel(path)

    # ---------------------------------------------------------
    # Build structured profiling results.
    # 构建结构化 Profile 结果。
    #
    # The result is deliberately JSON-friendly.
    # 结果故意设计成 JSON-friendly 格式。
    # ---------------------------------------------------------
    result = {
        # Total number of rows.
        # 总行数。
        "row_count": int(len(df)),

        # Total number of columns.
        # 总列数。
        "column_count": int(len(df.columns)),

        # Column names.
        # 列名。
        "columns": list(df.columns),

        # Data type of every column.
        # 每一列的数据类型。
        "data_types": {
            column: str(dtype)
            for column, dtype in df.dtypes.items()
        },

        # NULL count for every column.
        # 每一列的 NULL 数量。
        "null_counts": {
            column: int(count)
            for column, count in df.isnull().sum().items()
        },

        # Total number of completely duplicated rows.
        # 完全重复的行数量。
        "duplicate_rows": int(df.duplicated().sum()),
    }

    return result


def main():
    """
    Command-line entry point.
    命令行程序入口。

    This makes the script independently executable.
    这样这个脚本可以独立执行。
    """

    # ---------------------------------------------------------
    # Validate command-line arguments.
    # 验证命令行参数。
    # ---------------------------------------------------------
    if len(sys.argv) != 2:
        print(
            "Usage: python profile_excel.py <excel_file>",
            file=sys.stderr
        )
        sys.exit(1)

    file_path = sys.argv[1]

    try:
        # -----------------------------------------------------
        # Execute the profiling logic.
        # 执行 Profile 逻辑。
        # -----------------------------------------------------
        result = profile_excel(file_path)

        # -----------------------------------------------------
        # Convert Python dictionary into JSON.
        # 把 Python dictionary 转换成 JSON。
        #
        # JSON is easy for Agents and other programs to consume.
        # JSON 很容易被 Agent 和其他程序消费。
        # -----------------------------------------------------
        print(
            json.dumps(
                {
                    "status": "success",
                    "data": result
                },
                indent=2
            )
        )

    except Exception as exc:

        # -----------------------------------------------------
        # Return structured error information.
        # 返回结构化错误信息。
        # -----------------------------------------------------
        print(
            json.dumps(
                {
                    "status": "error",
                    "error": str(exc)
                },
                indent=2
            ),
            file=sys.stderr
        )

        sys.exit(1)


# -------------------------------------------------------------
# Only execute main() when this file is run directly.
# 只有直接运行这个文件时才执行 main()。
# -------------------------------------------------------------
if __name__ == "__main__":
    main()

SKILL.md Specification: File Structure & description

SKILL.md is a standardized markdown file that defines a specific “capability” or “skill” for an AI Agent. It is the “user manual” that tells the LLM exactly what a particular tool/function can do, when to use it, how to use it, and what the expected output looks like. It turns a raw Python function into a teachable, reusable “expertise” for the Agent.
A in CN: SKILL.md 是一个标准化的 Markdown 文件,用于为 AI Agent 定义一项特定的“能力”或“技能”。它是给 LLM 看的“用户手册”,准确告诉模型某个工具/函数能做什么、何时使用、如何使用以及预期的输出长什么样。它把一个原始的 Python 函数变成一个可教学、可复用的 Agent “专长”。

Content and Structure of SKILL.md

A complete SKILL.md typically contains 5 core sections. Each section plays a specific role in guiding the LLM’s behavior.
A in CN: 一个完整的 SKILL.md 通常包含 5 个核心部分。每个部分在引导 LLM 行为方面都扮演着特定的角色。

SKILL.md 本质上可以理解成:

给 Agent 的一份“能力说明 + 使用说明 + 行为规则 + 操作流程”。

SKILL.md

├── 我是谁? → Skill Identity
├── 我什么时候应该被使用? → Description / Trigger
├── 我能做什么? → Capabilities
├── 我应该怎么做? → Instructions / Workflow
├── 有哪些限制? → Constraints
├── 我需要什么资源? → Resources
└── 最终应该输出什么? → Output / Examples

1. YAML Frontmatter

元数据头

This is a mandatory YAML block at the very top of the file, enclosed by ---. It contains machine-readable metadata. The most critical field here is description.
A in CN: 这是文件最顶部的强制 YAML 块,由 --- 包围。它包含机器可读的元数据。这里最关键的字段是 description。

2. Description

描述 – 本单元核心!

This is a concise, high-signal, keyword-rich sentence or two that tells the LLM’s router (the top-level orchestrator) what this skill does and when to trigger it. It is the “sales pitch” for the skill. The orchestrator reads all descriptions of all available skills and selects the most relevant one for the user’s query. If your description is vague, the orchestrator will never choose it.
CN: 这是一到两句简洁、高信号、关键词丰富的句子,告诉 LLM 的路由器(顶层编排器)这个技能做什么以及何时触发它。它是该技能的“推销词”。编排器会读取所有可用技能的所有描述,并为用户的查询选择最相关的一个。如果你的描述含糊不清,编排器永远不会选择它。

3. Steps

执行步骤

A numbered list of clear, atomic, actionable instructions for the Agent to execute. The Agent will follow these steps sequentially. This is where you break down a complex task into a workflow.
CN: 一个编号列表,包含清晰、原子化、可操作的指令供 Agent 执行。Agent 将按顺序遵循这些步骤。这是你将复杂任务分解为工作流的地方。

4. Examples

示例

 At least 2-3 concrete examples of user inputs and expected outputs (or thought processes). Examples are extremely powerful for LLMs (few-shot learning within the skill). They align the model’s output style and logic to your expectation.
CN: 至少 2-3 个具体的用户输入和预期输出(或思考过程)的示例。示例对 LLM 极其有效(技能内的 few-shot 学习)。它们使模型的输出风格和逻辑与你的期望保持一致。

5. Constraints / Safety

约束/安全

Explicit boundaries, disallowed actions, and failure handling. This is the “guardrails” section.
CN: 明确的边界、禁止的操作和失败处理。这是“护栏”部分。

Step by Step to build a skill.md

1. The most important understanding

SKILL.md 本质上可以理解成:

给 Agent 的一份“能力说明 + 使用说明 + 行为规则 + 操作流程”。

SKILL.md

├── 我是谁? → Skill Identity
├── 我什么时候应该被使用? → Description / Trigger
├── 我能做什么? → Capabilities
├── 我应该怎么做? → Instructions / Workflow
├── 有哪些限制? → Constraints
├── 我需要什么资源? → Resources
└── 最终应该输出什么? → Output / Examples

假设我们要创建一个:Excel Data Analysis Skill
它帮助 Agent 分析 Excel 文件。那么最简单的 SKILL.md 骨架可以先写成:

2. Build a skeleton

---
name: excel-data-analysis
description: Analyze Excel files and produce data quality findings, summaries, and insights.
---

# Excel Data Analysis

## Purpose

...

## When to Use

...

## Capabilities

...

## Instructions

...

## Constraints

...

## Resources

...

## Output Format

...

## Examples

...

3. YAML Frontmatter

可以理解成这个 Skill 的“身份证”。

</> YAML
---
name: excel-data-analysis
description: Analyze Excel files and produce data quality findings, summaries, and insights.
---

3.1 name

</> YAML
name: excel-data-analysis

这是非常重要的。告诉 Skill 系统:这个 Skill 叫什么?
e.g.
excel-data-analysis
sql-optimization
pdf-processing
data-quality
azure-data-engineering

3.2 description

</> YAML
description: Analyze Excel files and produce data quality findings, summaries, and insights.

这个更加重要。它告诉 Agent:这个 Skill 是干什么的,以及什么时候可能需要它。

例如用户说:”Please analyze this Excel file and find duplicate records.”

Agent 就可以判断:

User request
     ↓
Excel analysis?
     ↓
Yes
     ↓
excel-data-analysis Skill

所以:

  • name 解决:Who are you?
  • description 解决:What are you for?

4. Purpose

</> Markdown
# Excel Data Analysis

## Purpose

This skill provides a structured workflow for analyzing Excel
files, identifying data quality issues, and producing
business-oriented findings.

这里是在告诉 Agent:这个 Skill 的总体目标是什么?

Purpose 和 description 不完全一样。

  • Description: 偏向 “什么时候应该考虑使用我?” e.g. Analyze Excel files…
  • Purpose: 偏向 “使用我以后,我到底要完成什么事情?”
    e.g identify data quality issues
    produce business-oriented findings

5. When to Use

</> Markdown

## When to Use

Use this skill when the user asks to:

- Analyze an Excel workbook
- Profile columns and data types
- Detect missing values
- Detect duplicate records
- Identify inconsistent values
- Produce data quality findings

这个 section 非常关键。它解决:什么时候应该启动这个 Skill?

所以这里实际上是在定义:Trigger conditions. 可以把它理解成:Skill 的适用边界。

6. Capabilities

</> Markdown

## Capabilities

This skill can:

1. Inspect workbook structure
2. Profile columns
3. Detect missing values
4. Detect duplicates
5. Detect inconsistent values
6. Generate a data quality summary

这个 section 解决的是:这个 Skill 到底“会什么”?

  • When to Use 回答:什么时候用我?
  • Capabilities 回答:用了我以后,我能干什么?

7. Instructions

现在进入最核心的部分。在不同的文章里可能叫不同的名字。 例如:WorkflowInstructionsSteps。反正都是告诉 Agent 如何 一步一步地去做什么,具体怎么做。Instructions 是一个更大的概念。Instructions 可以描述 Workflow,也可以描述规则、约束、方法、注意事项等。
Instructions can describe the Workflow, as well as rules, constraints, methods, and other guidance.

如果细化一下:

概念ENCN
InstructionsThe actual guidance/rules for performing the task完成任务时应该遵循的指导和规则
WorkflowThe overall sequence/flow of the work整个工作的流程
StepOne individual stage/action within the workflowWorkflow 中的一个具体步骤

Why can’t we just write one sentence?- “Analyze the Excel file and generate a data quality report.”

This sentence is not wrong. But it does not specify:

What should happen first?
What should happen next?
What should be checked?
When should processing stop?
When should processing continue?
How should the result be validated?
What should the final output contain?

</> Markdown

## Instructions

Follow these steps:

### Step 1: Inspect the workbook

Identify:

- Workbook name
- Sheet names
- Number of rows
- Number of columns
- Column names

### Step 2: Profile the data

For each column:

- Determine data type
- Calculate null count
- Calculate distinct count
- Identify suspicious values

### Step 3: Check data quality

Check for:

- Missing values
- Duplicate records
- Invalid formats
- Inconsistent categorical values

### Step 4: Summarize findings

Rank issues by:

1. Severity
2. Business impact
3. Number of affected records

这就是:Agent 到底应该怎么执行这个 Skill。
这才是 SKILL.md 最核心的价值。它给出了 Agent 一个做事的步骤,第一步做什么,第二步做什么,接下来做什么,,,,,,

7.1 What should a good Step contain?

内容ENCN
Step 名称Step name这一步叫什么
目的Objective为什么做这一步
输入Input这一步需要什么
操作Actions这一步做什么
判断Conditions什么情况下怎么处理
输出Output这一步产生什么

The most important principle: Be specific, actionable, and verifiable. 具体、可操作、可检查。

7.2 Step granularity

Step 的粒度. 每一个 Step 都代表一个有意义的工作阶段

Each Step represents a meaningful phase of work.
A Step can contain substeps 里面可以有子步骤. e.g.

### Step 3 — Detect Data Quality Issues

Check the following categories:

1. Missing values
   - Calculate null count.
   - Calculate null percentage.

2. Duplicates
   - Detect duplicate rows.
   - Detect duplicate business keys when defined.

3. Data types
   - Compare actual types with expected types.

4. Invalid values
   - Check values against available business rules.

7.3 Steps can contain conditions

Step 可以有条件. e.g.

### Step 4 — Validate Findings

1. If a business rule is available:
   - Validate the data against the rule.

2. If no business rule is available:
   - Report the observed anomaly.
   - Do not assume that the anomaly is a business error.

3. If the evidence is insufficient:
   - Do not report a definitive violation.
   - Mark the finding as requiring confirmation.

因此好的 Step 可以包含:

  • If
  • When
  • Unless
  • Otherwise

这些条件。

8. Constraints

</>Markdown


## Constraints

- Do not modify the original Excel file.
- Do not delete records.
- Do not infer business meaning without evidence.
- Do not silently correct source data.
- Clearly distinguish facts from assumptions.

这个非常容易被忽略。它解决:Agent 什么不能做?

如果没有 Constraints,Agent 可能:发现拼写错误

直接修改

保存文件

但是 Skill 可以规定:”Do not modify the original file.”

于是:

Original file

Read only

Analyze

Report problems

这就是 Skill 的行为边界

9. Resources

假设我们还有一个 Python 工具:scripts/profile_excel.py

</> Markdown

## Resources

Use the following resources when needed:

- `scripts/profile_excel.py`
  - Use this script to profile Excel files.

- `references/data-quality-rules.md`
  - Contains standard data quality rules.

这时候 Skill 就不只是“文字”。Agent Skill 往往是一个目录(folder)

excel-skill/

├── SKILL.md

├── scripts/
│ └── profile_excel.py

├── references/
│ └── data-quality-rules.md

└── resources/
├── customer_schema.json
└── template.sql

SKILL.md 中对应的内容就是前面研究讨论的内容:

SKILL.md

├── Frontmatter
│ ├── name
│ └── description

├── Purpose (→ 这个 Skill 是干什么的)

├── When to Use (→ 什么情况下使用)

├── Capabilities (→ 它能做什么)

├── Instructions (→ Agent 应该怎么做)

├── Scripts (→ 可以调用哪些脚本)

├── References (→ 可以查哪些参考资料)

├── Resources (→ 可以使用哪些资源)

├── Output Format (→ 最终结果应该长什么样)

└── Examples (→ 给 Agent 看具体使用例子)

两层合起来

excel-skill/
│
├── SKILL.md
│   │
|   ├── Frontmatter
│       ├── name
│       └── description
|   |
│   ├── Purpose
│   ├── When to Use
│   ├── Capabilities
│   ├── Instructions
│   │
│   ├── Scripts
│   │      └──→ scripts/profile_excel.py
│   │
│   ├── References
│   │      └──→ references/data-quality-rules.md
│   │
│   ├── Resources
│   │      ├──→ resources/customer_schema.json
│   │      └──→ resources/template.sql
│   │
│   ├── Output Format
│   │
│   └── Examples
│
├── scripts/
│   └── profile_excel.py
│
├── references/
│   └── data-quality-rules.md
│
└── resources/
    ├── customer_schema.json
    └── template.sql

10. Output Format

接下来告诉 Agent:最终结果应该长什么样?e.g.

## Output Format

Return the analysis using the following structure:

### Executive Summary

Briefly summarize the overall data quality.

### Findings

| Issue | Severity | Affected Records | Recommendation |
|---|---|---:|---|

### Details

Explain each significant issue.

### Recommendations

Provide recommended next steps.

11. Examples

## Examples

### Example 1

User:

"Analyze customers.xlsx and find data quality issues."

Expected behavior:

1. Inspect workbook
2. Profile columns
3. Check missing values
4. Check duplicates
5. Check inconsistent values
6. Produce a structured report

A Complete SKILL.md Example

---
name: excel-data-analysis
description: Analyze Excel files, identify data quality issues, and produce structured findings and recommendations.
---

# Excel Data Analysis

## Purpose

This skill provides a structured workflow for analyzing Excel
workbooks, identifying data quality issues, and producing
business-oriented findings.

## When to Use

Use this skill when the user asks to:

- Analyze an Excel workbook
- Profile columns and data types
- Detect missing values
- Detect duplicate records
- Identify inconsistent values
- Produce data quality findings

Do not use this skill for:

- Creating presentations
- General spreadsheet formatting
- Writing Excel formulas without data analysis

## Capabilities

This skill can:

1. Inspect workbook structure
2. Profile columns
3. Detect missing values
4. Detect duplicate records
5. Detect inconsistent values
6. Generate a data quality summary

## Instructions

### Step 1: Inspect the workbook

Identify:

- Workbook name
- Sheet names
- Number of rows
- Number of columns
- Column names

### Step 2: Profile the data

For each column:

- Determine data type
- Calculate null count
- Calculate distinct count
- Identify suspicious values

### Step 3: Check data quality

Check for:

- Missing values
- Duplicate records
- Invalid formats
- Inconsistent categorical values

### Step 4: Analyze findings

Rank issues based on:

1. Severity
2. Business impact
3. Number of affected records

### Step 5: Produce the report

Generate the output using the required format.

## Constraints

- Do not modify the original Excel file.
- Do not delete records.
- Do not silently correct source data.
- Do not infer business meaning without evidence.
- Clearly distinguish facts from assumptions.

## Resources

Use the following resources when needed:

- `scripts/profile_excel.py`
  - Use this script to profile Excel files.

- `references/data-quality-rules.md`
  - Contains standard data quality rules.

## Output Format

### Executive Summary

Provide a concise summary of the overall data quality.

### Findings

| Issue | Severity | Affected Records | Recommendation |
|---|---|---:|---|

### Details

Explain significant findings and provide supporting evidence.

### Recommendations

Provide practical next steps.

## Examples

### Example 1

User:

"Analyze customers.xlsx and identify data quality issues."

Expected behavior:

1. Inspect the workbook.
2. Profile the columns.
3. Check missing values.
4. Check duplicates.
5. Check inconsistent values.
6. Rank the findings.
7. Produce the structured report.

Agent Capability Design

In AI Agent terms: Tool = a callable function (e.g., get_weatherrun_sql). Capability = a complete skill (e.g., “Data Quality Reporting”) that orchestrates tools, prompts, and logic to achieve a business outcome.
CN: 在AI Agent术语中:工具 = 一个可调用函数(如 get_weatherrun_sql)。能力 = 一项完整技能(如“数据质量报告”),它编排工具、提示词和逻辑来实现业务结果。

The Relationship 

  • A Capability uses Tools, not the other way around. 能力(Capability)使用工具(Tools),而不是反过来。
  • One Capability can use 0, 1, or many Tools.  一个能力可以使用0个、1个或多个工具。
  • The Capability defines the “what” and the “why”; the Tool defines the “how”. 能力定义“做什么”和“为什么做”;工具定义“怎么做”。
  • The Capability also includes a System Prompt (role), an output format, error handling, and retry logic – all invisible to the LLM’s top-level decision maker. 能力还包括系统提示词(角色)、输出格式、错误处理和重试逻辑——所有这些对LLM的顶层决策者都是不可见的。

SKILL.md Specification: File Structure & description

Step by Step Writing An Entitle Data Quality Skill

MCP ecosystems: Public MCP Server Directory

A “Public MCP Server Directory” is a centralized place where MCP server implementations are listed, categorized, and made discoverable by developers and AI agents. Think of it like npm for Node.js packages, or Hugging Face for ML models — but specifically for MCP servers.

CN: “公开MCP Server目录”是一个集中式的列表/注册中心,用于收录、分类和展示MCP服务器的实现,让开发者或AI Agent可以方便地发现和使用它们。你可以把它想象成:Node.js的npm仓库,或者Hugging Face的模型库——但专门为MCP服务器而生。

 Imagine you built a power adapter (your MCP server) that lets your AI assistant talk to a specific device (like a database or a GitHub repo). A public directory is like an online hardware store catalog — it lists all available adapters, tells you what each one does, who made it, and how to plug it in. Without this catalog, you’d have to stumble upon each adapter by word of mouth or random internet searches.

CN (人话比喻): 想象你做了一个电源适配器(你的MCP服务器),让AI助手能连接某个特定设备(比如数据库或GitHub)。公开目录就像一个在线五金店的商品目录——它列出所有可用的适配器,告诉你每个是干什么的、谁做的、怎么插上用。没有这个目录,你就只能靠口碑或随机搜索才能发现每个适配器。

There is a fundamental distribution problem in the MCP ecosystem. You can build the best MCP server in the world, but if nobody can find it, it might as well not exist. Directories solve this discovery problem. They are the bridge between server builders and server users.

CN: MCP生态中存在一个根本性的分发问题。你可以在世界上构建最好的MCP服务器,但如果没人能找到它,那就等于不存在。目录解决了这个发现(Discovery) 问题——它们是服务器构建者和使用者之间的桥梁。

What Are the Major Public MCP Server Directories?

The MCP directory ecosystem can be divided into several tiers. Here are the most important ones:

CN: MCP目录生态可以分为几个层级。以下是最重要的几个:


3.1 The Official Registry

官方注册中心

属性ENCN
NameModel Context Protocol Official RegistryMCP官方注册中心
URLregistry.modelcontextprotocol.ioregistry.modelcontextprotocol.io
Maintained byAnthropic / MCP Steering GroupAnthropic / MCP指导组
NatureSource of truth; canonical registry权威来源;规范注册中心

 This is the single most important directory. When AI clients like Claude Desktop, Cursor, and others look for verified servers, this is where the chain of trust starts. Getting listed here signals legitimacy.

CN: 这是最重要的一个目录。当Claude Desktop、Cursor等AI客户端寻找经过验证的服务器时,信任链就从这里开始。在这里被收录意味着合法性认证

3.2 Community-Curated “Awesome” Lists

社区精选“Awesome”列表

 These are GitHub repositories that curate MCP servers from across the ecosystem. They are less formal than the official registry but often more comprehensive and up-to-date.

CN: 这些是GitHub仓库,从整个生态系统中精选MCP服务器。它们不如官方注册中心正式,但通常更全面、更新更快。

名称EN DescriptionCN 说明Stars参考
punkpeye/awesome-mcp-serversCurated list of production-ready and experimental MCP servers精选的生产级和实验性MCP服务器列表高活跃度
wong2/awesome-mcp-serversCurated list with web submission at mcpservers.org精选列表,通过 mcpservers.org 提交活跃
tolkonepiu/best-of-mcp-serversRanked list of 400+ MCP servers, updated weekly400+ MCP服务器的排名列表,每周更新1.2M总Stars
yzfly/Awesome-MCP-ZHChinese-language MCP resource collection中文MCP资源合集中文社区

3.3 Third-Party Directories & Aggregators

第三方目录与聚合器

EN: These are dedicated platforms built specifically for MCP server discovery, often with additional features like CLI tools, installation automation, and search.

CN: 这些是专门为MCP服务器发现而构建的平台,通常带有CLI工具、安装自动化和搜索等额外功能。

名称URLEN DescriptionCN 说明
Smitherysmithery.aiActs as an npm registry for MCPs; 6,000+ servers相当于MCP的npm注册中心;6000+服务器
Glama.aiglama.ai/mcp/servers[reference:36]Web directory synced with GitHub与GitHub同步的网页目录
MCPubmcpub.devOpen, no-gatekeeper directory; itself an MCP server开放、无门槛的目录;本身就是一个MCP服务器
PulseMCPpulsemcp.com20,110+ servers updated daily20,110+服务器,每日更新
SkillHub MCP广场腾讯云Chinese-language MCP marketplace with 27+ curated servers中文MCP市场,收录27+精选服务器

3.4 Public Test Servers

公开测试服务器

EN: Some directories host publicly accessible MCP endpoints specifically for testing and development.

CN: 一些目录托管了公开可访问的MCP端点,专门用于测试和开发

EN (Examples from kite-mcp):

  • Echo Server (echo.mcp.inevitable.fyi/mcp): Returns request data back — useful for debugging
  • Time Server (time.mcp.inevitable.fyi/mcp): Time-related functionality
  • Everything Server (everything.mcp.inevitable.fyi/mcp): Multi-purpose test server

CN (来自kite-mcp的例子):

  • Echo Server (echo.mcp.inevitable.fyi/mcp): 返回请求数据——用于调试
  • Time Server (time.mcp.inevitable.fyi/mcp): 时间相关功能
  • Everything Server (everything.mcp.inevitable.fyi/mcp): 多功能测试服务器

How to Find and Evaluate MCP Servers

4.1 Finding Servers

查找服务器

EN:

  1. Start with the Official Registry (registry.modelcontextprotocol.io) — it’s the canonical source
  2. Browse curated lists like punkpeye/awesome-mcp-servers for community-vetted options
  3. Use aggregators like Smithery or Glama.ai for search and filtering
  4. Check Chinese-language resources like SkillHub MCP广场 if you prefer CN content

CN:

  1. 从官方注册中心开始registry.modelcontextprotocol.io)——它是权威来源
  2. 浏览精选列表,如 punkpeye/awesome-mcp-servers,获取社区筛选过的选项
  3. 使用聚合器,如Smithery或Glama.ai,进行搜索和筛选
  4. 查看中文资源,如SkillHub MCP广场

Key Takeaways

要点ENCN
官方注册中心是权威来源Official Registry (registry.modelcontextprotocol.io) is the source of truth官方注册中心(registry.modelcontextprotocol.io)是权威来源
社区精选列表更全面Community “awesome” lists are more comprehensive but less vetted社区“awesome”列表更全面但审核更少
Smithery是MCP的npmSmithery is like npm for MCP serversSmithery就像MCP服务器的npm
检查维护状态Always check maintenance status — 5 of 65 servers are abandoned始终检查维护状态——65个服务器中有5个已被放弃
目录本身也可以是MCP服务器Some directories (like MCPub) are themselves MCP servers有些目录(如MCPub)本身就是MCP服务器
发现机制正在标准化Discovery mechanisms (Server Cards, DNS, mcp:// URIs) are being standardized发现机制(Server Cards、DNS、mcp:// URI)正在标准化
GitHub和Playwright是最流行的厂商服务器GitHub (30.8k stars) and Playwright (34.1k stars) are the most popular vendor serversGitHub(30.8k星)和Playwright(34.1k星)是最流行的厂商服务器

Databricks MCP Server

A Databricks MCP Server is a Model Context Protocol server that exposes Databricks platform capabilities (Unity Catalog, SQL, Jobs, Clusters, etc.) as MCP tools that AI agents can dynamically discover and call.

CN: Databricks MCP Server 是一个 MCP 服务器,它将 Databricks 平台的能力(Unity Catalog、SQL、Jobs、Clusters 等)暴露为 MCP 工具,让 AI Agent 可以动态发现和调用这些工具。

Databricks provides three types of MCP servers:

CN: Databricks 提供三种类型的 MCP 服务器:

Type / 类型EN DescriptionCN 说明
Managed MCPPre-configured, ready-to-use servers for Vector Search, Genie spaces, SQL, and Unity Catalog functions预配置、开箱即用的服务器,用于 Vector Search、Genie spaces、SQL 和 Unity Catalog functions
External MCPSecurely connect to MCP servers hosted outside Databricks using managed connections使用托管连接安全地连接到 Databricks 外部托管的 MCP 服务器
Custom MCPHost your own custom MCP server as a Databricks App将自己的自定义 MCP 服务器托管为 Databricks App

2.1 Managed MCP Servers(托管 MCP 服务器)

EN: Databricks provides the following managed MCP servers that work out of the box:

CN: Databricks 提供以下开箱即用的托管 MCP 服务器:

ServerEN PurposeCN 用途URL Pattern
Vector SearchQuery Vector Search indexes to find relevant documents查询 Vector Search 索引查找相关文档https://<workspace>/api/2.0/mcp/vector-search/{catalog}/{schema}/{index_name}
Genie SpaceQuery Genie spaces to analyze structured data using natural language查询 Genie spaces 用自然语言分析结构化数据https://<workspace>/api/2.0/mcp/genie/{genie_space_id}
Databricks SQLRun AI-generated SQL to author data pipelines运行 AI 生成的 SQL 来编写数据管道https://<workspace>/api/2.0/mcp/sql
Unity Catalog FunctionsUse Unity Catalog functions to run predefined SQL queries使用 Unity Catalog functions 运行预定义的 SQL 查询https://<workspace>/api/2.0/mcp/functions/{catalog}/{schema}/{function_name}

2.2 Custom MCP Servers(自定义 MCP 服务器)

EN: You can host custom or third-party MCP servers as Databricks Apps. This is useful if you:

  • Already have an MCP server you want to deploy
  • Want to run a third-party MCP server as a tool source
  • Need custom business logic not covered by managed servers

CN: 你可以将自定义或第三方的 MCP 服务器托管为 Databricks Apps。 这在以下情况很有用:

  • 你已经有一个想部署的 MCP 服务器
  • 想运行一个第三方 MCP 服务器作为工具来源
  • 需要托管服务器未覆盖的自定义业务逻辑

Key Takeaways

要点ENCN
Databricks MCP Server 类型Three types: Managed, External, Custom三种类型:托管、外部、自定义
认证由 SDK 自动处理Authentication is auto-handled by Databricks SDK认证由 Databricks SDK 自动处理
Claude Desktop 配置文件位置 (macOS)~/Library/Application Support/Claude/claude_desktop_config.json~/Library/Application Support/Claude/claude_desktop_config.json
Claude Desktop 配置文件位置 (Windows)%APPDATA%\Claude\claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json
工具定义使用 @server.list_tools()Define tools with @server.list_tools()用 @server.list_tools() 定义工具
工具执行使用 @server.call_tool()Execute tools with @server.call_tool()用 @server.call_tool() 执行工具
Databricks SDK 核心客户端WorkspaceClient() for all Databricks operationsWorkspaceClient() 用于所有 Databricks 操作
不要硬编码工具名称Do not hardcode tool names — dynamically discover at runtime不要硬编码工具名称——运行时动态发现
让 LLM 决定调用哪个工具Let the LLM decide which tools to call让 LLM 决定调用哪个工具
使用 uvx 运行 MCP 服务器Use uvx to run MCP servers without global install使用 uvx 运行 MCP 服务器,无需全局安装

MCP testing locally: Claude Desktop Connection

Claude Desktop Connection is the process of configuring Anthropic’s Claude desktop application to communicate with local MCP (Model Context Protocol) servers via stdio (standard input/output) transport.

CN: Claude Desktop 连接是指将 Anthropic 的 Claude 桌面应用程序配置为通过 stdio(标准输入/输出)传输方式与本地 MCP(模型上下文协议)服务器通信的过程。

Prerequisites

ENCN
Claude Desktop installed (latest version)Claude Desktop 已安装(最新版本)
Node.js installed (for npx)Node.js 已安装(用于 npx)
Your MCP server code ready (Python/Node.js)你的 MCP 服务器代码已就绪(Python/Node.js)
Config file accessible配置文件可访问
Config File Locations
OSPathENCN
macOS~/Library/Application Support/Claude/claude_desktop_config.jsonUser Library folder用户资料库文件夹
Windows%APPDATA%\Claude\claude_desktop_config.jsonAppData Roaming folderAppData Roaming 文件夹
Linux~/.config/Claude/claude_desktop_config.jsonConfig directory配置目录

Configuration Structure

The config file uses a JSON object with a top-level mcpServers key. Each server is a nested object with:

  • command: The executable to run (e.g., "python""npx""node")
  • args: Array of arguments passed to the command
  • cwd (optional): Working directory for the server process
  • env (optional): Environment variables

CN: 配置文件使用一个带有顶层 mcpServers 键的 JSON 对象。每个服务器是一个嵌套对象,包含:

  • command: 要运行的可执行文件(如 "python""npx""node"
  • args: 传递给命令的参数数组
  • cwd(可选): 服务器进程的工作目录
  • env(可选): 环境变量

Three Common Config Patterns

Pattern 1 — Python Server
{
  "mcpServers": {
    "my-python-server": {
      "command": "python",
      "args": ["/path/to/your/mcp_server.py"],
      "cwd": "/path/to/your/project"
    }
  }
}
Pattern 2 — npx Server
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/username/Desktop"]
    }
  }
}
Pattern 3 — Remote Bridge
{
  "mcpServers": {
    "remote-server": {
      "command": "npx",
      "args": ["mcp-remote", "http://studio:3456/sse"]
    }
  }
}

Complete Setup & Testing

Step 1: Verify Prerequisites

# EN: Check Node.js installation / 检查 Node.js 安装
node --version
# EN: Should output v18+ / 应输出 v18+

# EN: Check npm installation / 检查 npm 安装
npm --version

# EN: Check Python installation (if using Python server) / 检查 Python 安装(如果用 Python 服务器)
python --version
# EN: Should output Python 3.11+ / 应输出 Python 3.11+

Step 2: Create/Edit Config File (Windows Example)

Bash
C:

CD C:\Users\chene\AppData\Roaming\Claude        # 如果没有建立一个

create a file, named: claude_desktop_config.json (content below)

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "C:\\Users\\yourusername\\Desktop",
        "C:\\Users\\yourusername\\Downloads"
      ]
    },
    "my-python-mcp": {
      "command": "python",
      "args": [
        "C:\\Users\\yourusername\\projects\\my-mcp-server\\mcp_server.py"
      ],
      "cwd": "C:\\Users\\yourusername\\projects\\my-mcp-server"
    }
  }
}

Create mcp server

according to my config file above, create a mcp_seerver.py at
 "C:\\Users\\yourusername\\projects\\my-mcp-server\\mcp_server.py"

#!/usr/bin/env python3
"""
EN: Complete MCP Server with proper handshake (initialize + tools/list + tools/call).
CN: 完整的 MCP 服务器,包含正确的握手(initialize + tools/list + tools/call)。
"""

import json
import sys


def main():
    """
    EN: Main loop: reads JSON-RPC lines from stdin, writes responses to stdout.
    CN: 主循环:从 stdin 读取 JSON-RPC 行,向 stdout 写入响应。
    """
    # EN: MCP uses stdio — keep reading line by line forever
    # CN: MCP 使用 stdio —— 永远逐行持续读取
    for line in sys.stdin:
        # EN: Remove trailing newline and skip empty lines
        # CN: 移除末尾换行符并跳过空行
        line = line.strip()
        if not line:
            continue

        try:
            # EN: Parse the incoming JSON-RPC request
            # CN: 解析传入的 JSON-RPC 请求
            request = json.loads(line)
            method = request.get("method")
            req_id = request.get("id")

            # ============================================================
            # EN: PART 1 — MCP Handshake (MUST handle "initialize")
            # CN: 第一部分 — MCP 握手(必须处理 "initialize")
            # ============================================================
            if method == "initialize":
                """
                EN: Respond to the initialize request with protocol version and capabilities.
                    Then immediately send the "initialized" notification.
                    This is REQUIRED for Claude Desktop to accept the connection.
                CN: 用协议版本和能力响应 initialize 请求。
                    然后立即发送 "initialized" 通知。
                    这是 Claude Desktop 接受连接所必需的。
                """
                # EN: Send the initialize response back to Claude Desktop
                # CN: 将 initialize 响应发送回 Claude Desktop
                response = {
                    "jsonrpc": "2.0",
                    "id": req_id,
                    "result": {
                        "protocolVersion": "2024-11-05",
                        "capabilities": {
                            "tools": {}  # EN: We support tools / CN: 我们支持工具
                        },
                        "serverInfo": {
                            "name": "my-python-mcp",
                            "version": "1.0.0"
                        }
                    }
                }
                sys.stdout.write(json.dumps(response) + "\n")
                sys.stdout.flush()

                # EN: Send the "initialized" notification (THIS IS CRITICAL)
                # CN: 发送 "initialized" 通知(这是关键)
                notification = {
                    "jsonrpc": "2.0",
                    "method": "notifications/initialized"
                }
                sys.stdout.write(json.dumps(notification) + "\n")
                sys.stdout.flush()

            # ============================================================
            # EN: PART 2 — List available tools
            # CN: 第二部分 — 列出可用工具
            # ============================================================
            elif method == "tools/list":
                """
                EN: Return the list of tools this server provides.
                CN: 返回此服务器提供的工具列表。
                """
                response = {
                    "jsonrpc": "2.0",
                    "id": req_id,
                    "result": {
                        "tools": [
                            {
                                "name": "hello",
                                "description": "Say hello to someone",
                                "inputSchema": {
                                    "type": "object",
                                    "properties": {
                                        "name": {
                                            "type": "string",
                                            "description": "Name to greet"
                                        }
                                    },
                                    "required": ["name"]
                                }
                            }
                        ]
                    }
                }
                sys.stdout.write(json.dumps(response) + "\n")
                sys.stdout.flush()

            # ============================================================
            # EN: PART 3 — Execute a tool
            # CN: 第三部分 — 执行工具
            # ============================================================
            elif method == "tools/call":
                """
                EN: Execute the requested tool with the given arguments.
                CN: 用给定的参数执行请求的工具。
                """
                params = request.get("params", {})
                tool_name = params.get("name")
                arguments = params.get("arguments", {})

                if tool_name == "hello":
                    name = arguments.get("name", "World")
                    result = {
                        "jsonrpc": "2.0",
                        "id": req_id,
                        "result": {
                            "content": [
                                {
                                    "type": "text",
                                    "text": f"Hello, {name}! 👋"
                                }
                            ]
                        }
                    }
                    sys.stdout.write(json.dumps(result) + "\n")
                    sys.stdout.flush()

        except json.JSONDecodeError as e:
            # EN: Handle invalid JSON gracefully
            # CN: 优雅地处理无效 JSON
            error_response = {
                "jsonrpc": "2.0",
                "id": None,
                "error": {
                    "code": -32700,
                    "message": f"Parse error: {e}"
                }
            }
            sys.stdout.write(json.dumps(error_response) + "\n")
            sys.stdout.flush()
        except Exception as e:
            # EN: Catch any other error to prevent the server from crashing silently
            # CN: 捕获任何其他错误,防止服务器静默崩溃
            error_response = {
                "jsonrpc": "2.0",
                "id": request.get("id") if 'request' in locals() else None,
                "error": {
                    "code": -32603,
                    "message": f"Internal error: {e}"
                }
            }
            sys.stdout.write(json.dumps(error_response) + "\n")
            sys.stdout.flush()


if __name__ == "__main__":
    main()

Step 3: Validate JSON

A trailing comma will silently break the configuration — Claude Desktop won’t show errors, tools just won’t appear.

CN: 尾随逗号会静默破坏配置——Claude Desktop 不会显示错误,工具就是出不来

Bash

c:
cd  C:\Users\chene\AppData\Roaming\Claude


# EN: Validate JSON using Python / 用 Python 验证 JSON
python -c "import json; json.load(open('claude_desktop_config.json'))"
# EN: No output means valid JSON / 无输出表示 JSON 有效

# EN: Or use online validator / 或使用在线验证器
# https://jsonlint.com/

Step 4: Restart Claude Desktop

 Critical: You must fully quit Claude Desktop and reopen it. A window reload or “Refresh” is NOT enough.

CN — 关键: 你必须完全退出 Claude Desktop 再重新打开。窗口刷新或”重新加载”是不够的

PlatformHow to fully quitENCN
macOSCmd + Q or right-click dock icon → QuitCommand+Q 或右键 Dock 图标→退出Command+Q 或右键 Dock 图标→退出
WindowsRight-click system tray → Exit右键系统托盘→退出右键系统托盘→退出

MCP Python SDK: @app.resource()

The @app.resource() decorator in MCP Python SDK marks a function as a resource provider—a function that returns data (text, JSON, binary) when the AI requests a specific URI.

CN: MCP Python SDK 中的 @app.resource() 装饰器,把一个函数标记为资源提供者——当 AI 请求某个特定 URI 时,这个函数返回数据(文本、JSON、二进制)。

The @app.resource() decorator registers a function as a resource handler. The function must return either a string, a types.TextContent, or a types.Resource object.

CN@app.resource() 装饰器把一个函数注册为资源处理器。函数必须返回字符串、types.TextContent 或 types.Resource 对象。

Code Implementation

# ============================================================
# MCP Server with @app.resource() and Error Handling
# 带 @app.resource() 和错误处理的 MCP 服务器
# ============================================================

import asyncio
import json
import logging
from typing import Optional, List, Dict, Any

# MCP SDK imports / MCP SDK 导入
from mcp.server.fastmcp import FastMCP
import mcp.types as types
from mcp.shared.exceptions import McpError

# Configure logging / 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# ============================================================
# 1. Create MCP Server instance / 创建 MCP 服务器实例
# ============================================================
# FastMCP is the high-level server class that handles all the protocol details
# FastMCP 是高层服务器类,处理所有协议细节
mcp = FastMCP(
    name="data-engineering-mcp-server",
    version="1.0.0",
    description="MCP Server for Data Engineering tasks"
)

# ============================================================
# 2. STATIC RESOURCE: Fixed URI, always returns same data
#    静态资源:固定 URI,始终返回相同数据
# ============================================================
# @mcp.resource() registers this function as a resource provider
# @mcp.resource() 把这个函数注册为资源提供者
# The URI "config://settings" is the address the AI uses to access this resource
# URI "config://settings" 是 AI 用来访问此资源的地址
@mcp.resource("config://settings")
async def get_config() -> str:
    """
    Returns static configuration settings for the AI.
    返回 AI 的静态配置设置。
    
    This is a simple static resource - it always returns the same JSON.
    这是一个简单的静态资源——它总是返回相同的 JSON。
    """
    # Return as a JSON string / 以 JSON 字符串返回
    return json.dumps({
        "max_rows_return": 1000,
        "default_database": "analytics_prod",
        "query_timeout_seconds": 30,
        "enable_cache": True
    }, indent=2)


# ============================================================
# 3. STATIC RESOURCE with TextContent (more control)
#    带 TextContent 的静态资源(更多控制)
# ============================================================
@mcp.resource("info://version")
async def get_version_info() -> types.TextContent:
    """
    Returns version information as TextContent with MIME type.
    以 TextContent 返回版本信息,带 MIME 类型。
    
    TextContent allows you to specify the MIME type of the response.
    TextContent 允许你指定响应的 MIME 类型。
    """
    return types.TextContent(
        type="text",
        text="MCP Data Engineering Server v1.0.0 (built 2026-07-25)",
        # MIME type tells the client how to interpret the content
        # MIME 类型告诉客户端如何解释内容
        mime_type="text/plain"
    )


# ============================================================
# 4. DYNAMIC RESOURCE (Resource Template) with parameter
#    动态资源(资源模板)带参数
# ============================================================
# URI template with {table_name} placeholder - the AI provides the actual value
# URI 模板带 {table_name} 占位符——AI 提供实际值
# Example: AI requests "schema://tables/orders" -> table_name = "orders"
# 例如:AI 请求 "schema://tables/orders" -> table_name = "orders"
@mcp.resource("schema://tables/{table_name}")
async def get_table_schema(table_name: str) -> str:
    """
    Returns the schema of a specific database table.
    返回特定数据库表的 schema。
    
    This is a dynamic resource - the result depends on the {table_name} parameter.
    这是一个动态资源——结果取决于 {table_name} 参数。
    
    Args:
        table_name: Name of the table to describe / 要描述的表名
    """
    # In production, this would query your database metadata
    # 在生产环境中,这会查询你的数据库元数据
    # For demo, we return mock schema data / 演示用,返回模拟 schema 数据
    
    # Simulate a database schema lookup / 模拟数据库 schema 查询
    mock_schemas: Dict[str, Dict[str, Any]] = {
        "orders": {
            "columns": [
                {"name": "order_id", "type": "BIGINT", "nullable": False},
                {"name": "customer_id", "type": "BIGINT", "nullable": False},
                {"name": "order_date", "type": "DATE", "nullable": False},
                {"name": "total_amount", "type": "DECIMAL(10,2)", "nullable": False},
                {"name": "status", "type": "VARCHAR(50)", "nullable": False},
            ],
            "primary_key": "order_id",
            "partitioned_by": "order_date"
        },
        "customers": {
            "columns": [
                {"name": "customer_id", "type": "BIGINT", "nullable": False},
                {"name": "customer_name", "type": "VARCHAR(200)", "nullable": False},
                {"name": "email", "type": "VARCHAR(255)", "nullable": True},
                {"name": "created_at", "type": "TIMESTAMP", "nullable": False},
            ],
            "primary_key": "customer_id"
        }
    }
    
    # ============================================================
    # ERROR HANDLING: Resource not found
    # 错误处理:资源未找到
    # ============================================================
    # If the requested table doesn't exist, raise an McpError
    # 如果请求的表不存在,抛出 McpError
    if table_name not in mock_schemas:
        # McpError is the standard MCP error type
        # McpError 是标准的 MCP 错误类型
        # -32002 is the standard error code for "Resource Not Found"[reference:28]
        # -32002 是 "资源未找到" 的标准错误码[reference:29]
        raise McpError(
            code=-32002,  # Resource Not Found / 资源未找到
            message=f"Table '{table_name}' not found in database schema. "
                    f"Available tables: {', '.join(mock_schemas.keys())}"
        )
    
    # Return the schema as formatted JSON / 以格式化的 JSON 返回 schema
    return json.dumps(mock_schemas[table_name], indent=2)


# ============================================================
# 5. DYNAMIC RESOURCE with multiple parameters
#    带多个参数的动态资源
# ============================================================
@mcp.resource("query://results/{query_id}/{format}")
async def get_query_results(query_id: str, format: str) -> str:
    """
    Returns cached query results in specified format.
    以指定格式返回缓存的查询结果。
    
    This demonstrates a resource with TWO parameters.
    这演示了带两个参数的资源。
    
    Args:
        query_id: The ID of the saved query / 保存的查询的 ID
        format: Output format: 'json' or 'csv' / 输出格式:'json' 或 'csv'
    """
    # In production, this would fetch from a cache or database
    # 在生产环境中,这会从缓存或数据库获取
    
    # Simulate query results / 模拟查询结果
    mock_results = [
        {"date": "2026-07-01", "revenue": 125000, "orders": 342},
        {"date": "2026-07-02", "revenue": 98000, "orders": 287},
        {"date": "2026-07-03", "revenue": 156000, "orders": 415},
    ]
    
    # ============================================================
    # ERROR HANDLING: Invalid parameter value
    # 错误处理:无效参数值
    # ============================================================
    if format not in ["json", "csv"]:
        # -32602 is "Invalid params" / -32602 是 "无效参数"
        raise McpError(
            code=-32602,
            message=f"Invalid format '{format}'. Supported formats: json, csv"
        )
    
    if format == "csv":
        # Convert to CSV format / 转换为 CSV 格式
        import csv
        from io import StringIO
        output = StringIO()
        writer = csv.DictWriter(output, fieldnames=mock_results[0].keys())
        writer.writeheader()
        writer.writerows(mock_results)
        return output.getvalue()
    
    # Default: JSON format / 默认:JSON 格式
    return json.dumps(mock_results, indent=2)


# ============================================================
# 6. RESOURCE with list of resources (for client discovery)
#    带资源列表的资源(用于客户端发现)
# ============================================================
# @mcp.list_resources() lets the client discover all available resources
# @mcp.list_resources() 让客户端发现所有可用的资源
# This is called automatically by the SDK, but you can customize it
# 这是由 SDK 自动调用的,但你可以自定义它
@mcp.list_resources()
async def list_resources() -> List[types.Resource]:
    """
    Returns the list of all resources this server provides.
    返回此服务器提供的所有资源的列表。
    
    The client calls this to discover what resources are available.
    客户端调用此方法来发现有哪些资源可用。
    """
    return [
        types.Resource(
            uri="config://settings",
            name="Configuration Settings",
            description="Server configuration settings",
            mimeType="application/json"
        ),
        types.Resource(
            uri="info://version",
            name="Version Information",
            description="Server version info",
            mimeType="text/plain"
        ),
        # Resource template - uses URI template notation
        # 资源模板 - 使用 URI 模板表示法
        types.Resource(
            uri="schema://tables/{table_name}",
            name="Table Schema",
            description="Schema of a specific database table",
            mimeType="application/json"
        ),
        types.Resource(
            uri="query://results/{query_id}/{format}",
            name="Query Results",
            description="Cached query results in JSON or CSV format",
            mimeType="application/json"
        ),
    ]


# ============================================================
# 7. TOOL with error handling (for comparison)
#    带错误处理的 TOOL(用于对比)
# ============================================================
@mcp.tool()
async def execute_sql_query(query: str, limit: Optional[int] = None) -> str:
    """
    Execute a SQL query and return results.
    执行 SQL 查询并返回结果。
    
    This is a TOOL (action) for comparison with RESOURCES (data).
    这是一个 TOOL(动作),用于与 RESOURCES(数据)对比。
    """
    # ============================================================
    # ERROR HANDLING: Tool-specific errors
    # 错误处理:Tool 特定的错误
    # ============================================================
    # Tools should also use McpError for consistent error handling[reference:30]
    # Tools 也应该使用 McpError 来实现一致的错误处理[reference:31]
    
    # Validate input / 验证输入
    if not query or len(query.strip()) == 0:
        raise McpError(
            code=-32602,  # Invalid params / 无效参数
            message="SQL query cannot be empty"
        )
    
    # Check for dangerous SQL (simple demo check)
    # 检查危险的 SQL(简单演示检查)
    dangerous_keywords = ["DROP", "TRUNCATE", "DELETE", "UPDATE", "ALTER"]
    upper_query = query.upper()
    for keyword in dangerous_keywords:
        if keyword in upper_query:
            raise McpError(
                code=-32603,  # Internal error / 内部错误
                message=f"Query contains dangerous keyword '{keyword}'. Only SELECT queries are allowed."
            )
    
    # Simulate query execution / 模拟查询执行
    # In production, this would connect to your database
    # 在生产环境中,这会连接你的数据库
    mock_result = {
        "query": query,
        "row_count": 42,
        "execution_time_ms": 125,
        "results": [
            {"id": 1, "value": "sample data 1"},
            {"id": 2, "value": "sample data 2"},
        ][:limit if limit else 2]
    }
    
    return json.dumps(mock_result, indent=2)


# ============================================================
# 8. GLOBAL ERROR HANDLER (optional but recommended)
#    全局错误处理器(可选但推荐)
# ============================================================
# You can wrap resource functions with a decorator for consistent error handling
# 你可以用装饰器包装资源函数,实现一致的错误处理
def handle_resource_errors(func):
    """
    Decorator that catches exceptions and converts them to McpError.
    装饰器,捕获异常并转换为 McpError。
    
    This ensures all resource errors are returned in the MCP standard format.
    这确保所有资源错误都以 MCP 标准格式返回。
    """
    async def wrapper(*args, **kwargs):
        try:
            return await func(*args, **kwargs)
        except McpError:
            # McpError is already in the correct format - re-raise
            # McpError 已经是正确格式 - 重新抛出
            raise
        except Exception as e:
            # Unexpected errors - convert to McpError with internal error code
            # 意外错误 - 转换为带内部错误码的 McpError
            logger.error(f"Unexpected error in resource {func.__name__}: {e}")
            raise McpError(
                code=-32603,  # Internal error / 内部错误
                message=f"An unexpected error occurred: {str(e)}"
            )
    return wrapper


# ============================================================
# 9. SERVER ENTRY POINT / 服务器入口点
# ============================================================
if __name__ == "__main__":
    # Run the server with stdio transport (for local communication)
    # 使用 stdio 传输运行服务器(用于本地通信)
    # This is the most common way to run MCP servers[reference:32]
    # 这是运行 MCP 服务器最常见的方式[reference:33]
    mcp.run(transport="stdio")

Key Takeaways

要点ENCN
@mcp.resource() 注册资源提供者@mcp.resource() registers a resource provider function@mcp.resource() 注册资源提供者函数
Resource = 只读数据(GET 模式)Resource = read-only data (GET model)Resource = 只读数据(GET 模式)
Tool = 有副作用的操作(POST 模式)Tool = action with side effects (POST model)Tool = 有副作用的操作(POST 模式)
URI 模板用 {参数} 实现动态资源URI templates use {param} for dynamic resourcesURI 模板用 {param} 实现动态资源
资源未找到用错误码 -32002Resource not found uses error code -32002资源未找到用错误码 -32002
所有 MCP 错误用 McpError 类Use McpError class for all MCP errors所有 MCP 错误用 McpError 类
不要向客户端暴露内部错误Don’t expose internal errors to clients不要向客户端暴露内部错误
错误后需清理资源Clean up resources after errors错误后需清理资源
用 try-catch 包装工具/资源调用Wrap tool/resource calls with try-catch用 try-catch 包装工具/资源调用
记录安全相关错误Log security-relevant errors记录安全相关错误

MCP Python SDK: @app.tool() decorator

@app.tool() is a Python decorator provided by the MCP Python SDK (specifically through FastMCP) that automatically registers a plain Python function as a remotely callable MCP tool. When you decorate a function with @app.tool(), the framework automatically extracts the function name, parameter types, and docstring to generate the protocol interface information, making the function available for LLMs to call via the MCP protocol.

CN: @app.tool() 是 MCP Python SDK(通过 FastMCP 提供)的一个 Python 装饰器,它会自动将一个普通的 Python 函数注册为一个可远程调用的 MCP 工具。当你用 @app.tool() 装饰一个函数时,框架会自动提取函数名、参数类型和文档字符串,生成协议接口信息,使该函数可以通过 MCP 协议被 LLM 调用。

Suppose you’re building an AI assistant for data engineering. You want the assistant to be able to run SQL queries on your data warehouse. Without @app.tool(), you’d have to write complex JSON-RPC handlers, manually parse incoming requests, validate parameters, execute the query, format the response, and handle errors. With @app.tool(), you just write:

假设你在为数据工程构建一个 AI 助手。你希望助手能对你的数据仓库执行 SQL 查询。没有 @app.tool(),你需要编写复杂的 JSON-RPC 处理器、手动解析传入请求、验证参数、执行查询、格式化响应并处理错误。有了 @app.tool(),你只需写:

@app.tool()
def run_sql_query(sql: str, database: str = "default") -> dict:
    """Execute a SQL query on the specified database and return results."""
    # Your SQL execution logic here
    return {"rows": [...], "row_count": 42}

The simplest form is decorating a synchronous function with @app.tool(). The framework uses the function name as the tool name, the docstring as the tool description, and the type hints as the input schema.

CN: 最简单的形式是用 @app.tool() 装饰一个同步函数。框架使用函数名作为工具名,docstring 作为工具描述,类型提示作为输入 schema。

Decorator parameter

装饰器参数

@app.tool() accepts several keyword arguments to customize the tool:

参数说明
name覆盖导出的 MCP 工具名称(默认使用函数名)
title客户端的简短显示标签
description人类可读的描述(省略时使用函数 docstring)
annotationsMCP 元数据的 ToolAnnotations 对象
icons客户端渲染用的图标
meta传递给 FastMCP 的任意元数据
structured_output设为 True 表示返回结构化 JSON

Code Implement

Envirment

# 安装 MCP Python SDK
pip install mcp httpx pydantic

MCP Server

# calculator_server.py
"""
A simple MCP Server that exposes calculator tools.
一个暴露计算器工具的简单 MCP Server。
"""

# 导入 FastMCP —— MCP Python SDK 的高层框架
# Import FastMCP - the high-level framework from MCP Python SDK
from mcp.server.fastmcp import FastMCP

# 创建 MCP 服务实例,命名服务标识
# Create MCP server instance with a service identifier
mcp = FastMCP("calculator_mcp")  # 服务名遵循 {service}_mcp 命名规范[reference:32]


# ============================================================
# 工具 1: 加法 —— 最基础的 @mcp.tool() 用法
# Tool 1: Addition - the most basic @mcp.tool() usage
# ============================================================
@mcp.tool()  # 装饰器自动将函数注册为 MCP 工具[reference:33]
def add(a: float, b: float) -> float:
    """
    Add two numbers together.
    将两个数相加。
    
    这个 docstring 会被自动提取为工具的 description,
    LLM 通过它理解工具的用途。[reference:34]
    """
    result = a + b
    return result  # 返回值会自动序列化为 JSON-RPC 响应[reference:35]


# ============================================================
# 工具 2: 带自定义名称和描述的加法
# Tool 2: Addition with custom name and description
# ============================================================
@mcp.tool(
    name="calculate_sum",           # 覆盖默认的函数名作为工具名[reference:36]
    description="Calculate the sum of two floating-point numbers",  # 覆盖 docstring
    annotations={"title": "Sum Calculator"}  # 客户端的显示标签[reference:37]
)
def add_with_custom_name(x: float, y: float) -> float:
    """This docstring is overridden by the description parameter above."""
    return x + y


# ============================================================
# 工具 3: 减法 —— 使用 Pydantic 模型做输入验证
# Tool 3: Subtraction - using Pydantic model for input validation
# ============================================================
from pydantic import BaseModel, Field

# 定义 Pydantic 输入模型 —— 自动生成输入 Schema[reference:38]
# Define Pydantic input model - auto-generates input schema
class SubtractInput(BaseModel):
    """Input model for subtraction operation."""
    a: float = Field(..., description="First number (minuend)", gt=-1e6, lt=1e6)
    b: float = Field(..., description="Second number (subtrahend)", gt=-1e6, lt=1e6)

@mcp.tool()
def subtract(input: SubtractInput) -> float:
    """
    Subtract two numbers: a - b.
    两个数相减:a - b。
    
    使用 Pydantic 模型作为输入参数,框架会自动:
    1. 生成 JSON Schema 描述输入格式
    2. 在调用时自动校验参数[reference:39]
    """
    return input.a - input.b


# ============================================================
# 工具 4: 乘法 —— 返回结构化输出
# Tool 4: Multiplication - with structured output
# ============================================================
from typing import Dict, Any

@mcp.tool(
    structured_output=True  # 提示返回的是结构化 JSON[reference:40]
)
def multiply(a: float, b: float) -> Dict[str, Any]:
    """
    Multiply two numbers and return detailed result.
    两个数相乘并返回详细结果。
    """
    product = a * b
    return {
        "operation": "multiply",
        "a": a,
        "b": b,
        "result": product,
        "formatted": f"{a} × {b} = {product}"
    }


# ============================================================
# 工具 5: 除法 —— 带错误处理
# Tool 5: Division - with error handling
# ============================================================
@mcp.tool()
def divide(a: float, b: float) -> Dict[str, Any]:
    """
    Divide a by b. Returns error if b is zero.
    a 除以 b。如果 b 为零则返回错误。
    """
    # 业务逻辑中的错误处理
    # Error handling in business logic
    if b == 0:
        return {
            "success": False,
            "error": "Division by zero is not allowed",
            "message": "除数不能为零"
        }
    
    result = a / b
    return {
        "success": True,
        "quotient": result,
        "remainder": a % b if b != 0 else None
    }


# ============================================================
# 工具 6: 异步工具 —— 调用外部 API
# Tool 6: Async tool - calling external API
# ============================================================
import httpx
from typing import Optional

@mcp.tool()  # 对于快速异步操作,可以用 @mcp.tool() + async
async def get_exchange_rate(
    from_currency: str,
    to_currency: str,
    amount: Optional[float] = 1.0
) -> Dict[str, Any]:
    """
    Get the exchange rate between two currencies.
    获取两种货币之间的汇率。
    
    异步函数可以直接 await 其他异步 API[reference:41]
    """
    # 实际生产环境应使用真实的汇率 API
    # In production, use a real exchange rate API
    url = f"https://api.exchangerate-api.com/v4/latest/{from_currency.upper()}"
    
    async with httpx.AsyncClient(timeout=10.0) as client:
        response = await client.get(url)
        response.raise_for_status()
        data = response.json()
    
    rate = data.get("rates", {}).get(to_currency.upper(), 0)
    converted = amount * rate
    
    return {
        "from": from_currency.upper(),
        "to": to_currency.upper(),
        "rate": rate,
        "amount": amount,
        "converted": converted
    }


# ============================================================
# 服务启动
# Service startup
# ============================================================
if __name__ == "__main__":
    # 启动 MCP 服务,默认使用 stdio 管道通信[reference:42]
    # Start MCP server, default uses stdio pipe communication
    mcp.run()

Key Takeaways

要点ENCN
@mcp.tool() 自动注册函数为 MCP 工具@mcp.tool() automatically registers a function as an MCP tool@mcp.tool() 自动将函数注册为 MCP 工具
函数名 → 工具名,docstring → 描述,类型提示 → 输入 SchemaFunction name → tool name, docstring → description, type hints → input schema函数名→工具名,docstring→描述,类型提示→输入 Schema
使用 Pydantic 模型实现自动输入验证Use Pydantic models for automatic input validation用 Pydantic 模型实现自动输入验证
structured_output=True 提示返回 JSONstructured_output=True hints the return is JSONstructured_output=True 提示返回 JSON
装饰器在导入时验证函数签名The decorator validates function signature at import time装饰器在导入时验证函数签名
同步工具用 @mcp.tool(),异步用 @mcp.tool() + asyncUse @mcp.tool() for sync, @mcp.tool() + async for async同步用 @mcp.tool(),异步用 @mcp.tool() + async
服务命名规范:{service}_mcpServer naming convention: {service}_mcp服务命名规范:{service}_mcp
启动服务:mcp.run()Start server: mcp.run()启动服务:mcp.run()

MCP Python SDK: Server initialization

MCP Python SDK Server initialization is the process of creating an MCP server instance, registering its capabilities (tools, resources, prompts), and starting it to listen for incoming connections from MCP clients (like Claude Desktop, Cursor, or custom clients).

CN: MCP Python SDK Server 初始化是创建 MCP 服务器实例、注册其能力(工具、资源、提示词),并启动服务器以监听来自 MCP 客户端(如 Claude Desktop、Cursor 或自定义客户端)连接的过程。

What Does Server Initialization Include

组件ENCN
安装与环境配置Install MCP SDK and set up Python environment安装 MCP SDK 并配置 Python 环境
创建 Server 实例Instantiate FastMCP or MCPServer class实例化 FastMCP 或 MCPServer 类
注册能力Register tools, resources, and prompts via decorators通过装饰器注册工具、资源和提示词
选择传输协议Choose transport: stdio (local) or HTTP/SSE (remote)选择传输协议:stdio(本地)或 HTTP/SSE(远程)
启动服务器Call .run() or use CLI to start the server调用 .run() 或使用 CLI 启动服务器

Code Implementation

Check “uv ” ststus

uv is an extremely fast Python package and project manager written in Rust. It replaces multiple tools — pippip-toolspipxpoetrypyenv, and virtualenv — with a single unified tool.

CN: uv 是一个用 Rust 编写的极速 Python 包和项目管理器。它用一个统一工具取代了 pippip-toolspipxpoetrypyenv 和 virtualenv 等多个工具。

Bash

uv --version

# if return:  "uv 0.8.12"  or likes this, that means your envirionment has installed "uv"

# if you see: 'uv' is not recognized as an internal or external command, 
# that means you have to install uv at first

Install uv (Windows)

PowerShell

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Environment Setup

bash

# EN: Create a new project with uv (recommended package manager)
# CN: 使用 uv 创建新项目(推荐的包管理器)
uv init my-mcp-server
cd my-mcp-server

# EN: Create and activate virtual environment
# CN: 创建并激活虚拟环境
uv venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# EN: Install MCP SDK (v1.x stable for production)
# CN: 安装 MCP SDK(生产环境使用 v1.x 稳定版)
uv add "mcp[cli]>=1.27,<2"


# EN: Or using pip
# CN: 或使用 pip
pip install "mcp[cli]>=1.27,<2"

# EN: Create server file
# CN: 创建服务器文件
touch server.py

Basic Server Initialization

# EN: server.py - Basic MCP Server Initialization
# CN: server.py - 基础 MCP Server 初始化

# EN: Import FastMCP - the high-level framework for building MCP servers
# CN: 导入 FastMCP - 用于构建 MCP 服务器的高级框架
# EN: FastMCP handles all protocol complexities (JSON-RPC, session management, etc.)
# CN: FastMCP 处理所有协议复杂性(JSON-RPC、会话管理等)
from mcp.server.fastmcp import FastMCP

# ============================================================
# EN: Step 1: Create the server instance
# CN: 步骤 1:创建服务器实例
# EN: FastMCP("name") creates a server with a descriptive name
# CN: FastMCP("name") 创建一个带有描述性名称的服务器
# EN: This name appears in client logs and helps identify your server
# CN: 此名称出现在客户端日志中,有助于识别你的服务器
# ============================================================
mcp = FastMCP("My First MCP Server")

# ============================================================
# EN: Step 2: Register a tool (function that LLM can call)
# CN: 步骤 2:注册工具(LLM 可以调用的函数)
# EN: @mcp.tool decorator automatically:
# CN: @mcp.tool 装饰器自动完成:
# EN:   - Uses function name as tool name
# CN:   - 使用函数名作为工具名
# EN:   - Uses docstring as tool description for LLM
# CN:   - 使用 docstring 作为给 LLM 的工具描述
# EN:   - Uses type hints to generate JSON schema for inputs
# CN:   - 使用类型提示生成输入的 JSON schema
# ============================================================
@mcp.tool
def add(a: int, b: int) -> int:
    """Add two integers together."""  # EN: This becomes the tool description
    return a + b                       # CN: 这成为工具的描述

# ============================================================
# EN: Step 3: Register a resource (read-only data for LLM)
# CN: 步骤 3:注册资源(LLM 可用的只读数据)
# EN: @mcp.resource(uri) exposes data at a specific URI
# CN: @mcp.resource(uri) 在特定 URI 下暴露数据
# ============================================================
@mcp.resource("resource://config")
def get_config() -> dict:
    """Provide application configuration to the LLM."""
    return {
        "app_name": "My MCP Server",
        "version": "1.0.0",
        "environment": "development"
    }

# ============================================================
# EN: Step 4: Register a prompt (pre-written template for users)
# CN: 步骤 4:注册提示词(为用户预写的模板)
# EN: Prompts help users accomplish specific tasks with guidance
# CN: 提示词帮助用户在指导下完成特定任务
# ============================================================
@mcp.prompt
def code_review(code: str) -> str:
    """Generate a code review prompt template."""
    return f"""
    Please review this code and provide feedback on:
    1. Code quality and readability
    2. Potential bugs or edge cases
    3. Performance considerations
    4. Security concerns
    
    Code:
    {code}
    """

# ============================================================
# EN: Step 5: Run the server
# CN: 步骤 5:运行服务器
# EN: The if __name__ == "__main__" block ensures the server runs
# CN: if __name__ == "__main__" 块确保服务器运行
# EN: when the file is executed directly (not when imported)
# CN: 当文件被直接执行时(而不是被导入时)
# EN: Default transport is "stdio" - works with Claude Desktop, Cursor, etc.
# CN: 默认传输协议是 "stdio" - 适用于 Claude Desktop、Cursor 等
# ============================================================
if __name__ == "__main__":
    # EN: mcp.run() starts the server and blocks until stopped
    # CN: mcp.run() 启动服务器并阻塞直到停止
    # EN: It handles all connection management for you
    # CN: 它为你处理所有连接管理
    mcp.run()

A2A Protocol (Agent-to-Agent)

A2A (Agent-to-Agent Protocol) is an open standard protocol designed to enable AI agents from different vendors, built with different frameworks, to communicate and collaborate with each other directly.

CN: A2A(Agent-to-Agent Protocol,智能体间协议)是一个开放标准协议,旨在让来自不同供应商、使用不同框架构建的 AI 智能体能够直接相互通信和协作。

Core Content of A2A

Core Actors

角色 (Role)ENCN
A2A Client (Client Agent)An application, service, or AI agent that initiates communication and delegates tasks to remote agents.发起通信并将任务委托给远程智能体的应用程序、服务或 AI 智能体。
A2A Server (Remote Agent)An AI agent that exposes an HTTP endpoint, receives requests, processes tasks, and returns results.暴露 HTTP 端点、接收请求、处理任务并返回结果的 AI 智能体。

Agent Card

A JSON metadata document, typically at /.well-known/agent.json, that describes an A2A Server.

CN: 一个 JSON 元数据文档,通常在 /.well-known/agent.json 路径,描述 A2A 服务器。

EN: It contains: agent identity (name, description), endpoint URL, version, supported capabilities (streaming, push notifications), skills offered, input/output modalities, and authentication requirements.

CN: 它包含:智能体身份(名称、描述)、端点 URL、版本、支持的能力(流式、推送通知)、提供的技能、输入/输出模态和认证要求。

EN: Think of it as an agent’s business card that tells other agents: “This is who I am, what I can do, and how to talk to me.”

CN: 把它想象成 智能体的名片,告诉其他智能体:”我是谁,我能做什么,以及如何与我对话。

Task

The unit of work in A2A. When a client delegates to an A2A agent, it sends a task containing the user request and context.

CN: A2A 中的工作单元。当客户端委托给 A2A 智能体时,它发送一个包含用户请求和上下文的任务。

EN: Each task has a unique ID and progresses through a lifecycle: submitted → working → input-required → completed → failed.

CN: 每个任务有唯一 ID,并通过生命周期推进:submitted → working → input-required → completed → failed

EN: Tasks are stateful and can involve multiple exchanges between client and server.

CN: 任务是 有状态的,可以涉及客户端和服务器之间的多次交换。

Message & Part

Message represents a single turn of communication. It has a role (“user” or “agent”) and contains one or more Parts.

CN: Message 代表单轮通信。它有 role(”user” 或 “agent”)并包含一个或多个 Part

EN: Part is the fundamental unit of content — can be TextPart (plain text) or FilePart (file, as base64 or URI).

CN: Part 是内容的基本单元——可以是 TextPart(纯文本)或 FilePart(文件,base64 或 URI)。

Context ID

Maintains session continuity across agent boundaries. When a user’s session spans multiple turns, the context ID links each delegated task to the same ongoing conversation.

CN: 跨智能体边界维持会话连续性。当用户的会话跨越多个轮次时,上下文 ID 将每个委托的任务与同一正在进行的对话相关联。

A2A vs MCP: Key Differences

This is the most important concept to understand. MCP and A2A are complementary, not competing.

CN: 这是最重要的概念。MCP 和 A2A 是互补的,不是竞争的。

维度 (Dimension)MCP (Model Context Protocol)A2A (Agent-to-Agent)
EN: PurposeConnects LLM to tools and data sourcesConnects agents to other agents
CN: 用途连接 LLM 到工具和数据源连接智能体到其他智能体
EN: DirectionAgent down to toolsAgent out to other agents
CN: 方向智能体 向下 连工具智能体 向外 连其他智能体
EN: ControlOrchestrator controls tool selection and result synthesisExternal agent uses its own reasoning; tools are opaque to orchestrator
CN: 控制编排器控制工具选择和结果合成外部智能体使用自己的推理;工具对编排器不透明
EN: Analogy“How an agent uses its hands and tools”“How agents talk to each other”
CN: 比喻“智能体如何使用手和工具”“智能体之间如何对话”

Key Takeaways

要点 (Point)ENCN
A2A 定义A2A is an open standard for agent-to-agent communicationA2A 是智能体间通信的开放标准
A2A vs MCPMCP = agent to tools; A2A = agent to agents (complementary)MCP = 智能体到工具;A2A = 智能体到智能体(互补)
核心组件Core components: Agent Card, Task, Message, Part, Context ID核心组件:智能体名片、任务、消息、部件、上下文 ID
Agent CardAgent Card is a JSON at /.well-known/agent.json describing agent capabilities智能体名片是 /.well-known/agent.json 的 JSON,描述智能体能力
Task 生命周期Task lifecycle: submitted → working → input-required → completed → failed任务生命周期:submitted → working → input-required → completed → failed
不透明性Remote agent is “opaque” — client doesn’t see its internal tools/logic远程智能体是”不透明的”——客户端看不到其内部工具/逻辑
传输协议A2A uses HTTP(S) with JSON-RPC 2.0A2A 使用 HTTP(S) + JSON-RPC 2.0
现实应用Many systems will use both MCP (inside agents) and A2A (between agents)许多系统会同时使用 MCP(智能体内)和 A2A(智能体间)