A well-rounded MCP server doesn't just have tools — it also exposes Resources (data the AI can read) and Prompts (templates users can trigger).
// Static Resource: Server documentation
server.resource(
"server-readme",
"file:///docs/README.md",
{ description: "Server documentation and usage guide" },
async (uri) => ({
contents: [{
uri: uri.href,
text: "# Notes Server\n\nThis MCP server manages your markdown notes..."
}]
})
);
// Dynamic Resource Template: Individual notes
server.resourceTemplate(
"note",
"notes://note/{filename}",
{ description: "Read a specific note by filename" },
async (uri, { filename }) => {
const content = await readFile(
join(process.env.NOTES_DIR || "./notes", filename),
"utf-8"
);
return {
contents: [{ uri: uri.href, text: content }]
};
}
);
// Prompt: Summarize all notes on a topic
server.prompt(
"summarize_topic",
{
topic: z.string().describe("The topic to summarize across all notes")
},
({ topic }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `Search my notes for everything related to "${topic}" and create a comprehensive summary. Include key facts, dates, and action items. Organize by theme.`
}
}
]
})
);
// Prompt: Daily review
server.prompt(
"daily_review",
{},
() => ({
messages: [
{
role: "user",
content: {
type: "text",
text: "Review all my recent notes from the last 7 days. Summarize key decisions, flag overdue action items, and suggest priorities for today."
}
}
]
})
);
| Capability | User Interaction | LLM Interaction | Best For |
|---|---|---|---|
| Tool | Invisible (LLM calls it) | Can call autonomously | Actions, API calls, mutations |
| Resource | Can browse/attach in UI | Can read when attached | Files, configs, documentation |
| Prompt | Clicks to activate in UI | Receives as message context | Complex workflows, templates |