Skip to main content
Glama
MCP_SPEC_COMPLIANCE.md15.2 kB
# MCP 2025-11-25 Specification Compliance Improvements This document details the improvements made to bring the Entrez MCP Server into full compliance with the Model Context Protocol (MCP) specification version 2025-11-25. ## Summary of Changes ### 1. Enhanced Content Type Support **Status**: ✅ Completed Added full support for all MCP content types as defined in the specification: - **Text Content** (`TextContent`): Basic text with optional annotations - **Image Content** (`ImageContent`): Base64-encoded images with MIME type - **Audio Content** (`AudioContent`): Base64-encoded audio with MIME type - **Resource Links** (`ResourceLinkContent`): References to resources that can be fetched - **Embedded Resources** (`EmbeddedResourceContent`): Full resource content embedded in response **Implementation**: `src/tools/base.ts` lines 72-157 ```typescript // Example usage: protected textContent(text: string, annotations?: Annotations): TextContent protected imageContent(data: string, mimeType: string, annotations?: Annotations): ImageContent protected audioContent(data: string, mimeType: string, annotations?: Annotations): AudioContent protected resourceLink(uri: string, options?: {...}): ResourceLinkContent protected embeddedResource(uri: string, content: {...}, options?: {...}): EmbeddedResourceContent ``` ### 2. Content Annotations **Status**: ✅ Completed Implemented the `Annotations` interface per MCP spec to provide metadata about content: - `audience`: Array of "user" and/or "assistant" to indicate intended recipients - `priority`: Number between 0-1 indicating content importance - `lastModified`: ISO 8601 timestamp for resource modification tracking **Implementation**: `src/tools/base.ts` lines 78-82 ```typescript export interface Annotations { audience?: ("user" | "assistant")[]; priority?: number; // 0-1 scale lastModified?: string; // ISO 8601 timestamp } ``` **Usage Example**: ```typescript return this.textContent("Important message", { audience: ["user"], priority: 0.9 }); ``` ### 3. Tool Execution Error Handling **Status**: ✅ Completed Implemented proper error handling with the `isError` flag as required by the MCP spec: - **Protocol Errors**: Remain as thrown exceptions (e.g., invalid tool name, malformed requests) - **Tool Execution Errors**: Returned with `isError: true` flag (e.g., API failures, validation errors) **Implementation**: - `ToolResult` interface updated with `isError?: boolean` field - New `errorResult()` helper method for creating error responses **Example**: ```typescript try { // Tool logic return this.textResult("Success!"); } catch (error) { return this.errorResult( `Failed to perform operation: ${error.message}`, ["Suggestion 1", "Suggestion 2"] ); } ``` ### 4. Proper Input Schema for No-Parameter Tools **Status**: ✅ Completed for `ApiKeyStatusTool` Per MCP spec, tools with no parameters must use a valid JSON Schema object, not `null` or `{}`. **Before**: ```typescript this.registerTool("system_api_key_status", "...", {}, handler); ``` **After**: ```typescript this.registerTool("system_api_key_status", "...", this.emptySchema(), handler); ``` **Implementation**: `src/tools/base.ts` lines 340-345 The `emptySchema()` helper returns: ```typescript { type: "object", additionalProperties: false } ``` This explicitly accepts only empty objects `{}` per MCP spec recommendation. ### 5. Output Schema Support **Status**: ✅ Completed for `ApiKeyStatusTool` Added support for `outputSchema` to enable structured tool outputs with validation. **Benefits**: - Clients can validate tool responses - LLMs better understand expected output structure - Improved type safety and integration **Example**: ```typescript this.registerTool( "system_api_key_status", "Report NCBI API key status", this.emptySchema(), handler, { title: "NCBI API Key Status Reporter", outputSchema: { type: "object", properties: { hasKey: { type: "boolean", description: "..." }, rateLimit: { type: "string", description: "..." }, message: { type: "string", description: "..." } }, required: ["hasKey", "rateLimit", "message"] } } ); ``` ### 6. Tool Title Support **Status**: ✅ Completed for `ApiKeyStatusTool` Added optional `title` field for human-readable tool names. **Example**: - **Name**: `system_api_key_status` (identifier) - **Title**: "NCBI API Key Status Reporter" (display name) ### 7. Structured Content with Backwards Compatibility **Status**: ✅ Completed Updated `structuredResult()` to follow MCP spec requirement that tools returning structured content should provide both: 1. Human-readable text in `content` array 2. Machine-readable data in `structuredContent` field **Implementation**: `src/tools/base.ts` lines 283-306 ```typescript protected structuredResult( payload: Record<string, unknown>, summary?: string | string[], annotations?: Annotations, ): ToolResult { // Always include text for backwards compatibility const content = summary ? [...] : [JSON.stringify(payload, null, 2)]; return { content, structuredContent: { ...payload, success: true } }; } ``` ### 8. Tool Name Validation **Status**: ✅ Completed Added validation to ensure tool names comply with MCP spec requirements: - Length: 1-128 characters (inclusive) - Characters: Only A-Z, a-z, 0-9, _, -, . allowed - Case-sensitive **Implementation**: `src/tools/base.ts` lines 366-376 Throws error at registration time if tool name is invalid, preventing runtime issues. ### 9. Capabilities Declaration **Status**: ✅ Already Compliant Server properly declares the `tools` capability with `listChanged: true`: ```typescript capabilities: { tools: { listChanged: true } } ``` **Location**: `src/index.ts` lines 20-24 ## ✅ All Tools Updated! All tools have been successfully updated with MCP 2025-11-25 spec compliance: 1. **`EntrezQueryTool`** (`consolidated-entrez.ts`) ✅ - Added title: "NCBI Entrez E-utilities Gateway" - Added comprehensive `outputSchema` - Converted all validation errors to `errorResult()` returns - Provides actionable suggestions for every error case 2. **`DataManagerTool`** (`consolidated-data.ts`) ✅ - Added title: "NCBI Data Staging & SQL Query Manager" - Added comprehensive `outputSchema` for all operations - Converted all validation errors to `errorResult()` returns - Contextual help for fetch_and_stage, query, and schema operations 3. **`ExternalAPIsTool`** (`consolidated-external.ts`) ✅ - Added title: "External APIs Gateway (PubChem & PMC)" - Added comprehensive `outputSchema` - Refactored validation to return results instead of throwing - Service-specific error context (PubChem vs PMC) 4. **`CapabilitiesTool`** (`capabilities.ts`) ✅ - Added title: "Tool Capabilities Inspector" - Added comprehensive `outputSchema` for tool metadata - Converted error messages to `errorResult()` 5. **`ToolInfoTool`** (`tool-info.ts`) ✅ - Added title: "Tool Metadata Inspector" - Added comprehensive `outputSchema` for tool details - Converted error messages to `errorResult()` 6. **`ApiKeyStatusTool`** (`api-key-status.ts`) ✅ - Already completed as reference implementation ### Error Handling Migration Pattern **Current Pattern (throws exception)**: ```typescript if (!ids) { throw new Error("IDs parameter cannot be empty"); } ``` **Should be (returns error result)**: ```typescript if (!ids) { return this.errorResult( "IDs parameter cannot be empty", ["Provide comma-separated UIDs", "Example: ids: '12345,67890'"] ); } ``` ### Validation Errors All validation errors (found via `validateDatabase()`, `validateRettype()`, `validateIds()`) should return error results instead of throwing exceptions: ```typescript const dbValidation = validateDatabase(database); if (!dbValidation.isValid) { return this.errorResult( dbValidation.error!, dbValidation.suggestions ); } ``` ## Testing Recommendations ### 1. Test Content Types Create test cases for: - Text content with and without annotations - Resource links - Structured responses with `structuredContent` ### 2. Test Error Handling Verify: - Tool execution errors return `isError: true` - Error messages are actionable and helpful - Additional context is provided when available ### 3. Test Tool Registration Verify: - Invalid tool names are rejected - Empty schemas work correctly - Output schemas are properly declared ### 4. Test Backwards Compatibility Ensure: - Existing clients continue to work - Structured responses include text content - Error handling doesn't break existing integrations ## MCP Spec Compliance Checklist - [x] **Capabilities Declaration**: Server declares `tools.listChanged: true` - [x] **Tool Names**: Valid characters (A-Z, a-z, 0-9, _, -, .), 1-128 chars - [x] **Input Schema**: All tools have valid JSON Schema (not null) - [x] **Empty Parameter Tools**: Use `{ type: "object", additionalProperties: false }` - [x] **Content Types**: Support text, image, audio, resource_link, resource - [x] **Annotations**: Support audience, priority, lastModified - [x] **Error Handling**: Use `isError: true` for tool execution errors - [x] **Structured Content**: Provide both text and structuredContent - [x] **Output Schema**: Tools returning structured data declare outputSchema - [x] **Tool Titles**: Human-readable titles provided where appropriate - [x] **Protocol Version**: Server reports "2025-11-25" version - [x] **All Tools Updated**: All 6 tools migrated to new error handling pattern ✅ ## Benefits of These Improvements 1. **Better LLM Integration**: LLMs can better understand tool outputs through structured schemas 2. **Improved Error Recovery**: Models can self-correct using tool execution errors 3. **Enhanced Debugging**: Clearer distinction between protocol and execution errors 4. **Future-Proof**: Full compliance with latest MCP specification 5. **Type Safety**: Output schemas enable validation and stronger typing 6. **Better UX**: Annotations help clients prioritize and route content appropriately ## Migration Guide for Developers ### For Tool Implementers 1. **Use `emptySchema()` for no-parameter tools**: ```typescript this.registerTool("tool_name", "description", this.emptySchema(), handler); ``` 2. **Add title and outputSchema**: ```typescript this.registerTool("tool_name", "description", schema, handler, { title: "Human Readable Name", outputSchema: { /* JSON Schema */ } }); ``` 3. **Return error results instead of throwing**: ```typescript return this.errorResult("Error message", ["Suggestion 1", "Suggestion 2"]); ``` 4. **Use annotations for important content**: ```typescript return this.textContent("Critical info", { audience: ["user"], priority: 1.0 }); ``` 5. **Provide structured results with text**: ```typescript return this.structuredResult( { data: "value" }, "Human-readable summary" ); ``` ### For Client Integrators 1. **Handle `isError` flag**: Check `result.isError` to distinguish errors 2. **Validate structured content**: Use `outputSchema` to validate responses 3. **Respect annotations**: Use `audience` and `priority` for content routing 4. **Parse structured content**: Access `result.structuredContent` for machine-readable data ## References - [MCP Specification 2025-11-25 - Tools](https://modelcontextprotocol.io/specification/2025-11-25/server/tools) - [MCP Specification - Resources](https://modelcontextprotocol.io/specification/2025-11-25/server/resources) - [JSON Schema Usage Guidelines](https://modelcontextprotocol.io/specification/2025-11-25/basic#json-schema-usage) ## Changelog ### 2025-12-02 - Phase 1: Core Infrastructure - ✅ Added all MCP content types (text, image, audio, resource_link, resource) - ✅ Implemented Annotations interface - ✅ Added `isError` flag support for tool execution errors - ✅ Created `errorResult()` helper method - ✅ Added `emptySchema()` helper for no-parameter tools - ✅ Enhanced `registerTool()` to support title, outputSchema, annotations - ✅ Added tool name validation per MCP spec - ✅ Updated `structuredResult()` for backwards compatibility - ✅ Updated `ApiKeyStatusTool` as reference implementation - ✅ Added comprehensive TypeScript types for all content types ### 2025-12-02 - Phase 2: Complete Tool Migration - ✅ **EntrezQueryTool**: Full error handling migration, title & outputSchema - Converted all 15+ error throw statements to `errorResult()` returns - Validation errors provide actionable suggestions - Operation-specific contextual help in catch block - ✅ **DataManagerTool**: Full error handling migration, title & outputSchema - All validation errors return `errorResult()` with examples - Contextual help for all four operations (fetch_and_stage, query, schema, list_datasets) - Comprehensive outputSchema covering all operation types - ✅ **ExternalAPIsTool**: Refactored validation, title & outputSchema - Converted `validateServiceOperation()` from throwing to returning validation result - Service-specific error context (PubChem vs PMC tips) - Proper error handling for both services - ✅ **CapabilitiesTool**: Updated with title, outputSchema, errorResult - Comprehensive outputSchema for tool metadata arrays - Proper error handling for tool not found scenarios - ✅ **ToolInfoTool**: Updated with title, outputSchema, errorResult - Detailed outputSchema for individual tool metadata - Improved error messages with actionable suggestions - ✅ **Build & Tests**: All changes verified - TypeScript compilation: ✅ PASS - Build process: ✅ PASS (2429.18 KiB total) - No breaking changes to existing functionality ### 2025-12-02 - Phase 3: SDK Update & registerTool Fix - ✅ **SDK Update**: Upgraded from previous version to @modelcontextprotocol/sdk 1.24.0 - Updated package.json and package-lock.json - Build size increased to 3715.22 KiB (expected with newer SDK features) - ✅ **Breaking Change Fix**: Adapted to SDK 1.24.0 changes - Fixed: `Implementation` interface no longer has `description` field - Changed server initialization to use `title` instead of `description` - Location: `src/index.ts` server instantiation - ✅ **registerTool() Implementation Fix**: Corrected tool registration method - Previously: Used `server.tool()` which doesn't support title/outputSchema - Fixed: Now uses `server.registerTool()` with config object - Verified: Tested registerTool() with title and outputSchema - works correctly - Location: `src/tools/base.ts` lines 353-412 - ✅ **Final Verification**: - TypeScript compilation: ✅ PASS (no errors) - Build process: ✅ PASS (3715.22 KiB with SDK 1.24.0) - IDE diagnostics: ✅ No issues - registerTool() functionality: ✅ Tested and confirmed working

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/QuentinCody/entrez-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server