picomcpv0.1.2
Menu · Resources
Guides

Resources

Expose files, records and live data the client can read, with typed URI templates.

View .md Edit on GitHub

Resources are data the client can read and attach to a conversation: files, database rows, API responses. Tools are called by the model; resources are usually picked by the user or the application.

ts
server.resource("config://app", {
  description: "The app configuration",
  read: () => loadConfig(),
});

URI templates#

Put {variables} in the URI to serve a family of resources. The variables are typed from the string itself:

ts
server.resource("github://{owner}/{repo}/readme", {
  mimeType: "text/markdown",
  read: async ({ owner, repo }) => {
    //           ^? { owner: string; repo: string }
    const res = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/README.md`);
    return res.text();
  },
});
SyntaxMatchesExample
{name}One path segment, no /, ? or #users://{id} matches users://42
{+name}Anything, including /files://{+path} matches files://src/index.ts

Values are URL-decoded before they reach read. Static resources appear in resources/list, templates in resources/templates/list.

Return values#

read returnsContents sent
stringText, with mimeType or text/plain
Uint8ArrayBase64 blob, with mimeType or application/octet-stream
an array of { uri, text } or { uri, blob }Those contents as they are
any other valueIts JSON, as application/json

read receives the context as its second argument, with the requested uri added:

ts
read: (params, { uri, signal }) => fetch(toHttp(uri), { signal }).then((r) => r.text());

Options#

OptionDescription
nameIdentifier shown to users. Defaults to the URI.
titleDisplay name.
descriptionWhat the resource contains.
mimeTypeContent type of what read returns.
annotationsaudience, priority and lastModified hints.

Not found#

When no resource matches a URI, picomcp answers with the protocol's -32002 Resource not found error. To reject a URI that matches a template but points at nothing, throw an McpError with the same code:

ts
import { McpError } from "picomcp";

read: async ({ id }) => {
  const user = await db.users.find(id);
  if (!user) throw new McpError(-32002, `Resource not found: users://${id}`);
  return user;
};

Linking from tools#

A tool can point the model at a resource instead of inlining it, which keeps large data out of the context until it is needed:

ts
import { link } from "picomcp";

run: async () => link("reports://2026-q3", "Q3 report", { mimeType: "application/pdf" });