Skip to main content
Resources expose data that clients read by URI. Register one with server.resource(config, handler) — FastMCP auto-detects whether the URI is static or a template by checking for { in the URI string, so there’s no separate method to learn:
import { FastMCP } from '@prefecthq/fastmcp-ts/server'

const server = new FastMCP({ name: 'my-server' })

// Static resource
server.resource(
  { uri: 'config://settings', description: 'App configuration' },
  () => JSON.stringify({ theme: 'dark', lang: 'en' })
)

// URI template — extracted params are passed to the handler
server.resource(
  { uri: 'user://{id}', description: 'User by ID' },
  ({ id }) => `User #${id}`
)
Static resources are served via resources/list + resources/read. Templates appear in resources/templates/list and are matched at read time using RFC 6570 parameter extraction.

Template parameter styles

Three styles are supported:
StyleExampleMatches
Simpleuser://{id}A single path segment
Wildcardfiles://{path*}Multiple segments
Querysearch://items{?q,lang}Query-string parameters

Return values

Handler output is converted to an MCP ReadResourceResult automatically:
Returned valueConversion
stringText content (mimeType defaults to text/plain)
Buffer / Uint8ArrayBase64 blob content (mimeType defaults to application/octet-stream)
Plain object / arrayJSON-serialized text content (mimeType forced to application/json)
null / undefinedEmpty text content
ResourceResult(contents)Passed through as-is
ResourceResult is the escape hatch for full control over the contents array.

Config fields

FieldBehavior
uriRequired. Static URI or RFC 6570 template
name, title, descriptionDisplay metadata, forwarded in list responses
mimeTypeOverrides the inferred MIME type
sizeSize hint in bytes (static resources only — omitted from template listings, since it’s unknown for parameterized URIs)
annotationsaudience, priority, lastModified — forwarded verbatim
timeoutPer-read timeout in milliseconds
disabledHides the resource and rejects reads
tagsUsed by transforms
authPer-resource authorization check

Subscriptions

Clients can subscribe to a resource and be notified when it changes. On the client side:
await client.subscribeResource('config://settings', (uri) => {
  console.log(`${uri} changed — re-read it`)
})

await client.unsubscribeResource('config://settings')
The handler fires whenever the server sends notifications/resources/updated for that URI.

Dynamic registration

Like tools, resources can be registered before or after run() — adding one to a running server sends notifications/resources/list_changed automatically.