Skip to content

Support overriding tool annotations in aggregation config#4285

Open
jerm-dro wants to merge 4 commits intomainfrom
jd/annotation-overrides
Open

Support overriding tool annotations in aggregation config#4285
jerm-dro wants to merge 4 commits intomainfrom
jd/annotation-overrides

Conversation

@jerm-dro
Copy link
Contributor

Summary

  • MCP clients like Claude Desktop display annotations.title as the primary tool label, but vMCP aggregation config only supported overriding name and description. This meant overridden tools still showed the original backend's title (e.g., "List Channels" instead of "List Jira Projects").
  • Add ToolAnnotationsOverride struct with pointer fields (*string, *bool) so nil means "don't override" while zero values mean "explicitly set to this value." Wire annotation overrides through processBackendTools, manual conflict resolution, and the CRD-to-config converter.

Closes #4282

Type of change

  • New feature

Test plan

  • Unit tests (task test)

Changes

File Change
pkg/vmcp/config/config.go Add ToolAnnotationsOverride struct; add Annotations field to ToolOverride
cmd/thv-operator/api/v1alpha1/toolconfig_types.go Mirror CRD type for ToolAnnotationsOverride and ToolOverride.Annotations
pkg/vmcp/aggregator/tool_adapter.go Add applyAnnotationOverrides helper; apply in processBackendTools
pkg/vmcp/aggregator/manual_resolver.go Apply annotation overrides in resolveToolWithOverride
cmd/thv-operator/pkg/vmcpconfig/converter.go Propagate annotations through inline copy and CRD merge; add convertCRDAnnotationsOverride bridge
*/zz_generated.deepcopy.go Regenerated
deploy/charts/operator-crds/** Regenerated CRD manifests
*_test.go Tests for applyAnnotationOverrides, processBackendTools, manual resolver, converter merge, and CRD conversion

Does this introduce a user-facing change?

Yes. Users can now override tool annotation fields (title, readOnlyHint, destructiveHint, idempotentHint, openWorldHint) in vMCP aggregation config and MCPToolConfig CRDs. Example:

overrides:
  list_channels:
    name: list_slack_channels
    annotations:
      title: "List Slack Channels"
      readOnlyHint: true

Special notes for reviewers

  • All annotation override fields use pointers (*string, *bool) so nil = "don't override" and zero values = "explicitly set." This is important because annotations are optional in the MCP spec — a user may want to clear a title or set a hint to false.
  • ToolAnnotationsOverride is duplicated between pkg/vmcp/config and cmd/thv-operator/api/v1alpha1 because CRD types can't import config types (kubebuilder convention). A convertCRDAnnotationsOverride bridge handles the conversion, matching the existing Anti-Corruption Layer pattern.
  • applyAnnotationOverrides assigns *bool pointers directly (shared reference). Safe today since nothing mutates annotations post-construction, but worth noting.

Generated with Claude Code

MCP clients like Claude Desktop display annotations.title as the primary
tool label. Previously only name and description could be overridden in
vMCP aggregation config, so overridden tools still showed the original
backend's title.

Add ToolAnnotationsOverride with pointer fields (*string, *bool) so nil
means "don't override" while zero values mean "explicitly set." Wire
annotation overrides through processBackendTools, manual conflict
resolution, and the CRD-to-config converter.

Closes #4282

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added the size/L Large PR: 600-999 lines changed label Mar 19, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added size/L Large PR: 600-999 lines changed and removed size/L Large PR: 600-999 lines changed labels Mar 20, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added size/L Large PR: 600-999 lines changed and removed size/L Large PR: 600-999 lines changed labels Mar 20, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added size/L Large PR: 600-999 lines changed and removed size/L Large PR: 600-999 lines changed labels Mar 20, 2026
@codecov
Copy link

codecov bot commented Mar 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.09%. Comparing base (f52b6d0) to head (ffb3182).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4285      +/-   ##
==========================================
+ Coverage   68.54%   69.09%   +0.54%     
==========================================
  Files         471      471              
  Lines       47732    47683      -49     
==========================================
+ Hits        32717    32945     +228     
+ Misses      12247    12171      -76     
+ Partials     2768     2567     -201     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large PR: 600-999 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support overriding tool annotations (title) in aggregation config

1 participant