Skip to content

Commit 8358ff0

Browse files
feat: Add tool annotations for improved LLM tool understanding (#169)
1 parent a55fb01 commit 8358ff0

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

src/openapi-mcp-server/mcp/proxy.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,22 @@ export class MCPProxy {
6363
def.methods.forEach(method => {
6464
const toolNameWithMethod = `${toolName}-${method.name}`;
6565
const truncatedToolName = this.truncateToolName(toolNameWithMethod);
66+
67+
// Look up the HTTP method to determine annotations
68+
const operation = this.openApiLookup[toolNameWithMethod];
69+
const httpMethod = operation?.method?.toLowerCase();
70+
const isReadOnly = httpMethod === 'get';
71+
6672
tools.push({
6773
name: truncatedToolName,
6874
description: method.description,
6975
inputSchema: method.inputSchema as Tool['inputSchema'],
76+
annotations: {
77+
title: this.operationIdToTitle(method.name),
78+
...(isReadOnly
79+
? { readOnlyHint: true }
80+
: { destructiveHint: true }),
81+
},
7082
})
7183
})
7284
})
@@ -173,6 +185,19 @@ export class MCPProxy {
173185
return name.slice(0, 64);
174186
}
175187

188+
/**
189+
* Convert an operationId like "createDatabase" to a human-readable title like "Create Database"
190+
*/
191+
private operationIdToTitle(operationId: string): string {
192+
// Split on camelCase boundaries and capitalize each word
193+
return operationId
194+
.replace(/([a-z])([A-Z])/g, '$1 $2')
195+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
196+
.split(/[\s_-]+/)
197+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
198+
.join(' ');
199+
}
200+
176201
async connect(transport: Transport) {
177202
// The SDK will handle stdio communication
178203
await this.server.connect(transport)

0 commit comments

Comments
 (0)