Skip to content

Add stateless, streaming and async tool annotations #489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

pantanurag555
Copy link

Motivation and Context

This change adds 3 new tool annotations: stateless, streaming and asynchronous, that would be useful to convey the impact and nature of the tools to the client. Based on discussion #344. The client can make use of these annotations when deciding which tool to use:

  1. statelessHint: If true, this tool does not maintain state based on previous requests. If false, the tool may maintain state base on previous interactions and the context from the previous requests might influence the next response.
  2. streamingHint: If true, this tool streams its responses.
  3. asyncHint: If true, this tool accepts a request and continues to work asynchronously to generate responses.
  • Update tool annotations structure to include new annotations
  • Add documentation for new tool annotations
  • Add relevant examples to show the use of new tool annotations

Breaking Changes

None

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

@@ -333,6 +336,9 @@ The MCP specification defines the following annotations for tools:
| `destructiveHint` | boolean | true | If true, the tool may perform destructive updates (only meaningful when `readOnlyHint` is false) |
| `idempotentHint` | boolean | false | If true, calling the tool repeatedly with the same arguments has no additional effect (only meaningful when `readOnlyHint` is false) |
| `openWorldHint` | boolean | true | If true, the tool may interact with an "open world" of external entities |
| `statelessHint` | boolean | true | If true, this tool does not maintain state based on previous requests |

Choose a reason for hiding this comment

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

Does it make sense for the default to be true? I think it should either be undefined or false, as it's not possible to maintain correctness for existing tools if the default is true - as a trivial example, we can't suggest that filesystem tools are stateless just because they don't declare otherwise.

Choose a reason for hiding this comment

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

Or, alternatively - rename it to statefulHint instead of statelessHint, and update the description accordingly.

Copy link
Author

@pantanurag555 pantanurag555 May 9, 2025

Choose a reason for hiding this comment

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

  1. I think you are right. This should be false by default, since being marked stateful is more forgiving (based on description, if statelessHint is false the tool might maintain state of the previous interactions). Will change this.
  2. I would like to stick with statelessHint because we use stateless in server session as well. Would prefer to avoid confusion by having both stateful and stateless terms.

Choose a reason for hiding this comment

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

  1. Err, other way around - you have it true by default here already, as in: "assume this tool is stateless". Making it false by default would be "assume this tool is stateful", unless I'm misinterpreting the description.
  2. That's reasonable, though I think the double-negative in something potentially not being stateless is just as confusing (I think we're seeing that in this very discussion) 😅

Copy link
Author

Choose a reason for hiding this comment

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

  1. Corrected my comment. Meant false by default.
  2. I do agree about the double negative. However, since the current decision is to use stateless for the server session with False as the default value, I think we should stick with it for the tool as well.

Copy link

@LucaButBoring LucaButBoring left a comment

Choose a reason for hiding this comment

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

Comments resolved, will cede the floor to maintainers 😄

@000-000-000-000-000
Copy link

This change looks good to me - should we wait on async hint until that capability is added?

@pantanurag555
Copy link
Author

This change looks good to me - should we wait on async hint until that capability is added?

I think having it in there preemptively is not bad either. asyncHint can be set to false for all tools until the support has been added (I see async support as inevitable). I am fine with waiting but there are tools that could currently benefit from statelessHint and streamingHint annotations.

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.

3 participants