Skip to main content

Basic Usage

import { ResourceTemplate, ResourceContext } from '@frontmcp/sdk';

@ResourceTemplate({
  name: 'user-profile',
  uriTemplate: 'users://{userId}/profile',
  mimeType: 'application/json',
  description: 'User profile by ID',
})
class UserProfileResource extends ResourceContext<{ userId: string }> {
  async execute(uri: string, params: { userId: string }) {
    const user = await this.get(UserService).findById(params.userId);
    return {
      contents: [{
        uri,
        mimeType: 'application/json',
        text: JSON.stringify(user),
      }],
    };
  }
}

Signature

function ResourceTemplate(providedMetadata: ResourceTemplateMetadata): ClassDecorator

Configuration Options

Required Properties

PropertyTypeDescription
namestringUnique resource identifier
uriTemplatestringRFC 6570 URI template

Optional Properties

PropertyTypeDescription
titlestringHuman-readable title
descriptionstringResource description
mimeTypestringMIME type for all matching resources
iconsIcon[]Icons for display

URI Template Syntax

Templates follow RFC 6570 Level 1:
// Simple parameter
@ResourceTemplate({
  name: 'file',
  uriTemplate: 'file://{path}',
})

// Multiple parameters
@ResourceTemplate({
  name: 'repo-file',
  uriTemplate: 'github://{owner}/{repo}/{branch}/{path}',
})

// With path prefix
@ResourceTemplate({
  name: 'api-resource',
  uriTemplate: 'api://v1/resources/{resourceId}',
})

Parameter Extraction

Parameters are extracted automatically and passed to execute():
@ResourceTemplate({
  name: 'order-item',
  uriTemplate: 'orders://{orderId}/items/{itemId}',
})
class OrderItemResource extends ResourceContext<{ orderId: string; itemId: string }> {
  async execute(uri: string, params: { orderId: string; itemId: string }) {
    console.log(params.orderId); // "123"
    console.log(params.itemId);  // "456"
    // When requested: orders://123/items/456
  }
}

Function-Based Alternative

import { resourceTemplate } from '@frontmcp/sdk';

const userProfile = resourceTemplate({
  name: 'user-profile',
  uriTemplate: 'users://{userId}/profile',
  mimeType: 'application/json',
})((uri, params) => ({
  contents: [{
    uri,
    mimeType: 'application/json',
    text: JSON.stringify({ id: params.userId, name: 'John' }),
  }],
}));

vs Static Resource

Feature@Resource@ResourceTemplate
URIFixedTemplate with parameters
ParamsNoneExtracted from URI
Use caseSingle resourceCollection/dynamic resources
// Static: single config file
@Resource({
  name: 'app-config',
  uri: 'config://app',
})

// Template: any user's profile
@ResourceTemplate({
  name: 'user-profile',
  uriTemplate: 'users://{userId}/profile',
})

Full Example

import { ResourceTemplate, ResourceContext, App, FrontMcp } from '@frontmcp/sdk';

@ResourceTemplate({
  name: 'document',
  uriTemplate: 'docs://{category}/{documentId}',
  title: 'Document',
  description: 'Fetch documents by category and ID',
  mimeType: 'application/json',
})
class DocumentResource extends ResourceContext<{ category: string; documentId: string }> {
  async execute(uri: string, params: { category: string; documentId: string }) {
    this.mark('fetching');

    const docService = this.get(DocumentService);
    const doc = await docService.find(params.category, params.documentId);

    if (!doc) {
      this.fail(new ResourceNotFoundError(uri));
    }

    return {
      contents: [{
        uri,
        mimeType: 'application/json',
        text: JSON.stringify({
          id: doc.id,
          title: doc.title,
          category: params.category,
          content: doc.content,
          updatedAt: doc.updatedAt,
        }),
      }],
    };
  }
}

@ResourceTemplate({
  name: 'document-list',
  uriTemplate: 'docs://{category}',
  title: 'Document List',
  description: 'List documents in a category',
  mimeType: 'application/json',
})
class DocumentListResource extends ResourceContext<{ category: string }> {
  async execute(uri: string, params: { category: string }) {
    const docService = this.get(DocumentService);
    const docs = await docService.listByCategory(params.category);

    return {
      contents: [{
        uri,
        mimeType: 'application/json',
        text: JSON.stringify({
          category: params.category,
          documents: docs.map(d => ({ id: d.id, title: d.title })),
          total: docs.length,
        }),
      }],
    };
  }
}

@App({
  name: 'docs',
  resources: [DocumentResource, DocumentListResource],
})
class DocsApp {}

@FrontMcp({
  info: { name: 'Document Server', version: '1.0.0' },
  apps: [DocsApp],
})
export default class DocumentServer {}

@Resource

Static resources

ResourceContext

Context class details

ResourceRegistry

Resource registry API

Resource Errors

Resource-related errors