-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Expand file tree
/
Copy pathcollections.ts
More file actions
104 lines (98 loc) · 3.13 KB
/
collections.ts
File metadata and controls
104 lines (98 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
/**
* Sample collection items
* - These items represent a simple product catalog for demonstration purposes
*/
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";
/**
* Helper to generate an item URI
* @param id
*/
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:
* - `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
*/
export const registerCollectionResources = (server: McpServer) => {
// Main collection resource returning all items
server.registerResource(
"Summer Specials Collection",
`${collectionUriBase}/summer-specials`,
{
mimeType: "application/json",
description:
"A collection resource that returns multiple items, each with its own URI.",
},
async () => {
return {
contents: collectionItems.map((item) => ({
uri: itemUri(item.id),
mimeType: "application/json",
text: JSON.stringify(item, null, 2),
})),
};
}
);
// Category-filtered collections
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.`,
},
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),
})),
};
}
);
}
// Individual item resources
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),
},
],
};
}
);
}
};