Skip to content

Commit ac21335

Browse files
feat: support for annotations (#2007)
## Description The MCP spec supports tool annotations like the below structure in the 2025-06-18 version of the spec. https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations ``` { destructiveHint?: boolean; idempotentHint?: boolean; openWorldHint?: boolean; readOnlyHint?: boolean; } ``` Added a ToolAnnotations structure, an Annotations member to the McpManifest structure, and a nil initializer for the Annotations member to all calls to GetMcpManifest. The ToolAnnotations structure and the member annotations are all defined as pointers so that they are omited when not set. There are times when the zero value is meaningful so this was the only way to make sure that we distinguish between not setting the annotation and setting it with a zero value. ## PR Checklist > Thank you for opening a Pull Request! Before submitting your PR, there are a > few things you can do to make sure it goes smoothly: - [x] Make sure you reviewed [CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md) - [x] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/genai-toolbox/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [x] Appropriate docs were updated (if necessary) - [x] Make sure to add `!` if this involve a breaking change 🛠️ Fixes #927 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 9234790 commit ac21335

167 files changed

Lines changed: 498 additions & 342 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎internal/prebuiltconfigs/tools/looker-conversational-analytics.yaml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ tools:
2828
ask_data_insights:
2929
kind: looker-conversational-analytics
3030
source: looker-source
31+
annotations:
32+
readOnlyHint: true
3133
description: |
3234
Use this tool to perform data analysis, get insights,
3335
or answer complex questions about the contents of specific
@@ -36,6 +38,8 @@ tools:
3638
get_models:
3739
kind: looker-get-models
3840
source: looker-source
41+
annotations:
42+
readOnlyHint: true
3943
description: |
4044
The get_models tool retrieves the list of LookML models in the Looker system.
4145
@@ -44,6 +48,8 @@ tools:
4448
get_explores:
4549
kind: looker-get-explores
4650
source: looker-source
51+
annotations:
52+
readOnlyHint: true
4753
description: |
4854
The get_explores tool retrieves the list of explores defined in a LookML model
4955
in the Looker system.

‎internal/prebuiltconfigs/tools/looker.yaml‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ tools:
2929
get_models:
3030
kind: looker-get-models
3131
source: looker-source
32+
annotations:
33+
readOnlyHint: true
3234
description: |
3335
The get_models tool retrieves the list of LookML models in the Looker system.
3436
@@ -37,6 +39,8 @@ tools:
3739
get_explores:
3840
kind: looker-get-explores
3941
source: looker-source
42+
annotations:
43+
readOnlyHint: true
4044
description: |
4145
The get_explores tool retrieves the list of explores defined in a LookML model
4246
in the Looker system.
@@ -46,6 +50,8 @@ tools:
4650
get_dimensions:
4751
kind: looker-get-dimensions
4852
source: looker-source
53+
annotations:
54+
readOnlyHint: true
4955
description: |
5056
The get_dimensions tool retrieves the list of dimensions defined in
5157
an explore.
@@ -61,6 +67,8 @@ tools:
6167
get_measures:
6268
kind: looker-get-measures
6369
source: looker-source
70+
annotations:
71+
readOnlyHint: true
6472
description: |
6573
The get_measures tool retrieves the list of measures defined in
6674
an explore.
@@ -76,6 +84,8 @@ tools:
7684
get_filters:
7785
kind: looker-get-filters
7886
source: looker-source
87+
annotations:
88+
readOnlyHint: true
7989
description: |
8090
The get_filters tool retrieves the list of filters defined in
8191
an explore.
@@ -86,6 +96,8 @@ tools:
8696
get_parameters:
8797
kind: looker-get-parameters
8898
source: looker-source
99+
annotations:
100+
readOnlyHint: true
89101
description: |
90102
The get_parameters tool retrieves the list of parameters defined in
91103
an explore.
@@ -96,6 +108,8 @@ tools:
96108
query:
97109
kind: looker-query
98110
source: looker-source
111+
annotations:
112+
readOnlyHint: true
99113
description: |
100114
Query Tool
101115
@@ -136,6 +150,8 @@ tools:
136150
query_sql:
137151
kind: looker-query-sql
138152
source: looker-source
153+
annotations:
154+
readOnlyHint: true
139155
description: |
140156
Query SQL Tool
141157
@@ -148,6 +164,8 @@ tools:
148164
query_url:
149165
kind: looker-query-url
150166
source: looker-source
167+
annotations:
168+
readOnlyHint: true
151169
description: |
152170
Query URL Tool
153171
@@ -598,6 +616,8 @@ tools:
598616
get_looks:
599617
kind: looker-get-looks
600618
source: looker-source
619+
annotations:
620+
readOnlyHint: true
601621
description: |
602622
get_looks Tool
603623
@@ -618,6 +638,8 @@ tools:
618638
run_look:
619639
kind: looker-run-look
620640
source: looker-source
641+
annotations:
642+
readOnlyHint: true
621643
description: |
622644
run_look Tool
623645
@@ -628,6 +650,8 @@ tools:
628650
make_look:
629651
kind: looker-make-look
630652
source: looker-source
653+
annotations:
654+
readOnlyHint: false
631655
description: |
632656
make_look Tool
633657
@@ -647,6 +671,8 @@ tools:
647671
get_dashboards:
648672
kind: looker-get-dashboards
649673
source: looker-source
674+
annotations:
675+
readOnlyHint: true
650676
description: |
651677
get_dashboards Tool
652678
@@ -666,6 +692,8 @@ tools:
666692
run_dashboard:
667693
kind: looker-run-dashboard
668694
source: looker-source
695+
annotations:
696+
readOnlyHint: true
669697
description: |
670698
run_dashboard Tool
671699
@@ -676,6 +704,8 @@ tools:
676704
make_dashboard:
677705
kind: looker-make-dashboard
678706
source: looker-source
707+
annotations:
708+
readOnlyHint: false
679709
description: |
680710
make_dashboard Tool
681711
@@ -693,6 +723,8 @@ tools:
693723
add_dashboard_element:
694724
kind: looker-add-dashboard-element
695725
source: looker-source
726+
annotations:
727+
readOnlyHint: false
696728
description: |
697729
add_dashboard_element Tool
698730
@@ -710,6 +742,8 @@ tools:
710742
health_pulse:
711743
kind: looker-health-pulse
712744
source: looker-source
745+
annotations:
746+
readOnlyHint: true
713747
description: |
714748
health-pulse Tool
715749
@@ -729,6 +763,8 @@ tools:
729763
health_analyze:
730764
kind: looker-health-analyze
731765
source: looker-source
766+
annotations:
767+
readOnlyHint: true
732768
description: |
733769
health-analyze Tool
734770
@@ -745,6 +781,8 @@ tools:
745781
health_vacuum:
746782
kind: looker-health-vacuum
747783
source: looker-source
784+
annotations:
785+
readOnlyHint: true
748786
description: |
749787
health-vacuum Tool
750788
@@ -764,6 +802,8 @@ tools:
764802
dev_mode:
765803
kind: looker-dev-mode
766804
source: looker-source
805+
annotations:
806+
readOnlyHint: true
767807
description: |
768808
dev_mode Tool
769809
@@ -773,6 +813,8 @@ tools:
773813
get_projects:
774814
kind: looker-get-projects
775815
source: looker-source
816+
annotations:
817+
readOnlyHint: true
776818
description: |
777819
get_projects Tool
778820
@@ -782,6 +824,8 @@ tools:
782824
get_project_files:
783825
kind: looker-get-project-files
784826
source: looker-source
827+
annotations:
828+
readOnlyHint: true
785829
description: |
786830
get_project_files Tool
787831
@@ -791,6 +835,8 @@ tools:
791835
get_project_file:
792836
kind: looker-get-project-file
793837
source: looker-source
838+
annotations:
839+
readOnlyHint: true
794840
description: |
795841
get_project_file Tool
796842
@@ -800,6 +846,8 @@ tools:
800846
create_project_file:
801847
kind: looker-create-project-file
802848
source: looker-source
849+
annotations:
850+
readOnlyHint: false
803851
description: |
804852
create_project_file Tool
805853
@@ -812,6 +860,9 @@ tools:
812860
update_project_file:
813861
kind: looker-update-project-file
814862
source: looker-source
863+
annotations:
864+
destructiveHint: true
865+
readOnlyHint: false
815866
description: |
816867
update_project_file Tool
817868
@@ -824,6 +875,9 @@ tools:
824875
delete_project_file:
825876
kind: looker-delete-project-file
826877
source: looker-source
878+
annotations:
879+
destructiveHint: true
880+
readOnlyHint: false
827881
description: |
828882
delete_project_file Tool
829883
@@ -836,6 +890,8 @@ tools:
836890
get_connections:
837891
kind: looker-get-connections
838892
source: looker-source
893+
annotations:
894+
readOnlyHint: true
839895
description: |
840896
get_connections Tool
841897
@@ -846,6 +902,8 @@ tools:
846902
get_connection_schemas:
847903
kind: looker-get-connection-schemas
848904
source: looker-source
905+
annotations:
906+
readOnlyHint: true
849907
description: |
850908
get_connection_schemas Tool
851909
@@ -855,6 +913,8 @@ tools:
855913
get_connection_databases:
856914
kind: looker-get-connection-databases
857915
source: looker-source
916+
annotations:
917+
readOnlyHint: true
858918
description: |
859919
get_connection_databases Tool
860920
@@ -864,6 +924,8 @@ tools:
864924
get_connection_tables:
865925
kind: looker-get-connection-tables
866926
source: looker-source
927+
annotations:
928+
readOnlyHint: true
867929
description: |
868930
get_connection_tables Tool
869931
@@ -873,6 +935,8 @@ tools:
873935
get_connection_table_columns:
874936
kind: looker-get-connection-table-columns
875937
source: looker-source
938+
annotations:
939+
readOnlyHint: true
876940
description: |
877941
get_connection_table_columns Tool
878942

‎internal/server/mcp/v20241105/method.go‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,15 @@ func toolsListHandler(id jsonrpc.RequestId, toolset tools.Toolset, body []byte)
6565
return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err
6666
}
6767

