CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-modelcontextprotocol--sdk

TypeScript SDK for implementing the Model Context Protocol, enabling developers to build MCP servers and clients with support for multiple transports, tools, resources, prompts, and authentication

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

server-resources.mddocs/

Server Resources API

Resources expose data to LLMs without side effects. Resources are application-driven or user-driven (not model-controlled). Can be static (fixed URIs) or dynamic (URI templates).

Static Resources

server.registerResource(
  name: string,
  uri: string,
  config: {
    title?: string;
    description?: string;
    mimeType?: string;
    icons?: Icons;
    _meta?: Record<string, unknown>;
  },
  readCallback: (uri: URL) => Promise<ReadResourceResult> | ReadResourceResult
): RegisteredResource;

Examples

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import fs from 'fs/promises';

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

// Config resource
server.registerResource('config', 'config://app', {
  title: 'Application Config',
  description: 'Application configuration data',
  mimeType: 'application/json'
}, async (uri) => ({
  contents: [{
    uri: uri.href,
    mimeType: 'application/json',
    text: JSON.stringify({ setting1: 'value1', setting2: 'value2' })
  }]
}));

// File resource
server.registerResource('readme', 'file:///project/README.md', {
  title: 'Project README',
  description: 'Project documentation',
  mimeType: 'text/markdown'
}, async (uri) => ({
  contents: [{
    uri: uri.href,
    mimeType: 'text/markdown',
    text: await fs.readFile('/project/README.md', 'utf-8')
  }]
}));

Dynamic Resources (URI Templates)

server.registerResource(
  name: string,
  template: ResourceTemplate,
  config: { title?: string; description?: string; mimeType?: string; icons?: Icons; _meta?: Record<string, unknown>; },
  readCallback: (uri: URL, variables: Variables) => Promise<ReadResourceResult> | ReadResourceResult
): RegisteredResourceTemplate;

ResourceTemplate Class

import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
import { UriTemplate, Variables } from '@modelcontextprotocol/sdk/shared/uriTemplate.js';

class ResourceTemplate {
  constructor(
    uriTemplate: string | UriTemplate,
    callbacks: {
      list?: (cursor?: string) => Promise<Resource[]> | Resource[];
      complete?: {
        [variable: string]: (value: string, context?: { arguments?: Record<string, unknown> }) => Promise<string[]> | string[];
      };
    }
  );
  get uriTemplate(): UriTemplate;
  get listCallback(): ListResourcesCallback | undefined;
  completeCallback(variable: string): CompleteResourceTemplateCallback | undefined;
}

// UriTemplate (RFC 6570)
class UriTemplate {
  constructor(template: string);
  match(uri: string): Variables | undefined;      // Extract variables
  expand(variables: Variables): string;           // Expand template
  toString(): string;
}

type Variables = Record<string, string>;

Examples

// User profile with template
server.registerResource('user-profile',
  new ResourceTemplate('users://{userId}/profile', { list: undefined }),
  { title: 'User Profile' },
  async (uri, { userId }) => {
    const profile = await db.getUserProfile(userId);
    return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(profile) }] };
  }
);

// Repository files with template
server.registerResource('repo-file',
  new ResourceTemplate('github://repos/{owner}/{repo}/files/{path}', { list: undefined }),
  { title: 'GitHub Repository File' },
  async (uri, { owner, repo, path }) => {
    const content = await github.getFile(owner, repo, path);
    return { contents: [{ uri: uri.href, mimeType: 'text/plain', text: content }] };
  }
);

// Template with listing
server.registerResource('project-files',
  new ResourceTemplate('file:///project/{path}', {
    list: async (cursor) => {
      const files = await listProjectFiles(cursor);
      return files.map(file => ({
        uri: `file:///project/${file.path}`,
        name: file.name,
        description: file.description,
        mimeType: file.mimeType
      }));
    }
  }),
  { title: 'Project Files' },
  async (uri, { path }) => {
    const content = await fs.readFile(`/project/${path}`, 'utf-8');
    return { contents: [{ uri: uri.href, text: content }] };
  }
);

