Mcp_testlab

Mcp_testlab

🚀 MCP测试平台

本项目展示了如何使用模型上下文协议(MCP)进行情感分析,它基于Hugging Face MCP课程开发。与Hugging Face课程中使用的gradio库不同,本项目使用fastmcp库来实现MCP服务器和客户端。

✨ 主要特性

架构图

+-------------------+                   +-------------------+
|                   |                   |                   |
|  mcp_client_stdio |<----------------->|                   |
|                   |      stdio        |                   |
+-------------------+                   |                   |
|                   |
+-------------------+                   |                   |
|                   |<----------------->|                   |
|  mcp_client_sse   |-----/sse--------->|   MCP Server      |
|                   |                   | (app_fastmcp.py)  |
+-------------------+                   |                   |
|                   |
+-------------------+                   |                   |
|                   |<----------------->|                   |
| mcp_client_stream-|----/mcp---------->|                   |
|    able.py        |                   |                   |
+-------------------+                   +-------------------+

每个客户端模块使用不同的传输协议与MCP服务器进行通信:

  • mcp_client_stdio.py 使用标准输入输出(stdio)
  • mcp_client_sse.py 使用服务器发送事件(SSE),路径为 /sse
  • mcp_client_streamable.py 使用可流式HTTP,路径为 /mcp

服务器

  • mcp-sentiment/app_fastmcp.py
    使用FastMCP实现MCP服务器。提供了一个sentiment_analysis工具,该工具使用TextBlob分析输入文本的情感,并以JSON格式返回极性、主观性和总体评估结果。

客户端

  • mcp-sentiment/mcp_client_stdio.py
    使用标准输入输出传输的MCP客户端。通过子进程连接到服务器,列出可用工具,并发送文本进行情感分析。使用argparse处理命令行参数。

  • mcp-sentiment/mcp_client_sse.py
    使用服务器发送事件(SSE)传输的MCP客户端。通过HTTP SSE端点连接到服务器,列出工具并发送文本进行分析。使用argparse处理命令行参数。

  • mcp-sentiment/mcp_client_streamable.py
    使用可流式HTTP传输的MCP客户端。通过HTTP双向流连接到服务器,列出工具并发送文本进行分析。使用argparse处理命令行参数。

测试

  • tests/test_sentiment_analysis.py
    情感分析工具的单元测试,检查各种输入情况和错误处理。

  • tests/test_client_stdio.py
    标准输入输出客户端的测试,包括请求处理的单元测试和端到端情感分析的集成测试。

  • tests/test_client_sse.py
    SSE客户端的集成测试,包括服务器进程管理和情感分析检查。

  • tests/test_client_streamable.py
    可流式HTTP客户端的集成测试,包括服务器进程管理和情感分析检查。

目录结构

mcp_testlab/
├── mcp-sentiment/
│   ├── app_fastmcp.py                # 暴露情感分析工具的MCP服务器
│   ├── mcp_client_stdio.py           # MCP客户端(标准输入输出传输)
│   ├── mcp_client_sse.py             # MCP客户端(SSE传输)
│   └── mcp_client_streamable.py      # MCP客户端(可流式HTTP传输)
├── tests/
│   ├── test_sentiment_analysis.py    # 情感分析工具的单元测试
│   ├── test_client_stdio.py          # 标准输入输出客户端的测试
│   ├── test_client_sse.py            # SSE客户端的测试
│   └── test_client_streamable.py     # 可流式HTTP客户端的测试
├── requirements.txt                  # Python依赖项
├── README.md                         # 项目文档和使用说明
├── LICENSE                           # 许可证文件
├── .gitignore                        # Git忽略规则
└── .gitattributes                    # Git LFS属性

🚀 快速开始

本应用程序使用模型上下文协议(MCP)来促进客户端和情感分析服务器之间的通信。当你使用文本字符串运行客户端时,它会执行以下操作:

  1. 连接到服务器脚本 (app_fastmcp.py) 或 sse/streamable-http 端点。
  2. 发送你的文本进行情感分析。
  3. 返回情感分析结果(积极、消极或中性)。

