Commit f4d22d7
Add preMcpToolCall hook support to all SDKs (#1366)
* Add preMcpToolCall hook support to all SDKs
Add the preMcpToolCall hook which fires before an MCP tool call is
dispatched to an MCP server. This aligns with copilot-agent-runtime
1.0.51 which added support for this hook type.
The hook receives serverName, toolName, arguments, optional toolCallId,
and optional _meta as input. The output supports a tri-state metaToUse
field: absent (preserve existing _meta), null (remove _meta), or object
(replace _meta).
Changes per SDK:
- Node.js: PreMcpToolCallHookInput/Output types, handler, SessionHooks
- Python: PreMcpToolCallHookInput/Output TypedDicts, handler, SessionHooks
- Go: PreMcpToolCallHookInput/Output structs, handler, helper functions
- .NET: PreMcpToolCallHookInput/Output classes, SessionHooks, JsonElement?
- Rust: PreMcpToolCallInput/Output structs, HookEvent/Output variants, trait
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add preMcpToolCall hook E2E tests for Node.js, Python, Go, and Rust
Port the three preMcpToolCall hook test scenarios (set meta, replace meta,
remove meta) from the .NET reference implementation to all four remaining
SDK test suites.
Each test:
- Configures an MCP stdio server (meta-echo) that echoes _meta back
- Registers a preMcpToolCall hook that sets/replaces/removes metadata
- Verifies the tool result reflects the hook's effect
- Asserts hook input fields (serverName, toolName, workingDirectory, timestamp)
Snapshot files are reused from test/snapshots/pre_mcp_tool_call_hook/.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix code review feedback and add .NET E2E test infrastructure
- Add OnPreMcpToolCall to hasHooks checks in .NET Client.cs and Go client.go
- Add SerializeHookOutput helper for source-gen serialization
- Add .NET PreMcpToolCallHookE2ETests (3 tests: set, replace, remove meta)
- Add MCP meta-echo test server and snapshot YAML files
- Fix Go mcp_and_agents_e2e_test.go (Cwd -> WorkingDirectory)
- Remove stale dead_code lint expectation in Rust support.rs
- Add serialization unit tests for hook output
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Java PingResponse timestamp deserialization for ISO-8601 format
The Copilot CLI now returns ISO-8601 timestamp strings instead of numeric
epoch milliseconds. Update PingResponse.timestamp from long to String and
PingResult.timestamp from Long to String. Update corresponding test
assertions accordingly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Regenerate Java codegen output
Auto-committed by java-codegen-check workflow.
* Fix Java test type mismatch: PingResult.timestamp is Long not String
The generated PingResult record has timestamp as Long (milliseconds),
but tests were passing String values (ISO date format). Update tests
to use Long millisecond values instead.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Rename cwd to working_directory in Rust public API
Rename the public `cwd` field to `working_directory` on:
- ClientOptions (local-only, not serialized)
- McpStdioServerConfig (serialized; add #[serde(rename = "cwd")])
- SessionListFilter (serialized; add #[serde(rename = "cwd")])
The wire format remains unchanged (JSON key stays "cwd").
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Rename cwd to working_directory in Python public API
Rename all public API fields named 'cwd' to 'working_directory' and
'initial_cwd' to 'initial_working_directory' in the Python SDK while
preserving the wire format (JSON sent to/from the Copilot CLI runtime
still uses 'cwd' and 'initialCwd').
Fields renamed:
- SubprocessConfig.cwd -> working_directory
- MCPStdioServerConfig['cwd'] -> working_directory
- SessionContext.cwd -> working_directory
- SessionListFilter.cwd -> working_directory
- SessionFsConfig['initial_cwd'] -> initial_working_directory
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Rename cwd to workingDirectory in Node.js public API
Rename the public-facing 'cwd' field to 'workingDirectory' in:
- CopilotClientOptions.cwd
- MCPStdioServerConfig.cwd
- SessionContext.cwd
- SessionListFilter.cwd
The wire format (JSON sent to/from the Copilot CLI runtime) is preserved
as 'cwd' via transformation layers in client.ts:
- Outgoing: workingDirectory -> cwd (mcpServers, customAgents, listSessions filter)
- Incoming: cwd -> workingDirectory (session context in toSessionMetadata)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix formatting in Node.js and Python after cwd rename
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Rust E2E test: use working_directory in McpStdioServerConfig
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix flaky tests: increase CLI start timeout and add missing snapshot
- Node.js: Increase CLI server start timeout from 10s to 30s to accommodate
slow Windows CI runners
- Java: Add missing conversation to mcp_and_agents/should_accept_both_mcp_servers_and_custom_agents
snapshot (was empty, causing proxy 500 errors)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Update Java .lastmerge to include snapshot fix
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Rename Cwd/InitialCwd to WorkingDirectory/InitialWorkingDirectory in Go and .NET
Complete the cwd → workingDirectory rename across all SDKs for consistency.
Wire format (JSON) is preserved via struct tags and JsonPropertyName attributes.
Go:
- ClientOptions.Cwd → WorkingDirectory
- SessionFsConfig.InitialCwd → InitialWorkingDirectory
- SessionContext.Cwd → WorkingDirectory (json:"cwd")
- SessionListFilter.Cwd → WorkingDirectory (json:"cwd,omitempty")
.NET:
- SessionFsConfig.InitialCwd → InitialWorkingDirectory ([JsonPropertyName("initialCwd")])
- SessionContext.Cwd → WorkingDirectory ([JsonPropertyName("cwd")])
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix missed Cwd reference and run go fmt
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Revert Java SDK changes
Remove Java preMcpToolCall hook implementation from this PR to be handled separately.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Node.js Windows CI test failure
Split dependent SQL tool calls into separate CAPI turns in the
session_fs_sqlite snapshot. The CREATE TABLE and INSERT were previously
returned as separate choices in a single response, causing the CLI on
Windows to execute them concurrently. Since INSERT depends on CREATE
TABLE completing first, this produced a 'no such table: items' error.
The fix restructures the snapshot into 3 CAPI turns: first executing
report_intent + CREATE TABLE, then INSERT, then the final response.
This ensures CREATE TABLE always completes before INSERT is attempted.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>1 parent 311695e commit f4d22d7
74 files changed
Lines changed: 1716 additions & 248 deletions
File tree
- dotnet
- src
- test
- E2E
- Unit
- go
- internal/e2e
- testharness
- nodejs
- src
- test/e2e
- harness
- python
- copilot
- e2e
- testharness
- rust
- examples
- src
- tests
- e2e
- test
- harness
- snapshots
- mcp_and_agents
- pre_mcp_tool_call_hook
- session_fs_sqlite
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
528 | 528 | | |
529 | 529 | | |
530 | 530 | | |
| 531 | + | |
531 | 532 | | |
532 | 533 | | |
533 | 534 | | |
| |||
688 | 689 | | |
689 | 690 | | |
690 | 691 | | |
| 692 | + | |
691 | 693 | | |
692 | 694 | | |
693 | 695 | | |
| |||
1231 | 1233 | | |
1232 | 1234 | | |
1233 | 1235 | | |
1234 | | - | |
| 1236 | + | |
1235 | 1237 | | |
1236 | 1238 | | |
1237 | 1239 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1245 | 1245 | | |
1246 | 1246 | | |
1247 | 1247 | | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
| 1251 | + | |
| 1252 | + | |
1248 | 1253 | | |
1249 | 1254 | | |
1250 | 1255 | | |
| |||
1283 | 1288 | | |
1284 | 1289 | | |
1285 | 1290 | | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
1286 | 1299 | | |
1287 | 1300 | | |
1288 | 1301 | | |
| |||
1607 | 1620 | | |
1608 | 1621 | | |
1609 | 1622 | | |
| 1623 | + | |
| 1624 | + | |
1610 | 1625 | | |
1611 | 1626 | | |
1612 | 1627 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
396 | 396 | | |
397 | 397 | | |
398 | 398 | | |
399 | | - | |
| 399 | + | |
| 400 | + | |
400 | 401 | | |
401 | 402 | | |
402 | 403 | | |
| |||
1215 | 1216 | | |
1216 | 1217 | | |
1217 | 1218 | | |
1218 | | - | |
| 1219 | + | |
1219 | 1220 | | |
1220 | 1221 | | |
1221 | 1222 | | |
| |||
1271 | 1272 | | |
1272 | 1273 | | |
1273 | 1274 | | |
| 1275 | + | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
| 1304 | + | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
| 1316 | + | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
1274 | 1352 | | |
1275 | 1353 | | |
1276 | 1354 | | |
| |||
1293 | 1371 | | |
1294 | 1372 | | |
1295 | 1373 | | |
1296 | | - | |
| 1374 | + | |
1297 | 1375 | | |
1298 | 1376 | | |
1299 | 1377 | | |
| |||
1360 | 1438 | | |
1361 | 1439 | | |
1362 | 1440 | | |
1363 | | - | |
| 1441 | + | |
1364 | 1442 | | |
1365 | 1443 | | |
1366 | 1444 | | |
| |||
1415 | 1493 | | |
1416 | 1494 | | |
1417 | 1495 | | |
1418 | | - | |
| 1496 | + | |
1419 | 1497 | | |
1420 | 1498 | | |
1421 | 1499 | | |
| |||
1475 | 1553 | | |
1476 | 1554 | | |
1477 | 1555 | | |
1478 | | - | |
| 1556 | + | |
1479 | 1557 | | |
1480 | 1558 | | |
1481 | 1559 | | |
| |||
1549 | 1627 | | |
1550 | 1628 | | |
1551 | 1629 | | |
1552 | | - | |
| 1630 | + | |
1553 | 1631 | | |
1554 | 1632 | | |
1555 | 1633 | | |
| |||
1621 | 1699 | | |
1622 | 1700 | | |
1623 | 1701 | | |
| 1702 | + | |
| 1703 | + | |
| 1704 | + | |
| 1705 | + | |
| 1706 | + | |
1624 | 1707 | | |
1625 | 1708 | | |
1626 | 1709 | | |
| |||
2518 | 2601 | | |
2519 | 2602 | | |
2520 | 2603 | | |
2521 | | - | |
| 2604 | + | |
| 2605 | + | |
2522 | 2606 | | |
2523 | 2607 | | |
2524 | 2608 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
48 | | - | |
| 48 | + | |
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| |||
118 | 118 | | |
119 | 119 | | |
120 | 120 | | |
121 | | - | |
| 121 | + | |
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
| |||
188 | 188 | | |
189 | 189 | | |
190 | 190 | | |
191 | | - | |
| 191 | + | |
192 | 192 | | |
193 | 193 | | |
194 | 194 | | |
| |||
0 commit comments