@@ -88,6 +88,9 @@ func resolveToolIcon() *mcp.Icon {
8888// addTool registers a tool and wraps its handler with rate limiting + metrics instrumentation.
8989// It automatically injects the GREEN-API icon into the tool metadata when configured.
9090func (s * Server ) addTool (tool mcp.Tool , handler mcpgo.ToolHandlerFunc ) {
91+ applySubmissionReviewHints (& tool )
92+ applyToolTitle (& tool )
93+ applyWidgetToolMeta (& tool )
9194 if s .toolIcon != nil {
9295 tool .Icons = append (tool .Icons , * s .toolIcon )
9396 }
@@ -126,6 +129,132 @@ func (s *Server) addTool(tool mcp.Tool, handler mcpgo.ToolHandlerFunc) {
126129 }))
127130}
128131
132+ func applySubmissionReviewHints (tool * mcp.Tool ) {
133+ readOnlyTools := map [string ]bool {
134+ "whatsapp_check_whatsapp" : true ,
135+ "whatsapp_get_authorization_code" : true ,
136+ "whatsapp_get_chat_history" : true ,
137+ "whatsapp_get_contact_avatar" : true ,
138+ "whatsapp_get_contact_info" : true ,
139+ "whatsapp_get_contacts" : true ,
140+ "whatsapp_get_group_data" : true ,
141+ "whatsapp_get_instances" : true ,
142+ "whatsapp_get_message" : true ,
143+ "whatsapp_get_qr" : true ,
144+ "whatsapp_get_settings" : true ,
145+ "whatsapp_get_state" : true ,
146+ "whatsapp_get_wa_settings" : true ,
147+ "whatsapp_last_incoming_messages" : true ,
148+ "whatsapp_last_outgoing_messages" : true ,
149+ "whatsapp_receive_notification" : true ,
150+ }
151+ localOnlyTools := map [string ]bool {
152+ "whatsapp_connect" : true ,
153+ "whatsapp_disconnect" : true ,
154+ }
155+ destructiveTools := map [string ]bool {
156+ "whatsapp_delete_instance" : true ,
157+ "whatsapp_delete_message" : true ,
158+ "whatsapp_delete_notification" : true ,
159+ "whatsapp_edit_message" : true ,
160+ "whatsapp_forward_messages" : true ,
161+ "whatsapp_leave_group" : true ,
162+ "whatsapp_logout" : true ,
163+ "whatsapp_remove_group_admin" : true ,
164+ "whatsapp_remove_group_participant" : true ,
165+ "whatsapp_send_contact" : true ,
166+ "whatsapp_send_file" : true ,
167+ "whatsapp_send_file_by_upload" : true ,
168+ "whatsapp_send_location" : true ,
169+ "whatsapp_send_message" : true ,
170+ "whatsapp_send_poll" : true ,
171+ "whatsapp_set_settings" : true ,
172+ }
173+
174+ readOnly := readOnlyTools [tool .Name ]
175+ openWorld := ! readOnly && ! localOnlyTools [tool .Name ]
176+ destructive := destructiveTools [tool .Name ]
177+
178+ tool .Annotations .ReadOnlyHint = & readOnly
179+ tool .Annotations .OpenWorldHint = & openWorld
180+ tool .Annotations .DestructiveHint = & destructive
181+ if readOnly {
182+ idempotent := true
183+ tool .Annotations .IdempotentHint = & idempotent
184+ }
185+ }
186+
187+ var toolTitles = map [string ]string {
188+ "whatsapp_connect" : "Connect Instance" ,
189+ "whatsapp_disconnect" : "Disconnect Instance" ,
190+ "whatsapp_send_message" : "Send Message" ,
191+ "whatsapp_send_file" : "Send File by URL" ,
192+ "whatsapp_upload_file" : "Upload File" ,
193+ "whatsapp_send_file_by_upload" : "Send File" ,
194+ "whatsapp_send_location" : "Send Location" ,
195+ "whatsapp_send_contact" : "Send Contact" ,
196+ "whatsapp_send_poll" : "Send Poll" ,
197+ "whatsapp_forward_messages" : "Forward Messages" ,
198+ "whatsapp_edit_message" : "Edit Message" ,
199+ "whatsapp_delete_message" : "Delete Message" ,
200+ "whatsapp_get_state" : "Get Instance State" ,
201+ "whatsapp_get_settings" : "Get Instance Settings" ,
202+ "whatsapp_set_settings" : "Update Instance Settings" ,
203+ "whatsapp_get_qr" : "Get QR Code" ,
204+ "whatsapp_check_whatsapp" : "Check WhatsApp Number" ,
205+ "whatsapp_get_contacts" : "Get Contacts" ,
206+ "whatsapp_get_contact_info" : "Get Contact Info" ,
207+ "whatsapp_receive_notification" : "Receive Notification" ,
208+ "whatsapp_create_group" : "Create Group" ,
209+ "whatsapp_get_group_data" : "Get Group Data" ,
210+ "whatsapp_add_group_participant" : "Add Group Participant" ,
211+ "whatsapp_remove_group_participant" : "Remove Group Participant" ,
212+ "whatsapp_reboot" : "Reboot Instance" ,
213+ "whatsapp_logout" : "Logout Instance" ,
214+ "whatsapp_get_authorization_code" : "Get Authorization Code" ,
215+ "whatsapp_get_wa_settings" : "Get WhatsApp Account Settings" ,
216+ "whatsapp_get_chat_history" : "Get Chat History" ,
217+ "whatsapp_get_message" : "Get Message" ,
218+ "whatsapp_last_incoming_messages" : "Get Recent Incoming Messages" ,
219+ "whatsapp_last_outgoing_messages" : "Get Recent Outgoing Messages" ,
220+ "whatsapp_read_chat" : "Mark Chat as Read" ,
221+ "whatsapp_delete_notification" : "Delete Notification" ,
222+ "whatsapp_set_group_admin" : "Promote Group Admin" ,
223+ "whatsapp_remove_group_admin" : "Demote Group Admin" ,
224+ "whatsapp_leave_group" : "Leave Group" ,
225+ "whatsapp_get_contact_avatar" : "Get Contact Avatar" ,
226+ "whatsapp_create_instance" : "Create Partner Instance" ,
227+ "whatsapp_delete_instance" : "Delete Partner Instance" ,
228+ "whatsapp_get_instances" : "List Partner Instances" ,
229+ }
230+
231+ func applyToolTitle (tool * mcp.Tool ) {
232+ if title , ok := toolTitles [tool .Name ]; ok && tool .Annotations .Title == "" {
233+ tool .Annotations .Title = title
234+ }
235+ }
236+
237+ func applyWidgetToolMeta (tool * mcp.Tool ) {
238+ resourceURIByTool := map [string ]string {
239+ "whatsapp_get_contacts" : "ui://contacts" ,
240+ "whatsapp_get_qr" : "ui://qr" ,
241+ }
242+ resourceURI , ok := resourceURIByTool [tool .Name ]
243+ if ! ok {
244+ return
245+ }
246+
247+ fields := map [string ]any {}
248+ if tool .Meta != nil {
249+ for key , value := range tool .Meta .AdditionalFields {
250+ fields [key ] = value
251+ }
252+ }
253+ fields ["ui" ] = map [string ]any {"resourceUri" : resourceURI }
254+ fields ["openai/outputTemplate" ] = resourceURI
255+ tool .Meta = mcp .NewMetaFromMap (fields )
256+ }
257+
129258// ServeStdio runs the MCP server over stdio transport (blocking).
130259func (s * Server ) ServeStdio (ctx context.Context ) error {
131260 stdioSrv := mcpgo .NewStdioServer (s .mcp )
0 commit comments