Skip to content

Fix: Preserve tool annotations in MCP protocol responses#29

Merged
MaestroError merged 7 commits intomainfrom
copilot/fix-missing-annotations
Nov 10, 2025
Merged

Fix: Preserve tool annotations in MCP protocol responses#29
MaestroError merged 7 commits intomainfrom
copilot/fix-missing-annotations

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 5, 2025

✅ Task Complete: MCP Tool Annotations Support

All acceptance criteria have been met and the implementation is fully tested.

Implementation Summary

  • Core Implementation: Updated tool_converter.py to transfer all annotations from MCI to MCP
  • Unit Tests: Added 7 comprehensive unit tests (all passing)
  • Feature Tests: Added integration test for MCP server annotations (passing)
  • Manual Tests: Created 2 manual verification scripts (both passing)
  • Documentation: Updated README.md with comprehensive annotations guide
  • Code Review: Addressed all feedback
  • Security: CodeQL scan passed with 0 alerts
  • Quality: All 323 tests passing, linting clean
Original prompt

This section details on the original issue you should resolve

<issue_title>MCP server: Missing tool annotations in MCP protocol responses</issue_title>
<issue_description>## Problem
When running MCP servers via our CLI, tools exposed by the server do not include the annotations field (such as title, readOnlyHint, etc.) even when these fields exist in the original MCI schema file. The MCP tool objects returned in protocol responses always have annotations = {} (empty), which also means consumers lose metadata like the human-readable title, behavioral hints, and other information required for proper tool UX and filtering.

At this point, when we use Lite MCP client to fetch MCP tools, we are writing annotations to MCI schema file, but when we run our MCP server with "uvx mcix run" command, annotations lost

Example (from docs, for reference only):

{
  "name": "delete_resource",
  "annotations": {
    "title": "Delete Resource",
    "readOnlyHint": false,
    "destructiveHint": true,
    "idempotentHint": false,
    "openWorldHint": true
  },
  "description": "Delete a resource from the remote server",
  ...
}

The above fields (especially title and usage hints) should be preserved and present in tools served via MCP protocol. Currently, they are always empty in MCP output.

Acceptance Criteria

  • The MCP server correctly includes all annotations from the original MCI tool object in protocol responses, including title, readOnlyHint, destructiveHint, idempotentHint, and openWorldHint.
  • All MCP tool definitions exposed over the protocol match their annotations field as given in the MCI schema, as shown in the example above ("it is just reference, real implementation is up to you").
  • Add unit tests and feature tests verifying that annotations are present in the MCP tool object and correctly transferred.
  • Document the change and verify the README.md instructions mention correct annotation propagation (in project documentation, note what annotations are supported and that they will appear in MCP tools).

Deliverables

  • Bug fix implementation ensuring annotations are included in MCP server tool responses
  • Update affected files (see PLAN.md for guidelines):
    • Tool conversion logic: likely in src/mci/core/tool_converter.py
    • MCP server construction/integration: likely in src/mci/core/mcp_server.py or related dynamic server files
    • Tests: add/modify tests in tests/unit/core/test_tool_converter.py, tests/unit/core/test_mcp_server.py, and any integration tests
    • Documentation update: confirm/update annotation documentation in README.md

Project Docs/README.md Update:

  • Document supported annotation fields (title, readOnlyHint, etc.) in MCP tool responses if not already documented
  • Add note to users that annotation fields will be present in all tools served by MCP server for correct filtering and UX

Note

Examples from docs are for reference only; real implementation logic is up to you.


If further investigation reveals other code locations that handle tool conversion from MCI to MCP (not listed above), update those files accordingly.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 5 commits November 5, 2025 00:31
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix missing tool annotations in MCP protocol responses Fix: Preserve tool annotations in MCP protocol responses Nov 5, 2025
Copilot AI requested a review from MaestroError November 5, 2025 00:44
@MaestroError MaestroError requested a review from Copilot November 6, 2025 17:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for MCI tool annotations in MCP servers. The implementation enables MCP servers to preserve and serve annotation metadata (title, readOnlyHint, destructiveHint, idempotentHint, openWorldHint) from MCI tool definitions, allowing MCP clients to make better decisions about tool usage.

  • Adds convert_annotations() method to transfer annotation metadata from MCI to MCP format
  • Updates convert_to_mcp_tool() to include annotations in MCP Tool objects
  • Provides comprehensive test coverage including unit tests, feature tests, and manual tests
  • Documents the annotation feature with examples in README.md
  • Fixes spelling errors in README.md

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/mci/core/tool_converter.py Adds convert_annotations() method and updates convert_to_mcp_tool() to transfer annotations from MCI to MCP format
src/mci/core/mcp_server.py Formatting update only - no functional change
tests/unit/core/test_tool_converter.py Adds comprehensive unit tests for annotation conversion including full, partial, and missing annotations
tests/test_mcp_server_creation.py Adds feature test verifying annotations are preserved through server creation workflow
testsManual/test_annotations_in_mcp.py Adds manual test demonstrating end-to-end annotation transfer with visual output
testsManual/test_mcp_server_annotations.py Adds detailed manual test for verifying annotation presence in MCP server responses
README.md Documents annotation feature with examples and fixes spelling errors (authentification→authentication, orginize→organize, mantioned→mentioned)
mci.json Adds "weather-tools" to toolsets array

}

# Create temporary schema file
import tempfile
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tempfile import should be moved to the top of the file with other imports (line 9-16) to follow Python's import organization conventions. Standard library imports should be grouped together at the top, not imported inline.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ba7b096. Moved tempfile import to top of file along with other standard library imports.

return False
finally:
# Clean up temporary file
import pathlib
Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pathlib import should be moved to the top of the file with other imports (line 9-16) instead of being imported inline. This follows Python's import organization conventions and improves code readability.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ba7b096. Moved pathlib import to top of file along with other standard library imports.

Comment on lines +29 to +30
schema_path = os.path.join(project_root, "mci/example_toolset.mci.json")

Copy link

Copilot AI Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to 'schema_path' is unnecessary as it is redefined before this value is used.

Suggested change
schema_path = os.path.join(project_root, "mci/example_toolset.mci.json")

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ba7b096. Removed the unnecessary schema_path assignment that was being overwritten before use.

Copy link
Copy Markdown
Contributor

@MaestroError MaestroError left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Check review comments

return False
finally:
# Clean up temporary file
import pathlib
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix

}

# Create temporary schema file
import tempfile
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix

Comment on lines +29 to +30
schema_path = os.path.join(project_root, "mci/example_toolset.mci.json")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix

Co-authored-by: MaestroError <46760939+MaestroError@users.noreply.github.com>
Copilot AI requested a review from MaestroError November 6, 2025 20:43
@MaestroError MaestroError marked this pull request as ready for review November 10, 2025 17:06
@MaestroError MaestroError merged commit 41f17a8 into main Nov 10, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP server: Missing tool annotations in MCP protocol responses

3 participants