Architecture | Project Structure | Startup Process | Server Features | Extension Points | How It Works
src/everything
├── index.ts
├── AGENTS.md
├── package.json
├── docs
│ ├── architecture.md
│ ├── extension.md
│ ├── features.md
│ ├── how-it-works.md
│ ├── instructions.md
│ ├── startup.md
│ └── structure.md
├── prompts
│ ├── index.ts
│ ├── args.ts
│ ├── completions.ts
│ ├── simple.ts
│ └── resource.ts
├── resources
│ ├── index.ts
│ ├── files.ts
│ ├── minted.ts
│ ├── session.ts
│ ├── subscriptions.ts
│ └── templates.ts
├── server
│ ├── index.ts
│ ├── context.ts
│ ├── logging.ts
│ ├── roots.ts
│ └── tasks.ts
├── tools
│ ├── index.ts
│ ├── echo.ts
│ ├── get-annotated-message.ts
│ ├── get-env.ts
│ ├── get-header-params.ts
│ ├── get-resource-links.ts
│ ├── get-resource-reference.ts
│ ├── get-roots-list.ts
│ ├── get-structured-content.ts
│ ├── get-sum.ts
│ ├── get-tiny-image.ts
│ ├── gzip-file-as-resource.ts
│ ├── simulate-research-query.ts
│ ├── toggle-simulated-logging.ts
│ ├── toggle-subscriber-updates.ts
│ ├── trigger-elicitation-request-async.ts
│ ├── trigger-elicitation-request.ts
│ ├── trigger-list-changed.ts
│ ├── trigger-log-messages.ts
│ ├── trigger-long-running-operation.ts
│ ├── trigger-multi-step-elicitation.ts
│ ├── trigger-resource-update.ts
│ ├── trigger-sampling-request-async.ts
│ ├── trigger-sampling-request.ts
│ └── trigger-url-elicitation.ts
└── transports
├── in-memory-event-store.ts
├── listen.ts
├── sse.ts
├── stdio.ts
└── streamableHttp.ts
- CLI entry point that selects and runs a specific transport module based on the first CLI argument:
stdio,sse, orstreamableHttp.
- Directions for Agents/LLMs explaining coding guidelines and how to appropriately extend the server.
- 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 the TypeScript SDK v2 packages (
@modelcontextprotocol/server,@modelcontextprotocol/node,@modelcontextprotocol/server-legacy),express,cors,zod, etc.
architecture.md- Describes the server architecture, including transport layers, session initialization, and primitive registration.
extension.md- Explains how to extend the server with new tools, prompts, resources, or transports.
features.md- A comprehensive reference listing all implemented prompts, resources, tools, and protocol behaviors.
how-it-works.md- Explains how SSE and Streamable HTTP transports are set up and how sessions are managed.
instructions.md- Human‑readable instructions intended to be passed to the client/LLM as guidance on server use. Loaded by the server at startup and returned in the initialize exchange.
startup.md- Describes the server startup sequence, environment checks, and initialization.
structure.md- This document.
index.tsregisterPrompts(server)orchestrator; delegates to prompt factory/registration methods from in individual prompt files.
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.tsregisterResources(server, context)orchestrator; delegates to resource factory/registration methods from individual resource files, adding the minted-resource template on 2026-07-28.
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 positive integer; any other is not found (-32602). 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. - Gives each a one-hour public cache hint for 2026-07-28 reads.
- Registers static file-based resources for each file in the
minted.ts- 2026-07-28: stores resources tools create under server-minted URIs (
demo://resource/minted/<id>/<name>) for ten minutes, process-wide, and serves them through one template.
- 2026-07-28: stores resources tools create under server-minted URIs (
session.ts- 2025 era: registers resources tools create on the session's server instance (
demo://resource/session/<name>).
- 2025 era: registers resources tools create on the session's server instance (
subscriptions.ts- 2025 era: the
resources/subscribeandresources/unsubscribehandlers, and the timed updatestoggle-subscriber-updatesdrives.
- 2025 era: the
index.ts- Server factory that creates an
McpServerfor a protocol era (createServer({ era, publish })) with declared capabilities, cache hints and therequestStateverifier, loads server instructions, and registers tools, prompts, and resources for that era. - On the 2025 era, sets resource subscription handlers via
setSubscriptionHandlers(server, subscribed)and registers the capability-gated tools afterinitialize. - Exposes
{ server, cleanup }to the chosen transport. Cleanup stops any running intervals in the server when the connection ends.
- Server factory that creates an
context.ts- The per-instance context features receive: the era, the change publisher, the 2025-era subscriptions and a cleanup registry.
logging.ts- Implements simulated logging (2025 era). Periodically sends randomized log messages at various levels to the connected client. Started/stopped on demand via a dedicated tool.
roots.ts- 2025 era: syncs the client's roots after
initializeand onroots/list_changed, reporting each answer as a log message.
- 2025 era: syncs the client's roots after
tasks.ts- 2026-07-28: the server side of the tasks extension (
tasks/get,tasks/update,tasks/cancel) and the process-wide task store the task tools create tasks in.
- 2026-07-28: the server side of the tasks extension (
index.ts- Registration orchestrators, by era:
registerTools(server, context)(both),registerLegacyToolsandregisterConditionalTools(2025 era),registerModernTools(2026-07-28). Each delegates to the registration methods in individual tool files.
- Registration orchestrators, by era:
echo.ts- Registers an
echotool that takes a message and returnsEcho: {message}.
- Registers an
get-annotated-message.ts- Registers a
get-annotated-messagetool which demonstrates content-level annotations. Emits a primarytextmessage with contentannotations(priority,audience) that vary bymessageType("error" | "success" | "debug"), and optionally includes an annotatedimage(tiny PNG) whenincludeImageis true. All tools in this server include tool-level annotations (readOnlyHint,destructiveHint,idempotentHint,openWorldHint).
- Registers a
get-env.ts- Registers a
get-envtool that returns the current process environment variables as formatted JSON text; useful for debugging configuration. Values of credential-like names are masked as"<redacted>"unlessGET_ENV_INCLUDE_SECRETSis set to a truthy value.
- Registers a
get-header-params.ts- Registers a
get-header-paramstool with JSON Schema 2020-12 input and output schemas whoseregionargument carriesx-mcp-header; returns the argument and theMcp-Param-Regionheader it arrived in.
- Registers a
get-resource-links.ts- Registers a
get-resource-linkstool that returns an introtextblock followed by multipleresource_linkitems.
- Registers a
get-resource-reference.ts- Registers a
get-resource-referencetool that returns a reference for a selected dynamic resource.
- Registers a
get-roots-list.ts- Registers a
get-roots-listtool that asks the client for its roots with a multi-round-trip request and lists them.
- Registers a
gzip-file-as-resource.ts- Registers a
gzip-file-as-resourcetool that fetches content from a URL or data URI, compresses it, and then either:- returns a
resource_link(default) to a resource it can read later, or - returns an inline
resourcewith the gzipped data.
- returns a
- The linked resource is a per-session resource at
demo://resource/session/<name>(resources/session.ts) for a 2025-era client, and a minted one atdemo://resource/minted/<id>/<name>(resources/minted.ts) for a 2026-07-28 client, withmimeType: application/gzip. - Environment controls:
GZIP_MAX_FETCH_SIZE(bytes, default 10 MiB)GZIP_MAX_FETCH_TIME_MILLIS(ms, default 30000)GZIP_ALLOWED_DOMAINS(comma-separated name allowlist, checked on the caller's URL and on every redirect hop; empty means any name is allowed)GZIP_ALLOW_PRIVATE_IPS(1/trueto allow loopback, private, link-local and other non-public addresses; by default a host that resolves to one is refused, on every hop)
- Registers a
simulate-research-query.ts- 2026-07-28: registers a
simulate-research-querytool that runs as a task on the tasks extension, through four timed stages, pausing atinput_requiredfor a clarification on an ambiguous topic.
- 2026-07-28: registers a
trigger-elicitation-request.ts- Registers a
trigger-elicitation-requesttool that asks for a form with a multi-round-trip request and returns the elicitation result.
- Registers a
trigger-elicitation-request-async.ts- 2026-07-28: registers a
trigger-elicitation-request-asynctool that runs as a task waiting ininput_requiredfor a form elicitation.
- 2026-07-28: registers a
trigger-list-changed.ts- Registers a
trigger-list-changedtool that publishes a tools, prompts or resources list change.
- Registers a
trigger-log-messages.ts- Registers a
trigger-log-messagestool that sends one log message per level, filtered by the request's or session's log level.
- Registers a
trigger-multi-step-elicitation.ts- Registers a
trigger-multi-step-elicitationtool that asks two questions in sequence, carrying the first answer in a signedrequestState.
- Registers a
trigger-resource-update.ts- Registers a
trigger-resource-updatetool that publishes anotifications/resources/updatedfor a URI.
- Registers a
trigger-sampling-request-async.ts- 2026-07-28: registers a
trigger-sampling-request-asynctool that runs as a task waiting ininput_requiredfor a sampling request.
- 2026-07-28: registers a
trigger-url-elicitation.ts- On 2026-07-28, registers a
trigger-url-elicitationtool that returns its URL elicitation in-band (input_required). On the 2025 era, it either sends an out-of-band URL-modeelicitation/createrequest (mode: "url") including anelicitationId(request path) or throwsUrlElicitationRequiredError(-32042) for client-handled URL elicitation (error path). On the error path the carried prerequisite elicitation points at a different URL than the failing one (https://modelcontextprotocol.io), and when the client satisfies it and retries the same call, the retry ignoreserrorPathand proceeds via the request path — so the client does not loop on the same error.
- On 2026-07-28, registers a
trigger-sampling-request.ts- Registers a
trigger-sampling-requesttool that asks the client's LLM for a completion with a multi-round-trip request and returns the sampling result.
- Registers a
get-structured-content.ts- Registers a
get-structured-contenttool that demonstrates structuredContent block responses.
- Registers a
get-sum.ts- Registers a
get-sumtool with a Zod input schema that sums two numbersaandband returns the result.
- Registers a
get-tiny-image.ts- Registers a
get-tiny-imagetool, which returns a tiny PNG MCP logo as animagecontent item, along with surrounding descriptivetextitems.
- Registers a
trigger-long-running-operation.ts- Registers a
trigger-long-running-operationtool that simulates a long-running task over a specifiedduration(seconds) and number ofsteps; emitsnotifications/progressupdates when the client supplies aprogressToken.
- Registers a
toggle-simulated-logging.ts- 2025 era: registers a
toggle-simulated-loggingtool, which starts or stops simulated logging for the connection.
- 2025 era: registers a
toggle-subscriber-updates.ts- 2025 era: registers a
toggle-subscriber-updatestool, which starts or stops simulated resource subscription updates for the connection.
- 2025 era: registers a
in-memory-event-store.tsInMemoryEventStore: the Streamable HTTP transport's event store for resumability. Replays only the events of the stream aLast-Event-IDbelongs to, and reports an unknown event ID as having no stream, so the SDK refuses the resume.
listen.tslistenOrExit(app, port, listeningMessage): binds an Express app to its port for both HTTP transports.- Prints the listening message only once the port is bound; on a bind failure (such as a port already in use) prints why and exits non-zero.
stdio.ts- Serves
createServer({ era })over aStdioServerTransportwith the SDK'sserveStdio, which picks the connection's era from the client's first message. - Runs each instance's
cleanup()when it closes, and handlesSIGINTto close cleanly.
- Serves
sse.ts- Deprecated; 2025-era clients only. Warns on start.
- 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(from the frozen@modelcontextprotocol/server-legacy/ssebridge), created the server viacreateServer(), and connects it to a new transport. - On server disconnect, calls
cleanup()to remove any live intervals.
streamableHttp.ts- Express server exposing a single
/mcpendpoint for both protocol eras. - 2026-07-28: a session-less POST carrying the per-request envelope (classified by the SDK's
isLegacyRequest) is served bycreateMcpHandler, a fresh server per request, publishing change notifications on the handler's bus. - 2025 era: POST (JSON‑RPC), GET (SSE stream), and DELETE (session termination) using
NodeStreamableHTTPServerTransportfrom@modelcontextprotocol/node. - Uses an
InMemoryEventStorefor resumable sessions and tracks transports bysessionId. - Answers a request for an unknown or ended
Mcp-Session-Idwith404 Not Found, and closes every open session onSIGINT. - Connects a fresh server instance on initialization POST and reuses the transport for subsequent requests.
- Express server exposing a single