feat(mcp): Add tool annotations for improved LLM tool understanding#2012
feat(mcp): Add tool annotations for improved LLM tool understanding#2012bryankthompson wants to merge 1 commit intoawslabs:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds MCP tool annotations to improve LLM understanding of tool behavior across 72 tools in 6 MCP servers. The annotations include readOnlyHint, destructiveHint, openWorldHint, and title to help MCP clients make safer decisions about tool execution.
Key changes:
- Imports
ToolAnnotationsfrommcp.typesin all modified server files - Adds comprehensive annotations to all tool definitions following the established pattern from
aws-appsync-mcp-serverandaws-api-mcp-server - Annotates 72 tools total with appropriate hints for read-only operations, destructive operations, and external API call behavior
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/s3-tables-mcp-server/awslabs/s3_tables_mcp_server/server.py | Adds annotations to 16 S3 Tables tools, correctly distinguishing between read operations (list, query, get) and write operations (create, update, rename, import, append) |
| src/postgres-mcp-server/awslabs/postgres_mcp_server/server.py | Adds annotations to 7 PostgreSQL tools, marking database operations that make external API calls and distinguishing between connection management and query execution |
| src/iam-mcp-server/awslabs/iam_mcp_server/server.py | Adds annotations to 29 IAM tools, properly categorizing user, role, group, and policy management operations as destructive when appropriate |
| src/ecs-mcp-server/awslabs/ecs_mcp_server/modules/troubleshooting.py | Adds annotation to ECS troubleshooting tool as read-only with external API calls |
| src/ecs-mcp-server/awslabs/ecs_mcp_server/modules/resource_management.py | Adds annotation to ECS resource management tool as destructive with external API calls |
| src/ecs-mcp-server/awslabs/ecs_mcp_server/modules/express.py | Adds annotations to 4 ECS Express Mode tools for image building, validation, deletion, and service monitoring |
| src/ecs-mcp-server/awslabs/ecs_mcp_server/modules/containerize.py | Adds annotation to containerize tool as read-only local operation that provides guidance |
| src/dynamodb-mcp-server/awslabs/dynamodb_mcp_server/server.py | Adds annotations to 4 DynamoDB tools covering data modeling, analysis, command execution, and validation |
| src/cfn-mcp-server/awslabs/cfn_mcp_server/server.py | Adds annotations to 8 CloudFormation tools for resource schema retrieval, CRUD operations, and template creation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| annotations=ToolAnnotations( | ||
| title='Execute DynamoDB Command', | ||
| readOnlyHint=False, | ||
| destructiveHint=True, |
There was a problem hiding this comment.
The execute_dynamodb_command tool is marked with destructiveHint=True, but this is overly restrictive. Similar to SQL queries, DynamoDB commands can be both read-only (e.g., query, scan, get-item, describe-table) and destructive (e.g., put-item, delete-item, create-table). Marking the tool as always destructive is misleading since it accepts arbitrary AWS CLI DynamoDB commands. Consider using destructiveHint=False to indicate mixed behavior, as the tool's destructiveness depends entirely on the command provided by the user.
| destructiveHint=True, | |
| destructiveHint=False, |
There was a problem hiding this comment.
The execute_dynamodb_command may be destructive.
Since the definition of destructiveHint from version "2025-11-25" at https://modelcontextprotocol.io/specification/2025-11-25/schema#toolannotations-destructivehint has the operative word "MAY" the value should remain True.
destructiveHint
If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates.
|
Thanks for the feedback! You're absolutely right - |
scottschreckengaust
left a comment
There was a problem hiding this comment.
LGTM for cfn-mcp-server
|
@triepod-ai Thank you for the suggestions. Please review the |
5791c44
| annotations=ToolAnnotations( | ||
| title='Create Table Bucket', | ||
| readOnlyHint=False, | ||
| destructiveHint=True, |
There was a problem hiding this comment.
According to the MCP documentation:
destructiveHint
If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates.
This tool only creates a new table bucket, which is an additive operation.
| annotations=ToolAnnotations( | ||
| title='Create Namespace', | ||
| readOnlyHint=False, | ||
| destructiveHint=True, |
There was a problem hiding this comment.
According to the MCP documentation:
destructiveHint
If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates.
This tool only creates a new namespace, which is an additive operation.
| annotations=ToolAnnotations( | ||
| title='Create Table', | ||
| readOnlyHint=False, | ||
| destructiveHint=True, |
There was a problem hiding this comment.
According to the MCP documentation:
destructiveHint
If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates.
This tool only creates a new table, which is an additive operation.
| annotations=ToolAnnotations( | ||
| title='Import CSV to Table', | ||
| readOnlyHint=False, | ||
| destructiveHint=True, |
There was a problem hiding this comment.
According to the MCP documentation:
destructiveHint
If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates.
This tool only appends rows, which is an additive operation.
| annotations=ToolAnnotations( | ||
| title='Import Parquet to Table', | ||
| readOnlyHint=False, | ||
| destructiveHint=True, |
There was a problem hiding this comment.
According to the MCP documentation:
destructiveHint
If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates.
This tool only appends rows, which is an additive operation.
| annotations=ToolAnnotations( | ||
| title='Append Rows to Table', | ||
| readOnlyHint=False, | ||
| destructiveHint=True, |
There was a problem hiding this comment.
According to the MCP documentation:
destructiveHint
If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates.
This tool only appends rows, which is an additive operation.
|
@okhomin Thanks for the thorough review! You're absolutely correct - create, import, and append operations are additive per the MCP spec:
I've updated all 6 tools to use
|
matthewgoodman13
left a comment
There was a problem hiding this comment.
ecs-mcp-server:
The description mentions 8 tool changes, but there are 7: containerize, build & push, validate, delete, wait for service ready, ecs resource management tool, troubleshooting. 7 is the correct number of tools (excluding the knowledge proxy tools).
Overall, changes LGTM. As improvement, would have been nice to see more added unit tests, but will not block on that. Approving on behalf of the ECS MCP Server.
|
Hi @okhomin, I've addressed your feedback in commit 8db72e7 - changed You're absolutely right that these are purely additive operations per the MCP spec definition. Thanks for the thorough review! Could you please re-review when you have a chance? |
nineonine
left a comment
There was a problem hiding this comment.
ECS changes look good to me
ee3c775
988bf41 to
ee3c775
Compare
|
Hi @okhomin, I've rebased on main to resolve merge conflicts and your previous feedback has been addressed: Changes made per your review:
Additional update during rebase:
Could you please re-review when you have a chance? Thank you! |
|
This pull request is now marked as stale because it hasn't seen activity for a while. Add a comment or it will be closed soon. If you wish to exclude this issue from being marked as stale, add the "backlog" label. |
Add readOnlyHint, destructiveHint, openWorldHint, and title annotations to: - dynamodb-mcp-server (4 tools) - iam-mcp-server (29 tools) - s3-tables-mcp-server (16 tools) - ecs-mcp-server (8 tools) - postgres-mcp-server (7 tools) - cfn-mcp-server (8 tools) Total: 72 tools annotated across 6 servers. These annotations help MCP clients understand tool behavior and make safer decisions about tool execution. The annotations follow the existing pattern established in aws-appsync-mcp-server and aws-api-mcp-server. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ee3c775 to
7248a12
Compare
|
Hi maintainers! I've rebased on main and addressed all previous feedback. Changes in this update:okhomin's feedback (S3 Tables)✅ Changed
Per the MCP spec: "If false, the tool performs only additive updates" — these tools only create new resources without modifying/deleting existing ones. DynamoDB server changes
Summary
Could the codeowners please re-review? Thank you! |
Summary
readOnlyHint,destructiveHint,openWorldHint, andtitle) to 72 tools across 6 MCP serversaws-appsync-mcp-serverandaws-api-mcp-serverAnnotated Servers
Total: 72 tools annotated
Motivation
Tool annotations help MCP clients understand tool behavior and make safer decisions about tool execution:
readOnlyHint: Indicates if the tool only reads data without modificationsdestructiveHint: Indicates if the tool performs destructive operations (create, update, delete)openWorldHint: Indicates if the tool makes external API callstitle: Human-readable name for the toolTest plan
from mcp.types import ToolAnnotations)By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.
🤖 Generated with Claude Code