Askr documentation
Server & APIs

Primitives

Primitives at the Askr server boundary, with validated input and explicit failure states.

Example

const mcp = createMcpServer({ name: 'project-tools', version: '1.0.0' })
  .tool('lookup-project', { input: projectInput }, async (context, input) => {
    return { content: [{ type: 'text', text: await lookup(input.id) }] };
  });

Tools

A tool is registered with server.tool(name, { input, output, auth, ... }, handler); the handler receives an McpContext and the parsed input, and returns { content, structuredContent, isError }. If you declare an output schema and the handler sets structuredContent, the result is validated with safeParse too — a mismatch produces a JSON-RPC internal error rather than a silently wrong response. tools/list returns each tool's name, its declared options, inputSchema, and outputSchema when present, paginated with a numeric-string cursor.

Resources

server.resource(uri, options, handler) registers an exact-match URI; resources/read looks it up directly and calls the handler with the parsed URL. The handler can return a single McpContent object or a readonly array — the server normalizes either into a contents array in the response. resources/list returns { uri, name, ...options } for every visible resource, where name defaults to the URI itself if you don't set options.name.

Resource templates

server.resourceTemplate(template, options, handler) accepts a URI pattern with {name} placeholders; incoming reads are matched against every registered template with a generated regular expression, and the first match supplies the extracted variables to your handler. Templates also support an optional complete(argument, value) function used by completion/complete to return argument suggestions — the server caps returned values at 100 and reports hasMore if there were more. Unlike exact resources, template matching happens on every resources/read call whose URI isn't an exact registry hit, so keep templates reasonably specific to avoid ambiguous matches.

Prompts

server.prompt(name, options, handler) registers a named prompt whose arguments schema (an ObjectSchema, defaulting to empty) is parsed before the handler runs, mirroring tool input validation. The handler returns { description?, messages }, and prompts/list derives each argument's name, description, and required flag directly from the schema's JSON Schema properties and required array — there's no separate argument-metadata API to keep in sync. Invalid prompt arguments produce a -32602 JSON-RPC error with the schema's issues attached, the same shape tools use for invalid input.