@microfox/tool-kit
Version:
A central tool kit for parsing Open Apis into MCP servers with Oauth Handling and HITL
424 lines (417 loc) • 13.9 kB
text/typescript
import { Tool as Tool$1, UIMessage, UIMessageStreamWriter, ToolUIPart, StopCondition, ToolCallPart, ToolSet as ToolSet$1 } from 'ai';
import { AgentOpenApi, JsonSchema, AgentPathAiInstruction, SecurityRequirementObject, HitlDetails, AgentUi } from '@microfox/types';
import { z } from 'zod';
import { ReadableStream } from 'stream/web';
type ToolMetaInfo = {
toolName?: string;
clientName?: string;
description?: string;
summary?: string;
_id?: string;
};
type Tool = Tool$1 & ToolMetaInfo & {
_id?: string;
};
type ToolSet = Record<string, Tool>;
declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "DELETE", "PATCH"];
type HttpMethod = (typeof HTTP_METHODS)[number];
type FormValues = Record<string, string>;
type OpenAPISchema = {
type?: string;
format?: string;
description?: string;
properties?: Record<string, OpenAPISchema>;
items?: OpenAPISchema;
required?: string[];
example?: any;
enum?: any[];
default?: any;
additionalProperties?: boolean | OpenAPISchema;
oneOf?: OpenAPISchema[];
anyOf?: OpenAPISchema[];
allOf?: OpenAPISchema[];
$ref?: string;
};
type OpenAPIParameter = {
name: string;
in: 'query' | 'path' | 'header' | 'cookie' | 'body' | string;
required?: boolean;
schema: OpenAPISchema;
description?: string;
example?: any;
};
type OpenAPIContent = {
schema: OpenAPISchema;
};
type OpenAPIResponse = {
description: string;
content?: {
[key: string]: OpenAPIContent;
};
};
type OpenAPIRequestBody = {
required?: boolean;
content: {
[key: string]: OpenAPIContent;
};
};
type OpenAPIOperation = {
name?: string;
summary?: string;
description?: string;
operationId?: string;
tags?: string[];
ai?: AgentPathAiInstruction;
security?: SecurityRequirementObject[];
hitl?: HitlDetails;
ui?: AgentUi;
parameters?: OpenAPIParameter[];
requestBody?: OpenAPIRequestBody;
responses: {
[key: string]: OpenAPIResponse;
};
instructions?: string;
method?: string;
path?: string;
};
type OpenAPIPath = {
[method: string]: OpenAPIOperation;
};
type OpenAPIDoc = AgentOpenApi;
type ToolMethod = {
name: string;
description: string;
inputSchema: JsonSchema & {
type: 'object';
};
returnSchema?: JsonSchema;
};
type ToolSchema = {
description?: string;
parameters: {
type: string;
properties: Record<string, any>;
required?: string[];
};
};
type ToolSchemas = Record<string, ToolSchema> | 'automatic';
type ToolExecuteFn = Tool['execute'];
type ToolMetadata = ToolMetaInfo & {
jsonSchema: JsonSchema & {
type: 'object';
};
humanLayer: {
required: boolean;
};
};
type ToolMetadataSet = Record<string, ToolMetadata>;
type ToolExecuteSet = Record<string, ToolExecuteFn>;
type SchemaConfig = {
/**
* Source of the OpenAPI schema
* - object: direct OpenAPIDoc object
* - text: JSON string of the schema
* - url: URL to fetch the schema from
*/
type: 'object' | 'text' | 'url';
/**
* The OpenAPI schema when type is 'object' or 'text'
*/
schema?: OpenAPIDoc | string;
/**
* URL to fetch the schema from when type is 'url'
*/
url?: string;
};
type AuthOptions = {
packages?: {
packageName: string;
packageConstructor?: string[];
}[];
customSecrets?: {
key: string;
description: string;
required: boolean;
type: string;
format?: string;
enum?: any[];
default?: any;
}[];
};
type AuthObject = {
encryptionKey?: string;
variables?: {
key: string;
value: string;
}[];
[key: string]: any;
};
interface OpenAPIToolsClientOptions {
/**
* Schema configuration
*/
schema: SchemaConfig | OpenAPIDoc | string;
/**
* Base URL to use for the client
* If provided, overrides the URL from the schema's servers array
*/
baseUrl?: string;
/**
* Custom headers to include with every request
*/
headers?: Record<string, string>;
/**
* Preset fields to include in request bodies
* These will be merged with the actual request data, with user-provided fields taking precedence
*/
presetBodyFields?: Record<string, any>;
/**
* Function called on API request errors
*/
onError?: (error: Error) => void;
/**
* Name of the client instance
*/
name?: string;
/**
* Static authentication object.
*/
auth?: AuthObject;
/**
* Function to dynamically fetch authentication credentials.
*/
getAuth?: (options: AuthOptions) => Promise<AuthObject>;
/**
* Callback to determine if human intervention is required for a tool call.
*/
getHumanIntervention?: (context: HumanInterventionContext) => Promise<HumanInterventionDecision>;
/**
* Function to dynamically fetch additional arguments for a tool call.
*/
getAdditionalArgs?: (args: {
toolName: string;
clientName: string;
summary?: string;
}) => Promise<z.ZodObject<any> | undefined>;
}
interface HumanInterventionContext {
toolName: string;
generatedArgs: Record<string, any>;
mcpConfig: any;
toolCallId: string;
auth?: AuthObject;
}
type HumanDecisionArgs = {
originalToolCallId?: string;
originalToolName?: string;
ui: any;
};
type HumanInterventionDecision = {
shouldPause: false;
} | {
shouldPause: true;
args: HumanDecisionArgs;
};
interface PendingToolContext {
originalToolCallId: string;
toolName: string;
originalArgs: object;
}
interface FetchOptions {
url: string;
method: string;
headers: Record<string, string>;
body?: string;
signal?: AbortSignal;
auth?: AuthObject;
getAuth?: () => Promise<AuthObject>;
getHumanIntervention?: (context: HumanInterventionContext) => Promise<HumanInterventionDecision>;
}
interface APIResponse {
data: any;
contentType: string;
status: number;
}
type ToolOptions = {
schemas?: ToolSchemas;
validateParameters?: boolean;
disabledExecutions?: string[];
disableAllExecutions?: boolean;
includeDisabled?: boolean;
auth?: AuthObject;
getAuth?: (options: AuthOptions) => Promise<AuthObject>;
cleanAuth?: (auth: AuthObject) => Promise<AuthObject>;
getHumanIntervention?: (context: HumanInterventionContext) => Promise<HumanInterventionDecision>;
getAdditionalArgs?: (args: {
toolName: string;
clientName: string;
summary?: string;
}) => Promise<z.ZodObject<any> | undefined>;
};
type ToolResult = {
tools: ToolSet;
executions: ToolExecuteSet;
metadata: ToolMetadataSet;
uiMaps?: Record<string, any>;
};
declare const PAUSED_TOOL_CONTEXT: unique symbol;
declare function isPausedToolContext(value: any): value is HumanInterventionContext;
type ToolAuth = {
type: 'oauth2' | 'apiKey';
};
/**
* Client for interacting with APIs described by OpenAPI schemas
* Provides methods for calling API operations and generating AI SDK-compatible tools
*/
declare class OpenApiToolset {
private clients;
private initialized;
private pendingTools;
private options;
constructor(options: OpenAPIToolsClientOptions | OpenAPIToolsClientOptions[]);
/**
* Add a tool to the pending map
*/
private addPendingTool;
/**
* Find and remove a pending tool from the map
*/
private consumePendingTool;
/**
* Initialize all clients
*/
init(): Promise<OpenApiToolset>;
/**
* List all available API operations from all OpenAPI schemas
*/
listOperations(): Promise<{
operations: {
id: string;
summary?: string;
description?: string;
parameters?: OpenAPIParameter[];
requestBody?: OpenAPIRequestBody;
path: string;
method: string;
}[];
}>;
/**
* Call a specific API operation from any client
*/
callOperation(id: string, args?: Record<string, any>, options?: any): Promise<APIResponse>;
/**
* Generates a combined system prompt from all OpenAPI schemas.
*/
generateSystemPrompt(): string;
/**
* Returns a set of tools generated from all OpenAPI schemas
*/
tools({ schemas, validateParameters, disabledExecutions, disableAllExecutions, auth, getAuth, getHumanIntervention, }?: ToolOptions): Promise<ToolResult>;
/**
* Parses incoming messages for HITL responses, resumes the original tool,
* and returns a cleaned message history.
* @param messages The full message history.
* @returns A promise that resolves to the processed message history.
*/
processHitlToolResult(messages: UIMessage[], options: {
dataStream?: UIMessageStreamWriter;
inserAuthVariables?: (auth: AuthObject) => Promise<AuthObject>;
mutateOutput?: (output: any, { part, uiMapper }: {
part: ToolUIPart;
uiMapper?: AgentUi;
}) => Promise<any>;
}): Promise<UIMessage[]>;
isHitlStep(): StopCondition<any>;
/**
* Processes a stream from `streamText`, transforming paused tool markers
* into `FAKE_HUMAN_INTERACTION` tool calls on the fly.
* @param resultStream The stream from `streamText`.
* @returns A new stream with HITL logic applied.
*/
stream(resultStream: ReadableStream, dataStream?: UIMessageStreamWriter): ReadableStream;
isHumanLoop(part: ToolCallPart): boolean;
ui(part: ToolCallPart): any;
}
/**
* Create an OpenAPI client for interacting with an API described by an OpenAPI schema
* The client can be used to call API operations directly or generate AI SDK-compatible tools
*
* @param options Client configuration options (single or array for multiple schemas)
* - schema: The OpenAPI schema configuration
* - baseUrl: Optional base URL to override schema servers
* - headers: Custom headers to include with every request
* - presetBodyFields: Fields to automatically include in request bodies (can be overridden by tool callers)
* - onError: Error handler function
* - name: Custom name for the client instance
* @returns OpenAPIToolsClient instance
*/
declare function createOpenApiToolset(options: OpenAPIToolsClientOptions | OpenAPIToolsClientOptions[]): Promise<OpenApiToolset>;
/**
* Parse and validate the schema configuration
*/
declare function parseSchema(config: SchemaConfig | OpenAPIDoc | string): Promise<OpenAPIDoc>;
/**
* Configuration for a single server, including its schema and how to connect to it.
*/
interface ServerConfig {
/**
* A unique identifier for this server/tool source (e.g., 'github', 'jira').
* This will be used to prefix tool names to prevent collisions.
*/
id: string;
/**
* The base URL for the API.
*/
baseUrl: string;
/**
* The OpenAPI schema document for this server.
*/
docData: OpenAPIDoc;
}
/**
* The client for managing and generating tools from multiple OpenAPI sources.
*/
interface MixedToolsClient {
/**
* Generates a unified ToolSet from all configured servers.
* @param options - Options to filter which tools are included.
*/
tools(options?: {
/**
* A function to dynamically filter tools. It receives the tool's original
* operationId and the serverId it belongs to. Return true to include the tool.
* e.g., (toolName, serverId) => serverId === 'github' && toolName.startsWith('get')
*/
filter?: (toolName: string, serverId: string) => boolean;
/**
* An alternative, simpler filter to include only tools whose names are in this array.
*/
toolNames?: string[];
/**
* Forwards the `disableAllExecutions` option to the underlying clients,
* requiring user approval before execution.
*/
disableAllExecutions?: boolean;
}): Promise<ToolSet$1>;
}
/**
* Creates a client that can manage tools from multiple OpenAPI schemas.
*
* @param configs - An array of server configurations.
* @returns A MixedToolsClient instance.
*/
declare function createMixedToolsClient(configs: ServerConfig[]): Promise<MixedToolsClient>;
/**
* Extracts auth options from an OpenAPI schema for a specific operation
* @param schema The complete OpenAPI schema
* @param operation The operation details or operation ID
* @returns Auth options including packages and custom secrets
*/
declare function getAuthOptions(schema: OpenAPIDoc, operation: OpenAPIOperation | string): AuthOptions;
/**
* Constructs headers from an auth object, including encryption of secrets
* @param auth The auth object containing encryption key and variables
* @returns Record of headers
*/
declare function constructHeaders(auth?: AuthObject): Record<string, string>;
export { type APIResponse, type AuthObject, type AuthOptions, type FetchOptions, type FormValues, HTTP_METHODS, type HttpMethod, type HumanDecisionArgs, type HumanInterventionContext, type HumanInterventionDecision, type MixedToolsClient, type OpenAPIContent, type OpenAPIDoc, type OpenAPIOperation, type OpenAPIParameter, type OpenAPIPath, type OpenAPIRequestBody, type OpenAPIResponse, type OpenAPISchema, type OpenAPIToolsClientOptions, OpenApiToolset, PAUSED_TOOL_CONTEXT, type PendingToolContext, type SchemaConfig, type ServerConfig, type Tool, type ToolAuth, type ToolExecuteFn, type ToolExecuteSet, type ToolMetaInfo, type ToolMetadata, type ToolMetadataSet, type ToolMethod, type ToolOptions, type ToolResult, type ToolSchema, type ToolSchemas, type ToolSet, constructHeaders, createMixedToolsClient, createOpenApiToolset, getAuthOptions, isPausedToolContext, parseSchema };