68+
// exclude annotations from this version
69+
manifests := make([]tools.McpManifest, len(toolset.McpManifest))
70+
for i, m := range toolset.McpManifest {
71+
m.Annotations = nil
72+
manifests[i] = m
73+
}
74+
6875
result := ListToolsResult{
69-
Tools: toolset.McpManifest,
76+
Tools: manifests,
7077
}
7178
return jsonrpc.JSONRPCResponse{
7279
Jsonrpc: jsonrpc.JSONRPC_VERSION,

‎internal/server/mcp/v20250326/method.go‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,15 @@ func toolsListHandler(id jsonrpc.RequestId, toolset tools.Toolset, body []byte)
6565
return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err
6666
}
6767

68+
// exclude annotations from this version
69+
manifests := make([]tools.McpManifest, len(toolset.McpManifest))
70+
for i, m := range toolset.McpManifest {
71+
m.Annotations = nil
72+
manifests[i] = m
73+
}
74+
6875
result := ListToolsResult{
69-
Tools: toolset.McpManifest,
76+
Tools: manifests,
7077
}
7178
return jsonrpc.JSONRPCResponse{
7279
Jsonrpc: jsonrpc.JSONRPC_VERSION,

‎internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
9393
if description == "" {
9494
description = "Creates a new AlloyDB cluster. This is a long-running operation, but the API call returns quickly. This will return operation id to be used by get operations tool. Take all parameters from user in one go."
9595
}
96-
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters)
96+
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
9797

