* Added git-tiny-image.ts - registers a tool that returns a tiny MCP logo * In all other tools, updated function docs
16 KiB
Everything Server – Architecture and Layout
This document summarizes the current layout and runtime architecture of the src/everything package. It explains how the server starts, how transports are wired, where tools, prompts, and resources are registered, and how to extend the system.
High‑level Overview
-
Purpose: A minimal, modular MCP server showcasing core Model Context Protocol features. It exposes a simple tool, several prompts, and both static and dynamic resources, and can be run over multiple transports (STDIO, SSE, and Streamable HTTP).
-
Design: A small “server factory” constructs the MCP server and registers features. Transports are separate entry points that create/connect the server and handle network concerns. Tools, prompts, and resources are organized in their own submodules.
-
Design: A small “server factory” constructs the MCP server and registers features. Transports are separate entry points that create/connect the server and handle network concerns. Tools, prompts, and resources are organized in their own submodules. Simulated logging and resource‑update notifications are opt‑in and controlled by tools.
-
Two server implementations exist:
server/index.ts: The lightweight, modular server used by transports in this package.server/everything.ts: A comprehensive reference server (much larger, many tools/prompts/resources) kept for reference/testing but not wired up by default in the entry points.
-
Multi‑client subscriptions: The server supports multiple concurrent clients. Each client manages its own resource subscriptions and receives notifications only for the URIs it subscribed to, independent of other clients.
Directory Layout
src/everything
├── index.ts
├── server
│ ├── index.ts
│ ├── logging.ts
│ └── everything.ts
├── transports
│ ├── sse.ts
│ ├── stdio.ts
│ └── streamableHttp.ts
├── tools
│ ├── index.ts
│ ├── add.ts
│ ├── echo.ts
│ ├── get-tiny-image.ts
│ ├── long-running-operation.ts
│ ├── print-env.ts
│ ├── sampling-request.ts
│ ├── toggle-logging.ts
│ └── toggle-subscriber-updates.ts
├── prompts
│ ├── index.ts
│ ├── args.ts
│ ├── completions.ts
│ ├── simple.ts
│ └── resource.ts
├── resources
│ ├── index.ts
│ ├── files.ts
│ ├── subscriptions.ts
│ └── templates.ts
├── docs
│ ├── architecture.md
│ └── server-instructions.md
└── package.json
At src/everything:
-
index.ts
- CLI entry that selects and runs a specific transport module based on the first CLI argument:
stdio,sse, orstreamableHttp.
- CLI entry that selects and runs a specific transport module based on the first CLI argument:
-
server/
- index.ts
- Server factory that creates an
McpServerwith declared capabilities, loads server instructions, and registers tools, prompts, and resources. - Sets resource subscription handlers via
setSubscriptionHandlers(server). - Exposes
{ server, cleanup }to the chosen transport. Cleanup stops any running intervals in the server when the transport disconencts.
- Server factory that creates an
- logging.ts
- Implements simulated logging. Periodically sends randomized log messages at various levels to the connected client session. Started/stopped on demand via a dedicated tool.
- everything.ts
- A full “reference/monolith” implementation demonstrating most MCP features. Not the default path used by the transports in this package.
- index.ts
-
transports/
- stdio.ts
- Starts a
StdioServerTransport, created the server viacreateServer(), and connects it. HandlesSIGINTto close cleanly and callscleanup()to remove any live intervals.
- Starts a
- sse.ts
- Express server exposing:
GET /sseto establish an SSE connection per session.POST /messagefor client messages.
- Manages multiple connected clients via a transport map.
- Starts an
SSEServerTransport, created the server viacreateServer(), and connects it to a new transport. - On server disconnect, calls
cleanup()to remove any live intervals.
- Express server exposing:
- streamableHttp.ts
- Express server exposing a single
/mcpendpoint for POST (JSON‑RPC), GET (SSE stream), and DELETE (session termination) usingStreamableHTTPServerTransport. - Uses an
InMemoryEventStorefor resumable sessions and tracks transports bysessionId. Connects a fresh server instance on initialization POST and reuses the transport for subsequent requests.
- Express server exposing a single
- stdio.ts
-
tools/
- index.ts
registerTools(server)orchestrator; delegates to basic tools and control tools.
- add.ts
- Defines an
addtool with a Zod input schema that sums two numbersaandband returns the result.
- Defines an
- echo.ts
- Defines a minimal
echotool with a Zod input schema and returnsEcho: {message}.
- Defines a minimal
- get-tiny-image.ts
- Defines
get-tiny-imagetool, which returns a tiny PNG MCP logo as animagecontent item, along with surrounding descriptivetextitems.
- Defines
- long-running-operation.ts
- Defines
long-running-operation: simulates a long-running task over a specifiedduration(seconds) and number ofsteps; emitsnotifications/progressupdates when the client supplies aprogressToken.
- Defines
- print-env.ts
- Defines
print-env: returns the current process environment variables as formatted JSON text; useful for debugging configuration.
- Defines
- toggle-logging.ts
- Defines
toggle-logging: starts/stops simulated logging for the invoking session.
- Defines
- toggle-subscriber-updates.ts
- Defines
toggle-subscriber-updates: starts/stops simulated resource subscription update checks for the invoking session.
- Defines
- sampling-request.ts
- Defines
sampling-request: sends asampling/createMessagerequest to the client/LLM and returns the sampling result.
- Defines
- index.ts
-
prompts/
- index.ts
registerPrompts(server)orchestrator; delegates to individual prompt registrations.
- simple.ts
- Registers
simple-prompt: a prompt with no arguments that returns a single user message.
- Registers
- args.ts
- Registers
args-prompt: a prompt with two arguments (cityrequired,stateoptional) used to compose a message.
- Registers
- completions.ts
- Registers
completable-prompt: a prompt whose arguments support server-driven completions using the SDK’scompletable(...)helper (e.g., completingdepartmentand context-awarename).
- Registers
- resource.ts
- Exposes
registerEmbeddedResourcePrompt(server)which registersresource-prompt— a prompt that acceptsresourceType("Text" or "Blob") andresourceId(integer), and embeds a dynamically generated resource of the requested type within the returned messages. Internally reuses helpers fromresources/templates.ts.
- Exposes
- index.ts
-
resources/
- index.ts
registerResources(server)orchestrator; delegates to template‑based dynamic resources and static file-based resources by callingregisterResourceTemplates(server)andregisterFileResources(server).
- templates.ts
- Registers two dynamic, template‑driven resources using
ResourceTemplate:- Text:
demo://resource/dynamic/text/{index}(MIME:text/plain) - Blob:
demo://resource/dynamic/blob/{index}(MIME:application/octet-stream, Base64 payload)
- Text:
- The
{index}path variable must be a finite integer. Content is generated on demand with a timestamp. - Exposes helpers
textResource(uri, index),textResourceUri(index),blobResource(uri, index), andblobResourceUri(index)so other modules can construct and embed dynamic resources directly (e.g., from prompts).
- Registers two dynamic, template‑driven resources using
- files.ts
- Registers static file-based resources for each file in the
docs/folder. - URIs follow the pattern:
demo://resource/static/document/<filename>. - Serves markdown files as
text/markdown,.txtastext/plain,.jsonasapplication/json, others default totext/plain.
- Registers static file-based resources for each file in the
- index.ts
-
docs/
- server-instructions.md
- Human‑readable instructions intended to be passed to the client/LLM as MCP server instructions. Loaded by the server at startup.
- architecture.md (this document)
- server-instructions.md
-
package.json
- Package metadata and scripts:
build: TypeScript compile todist/, copiesdocs/intodist/and marks the compiled entry scripts as executable.start:stdio,start:sse,start:streamableHttp: Run built transports fromdist/.
- Declares dependencies on
@modelcontextprotocol/sdk,express,cors,zod, etc.
- Package metadata and scripts:
Startup and Runtime Flow
-
A transport is chosen via the CLI entry
index.ts:node dist/index.js stdio→ loadstransports/stdio.jsnode dist/index.js sse→ loadstransports/sse.jsnode dist/index.js streamableHttp→ loadstransports/streamableHttp.js
-
The transport creates the server via
createServer()fromserver/index.tsand connects it to the chosen transport type from the MCP SDK. -
The server factory (
server/index.ts) does the following:- Creates
new McpServer({ name, title, version }, { capabilities, instructions }). - Capabilities:
tools: {}logging: {}prompts: {}resources: { subscribe: true }
- Loads human‑readable “server instructions” from the docs folder (
server-instructions.md). - Registers tools via
registerTools(server). - Registers resources via
registerResources(server). - Registers prompts via
registerPrompts(server). - Sets up resource subscription handlers via
setSubscriptionHandlers(server). - Returns the server and a
cleanup(sessionId?)hook that stops any active intervals and removes any session‑scoped state.
- Creates
-
Each transport is responsible for network/session lifecycle:
- STDIO: simple process‑bound connection; closes on
SIGINTand callscleanup(). - SSE: maintains a session map keyed by
sessionId; hooks server’soncloseto clean and remove session; exposes/sse(GET) and/message(POST) endpoints. - Streamable HTTP: exposes
/mcpfor POST (JSON‑RPC messages), GET (SSE stream), and DELETE (termination). Uses an event store for resumability and stores transports bysessionId. Does not auto‑start simulated features; callscleanup(sessionId)on DELETE.
- STDIO: simple process‑bound connection; closes on
Registered Features (current minimal set)
-
Tools
add(tools/add.ts): Adds two numbersaandband returns their sum. Uses Zod to validate inputs.echo(tools/echo.ts): Echoes the providedmessage: string. Uses Zod to validate inputs.get-tiny-image(tools/get-tiny-image.ts): Returns a tiny PNG MCP logo as animagecontent item with brief descriptive text before and after.long-running-operation(tools/long-running-operation.ts): Simulates a multi-step operation over a givendurationand number ofsteps; reports progress vianotifications/progresswhen aprogressTokenis provided by the client.print-env(tools/print-env.ts): Returns all environment variables from the running process as pretty-printed JSON text.sampling-request(tools/sampling-request.ts): Issues asampling/createMessagerequest to the client/LLM using providedpromptand optional generation controls; returns the LLM’s response payload.toggle-logging(tools/toggle-logging.ts): Starts or stops simulated, random‑leveled logging for the invoking session. Respects the client’s selected minimum logging level.toggle-subscriber-updates(tools/toggle-subscriber-updates.ts): Starts or stops simulated resource update notifications for URIs the invoking session has subscribed to.
-
Prompts
simple-prompt(prompts/simple.ts): No-argument prompt that returns a static user message.args-prompt(prompts/args.ts): Two-argument prompt withcity(required) andstate(optional) used to compose a question.completable-prompt(prompts/completions.ts): Demonstrates argument auto-completions with the SDK’scompletablehelper;departmentcompletions drive context-awarenamesuggestions.resource-prompt(prompts/resource.ts): AcceptsresourceType("Text" or "Blob") andresourceId(string convertible to integer) and returns messages that include an embedded dynamic resource of the selected type generated viaresources/templates.ts.
-
Resources
- Dynamic Text:
demo://resource/dynamic/text/{index}(content generated on the fly) - Dynamic Blob:
demo://resource/dynamic/blob/{index}(base64 payload generated on the fly) - Static Docs:
demo://resource/static/document/<filename>(serves files fromsrc/everything/docs/as static file-based resources)
- Dynamic Text:
-
Resource Subscriptions and Notifications
- Clients may subscribe/unsubscribe to resource URIs using the MCP
resources/subscribeandresources/unsubscriberequests. - Simulated update notifications are opt‑in and off by default. Use the
toggle-subscriber-updatestool to start/stop a per‑session interval that emitsnotifications/resources/updated { uri }only for URIs that session has subscribed to. - Multiple concurrent clients are supported; each client’s subscriptions are tracked per session and notifications are delivered independently via the server instance associated with that session.
- Clients may subscribe/unsubscribe to resource URIs using the MCP
-
Logging
- Simulated logging is available but off by default. Use the
toggle-loggingtool to start/stop periodic log messages of varying levels (debug, info, notice, warning, error, critical, alert, emergency) per session. Clients can control the minimum level they receive via the standard MCPlogging/setLevelrequest.
- Simulated logging is available but off by default. Use the
Extension Points
-
Adding Tools
- Create a new file under
tools/with yourregisterXTool(server)function that registers the tool viaserver.registerTool(...). - Export and call it from
tools/index.tsinsideregisterTools(server).
- Create a new file under
-
Adding Prompts
- Create a new file under
prompts/with yourregisterXPrompt(server)function that registers the prompt viaserver.registerPrompt(...). - Export and call it from
prompts/index.tsinsideregisterPrompts(server).
- Create a new file under
-
Adding Resources
- Create a new file under
resources/with yourregisterXResources(server)function usingserver.registerResource(...)(optionally withResourceTemplate). - Export and call it from
resources/index.tsinsideregisterResources(server).
- Create a new file under
Resource Subscriptions – How It Works
-
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-updatestool, which callsbeginSimulatedResourceUpdates(server, sessionId)andstopSimulatedResourceUpdates(sessionId). cleanup(sessionId?)callsstopSimulatedResourceUpdates(sessionId)to clear intervals and remove session‑scoped state.
- Tracks subscribers per URI:
-
Design note: Each client session has its own
McpServerinstance; periodic checks run per session and invokeserver.notification(...)on that instance, so messages are delivered only to the intended client.
Simulated Logging – How It Works
-
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-loggingtool, which callsbeginSimulatedLogging(server, sessionId?)andstopSimulatedLogging(sessionId?). Note that transport disconnect triggerscleanup()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.
-
Adding Transports
- Implement a new transport module under
transports/. - Add a case to
index.tsso the CLI can select it.
- Implement a new transport module under
Build and Distribution
- TypeScript sources are compiled into
dist/vianpm run build. - The
buildscript copiesdocs/intodist/so instruction files ship alongside the compiled server. - The CLI bin is configured in
package.jsonasmcp-server-everything→dist/index.js.
Relationship to the Full Reference Server
The large server/everything.ts shows a comprehensive MCP server showcasing many features (tools with schemas, prompts, resource operations, notifications, etc.). The current transports in this package use the lean factory from server/index.ts instead, keeping the runtime small and focused while preserving the reference implementation for learning and experimentation.