Use types for tool annotations to reduce confusion
Opened this issue · 0 comments
kentcdodds commented
Is your feature request related to a problem? Please describe.
The way that tool annotations work is confusing because some of the properties only matter if you have read-only set to false.
Describe the solution you'd like
I would like to have type warnings if I am setting destructiveHint or idempotentHint to anything when readOnly is set to false.
Something like this:
Implement a discriminated union type that:
- Enforces the read-only constraint: When
readOnlyHint: true,destructiveHintandidempotentHintcannot be specified - Prevents redundant defaults: Only allows specifying properties when they differ from their default values
- Uses defaults:
destructiveHint: true,idempotentHint: false,openWorldHint: true,readOnlyHint: false
Proposed Type Definition:
type ToolAnnotations =
| {
readOnlyHint: true;
openWorldHint?: boolean;
}
| {
destructiveHint?: false; // Only allow false (default is true)
idempotentHint?: true; // Only allow true (default is false)
openWorldHint?: false; // Only allow false (default is true)
};Benefits:
- Cleaner configurations: No need to specify default values
- Type safety: Prevents invalid combinations at compile time
- Explicit intent: Only specify what differs from defaults
- Constraint enforcement: Cannot set destructive/idempotent on read-only tools
Examples:
type ToolAnnotations =
| {
readOnlyHint: true;
openWorldHint?: boolean;
}
| {
destructiveHint?: false; // Only allow false (default is true)
idempotentHint?: true; // Only allow true (default is false)
openWorldHint?: false; // Only allow false (default is true)
};
// ✅ Clean - all defaults
const defaultTool: ToolAnnotations = {};
// ✅ Only specify non-defaults
const nonDestructiveTool: ToolAnnotations = {
destructiveHint: false // Only specify when false (default is true)
};
// ✅ Read-only tool
const readOnlyTool: ToolAnnotations = {
readOnlyHint: true,
openWorldHint: false
};
// ❌ TypeScript error - cannot specify defaults
const invalidDefaults: ToolAnnotations = {
destructiveHint: true, // Error: Type 'true' is not assignable to type 'false'
idempotentHint: false, // Error: Type 'false' is not assignable to type 'true'
openWorldHint: true // Error: Type 'true' is not assignable to type 'false'
};
// ❌ TypeScript error - cannot set destructive/idempotent on read-only
const invalidReadOnly: ToolAnnotations = {
readOnlyHint: true,
destructiveHint: true // Error: Property 'destructiveHint' does not exist
};Describe alternatives you've considered
The status quo is me being pretty confused 😅