Skip to content

Commit 0f9009c

Browse files
authored
improvement(search-mcp): log the field names a rejected tool call's arguments carry (#10003)
* improvement(search-mcp): log the field names a rejected tool call's arguments carry * improvement(search-mcp): say the logged-key cap applies per schema issue
1 parent 86817f3 commit 0f9009c

2 files changed

Lines changed: 47 additions & 2 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
import { describe, expect, it } from 'vitest'
5+
import { toolCallInputIssues } from '@/lib/knowledge/mcp/tool-arguments'
6+
7+
const searchCall = (args: Record<string, unknown>) => ({
8+
jsonrpc: '2.0',
9+
id: 1,
10+
method: 'tools/call',
11+
params: { name: 'search', arguments: args },
12+
})
13+
14+
describe('toolCallInputIssues', () => {
15+
it('names the fields a native query carries that the schema does not know', () => {
16+
const issues = toolCallInputIssues(
17+
searchCall({
18+
query: 'roadmap',
19+
nativeQueries: [{ provider: 'jira', query: 'roadmap', limit: 5 }],
20+
})
21+
)
22+
expect(issues?.issues).toContainEqual({
23+
code: 'unrecognized_keys',
24+
path: 'nativeQueries.0',
25+
keys: ['limit'],
26+
})
27+
})
28+
})

‎apps/sim/lib/knowledge/mcp/tool-arguments.ts‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,18 @@ export function repairToolCallMessage(message: Record<string, unknown>) {
8787
return { message: { ...message, params: { ...call, arguments: args } }, repairs: [...repairs] }
8888
}
8989

90+
/**
91+
* Unrecognized field names logged per schema issue, each cut short. The schema caps native queries
92+
* at nine, so a rejection's log line stays bounded.
93+
*/
94+
const MAX_LOGGED_KEYS = 5
95+
const MAX_LOGGED_KEY_CHARACTERS = 64
96+
9097
/**
9198
* Where a tool call's arguments fail its input schema, as field paths and issue codes without
92-
* values. The SDK rejects such a call before the tool runs, so nothing else records it.
99+
* values, plus the names of fields the schema does not know, so a repeated client mistake can be
100+
* told apart from a new one. The SDK rejects such a call before the tool runs, so nothing else
101+
* records it.
93102
*/
94103
export function toolCallInputIssues(message: Record<string, unknown>) {
95104
const call = readToolCall(message)
@@ -99,6 +108,14 @@ export function toolCallInputIssues(message: Record<string, unknown>) {
99108
if (parsed.success) return undefined
100109
return {
101110
toolName: call.name,
102-
issues: parsed.error.issues.map(({ code, path }) => ({ code, path: path.join('.') })),
111+
issues: parsed.error.issues.map((issue) => ({
112+
code: issue.code,
113+
path: issue.path.join('.'),
114+
...(issue.code === 'unrecognized_keys' && {
115+
keys: issue.keys
116+
.slice(0, MAX_LOGGED_KEYS)
117+
.map((key) => key.slice(0, MAX_LOGGED_KEY_CHARACTERS)),
118+
}),
119+
})),
103120
}
104121
}

0 commit comments

Comments
 (0)