From typescript-experts
Adds static or template resources to existing FastMCP servers via interactive prompts for URI, name, MIME type, parameters, content type, and data source, generating TypeScript code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/typescript-experts:add-mcp-resourceThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Add a new resource or resource template to an existing FastMCP server.
Add a new resource or resource template to an existing FastMCP server.
/add-mcp-resource [resource-uri]
[resource-uri]: Optional - URI pattern for the resource (will prompt if not provided)When this command is run:
Looking for FastMCP server...
Found: src/server.ts
Is this the correct server file? (yes/no):
What type of resource do you want to add?
1. Static resource - Fixed URI (e.g., "file:///config/settings.json")
2. Resource template - Dynamic URI with parameters (e.g., "user://{id}/profile")
Select (1-2):
For static resources:
Resource URI:
Example: "file:///logs/app.log", "config://settings", "docs://readme"
URI:
Resource name (human-readable):
Example: "Application Logs", "Server Configuration"
Name:
MIME type:
1. text/plain
2. application/json
3. text/markdown
4. text/html
5. Other (specify)
Select (1-5):
Description (optional):
For resource templates:
URI template pattern:
Use {parameter} syntax for dynamic parts.
Examples:
- "file:///logs/{name}.log"
- "user://{userId}/profile"
- "docs://{category}/{page}"
URI template:
Resource name:
Example: "User Profiles", "Log Files"
Name:
Let's define the template parameters.
Parameter: {name}
Description:
Required? (yes/no):
Add auto-completion? (yes/no):
If auto-completion:
How should auto-completion work?
1. Static list of values
2. Dynamic lookup (I'll implement)
3. Prefix matching (e.g., "Ex" -> "Example")
Select (1-3):
What type of content does this resource return?
1. Text content
2. Binary content (base64 blob)
3. Multiple items (array of content)
Select (1-3):
Where does the resource data come from?
1. File system
2. Database
3. External API
4. In-memory/computed
5. Other
Select (1-5):
server.addResource({
uri: "{{uri}}",
name: "{{name}}",
mimeType: "{{mimeType}}",
description: "{{description}}",
async load() {
// TODO: Implement data loading
const content = await readFile("path/to/file");
return {
text: content,
};
},
});
server.addResource({
uri: "{{uri}}",
name: "{{name}}",
mimeType: "{{mimeType}}",
async load() {
// TODO: Load binary data
const buffer = await readFile("path/to/file");
return {
blob: buffer.toString("base64"),
};
},
});
server.addResource({
uri: "{{uri}}",
name: "{{name}}",
mimeType: "{{mimeType}}",
async load() {
// Return multiple content items
return [
{ text: "First section content" },
{ text: "Second section content" },
{ text: "Third section content" },
];
},
});
server.addResourceTemplate({
uriTemplate: "{{uriTemplate}}",
name: "{{name}}",
mimeType: "{{mimeType}}",
arguments: [
{{#each parameters}}
{
name: "{{name}}",
description: "{{description}}",
required: {{required}},
},
{{/each}}
],
async load(args) {
const { {{parameterNames}} } = args;
// TODO: Load resource based on parameters
return {
text: `Content for ${JSON.stringify(args)}`,
};
},
});
server.addResourceTemplate({
uriTemplate: "{{uriTemplate}}",
name: "{{name}}",
mimeType: "text/plain",
arguments: [
{
name: "{{paramName}}",
description: "{{paramDescription}}",
required: true,
complete: async (value) => {
// Static list of completions
const options = ["option1", "option2", "option3"];
const filtered = options.filter(opt =>
opt.toLowerCase().includes(value.toLowerCase())
);
return { values: filtered };
},
},
],
async load(args) {
return {
text: `Content for ${args.{{paramName}}}`,
};
},
});
server.addResourceTemplate({
uriTemplate: "{{uriTemplate}}",
name: "{{name}}",
mimeType: "application/json",
arguments: [
{
name: "{{paramName}}",
description: "{{paramDescription}}",
required: true,
complete: async (value) => {
// Dynamic lookup from database/API
const results = await searchItems(value);
return {
values: results.map(r => r.name),
};
},
},
],
async load(args) {
const item = await findItem(args.{{paramName}});
if (!item) {
return { text: "Not found" };
}
return {
text: JSON.stringify(item, null, 2),
};
},
});
import { readFile } from "fs/promises";
import { join } from "path";
server.addResourceTemplate({
uriTemplate: "file:///logs/{name}.log",
name: "Log Files",
mimeType: "text/plain",
arguments: [
{
name: "name",
description: "Name of the log file",
required: true,
complete: async (value) => {
// List available log files
const files = await readdir("/var/logs");
const logFiles = files
.filter(f => f.endsWith(".log"))
.map(f => f.replace(".log", ""));
return {
values: logFiles.filter(f => f.includes(value)),
};
},
},
],
async load(args) {
const filePath = join("/var/logs", `${args.name}.log`);
const content = await readFile(filePath, "utf-8");
return { text: content };
},
});
server.addResourceTemplate({
uriTemplate: "user://{userId}/profile",
name: "User Profiles",
mimeType: "application/json",
arguments: [
{
name: "userId",
description: "User ID",
required: true,
},
],
async load(args) {
const user = await db.users.findById(args.userId);
if (!user) {
return { text: JSON.stringify({ error: "User not found" }) };
}
return {
text: JSON.stringify({
id: user.id,
name: user.name,
email: user.email,
createdAt: user.createdAt,
}, null, 2),
};
},
});
server.addResourceTemplate({
uriTemplate: "weather://{city}",
name: "Weather Data",
mimeType: "application/json",
arguments: [
{
name: "city",
description: "City name",
required: true,
},
],
async load(args) {
const response = await fetch(
`https://api.weather.example/v1/${encodeURIComponent(args.city)}`
);
if (!response.ok) {
return { text: JSON.stringify({ error: "City not found" }) };
}
const data = await response.json();
return {
text: JSON.stringify(data, null, 2),
};
},
});
Where should the resource code be added?
1. Inline in server.ts
2. New file in resources/ directory
3. Existing resources file
Select (1-3):
npx claudepluginhub jpoutrin/product-forge --plugin typescript-expertsScaffolds MCP resource definitions with URI templates, Zod-validated params, and pagination support. Useful when adding a data endpoint or exposing data via URI in an MCP server.
Provides TypeScript patterns for FastMCP MCP servers: basic setup, tools with Zod schemas, logging, progress reporting, streaming output, multiple content types, and image handling.
Guides MCP server development with tool design, resource endpoints, prompt templates, and transport configuration using the MCP SDK.