A multi-transport MCP server providing news search, sentiment analysis, and email capabilities, with multiple example implementations including FastMCP and official MCP SDK variants
This server exhibits significant quality gaps across naming, descriptions, and schemas. Tool definitions are present but lack rigor. Multiple tools share identical names (add, substract, multiply, divide appear twice each), creating registration chaos. Descriptions are present but often minimal (10-30 chars) and fail to explain WHEN to use tools or what their side effects are. Schemas are basic, input parameters have type and description, but output schemas are undocumented. The server mixes concerns: search_google_news both searches AND writes files; analyze_sentiment calls external APIs AND writes markdown; send_email_with_attachment manages file paths AND sends mail. Three tools (in client.py) are inferred from code analysis rather than explicit tool registration, capping their scores at 50. Error handling is minimal, most tools return generic strings rather than structured error guidance. Security concerns: analyze_sentiment and send_email_with_attachment expose file paths and rely on environment variables without validation; no permission gating or audit trails.
Add two numbers together.
Add two numbers together.
对传入文本进行情感分析,把结果保存到指定名称的md文件。
Divide the first number by the second number.
Divide the first number by the second number.
Multiply two numbers together.
Multiply two numbers together.
Duplicate tool names across files: 'add', 'substract', 'multiply', 'divide' appear in both fastmcp_sse_server.py and fastmcp_stdio_server.py. This creates registration ambiguity and prevents simultaneous operation of both server implementations. Tool registration will silently overwrite earlier definitions.
Misspelled tool name 'substract' should be 'subtract'. This forces LLMs to learn a non-standard spelling and increases hallucination risk when agents generate tool calls.
Tool descriptions are too brief (10 - 35 chars) and do not explain WHEN to use each tool or what side effects occur. For example, 'search_google_news' description (in Chinese) is '使用 Serper API 根据关键词搜素新闻' (~40 chars), lacks info about pagination, output format, or that results are written to disk. Baseline: descriptions should be 50 - 200 chars for LLM decision-making.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 59 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 39 | - | v1 |
使用 Serper API 根据关键词搜素新闻。
发送带有附件的邮件。
Subtract the second number from the first number.
Subtract the second number from the first number.
Output schemas are undocumented for all tools. LLMs cannot plan downstream calls without knowing the shape of returned data. For example, search_google_news returns a JSON string with 'title', 'desc', 'url' fields, but this structure is not declared in the schema.
Multiple concerns bundled into single tools: search_google_news searches AND writes JSON files to disk; analyze_sentiment calls an LLM API AND writes markdown files; send_email_with_attachment manages file paths AND sends mail. This violates the single-responsibility principle and makes tools harder to test and compose. Pattern: tool should do exactly one thing.
Error handling returns unstructured strings (e.g., 'User not found. Try search_users() with a partial name.') rather than structured errors with categorization (retryable vs. fatal). When analyze_sentiment's file_path construction fails, it returns '附件文件不存在。' (bare message) instead of guiding the agent to call analyze_sentiment again or verify file_name. No error classification per pattern:error-classification.
Security: send_email_with_attachment constructs file paths via os.path.join('./sentiment_report', file_name) with no sanitization. A user-provided file_name like '../../../etc/passwd' will traverse directories. This is a path-traversal vulnerability. Input validation required: pattern:tool-gateway.
Environment variables (SERPER_API_KEY, OPENAI_API_KEY, SMTP_SERVER, SENDER_PASS) are read but never validated for presence/format before use. Missing SERPER_API_KEY raises ValueError 'SERPER_API_KEY环境变量 not found', but missing OPENAI_API_KEY or BASE_URL silently fails later when OpenAI client is instantiated. Add upfront validation on server startup.
Tools in client.py (analyze_sentiment, send_email_with_attachment) are not explicitly registered via @mcp.tool() decorator visible in the source, they are inferred from the MCPClient class. Recommend moving all tool definitions to server-side files (server.py, fastmcp_sse_server.py) with explicit @mcp.tool() registration.
Parameters lack validation constraints. For example, send_email_with_attachment's 'to' parameter accepts any string with no email format check; analyze_sentiment's 'file_name' parameter has no length, character, or path restriction. Per pattern:constrained-input, add regex patterns, min/max lengths, and enum constraints where applicable. Baseline: validated params reduce LLM errors by ~40%.