Skip to content

Instantly share code, notes, and snippets.

@olaservo
Created December 14, 2025 15:21
Show Gist options
  • Select an option

  • Save olaservo/585b1ad042723a824b6a0e0e02ae60a8 to your computer and use it in GitHub Desktop.

Select an option

Save olaservo/585b1ad042723a824b6a0e0e02ae60a8 to your computer and use it in GitHub Desktop.
Example of MCP Resource Collection
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
/**
* Example items in a collection - simulating a product catalog
*/
const collectionItems = [
{ id: 1, name: "Summer Hat", price: 29.99, category: "accessories" },
{ id: 2, name: "Beach Towel", price: 19.99, category: "accessories" },
{ id: 3, name: "Sunglasses", price: 49.99, category: "accessories" },
{ id: 4, name: "Flip Flops", price: 14.99, category: "footwear" },
{ id: 5, name: "Sunscreen SPF50", price: 12.99, category: "skincare" },
];
const collectionUriBase = "demo://collection";
const itemUriBase = "demo://collection/item";
/**
* Create a URI for an individual item
*/
const itemUri = (id: number) => `${itemUriBase}/${id}`;
/**
* Register collection resources with the MCP server.
*
* This demonstrates the pattern where a single resources/read request
* returns multiple ResourceContents with different URIs - useful for
* modeling collections, indexes, or composite resources.
*
* Resources registered:
* - demo://collection/summer-specials: Returns all items as separate resources
* - demo://collection/by-category/{category}: Returns items filtered by category
* - demo://collection/item/{id}: Returns a single item (for individual access)
*
* @param server The MCP server instance
*/
export const registerCollectionResources = (server: McpServer) => {
// Register the main collection resource
// When read, returns ALL items as separate ResourceContents with distinct URIs
server.registerResource(
"Summer Specials Collection",
`${collectionUriBase}/summer-specials`,
{
mimeType: "application/json",
description:
"A collection resource that returns multiple items, each with its own URI. " +
"Demonstrates the pattern where one resources/read request returns multiple " +
"ResourceContents with different URIs.",
},
async () => {
// Return all items, each with its own distinct URI
return {
contents: collectionItems.map((item) => ({
uri: itemUri(item.id),
mimeType: "application/json",
text: JSON.stringify(item, null, 2),
})),
};
}
);
// Register a filtered collection by category
// Demonstrates parameterized collection access
const categories = [...new Set(collectionItems.map((i) => i.category))];
for (const category of categories) {
server.registerResource(
`Collection: ${category}`,
`${collectionUriBase}/by-category/${category}`,
{
mimeType: "application/json",
description: `Items in the "${category}" category. Returns multiple items with distinct URIs.`,
},
async () => {
const filtered = collectionItems.filter((i) => i.category === category);
return {
contents: filtered.map((item) => ({
uri: itemUri(item.id),
mimeType: "application/json",
text: JSON.stringify(item, null, 2),
})),
};
}
);
}
// Register individual item resources for direct access
for (const item of collectionItems) {
server.registerResource(
`Item: ${item.name}`,
itemUri(item.id),
{
mimeType: "application/json",
description: `Individual item: ${item.name} ($${item.price})`,
},
async (uri) => {
return {
contents: [
{
uri: uri.toString(),
mimeType: "application/json",
text: JSON.stringify(item, null, 2),
},
],
};
}
);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment