servers/src/everything/docs/how-it-works.md
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

45 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Everything Server - How It Works
**[Architecture](architecture.md)
| [Project Structure](structure.md)
| [Startup Process](startup.md)
| [Server Features](features.md)
| [Extension Points](extension.md)
| How It Works**
# Conditional Tool Registration
### Module: `server/index.ts`
- Some tools require client support for the capability they demonstrate. These are:
- `get-roots-list`
- `trigger-elicitation-request`
- `trigger-sampling-request`
- Client capabilities aren't known until after initilization handshake is complete.
- Most tools are registered immediately during the Server Factory execution, prior to client connection.
- To defer registration of these commands until client capabilities are known, a `registerConditionalTools(server)` function is invoked from an `onintitialized` handler.
## Resource Subscriptions
### Module: `resources/subscriptions.ts`
- Tracks subscribers per URI: `Map<uri, Set<sessionId>>`.
- Installs handlers via `setSubscriptionHandlers(server)` to process subscribe/unsubscribe requests and keep the map updated.
- Updates are started/stopped on demand by the `toggle-subscriber-updates` tool, which calls `beginSimulatedResourceUpdates(server, sessionId)` and `stopSimulatedResourceUpdates(sessionId)`.
- `cleanup(sessionId?)` calls `stopSimulatedResourceUpdates(sessionId)` to clear intervals and remove session‑scoped state.
## Session‑scoped Resources
### Module: `resources/session.ts`
- `getSessionResourceURI(name: string)`: Builds a session resource URI: `demo://resource/session/<name>`.
- `registerSessionResource(server, resource, type, payload)`: Registers a resource with the given `uri`, `name`, and `mimeType`, returning a `resource_link`. The content is served from memory for the life of the session only. Supports `type: "text" | "blob"` and returns data in the corresponding field.
- Intended usage: tools can create and expose per-session artifacts without persisting them. For example, `tools/gzip-file-as-resource.ts` compresses fetched content, registers it as a session resource with `mimeType: application/gzip`, and returns either a `resource_link` or an inline `resource` based on `outputType`.
## Simulated Logging
### Module: `server/logging.ts`
- Periodically sends randomized log messages at different levels. Messages can include the session ID for clarity during demos.
- Started/stopped on demand via the `toggle-simulated-logging` tool, which calls `beginSimulatedLogging(server, sessionId?)` and `stopSimulatedLogging(sessionId?)`. Note that transport disconnect triggers `cleanup()` which also stops any active intervals.
- Uses `server.sendLoggingMessage({ level, data }, sessionId?)` so that the client’s configured minimum logging level is respected by the SDK.