An MCP server implementation using Spring AI framework providing tools for date/time queries, email operations, and product management via database interactions
This SpringAI MCP server exhibits significant quality gaps across naming, descriptions, and parameter documentation. While 10 tools are defined with basic schemas, the definitions lack the clarity and structure required for reliable LLM agent interaction. Tool names are inconsistent in verb usage (getCurrentTimeByZoneId vs getCurrentTime vs getMyEmailAddress), descriptions are terse and often in Chinese without English translations, and critical parameter documentation is minimal. Parameter schemas exist but descriptions are often single words or phrases lacking the context LLMs need to understand constraints, dependencies, and expected formats. No output schemas are documented, no error recovery guidance is provided, and destructive operations (deleteProduct) lack confirmation patterns. The codebase uses spring-ai-starter-mcp-server-webflux, indicating WebFlux/HTTP transport, but the transport type is listed as 'UNKNOWN' in the metadata.
Tool descriptions entirely in Chinese; no English translations provided. Prevents tool usage by English-speaking LLM agents and violates accessibility and internationalization standards.
No output schemas documented. Agents cannot predict return structure, forcing them to guess at response fields and inviting type mismatches and failed downstream tool calls.
Translate ALL tool descriptions and parameter descriptions to English. Chinese-only documentation is not accessible to English LLM agents. Provide English as the primary language and optionally include Chinese as a secondary translation.
Document output schemas for every tool. Specify the structure of return values: for getCurrentTime, return {timestamp: string, timezone: string, format: 'ISO-8601'}. For queryProductListByCondition, return {products: [{id, name, price, ...}], total: number, limit: number, offset: number}.
Expand parameter descriptions to 50 - 150 characters. Instead of 'City name', write 'The city name in English (e.g., New York, Tokyo). Used to determine timezone; required if zoneId is not provided.'
Replace magic numeric enums (status: 0/1/2) with proper JSON Schema enums and symbolic names. E.g. 'status' should be enum: ['unlisted', 'active', 'presale'] instead of numeric codes.
Remove internal enum-conversion tools (getSortEnum, getPriceCompareEnum) from the agent interface. Instead, queryProductListByCondition should accept natural-language sort directions ('ascending', 'descending') and comparison operators ('greater_than', 'less_than'), convert internally.
Add pagination support to queryProductListByCondition: include limit (default 20, max 100) and offset parameters. Document in description: 'Returns paginated list; default limit is 20 items. Use offset parameter to fetch subsequent pages.'
Document idempotency for data-modifying tools. E.g. 'createNewProduct is idempotent: calling twice with identical inputs and a unique external_reference_id returns the same product, no duplicate.'
Parameter descriptions are minimal or absent (single words like 'City name', 'Timezone ID'). LLMs cannot infer expected format, valid ranges, or constraints. No guidance on mutually exclusive parameters or dependencies.
deleteProduct is a destructive operation with no confirmation pattern, dry-run option, or recovery guidance. Agents can permanently delete products with no safeguards.
Internal enum conversion tools (getSortEnum, getPriceCompareEnum) are exposed in the agent interface. This leaks implementation details and forces agents to call conversion utilities before querying, adding unnecessary steps and error surface.
Magic values for status enum (0=下架, 1=上架, 2=预售) are documented in parameter descriptions rather than as JSON Schema enums. LLMs cannot reliably select correct numeric values and must parse Chinese descriptions.
No pagination guidance for queryProductListByCondition. Large result sets will exhaust context windows; no documentation of result limits, cursors, or offset/limit parameters.
Idempotency not documented. Tools like createNewProduct and modifyProduct do not state whether repeated calls with identical inputs produce duplicates or are safely idempotent.
Tool names inconsistent: some use verb_noun convention (getCurrentTime, sendMailMessage) while others are verbose (queryProductListByCondition) or vague (getSortEnum). No clear naming pattern for agent discoverability.
Add error recovery guidance. E.g. sendMailMessage should document: 'Returns status: success|invalid_email|rate_limited. If rate_limited, retry after 60 seconds. If invalid_email, verify recipient address and try again.'
Add a dry-run or confirmation step for deleteProduct. Offer a second parameter: confirm_delete: boolean (default false). When false, return 'This will delete product {id}. Call again with confirm_delete=true to proceed.' When true, execute deletion.
Add parameter dependencies in descriptions. E.g. 'cityName and zoneId are mutually exclusive, provide one or the other, not both. If both provided, zoneId takes precedence.'
Validate parameter constraints and document them. E.g. 'price must be a positive integer (0 < price <= 999999). stock must be non-negative integer (0 <= stock <= 999999).'
For sendMailMessage, clarify the contentType enum. Instead of magic value 1/2, use 'contentType: enum ["markdown", "html"]'. Document: 'markdown: message will be converted to HTML before sending. html: message sent as-is.'
Provide batch variants where agents call tools in loops. E.g. add a createProductsBatch tool that accepts an array of products, returns array of results with per-product success/failure, and is more token-efficient than N sequential calls.