@tanstack/ai-mcp
Version:
Host-side Model Context Protocol client for TanStack AI: discover and run MCP server tools, resources, and prompts in any adapter's chat() loop, with generated end-to-end types.
986 lines (985 loc) • 35.1 kB
TypeScript
import { JSONSchema } from '@tanstack/ai';
import { AnyHarness, HarnessHost, HarnessUser } from '@tanstack/ai-harness';
import { OpenAccess } from '@tanstack/ai-harness/server';
import { MCPToolContext } from './server/context.js';
import { MCPHandleOptions } from './server/index.js';
export { mcp } from './harness-plugin.js';
export type { McpServerConfig, McpServerStatus } from './harness-plugin.js';
/** Options for {@link createHarnessMcpServer}. */
export interface HarnessMcpServerOptions<U extends HarnessUser = HarnessUser> {
/**
* The host that runs the sessions, from `createHarnessHost`. With
* `access`, `access.getUser` reads the user of each HTTP request, and the
* host checks each tool call of that user.
*/
host: HarnessHost<U>;
/** The harness to serve. */
harness: AnyHarness;
/**
* For a host without `access` only: who the tool calls run as. `true`:
* with no user (one user). `{ user }`: as that user, for
* example the one local user of a stdio server. Without host access and
* without this option, the server throws at the start, so it never serves
* every thread to everyone by mistake.
*/
openAccess?: OpenAccess<U>;
/** The conversation of a tool call that names no `threadId`. Default `'main'`. */
threadId?: string;
/**
* What happens when a turn stops for a tool call that needs approval.
* - `'ask'` (default): ask the user in the MCP client (elicitation). A
* client without elicitation gets the approvals in the result. It answers
* them with `approve`, `reject`, or `resolve`.
* - `'auto'`: approve every tool call.
*
* Both modes answer tool approvals only. When the turn also waits for
* another kind of interrupt, every interrupt comes back in the result. The
* client answers them all with one `resolve`.
*/
approvals?: 'ask' | 'auto';
/**
* The folders that a `path` attachment of `chat` can read from. A path must
* resolve, after every symlink, to a file inside one of them. Leave it out,
* and every `path` attachment is refused.
*
* The stdio CLI (`--mcp`) passes the working folder. An HTTP server should
* pass none, because a remote client must not read files on the server.
*/
filePaths?: ReadonlyArray<string>;
/** The MCP server name. Default: the harness name. */
name?: string;
/** The MCP server version. Default `'1.0.0'`. */
version?: string;
}
/** What a tool call of this server gets on `ctx.context`. */
type CallContext = MCPToolContext<Record<string, unknown>>;
/**
* Serves a harness as an MCP server, so any MCP client (Claude Code, Claude
* Desktop, Cursor, another agent) can use it.
*
* The tools are `chat`, `steer`, `cancel`, `approve`, `reject`, `resolve`,
* `answer`, and `status`, plus `agent_<name>` for each agent in
* `harness.expose.agents`, `command_<name>` for each plugin command in
* `harness.expose.commands`, and `tool_<name>` for each tool in
* `harness.expose.tools`.
* Every tool takes an optional `threadId`. Sessions open with
* `host.open(harness, { threadId, user })`, so the host checks each
* call. The `status` tool and the media resource only read: they use
* `host.observe`, so they open no session and mount no plugins.
*
* Who makes the calls:
*
* - A host with `access`: the user that `access.getUser` finds for each
* HTTP request. `null` gets a 401. A refused action is a tool error. Each
* spec 2025 session belongs to its user, and `handle` replaces the
* `authInfo` of its options for that. Such a server needs HTTP: over stdio
* it throws. The server lists the agents of the harness definition, and
* no commands or agents of plugins, as it opens no session at the start.
* - A host without `access`: the `openAccess` user, or no user
* with `openAccess: true`.
*
* The server throws at the start for a host without `access` and without
* `openAccess`, and for a host with both.
*
* A result lists the open waits of its work in `waits`, each with its
* `kind` (see `waitKind`): `approval`, `question`, `sign-in`,
* `client-tool`, or `human`. `interrupts` are the waits of a stopped turn,
* and `questions` the questions of the work. `approve` and `reject` answer
* the approvals of the turn only. `resolve` answers the interrupts of the
* turn, or the waits of a background agent run: `approved` for an
* approval, and `payload` for the others. `answer` answers a question.
*
* `chat` takes `attachments`: `{ path }` (only inside `filePaths`),
* `{ url, mimeType? }` (the model reads the URL, the server does not fetch
* it), or `{ data, mimeType }` (base64). A result lists the media that the
* work made in `media`. An image or audio file up to 5 MB comes back inline.
* Any other file comes back as a `resource_link` to
* `harness-media://<threadId>/<id>`, which `resources/read` returns.
*
* The result is the server from `createMCPServer`. Mount `server.fetch` on
* an HTTP route, or pass the server to `serveMCPStdio`.
*
* @param options - The host, the harness, who the calls run as, the default thread, the approval mode, and the folders for `path` attachments
*
* @example
* ```ts
* const server = await createHarnessMcpServer({
* host,
* harness: assistant,
* openAccess: { user: { id: 'local-user' } },
* })
* serveMCPStdio(server)
* ```
*/
export declare function createHarnessMcpServer<U extends HarnessUser = HarnessUser>(options: HarnessMcpServerOptions<U>): Promise<{
fetch: (request: Request) => Promise<Response>;
handle: (request: Request, handleOptions?: MCPHandleOptions) => Promise<Response>;
name: string;
version: string;
tools: readonly [] | readonly [import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "chat", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "steer", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "cancel", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "approve", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "reject", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "resolve", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "answer", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, import('@tanstack/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "status", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}, ...((import('/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, string, CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}) | (import('/ai').ServerTool<{
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
}, undefined, "append", CallContext, false, undefined> & {
inputSchema: {
type: string;
properties: {
threadId: JSONSchema;
};
items?: JSONSchema | Array<JSONSchema>;
required?: Array<string>;
enum?: Array<unknown>;
const?: unknown;
description?: string;
default?: unknown;
$ref?: string;
$defs?: Record<string, JSONSchema>;
definitions?: Record<string, JSONSchema>;
allOf?: Array<JSONSchema>;
anyOf?: Array<JSONSchema>;
oneOf?: Array<JSONSchema>;
not?: JSONSchema;
if?: JSONSchema;
then?: JSONSchema;
else?: JSONSchema;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;
exclusiveMaximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
format?: string;
minItems?: number;
maxItems?: number;
uniqueItems?: boolean;
additionalProperties?: boolean | JSONSchema;
additionalItems?: boolean | JSONSchema;
patternProperties?: Record<string, JSONSchema>;
propertyNames?: JSONSchema;
minProperties?: number;
maxProperties?: number;
title?: string;
examples?: Array<unknown>;
};
outputSchema: undefined;
approvalSchema: undefined;
}))[]];
resources: readonly [] | readonly [{
readonly uriTemplate: "harness-media://{threadId}/{id}";
readonly name: "media";
readonly mimeType: "application/octet-stream";
readonly argsSchema: {
readonly parse: typeof mediaAddress;
};
} & {
read: (uri: URL, variables: import('/server').Variables, ctx: import('./server/definitions.js').MCPResourceContext) => {
blob: string;
mimeType: string;
} | Promise<{
blob: string;
mimeType: string;
}>;
}];
prompts: [] | readonly [];
}>;
/**
* The thread and media id of a `harness-media://<threadId>/<id>` URI, from
* the template variables. `mediaUri` encodes both, so they are decoded here.
*/
declare function mediaAddress(variables: unknown): {
threadId: string;
id: string;
};