Create xmcp Resource
You are helping the user create a new xmcp resource. Follow this interactive workflow.
Step 1: Gather Information
Before generating any code, ask the user these questions using AskUserQuestion:
-
Resource name (if not provided): What should the resource be named? (Use kebab-case)
-
Resource type: Ask which type of resource they need:
- Static - Fixed content that doesn't change (configuration, documentation)
- Dynamic - Content that depends on parameters (user profiles, reports)
- File-based - Content read from files (logs, data files)
-
URI pattern: How should the resource be accessed?
- Simple:
config://appordocs://readme - With parameters:
users://[userId]/profile - Nested:
reports://[year]/[month]/summary
- Simple:
-
Content details:
- What is the content about?
-
Widget support (optional): Ask if they need OpenAI widget rendering.
Step 2: Generate the Resource
Create the resource file in src/resources/ following the routing conventions:
File Location & Routing
Resources use file-based routing similar to Next.js:
src/resources/
├── (config)/ # Route group (not in URI)
│ └── app.ts # → config://app
├── (users)/
│ └── [userId]/ # Dynamic segment
│ └── profile.ts # → users://[userId]/profile
└── docs/
└── readme.ts # → docs://readme
Routing conventions:
(folder)- Route group, excluded from URI path[param]- Dynamic parameter segment- Filename becomes the final URI segment
Resource Structure Reference
Every xmcp resource has two main exports:
// 1. Metadata (optional) - Resource configuration
export const metadata: ResourceMetadata = { /* ... */ };
// 2. Handler (required) - Default export function
export default function handler(params?) { /* ... */ }
// 3. Schema (optional) - For dynamic resources with parameters
export const schema = { /* ... */ };
Quick Reference
Essential Imports
import { type ResourceMetadata } from "xmcp";
// For dynamic resources
import { z } from "zod";
import { type InferSchema, type ResourceMetadata } from "xmcp";
Metadata Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No* | Unique resource identifier |
title | string | No | Human-readable title |
description | string | No | What this resource provides |
mimeType | string | No | Content type (default: text/plain) |
size | number | No | Content size in bytes |
_meta | object | No | Vendor extensions (OpenAI, etc.) |
*When metadata is omitted, xmcp uses the filename as the resource name.
Handler Return Types
| Return Type | Use Case |
|---|---|
string | Simple text content |
{ text: string } | Explicit text content |
{ blob: Uint8Array, mimeType: string } | Binary content |
JSON.stringify(data) | JSON content |
Detailed Templates
For complete code templates including:
- Static resource patterns
- Dynamic resource with parameters
- File-based resources
- Nested routing examples
- OpenAI metadata examples
Read: references/patterns.md
Checklist After Generation
- File created in correct
src/resources/location - If using metadata, ensure it has descriptive
nameanddescription - Schema uses
.describe()for all parameters (if dynamic) - Handler returns appropriate content type
- File path matches intended URI pattern
Suggest running pnpm build to verify the resource compiles correctly.