[WIP] Refactor everything server to be more modular and use recommended APIs.

* Updated architecture.md

* Refactor / renamed all addXPrompt, addXTool, and addXResource functions to registerX...

* Added the add tool
This commit is contained in:
cliffhall
2025-12-05 18:43:36 -05:00
parent d868b1c8ac
commit eee9866ebb
11 changed files with 59 additions and 23 deletions

View File

@@ -24,7 +24,8 @@ src/everything
│ └── streamableHttp.ts │ └── streamableHttp.ts
├── tools ├── tools
│ ├── index.ts │ ├── index.ts
── echo.ts ── echo.ts
│ └── add.ts
├── prompts ├── prompts
│ ├── index.ts │ ├── index.ts
│ ├── simple.ts │ ├── simple.ts
@@ -70,9 +71,11 @@ At `src/everything`:
- tools/ - tools/
- index.ts - index.ts
- `registerTools(server)` orchestrator, currently delegates to `addToolEcho`. - `registerTools(server)` orchestrator, currently delegates to `registerEchoTool` and `registerAddTool`.
- echo.ts - echo.ts
- Defines a minimal `echo` tool with a Zod input schema and returns `Echo: {message}`. - Defines a minimal `echo` tool with a Zod input schema and returns `Echo: {message}`.
- add.ts
- Defines an `add` tool with a Zod input schema that sums two numbers `a` and `b` and returns the result.
- prompts/ - prompts/
@@ -147,6 +150,7 @@ At `src/everything`:
- Tools - Tools
- `echo` (tools/echo.ts): Echoes the provided `message: string`. Uses Zod to validate inputs. - `echo` (tools/echo.ts): Echoes the provided `message: string`. Uses Zod to validate inputs.
- `add` (tools/add.ts): Adds two numbers `a` and `b` and returns their sum. Uses Zod to validate inputs.
- Prompts - Prompts
@@ -163,17 +167,17 @@ At `src/everything`:
- Adding Tools - Adding Tools
- Create a new file under `tools/` with your `addToolX(server)` function that registers the tool via `server.registerTool(...)`. - Create a new file under `tools/` with your `registerXTool(server)` function that registers the tool via `server.registerTool(...)`.
- Export and call it from `tools/index.ts` inside `registerTools(server)`. - Export and call it from `tools/index.ts` inside `registerTools(server)`.
- Adding Prompts - Adding Prompts
- Create a new file under `prompts/` with your `addXPrompt(server)` function that registers the prompt via `server.registerPrompt(...)`. - Create a new file under `prompts/` with your `registerXPrompt(server)` function that registers the prompt via `server.registerPrompt(...)`.
- Export and call it from `prompts/index.ts` inside `registerPrompts(server)`. - Export and call it from `prompts/index.ts` inside `registerPrompts(server)`.
- Adding Resources - Adding Resources
- Create a new file under `resources/` with your `addXResources(server)` function using `server.registerResource(...)` (optionally with `ResourceTemplate`). - Create a new file under `resources/` with your `registerXResources(server)` function using `server.registerResource(...)` (optionally with `ResourceTemplate`).
- Export and call it from `resources/index.ts` inside `registerResources(server)`. - Export and call it from `resources/index.ts` inside `registerResources(server)`.
- Adding Transports - Adding Transports

View File

