add-mcp-resource

Add a new resource or resource template to an existing FastMCP server.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "add-mcp-resource" with this command: npx skills add jpoutrin/product-forge/jpoutrin-product-forge-add-mcp-resource

Add MCP Resource

Add a new resource or resource template to an existing FastMCP server.

Usage

/add-mcp-resource [resource-uri]

Arguments

  • [resource-uri] : Optional - URI pattern for the resource (will prompt if not provided)

Execution Instructions for Claude Code

When this command is run:

  • Locate the FastMCP server in the current project

  • Determine resource type (static or template)

  • Gather resource requirements through interactive questions

  • Generate resource code based on configuration

  • Add resource to server by modifying existing files

Interactive Session Flow

  1. Locate Server

Looking for FastMCP server...

Found: src/server.ts

Is this the correct server file? (yes/no):

  1. Resource Type

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):

  1. Static Resource Configuration

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):

  1. Resource Template Configuration

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):

  1. Content Type

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):

  1. Data Source

Where does the resource data come from?

  1. File system
  2. Database
  3. External API
  4. In-memory/computed
  5. Other

Select (1-5):

Generated Code Examples

Static Resource (Text)

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, }; }, });

Static Resource (Binary)

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"), }; }, });

Static Resource (Multiple Items)

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" }, ]; }, });

Resource Template (Basic)

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)}`,
};

}, });

Resource Template with Auto-Completion (Static)

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}}}, }; }, });

Resource Template with Dynamic Completion

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), }; }, });

Resource from File System

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 }; }, });

Resource from Database

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), }; }, });

Resource from External API

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),
};

}, });

File Placement

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):

Implementation Notes

  • Find existing server: Locate FastMCP server files

  • Check for resources directory: Create if needed

  • Generate imports: Add necessary imports

  • Insert code: Add resource at appropriate location

  • Match style: Preserve existing code formatting

  • Summary: Show generated resource and URI pattern

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

rfc-specification

No summary provided by upstream source.

Repository SourceNeeds Review
General

brainstorm-solution

No summary provided by upstream source.

Repository SourceNeeds Review
General

task-focus

No summary provided by upstream source.

Repository SourceNeeds Review
General

generate-tasks

No summary provided by upstream source.

Repository SourceNeeds Review