Commit Graph
6 Commits
Author SHA1 Message Date
63b203b937 feat(mcp): resource notifications, subscriptions, and read_resource builtin tool (#254)
* feat(mcp): resource notifications, subscriptions, and read_resource builtin tool

- Add MCP resource subscription lifecycle (subscribe/unsubscribe on connect/disconnect)
- Wire mcp.notifications setting with live toggle support
- Add debounced followUp injection for resource change notifications
- Add global read_resource builtin tool with server resolution by URI/template scheme
- Add MCP prompt commands (buildMCPPromptCommands) with array content support
- Add server instructions injection into system prompt with attribution
- Add mcp.notificationDebounceMs configurable setting

Client (client.ts):
  listResources, listResourceTemplates, readResource with pagination
  subscribeToResources, unsubscribeFromResources
  listPrompts, getPrompt, serverSupportsPrompts
  serverSupportsResources, serverSupportsResourceSubscriptions

Manager (manager.ts):
  Notification dispatch with subscribed-URI guard
  Concurrent refresh deduplication via pending promise map
  setNotificationsEnabled with subscribe/unsubscribe toggle

Tests:
  client-resources.test.ts (31 tests)
  client-prompts.test.ts (20 tests)
  mcp-read-resource.test.ts (13 tests)

* fix(mcp): address PR review - eager prompt init and stale subscription cleanup

P1: Make setOnPromptsChanged eagerly fire for servers that already
have prompts loaded. The callback is registered after MCP discovery
has already loaded prompts and fired the hook, so without this the
handler is never called on the common startup path. The fix is in
the manager itself (not the caller), eliminating the race condition
regardless of when the callback is wired.

P2: Unsubscribe removed resource URIs on resource refresh.
refreshServerResources was subscribing to the new URI set and
overwriting #subscribedResources without unsubscribing URIs that
were previously subscribed but no longer present, leaving stale
subscriptions active on the server.

* fix(mcp): add resources and prompts to /mcp help text and subcommand completions

* feat(mcp): add /mcp notifications command

Shows per-server notification capabilities with subscription state:
- Lists supported notification types (tools/list_changed, resources/list_changed,
  prompts/list_changed) with check marks
- Shows resources/subscribe status with active subscription count
- Lists subscribed URIs with green ticks when notifications are enabled
- Displays overall enabled/disabled state (mcp.notifications setting)

* fix(mcp): address PR review comments on race conditions and stale state

- Await subscribe/unsubscribe in refreshServerResources so the refresh
  promise doesn't resolve before subscriptions are settled, preventing
  a second refresh from racing and overwriting tracking state (P2 #3)

- Guard setNotificationsEnabled subscribe .then() against a disable
  that happens while the subscribe request is in-flight (P2 #5)

- Re-check mcp.notifications setting inside debounce setTimeout
  callback so toggling off mid-window actually suppresses the
  follow-up message (P2 #4)

- Fire onToolsChanged and onPromptsChanged callbacks in
  disconnectServer so stale slash commands and tool registrations
  are cleaned up when a server is removed (P2 #2)

---------

Co-authored-by: Miroslav Drbal <miroslav.drbal@gendigital.com>
2026-03-03 03:26:07 +01:00
can1357 abf8c1efc9 refactor: unslop common utilities 2026-02-22 11:01:11 +01:00
can1357 8d10a6b879 feat(coding-agent): added abort signal support and improved cancellation handling in MCP server operations
- Added abort signal support to MCP server connection and tool listing operations, enabling cancellation via Escape key during testing.
- Enhanced MCP connection timeout handling with improved abort signal integration in the withTimeout function to prevent race conditions.
- Improved MCP test command UI to display '(esc to cancel)' indicator and handle cancellation gracefully.
- Updated HTTP transport session termination to include timeout mechanism preventing indefinite hangs.
- Fixed MCP test command cleanup to prevent resource leaks when operations are cancelled or aborted.
2026-02-10 17:33:46 +01:00
can1357 9f94d39789 feat(coding-agent/mcp): added abort signal support to MCP request handling for cancellation
- Added MCPRequestOptions interface with signal property for request cancellation via AbortSignal.
- Added abort signal support to MCP tool execution enabling request cancellation via Escape-to-interrupt or other abort mechanisms.
- Enhanced MCP request handling with abort signal propagation through HTTP, SSE, and stdio transports with proper cleanup.
- Improved stdio transport request handling to use Promise.withResolvers for cleaner async flow and better abort signal integration.
- Updated HTTP transport to combine operation abort signals with timeout signals using AbortSignal.any() for unified cancellation.
- Modified SSE response parsing to support abort signals and distinguish between timeout and user-initiated cancellation.
2026-02-10 17:19:50 +01:00
can1357 779ca4872b style(deps): migrated from Prettier to Biome and updated formatting rules
- Removed Prettier configuration files (.prettierignore and .prettierrc) and migrated formatting to Biome.
- Updated Biome configuration from version 2.3.11 to 2.3.12 and changed arrowParentheses rule from 'always' to 'asNeeded'.
- Pinned @biomejs/biome dependency to exact version 2.3.12 in package.json and bun.lock.
- Applied consistent arrow function formatting across 489 files by removing unnecessary parentheses around single parameters.
- Removed blank lines after comment blocks and reorganized imports for consistency across the codebase.
2026-01-24 04:20:19 +01:00
can1357 cb5bbbf382 refactor(coding-agent): flattened directory structure, eliminated core/ folder
- Eliminated core/ directory (252 files, 23 subdirs → distributed)
- Reduced max nesting from 9 levels to 5 levels
- Promoted tool subdirs to top level: exa/, lsp/, patch/, task/, web/
- Merged web-scrapers/ + web-search/ into web/{scrapers,search}/
- Flattened modes/interactive/ to modes/
- Split execution/ into: ipy/ (python), exec/ (bash), ssh/
- Renamed ipy/python-*.ts to ipy/*.ts (executor, kernel, etc.)
- Flattened cursor/exec-bridge.ts to cursor.ts
- Created logical groupings: config/, session/, extensibility/, export/
- Updated all imports across 500+ files
2026-01-23 12:24:47 +01:00