服务器 (app_fastmcp.py)

app_fastmcp.py 文件使用FastMCP实现了一个MCP服务器,该服务器:

  • 通过模型上下文协议暴露一个情感分析工具。
  • 使用TextBlob库分析提供的文本的情感。
  • 返回包含以下内容的JSON结果:
    • 极性得分(-1到1,从消极到积极)
    • 主观性得分(0到1,从客观到主观)
    • 总体评估(积极、消极或中性)
  • 支持 stdiossestreamable-http 传输与客户端进行通信。

客户端 (mcp_client_stdio.py)

mcp_client_stdio.py 文件实现了一个MCP客户端,该客户端:

  • 使用argparse库处理命令行参数。
  • 接受文本输入作为必需的位置参数。
  • 接受可选的 --server 参数来指定服务器脚本的路径。
  • 接受可选的 --verbose 标志来显示详细的工具信息。
  • 使用标准输入输出传输建立与MCP服务器的连接。
  • 列出连接服务器上的可用工具。
  • 将输入文本发送到 sentiment_analysis 工具。
  • 显示格式化的情感分析结果,包括极性、主观性和评估。
  • 使用异步上下文管理器和AsyncExitStack正确管理资源。

客户端 (mcp_client_sse.py)

mcp_client_sse.py 文件实现了一个MCP客户端,该客户端:

  • 使用argparse库处理命令行参数。
  • 接受文本输入作为必需的位置参数。
  • 接受可选的 --url 参数来指定服务器端点(默认:http://localhost:8000/sse)。
  • 接受可选的 --verbose 标志来显示详细的工具信息。
  • 使用SSE传输建立与MCP服务器的连接。
  • 列出连接服务器上的可用工具。
  • 将输入文本发送到 sentiment_analysis 工具。
  • 显示格式化的情感分析结果,包括极性、主观性和评估。
  • 使用异步上下文管理器和AsyncExitStack正确管理资源。

客户端 (mcp_client_streamable.py)

mcp_client_streamable.py 文件实现了一个MCP客户端,该客户端:

  • 使用argparse库处理命令行参数。
  • 接受文本输入作为必需的位置参数。
  • 接受可选的 --url 参数来指定服务器端点(默认:http://localhost:8000/mcp)。
  • 接受可选的 --verbose 标志来显示详细的工具信息。
  • 使用可流式HTTP传输建立与MCP服务器的连接。
  • 显示可用的会话ID。
  • 列出连接服务器上的可用工具。
  • 将输入文本发送到 sentiment_analysis 工具。
  • 显示格式化的情感分析结果,包括极性、主观性和评估。
  • 使用异步上下文管理器和AsyncExitStack正确管理资源。

💻 使用示例

标准输入输出传输的使用示例

命令行参数

((venv) ) Mac:jim mcp_testlab[529]$ python mcp-sentiment/mcp_client_stdio.py --help
usage: mcp_client_stdio.py [-h] [--server SERVER] [--verbose] text

MCP Client for sentiment analysis using stdio transport

positional arguments:
text             Text to analyze for sentiment

options:
-h, --help       show this help message and exit
--server SERVER  Path to the MCP server script (default: mcp-sentiment/app_fastmcp.py)
--verbose, -v    Display detailed information about available tools

客户端

((venv) ) Mac:jim mcp_testlab[512]$ python mcp-sentiment/mcp_client_stdio.py "i love  mcp"

Connected to MCP server at mcp-sentiment/app_fastmcp.py
Listing available tools...
[07/29/25 13:45:16] INFO     Processing request of type ListToolsRequest                                                             server.py:619

Connected to MCP server. Listing available tools...
INFO     Processing request of type ListToolsRequest                                                             server.py:619

Available tools: ['sentiment_analysis']

Analyzing sentiment for: 'i love  mcp'
INFO     Processing request of type CallToolRequest                                                              server.py:619
{'polarity': 0.5, 'subjectivity': 0.6, 'assessment': 'positive'}

Sentiment Analysis Result:
Polarity: 0.5 (-1=negative, 1=positive)
Subjectivity: 0.6 (0=objective, 1=subjective)
Assessment: positive

Sentiment Analysis Result: (0.5, 0.6, 'positive')
((venv) ) Mac:jim mcp_testlab[513]$ python mcp-sentiment/mcp_client_stdio.py "i hate java"

Connected to MCP server at mcp-sentiment/app_fastmcp.py
Listing available tools...
[07/29/25 13:45:38] INFO     Processing request of type ListToolsRequest                                                             server.py:619

Connected to MCP server. Listing available tools...
INFO     Processing request of type ListToolsRequest                                                             server.py:619

Available tools: ['sentiment_analysis']

Analyzing sentiment for: 'i hate java'
INFO     Processing request of type CallToolRequest                                                              server.py:619
{'polarity': -0.8, 'subjectivity': 0.9, 'assessment': 'negative'}

Sentiment Analysis Result:
Polarity: -0.8 (-1=negative, 1=positive)
Subjectivity: 0.9 (0=objective, 1=subjective)
Assessment: negative

Sentiment Analysis Result: (-0.8, 0.9, 'negative')

((venv) ) Mac:jim mcp_testlab[514]$ python mcp-sentiment/mcp_client_stdio.py "i really like python" -v

Connected to MCP server at mcp-sentiment/app_fastmcp.py
Listing available tools...
[07/29/25 13:46:35] INFO     Processing request of type ListToolsRequest                                                             server.py:619

Connected to MCP server. Listing available tools...
INFO     Processing request of type ListToolsRequest                                                             server.py:619

sentiment_analysis:
Description:
Analyze the sentiment of the given text.

Args:
text (str): The text to analyze

Returns:
str: A JSON string containing polarity, subjectivity, and assessment

Annotations: None
Inputschema: {'properties': {'text': {'title': 'Text', 'type': 'string'}}, 'required': ['text'], 'title': 'sentiment_analysisArguments', 'type': 'object'}
Meta: None
/Users/jim/Desktop/modelcontextprotocol/mcp_testlab/mcp-sentiment/mcp_client_stdio.py:154: PydanticDeprecatedSince211: Accessing the 'model_computed_fields' attribute on the instance is deprecated. Instead, you should access this attribute from the model class. Deprecated in Pydantic V2.11 to be removed in V3.0.
value = getattr(tool, attr)
Model_computed_fields: {}
Model_config: {'extra': 'allow'}
Model_extra: {}
/Users/jim/Desktop/modelcontextprotocol/mcp_testlab/mcp-sentiment/mcp_client_stdio.py:154: PydanticDeprecatedSince211: Accessing the 'model_fields' attribute on the instance is deprecated. Instead, you should access this attribute from the model class. Deprecated in Pydantic V2.11 to be removed in V3.0.
value = getattr(tool, attr)
Model_fields: {'name': FieldInfo(annotation=str, required=True), 'title': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'description': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'inputSchema': FieldInfo(annotation=dict[str, Any], required=True), 'outputSchema': FieldInfo(annotation=Union[dict[str, Any], NoneType], required=False, default=None), 'annotations': FieldInfo(annotation=Union[ToolAnnotations, NoneType], required=False, default=None), 'meta': FieldInfo(annotation=Union[dict[str, Any], NoneType], required=False, default=None, alias='_meta', alias_priority=2)}
Model_fields_set: {'description', 'inputSchema', 'outputSchema', 'name'}
Outputschema: {'properties': {'result': {'title': 'Result', 'type': 'string'}}, 'required': ['result'], 'title': 'sentiment_analysisOutput', 'type': 'object'}
Title: None

Analyzing sentiment for: 'i really like python'
INFO     Processing request of type CallToolRequest                                                              server.py:619
{'polarity': 0.2, 'subjectivity': 0.2, 'assessment': 'positive'}

Sentiment Analysis Result:
Polarity: 0.2 (-1=negative, 1=positive)
Subjectivity: 0.2 (0=objective, 1=subjective)
Assessment: positive

Sentiment Analysis Result: (0.2, 0.2, 'positive')

SSE传输的使用示例

命令行参数

((venv) ) Mac:jim mcp_testlab[532]$ python mcp-sentiment/mcp_client_sse.py --help
usage: mcp_client_sse.py [-h] [--url URL] [--verbose] text_to_test

MCP SSE Client for Sentiment Analysis

positional arguments:
text_to_test   Text to analyze for sentiment

options:
-h, --help     show this help message and exit
--url URL      URL of the SSE server endpoint (default: http://localhost:8000/sse)
--verbose, -v  Display detailed information about available tools

客户端

python mcp-sentiment/mcp_client_sse.py "i really like python"
Connecting to MCP server at http://localhost:8000/sse...

Connected to MCP server. Listing available tools...

Available tools: ['sentiment_analysis']

Analyzing sentiment for: 'i really like python'

Sentiment Analysis Result:
Polarity: 0.2 (-1=negative, 1=positive)
Subjectivity: 0.2 (0=objective, 1=subjective)
Assessment: positive

SSE服务器

((venv) ) Mac:jim mcp_testlab[506]$ python mcp-sentiment/app_fastmcp.py --transport sse
INFO:     Started server process [8908]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:49538 - "GET /sse HTTP/1.1" 200 OK
INFO:     127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted
[07/29/25 06:13:08] INFO     Processing request of type ListToolsRequest                                                                                                                           server.py:619
INFO:     127.0.0.1:49540 - "POST /messages/?session_id=fb1a89915f0b40e98f44385af5b6db58 HTTP/1.1" 202 Accepted
INFO     Processing request of type CallToolRequest                                                                                                                            server.py:619
INFO:     127.0.0.1:49543 - "GET /sse HTTP/1.1" 200 OK
INFO:     127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted
[07/29/25 06:13:46] INFO     Processing request of type ListToolsRequest                                                                                                                           server.py:619
INFO:     127.0.0.1:49545 - "POST /messages/?session_id=632a380ef69344eab4bf145158e05051 HTTP/1.1" 202 Accepted
INFO     Processing request of type CallToolRequest                                                                                                                            server.py:619
INFO:     127.0.0.1:49547 - "GET /sse HTTP/1.1" 200 OK
INFO:     127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted
[07/29/25 06:14:17] INFO     Processing request of type ListToolsRequest                                                                                                                           server.py:619
INFO:     127.0.0.1:49549 - "POST /messages/?session_id=f6a51e126c12412398bacc85753174a3 HTTP/1.1" 202 Accepted
INFO     Processing request of type CallToolRequest                                                                                                                            server.py:619
INFO:     Shutting down
INFO:     Waiting for application shutdown.
INFO:     Application shutdown complete.
INFO:     Finished server process [8908]
Terminated: 15             python mcp-sentiment/app_fastmcp.py --transport sse

可流式HTTP传输的使用示例

命令行参数

((venv) ) Mac:jim mcp_testlab[533]$ python mcp-sentiment/mcp_client_streamable.py --help
usage: mcp_client_streamable.py [-h] [--url URL] [--verbose] text_to_test

MCP Streamable Client for Sentiment Analysis

positional arguments:
text_to_test   Text to analyze for sentiment

options:
-h, --help     show this help message and exit
--url URL      URL of the streamable-http server endpoint (default: http://localhost:8000/mcp)
--verbose, -v  Display detailed information about available tools

客户端

# 使用默认URL
((venv) ) Mac:jim mcp_testlab[517]$ python mcp-sentiment/mcp_client_streamable.py "MCP is the best"
Connecting to MCP server at http://localhost:8000/mcp...
Session ID: fdc3c721f04441a1ae4c22cadebc9226

Connected to MCP server. Listing available tools...

Available tools: ['sentiment_analysis']

Analyzing sentiment for: 'MCP is the best'

Sentiment Analysis Result:
Polarity: 1.0 (-1=negative, 1=positive)
Subjectivity: 0.3 (0=objective, 1=subjective)
Assessment: positive

可流式HTTP服务器

((venv) ) Mac:jim mcp_testlab[507]$ python mcp-sentiment/app_fastmcp.py --transport streamable-http
INFO:     Started server process [2701]
INFO:     Waiting for application startup.
[07/28/25 22:48:20] INFO     StreamableHTTP session manager started                                                                                                               streamable_http_manager.py:112
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:54049 - "POST /mcp HTTP/1.1" 307 Temporary Redirect
[07/28/25 22:48:29] INFO     Created new transport with session ID: 6a17c2206e6e478b830bd0da73771b8b                                                                              streamable_http_manager.py:229
INFO:     127.0.0.1:54049 - "POST /mcp/ HTTP/1.1" 200 OK
INFO:     127.0.0.1:54052 - "POST /mcp HTTP/1.1" 307 Temporary Redirect
INFO:     127.0.0.1:54053 - "GET /mcp HTTP/1.1" 307 Temporary Redirect
INFO:     127.0.0.1:54052 - "POST /mcp/ HTTP/1.1" 202 Accepted
INFO:     127.0.0.1:54053 - "GET /mcp/ HTTP/1.1" 200 OK
INFO:     127.0.0.1:54055 - "POST /mcp HTTP/1.1" 307 Temporary Redirect
INFO:     127.0.0.1:54055 - "POST /mcp/ HTTP/1.1" 200 OK
INFO     Processing request of type ListToolsRequest                                                                                                                           server.py:619
INFO:     127.0.0.1:54057 - "POST /mcp HTTP/1.1" 307 Temporary Redirect
INFO:     127.0.0.1:54057 - "POST /mcp/ HTTP/1.1" 200 OK
INFO     Processing request of type CallToolRequest                                                                                                                            server.py:619
INFO:     127.0.0.1:54059 - "DELETE /mcp HTTP/1.1" 307 Temporary Redirect
INFO     Terminating session: 6a17c2206e6e478b830bd0da73771b8b                                                                                                        streamable_http.py:633
INFO:     127.0.0.1:54059 - "DELETE /mcp/ HTTP/1.1" 200 OK
INFO:     Shutting down
INFO:     Waiting for application shutdown.
[07/28/25 22:48:42] INFO     StreamableHTTP session manager shutting down                                                                                                         streamable_http_manager.py:116
INFO:     Application shutdown complete.
INFO:     Finished server process [2701]
Terminated: 15             python mcp-sentiment/app_fastmcp.py --transport streamable-http

🔧 单元测试

提供了单元测试以确保MCP服务器和客户端的功能正常。要运行测试,请使用以下命令:

$ pytest -v tests

示例输出:

MCP检查器

MCP检查器是一个用于探索和与模型上下文协议(MCP)服务器进行交互的工具。它提供了一个用户友好的界面,用于:

  • 发现可用的工具及其功能。
  • 向工具发送请求并查看响应。
  • 调试和测试MCP交互。

使用标准输入输出传输运行MCP检查器

要使用标准输入输出传输为服务器运行MCP检查器,请使用以下命令:

mcp dev mcp-sentiment/app_fastmcp.py

示例输出将显示可用的工具及其描述,允许你与情感分析工具进行交互。

MCP检查器列出工具

MCP检查器测试情感分析

使用SSE传输运行MCP检查器

启动用于测试的SSE服务器

python mcp-sentiment/app_fastmcp.py --transport sse

要使用SSE或可流式HTTP传输为服务器运行MCP检查器,请使用以下命令:

npx @modelcontextprotocol/inspector

连接到MCP检查器

打开浏览器访问MCP检查器界面,必要时将 http 更改为 https。MCP检查器运行后,为 ssestreamable-http 配置“传输类型”,并将服务器URL设置为指向正在运行的MCP服务器(例如,http://localhost:8000/ssehttp://localhost:8000/mcp),然后点击“连接”按钮。

SSE服务器URLhttp://localhost:8000/sse

📦 安装指南

  • Python 3.12+
  • 依赖项:pip install -r requirements.txt
  • 情感分析所需的NLP库
  • 运行MCP检查器需要 node 版本大于 v20.x(请参阅 GH Issue on unexpected token
  • 0 关注
  • 0 收藏,8 浏览
  • system 提出于 2025-09-28 14:18

相似服务问题