// Template with completion
server.registerResource('repository',
  new ResourceTemplate('github://repos/{owner}/{repo}', {
    list: undefined,
    complete: {
      repo: (value, context) => {
        const owner = context?.arguments?.['owner'];
        if (owner === 'anthropics') {
          return ['claude-sdk', 'typescript-sdk', 'python-sdk'].filter(r => r.startsWith(value));
        }
        return ['default-repo'].filter(r => r.startsWith(value));
      }
    }
  }),
  { title: 'GitHub Repository' },
  async (uri, { owner, repo }) => ({
    contents: [{ uri: uri.href, text: `Repository: ${owner}/${repo}` }]
  })
);

Return Values

interface ReadResourceResult {
  contents: ResourceContents[];
  _meta?: Record<string, unknown>;
}

type ResourceContents = TextResourceContents | BlobResourceContents;

interface TextResourceContents {
  uri: string;
  mimeType?: string;
  text: string;
}

interface BlobResourceContents {
  uri: string;
  mimeType?: string;
  blob: string;  // Base64 encoded
}

Examples

// Text resource
return {
  contents: [{ uri: uri.href, mimeType: 'text/plain', text: 'Resource content here' }]
};

// JSON resource
return {
  contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify({ key: 'value' }) }]
};

// Binary resource (image)
return {
  contents: [{ uri: uri.href, mimeType: 'image/png', blob: base64EncodedImageData }]
};

// Multiple contents
return {
  contents: [
    { uri: 'file:///project/README.md', mimeType: 'text/markdown', text: readmeContent },
    { uri: 'file:///project/LICENSE', mimeType: 'text/plain', text: licenseContent }
  ]
};

Managing Resources

interface RegisteredResource {
  enable(): void;
  disable(): void;
  remove(): void;
}

interface RegisteredResourceTemplate {
  enable(): void;
  disable(): void;
  remove(): void;
}

Example

const resource = server.registerResource('data', 'app://data', config, callback);
resource.disable();
resource.enable();
resource.remove();

Subscriptions

Requires server capability declaration:

const server = new McpServer(
  { name: 'my-server', version: '1.0.0' },
  {
    capabilities: {
      resources: {
        subscribe: true,      // Enable subscriptions
        listChanged: true     // Enable list change notifications
      }
    }
  }
);

Notification Methods

server.sendResourceUpdated(params: { uri: string }): Promise<void>;
server.sendResourceListChanged(): Promise<void>;

Example

// Notify about specific resource update
await server.sendResourceUpdated({ uri: 'config://app' });

// Notify that resource list changed
await server.sendResourceListChanged();

Types Reference

interface Resource {
  uri: string;
  name: string;
  title?: string;
  description?: string;
  mimeType?: string;
  icons?: Icons;
  _meta?: Record<string, unknown>;
}

interface ResourceTemplate {
  uriTemplate: string;
  name: string;
  title?: string;
  description?: string;
  mimeType?: string;
  icons?: Icons;
  _meta?: Record<string, unknown>;
}

interface ListResourcesResult {
  resources: Resource[];
  nextCursor?: string;
}

interface ListResourceTemplatesResult {
  resourceTemplates: ResourceTemplate[];
  nextCursor?: string;
}

interface Icons {
  icon?: Icon;
  light?: Icon;
  dark?: Icon;
}

interface Icon {
  src: string;
  mimeType?: string;
  size?: string;
}

Legacy API

server.resource(name: string, uri: string, readCallback: ReadResourceCallback): RegisteredResource;
server.resource(name: string, uri: string, metadata: ResourceMetadata, readCallback: ReadResourceCallback): RegisteredResource;
server.resource(name: string, template: ResourceTemplate, readCallback: ReadResourceTemplateCallback): RegisteredResourceTemplate;
server.resource(name: string, template: ResourceTemplate, metadata: ResourceMetadata, readCallback: ReadResourceTemplateCallback): RegisteredResourceTemplate;

Use registerResource for new code.

docs

authentication.md

client.md

index.md

server-advanced.md

server-prompts.md

server-resources.md

server-tools.md

transports.md

types.md

tile.json