9898
return Tool{
9999
Config: cfg,

‎internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
9494
if description == "" {
9595
description = "Creates a new AlloyDB instance (PRIMARY or READ_POOL) within a cluster. This is a long-running operation. This will return operation id to be used by get operations tool. Take all parameters from user in one go."
9696
}
97-
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters)
97+
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
9898

9999
return Tool{
100100
Config: cfg,

‎internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
9494
if description == "" {
9595
description = "Creates a new AlloyDB user within a cluster. Takes the new user's name and a secure password. Optionally, a list of database roles can be assigned. Always ask the user for the type of user to create. ALLOYDB_IAM_USER is recommended."
9696
}
97-
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters)
97+
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
9898

9999
return Tool{
100100
Config: cfg,

‎internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
9090
if description == "" {
9191
description = "Retrieves details about a specific AlloyDB cluster."
9292
}
93-
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters)
93+
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
9494

9595
return Tool{
9696
Config: cfg,

‎internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
9191
if description == "" {
9292
description = "Retrieves details about a specific AlloyDB instance."
9393
}
94-
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters)
94+
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
9595

9696
return Tool{
9797
Config: cfg,

‎internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
9191
if description == "" {
9292
description = "Retrieves details about a specific AlloyDB user."
9393
}
94-
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters)
94+
mcpManifest := tools.GetMcpManifest(cfg.Name, description, cfg.AuthRequired, allParameters, nil)
9595

9696
return Tool{
9797
Config: cfg,

0 commit comments

Comments
 (0)