@@ -2,7 +2,7 @@ import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { completable } from "@modelcontextprotocol/sdk/server/completable.js"; import { completable } from "@modelcontextprotocol/sdk/server/completable.js";
export const addPromptWithCompletions = (server: McpServer) => { export const registerPromptWithCompletions = (server: McpServer) => {
const promptArgsSchema = { const promptArgsSchema = {
department: completable(z.string(), (value) => { department: completable(z.string(), (value) => {
return ["Engineering", "Sales", "Marketing", "Support"].filter((d) => return ["Engineering", "Sales", "Marketing", "Support"].filter((d) =>

View File

@@ -1,7 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
export const addComplexPrompt = (server: McpServer) => { export const registerComplexPrompt = (server: McpServer) => {
const promptArgsSchema = { const promptArgsSchema = {
city: z.string().describe("Name of the city"), city: z.string().describe("Name of the city"),
state: z.string().describe("Name of the state").optional(), state: z.string().describe("Name of the state").optional(),

View File

@@ -1,14 +1,14 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { addSimplePrompt } from "./simple.js"; import { registerSimplePrompt } from "./simple.js";
import { addComplexPrompt } from "./complex.js"; import { registerComplexPrompt } from "./complex.js";
import { addPromptWithCompletions } from "./completions.js"; import { registerPromptWithCompletions } from "./completions.js";
/** /**
* Register the prompts with the MCP server. * Register the prompts with the MCP server.
* @param server * @param server
*/ */
export const registerPrompts = (server: McpServer) => { export const registerPrompts = (server: McpServer) => {
addSimplePrompt(server); registerSimplePrompt(server);
addComplexPrompt(server); registerComplexPrompt(server);
addPromptWithCompletions(server); registerPromptWithCompletions(server);
}; };

View File

@@ -1,6 +1,6 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
export const addSimplePrompt = (server: McpServer) => { export const registerSimplePrompt = (server: McpServer) => {
server.registerPrompt( server.registerPrompt(
"simple-prompt", "simple-prompt",
{ {

View File

@@ -18,7 +18,7 @@ import {
* *
* @param server * @param server
*/ */
export const addDynamicResources = (server: McpServer) => { export const registerDynamicResources = (server: McpServer) => {
const uriBase: string = "test://dynamic/resource"; const uriBase: string = "test://dynamic/resource";
const textUriBase: string = `${uriBase}/text`; const textUriBase: string = `${uriBase}/text`;
const blobUriBase: string = `${uriBase}/blob`; const blobUriBase: string = `${uriBase}/blob`;

View File

@@ -1,12 +1,12 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { addDynamicResources } from "./dynamic.js"; import { registerDynamicResources } from "./dynamic.js";
import { addStaticResources } from "./static.js"; import { registerStaticResources } from "./static.js";
/** /**
* Register the resources with the MCP server. * Register the resources with the MCP server.
* @param server * @param server
*/ */
export const registerResources = (server: McpServer) => { export const registerResources = (server: McpServer) => {
addDynamicResources(server); registerDynamicResources(server);
addStaticResources(server); registerStaticResources(server);
}; };

View File

@@ -15,7 +15,7 @@ const __dirname = dirname(__filename);
* *
* @param server * @param server
*/ */
export const addStaticResources = (server: McpServer) => { export const registerStaticResources = (server: McpServer) => {
const docsDir = join(__dirname, "..", "docs"); const docsDir = join(__dirname, "..", "docs");
let entries: string[] = []; let entries: string[] = [];

View File

@@ -0,0 +1,30 @@
import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
const AddSchema = z.object({
a: z.number().describe("First number"),
b: z.number().describe("Second number"),
});
const name = "add";
const config = {
title: "Add Tool",
description: "Adds two numbers",
inputSchema: AddSchema,
};
export const registerAddTool = (server: McpServer) => {
server.registerTool(name, config, async (args): Promise<CallToolResult> => {
const validatedArgs = AddSchema.parse(args);
const sum = validatedArgs.a + validatedArgs.b;
return {
content: [
{
type: "text",
text: `The sum of ${validatedArgs.a} and ${validatedArgs.b} is ${sum}.`,
},
],
};
});
};

View File

@@ -13,7 +13,7 @@ const config = {
inputSchema: EchoSchema, inputSchema: EchoSchema,
}; };
export const addToolEcho = (server: McpServer) => { export const registerEchoTool = (server: McpServer) => {
server.registerTool(name, config, async (args): Promise<CallToolResult> => { server.registerTool(name, config, async (args): Promise<CallToolResult> => {
const validatedArgs = EchoSchema.parse(args); const validatedArgs = EchoSchema.parse(args);
return { return {

View File

@@ -1,10 +1,12 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { addToolEcho } from "./echo.js"; import { registerEchoTool } from "./echo.js";
import { registerAddTool } from "./add.js";
/** /**
* Register the tools with the MCP server. * Register the tools with the MCP server.
* @param server * @param server
*/ */
export const registerTools = (server: McpServer) => { export const registerTools = (server: McpServer) => {
addToolEcho(server); registerEchoTool(server);
registerAddTool(server);
}; };