I have successfully created a regular/static resource template; however, I am having trouble developing a resource template that mirrors the structure and content of the TypeScript SDK repository on GitHub, specifically the README file’s “Resources” section.
LINK: https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#resources
// Dynamic resource with parameters
server.resource(
"user-profile",
new ResourceTemplate("users://{userId}/profile", { list: undefined }),
async (uri, { userId }) => ({
contents: [{
uri: uri.href,
text: `Profile data for user ${userId}`
}]
})
);Any suggestions on how to mimic this?
Activity
11@quuu Can you show me the code of how you are referencing it? I'm getting a bunch of type errors. It says it's expecting a string. Can't seem to get ResourceTemplate type either.
@quuu Can you show me the code of how you are referencing it? I'm getting a bunch of type errors. It says it's expecting a string. Can't seem to get ResourceTemplate type either.
here's my full code:
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { createMcpHandler } from "@vercel/mcp-adapter";
import { z } from "zod";
const handler = createMcpHandler(
(server) => {
server.tool(
"roll_dice",
"Rolls an N-sided die",
{ sides: z.number().int().min(2) },
async ({ sides }) => {
const value = 1 + Math.floor(Math.random() * sides);
return {
content: [{ type: "text", text: `🎲 You rolled a ${value}!` }],
};
}
);
server.resource(
"user-profile",
new ResourceTemplate("users://{userId}/profile", { list: undefined }),
async (uri, { userId }) => ({
contents: [
{
uri: uri.href,
text: `Profile data for user ${userId}`,
},
],
})
);
},
{},
{
redisUrl: process.env.REDIS_URL,
basePath: "/",
verboseLogs: true,
maxDuration: 800,
}
);
export { handler as GET, handler as POST, handler as DELETE };
Hey @quuu can you help how you manage to run it on the inspector I do have
import { gigsService } from '@/lib/services/GigsService';
import { createMcpHandler } from '@vercel/mcp-adapter';
import { z } from 'zod';
const handler = createMcpHandler(
(server) => {
// @ts-ignore
server.tool('list_gigs', 'List all gigs', {}, async () => {
const gigs = await gigsService.getGigs();
return {
content: [{ type: 'text', text: JSON.stringify(gigs) }],
};
});
},
{
// Optional server options
instructions: 'You are a helpful assistant that can list all gigs.',
},
{
// Optional redis config
redisUrl: process.env.REDIS_URL,
basePath: '/api/sse/gigs',
maxDuration: 800,
verboseLogs: true,
},
);
export { handler as GET, handler as POST, handler as DELETE };I'm seeing
on Request payload:
url: http://localhost:3000/api/sse/gigs/mcp
transportType: sseBut then on the response. I do see:
code: 405
event: {code: 405, message: "Non-200 status code (405)"}
code: 405
message: "Non-200 status code (405)"I see from the logs is trying to do GET
GET /api/sse/gigs/mcp 405 in 408mswhich I do have
export { handler as GET, handler as POST, handler as DELETE };
but still fails with 405 any suggestions
Hey @quuu can you help how you manage to run it on the inspector I do have
import { gigsService } from '@/lib/services/GigsService'; import { createMcpHandler } from '@vercel/mcp-adapter'; import { z } from 'zod'; const handler = createMcpHandler( (server) => { // @ts-ignore server.tool('list_gigs', 'List all gigs', {}, async () => { const gigs = await gigsService.getGigs(); return { content: [{ type: 'text', text: JSON.stringify(gigs) }], }; }); }, { // Optional server options instructions: 'You are a helpful assistant that can list all gigs.', }, { // Optional redis config redisUrl: process.env.REDIS_URL, basePath: '/api/sse/gigs', maxDuration: 800, verboseLogs: true, }, ); export { handler as GET, handler as POST, handler as DELETE };I'm seeing
on Request payload:
url: http://localhost:3000/api/sse/gigs/mcp transportType: sseBut then on the response. I do see:
code: 405 event: {code: 405, message: "Non-200 status code (405)"} code: 405 message: "Non-200 status code (405)"I see from the logs is trying to do GET
GET /api/sse/gigs/mcp 405 in 408mswhich I do have
export { handler as GET, handler as POST, handler as DELETE };
but still fails with 405 any suggestions
@AndonMitev whats the path of your mcp file?
Hey @quuu can you help how you manage to run it on the inspector I do have
import { gigsService } from '@/lib/services/GigsService'; import { createMcpHandler } from '@vercel/mcp-adapter'; import { z } from 'zod'; const handler = createMcpHandler( (server) => { // @ts-ignore server.tool('list_gigs', 'List all gigs', {}, async () => { const gigs = await gigsService.getGigs(); return { content: [{ type: 'text', text: JSON.stringify(gigs) }], }; }); }, { // Optional server options instructions: 'You are a helpful assistant that can list all gigs.', }, { // Optional redis config redisUrl: process.env.REDIS_URL, basePath: '/api/sse/gigs', maxDuration: 800, verboseLogs: true, }, ); export { handler as GET, handler as POST, handler as DELETE };I'm seeing on Request payload:
url: http://localhost:3000/api/sse/gigs/mcp transportType: sseBut then on the response. I do see:
code: 405 event: {code: 405, message: "Non-200 status code (405)"} code: 405 message: "Non-200 status code (405)"I see from the logs is trying to do GET
GET /api/sse/gigs/mcp 405 in 408mswhich I do have export { handler as GET, handler as POST, handler as DELETE }; but still fails with 405 any suggestions
@AndonMitev whats the path of your mcp file?
Hey @quuu
Path to the MCP entry point
app/api/sse/gigs/[...transport]/route.ts
@AndonMitev where do you see:
url: http://localhost:3000/api/sse/gigs/mcp
transportType: sseyour setup looks right, connecting to /api/sse/gigs/mcp will use StreamableHTTP though
while /api/sse/gigs/sse will use SSE
@AndonMitev where do you see:
url: http://localhost:3000/api/sse/gigs/mcp transportType: sseyour setup looks right, connecting to
/api/sse/gigs/mcpwill use StreamableHTTP though while/api/sse/gigs/ssewill use SSE
Ok sorry maybe I do not understand something, this is my code:
I've updated the path it's /api/mcp/gigs/[...transport]/route.ts
Inside the inspector I try with
http://localhost:3000/api/mcp/gigs/mcp or http://localhost:3000/api/mcp/gigs/sse
also switching between different transport types can't make it work with any, i gotta check what is streamable http is this the best way, better than sse ( I'm not sure if i'm running sse tbh xaxa) :)
@AndonMitev that looks right to me!
i'm writing up a longer article on the difference between SSE and StreamableHTTP, but they're different methods of transport
StreambleHTTP is the new way, SSE is getting deprecated
what is the exact error you see when you use those url's?
i created a similar set up to you and it's connecting fine
when StreamableHTTP is the transport, and i'm connecting to /api/mcp/gigs/mcp and SSE is the transport when I'm connecting to /api/mcp/gigs/sse
@AndonMitev that looks right to me!
i'm writing up a longer article on the difference between SSE and StreamableHTTP, but they're different methods of transport
StreambleHTTP is the new way, SSE is getting deprecated
what is the exact error you see when you use those url's?
i created a similar set up to you and it's connecting fine
when StreamableHTTP is the transport, and i'm connecting to /api/mcp/gigs/mcp and SSE is the transport when I'm connecting to /api/mcp/gigs/sse
@quuu with this setup,
I'm getting:
Connected to Streamable HTTP transport
Connected MCP client to server transport
Created streamable web app transport a03de765-b5b7-41c1-9ec3-36693db0bcd2
Error from MCP server: TypeError: fetch failed
at node:internal/deps/undici/undici:13502:13
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async StreamableHTTPClientTransport.send (file:///Users/andonmitev/.npm/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js:248:30) {
[cause]: AggregateError [ECONNREFUSED]:
at internalConnectMultiple (node:net:1139:18)
at afterConnectMultiple (node:net:1712:7) {
code: 'ECONNREFUSED',
[errors]: [ [Error], [Error] ]
}
}This is the full url: http://localhost:3000/api/mcp/gigs/mcp ( updated from api/sse to api/mcp but it's all good on claude and cursor is working perfectly fine all day actually just on the inspector fails :( )
Also version of the packages that I'm currently using:
"@vercel/mcp-adapter": "^0.9.1",
"@modelcontextprotocol/sdk": "1.12.0",any clue @quuu 🤔
@AndonMitev i know you're not testing in claude desktop, but I've seen similar reports from claude desktop where localhost isn't known by the client, and so you'd have to use your actual IP:
https://github.com/modelcontextprotocol/servers/issues/1065
let me know if using the actual ip works for you
@djshubs i just tried adding a resource and it worked well for me?
here's a screenshot of using the MCP Inspector to fetch the resource on my next.js MCP server:
let me know if you have a screen recording showing off a question or concern!