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

* Updated architecture.md

* Refactor/renamed resources/dynamic.ts to resources/template.ts
  - refactor/renamed registerDynamicResources to registerResourceTemplates
    - this highlights the more salient fact that we are demonstrating registration of resource templates in this example.
  - exposed the ability to dynamically create the text resources from elsewhere (namely the resource-prompt example

* Added prompts/resource.ts
  - in registerEmbeddedResourcePrompt()
    - register a prompt that takes a resourceId and returns the prompt with the corresponding dynamically created resource embedded
This commit is contained in:
cliffhall
2025-12-06 12:50:09 -05:00
parent 743529180e
commit 0aeb8a794d
5 changed files with 115 additions and 62 deletions

View File

@@ -2,6 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { registerSimplePrompt } from "./simple.js";
import { registerComplexPrompt } from "./complex.js";
import { registerPromptWithCompletions } from "./completions.js";
import { registerEmbeddedResourcePrompt } from "./resource.js"
/**
* Register the prompts with the MCP server.
@@ -11,4 +12,5 @@ export const registerPrompts = (server: McpServer) => {
registerSimplePrompt(server);
registerComplexPrompt(server);
registerPromptWithCompletions(server);
registerEmbeddedResourcePrompt(server);
};

View File

@@ -0,0 +1,51 @@
import { z } from "zod";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import {textResource, textResourceUri} from "../resources/template.js";
export const registerEmbeddedResourcePrompt = (server: McpServer) => {
// NOTE: Currently, prompt arguments can only be strings since type is not field of PromptArgument
// Consequently, we must define it as a string and convert the argument to number before using it
// https://modelcontextprotocol.io/specification/2025-11-25/schema#promptargument
const promptArgsSchema = {
resourceId: z.string().describe("ID of the text resource to fetch"),
};
server.registerPrompt(
"resource-prompt",
{
title: "Resource Prompt",
description: "A prompt that includes an embedded resource reference",
argsSchema: promptArgsSchema,
},
(args) => {
const resourceId = Number(args?.resourceId); // Inspector sends strings only
if (!Number.isFinite(resourceId) || !Number.isInteger(resourceId)) {
throw new Error(
`Invalid resourceId: ${args?.resourceId}. Must be a finite integer.`
);
}
const uri = textResourceUri(resourceId);
const resource = textResource(uri, resourceId);
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `This prompt includes the text resource with id: ${resourceId}. Please analyze the following resource:`,
},
},
{
role: "user",
content: {
type: "resource",
resource: resource,
},
},
],
};
}
);
};