servers icon indicating copy to clipboard operation
servers copied to clipboard

Refactor Everything Server to use modern APIs

Open olaservo opened this issue 1 month ago • 2 comments

Summary

Following the discussion in #3017, this issue proposes a thoughtful refactoring of the Everything server to use modern TypeScript SDK APIs while serving as a clean, well-architected reference implementation.

Background

PR #3017 attempted to convert the Everything server to the modern McpServer API but was closed after encountering issues with several tools breaking and challenges with features requiring low-level SDK access. The PR discussion surfaced an important insight: this is a larger architectural task that would benefit from careful planning rather than a straightforward migration.

Why This Matters

The Everything server serves as more than just a test fixture—it's become a de facto reference implementation for MCP server features in TypeScript:

  • Learning resource: Developers often use it as a starting point for implementing specific MCP server features
  • Debugging aid: It's valuable for creating specific scenarios to reproduce issues or understand less-documented MCP features
  • Spec coverage: With the 2025-11-25 specification adding new features (elicitation, audio support, etc.), having a well-organized reference implementation becomes even more important
  • Onboarding: The MCP ecosystem is moving fast, and many tutorials/videos showing older SDK patterns are now outdated—a modern reference helps newcomers start correctly

Proposed Approach

Rather than a wholesale migration, we might want to consider an incremental, well-architected approach:

  1. Modular architecture: Organize features into logical modules that can be developed and tested independently
  2. Hybrid API usage: Use registerTool()/registerPrompt() for simple declarative cases, while clearly documenting where and why low-level setRequestHandler() is needed
  3. Clear documentation: Each feature should document which SDK patterns it demonstrates
  4. Incremental migration: Add/update features a few at a time with proper testing

Suggested Module Structure

My suggestion is to break down functionality into separate handler modules under a handlers/ directory:

src/everything/
├── index.ts              # Main entry point, server setup
├── handlers/
│   ├── tools.ts          # Tool definitions and handlers
│   ├── prompts.ts        # Prompt definitions and handlers
│   ├── resources.ts      # Resource definitions, templates, subscriptions
│   └── ...

Each handler module would export a setup function:

// handlers/tools.ts
export function setupToolHandlers(server: Server) {
  // Register simple tools with modern API
  // Register advanced tools with setRequestHandler where needed
}

// index.ts
import { setupToolHandlers } from "./handlers/tools.js";
import { setupPromptHandlers } from "./handlers/prompts.js";
import { setupResourceHandlers } from "./handlers/resources.js";

const server = new Server(...);
setupToolHandlers(server);
setupPromptHandlers(server);
setupResourceHandlers(server);

This structure:

  • Makes it easy to find examples of specific feature implementations
  • Keeps the main entry point clean and readable
  • Makes it easier to test

Transports:

  • stdio
  • SSE
  • Streamable HTTP

Open Questions

  1. What's the right level of granularity for modules?
  2. Should each feature include inline documentation explaining the SDK pattern being demonstrated?

Related

  • #3017 - Original migration PR (closed)
  • 2025-11-25 MCP specification updates

cc @domdomegg @gitenstuff


Originally written by Claude and edited by me

olaservo avatar Nov 26 '25 15:11 olaservo

What's the right level of granularity for modules?

If we're going modular, I think we should go all the way, e.g., each tool is its own file.

Also different resource "providers" perhaps. We currently spit out a bunch of text or blob resources and call it a day. That could be one provider. But another one could reflect an actual folder hierarchy with files as resources. Or dynamic resources (similar to my puzzlebox state machines) — in-memory constructs that can be changed by a tool. That would be the thing to subscribe to and send resource updates from rather than the fake ones we send now.

Should each feature include inline documentation explaining the SDK pattern being demonstrated?

IMO, this is made much easier if each feature is in its own file. In the monolith, we're dissuaded from documenting so much because it's just more scrolling to get to anything.

cliffhall avatar Nov 26 '25 21:11 cliffhall

The pluggable one file per tool concept sounds very smart.

For documentstion maybe short inline comments with links to relavant sections within a comprehensive mcp-concepts. md

gitenstuff avatar Nov 26 '25 22:11 gitenstuff

@olaservo I'm going to have a crack at this. We have several spec additions to make and I'd rather modularize and update first than make what we have more complicated.

cliffhall avatar Dec 03 '25 21:12 cliffhall

Ok, the refactor is complete: https://github.com/modelcontextprotocol/servers/pull/3121

cliffhall avatar Dec 13 '25 16:12 cliffhall

~~Gonna close this, I think https://github.com/modelcontextprotocol/servers/pull/3121 is better~~

EDIT: ignore me, got confused between this and my old PR 🤦

domdomegg avatar Dec 16 '25 21:12 domdomegg