index.d.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. import { Protocol, type ProtocolOptions, type RequestOptions } from '../shared/protocol.js';
  2. import type { Transport } from '../shared/transport.js';
  3. import { type CallToolRequest, CallToolResultSchema, type ClientCapabilities, type ClientNotification, type ClientRequest, type ClientResult, type CompatibilityCallToolResultSchema, type CompleteRequest, type GetPromptRequest, type Implementation, type ListPromptsRequest, type ListResourcesRequest, type ListResourceTemplatesRequest, type ListToolsRequest, type LoggingLevel, type ReadResourceRequest, type ServerCapabilities, type SubscribeRequest, type UnsubscribeRequest, type ListChangedHandlers, type Request, type Notification, type Result } from '../types.js';
  4. import type { jsonSchemaValidator } from '../validation/types.js';
  5. import { AnyObjectSchema, SchemaOutput } from '../server/zod-compat.js';
  6. import type { RequestHandlerExtra } from '../shared/protocol.js';
  7. import { ExperimentalClientTasks } from '../experimental/tasks/client.js';
  8. /**
  9. * Determines which elicitation modes are supported based on declared client capabilities.
  10. *
  11. * According to the spec:
  12. * - An empty elicitation capability object defaults to form mode support (backwards compatibility)
  13. * - URL mode is only supported if explicitly declared
  14. *
  15. * @param capabilities - The client's elicitation capabilities
  16. * @returns An object indicating which modes are supported
  17. */
  18. export declare function getSupportedElicitationModes(capabilities: ClientCapabilities['elicitation']): {
  19. supportsFormMode: boolean;
  20. supportsUrlMode: boolean;
  21. };
  22. export type ClientOptions = ProtocolOptions & {
  23. /**
  24. * Capabilities to advertise as being supported by this client.
  25. */
  26. capabilities?: ClientCapabilities;
  27. /**
  28. * JSON Schema validator for tool output validation.
  29. *
  30. * The validator is used to validate structured content returned by tools
  31. * against their declared output schemas.
  32. *
  33. * @default AjvJsonSchemaValidator
  34. *
  35. * @example
  36. * ```typescript
  37. * // ajv
  38. * const client = new Client(
  39. * { name: 'my-client', version: '1.0.0' },
  40. * {
  41. * capabilities: {},
  42. * jsonSchemaValidator: new AjvJsonSchemaValidator()
  43. * }
  44. * );
  45. *
  46. * // @cfworker/json-schema
  47. * const client = new Client(
  48. * { name: 'my-client', version: '1.0.0' },
  49. * {
  50. * capabilities: {},
  51. * jsonSchemaValidator: new CfWorkerJsonSchemaValidator()
  52. * }
  53. * );
  54. * ```
  55. */
  56. jsonSchemaValidator?: jsonSchemaValidator;
  57. /**
  58. * Configure handlers for list changed notifications (tools, prompts, resources).
  59. *
  60. * @example
  61. * ```typescript
  62. * const client = new Client(
  63. * { name: 'my-client', version: '1.0.0' },
  64. * {
  65. * listChanged: {
  66. * tools: {
  67. * onChanged: (error, tools) => {
  68. * if (error) {
  69. * console.error('Failed to refresh tools:', error);
  70. * return;
  71. * }
  72. * console.log('Tools updated:', tools);
  73. * }
  74. * },
  75. * prompts: {
  76. * onChanged: (error, prompts) => console.log('Prompts updated:', prompts)
  77. * }
  78. * }
  79. * }
  80. * );
  81. * ```
  82. */
  83. listChanged?: ListChangedHandlers;
  84. };
  85. /**
  86. * An MCP client on top of a pluggable transport.
  87. *
  88. * The client will automatically begin the initialization flow with the server when connect() is called.
  89. *
  90. * To use with custom types, extend the base Request/Notification/Result types and pass them as type parameters:
  91. *
  92. * ```typescript
  93. * // Custom schemas
  94. * const CustomRequestSchema = RequestSchema.extend({...})
  95. * const CustomNotificationSchema = NotificationSchema.extend({...})
  96. * const CustomResultSchema = ResultSchema.extend({...})
  97. *
  98. * // Type aliases
  99. * type CustomRequest = z.infer<typeof CustomRequestSchema>
  100. * type CustomNotification = z.infer<typeof CustomNotificationSchema>
  101. * type CustomResult = z.infer<typeof CustomResultSchema>
  102. *
  103. * // Create typed client
  104. * const client = new Client<CustomRequest, CustomNotification, CustomResult>({
  105. * name: "CustomClient",
  106. * version: "1.0.0"
  107. * })
  108. * ```
  109. */
  110. export declare class Client<RequestT extends Request = Request, NotificationT extends Notification = Notification, ResultT extends Result = Result> extends Protocol<ClientRequest | RequestT, ClientNotification | NotificationT, ClientResult | ResultT> {
  111. private _clientInfo;
  112. private _serverCapabilities?;
  113. private _serverVersion?;
  114. private _capabilities;
  115. private _instructions?;
  116. private _jsonSchemaValidator;
  117. private _cachedToolOutputValidators;
  118. private _cachedKnownTaskTools;
  119. private _cachedRequiredTaskTools;
  120. private _experimental?;
  121. private _listChangedDebounceTimers;
  122. private _pendingListChangedConfig?;
  123. /**
  124. * Initializes this client with the given name and version information.
  125. */
  126. constructor(_clientInfo: Implementation, options?: ClientOptions);
  127. /**
  128. * Set up handlers for list changed notifications based on config and server capabilities.
  129. * This should only be called after initialization when server capabilities are known.
  130. * Handlers are silently skipped if the server doesn't advertise the corresponding listChanged capability.
  131. * @internal
  132. */
  133. private _setupListChangedHandlers;
  134. /**
  135. * Access experimental features.
  136. *
  137. * WARNING: These APIs are experimental and may change without notice.
  138. *
  139. * @experimental
  140. */
  141. get experimental(): {
  142. tasks: ExperimentalClientTasks<RequestT, NotificationT, ResultT>;
  143. };
  144. /**
  145. * Registers new capabilities. This can only be called before connecting to a transport.
  146. *
  147. * The new capabilities will be merged with any existing capabilities previously given (e.g., at initialization).
  148. */
  149. registerCapabilities(capabilities: ClientCapabilities): void;
  150. /**
  151. * Override request handler registration to enforce client-side validation for elicitation.
  152. */
  153. setRequestHandler<T extends AnyObjectSchema>(requestSchema: T, handler: (request: SchemaOutput<T>, extra: RequestHandlerExtra<ClientRequest | RequestT, ClientNotification | NotificationT>) => ClientResult | ResultT | Promise<ClientResult | ResultT>): void;
  154. protected assertCapability(capability: keyof ServerCapabilities, method: string): void;
  155. connect(transport: Transport, options?: RequestOptions): Promise<void>;
  156. /**
  157. * After initialization has completed, this will be populated with the server's reported capabilities.
  158. */
  159. getServerCapabilities(): ServerCapabilities | undefined;
  160. /**
  161. * After initialization has completed, this will be populated with information about the server's name and version.
  162. */
  163. getServerVersion(): Implementation | undefined;
  164. /**
  165. * After initialization has completed, this may be populated with information about the server's instructions.
  166. */
  167. getInstructions(): string | undefined;
  168. protected assertCapabilityForMethod(method: RequestT['method']): void;
  169. protected assertNotificationCapability(method: NotificationT['method']): void;
  170. protected assertRequestHandlerCapability(method: string): void;
  171. protected assertTaskCapability(method: string): void;
  172. protected assertTaskHandlerCapability(method: string): void;
  173. ping(options?: RequestOptions): Promise<{
  174. _meta?: {
  175. [x: string]: unknown;
  176. progressToken?: string | number | undefined;
  177. "io.modelcontextprotocol/related-task"?: {
  178. taskId: string;
  179. } | undefined;
  180. } | undefined;
  181. }>;
  182. complete(params: CompleteRequest['params'], options?: RequestOptions): Promise<{
  183. [x: string]: unknown;
  184. completion: {
  185. [x: string]: unknown;
  186. values: string[];
  187. total?: number | undefined;
  188. hasMore?: boolean | undefined;
  189. };
  190. _meta?: {
  191. [x: string]: unknown;
  192. progressToken?: string | number | undefined;
  193. "io.modelcontextprotocol/related-task"?: {
  194. taskId: string;
  195. } | undefined;
  196. } | undefined;
  197. }>;
  198. setLoggingLevel(level: LoggingLevel, options?: RequestOptions): Promise<{
  199. _meta?: {
  200. [x: string]: unknown;
  201. progressToken?: string | number | undefined;
  202. "io.modelcontextprotocol/related-task"?: {
  203. taskId: string;
  204. } | undefined;
  205. } | undefined;
  206. }>;
  207. getPrompt(params: GetPromptRequest['params'], options?: RequestOptions): Promise<{
  208. [x: string]: unknown;
  209. messages: {
  210. role: "user" | "assistant";
  211. content: {
  212. type: "text";
  213. text: string;
  214. annotations?: {
  215. audience?: ("user" | "assistant")[] | undefined;
  216. priority?: number | undefined;
  217. lastModified?: string | undefined;
  218. } | undefined;
  219. _meta?: Record<string, unknown> | undefined;
  220. } | {
  221. type: "image";
  222. data: string;
  223. mimeType: string;
  224. annotations?: {
  225. audience?: ("user" | "assistant")[] | undefined;
  226. priority?: number | undefined;
  227. lastModified?: string | undefined;
  228. } | undefined;
  229. _meta?: Record<string, unknown> | undefined;
  230. } | {
  231. type: "audio";
  232. data: string;
  233. mimeType: string;
  234. annotations?: {
  235. audience?: ("user" | "assistant")[] | undefined;
  236. priority?: number | undefined;
  237. lastModified?: string | undefined;
  238. } | undefined;
  239. _meta?: Record<string, unknown> | undefined;
  240. } | {
  241. type: "resource";
  242. resource: {
  243. uri: string;
  244. text: string;
  245. mimeType?: string | undefined;
  246. _meta?: Record<string, unknown> | undefined;
  247. } | {
  248. uri: string;
  249. blob: string;
  250. mimeType?: string | undefined;
  251. _meta?: Record<string, unknown> | undefined;
  252. };
  253. annotations?: {
  254. audience?: ("user" | "assistant")[] | undefined;
  255. priority?: number | undefined;
  256. lastModified?: string | undefined;
  257. } | undefined;
  258. _meta?: Record<string, unknown> | undefined;
  259. } | {
  260. uri: string;
  261. name: string;
  262. type: "resource_link";
  263. description?: string | undefined;
  264. mimeType?: string | undefined;
  265. size?: number | undefined;
  266. annotations?: {
  267. audience?: ("user" | "assistant")[] | undefined;
  268. priority?: number | undefined;
  269. lastModified?: string | undefined;
  270. } | undefined;
  271. _meta?: {
  272. [x: string]: unknown;
  273. } | undefined;
  274. icons?: {
  275. src: string;
  276. mimeType?: string | undefined;
  277. sizes?: string[] | undefined;
  278. theme?: "light" | "dark" | undefined;
  279. }[] | undefined;
  280. title?: string | undefined;
  281. };
  282. }[];
  283. _meta?: {
  284. [x: string]: unknown;
  285. progressToken?: string | number | undefined;
  286. "io.modelcontextprotocol/related-task"?: {
  287. taskId: string;
  288. } | undefined;
  289. } | undefined;
  290. description?: string | undefined;
  291. }>;
  292. listPrompts(params?: ListPromptsRequest['params'], options?: RequestOptions): Promise<{
  293. [x: string]: unknown;
  294. prompts: {
  295. name: string;
  296. description?: string | undefined;
  297. arguments?: {
  298. name: string;
  299. description?: string | undefined;
  300. required?: boolean | undefined;
  301. }[] | undefined;
  302. _meta?: {
  303. [x: string]: unknown;
  304. } | undefined;
  305. icons?: {
  306. src: string;
  307. mimeType?: string | undefined;
  308. sizes?: string[] | undefined;
  309. theme?: "light" | "dark" | undefined;
  310. }[] | undefined;
  311. title?: string | undefined;
  312. }[];
  313. _meta?: {
  314. [x: string]: unknown;
  315. progressToken?: string | number | undefined;
  316. "io.modelcontextprotocol/related-task"?: {
  317. taskId: string;
  318. } | undefined;
  319. } | undefined;
  320. nextCursor?: string | undefined;
  321. }>;
  322. listResources(params?: ListResourcesRequest['params'], options?: RequestOptions): Promise<{
  323. [x: string]: unknown;
  324. resources: {
  325. uri: string;
  326. name: string;
  327. description?: string | undefined;
  328. mimeType?: string | undefined;
  329. size?: number | undefined;
  330. annotations?: {
  331. audience?: ("user" | "assistant")[] | undefined;
  332. priority?: number | undefined;
  333. lastModified?: string | undefined;
  334. } | undefined;
  335. _meta?: {
  336. [x: string]: unknown;
  337. } | undefined;
  338. icons?: {
  339. src: string;
  340. mimeType?: string | undefined;
  341. sizes?: string[] | undefined;
  342. theme?: "light" | "dark" | undefined;
  343. }[] | undefined;
  344. title?: string | undefined;
  345. }[];
  346. _meta?: {
  347. [x: string]: unknown;
  348. progressToken?: string | number | undefined;
  349. "io.modelcontextprotocol/related-task"?: {
  350. taskId: string;
  351. } | undefined;
  352. } | undefined;
  353. nextCursor?: string | undefined;
  354. }>;
  355. listResourceTemplates(params?: ListResourceTemplatesRequest['params'], options?: RequestOptions): Promise<{
  356. [x: string]: unknown;
  357. resourceTemplates: {
  358. uriTemplate: string;
  359. name: string;
  360. description?: string | undefined;
  361. mimeType?: string | undefined;
  362. annotations?: {
  363. audience?: ("user" | "assistant")[] | undefined;
  364. priority?: number | undefined;
  365. lastModified?: string | undefined;
  366. } | undefined;
  367. _meta?: {
  368. [x: string]: unknown;
  369. } | undefined;
  370. icons?: {
  371. src: string;
  372. mimeType?: string | undefined;
  373. sizes?: string[] | undefined;
  374. theme?: "light" | "dark" | undefined;
  375. }[] | undefined;
  376. title?: string | undefined;
  377. }[];
  378. _meta?: {
  379. [x: string]: unknown;
  380. progressToken?: string | number | undefined;
  381. "io.modelcontextprotocol/related-task"?: {
  382. taskId: string;
  383. } | undefined;
  384. } | undefined;
  385. nextCursor?: string | undefined;
  386. }>;
  387. readResource(params: ReadResourceRequest['params'], options?: RequestOptions): Promise<{
  388. [x: string]: unknown;
  389. contents: ({
  390. uri: string;
  391. text: string;
  392. mimeType?: string | undefined;
  393. _meta?: Record<string, unknown> | undefined;
  394. } | {
  395. uri: string;
  396. blob: string;
  397. mimeType?: string | undefined;
  398. _meta?: Record<string, unknown> | undefined;
  399. })[];
  400. _meta?: {
  401. [x: string]: unknown;
  402. progressToken?: string | number | undefined;
  403. "io.modelcontextprotocol/related-task"?: {
  404. taskId: string;
  405. } | undefined;
  406. } | undefined;
  407. }>;
  408. subscribeResource(params: SubscribeRequest['params'], options?: RequestOptions): Promise<{
  409. _meta?: {
  410. [x: string]: unknown;
  411. progressToken?: string | number | undefined;
  412. "io.modelcontextprotocol/related-task"?: {
  413. taskId: string;
  414. } | undefined;
  415. } | undefined;
  416. }>;
  417. unsubscribeResource(params: UnsubscribeRequest['params'], options?: RequestOptions): Promise<{
  418. _meta?: {
  419. [x: string]: unknown;
  420. progressToken?: string | number | undefined;
  421. "io.modelcontextprotocol/related-task"?: {
  422. taskId: string;
  423. } | undefined;
  424. } | undefined;
  425. }>;
  426. /**
  427. * Calls a tool and waits for the result. Automatically validates structured output if the tool has an outputSchema.
  428. *
  429. * For task-based execution with streaming behavior, use client.experimental.tasks.callToolStream() instead.
  430. */
  431. callTool(params: CallToolRequest['params'], resultSchema?: typeof CallToolResultSchema | typeof CompatibilityCallToolResultSchema, options?: RequestOptions): Promise<{
  432. [x: string]: unknown;
  433. content: ({
  434. type: "text";
  435. text: string;
  436. annotations?: {
  437. audience?: ("user" | "assistant")[] | undefined;
  438. priority?: number | undefined;
  439. lastModified?: string | undefined;
  440. } | undefined;
  441. _meta?: Record<string, unknown> | undefined;
  442. } | {
  443. type: "image";
  444. data: string;
  445. mimeType: string;
  446. annotations?: {
  447. audience?: ("user" | "assistant")[] | undefined;
  448. priority?: number | undefined;
  449. lastModified?: string | undefined;
  450. } | undefined;
  451. _meta?: Record<string, unknown> | undefined;
  452. } | {
  453. type: "audio";
  454. data: string;
  455. mimeType: string;
  456. annotations?: {
  457. audience?: ("user" | "assistant")[] | undefined;
  458. priority?: number | undefined;
  459. lastModified?: string | undefined;
  460. } | undefined;
  461. _meta?: Record<string, unknown> | undefined;
  462. } | {
  463. type: "resource";
  464. resource: {
  465. uri: string;
  466. text: string;
  467. mimeType?: string | undefined;
  468. _meta?: Record<string, unknown> | undefined;
  469. } | {
  470. uri: string;
  471. blob: string;
  472. mimeType?: string | undefined;
  473. _meta?: Record<string, unknown> | undefined;
  474. };
  475. annotations?: {
  476. audience?: ("user" | "assistant")[] | undefined;
  477. priority?: number | undefined;
  478. lastModified?: string | undefined;
  479. } | undefined;
  480. _meta?: Record<string, unknown> | undefined;
  481. } | {
  482. uri: string;
  483. name: string;
  484. type: "resource_link";
  485. description?: string | undefined;
  486. mimeType?: string | undefined;
  487. size?: number | undefined;
  488. annotations?: {
  489. audience?: ("user" | "assistant")[] | undefined;
  490. priority?: number | undefined;
  491. lastModified?: string | undefined;
  492. } | undefined;
  493. _meta?: {
  494. [x: string]: unknown;
  495. } | undefined;
  496. icons?: {
  497. src: string;
  498. mimeType?: string | undefined;
  499. sizes?: string[] | undefined;
  500. theme?: "light" | "dark" | undefined;
  501. }[] | undefined;
  502. title?: string | undefined;
  503. })[];
  504. _meta?: {
  505. [x: string]: unknown;
  506. progressToken?: string | number | undefined;
  507. "io.modelcontextprotocol/related-task"?: {
  508. taskId: string;
  509. } | undefined;
  510. } | undefined;
  511. structuredContent?: Record<string, unknown> | undefined;
  512. isError?: boolean | undefined;
  513. } | {
  514. [x: string]: unknown;
  515. toolResult: unknown;
  516. _meta?: {
  517. [x: string]: unknown;
  518. progressToken?: string | number | undefined;
  519. "io.modelcontextprotocol/related-task"?: {
  520. taskId: string;
  521. } | undefined;
  522. } | undefined;
  523. }>;
  524. private isToolTask;
  525. /**
  526. * Check if a tool requires task-based execution.
  527. * Unlike isToolTask which includes 'optional' tools, this only checks for 'required'.
  528. */
  529. private isToolTaskRequired;
  530. /**
  531. * Cache validators for tool output schemas.
  532. * Called after listTools() to pre-compile validators for better performance.
  533. */
  534. private cacheToolMetadata;
  535. /**
  536. * Get cached validator for a tool
  537. */
  538. private getToolOutputValidator;
  539. listTools(params?: ListToolsRequest['params'], options?: RequestOptions): Promise<{
  540. [x: string]: unknown;
  541. tools: {
  542. inputSchema: {
  543. [x: string]: unknown;
  544. type: "object";
  545. properties?: Record<string, object> | undefined;
  546. required?: string[] | undefined;
  547. };
  548. name: string;
  549. description?: string | undefined;
  550. outputSchema?: {
  551. [x: string]: unknown;
  552. type: "object";
  553. properties?: Record<string, object> | undefined;
  554. required?: string[] | undefined;
  555. } | undefined;
  556. annotations?: {
  557. title?: string | undefined;
  558. readOnlyHint?: boolean | undefined;
  559. destructiveHint?: boolean | undefined;
  560. idempotentHint?: boolean | undefined;
  561. openWorldHint?: boolean | undefined;
  562. } | undefined;
  563. execution?: {
  564. taskSupport?: "optional" | "required" | "forbidden" | undefined;
  565. } | undefined;
  566. _meta?: Record<string, unknown> | undefined;
  567. icons?: {
  568. src: string;
  569. mimeType?: string | undefined;
  570. sizes?: string[] | undefined;
  571. theme?: "light" | "dark" | undefined;
  572. }[] | undefined;
  573. title?: string | undefined;
  574. }[];
  575. _meta?: {
  576. [x: string]: unknown;
  577. progressToken?: string | number | undefined;
  578. "io.modelcontextprotocol/related-task"?: {
  579. taskId: string;
  580. } | undefined;
  581. } | undefined;
  582. nextCursor?: string | undefined;
  583. }>;
  584. /**
  585. * Set up a single list changed handler.
  586. * @internal
  587. */
  588. private _setupListChangedHandler;
  589. sendRootsListChanged(): Promise<void>;
  590. }
  591. //# sourceMappingURL=index.d.ts.map