diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7f7096160..42cf93a67 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "6.38.2" + ".": "6.39.0" } diff --git a/.stats.yml b/.stats.yml index 906bc7753..6dc87a141 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 46 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-0105d239fcaf84750c886dfa6c2cfbf2b2087f89a48f8827c4cbe28479ebfb13.yml -openapi_spec_hash: 34895c3d3c137fb9f5a019ac5370afbb +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-b817e7a30a6366c063a8c9a334d5be281eb8d93e21acc8c8219d3bdc95043deb.yml +openapi_spec_hash: d4cc4a5cba9f13986e38d148d330aa00 config_hash: 5c64f384746e7570c10f19fe241062a7 diff --git a/CHANGELOG.md b/CHANGELOG.md index da47438f7..6b5563bb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 6.39.0 (2025-11-03) + +Full Changelog: [v6.38.2...v6.39.0](https://github.com/Finch-API/finch-api-node/compare/v6.38.2...v6.39.0) + +### Features + +* **api:** api update ([b6892f5](https://github.com/Finch-API/finch-api-node/commit/b6892f5c579a0eeb8fa03863d9a72faa36adab9d)) + + +### Chores + +* **internal:** grammar fix (it's -> its) ([54ad7ca](https://github.com/Finch-API/finch-api-node/commit/54ad7ca2689051eccdb1de832e9041e3a6fe8d52)) +* use structured error when code execution tool errors ([a85e9d8](https://github.com/Finch-API/finch-api-node/commit/a85e9d8431d5b22e82f34606a813821f5573d197)) + ## 6.38.2 (2025-10-31) Full Changelog: [v6.38.1...v6.38.2](https://github.com/Finch-API/finch-api-node/compare/v6.38.1...v6.38.2) diff --git a/package.json b/package.json index f31d203a9..8652fcbd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tryfinch/finch-api", - "version": "6.38.2", + "version": "6.39.0", "description": "The official TypeScript library for the Finch API", "author": "Finch ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index df47a2ef0..4c55b951d 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "@tryfinch/finch-api-mcp", - "version": "6.38.2", + "version": "6.39.0", "description": "The official MCP Server for the Finch API", "author": "Finch ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/src/code-tool.ts b/packages/mcp-server/src/code-tool.ts index 8e5e5e2f9..c4c9814aa 100644 --- a/packages/mcp-server/src/code-tool.ts +++ b/packages/mcp-server/src/code-tool.ts @@ -3,7 +3,7 @@ import { dirname } from 'node:path'; import { pathToFileURL } from 'node:url'; import Finch, { ClientOptions } from '@tryfinch/finch-api'; -import { Endpoint, ContentBlock, Metadata } from './tools/types'; +import { ContentBlock, Endpoint, Metadata, ToolCallResult } from './tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; @@ -12,7 +12,7 @@ import { WorkerInput, WorkerError, WorkerSuccess } from './code-tool-types'; /** * A tool that runs code against a copy of the SDK. * - * Instead of exposing every endpoint as it's own tool, which uses up too many tokens for LLMs to use at once, + * Instead of exposing every endpoint as its own tool, which uses up too many tokens for LLMs to use at once, * we expose a single tool that can be used to search for endpoints by name, resource, operation, or tag, and then * a generic endpoint that can be used to invoke any endpoint with the provided arguments. * @@ -23,7 +23,7 @@ export async function codeTool(): Promise { const tool: Tool = { name: 'execute', description: - 'Runs Typescript code to interact with the API.\nYou are a skilled programmer writing code to interface with the service.\nDefine an async function named "run" that takes a single parameter of an initialized client, and it will be run.\nDo not initialize a client, but instead use the client that you are given as a parameter.\nYou will be returned anything that your function returns, plus the results of any console.log statements.\nIf any code triggers an error, the tool will return an error response, so you do not need to add error handling unless you want to output something more helpful than the raw error.\nIt is not necessary to add comments to code, unless by adding those comments you believe that you can generate better code.\nThis code will run in a container, and you will not be able to use fetch or otherwise interact with the network calls other than through the client you are given.\nAny variables you define won\'t live between successive uses of this call, so make sure to return or log any data you might need later.', + 'Runs TypeScript code to interact with the API.\nYou are a skilled programmer writing code to interface with the service.\nDefine an async function named "run" that takes a single parameter of an initialized client, and it will be run.\nDo not initialize a client, but instead use the client that you are given as a parameter.\nYou will be returned anything that your function returns, plus the results of any console.log statements.\nIf any code triggers an error, the tool will return an error response, so you do not need to add error handling unless you want to output something more helpful than the raw error.\nIt is not necessary to add comments to code, unless by adding those comments you believe that you can generate better code.\nThis code will run in a container, and you will not be able to use fetch or otherwise interact with the network calls other than through the client you are given.\nAny variables you define won\'t live between successive uses of this call, so make sure to return or log any data you might need later.', inputSchema: { type: 'object', properties: { code: { type: 'string' } } }, }; @@ -31,7 +31,7 @@ export async function codeTool(): Promise { const { newDenoHTTPWorker } = await import('@valtown/deno-http-worker'); const { workerPath } = await import('./code-tool-paths.cjs'); - const handler = async (client: Finch, args: unknown) => { + const handler = async (client: Finch, args: unknown): Promise => { const baseURLHostname = new URL(client.baseURL).hostname; const { code } = args as { code: string }; @@ -100,7 +100,7 @@ export async function codeTool(): Promise { } satisfies WorkerInput); req.write(body, (err) => { - if (err !== null && err !== undefined) { + if (err != null) { reject(err); } }); @@ -111,12 +111,12 @@ export async function codeTool(): Promise { if (resp.status === 200) { const { result, logLines, errLines } = (await resp.json()) as WorkerSuccess; const returnOutput: ContentBlock | null = - result === null ? null - : result === undefined ? null - : { + result == null ? null : ( + { type: 'text', - text: typeof result === 'string' ? (result as string) : JSON.stringify(result), - }; + text: typeof result === 'string' ? result : JSON.stringify(result), + } + ); const logOutput: ContentBlock | null = logLines.length === 0 ? null @@ -136,10 +136,11 @@ export async function codeTool(): Promise { }; } else { const { message } = (await resp.json()) as WorkerError; - throw new Error(message); + return { + content: message == null ? [] : [{ type: 'text', text: message }], + isError: true, + }; } - } catch (e) { - throw e; } finally { worker.terminate(); } diff --git a/packages/mcp-server/src/dynamic-tools.ts b/packages/mcp-server/src/dynamic-tools.ts index 9aab541d9..3e4e9fb91 100644 --- a/packages/mcp-server/src/dynamic-tools.ts +++ b/packages/mcp-server/src/dynamic-tools.ts @@ -14,7 +14,7 @@ function zodToInputSchema(schema: z.ZodSchema) { /** * A list of tools that expose all the endpoints in the API dynamically. * - * Instead of exposing every endpoint as it's own tool, which uses up too many tokens for LLMs to use at once, + * Instead of exposing every endpoint as its own tool, which uses up too many tokens for LLMs to use at once, * we expose a single tool that can be used to search for endpoints by name, resource, operation, or tag, and then * a generic endpoint that can be used to invoke any endpoint with the provided arguments. * diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index cf8899c75..feff66646 100644 --- a/packages/mcp-server/src/server.ts +++ b/packages/mcp-server/src/server.ts @@ -33,7 +33,7 @@ export const newMcpServer = () => new McpServer( { name: 'tryfinch_finch_api_api', - version: '6.38.2', + version: '6.39.0', }, { capabilities: { tools: {}, logging: {} } }, ); diff --git a/packages/mcp-server/src/tools/connect/sessions/new-connect-sessions.ts b/packages/mcp-server/src/tools/connect/sessions/new-connect-sessions.ts index 0333a867e..dcc65e401 100644 --- a/packages/mcp-server/src/tools/connect/sessions/new-connect-sessions.ts +++ b/packages/mcp-server/src/tools/connect/sessions/new-connect-sessions.ts @@ -22,10 +22,6 @@ export const tool: Tool = { inputSchema: { type: 'object', properties: { - customer_email: { - type: 'string', - description: 'Email address of the customer', - }, customer_id: { type: 'string', description: 'Unique identifier for the customer', @@ -34,31 +30,6 @@ export const tool: Tool = { type: 'string', description: 'Name of the customer', }, - integration: { - type: 'object', - description: 'Integration configuration for the connect session', - properties: { - auth_method: { - type: 'string', - description: 'The authentication method to use', - enum: ['assisted', 'credential', 'oauth', 'api_token'], - }, - provider: { - type: 'string', - description: 'The provider to integrate with', - }, - }, - required: ['auth_method', 'provider'], - }, - manual: { - type: 'boolean', - description: 'Enable manual authentication mode', - }, - minutes_to_expire: { - type: 'number', - description: - 'The number of minutes until the session expires (defaults to 129,600, which is 90 days)', - }, products: { type: 'array', description: 'The Finch products to request access to', @@ -79,6 +50,35 @@ export const tool: Tool = { ], }, }, + customer_email: { + type: 'string', + description: 'Email address of the customer', + }, + integration: { + type: 'object', + description: 'Integration configuration for the connect session', + properties: { + provider: { + type: 'string', + description: 'The provider to integrate with', + }, + auth_method: { + type: 'string', + description: 'The authentication method to use', + enum: ['assisted', 'credential', 'oauth', 'api_token'], + }, + }, + required: ['provider'], + }, + manual: { + type: 'boolean', + description: 'Enable manual authentication mode', + }, + minutes_to_expire: { + type: 'number', + description: + 'The number of minutes until the session expires (defaults to 129,600, which is 90 days)', + }, redirect_uri: { type: 'string', description: 'The URI to redirect to after the Connect flow is completed', @@ -95,17 +95,7 @@ export const tool: Tool = { 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).', }, }, - required: [ - 'customer_email', - 'customer_id', - 'customer_name', - 'integration', - 'manual', - 'minutes_to_expire', - 'products', - 'redirect_uri', - 'sandbox', - ], + required: ['customer_id', 'customer_name', 'products'], }, annotations: {}, }; diff --git a/packages/mcp-server/src/tools/connect/sessions/reauthenticate-connect-sessions.ts b/packages/mcp-server/src/tools/connect/sessions/reauthenticate-connect-sessions.ts index 028508c64..15b21a9a3 100644 --- a/packages/mcp-server/src/tools/connect/sessions/reauthenticate-connect-sessions.ts +++ b/packages/mcp-server/src/tools/connect/sessions/reauthenticate-connect-sessions.ts @@ -61,7 +61,7 @@ export const tool: Tool = { 'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).', }, }, - required: ['connection_id', 'minutes_to_expire', 'products', 'redirect_uri'], + required: ['connection_id'], }, annotations: {}, }; diff --git a/src/resources/connect/sessions.ts b/src/resources/connect/sessions.ts index 1c3aa83ae..845de320d 100644 --- a/src/resources/connect/sessions.ts +++ b/src/resources/connect/sessions.ts @@ -47,11 +47,6 @@ export interface SessionReauthenticateResponse { } export interface SessionNewParams { - /** - * Email address of the customer - */ - customer_email: string | null; - /** * Unique identifier for the customer */ @@ -62,22 +57,6 @@ export interface SessionNewParams { */ customer_name: string; - /** - * Integration configuration for the connect session - */ - integration: SessionNewParams.Integration | null; - - /** - * Enable manual authentication mode - */ - manual: boolean | null; - - /** - * The number of minutes until the session expires (defaults to 129,600, which is - * 90 days) - */ - minutes_to_expire: number | null; - /** * The Finch products to request access to */ @@ -94,15 +73,36 @@ export interface SessionNewParams { | 'ssn' >; + /** + * Email address of the customer + */ + customer_email?: string | null; + + /** + * Integration configuration for the connect session + */ + integration?: SessionNewParams.Integration | null; + + /** + * Enable manual authentication mode + */ + manual?: boolean | null; + + /** + * The number of minutes until the session expires (defaults to 129,600, which is + * 90 days) + */ + minutes_to_expire?: number | null; + /** * The URI to redirect to after the Connect flow is completed */ - redirect_uri: string | null; + redirect_uri?: string | null; /** * Sandbox mode for testing */ - sandbox: 'finch' | 'provider' | null; + sandbox?: 'finch' | 'provider' | null; } export namespace SessionNewParams { @@ -111,14 +111,14 @@ export namespace SessionNewParams { */ export interface Integration { /** - * The authentication method to use + * The provider to integrate with */ - auth_method: 'assisted' | 'credential' | 'oauth' | 'api_token' | null; + provider: string; /** - * The provider to integrate with + * The authentication method to use */ - provider: string | null; + auth_method?: 'assisted' | 'credential' | 'oauth' | 'api_token' | null; } } @@ -132,12 +132,12 @@ export interface SessionReauthenticateParams { * The number of minutes until the session expires (defaults to 43,200, which is 30 * days) */ - minutes_to_expire: number; + minutes_to_expire?: number; /** * The products to request access to (optional for reauthentication) */ - products: Array< + products?: Array< | 'benefits' | 'company' | 'deduction' @@ -153,7 +153,7 @@ export interface SessionReauthenticateParams { /** * The URI to redirect to after the Connect flow is completed */ - redirect_uri: string | null; + redirect_uri?: string | null; } export declare namespace Sessions { diff --git a/src/version.ts b/src/version.ts index f28a7b68b..b44926972 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '6.38.2'; // x-release-please-version +export const VERSION = '6.39.0'; // x-release-please-version diff --git a/tests/api-resources/connect/sessions.test.ts b/tests/api-resources/connect/sessions.test.ts index d66e242d2..773a75544 100644 --- a/tests/api-resources/connect/sessions.test.ts +++ b/tests/api-resources/connect/sessions.test.ts @@ -12,15 +12,9 @@ describe('resource sessions', () => { // prism tests are broken test.skip('new: only required params', async () => { const responsePromise = client.connect.sessions.new({ - customer_email: 'dev@stainless.com', customer_id: 'x', customer_name: 'x', - integration: { auth_method: 'assisted', provider: 'provider' }, - manual: true, - minutes_to_expire: 1, products: ['benefits'], - redirect_uri: 'redirect_uri', - sandbox: 'finch', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -34,13 +28,13 @@ describe('resource sessions', () => { // prism tests are broken test.skip('new: required and optional params', async () => { const response = await client.connect.sessions.new({ - customer_email: 'dev@stainless.com', customer_id: 'x', customer_name: 'x', - integration: { auth_method: 'assisted', provider: 'provider' }, + products: ['benefits'], + customer_email: 'dev@stainless.com', + integration: { provider: 'provider', auth_method: 'assisted' }, manual: true, minutes_to_expire: 1, - products: ['benefits'], redirect_uri: 'redirect_uri', sandbox: 'finch', }); @@ -48,12 +42,7 @@ describe('resource sessions', () => { // prism tests are broken test.skip('reauthenticate: only required params', async () => { - const responsePromise = client.connect.sessions.reauthenticate({ - connection_id: 'connection_id', - minutes_to_expire: 0, - products: ['benefits'], - redirect_uri: 'https://example.com', - }); + const responsePromise = client.connect.sessions.reauthenticate({ connection_id: 'connection_id' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise;