AgentStack
SKILL verified MIT Self-run

Mcp Resource Patterns

skill-versoxbt-claude-initial-setup-mcp-resource-patterns · by VersoXBT

>

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-versoxbt-claude-initial-setup-mcp-resource-patterns

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Mcp Resource Patterns? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

MCP Resource Patterns

Patterns for designing and implementing MCP resources. Covers URI design, templates, subscriptions, dynamic resources, MIME types, and context provision strategies.

When to Use

  • User is exposing data as MCP resources (files, configs, database records)
  • User is designing resource URI schemes
  • User needs parameterized resource templates
  • User wants real-time resource updates via subscriptions
  • User is providing contextual data to Claude through resources

Core Patterns

Static Resources

Expose fixed data sources that Claude can read for context.

import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });

// Static resource with a fixed URI
server.resource(
  "project-config",
  "config://project",
  { description: "Project configuration including build settings and dependencies." },
  async (uri) => ({
    contents: [{
      uri: uri.href,
      mimeType: "application/json",
      text: JSON.stringify(await loadProjectConfig(), null, 2)
    }]
  })
);

// Static resource for a text file
server.resource(
  "readme",
  "file:///project/README.md",
  { description: "Project README with setup instructions and architecture overview." },
  async (uri) => ({
    contents: [{
      uri: uri.href,
      mimeType: "text/markdown",
      text: await fs.readFile("README.md", "utf-8")
    }]
  })
);

Resource Templates

Parameterized URIs that resolve to specific resources based on input.

// Template with a parameter
server.resource(
  "user-profile",
  new ResourceTemplate("users://{userId}/profile", { list: undefined }),
  { description: "User profile data by user ID." },
  async (uri, { userId }) => {
    const user = await db.users.findById(userId);
    if (!user) {
      return { contents: [] };  // Empty contents signals not found
    }
    return {
      contents: [{
        uri: uri.href,
        mimeType: "application/json",
        text: JSON.stringify({
          id: user.id,
          name: user.name,
          email: user.email,
          role: user.role
        }, null, 2)
      }]
    };
  }
);

// Template with list callback for discovery
server.resource(
  "log-file",
  new ResourceTemplate("logs://{date}/{level}", {
    list: async () => {
      const dates = await getAvailableLogDates();
      return dates.flatMap(date =>
        ["info", "warn", "error"].map(level => ({
          uri: `logs://${date}/${level}`,
          name: `${date} ${level} logs`,
          description: `${level}-level logs from ${date}`
        }))
      );
    }
  }),
  { description: "Application logs filtered by date and level." },
  async (uri, { date, level }) => ({
    contents: [{
      uri: uri.href,
      mimeType: "text/plain",
      text: await readLogFile(date, level)
    }]
  })
);

Resource Subscriptions

Notify clients when resource content changes.

# Python - resource with subscription support
from mcp.server import Server
import mcp.types as types

server = Server("my-server")

@server.list_resources()
async def list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri="metrics://system/health",
            name="System Health",
            description="Real-time system health metrics.",
            mimeType="application/json"
        )
    ]

@server.read_resource()
async def read_resource(uri: str) -> str:
    if uri == "metrics://system/health":
        metrics = await collect_system_metrics()
        return json.dumps(metrics)
    raise ValueError(f"Unknown resource: {uri}")

# Notify subscribers when metrics change
async def on_metrics_update():
    await server.request_context.session.send_resource_updated(
        uri="metrics://system/health"
    )

Dynamic Resource Lists

Generate resource lists dynamically based on current state.

// List resources dynamically from a database
server.resource(
  "db-table",
  new ResourceTemplate("db://{schema}/{table}", {
    list: async () => {
      const tables = await db.query(
        "SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema')"
      );
      return tables.map(t => ({
        uri: `db://${t.table_schema}/${t.table_name}`,
        name: `${t.table_schema}.${t.table_name}`,
        description: `Database table ${t.table_schema}.${t.table_name}`,
        mimeType: "application/json"
      }));
    }
  }),
  { description: "Database table schema and sample data." },
  async (uri, { schema, table }) => {
    const columns = await db.getColumns(schema, table);
    const sample = await db.query(`SELECT * FROM "${schema}"."${table}" LIMIT 5`);
    return {
      contents: [{
        uri: uri.href,
        mimeType: "application/json",
        text: JSON.stringify({ columns, sample_rows: sample }, null, 2)
      }]
    };
  }
);

MIME Types

Choose the right MIME type for resource content.

// Common MIME types for MCP resources
const mimeTypes = {
  "application/json":    "Structured data, API responses, configs",
  "text/plain":          "Logs, raw text, CLI output",
  "text/markdown":       "Documentation, READMEs, notes",
  "text/html":           "Web content (use sparingly)",
  "application/xml":     "XML configs, SOAP responses",
  "text/csv":            "Tabular data, exports",
  "application/pdf":     "Binary documents (base64 encoded)",
  "image/png":           "Screenshots, diagrams (base64 encoded)",
};

// Binary content uses base64 encoding
server.resource("screenshot", "screen://current", {}, async (uri) => ({
  contents: [{
    uri: uri.href,
    mimeType: "image/png",
    blob: await captureScreenBase64()  // base64-encoded string
  }]
}));

Anti-Patterns

  • Using opaque IDs in URIs instead of human-readable paths (res://abc123 vs users://42/profile)
  • Not implementing the list callback on templates (Claude cannot discover available resources)
  • Returning massive resources without summarization (floods context window)
  • Using text/plain for structured data that should be JSON
  • Not handling missing resources (return empty contents, do not throw)
  • Exposing sensitive data (secrets, credentials) through resources without access control
  • Making resource reads slow by including expensive computations (cache instead)

Quick Reference

| Concept | Pattern | |---------|---------| | Static resource | Fixed URI, single data source | | Resource template | Parameterized URI with {param} syntax | | List callback | Discovery function returning available resources | | Subscription | Server pushes updates when content changes | | Binary content | Use blob field with base64, set correct MIME type |

URI scheme conventions:

file:///path/to/file          # Local files
db://{schema}/{table}         # Database objects
config://{section}            # Configuration
logs://{date}/{level}         # Log entries
metrics://{category}          # Monitoring data
repo://{owner}/{name}         # Repository data

Checklist: human-readable URIs, descriptive descriptions, correct MIME types, list callbacks for discoverability, concise content, redacted sensitive data.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.