Skip to content

Refactor Everything Server to use modern APIs #3080

Closed

Description

@olaservo

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

cc @domdomegg @gitenstuff


Originally written by Claude and edited by me

Activity

  1. added
    enhancementNew feature or request
    help wantedExtra attention is needed
    server-everythingReference implementation for the Everything MCP server - src/everything
    on Nov 26, 2025
  2. cliffhall commented on Nov 26, 2025

    @cliffhall
    Member

    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.

  3. gitenstuff commented on Nov 26, 2025

    @gitenstuff

    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

  4. cliffhall commented on Dec 3, 2025

    @cliffhall
    Member

    @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.

  5. self-assigned this
    on Dec 3, 2025
  6. cliffhall commented on Dec 13, 2025

    @cliffhall
    Member

    Ok, the refactor is complete: #3121

  7. domdomegg commented on Dec 16, 2025

    @domdomegg
    Member

    Gonna close this, I think #3121 is better

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestserver-everythingReference implementation for the Everything MCP server - src/everything

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions