Commit Graph

24 Commits

Author SHA1 Message Date
olaservo
9d863fb7e6 feat: add async sampling and elicitation tools
Add tools that demonstrate bidirectional MCP tasks where the server
sends requests to the client for async execution:

- trigger-sampling-request-async: Send sampling request with task
  params, client creates task and executes LLM call in background,
  server polls for completion and retrieves result

- trigger-elicitation-request-async: Same pattern for user input,
  useful when user may take time to fill out forms

Both tools:
- Check client capabilities (tasks.requests.sampling/elicitation)
- Accept both CreateTaskResult and direct result responses
- Poll tasks/get for status updates
- Fetch final result via tasks/result

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 09:14:30 -07:00
olaservo
0208e93f85 feat(everything): add SEP-1686 Tasks support
- Add tasks capability with list, cancel, and requests.tools.call
- Add InMemoryTaskStore and InMemoryTaskMessageQueue from SDK experimental
- Add simulate-research-query tool demonstrating task lifecycle
- Task demonstrates working -> input_required -> completed status flow
- Uses elicitation for ambiguous queries when client supports it

Closes #3037

🦉 Generated with [Claude Code](https://claude.ai/code)
2026-01-09 06:48:53 -07:00
cliffhall
f8933ec3e6 Sync roots at startup. This was deferred to list_roots tool is used, but I'm putting it back.
The syncRoots call should be idempotent, requesting roots if they haven't been yet for the session, but always retuning the cached roots otherwise. That could be deferred but setting the handler for roots_list changed note should not.

* In server/roots.ts
  - only set the notification handler and call for initial roots list if the roots aren't already cached for this client.

* In server/index.ts
  - in the oninitialized handler
    - get the sessionId from the transport
    - set a 350ms timeout to call syncRoots with the server and sessionId
      - this delay cause it to run after the `notifications/initialized` handler finishes, otherwise, the request gets lost.

* All other changes attributable to prettier
2025-12-17 17:46:24 -05:00
cliffhall
1b8f376b90 Demonstrate registration of tools conditioned upon client capability support. Also, obviated need for clientConnected callback to pass sessionId because we defer initial fetching of roots happens when you run the get-roots-list tool.
* In how-it-works.md,
  - added a section on conditional tool registration

* In server/index.ts
  - import registerConditionalTools
  - in an oninitialized handler for the server, call registerConditionalTools
  - removed clientConnected from ServerFactoryResponse and all mentions in docs

* In tools/index.ts
  - export a registerConditionalTools function
  - refactor/move calls to registerGetRootsListTool, registerTriggerElicitationRequestTool, and registerTriggerSamplingRequestTool out of registerTools and into registerConditionalTools

* In server/roots.ts
  - only act if client supports roots
  - remove setInterval from call to requestRoots. It isn't happening during the initialze handshake anymore, so it doesn't interfere with that process if called immediaately

* In get-roots-list.ts, trigger-elicitation-request.ts, and trigger-sampling-request.ts,
  - only register tool if client supports capability

* Throughout the rest of the files, removing all references to `clientConnected`
2025-12-15 17:51:30 -05:00
cliffhall
2b60822057 Refactor-renamed long-running-operation.ts to trigger-long-running-operation.ts 2025-12-13 14:20:24 -05:00
cliffhall
f561f70002 [WIP] Refactor everything server to be more modular and use recommended APIs.
* Updated docs

* Refactor/renamed toggle-logging.ts to toggle-simulated-logging.ts
  - refactor/renamed registerToggleLoggingTool to registerToggleSimulatedLoggingTool
2025-12-13 10:59:35 -05:00
cliffhall
18ef6aa69b [WIP] Refactor everything server to be more modular and use recommended APIs.
Adding Trigger Elicitation Request and Get Roots List tools

* Updated architecture.md

* Added roots.ts
  - tracks roots by sessionId
  - setRootsListChangedHandler
    - listens for roots changed notification from the client
      - updates the roots map by sessionId
      - sends log notification or error to the client

* In server/index.ts
  - import setRootsListChangedHandler
  - in clientConnected callback
    - call setRootsListChangedHandler passing server and sessionId

* In sse.ts, stdio.ts, and streamableHttp.ts
  - receive clientConnected from server factory
  - call clientConnected when server is connected to transport
* Added get-roots-list.ts
  - registerGetRootsListTool
    - Registers the 'get-roots-list' tool with the given MCP server.

* Added trigger-elicitation-request.ts
  - registerTriggerElicitationRequestTool
    - registered tool sends an elicitation request that exercises all supported field types

* In tools/index.ts
  - imports registerTriggerElicitationRequestTool and registerGetRootsListTool
  - in registerTools
    - call registerTriggerElicitationRequestTool and registerGetRootsListTool, passing server
2025-12-11 20:25:37 -05:00
cliffhall
ea6fe271cd [WIP] Refactor everything server to be more modular and use recommended APIs.
Adding Trigger Elicitation Request tool

* Updated architecture.md

* Added trigger-elicitation-request.ts
  - registerTriggerElicitationRequestTool
    - registered tool sends an elicitation request that exercises all supported field types

* In tools/index.ts
  - imports registerTriggerElicitationRequestTool
  - in registerTools
    - call registerTriggerElicitationRequestTool passing server
2025-12-11 18:10:37 -05:00
cliffhall
339e056ea0 [WIP] Refactor everything server to be more modular and use recommended APIs.
* Updated architecture.md

* Refactor/renamed get-sampling-request.ts to trigger-sampling-request.ts
  - use trigger instead of get throughout

* In tools/index.ts
  - sorted display order
2025-12-11 17:39:25 -05:00
cliffhall
2afc618ccd [WIP] Refactor everything server to be more modular and use recommended APIs.
[WIP] Adding Gzip File as Resource tool

* Updated architecture.md

* Added gzip-file-as-resource.ts
  - imports getSessionResourceURI and  registerSessionResource from session.ts
  - exports registerGZipFileAsResourceTool
    - the registered tool
      - validates the input URI
      - fetches the file safely
      - compresses it
      - creates and registers the resource
      - returns resource or resource link

* In tools/index.ts
  - import registerGZipFileAsResourceTool
  - in registerTools,
    - call registerGZipFileAsResourceTool passing server

* Added resources/session.ts
  - getSessionResourceURI gets a uri to the specified name
  - registerSessionResource registers the session-scoped resource and returns a resource link
2025-12-11 17:23:27 -05:00
cliffhall
48bf94a728 [WIP] Refactor everything server to be more modular and use recommended APIs.
* Updated architecture.md

* Refactor/renamed sampling-request.ts to get-sampling-request.ts

* In tools/index.ts
  - sorted presenation order
2025-12-10 16:58:25 -05:00
cliffhall
f759d9eaa1 [WIP] Refactor everything server to be more modular and use recommended APIs.
For tools where we seek to get some response from the server, renamed as an action, e.g., "Get Sum" rather than "Add" or "Get Annotated Message" rather than "Annotated Message", so that it's clear what the intent of the tool is in a quick review.

* Updated architecture.md

* Refactor/renamed add.ts to get-sum.ts
* Refactor/renamed annotated-message.ts to get-annotated-message.ts
* In tools/index.ts
  - sorted presentation order
2025-12-10 16:08:41 -05:00
cliffhall
904d0ea71f [WIP] Refactor everything server to be more modular and use recommended APIs.
Adding get-structured-content tool

* Updated architecture.md

* added get-structured-content.ts
  - Registers the 'get-structured-content' tool with the provided McpServer instance.
  - The registered tool processes incoming arguments using a predefined input schema,
    generates structured content with weather information including temperature,
    conditions, and humidity, and returns both backward-compatible content blocks
    and structured content in the response.
2025-12-09 20:11:29 -05:00
cliffhall
03d3da0d55 [WIP] Refactor everything server to be more modular and use recommended APIs.
Refactor/rename `print-env` tool to `get-env`

* Updated architecture.md

* Refactor rename print-env.ts to get-env.ts

* In tools/index.ts
  - reorder tools alphabetically
2025-12-09 19:24:39 -05:00
cliffhall
8530747606 [WIP] Refactor everything server to be more modular and use recommended APIs.
Adding the get-resource-reference and get-resource-reference tools

* Updated architecture.md

* Added get-resource-links.ts
  - Registers the 'get-resource-reference' tool with the provided McpServer instance.
  - The registered tool retrieves a specified number of resource links and their metadata.

* In get-resource-reference.ts
  - fixed tool description

* In tools/index.ts
  - import registerGetResourceLinksTool
  - in registerTool
    - call registerGetResourceLinksTool
2025-12-09 19:17:00 -05:00
cliffhall
320e3d8b25 [WIP] Refactor everything server to be more modular and use recommended APIs.
Adding the get-resource-reference tool

* Updated architecture.md

* In prompts/resource.ts
  - Refactor/extracted the prompt argument completers into exported functions in resources/templates.ts
  - Refactor/extracted BLOB_TYPE, TEXT_TYPE, and resourceTypes into exported constants in resources/templates.ts as RESOURCE_TYPE_BLOB, RESOURCE_TYPE_TEXT, and RESOURCE_TYPES
  - In resources/templates.ts
    - refactor renamed index to resourceId throughout for consistency with prompts and tool references
* Added tools/get-resource-reference.ts
  - Registers the 'get-resource-reference' tool with the provided McpServer instance.
  - uses enum and number schema for tools to provide resourceType and resourceId arguments. Completables don't work for tool arguments.
  - Returns the corresponding dynamic resource
* In tools/index.ts
  - imported registerGetResourceReferenceTool
  - in registerTools
    - called registerGetResourceReferenceTool
2025-12-09 17:47:38 -05:00
cliffhall
0bf6c6911d [WIP] Refactor everything server to be more modular and use recommended APIs.
Adding the annotated message tool

* Updated architecture.md

* Added annotated-message.ts
  - registers a tool that returns a message with annotations on different content types

* In package.json
  - updated TS SDK version
2025-12-09 12:17:08 -05:00
cliffhall
2ce87b168c [WIP] Refactor everything server to be more modular and use recommended APIs.
* Added git-tiny-image.ts
  - registers a tool that returns a tiny MCP logo

* In all other tools, updated function docs
2025-12-09 10:17:37 -05:00
cliffhall
0f3e27ef87 [WIP] Refactor everything server to be more modular and use recommended APIs.
Added print-env, and sampling-request tools

* Updated architecture.md

* In tools/index.ts
  - import registerPrintEnvTool and registerSamplingRequestTool
  - in registerTools
    - call registerPrintEnvTool and registerSamplingRequestTool

* Added tools/print-env.ts
  - registers a tool that takes no args and returns the environment variables

* Added tools/sampling-request
  - registers a tool that
    - takes prompt and maxTokens args
    - sends client a sampling request
    - returns the client response in the result
2025-12-08 19:14:06 -05:00
cliffhall
1df8623bcc [WIP] Refactor everything server to be more modular and use recommended APIs.
Added long-running-operation tool and improved comments in all tools

* Updated architecture.md

* In tools/
  - add.ts
  - echo.ts
  - toggle-logging.ts
  - toggle-subscriber-updates.ts
    - Add better function and inline docs

* Added tools/long-running-operation.ts
  - similar implementation as in everything v1

* In tools/index.ts
  - import registerLongRunningOperationTool
  - in registerTools
    - registerLongRunningOperationTool
2025-12-08 17:55:04 -05:00
cliffhall
346c29a086 [WIP] Refactor everything server to be more modular and use recommended APIs.
Added tools to toggle simulated logging and resource updates on and off rather than have them start immediately upon connection

* Updated architecture.md

* In server/index.ts
  - remove import of beginSimulatedResourceUpdates and beginSimulatedLogging
  - remove clientConnected from createServer factory result

* In tools/index.ts
  - import registerToggleLoggingTool and registerToggleSubscriberUpdatesTool
  - in registerTools
    - call registerToggleLoggingTool and registerToggleSubscriberUpdatesTool

* In logging.ts
  - in beginSimulatedLogging
    - refactor extract inline interval callback into function sendSimulatedLoggingMessage
  - call sendSimulatedLoggingMessage right away to send the first message
  - supply sendSimulatedLoggingMessage as interval callback

* In subscriptions.ts
  - remove import of Transport
  - remove transports map
  - in beginSimulatedResourceUpdates()
    - change arguments to server and sessionId
    - check for the subsUpdateInterval for the session
    - remove all transport storage and interaction
    - instead use the server to send the notification
 - in stopSimulatedResourceUpdates()
   - remove management of transports map

* In stdio.ts, sse.ts, and streamableHttp.ts
  - remove destructure and calling of clientConnected

* Added tools/toggle-logging.ts
  - registers a tool that
    - takes no arguments
    - tracks clients that have been enabled by session id in a set
    - if client isn't enabled,
       - calls beginSimulatedLogging
       - adds session id to client set
    - else
      - calls stopSimulatedLogging
      - deletes session id from client set
    - returns a message explaining what was done including what to expect when logging is enabled

 * Added tools/toggle-subscriber-updates.ts
   - registers a tool that
     - takes no arguments
     - tracks clients that have been enabled by session id in a set
     - if client isn't enabled,
        - calls beginSimulatedResourceUpdates
        - adds session id to client set
     - else
       - calls stopSimulatedResourceUpdates
       - deletes session id from client set
     - returns a message explaining what was done including what to expect when logging is enabled
2025-12-08 17:13:42 -05:00
cliffhall
eee9866ebb [WIP] Refactor everything server to be more modular and use recommended APIs.
* Updated architecture.md

* Refactor / renamed all addXPrompt, addXTool, and addXResource functions to registerX...

* Added the add tool
2025-12-05 18:43:36 -05:00
cliffhall
1c64b36c78 [WIP] Refactor everything server to be more modular and use recommended APIs.
* Adding static resources, move server instructions to
the new docs folder, and add code formatting

* Add docs folder

* Add docs/architecture.md which describes the architecture of the project thus far.

* Refactor moved instructions.md to docs/server-instructions.md

* Add resources/static.ts
  - in addStaticResources()
    - read the file entries from the docs folder
    - register each file as a resource (no template), with a readResource function that reads the file and returns it in a contents block with the appropriate mime type and contents
  - getMimeType helper function gets the mime type for a filename
  - readSafe helper function reads the file synchronously as utf-8 or returns an error string

* Add resources/index.ts
  - import addStaticResources
  - export registerResources function
  - in registerResources()
    - call addStaticResources

* In package.json
  - add prettier devDependency
  - add prettier:check script
  - add prettier:fix script
  - in build script, copy docs folder to dist

* All other changes were prettier formatting
2025-12-05 13:26:08 -05:00
cliffhall
5de886ca63 [WIP] Refactor everything server to be more modular and use recommended APIs
In src/everything:

* Refactor / move streamableHttp.ts, sse.ts, and stdio.ts to transports/

* Move everything.ts to server/ for reference

* Add server/index.js
  - exports the createServer function
  - import registerTools from tools/index.js
  - in createServer()
    - read instructions.md and include in ServerOptions for McpServer constructor
    - construct McpServer instead of Server
    - call registerTools, passing server

* Add tools/echo.ts
  - define EchoSchema
  - define tool config
  - export addToolEcho function
  - in addToolEcho()
    - register handler for Echo tool

* Add tools/index.ts
  - import addToolEcho
  - export registerTools function
  - in registerTools()
    - call addToolEcho
2025-12-03 17:36:47 -05:00