From f75e3010fb346dde47038f0e876549bc6eba301f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 22:13:05 +0000 Subject: [PATCH 01/26] chore(internal): remove .eslintcache --- .eslintcache | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .eslintcache diff --git a/.eslintcache b/.eslintcache deleted file mode 100644 index fa0627a5..00000000 --- a/.eslintcache +++ /dev/null @@ -1 +0,0 @@ -[{"/home/tempuser-2eudnk/run/codegen-output/writerai/writer-typescript/src/resources/tools/comprehend.ts":"1","/home/tempuser-2eudnk/run/codegen-output/writerai/writer-typescript/src/resources/tools/tools.ts":"2","/home/tempuser-2eudnk/run/codegen-output/writerai/writer-typescript/src/resources/translation.ts":"3"},{"size":2779,"mtime":1759270331968},{"size":9476,"mtime":1759270331968},{"size":5973,"mtime":1759270331968}] \ No newline at end of file From d227de61034910da49481c6ff488436fcfed61fd Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 22:13:04 +0000 Subject: [PATCH 02/26] =?UTF-8?q?chore(jsdoc):=20fix=20@link=20annotations?= =?UTF-8?q?=20to=20refer=20only=20to=20parts=20of=20the=20package=E2=80=98?= =?UTF-8?q?s=20public=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/internal/to-file.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts index 245e8493..30eada32 100644 --- a/src/internal/to-file.ts +++ b/src/internal/to-file.ts @@ -73,7 +73,7 @@ export type ToFileInput = /** * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats - * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s + * @param value the raw content of the file. Can be an {@link Uploadable}, BlobLikePart, or AsyncIterable of BlobLikeParts * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible * @param {Object=} options additional properties * @param {string=} options.type the MIME type of the content From 38c37a1cfc2af919b9833344716ff5172a5076b3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 21:36:52 +0000 Subject: [PATCH 03/26] chore(internal): use npm pack for build uploads --- scripts/utils/upload-artifact.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh index 7d8dd272..a90e5b8f 100755 --- a/scripts/utils/upload-artifact.sh +++ b/scripts/utils/upload-artifact.sh @@ -12,9 +12,11 @@ if [[ "$SIGNED_URL" == "null" ]]; then exit 1 fi -UPLOAD_RESPONSE=$(tar "${BASE_PATH:+-C$BASE_PATH}" -cz "${ARTIFACT_PATH:-dist}" | curl -v -X PUT \ +TARBALL=$(cd dist && npm pack --silent) + +UPLOAD_RESPONSE=$(curl -v -X PUT \ -H "Content-Type: application/gzip" \ - --data-binary @- "$SIGNED_URL" 2>&1) + --data-binary "@dist/$TARBALL" "$SIGNED_URL" 2>&1) if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then echo -e "\033[32mUploaded build to Stainless storage.\033[0m" From de1e15096bb097df00cdee211b752487d364d977 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 17:03:45 +0000 Subject: [PATCH 04/26] chore: extract some types in mcp docs --- .../src/tools/applications/jobs/create-applications-jobs.ts | 2 +- .../src/tools/applications/jobs/retry-applications-jobs.ts | 2 +- packages/mcp-server/src/tools/applications/list-applications.ts | 2 +- .../mcp-server/src/tools/applications/retrieve-applications.ts | 2 +- packages/mcp-server/src/tools/files/delete-files.ts | 2 +- packages/mcp-server/src/tools/files/retry-files.ts | 2 +- packages/mcp-server/src/tools/graphs/create-graphs.ts | 2 +- packages/mcp-server/src/tools/graphs/delete-graphs.ts | 2 +- .../src/tools/graphs/remove-file-from-graph-graphs.ts | 2 +- packages/mcp-server/src/tools/graphs/update-graphs.ts | 2 +- packages/mcp-server/src/tools/models/list-models.ts | 2 +- packages/mcp-server/src/tools/tools/ai-detect-tools.ts | 2 +- .../src/tools/tools/comprehend/medical-tools-comprehend.ts | 2 +- .../mcp-server/src/tools/tools/context-aware-splitting-tools.ts | 2 +- packages/mcp-server/src/tools/tools/parse-pdf-tools.ts | 2 +- packages/mcp-server/src/tools/tools/web-search-tools.ts | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts b/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts index af7c4a48..1427d004 100644 --- a/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts +++ b/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'create_applications_jobs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGenerate content asynchronously from an existing no-code agent (formerly called no-code applications) with inputs.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'generate_application_async_response',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier for the async job created.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the job was created.',\n format: 'date-time'\n },\n status: {\n type: 'string',\n title: 'api_job_status',\n description: 'The status of the job.',\n enum: [ 'in_progress',\n 'failed',\n 'completed'\n ]\n }\n },\n required: [ 'id',\n 'created_at',\n 'status'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGenerate content asynchronously from an existing no-code agent (formerly called no-code applications) with inputs.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/job_create_response',\n $defs: {\n job_create_response: {\n type: 'object',\n title: 'generate_application_async_response',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier for the async job created.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the job was created.',\n format: 'date-time'\n },\n status: {\n type: 'string',\n title: 'api_job_status',\n description: 'The status of the job.',\n enum: [ 'in_progress',\n 'failed',\n 'completed'\n ]\n }\n },\n required: [ 'id',\n 'created_at',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts b/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts index 26448256..6874b919 100644 --- a/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts +++ b/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'retry_applications_jobs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRe-triggers the async execution of a single job previously created via the Async api and terminated in error.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'generate_application_async_response',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier for the async job created.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the job was created.',\n format: 'date-time'\n },\n status: {\n type: 'string',\n title: 'api_job_status',\n description: 'The status of the job.',\n enum: [ 'in_progress',\n 'failed',\n 'completed'\n ]\n }\n },\n required: [ 'id',\n 'created_at',\n 'status'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRe-triggers the async execution of a single job previously created via the Async api and terminated in error.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/job_retry_response',\n $defs: {\n job_retry_response: {\n type: 'object',\n title: 'generate_application_async_response',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier for the async job created.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the job was created.',\n format: 'date-time'\n },\n status: {\n type: 'string',\n title: 'api_job_status',\n description: 'The status of the job.',\n enum: [ 'in_progress',\n 'failed',\n 'completed'\n ]\n }\n },\n required: [ 'id',\n 'created_at',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/applications/list-applications.ts b/packages/mcp-server/src/tools/applications/list-applications.ts index b768f6ee..a42bad58 100644 --- a/packages/mcp-server/src/tools/applications/list-applications.ts +++ b/packages/mcp-server/src/tools/applications/list-applications.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'list_applications', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieves a paginated list of no-code agents (formerly called no-code applications) with optional filtering and sorting capabilities.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'get_applications_response',\n description: 'Response object containing a paginated list of applications.',\n properties: {\n data: {\n type: 'array',\n description: 'List of application objects with their configurations.',\n items: {\n type: 'object',\n title: 'application_with_inputs',\n description: 'Detailed application object including its input configuration.',\n properties: {\n id: {\n type: 'string',\n description: 'Unique identifier for the application.'\n },\n created_at: {\n type: 'string',\n description: 'Timestamp when the application was created.',\n format: 'date-time'\n },\n inputs: {\n type: 'array',\n description: 'List of input configurations for the application.',\n items: {\n type: 'object',\n title: 'application_input',\n description: 'Configuration for an individual input field in the application.',\n properties: {\n input_type: {\n type: 'string',\n title: 'application_input_type',\n description: 'Type of input field determining its behavior and validation rules.',\n enum: [ 'text',\n 'dropdown',\n 'file',\n 'media'\n ]\n },\n name: {\n type: 'string',\n description: 'Identifier for the input field.'\n },\n required: {\n type: 'boolean',\n description: 'Indicates if this input field is mandatory.'\n },\n description: {\n type: 'string',\n description: 'Human-readable description of the input field\\'s purpose.'\n },\n options: {\n anyOf: [ {\n type: 'object',\n title: 'Dropdown',\n description: 'Configuration options specific to dropdown-type input fields.',\n properties: {\n list: {\n type: 'array',\n description: 'List of available options in the dropdown menu.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'list'\n ]\n },\n {\n type: 'object',\n title: 'File',\n description: 'Configuration options specific to file upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed file extensions.',\n items: {\n type: 'string'\n }\n },\n max_file_size_mb: {\n type: 'integer',\n description: 'Maximum file size allowed in megabytes.'\n },\n max_files: {\n type: 'integer',\n description: 'Maximum number of files that can be uploaded.'\n },\n max_word_count: {\n type: 'integer',\n description: 'Maximum number of words allowed in text files.'\n },\n upload_types: {\n type: 'array',\n description: 'List of allowed upload types for file inputs.',\n items: {\n type: 'string',\n title: 'file_upload_type',\n description: 'Type of file upload method supported by the application.',\n enum: [ 'url',\n 'file_id'\n ]\n }\n }\n },\n required: [ 'file_types',\n 'max_file_size_mb',\n 'max_files',\n 'max_word_count',\n 'upload_types'\n ]\n },\n {\n type: 'object',\n title: 'Media',\n description: 'Configuration options specific to media upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed media file types.',\n items: {\n type: 'string'\n }\n },\n max_image_size_mb: {\n type: 'integer',\n description: 'Maximum media file size allowed in megabytes.'\n }\n },\n required: [ 'file_types',\n 'max_image_size_mb'\n ]\n },\n {\n type: 'object',\n title: 'Text',\n description: 'Configuration options specific to text input fields.',\n properties: {\n max_fields: {\n type: 'integer',\n description: 'Maximum number of text fields allowed.'\n },\n min_fields: {\n type: 'integer',\n description: 'Minimum number of text fields required.'\n }\n },\n required: [ 'max_fields',\n 'min_fields'\n ]\n }\n ],\n description: 'Type-specific configuration options for input fields.'\n }\n },\n required: [ 'input_type',\n 'name',\n 'required'\n ]\n }\n },\n name: {\n type: 'string',\n description: 'Display name of the application.'\n },\n status: {\n type: 'string',\n title: 'application_status',\n description: 'Current deployment status of the application. Note: currently only `deployed` applications are returned.',\n enum: [ 'deployed',\n 'draft'\n ]\n },\n type: {\n type: 'string',\n title: 'application_type',\n description: 'The type of no-code application.',\n enum: [ 'generation'\n ]\n },\n updated_at: {\n type: 'string',\n description: 'Timestamp when the application was last updated.',\n format: 'date-time'\n },\n last_deployed_at: {\n type: 'string',\n description: 'Timestamp when the application was last deployed.',\n format: 'date-time'\n }\n },\n required: [ 'id',\n 'created_at',\n 'inputs',\n 'name',\n 'status',\n 'type',\n 'updated_at'\n ]\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more results available in subsequent pages.'\n },\n first_id: {\n type: 'string',\n description: 'UUID of the first application in the current page.'\n },\n last_id: {\n type: 'string',\n description: 'UUID of the last application in the current page.'\n }\n },\n required: [ 'data',\n 'has_more'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieves a paginated list of no-code agents (formerly called no-code applications) with optional filtering and sorting capabilities.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'get_applications_response',\n description: 'Response object containing a paginated list of applications.',\n properties: {\n data: {\n type: 'array',\n description: 'List of application objects with their configurations.',\n items: {\n $ref: '#/$defs/application_list_response'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more results available in subsequent pages.'\n },\n first_id: {\n type: 'string',\n description: 'UUID of the first application in the current page.'\n },\n last_id: {\n type: 'string',\n description: 'UUID of the last application in the current page.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n application_list_response: {\n type: 'object',\n title: 'application_with_inputs',\n description: 'Detailed application object including its input configuration.',\n properties: {\n id: {\n type: 'string',\n description: 'Unique identifier for the application.'\n },\n created_at: {\n type: 'string',\n description: 'Timestamp when the application was created.',\n format: 'date-time'\n },\n inputs: {\n type: 'array',\n description: 'List of input configurations for the application.',\n items: {\n type: 'object',\n title: 'application_input',\n description: 'Configuration for an individual input field in the application.',\n properties: {\n input_type: {\n type: 'string',\n title: 'application_input_type',\n description: 'Type of input field determining its behavior and validation rules.',\n enum: [ 'text',\n 'dropdown',\n 'file',\n 'media'\n ]\n },\n name: {\n type: 'string',\n description: 'Identifier for the input field.'\n },\n required: {\n type: 'boolean',\n description: 'Indicates if this input field is mandatory.'\n },\n description: {\n type: 'string',\n description: 'Human-readable description of the input field\\'s purpose.'\n },\n options: {\n anyOf: [ {\n type: 'object',\n title: 'Dropdown',\n description: 'Configuration options specific to dropdown-type input fields.',\n properties: {\n list: {\n type: 'array',\n description: 'List of available options in the dropdown menu.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'list'\n ]\n },\n {\n type: 'object',\n title: 'File',\n description: 'Configuration options specific to file upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed file extensions.',\n items: {\n type: 'string'\n }\n },\n max_file_size_mb: {\n type: 'integer',\n description: 'Maximum file size allowed in megabytes.'\n },\n max_files: {\n type: 'integer',\n description: 'Maximum number of files that can be uploaded.'\n },\n max_word_count: {\n type: 'integer',\n description: 'Maximum number of words allowed in text files.'\n },\n upload_types: {\n type: 'array',\n description: 'List of allowed upload types for file inputs.',\n items: {\n type: 'string',\n title: 'file_upload_type',\n description: 'Type of file upload method supported by the application.',\n enum: [ 'url',\n 'file_id'\n ]\n }\n }\n },\n required: [ 'file_types',\n 'max_file_size_mb',\n 'max_files',\n 'max_word_count',\n 'upload_types'\n ]\n },\n {\n type: 'object',\n title: 'Media',\n description: 'Configuration options specific to media upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed media file types.',\n items: {\n type: 'string'\n }\n },\n max_image_size_mb: {\n type: 'integer',\n description: 'Maximum media file size allowed in megabytes.'\n }\n },\n required: [ 'file_types',\n 'max_image_size_mb'\n ]\n },\n {\n type: 'object',\n title: 'Text',\n description: 'Configuration options specific to text input fields.',\n properties: {\n max_fields: {\n type: 'integer',\n description: 'Maximum number of text fields allowed.'\n },\n min_fields: {\n type: 'integer',\n description: 'Minimum number of text fields required.'\n }\n },\n required: [ 'max_fields',\n 'min_fields'\n ]\n }\n ],\n description: 'Type-specific configuration options for input fields.'\n }\n },\n required: [ 'input_type',\n 'name',\n 'required'\n ]\n }\n },\n name: {\n type: 'string',\n description: 'Display name of the application.'\n },\n status: {\n type: 'string',\n title: 'application_status',\n description: 'Current deployment status of the application. Note: currently only `deployed` applications are returned.',\n enum: [ 'deployed',\n 'draft'\n ]\n },\n type: {\n type: 'string',\n title: 'application_type',\n description: 'The type of no-code application.',\n enum: [ 'generation'\n ]\n },\n updated_at: {\n type: 'string',\n description: 'Timestamp when the application was last updated.',\n format: 'date-time'\n },\n last_deployed_at: {\n type: 'string',\n description: 'Timestamp when the application was last deployed.',\n format: 'date-time'\n }\n },\n required: [ 'id',\n 'created_at',\n 'inputs',\n 'name',\n 'status',\n 'type',\n 'updated_at'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/applications/retrieve-applications.ts b/packages/mcp-server/src/tools/applications/retrieve-applications.ts index b8585cc4..c05e0b7c 100644 --- a/packages/mcp-server/src/tools/applications/retrieve-applications.ts +++ b/packages/mcp-server/src/tools/applications/retrieve-applications.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'retrieve_applications', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieves detailed information for a specific no-code agent (formerly called no-code applications), including its configuration and current status.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'application_with_inputs',\n description: 'Detailed application object including its input configuration.',\n properties: {\n id: {\n type: 'string',\n description: 'Unique identifier for the application.'\n },\n created_at: {\n type: 'string',\n description: 'Timestamp when the application was created.',\n format: 'date-time'\n },\n inputs: {\n type: 'array',\n description: 'List of input configurations for the application.',\n items: {\n type: 'object',\n title: 'application_input',\n description: 'Configuration for an individual input field in the application.',\n properties: {\n input_type: {\n type: 'string',\n title: 'application_input_type',\n description: 'Type of input field determining its behavior and validation rules.',\n enum: [ 'text',\n 'dropdown',\n 'file',\n 'media'\n ]\n },\n name: {\n type: 'string',\n description: 'Identifier for the input field.'\n },\n required: {\n type: 'boolean',\n description: 'Indicates if this input field is mandatory.'\n },\n description: {\n type: 'string',\n description: 'Human-readable description of the input field\\'s purpose.'\n },\n options: {\n anyOf: [ {\n type: 'object',\n title: 'Dropdown',\n description: 'Configuration options specific to dropdown-type input fields.',\n properties: {\n list: {\n type: 'array',\n description: 'List of available options in the dropdown menu.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'list'\n ]\n },\n {\n type: 'object',\n title: 'File',\n description: 'Configuration options specific to file upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed file extensions.',\n items: {\n type: 'string'\n }\n },\n max_file_size_mb: {\n type: 'integer',\n description: 'Maximum file size allowed in megabytes.'\n },\n max_files: {\n type: 'integer',\n description: 'Maximum number of files that can be uploaded.'\n },\n max_word_count: {\n type: 'integer',\n description: 'Maximum number of words allowed in text files.'\n },\n upload_types: {\n type: 'array',\n description: 'List of allowed upload types for file inputs.',\n items: {\n type: 'string',\n title: 'file_upload_type',\n description: 'Type of file upload method supported by the application.',\n enum: [ 'url',\n 'file_id'\n ]\n }\n }\n },\n required: [ 'file_types',\n 'max_file_size_mb',\n 'max_files',\n 'max_word_count',\n 'upload_types'\n ]\n },\n {\n type: 'object',\n title: 'Media',\n description: 'Configuration options specific to media upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed media file types.',\n items: {\n type: 'string'\n }\n },\n max_image_size_mb: {\n type: 'integer',\n description: 'Maximum media file size allowed in megabytes.'\n }\n },\n required: [ 'file_types',\n 'max_image_size_mb'\n ]\n },\n {\n type: 'object',\n title: 'Text',\n description: 'Configuration options specific to text input fields.',\n properties: {\n max_fields: {\n type: 'integer',\n description: 'Maximum number of text fields allowed.'\n },\n min_fields: {\n type: 'integer',\n description: 'Minimum number of text fields required.'\n }\n },\n required: [ 'max_fields',\n 'min_fields'\n ]\n }\n ],\n description: 'Type-specific configuration options for input fields.'\n }\n },\n required: [ 'input_type',\n 'name',\n 'required'\n ]\n }\n },\n name: {\n type: 'string',\n description: 'Display name of the application.'\n },\n status: {\n type: 'string',\n title: 'application_status',\n description: 'Current deployment status of the application. Note: currently only `deployed` applications are returned.',\n enum: [ 'deployed',\n 'draft'\n ]\n },\n type: {\n type: 'string',\n title: 'application_type',\n description: 'The type of no-code application.',\n enum: [ 'generation'\n ]\n },\n updated_at: {\n type: 'string',\n description: 'Timestamp when the application was last updated.',\n format: 'date-time'\n },\n last_deployed_at: {\n type: 'string',\n description: 'Timestamp when the application was last deployed.',\n format: 'date-time'\n }\n },\n required: [ 'id',\n 'created_at',\n 'inputs',\n 'name',\n 'status',\n 'type',\n 'updated_at'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieves detailed information for a specific no-code agent (formerly called no-code applications), including its configuration and current status.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/application_retrieve_response',\n $defs: {\n application_retrieve_response: {\n type: 'object',\n title: 'application_with_inputs',\n description: 'Detailed application object including its input configuration.',\n properties: {\n id: {\n type: 'string',\n description: 'Unique identifier for the application.'\n },\n created_at: {\n type: 'string',\n description: 'Timestamp when the application was created.',\n format: 'date-time'\n },\n inputs: {\n type: 'array',\n description: 'List of input configurations for the application.',\n items: {\n type: 'object',\n title: 'application_input',\n description: 'Configuration for an individual input field in the application.',\n properties: {\n input_type: {\n type: 'string',\n title: 'application_input_type',\n description: 'Type of input field determining its behavior and validation rules.',\n enum: [ 'text',\n 'dropdown',\n 'file',\n 'media'\n ]\n },\n name: {\n type: 'string',\n description: 'Identifier for the input field.'\n },\n required: {\n type: 'boolean',\n description: 'Indicates if this input field is mandatory.'\n },\n description: {\n type: 'string',\n description: 'Human-readable description of the input field\\'s purpose.'\n },\n options: {\n anyOf: [ {\n type: 'object',\n title: 'Dropdown',\n description: 'Configuration options specific to dropdown-type input fields.',\n properties: {\n list: {\n type: 'array',\n description: 'List of available options in the dropdown menu.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'list'\n ]\n },\n {\n type: 'object',\n title: 'File',\n description: 'Configuration options specific to file upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed file extensions.',\n items: {\n type: 'string'\n }\n },\n max_file_size_mb: {\n type: 'integer',\n description: 'Maximum file size allowed in megabytes.'\n },\n max_files: {\n type: 'integer',\n description: 'Maximum number of files that can be uploaded.'\n },\n max_word_count: {\n type: 'integer',\n description: 'Maximum number of words allowed in text files.'\n },\n upload_types: {\n type: 'array',\n description: 'List of allowed upload types for file inputs.',\n items: {\n type: 'string',\n title: 'file_upload_type',\n description: 'Type of file upload method supported by the application.',\n enum: [ 'url',\n 'file_id'\n ]\n }\n }\n },\n required: [ 'file_types',\n 'max_file_size_mb',\n 'max_files',\n 'max_word_count',\n 'upload_types'\n ]\n },\n {\n type: 'object',\n title: 'Media',\n description: 'Configuration options specific to media upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed media file types.',\n items: {\n type: 'string'\n }\n },\n max_image_size_mb: {\n type: 'integer',\n description: 'Maximum media file size allowed in megabytes.'\n }\n },\n required: [ 'file_types',\n 'max_image_size_mb'\n ]\n },\n {\n type: 'object',\n title: 'Text',\n description: 'Configuration options specific to text input fields.',\n properties: {\n max_fields: {\n type: 'integer',\n description: 'Maximum number of text fields allowed.'\n },\n min_fields: {\n type: 'integer',\n description: 'Minimum number of text fields required.'\n }\n },\n required: [ 'max_fields',\n 'min_fields'\n ]\n }\n ],\n description: 'Type-specific configuration options for input fields.'\n }\n },\n required: [ 'input_type',\n 'name',\n 'required'\n ]\n }\n },\n name: {\n type: 'string',\n description: 'Display name of the application.'\n },\n status: {\n type: 'string',\n title: 'application_status',\n description: 'Current deployment status of the application. Note: currently only `deployed` applications are returned.',\n enum: [ 'deployed',\n 'draft'\n ]\n },\n type: {\n type: 'string',\n title: 'application_type',\n description: 'The type of no-code application.',\n enum: [ 'generation'\n ]\n },\n updated_at: {\n type: 'string',\n description: 'Timestamp when the application was last updated.',\n format: 'date-time'\n },\n last_deployed_at: {\n type: 'string',\n description: 'Timestamp when the application was last deployed.',\n format: 'date-time'\n }\n },\n required: [ 'id',\n 'created_at',\n 'inputs',\n 'name',\n 'status',\n 'type',\n 'updated_at'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/files/delete-files.ts b/packages/mcp-server/src/tools/files/delete-files.ts index d7af8d32..ed9fe7cd 100644 --- a/packages/mcp-server/src/tools/files/delete-files.ts +++ b/packages/mcp-server/src/tools/files/delete-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'delete_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nPermanently delete a file from the system. This action cannot be undone.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'delete_file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the deleted file.'\n },\n deleted: {\n type: 'boolean',\n description: 'Indicates whether the file was successfully deleted.'\n }\n },\n required: [ 'id',\n 'deleted'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nPermanently delete a file from the system. This action cannot be undone.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file_delete_response',\n $defs: {\n file_delete_response: {\n type: 'object',\n title: 'delete_file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the deleted file.'\n },\n deleted: {\n type: 'boolean',\n description: 'Indicates whether the file was successfully deleted.'\n }\n },\n required: [ 'id',\n 'deleted'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/files/retry-files.ts b/packages/mcp-server/src/tools/files/retry-files.ts index 868ae1e1..4470e40a 100644 --- a/packages/mcp-server/src/tools/files/retry-files.ts +++ b/packages/mcp-server/src/tools/files/retry-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'retry_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetry processing of files that previously failed to process. This will re-attempt the processing of the specified files.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'retry_files_response',\n properties: {\n success: {\n type: 'boolean',\n description: 'Indicates whether the retry operation was successful.'\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetry processing of files that previously failed to process. This will re-attempt the processing of the specified files.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file_retry_response',\n $defs: {\n file_retry_response: {\n type: 'object',\n title: 'retry_files_response',\n properties: {\n success: {\n type: 'boolean',\n description: 'Indicates whether the retry operation was successful.'\n }\n }\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/create-graphs.ts b/packages/mcp-server/src/tools/graphs/create-graphs.ts index 7d7bbd88..b68a196d 100644 --- a/packages/mcp-server/src/tools/graphs/create-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/create-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'create_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nCreate a new Knowledge Graph.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph (max 255 characters).'\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph (max 255 characters).'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'name'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nCreate a new Knowledge Graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph_create_response',\n $defs: {\n graph_create_response: {\n type: 'object',\n title: 'graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph (max 255 characters).'\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph (max 255 characters).'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'name'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/delete-graphs.ts b/packages/mcp-server/src/tools/graphs/delete-graphs.ts index aa2d12a4..ca9207eb 100644 --- a/packages/mcp-server/src/tools/graphs/delete-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/delete-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'delete_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nDelete a Knowledge Graph.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'delete_graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the deleted Knowledge Graph.'\n },\n deleted: {\n type: 'boolean',\n description: 'Indicates whether the Knowledge Graph was successfully deleted.'\n }\n },\n required: [ 'id',\n 'deleted'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nDelete a Knowledge Graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph_delete_response',\n $defs: {\n graph_delete_response: {\n type: 'object',\n title: 'delete_graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the deleted Knowledge Graph.'\n },\n deleted: {\n type: 'boolean',\n description: 'Indicates whether the Knowledge Graph was successfully deleted.'\n }\n },\n required: [ 'id',\n 'deleted'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts b/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts index 2e049669..9cec09d2 100644 --- a/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'remove_file_from_graph_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRemove a file from a Knowledge Graph.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'delete_file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the deleted file.'\n },\n deleted: {\n type: 'boolean',\n description: 'Indicates whether the file was successfully deleted.'\n }\n },\n required: [ 'id',\n 'deleted'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRemove a file from a Knowledge Graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph_remove_file_from_graph_response',\n $defs: {\n graph_remove_file_from_graph_response: {\n type: 'object',\n title: 'delete_file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the deleted file.'\n },\n deleted: {\n type: 'boolean',\n description: 'Indicates whether the file was successfully deleted.'\n }\n },\n required: [ 'id',\n 'deleted'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/update-graphs.ts b/packages/mcp-server/src/tools/graphs/update-graphs.ts index 1657182e..38c571a6 100644 --- a/packages/mcp-server/src/tools/graphs/update-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/update-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'update_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nUpdate the name and description of a Knowledge Graph.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph (max 255 characters).'\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph (max 255 characters).'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'name'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nUpdate the name and description of a Knowledge Graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph_update_response',\n $defs: {\n graph_update_response: {\n type: 'object',\n title: 'graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph (max 255 characters).'\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph (max 255 characters).'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'name'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/models/list-models.ts b/packages/mcp-server/src/tools/models/list-models.ts index 11288956..32fc949e 100644 --- a/packages/mcp-server/src/tools/models/list-models.ts +++ b/packages/mcp-server/src/tools/models/list-models.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'list_models', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieve a list of available models that can be used for text generation, chat completions, and other AI tasks.\n\n# Response Schema\n```json\n{\n type: 'object',\n properties: {\n models: {\n type: 'array',\n description: 'The [ID of the model](https://dev.writer.com/home/models) to use for processing the request.',\n items: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The ID of the particular LLM that you want to use'\n },\n name: {\n type: 'string',\n description: 'The name of the particular LLM that you want to use.'\n }\n },\n required: [ 'id',\n 'name'\n ]\n }\n }\n },\n required: [ 'models'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieve a list of available models that can be used for text generation, chat completions, and other AI tasks.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/model_list_response',\n $defs: {\n model_list_response: {\n type: 'object',\n properties: {\n models: {\n type: 'array',\n description: 'The [ID of the model](https://dev.writer.com/home/models) to use for processing the request.',\n items: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The ID of the particular LLM that you want to use'\n },\n name: {\n type: 'string',\n description: 'The name of the particular LLM that you want to use.'\n }\n },\n required: [ 'id',\n 'name'\n ]\n }\n }\n },\n required: [ 'models'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/tools/ai-detect-tools.ts b/packages/mcp-server/src/tools/tools/ai-detect-tools.ts index f9d3aabb..b7f07f11 100644 --- a/packages/mcp-server/src/tools/tools/ai-detect-tools.ts +++ b/packages/mcp-server/src/tools/tools/ai-detect-tools.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'ai_detect_tools', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nDetects if content is AI- or human-generated, with a confidence score. Content must have at least 350 characters\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'ai_detection_response',\n properties: {\n label: {\n type: 'string',\n enum: [ 'fake',\n 'real'\n ]\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'label',\n 'score'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nDetects if content is AI- or human-generated, with a confidence score. Content must have at least 350 characters\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/tool_ai_detect_response',\n $defs: {\n tool_ai_detect_response: {\n type: 'object',\n title: 'ai_detection_response',\n properties: {\n label: {\n type: 'string',\n enum: [ 'fake',\n 'real'\n ]\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'label',\n 'score'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts b/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts index 1daf29e4..4e7ae07e 100644 --- a/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts +++ b/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'medical_tools_comprehend', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nAnalyze unstructured medical text to extract entities labeled with standardized medical codes and confidence scores.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'medical_comprehend_response',\n properties: {\n entities: {\n type: 'array',\n description: 'An array of medical entities extracted from the input text.',\n items: {\n type: 'object',\n title: 'medical_comprehend_entity',\n properties: {\n attributes: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_attribute',\n properties: {\n begin_offset: {\n type: 'integer'\n },\n concepts: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_concept',\n properties: {\n code: {\n type: 'string'\n },\n description: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'code',\n 'description',\n 'score'\n ]\n }\n },\n end_offset: {\n type: 'integer'\n },\n relationship_score: {\n type: 'number'\n },\n score: {\n type: 'number'\n },\n text: {\n type: 'string'\n },\n traits: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_trait',\n properties: {\n name: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'name',\n 'score'\n ]\n }\n },\n type: {\n type: 'string'\n },\n category: {\n type: 'string'\n },\n relationship_type: {\n type: 'string'\n }\n },\n required: [ 'begin_offset',\n 'concepts',\n 'end_offset',\n 'relationship_score',\n 'score',\n 'text',\n 'traits',\n 'type'\n ]\n }\n },\n begin_offset: {\n type: 'integer'\n },\n category: {\n type: 'string'\n },\n concepts: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_concept',\n properties: {\n code: {\n type: 'string'\n },\n description: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'code',\n 'description',\n 'score'\n ]\n }\n },\n end_offset: {\n type: 'integer'\n },\n score: {\n type: 'number'\n },\n text: {\n type: 'string'\n },\n traits: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_trait',\n properties: {\n name: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'name',\n 'score'\n ]\n }\n },\n type: {\n type: 'string'\n }\n },\n required: [ 'attributes',\n 'begin_offset',\n 'category',\n 'concepts',\n 'end_offset',\n 'score',\n 'text',\n 'traits',\n 'type'\n ]\n }\n }\n },\n required: [ 'entities'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nAnalyze unstructured medical text to extract entities labeled with standardized medical codes and confidence scores.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/comprehend_medical_response',\n $defs: {\n comprehend_medical_response: {\n type: 'object',\n title: 'medical_comprehend_response',\n properties: {\n entities: {\n type: 'array',\n description: 'An array of medical entities extracted from the input text.',\n items: {\n type: 'object',\n title: 'medical_comprehend_entity',\n properties: {\n attributes: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_attribute',\n properties: {\n begin_offset: {\n type: 'integer'\n },\n concepts: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_concept',\n properties: {\n code: {\n type: 'string'\n },\n description: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'code',\n 'description',\n 'score'\n ]\n }\n },\n end_offset: {\n type: 'integer'\n },\n relationship_score: {\n type: 'number'\n },\n score: {\n type: 'number'\n },\n text: {\n type: 'string'\n },\n traits: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_trait',\n properties: {\n name: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'name',\n 'score'\n ]\n }\n },\n type: {\n type: 'string'\n },\n category: {\n type: 'string'\n },\n relationship_type: {\n type: 'string'\n }\n },\n required: [ 'begin_offset',\n 'concepts',\n 'end_offset',\n 'relationship_score',\n 'score',\n 'text',\n 'traits',\n 'type'\n ]\n }\n },\n begin_offset: {\n type: 'integer'\n },\n category: {\n type: 'string'\n },\n concepts: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_concept',\n properties: {\n code: {\n type: 'string'\n },\n description: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'code',\n 'description',\n 'score'\n ]\n }\n },\n end_offset: {\n type: 'integer'\n },\n score: {\n type: 'number'\n },\n text: {\n type: 'string'\n },\n traits: {\n type: 'array',\n items: {\n type: 'object',\n title: 'medical_comprehend_trait',\n properties: {\n name: {\n type: 'string'\n },\n score: {\n type: 'number'\n }\n },\n required: [ 'name',\n 'score'\n ]\n }\n },\n type: {\n type: 'string'\n }\n },\n required: [ 'attributes',\n 'begin_offset',\n 'category',\n 'concepts',\n 'end_offset',\n 'score',\n 'text',\n 'traits',\n 'type'\n ]\n }\n }\n },\n required: [ 'entities'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts b/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts index b79d9615..d5a582e3 100644 --- a/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts +++ b/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'context_aware_splitting_tools', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nSplits a long block of text (maximum 4000 words) into smaller chunks while preserving the semantic meaning of the text and context between the chunks.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'context_aware_splitting_response',\n properties: {\n chunks: {\n type: 'array',\n description: 'An array of text chunks generated by splitting the input text based on the specified strategy.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'chunks'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nSplits a long block of text (maximum 4000 words) into smaller chunks while preserving the semantic meaning of the text and context between the chunks.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/tool_context_aware_splitting_response',\n $defs: {\n tool_context_aware_splitting_response: {\n type: 'object',\n title: 'context_aware_splitting_response',\n properties: {\n chunks: {\n type: 'array',\n description: 'An array of text chunks generated by splitting the input text based on the specified strategy.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'chunks'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts b/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts index 38d6797f..046ce377 100644 --- a/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts +++ b/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'parse_pdf_tools', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nParse PDF to other formats.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'parse_pdf_response',\n properties: {\n content: {\n type: 'string',\n description: 'The extracted content from the PDF file, converted to the specified format.'\n }\n },\n required: [ 'content'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nParse PDF to other formats.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/tool_parse_pdf_response',\n $defs: {\n tool_parse_pdf_response: {\n type: 'object',\n title: 'parse_pdf_response',\n properties: {\n content: {\n type: 'string',\n description: 'The extracted content from the PDF file, converted to the specified format.'\n }\n },\n required: [ 'content'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/tools/web-search-tools.ts b/packages/mcp-server/src/tools/tools/web-search-tools.ts index 983b70d6..14c18197 100644 --- a/packages/mcp-server/src/tools/tools/web-search-tools.ts +++ b/packages/mcp-server/src/tools/tools/web-search-tools.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'web_search_tools', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nSearch the web for information about a given query and return relevant results with source URLs.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'web_search_response',\n properties: {\n query: {\n type: 'string',\n description: 'The search query that was submitted.'\n },\n sources: {\n type: 'array',\n description: 'The search results found.',\n items: {\n type: 'object',\n properties: {\n raw_content: {\n type: 'string',\n description: 'Raw content from the source URL. Not included if `include_raw_content` is `false`.'\n },\n url: {\n type: 'string',\n description: 'URL of the search result.'\n }\n }\n }\n },\n answer: {\n type: 'string',\n description: 'Generated answer based on the search results. Not included if `include_answer` is `false`.'\n }\n },\n required: [ 'query',\n 'sources'\n ]\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nSearch the web for information about a given query and return relevant results with source URLs.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/tool_web_search_response',\n $defs: {\n tool_web_search_response: {\n type: 'object',\n title: 'web_search_response',\n properties: {\n query: {\n type: 'string',\n description: 'The search query that was submitted.'\n },\n sources: {\n type: 'array',\n description: 'The search results found.',\n items: {\n type: 'object',\n properties: {\n raw_content: {\n type: 'string',\n description: 'Raw content from the source URL. Not included if `include_raw_content` is `false`.'\n },\n url: {\n type: 'string',\n description: 'URL of the search result.'\n }\n }\n }\n },\n answer: {\n type: 'string',\n description: 'Generated answer based on the search results. Not included if `include_answer` is `false`.'\n }\n },\n required: [ 'query',\n 'sources'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { From b7847abd4a65c07090855fd674c6bd4ff15b9760 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 17:14:36 +0000 Subject: [PATCH 05/26] fix(client): incorrect offset pagination check --- src/core/pagination.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/pagination.ts b/src/core/pagination.ts index ef93f02a..383535e1 100644 --- a/src/core/pagination.ts +++ b/src/core/pagination.ts @@ -245,11 +245,7 @@ export class ApplicationJobsOffset } nextPageRequestOptions(): PageRequestOptions | null { - const offset = this.pagination?.offset; - if (!offset) { - return null; - } - + const offset = this.pagination?.offset ?? 0; const length = this.getPaginatedItems().length; const currentCount = offset + length; From 43acbcefa5cdbabe670ef4a5687ef871a3acf9f6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 30 Oct 2025 17:45:52 +0000 Subject: [PATCH 06/26] fix(mcpb): pin @anthropic-ai/mcpb version --- packages/mcp-server/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 73f08781..c989c5b4 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -47,7 +47,7 @@ "mcp-server": "dist/index.js" }, "devDependencies": { - "@anthropic-ai/mcpb": "^1.1.0", + "@anthropic-ai/mcpb": "1.1.0", "@types/cors": "^2.8.19", "@types/express": "^5.0.3", "@types/jest": "^29.4.0", From 7dfbe171aa29752dd3e42e15d045fde008d6e96c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:11:48 +0000 Subject: [PATCH 07/26] chore(internal): grammar fix (it's -> its) --- packages/mcp-server/src/code-tool.ts | 4 ++-- packages/mcp-server/src/dynamic-tools.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/mcp-server/src/code-tool.ts b/packages/mcp-server/src/code-tool.ts index 3b16d71c..026e8d81 100644 --- a/packages/mcp-server/src/code-tool.ts +++ b/packages/mcp-server/src/code-tool.ts @@ -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' } } }, }; diff --git a/packages/mcp-server/src/dynamic-tools.ts b/packages/mcp-server/src/dynamic-tools.ts index 88303f0d..a35da358 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. * From e140047e470588b4c18bccbdb752078f198d8374 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 23:01:07 +0000 Subject: [PATCH 08/26] chore: use structured error when code execution tool errors --- packages/mcp-server/src/code-tool.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/mcp-server/src/code-tool.ts b/packages/mcp-server/src/code-tool.ts index 026e8d81..4c0376fb 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 Writer, { ClientOptions } from 'writer-sdk'; -import { Endpoint, ContentBlock, Metadata } from './tools/types'; +import { ContentBlock, Endpoint, Metadata, ToolCallResult } from './tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; @@ -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: Writer, args: unknown) => { + const handler = async (client: Writer, args: unknown): Promise => { const baseURLHostname = new URL(client.baseURL).hostname; const { code } = args as { code: string }; @@ -97,7 +97,7 @@ export async function codeTool(): Promise { } satisfies WorkerInput); req.write(body, (err) => { - if (err !== null && err !== undefined) { + if (err != null) { reject(err); } }); @@ -108,12 +108,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 @@ -133,10 +133,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(); } From 16c1a446e5f1cf853582afe76bbc21739855ca70 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 15:52:22 +0000 Subject: [PATCH 09/26] chore: mcp code tool explicit error message when missing a run function --- packages/mcp-server/package.json | 4 +- packages/mcp-server/src/code-tool-worker.ts | 47 +++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index c989c5b4..27703b71 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -38,6 +38,7 @@ "express": "^5.1.0", "jq-web": "https://github.com/stainless-api/jq-web/releases/download/v0.8.6/jq-web.tar.gz", "qs": "^6.14.0", + "typescript": "5.8.3", "yargs": "^17.7.2", "zod": "^3.25.20", "zod-to-json-schema": "^3.24.5", @@ -64,8 +65,7 @@ "ts-morph": "^19.0.0", "ts-node": "^10.5.0", "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz", - "tsconfig-paths": "^4.0.0", - "typescript": "5.8.3" + "tsconfig-paths": "^4.0.0" }, "imports": { "writer-sdk-mcp": ".", diff --git a/packages/mcp-server/src/code-tool-worker.ts b/packages/mcp-server/src/code-tool-worker.ts index 2995c75c..50231703 100644 --- a/packages/mcp-server/src/code-tool-worker.ts +++ b/packages/mcp-server/src/code-tool-worker.ts @@ -1,11 +1,58 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import util from 'node:util'; + +import ts from 'typescript'; + import { WorkerInput, WorkerSuccess, WorkerError } from './code-tool-types'; import { Writer } from 'writer-sdk'; +function getRunFunctionNode( + code: string, +): ts.FunctionDeclaration | ts.FunctionExpression | ts.ArrowFunction | null { + const sourceFile = ts.createSourceFile('code.ts', code, ts.ScriptTarget.Latest, true); + + for (const statement of sourceFile.statements) { + // Check for top-level function declarations + if (ts.isFunctionDeclaration(statement)) { + if (statement.name?.text === 'run') { + return statement; + } + } + + // Check for variable declarations: const run = () => {} or const run = function() {} + if (ts.isVariableStatement(statement)) { + for (const declaration of statement.declarationList.declarations) { + if (ts.isIdentifier(declaration.name) && declaration.name.text === 'run') { + // Check if it's initialized with a function + if ( + declaration.initializer && + (ts.isFunctionExpression(declaration.initializer) || ts.isArrowFunction(declaration.initializer)) + ) { + return declaration.initializer; + } + } + } + } + } + + return null; +} + const fetch = async (req: Request): Promise => { const { opts, code } = (await req.json()) as WorkerInput; + + const runFunctionNode = getRunFunctionNode(code); + if (!runFunctionNode) { + return Response.json( + { + message: + 'The code is missing a top-level `run` function. Write code within this template:\n\n```\nasync function run(client) {\n // Fill this out\n}\n```', + } satisfies WorkerError, + { status: 400, statusText: 'Code execution error' }, + ); + } + const client = new Writer({ ...opts, }); From cad37b70c93d26bdafdfdf6047e9591a1b27376e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 22:22:55 +0000 Subject: [PATCH 10/26] feat(mcp): enable optional code execution tool on http mcp servers --- packages/mcp-server/src/options.ts | 13 ++++++++++--- packages/mcp-server/tests/options.test.ts | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/mcp-server/src/options.ts b/packages/mcp-server/src/options.ts index 4fe3b987..b6ff5976 100644 --- a/packages/mcp-server/src/options.ts +++ b/packages/mcp-server/src/options.ts @@ -284,8 +284,10 @@ const coerceArray = (zodType: T) => ); const QueryOptions = z.object({ - tools: coerceArray(z.enum(['dynamic', 'all', 'docs'])).describe('Use dynamic tools or all tools'), - no_tools: coerceArray(z.enum(['dynamic', 'all', 'docs'])).describe('Do not use dynamic tools or all tools'), + tools: coerceArray(z.enum(['dynamic', 'all', 'code', 'docs'])).describe('Specify which MCP tools to use'), + no_tools: coerceArray(z.enum(['dynamic', 'all', 'code', 'docs'])).describe( + 'Specify which MCP tools to not use.', + ), tool: coerceArray(z.string()).describe('Include tools matching the specified names'), resource: coerceArray(z.string()).describe('Include tools matching the specified resources'), operation: coerceArray(z.enum(['read', 'write'])).describe( @@ -385,11 +387,16 @@ export function parseQueryOptions(defaultOptions: McpOptions, query: unknown): M : queryOptions.tools?.includes('docs') ? true : defaultOptions.includeDocsTools; + let codeTools: boolean | undefined = + queryOptions.no_tools && queryOptions.no_tools?.includes('code') ? false + : queryOptions.tools?.includes('code') && defaultOptions.includeCodeTools ? true + : defaultOptions.includeCodeTools; + return { client: queryOptions.client ?? defaultOptions.client, includeDynamicTools: dynamicTools, includeAllTools: allTools, - includeCodeTools: undefined, + includeCodeTools: codeTools, includeDocsTools: docsTools, filters, capabilities: clientCapabilities, diff --git a/packages/mcp-server/tests/options.test.ts b/packages/mcp-server/tests/options.test.ts index a8a5b81a..4d9b60ca 100644 --- a/packages/mcp-server/tests/options.test.ts +++ b/packages/mcp-server/tests/options.test.ts @@ -171,6 +171,7 @@ describe('parseQueryOptions', () => { const defaultOptions = { client: undefined, includeDynamicTools: undefined, + includeCodeTools: undefined, includeAllTools: undefined, filters: [], capabilities: { @@ -383,6 +384,27 @@ describe('parseQueryOptions', () => { { type: 'tool', op: 'exclude', value: 'exclude-tool' }, ]); }); + + it('code tools are enabled on http servers with default option set', () => { + const query = 'tools=code'; + const result = parseQueryOptions({ ...defaultOptions, includeCodeTools: true }, query); + + expect(result.includeCodeTools).toBe(true); + }); + + it('code tools are prevented on http servers when no default option set', () => { + const query = 'tools=code'; + const result = parseQueryOptions(defaultOptions, query); + + expect(result.includeCodeTools).toBe(undefined); + }); + + it('code tools are prevented on http servers when default option is explicitly false', () => { + const query = 'tools=code'; + const result = parseQueryOptions({ ...defaultOptions, includeCodeTools: false }, query); + + expect(result.includeCodeTools).toBe(false); + }); }); describe('parseEmbeddedJSON', () => { From e6a4a0c0936a215c9aed87365108b3bcf59303fd Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 16:20:20 +0000 Subject: [PATCH 11/26] chore(mcp): add friendlier MCP code tool errors on incorrect method invocations --- packages/mcp-server/package.json | 1 + packages/mcp-server/src/code-tool-worker.ts | 121 +++++++++++++++++++- packages/mcp-server/src/code-tool.ts | 2 +- 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 27703b71..5a617c1c 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -36,6 +36,7 @@ "@valtown/deno-http-worker": "^0.0.21", "cors": "^2.8.5", "express": "^5.1.0", + "fuse.js": "^7.1.0", "jq-web": "https://github.com/stainless-api/jq-web/releases/download/v0.8.6/jq-web.tar.gz", "qs": "^6.14.0", "typescript": "5.8.3", diff --git a/packages/mcp-server/src/code-tool-worker.ts b/packages/mcp-server/src/code-tool-worker.ts index 50231703..cf00f975 100644 --- a/packages/mcp-server/src/code-tool-worker.ts +++ b/packages/mcp-server/src/code-tool-worker.ts @@ -2,6 +2,7 @@ import util from 'node:util'; +import Fuse from 'fuse.js'; import ts from 'typescript'; import { WorkerInput, WorkerSuccess, WorkerError } from './code-tool-types'; @@ -39,8 +40,126 @@ function getRunFunctionNode( return null; } +const fuse = new Fuse( + [ + 'client.applications.generateContent', + 'client.applications.list', + 'client.applications.retrieve', + 'client.applications.jobs.create', + 'client.applications.jobs.list', + 'client.applications.jobs.retrieve', + 'client.applications.jobs.retry', + 'client.applications.graphs.list', + 'client.applications.graphs.update', + 'client.chat.chat', + 'client.completions.create', + 'client.models.list', + 'client.graphs.addFileToGraph', + 'client.graphs.create', + 'client.graphs.delete', + 'client.graphs.list', + 'client.graphs.question', + 'client.graphs.removeFileFromGraph', + 'client.graphs.retrieve', + 'client.graphs.update', + 'client.files.delete', + 'client.files.download', + 'client.files.list', + 'client.files.retrieve', + 'client.files.retry', + 'client.files.upload', + 'client.tools.aiDetect', + 'client.tools.contextAwareSplitting', + 'client.tools.parsePdf', + 'client.tools.webSearch', + 'client.tools.comprehend.medical', + 'client.translation.translate', + 'client.vision.analyze', + ], + { threshold: 1, shouldSort: true }, +); + +function getMethodSuggestions(fullyQualifiedMethodName: string): string[] { + return fuse + .search(fullyQualifiedMethodName) + .map(({ item }) => item) + .slice(0, 5); +} + +const proxyToObj = new WeakMap(); +const objToProxy = new WeakMap(); + +type ClientProxyConfig = { + path: string[]; + isBelievedBad?: boolean; +}; + +function makeSdkProxy(obj: T, { path, isBelievedBad = false }: ClientProxyConfig): T { + let proxy: T = objToProxy.get(obj); + + if (!proxy) { + proxy = new Proxy(obj, { + get(target, prop, receiver) { + const propPath = [...path, String(prop)]; + const value = Reflect.get(target, prop, receiver); + + if (isBelievedBad || (!(prop in target) && value === undefined)) { + // If we're accessing a path that doesn't exist, it will probably eventually error. + // Let's proxy it and mark it bad so that we can control the error message. + // We proxy an empty class so that an invocation or construction attempt is possible. + return makeSdkProxy(class {}, { path: propPath, isBelievedBad: true }); + } + + if (value !== null && (typeof value === 'object' || typeof value === 'function')) { + return makeSdkProxy(value, { path: propPath, isBelievedBad }); + } + + return value; + }, + + apply(target, thisArg, args) { + if (isBelievedBad || typeof target !== 'function') { + const fullyQualifiedMethodName = path.join('.'); + const suggestions = getMethodSuggestions(fullyQualifiedMethodName); + throw new Error( + `${fullyQualifiedMethodName} is not a function. Did you mean: ${suggestions.join(', ')}`, + ); + } + + return Reflect.apply(target, proxyToObj.get(thisArg) ?? thisArg, args); + }, + + construct(target, args, newTarget) { + if (isBelievedBad || typeof target !== 'function') { + const fullyQualifiedMethodName = path.join('.'); + const suggestions = getMethodSuggestions(fullyQualifiedMethodName); + throw new Error( + `${fullyQualifiedMethodName} is not a constructor. Did you mean: ${suggestions.join(', ')}`, + ); + } + + return Reflect.construct(target, args, newTarget); + }, + }); + + objToProxy.set(obj, proxy); + proxyToObj.set(proxy, obj); + } + + return proxy; +} + const fetch = async (req: Request): Promise => { const { opts, code } = (await req.json()) as WorkerInput; + if (code == null) { + return Response.json( + { + message: + 'The code param is missing. Provide one containing a top-level `run` function. Write code within this template:\n\n```\nasync function run(client) {\n // Fill this out\n}\n```', + } satisfies WorkerError, + { status: 400, statusText: 'Code execution error' }, + ); + } const runFunctionNode = getRunFunctionNode(code); if (!runFunctionNode) { @@ -73,7 +192,7 @@ const fetch = async (req: Request): Promise => { ${code} run_ = run; `); - const result = await run_(client); + const result = await run_(makeSdkProxy(client, { path: ['client'] })); return Response.json({ result, logLines, diff --git a/packages/mcp-server/src/code-tool.ts b/packages/mcp-server/src/code-tool.ts index 4c0376fb..ecd7da9b 100644 --- a/packages/mcp-server/src/code-tool.ts +++ b/packages/mcp-server/src/code-tool.ts @@ -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.\n\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 named "client", and it will be run.\nWrite code within this template:\n\n```\nasync function run(client) {\n // Fill this out\n}\n```\n\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' } } }, }; From 00af445b63b9a0db2fb59202f7ed3c4d34887990 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 18:26:04 +0000 Subject: [PATCH 12/26] chore(mcp): add line numbers to code tool errors --- packages/mcp-server/src/code-tool-worker.ts | 27 ++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/mcp-server/src/code-tool-worker.ts b/packages/mcp-server/src/code-tool-worker.ts index cf00f975..1c458202 100644 --- a/packages/mcp-server/src/code-tool-worker.ts +++ b/packages/mcp-server/src/code-tool-worker.ts @@ -149,6 +149,25 @@ function makeSdkProxy(obj: T, { path, isBelievedBad = false }: return proxy; } +function parseError(code: string, error: unknown): string | undefined { + if (!(error instanceof Error)) return; + const message = error.name ? `${error.name}: ${error.message}` : error.message; + try { + // Deno uses V8; the first ":LINE:COLUMN" is the top of stack. + const lineNumber = error.stack?.match(/:([0-9]+):[0-9]+/)?.[1]; + // -1 for the zero-based indexing + const line = + lineNumber && + code + .split('\n') + .at(parseInt(lineNumber, 10) - 1) + ?.trim(); + return line ? `${message}\n at line ${lineNumber}\n ${line}` : message; + } catch { + return message; + } +} + const fetch = async (req: Request): Promise => { const { opts, code } = (await req.json()) as WorkerInput; if (code == null) { @@ -188,10 +207,7 @@ const fetch = async (req: Request): Promise => { }; try { let run_ = async (client: any) => {}; - eval(` - ${code} - run_ = run; - `); + eval(`${code}\nrun_ = run;`); const result = await run_(makeSdkProxy(client, { path: ['client'] })); return Response.json({ result, @@ -199,10 +215,9 @@ const fetch = async (req: Request): Promise => { errLines, } satisfies WorkerSuccess); } catch (e) { - const message = e instanceof Error ? e.message : undefined; return Response.json( { - message, + message: parseError(code, e), } satisfies WorkerError, { status: 400, statusText: 'Code execution error' }, ); From 062b7d73c91530ea083872b67036a77265db9a8d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 21:19:27 +0000 Subject: [PATCH 13/26] docs(mcp): add a README button for one-click add to Cursor --- packages/mcp-server/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 1f3c8de9..dd1fd2f4 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -34,6 +34,13 @@ For clients with a configuration JSON, it might look something like this: } ``` +### Cursor + + If you use Cursor, you can install the MCP server by using the button below. You will need to set your environment variables + in Cursor's `mcp.json`, which can be found in Cursor Settings > Tools & MCP > New MCP Server. + + [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6IlNldCB5b3VyIFdSSVRFUl9BUElfS0VZIGhlcmUuIn19) + ## Exposing endpoints to your MCP Client There are two ways to expose endpoints as tools in the MCP server: From 5e3027034d15d23909742ac7a65d5e1db6709631 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 00:42:32 +0000 Subject: [PATCH 14/26] chore(internal): codegen related update --- packages/mcp-server/README.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index dd1fd2f4..5b4edcd5 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -36,17 +36,18 @@ For clients with a configuration JSON, it might look something like this: ### Cursor - If you use Cursor, you can install the MCP server by using the button below. You will need to set your environment variables - in Cursor's `mcp.json`, which can be found in Cursor Settings > Tools & MCP > New MCP Server. +If you use Cursor, you can install the MCP server by using the button below. You will need to set your environment variables +in Cursor's `mcp.json`, which can be found in Cursor Settings > Tools & MCP > New MCP Server. - [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6IlNldCB5b3VyIFdSSVRFUl9BUElfS0VZIGhlcmUuIn19) +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6IlNldCB5b3VyIFdSSVRFUl9BUElfS0VZIGhlcmUuIn19) ## Exposing endpoints to your MCP Client -There are two ways to expose endpoints as tools in the MCP server: +There are three ways to expose endpoints as tools in the MCP server: 1. Exposing one tool per endpoint, and filtering as necessary 2. Exposing a set of tools to dynamically discover and invoke endpoints from the API +3. Exposing a docs search tool and a code execution tool, allowing the client to write code to be executed against the TypeScript client ### Filtering endpoints and tools @@ -81,6 +82,18 @@ All of these command-line options can be repeated, combined together, and have c Use `--list` to see the list of available tools, or see below. +### Code execution + +If you specify `--tools=code` to the MCP server, it will expose just two tools: + +- `search_docs` - Searches the API documentation and returns a list of markdown results +- `execute` - Runs code against the TypeScript client + +This allows the LLM to implement more complex logic by chaining together many API calls without loading +intermediary results into its context window. + +The code execution itself happens in a Deno sandbox that has network access only to the base URL for the API. + ### Specifying the MCP Client Different clients have varying abilities to handle arbitrary tools and schemas. From bb1991af52bb810f9b69ec7d9d761d8b79aa6b15 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 20:43:20 +0000 Subject: [PATCH 15/26] docs(mcp): add a README link to add server to VS Code or Claude Code --- packages/mcp-server/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index 5b4edcd5..b16d302a 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -41,6 +41,22 @@ in Cursor's `mcp.json`, which can be found in Cursor Settings > Tools & MCP > Ne [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=writer-sdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIndyaXRlci1zZGstbWNwIl0sImVudiI6eyJXUklURVJfQVBJX0tFWSI6IlNldCB5b3VyIFdSSVRFUl9BUElfS0VZIGhlcmUuIn19) +### VS Code + +If you use MCP, you can install the MCP server by clicking the link below. You will need to set your environment variables +in VS Code's `mcp.json`, which can be found via Command Palette > MCP: Open User Configuration. + +[Open VS Code](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22writer-sdk-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22writer-sdk-mcp%22%5D%2C%22env%22%3A%7B%22WRITER_API_KEY%22%3A%22Set%20your%20WRITER_API_KEY%20here.%22%7D%7D) + +### Claude Code + +If you use Claude Code, you can install the MCP server by running the command below in your terminal. You will need to set your +environment variables in Claude Code's `.claude.json`, which can be found in your home directory. + +``` +claude mcp add --transport stdio writer_sdk_api --env WRITER_API_KEY="Your WRITER_API_KEY here." -- npx -y writer-sdk-mcp +``` + ## Exposing endpoints to your MCP Client There are three ways to expose endpoints as tools in the MCP server: From 35b1a8fd3128b36cb3a99025547b3484e57ae318 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 7 Nov 2025 21:07:51 +0000 Subject: [PATCH 16/26] chore(internal): codegen related update --- packages/mcp-server/src/code-tool.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mcp-server/src/code-tool.ts b/packages/mcp-server/src/code-tool.ts index ecd7da9b..d7cd783d 100644 --- a/packages/mcp-server/src/code-tool.ts +++ b/packages/mcp-server/src/code-tool.ts @@ -23,7 +23,7 @@ export async function codeTool(): Promise { const tool: Tool = { name: 'execute', description: - 'Runs TypeScript code to interact with the API.\n\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 named "client", and it will be run.\nWrite code within this template:\n\n```\nasync function run(client) {\n // Fill this out\n}\n```\n\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 JavaScript code to interact with the API.\n\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 named "client", and it will be run.\nWrite code within this template:\n\n```\nasync function run(client) {\n // Fill this out\n}\n```\n\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' } } }, }; From bd123e075e8bd0b179f95d8f8513a53414f86ac6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 16:19:48 +0000 Subject: [PATCH 17/26] chore(mcp): clarify http auth error --- packages/mcp-server/src/headers.ts | 4 +++- packages/mcp-server/src/http.ts | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/mcp-server/src/headers.ts b/packages/mcp-server/src/headers.ts index db114003..555715b7 100644 --- a/packages/mcp-server/src/headers.ts +++ b/packages/mcp-server/src/headers.ts @@ -11,7 +11,9 @@ export const parseAuthHeaders = (req: IncomingMessage): Partial = case 'Bearer': return { apiKey: req.headers.authorization.slice('Bearer '.length) }; default: - throw new Error(`Unsupported authorization scheme`); + throw new Error( + 'Unsupported authorization scheme. Expected the "Authorization" header to be a supported scheme (Bearer).', + ); } } diff --git a/packages/mcp-server/src/http.ts b/packages/mcp-server/src/http.ts index ec34ab47..84517003 100644 --- a/packages/mcp-server/src/http.ts +++ b/packages/mcp-server/src/http.ts @@ -46,12 +46,12 @@ const newServer = ({ }, mcpOptions, }); - } catch { + } catch (error) { res.status(401).json({ jsonrpc: '2.0', error: { code: -32000, - message: 'Unauthorized', + message: `Unauthorized: ${error instanceof Error ? error.message : error}`, }, }); return null; From 95aa71460549717420896fd47fcebbd603739743 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 18:51:31 +0000 Subject: [PATCH 18/26] feat(api): Improve MCP tool descriptions --- .stats.yml | 2 +- packages/mcp-server/README.md | 24 +++++++++---------- .../generate-content-applications.ts | 2 +- .../tools/applications/list-applications.ts | 2 +- .../mcp-server/src/tools/chat/chat-chat.ts | 2 +- .../tools/completions/create-completions.ts | 2 +- .../mcp-server/src/tools/files/list-files.ts | 2 +- .../src/tools/files/retrieve-files.ts | 2 +- .../src/tools/files/upload-files.ts | 2 +- .../tools/graphs/add-file-to-graph-graphs.ts | 2 +- .../src/tools/graphs/create-graphs.ts | 2 +- .../src/tools/graphs/list-graphs.ts | 2 +- .../src/tools/graphs/question-graphs.ts | 3 ++- .../src/tools/graphs/retrieve-graphs.ts | 2 +- 14 files changed, 26 insertions(+), 25 deletions(-) diff --git a/.stats.yml b/.stats.yml index b3d54722..9ff96150 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 33 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/writerai%2Fwriter-4ec783072dd7f57c6e021a746df7650fb8d7a164d8ec25c7d5cab06c33bc114f.yml openapi_spec_hash: ceab065d515f3681b0c33137da308968 -config_hash: 089fd5502b9cf91247887b19117f1ca2 +config_hash: 886645f89dc98f04b8931eaf02854e5f diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index b16d302a..ce6ef16f 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -243,8 +243,8 @@ The following tools are available in this MCP server. ### Resource `applications`: - `retrieve_applications` (`read`): Retrieves detailed information for a specific no-code agent (formerly called no-code applications), including its configuration and current status. -- `list_applications` (`read`): Retrieves a paginated list of no-code agents (formerly called no-code applications) with optional filtering and sorting capabilities. -- `generate_content_applications` (`write`): Generate content from an existing no-code agent (formerly called no-code applications) with inputs. +- `list_applications` (`read`): Get all available no-code agents (applications) in your account. No-code agents are pre-configured AI workflows built in Writer's AI Studio. Use this to discover which agents are available before generating content from them. +- `generate_content_applications` (`write`): Generate content using a pre-configured no-code agent. No-code agents are custom AI workflows you've built in AI Studio with specific prompts, models, and settings. Provide the application ID and required inputs to get tailored content. Useful for consistent, repeatable AI tasks like content generation, data extraction, or custom workflows. ### Resource `applications.jobs`: @@ -260,11 +260,11 @@ The following tools are available in this MCP server. ### Resource `chat`: -- `chat_chat` (`write`): Generate a chat completion based on the provided messages. The response shown below is for non-streaming. To learn about streaming responses, see the [chat completion guide](https://dev.writer.com/home/chat-completion). +- `chat_chat` (`write`): Generate AI responses for conversational interactions. Use this for chat-based tasks, Q&A, content generation, and any natural language processing. Supports tools like Knowledge Graphs, web search, translation, and vision. Choose from models like palmyra-x5, palmyra-x4, palmyra-creative, palmyra-med, or palmyra-fin depending on the task. ### Resource `completions`: -- `create_completions` (`write`): Generate text completions using the specified model and prompt. This endpoint is useful for text generation tasks that don't require conversational context. +- `create_completions` (`write`): Generate text completions from a single prompt without conversational context. Best for straightforward text generation tasks like article writing, summaries, or creative content. For interactive conversations or multi-turn dialogues, use generate-chat-completion instead. ### Resource `models`: @@ -272,23 +272,23 @@ The following tools are available in this MCP server. ### Resource `graphs`: -- `create_graphs` (`write`): Create a new Knowledge Graph. -- `retrieve_graphs` (`read`): Retrieve a Knowledge Graph. +- `create_graphs` (`write`): Create a new Knowledge Graph to organize and query documents. Knowledge Graphs are containers for files that enable AI-powered search and question answering. After creation, add files to the graph using add-file-to-graph, then query it using query-knowledge-graph. +- `retrieve_graphs` (`read`): Get detailed information about a specific Knowledge Graph by its ID. Returns the graph name, description, creation date, file processing status, and associated URLs (for web-based graphs). Use this to check processing status or get graph metadata. - `update_graphs` (`write`): Update the name and description of a Knowledge Graph. -- `list_graphs` (`read`): Retrieve a list of Knowledge Graphs. +- `list_graphs` (`read`): Get all available Knowledge Graphs in your account. Knowledge Graphs are collections of documents and files that can be queried using AI. Use this to discover which knowledge bases are available before querying them. - `delete_graphs` (`write`): Delete a Knowledge Graph. -- `add_file_to_graph_graphs` (`write`): Add a file to a Knowledge Graph. -- `question_graphs` (`write`): Ask a question to specified Knowledge Graphs. +- `add_file_to_graph_graphs` (`write`): Add an uploaded file to a Knowledge Graph to make it queryable. The file must already be uploaded using upload-file. Once added, the file's content becomes searchable when querying the Knowledge Graph. Files are processed asynchronously - check status using get-file-info. +- `question_graphs` (`write`): Ask questions and get AI-generated answers based on your Knowledge Graph content. Queries your uploaded documents, PDFs, and files to retrieve accurate, source-cited information. Returns answers with supporting snippets and file references. Ideal for RAG (Retrieval-Augmented Generation) applications and knowledge base queries. - `remove_file_from_graph_graphs` (`write`): Remove a file from a Knowledge Graph. ### Resource `files`: -- `retrieve_files` (`read`): Retrieve detailed information about a specific file, including its metadata, status, and associated graphs. -- `list_files` (`read`): Retrieve a paginated list of files with optional filtering by status, graph association, and file type. +- `retrieve_files` (`read`): Get metadata and status information for a specific file by its ID. Returns file name, creation date, processing status, and associated Knowledge Graph IDs. Use this to check if a file has finished processing or to find which Knowledge Graphs contain a specific file. +- `list_files` (`read`): Get a paginated list of all uploaded files. Filter by processing status (in_progress, completed, failed), Knowledge Graph association, or file type. Use this to discover available files, monitor processing status, or find files to add to Knowledge Graphs. - `delete_files` (`write`): Permanently delete a file from the system. This action cannot be undone. - `download_files` (`read`): Download the binary content of a file. The response will contain the file data in the appropriate MIME type. - `retry_files` (`write`): Retry processing of files that previously failed to process. This will re-attempt the processing of the specified files. -- `upload_files` (`write`): Upload a new file to the system. Supports various file formats including PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, and XLSX. +- `upload_files` (`write`): Upload documents and files to Writer. Supports PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, XLSX, MP3, and MP4 formats. Once uploaded, files can be added to Knowledge Graphs for querying or used with Vision API for image analysis. Returns a file ID for subsequent operations. ### Resource `tools`: diff --git a/packages/mcp-server/src/tools/applications/generate-content-applications.ts b/packages/mcp-server/src/tools/applications/generate-content-applications.ts index 96d103bc..6b9b5b70 100644 --- a/packages/mcp-server/src/tools/applications/generate-content-applications.ts +++ b/packages/mcp-server/src/tools/applications/generate-content-applications.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'generate_content_applications', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGenerate content from an existing no-code agent (formerly called no-code applications) with inputs.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/application_generate_content_response',\n $defs: {\n application_generate_content_response: {\n type: 'object',\n title: 'generate_application_response',\n properties: {\n suggestion: {\n type: 'string',\n description: 'The response from the model specified in the application.'\n },\n title: {\n type: 'string',\n description: 'The name of the output field.'\n }\n },\n required: [ 'suggestion'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGenerate content using a pre-configured no-code agent. No-code agents are custom AI workflows you've built in AI Studio with specific prompts, models, and settings. Provide the application ID and required inputs to get tailored content. Useful for consistent, repeatable AI tasks like content generation, data extraction, or custom workflows.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/application_generate_content_response',\n $defs: {\n application_generate_content_response: {\n type: 'object',\n title: 'generate_application_response',\n properties: {\n suggestion: {\n type: 'string',\n description: 'The response from the model specified in the application.'\n },\n title: {\n type: 'string',\n description: 'The name of the output field.'\n }\n },\n required: [ 'suggestion'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', anyOf: [ diff --git a/packages/mcp-server/src/tools/applications/list-applications.ts b/packages/mcp-server/src/tools/applications/list-applications.ts index a42bad58..402063ef 100644 --- a/packages/mcp-server/src/tools/applications/list-applications.ts +++ b/packages/mcp-server/src/tools/applications/list-applications.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'list_applications', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieves a paginated list of no-code agents (formerly called no-code applications) with optional filtering and sorting capabilities.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'get_applications_response',\n description: 'Response object containing a paginated list of applications.',\n properties: {\n data: {\n type: 'array',\n description: 'List of application objects with their configurations.',\n items: {\n $ref: '#/$defs/application_list_response'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more results available in subsequent pages.'\n },\n first_id: {\n type: 'string',\n description: 'UUID of the first application in the current page.'\n },\n last_id: {\n type: 'string',\n description: 'UUID of the last application in the current page.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n application_list_response: {\n type: 'object',\n title: 'application_with_inputs',\n description: 'Detailed application object including its input configuration.',\n properties: {\n id: {\n type: 'string',\n description: 'Unique identifier for the application.'\n },\n created_at: {\n type: 'string',\n description: 'Timestamp when the application was created.',\n format: 'date-time'\n },\n inputs: {\n type: 'array',\n description: 'List of input configurations for the application.',\n items: {\n type: 'object',\n title: 'application_input',\n description: 'Configuration for an individual input field in the application.',\n properties: {\n input_type: {\n type: 'string',\n title: 'application_input_type',\n description: 'Type of input field determining its behavior and validation rules.',\n enum: [ 'text',\n 'dropdown',\n 'file',\n 'media'\n ]\n },\n name: {\n type: 'string',\n description: 'Identifier for the input field.'\n },\n required: {\n type: 'boolean',\n description: 'Indicates if this input field is mandatory.'\n },\n description: {\n type: 'string',\n description: 'Human-readable description of the input field\\'s purpose.'\n },\n options: {\n anyOf: [ {\n type: 'object',\n title: 'Dropdown',\n description: 'Configuration options specific to dropdown-type input fields.',\n properties: {\n list: {\n type: 'array',\n description: 'List of available options in the dropdown menu.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'list'\n ]\n },\n {\n type: 'object',\n title: 'File',\n description: 'Configuration options specific to file upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed file extensions.',\n items: {\n type: 'string'\n }\n },\n max_file_size_mb: {\n type: 'integer',\n description: 'Maximum file size allowed in megabytes.'\n },\n max_files: {\n type: 'integer',\n description: 'Maximum number of files that can be uploaded.'\n },\n max_word_count: {\n type: 'integer',\n description: 'Maximum number of words allowed in text files.'\n },\n upload_types: {\n type: 'array',\n description: 'List of allowed upload types for file inputs.',\n items: {\n type: 'string',\n title: 'file_upload_type',\n description: 'Type of file upload method supported by the application.',\n enum: [ 'url',\n 'file_id'\n ]\n }\n }\n },\n required: [ 'file_types',\n 'max_file_size_mb',\n 'max_files',\n 'max_word_count',\n 'upload_types'\n ]\n },\n {\n type: 'object',\n title: 'Media',\n description: 'Configuration options specific to media upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed media file types.',\n items: {\n type: 'string'\n }\n },\n max_image_size_mb: {\n type: 'integer',\n description: 'Maximum media file size allowed in megabytes.'\n }\n },\n required: [ 'file_types',\n 'max_image_size_mb'\n ]\n },\n {\n type: 'object',\n title: 'Text',\n description: 'Configuration options specific to text input fields.',\n properties: {\n max_fields: {\n type: 'integer',\n description: 'Maximum number of text fields allowed.'\n },\n min_fields: {\n type: 'integer',\n description: 'Minimum number of text fields required.'\n }\n },\n required: [ 'max_fields',\n 'min_fields'\n ]\n }\n ],\n description: 'Type-specific configuration options for input fields.'\n }\n },\n required: [ 'input_type',\n 'name',\n 'required'\n ]\n }\n },\n name: {\n type: 'string',\n description: 'Display name of the application.'\n },\n status: {\n type: 'string',\n title: 'application_status',\n description: 'Current deployment status of the application. Note: currently only `deployed` applications are returned.',\n enum: [ 'deployed',\n 'draft'\n ]\n },\n type: {\n type: 'string',\n title: 'application_type',\n description: 'The type of no-code application.',\n enum: [ 'generation'\n ]\n },\n updated_at: {\n type: 'string',\n description: 'Timestamp when the application was last updated.',\n format: 'date-time'\n },\n last_deployed_at: {\n type: 'string',\n description: 'Timestamp when the application was last deployed.',\n format: 'date-time'\n }\n },\n required: [ 'id',\n 'created_at',\n 'inputs',\n 'name',\n 'status',\n 'type',\n 'updated_at'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet all available no-code agents (applications) in your account. No-code agents are pre-configured AI workflows built in Writer's AI Studio. Use this to discover which agents are available before generating content from them.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'get_applications_response',\n description: 'Response object containing a paginated list of applications.',\n properties: {\n data: {\n type: 'array',\n description: 'List of application objects with their configurations.',\n items: {\n $ref: '#/$defs/application_list_response'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more results available in subsequent pages.'\n },\n first_id: {\n type: 'string',\n description: 'UUID of the first application in the current page.'\n },\n last_id: {\n type: 'string',\n description: 'UUID of the last application in the current page.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n application_list_response: {\n type: 'object',\n title: 'application_with_inputs',\n description: 'Detailed application object including its input configuration.',\n properties: {\n id: {\n type: 'string',\n description: 'Unique identifier for the application.'\n },\n created_at: {\n type: 'string',\n description: 'Timestamp when the application was created.',\n format: 'date-time'\n },\n inputs: {\n type: 'array',\n description: 'List of input configurations for the application.',\n items: {\n type: 'object',\n title: 'application_input',\n description: 'Configuration for an individual input field in the application.',\n properties: {\n input_type: {\n type: 'string',\n title: 'application_input_type',\n description: 'Type of input field determining its behavior and validation rules.',\n enum: [ 'text',\n 'dropdown',\n 'file',\n 'media'\n ]\n },\n name: {\n type: 'string',\n description: 'Identifier for the input field.'\n },\n required: {\n type: 'boolean',\n description: 'Indicates if this input field is mandatory.'\n },\n description: {\n type: 'string',\n description: 'Human-readable description of the input field\\'s purpose.'\n },\n options: {\n anyOf: [ {\n type: 'object',\n title: 'Dropdown',\n description: 'Configuration options specific to dropdown-type input fields.',\n properties: {\n list: {\n type: 'array',\n description: 'List of available options in the dropdown menu.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'list'\n ]\n },\n {\n type: 'object',\n title: 'File',\n description: 'Configuration options specific to file upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed file extensions.',\n items: {\n type: 'string'\n }\n },\n max_file_size_mb: {\n type: 'integer',\n description: 'Maximum file size allowed in megabytes.'\n },\n max_files: {\n type: 'integer',\n description: 'Maximum number of files that can be uploaded.'\n },\n max_word_count: {\n type: 'integer',\n description: 'Maximum number of words allowed in text files.'\n },\n upload_types: {\n type: 'array',\n description: 'List of allowed upload types for file inputs.',\n items: {\n type: 'string',\n title: 'file_upload_type',\n description: 'Type of file upload method supported by the application.',\n enum: [ 'url',\n 'file_id'\n ]\n }\n }\n },\n required: [ 'file_types',\n 'max_file_size_mb',\n 'max_files',\n 'max_word_count',\n 'upload_types'\n ]\n },\n {\n type: 'object',\n title: 'Media',\n description: 'Configuration options specific to media upload input fields.',\n properties: {\n file_types: {\n type: 'array',\n description: 'List of allowed media file types.',\n items: {\n type: 'string'\n }\n },\n max_image_size_mb: {\n type: 'integer',\n description: 'Maximum media file size allowed in megabytes.'\n }\n },\n required: [ 'file_types',\n 'max_image_size_mb'\n ]\n },\n {\n type: 'object',\n title: 'Text',\n description: 'Configuration options specific to text input fields.',\n properties: {\n max_fields: {\n type: 'integer',\n description: 'Maximum number of text fields allowed.'\n },\n min_fields: {\n type: 'integer',\n description: 'Minimum number of text fields required.'\n }\n },\n required: [ 'max_fields',\n 'min_fields'\n ]\n }\n ],\n description: 'Type-specific configuration options for input fields.'\n }\n },\n required: [ 'input_type',\n 'name',\n 'required'\n ]\n }\n },\n name: {\n type: 'string',\n description: 'Display name of the application.'\n },\n status: {\n type: 'string',\n title: 'application_status',\n description: 'Current deployment status of the application. Note: currently only `deployed` applications are returned.',\n enum: [ 'deployed',\n 'draft'\n ]\n },\n type: {\n type: 'string',\n title: 'application_type',\n description: 'The type of no-code application.',\n enum: [ 'generation'\n ]\n },\n updated_at: {\n type: 'string',\n description: 'Timestamp when the application was last updated.',\n format: 'date-time'\n },\n last_deployed_at: {\n type: 'string',\n description: 'Timestamp when the application was last deployed.',\n format: 'date-time'\n }\n },\n required: [ 'id',\n 'created_at',\n 'inputs',\n 'name',\n 'status',\n 'type',\n 'updated_at'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/chat/chat-chat.ts b/packages/mcp-server/src/tools/chat/chat-chat.ts index a89af792..9f460d75 100644 --- a/packages/mcp-server/src/tools/chat/chat-chat.ts +++ b/packages/mcp-server/src/tools/chat/chat-chat.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'chat_chat', description: - 'Generate a chat completion based on the provided messages. The response shown below is for non-streaming. To learn about streaming responses, see the [chat completion guide](https://dev.writer.com/home/chat-completion).', + 'Generate AI responses for conversational interactions. Use this for chat-based tasks, Q&A, content generation, and any natural language processing. Supports tools like Knowledge Graphs, web search, translation, and vision. Choose from models like palmyra-x5, palmyra-x4, palmyra-creative, palmyra-med, or palmyra-fin depending on the task.', inputSchema: { type: 'object', anyOf: [ diff --git a/packages/mcp-server/src/tools/completions/create-completions.ts b/packages/mcp-server/src/tools/completions/create-completions.ts index 6b9085d2..c1593d85 100644 --- a/packages/mcp-server/src/tools/completions/create-completions.ts +++ b/packages/mcp-server/src/tools/completions/create-completions.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'create_completions', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGenerate text completions using the specified model and prompt. This endpoint is useful for text generation tasks that don't require conversational context.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/completion',\n $defs: {\n completion: {\n type: 'object',\n properties: {\n choices: {\n type: 'array',\n description: 'A list of choices generated by the model, each containing the text of the completion and associated metadata such as log probabilities.',\n items: {\n type: 'object',\n properties: {\n text: {\n type: 'string',\n description: 'The generated text output from the model, which forms the main content of the response.'\n },\n log_probs: {\n $ref: '#/$defs/logprobs'\n }\n },\n required: [ 'text'\n ]\n }\n },\n model: {\n type: 'string',\n description: 'The identifier of the model that was used to generate the responses in the \\'choices\\' array.'\n }\n },\n required: [ 'choices'\n ]\n },\n logprobs: {\n type: 'object',\n properties: {\n content: {\n type: 'array',\n items: {\n $ref: '#/$defs/logprobs_token'\n }\n },\n refusal: {\n type: 'array',\n items: {\n $ref: '#/$defs/logprobs_token'\n }\n }\n },\n required: [ 'content',\n 'refusal'\n ]\n },\n logprobs_token: {\n type: 'object',\n title: 'logprobs_token',\n properties: {\n token: {\n type: 'string'\n },\n logprob: {\n type: 'number'\n },\n top_logprobs: {\n type: 'array',\n items: {\n type: 'object',\n title: 'top_log_prob',\n description: 'An array of mappings for each token to its top log probabilities, showing detailed prediction probabilities.',\n properties: {\n token: {\n type: 'string'\n },\n logprob: {\n type: 'number'\n },\n bytes: {\n type: 'array',\n items: {\n type: 'integer'\n }\n }\n },\n required: [ 'token',\n 'logprob'\n ]\n }\n },\n bytes: {\n type: 'array',\n items: {\n type: 'integer'\n }\n }\n },\n required: [ 'token',\n 'logprob',\n 'top_logprobs'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGenerate text completions from a single prompt without conversational context. Best for straightforward text generation tasks like article writing, summaries, or creative content. For interactive conversations or multi-turn dialogues, use generate-chat-completion instead.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/completion',\n $defs: {\n completion: {\n type: 'object',\n properties: {\n choices: {\n type: 'array',\n description: 'A list of choices generated by the model, each containing the text of the completion and associated metadata such as log probabilities.',\n items: {\n type: 'object',\n properties: {\n text: {\n type: 'string',\n description: 'The generated text output from the model, which forms the main content of the response.'\n },\n log_probs: {\n $ref: '#/$defs/logprobs'\n }\n },\n required: [ 'text'\n ]\n }\n },\n model: {\n type: 'string',\n description: 'The identifier of the model that was used to generate the responses in the \\'choices\\' array.'\n }\n },\n required: [ 'choices'\n ]\n },\n logprobs: {\n type: 'object',\n properties: {\n content: {\n type: 'array',\n items: {\n $ref: '#/$defs/logprobs_token'\n }\n },\n refusal: {\n type: 'array',\n items: {\n $ref: '#/$defs/logprobs_token'\n }\n }\n },\n required: [ 'content',\n 'refusal'\n ]\n },\n logprobs_token: {\n type: 'object',\n title: 'logprobs_token',\n properties: {\n token: {\n type: 'string'\n },\n logprob: {\n type: 'number'\n },\n top_logprobs: {\n type: 'array',\n items: {\n type: 'object',\n title: 'top_log_prob',\n description: 'An array of mappings for each token to its top log probabilities, showing detailed prediction probabilities.',\n properties: {\n token: {\n type: 'string'\n },\n logprob: {\n type: 'number'\n },\n bytes: {\n type: 'array',\n items: {\n type: 'integer'\n }\n }\n },\n required: [ 'token',\n 'logprob'\n ]\n }\n },\n bytes: {\n type: 'array',\n items: {\n type: 'integer'\n }\n }\n },\n required: [ 'token',\n 'logprob',\n 'top_logprobs'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', anyOf: [ diff --git a/packages/mcp-server/src/tools/files/list-files.ts b/packages/mcp-server/src/tools/files/list-files.ts index ffd1593d..ee94d844 100644 --- a/packages/mcp-server/src/tools/files/list-files.ts +++ b/packages/mcp-server/src/tools/files/list-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'list_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieve a paginated list of files with optional filtering by status, graph association, and file type.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'files_response',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: '#/$defs/file'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more files available beyond the current page.'\n },\n first_id: {\n type: 'string',\n description: 'The ID of the first file in the current response.'\n },\n last_id: {\n type: 'string',\n description: 'The ID of the last file in the current response.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet a paginated list of all uploaded files. Filter by processing status (in_progress, completed, failed), Knowledge Graph association, or file type. Use this to discover available files, monitor processing status, or find files to add to Knowledge Graphs.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'files_response',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: '#/$defs/file'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more files available beyond the current page.'\n },\n first_id: {\n type: 'string',\n description: 'The ID of the first file in the current response.'\n },\n last_id: {\n type: 'string',\n description: 'The ID of the last file in the current response.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/files/retrieve-files.ts b/packages/mcp-server/src/tools/files/retrieve-files.ts index 2dbd0e6b..e9a55d10 100644 --- a/packages/mcp-server/src/tools/files/retrieve-files.ts +++ b/packages/mcp-server/src/tools/files/retrieve-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'retrieve_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieve detailed information about a specific file, including its metadata, status, and associated graphs.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet metadata and status information for a specific file by its ID. Returns file name, creation date, processing status, and associated Knowledge Graph IDs. Use this to check if a file has finished processing or to find which Knowledge Graphs contain a specific file.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/files/upload-files.ts b/packages/mcp-server/src/tools/files/upload-files.ts index ae6ffc33..7babd137 100644 --- a/packages/mcp-server/src/tools/files/upload-files.ts +++ b/packages/mcp-server/src/tools/files/upload-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'upload_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nUpload a new file to the system. Supports various file formats including PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, and XLSX.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nUpload documents and files to Writer. Supports PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, XLSX, MP3, and MP4 formats. Once uploaded, files can be added to Knowledge Graphs for querying or used with Vision API for image analysis. Returns a file ID for subsequent operations.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts b/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts index daf1d456..98601626 100644 --- a/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'add_file_to_graph_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nAdd a file to a Knowledge Graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nAdd an uploaded file to a Knowledge Graph to make it queryable. The file must already be uploaded using upload-file. Once added, the file's content becomes searchable when querying the Knowledge Graph. Files are processed asynchronously - check status using get-file-info.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/create-graphs.ts b/packages/mcp-server/src/tools/graphs/create-graphs.ts index b68a196d..63706f7c 100644 --- a/packages/mcp-server/src/tools/graphs/create-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/create-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'create_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nCreate a new Knowledge Graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph_create_response',\n $defs: {\n graph_create_response: {\n type: 'object',\n title: 'graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph (max 255 characters).'\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph (max 255 characters).'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'name'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nCreate a new Knowledge Graph to organize and query documents. Knowledge Graphs are containers for files that enable AI-powered search and question answering. After creation, add files to the graph using add-file-to-graph, then query it using query-knowledge-graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph_create_response',\n $defs: {\n graph_create_response: {\n type: 'object',\n title: 'graph_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph (max 255 characters).'\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph (max 255 characters).'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'name'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/list-graphs.ts b/packages/mcp-server/src/tools/graphs/list-graphs.ts index e4db238f..98dd37e9 100644 --- a/packages/mcp-server/src/tools/graphs/list-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/list-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'list_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieve a list of Knowledge Graphs.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'graphs_response',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: '#/$defs/graph'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more Knowledge Graphs available beyond the current page.'\n },\n first_id: {\n type: 'string',\n description: 'The ID of the first Knowledge Graph in the current response.'\n },\n last_id: {\n type: 'string',\n description: 'The ID of the last Knowledge Graph in the current response.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n graph: {\n type: 'object',\n title: 'graph',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n file_status: {\n type: 'object',\n title: 'graph_file_status',\n description: 'The processing status of files in the Knowledge Graph.',\n properties: {\n completed: {\n type: 'integer',\n description: 'The number of files that have been successfully processed.'\n },\n failed: {\n type: 'integer',\n description: 'The number of files that failed to process.'\n },\n in_progress: {\n type: 'integer',\n description: 'The number of files currently being processed.'\n },\n total: {\n type: 'integer',\n description: 'The total number of files associated with the Knowledge Graph.'\n }\n },\n required: [ 'completed',\n 'failed',\n 'in_progress',\n 'total'\n ]\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph.'\n },\n type: {\n type: 'string',\n title: 'graph_type',\n description: 'The type of Knowledge Graph.\\n\\n- `manual`: files are uploaded via UI or API\\n- `connector`: files are uploaded via a data connector such as Google Drive or Confluence\\n- `web`: URLs are connected to the Knowledge Graph',\n enum: [ 'manual',\n 'connector',\n 'web'\n ]\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph.'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'file_status',\n 'name',\n 'type'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet all available Knowledge Graphs in your account. Knowledge Graphs are collections of documents and files that can be queried using AI. Use this to discover which knowledge bases are available before querying them.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'graphs_response',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: '#/$defs/graph'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more Knowledge Graphs available beyond the current page.'\n },\n first_id: {\n type: 'string',\n description: 'The ID of the first Knowledge Graph in the current response.'\n },\n last_id: {\n type: 'string',\n description: 'The ID of the last Knowledge Graph in the current response.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n graph: {\n type: 'object',\n title: 'graph',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n file_status: {\n type: 'object',\n title: 'graph_file_status',\n description: 'The processing status of files in the Knowledge Graph.',\n properties: {\n completed: {\n type: 'integer',\n description: 'The number of files that have been successfully processed.'\n },\n failed: {\n type: 'integer',\n description: 'The number of files that failed to process.'\n },\n in_progress: {\n type: 'integer',\n description: 'The number of files currently being processed.'\n },\n total: {\n type: 'integer',\n description: 'The total number of files associated with the Knowledge Graph.'\n }\n },\n required: [ 'completed',\n 'failed',\n 'in_progress',\n 'total'\n ]\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph.'\n },\n type: {\n type: 'string',\n title: 'graph_type',\n description: 'The type of Knowledge Graph.\\n\\n- `manual`: files are uploaded via UI or API\\n- `connector`: files are uploaded via a data connector such as Google Drive or Confluence\\n- `web`: URLs are connected to the Knowledge Graph',\n enum: [ 'manual',\n 'connector',\n 'web'\n ]\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph.'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'file_status',\n 'name',\n 'type'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/graphs/question-graphs.ts b/packages/mcp-server/src/tools/graphs/question-graphs.ts index b73facf1..b8b11c61 100644 --- a/packages/mcp-server/src/tools/graphs/question-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/question-graphs.ts @@ -16,7 +16,8 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'question_graphs', - description: 'Ask a question to specified Knowledge Graphs.', + description: + 'Ask questions and get AI-generated answers based on your Knowledge Graph content. Queries your uploaded documents, PDFs, and files to retrieve accurate, source-cited information. Returns answers with supporting snippets and file references. Ideal for RAG (Retrieval-Augmented Generation) applications and knowledge base queries.', inputSchema: { type: 'object', anyOf: [ diff --git a/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts b/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts index b38ee70d..4ed07bd7 100644 --- a/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'retrieve_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nRetrieve a Knowledge Graph.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph',\n $defs: {\n graph: {\n type: 'object',\n title: 'graph',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n file_status: {\n type: 'object',\n title: 'graph_file_status',\n description: 'The processing status of files in the Knowledge Graph.',\n properties: {\n completed: {\n type: 'integer',\n description: 'The number of files that have been successfully processed.'\n },\n failed: {\n type: 'integer',\n description: 'The number of files that failed to process.'\n },\n in_progress: {\n type: 'integer',\n description: 'The number of files currently being processed.'\n },\n total: {\n type: 'integer',\n description: 'The total number of files associated with the Knowledge Graph.'\n }\n },\n required: [ 'completed',\n 'failed',\n 'in_progress',\n 'total'\n ]\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph.'\n },\n type: {\n type: 'string',\n title: 'graph_type',\n description: 'The type of Knowledge Graph.\\n\\n- `manual`: files are uploaded via UI or API\\n- `connector`: files are uploaded via a data connector such as Google Drive or Confluence\\n- `web`: URLs are connected to the Knowledge Graph',\n enum: [ 'manual',\n 'connector',\n 'web'\n ]\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph.'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'file_status',\n 'name',\n 'type'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet detailed information about a specific Knowledge Graph by its ID. Returns the graph name, description, creation date, file processing status, and associated URLs (for web-based graphs). Use this to check processing status or get graph metadata.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/graph',\n $defs: {\n graph: {\n type: 'object',\n title: 'graph',\n properties: {\n id: {\n type: 'string',\n description: 'The unique identifier of the Knowledge Graph.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the Knowledge Graph was created.',\n format: 'date-time'\n },\n file_status: {\n type: 'object',\n title: 'graph_file_status',\n description: 'The processing status of files in the Knowledge Graph.',\n properties: {\n completed: {\n type: 'integer',\n description: 'The number of files that have been successfully processed.'\n },\n failed: {\n type: 'integer',\n description: 'The number of files that failed to process.'\n },\n in_progress: {\n type: 'integer',\n description: 'The number of files currently being processed.'\n },\n total: {\n type: 'integer',\n description: 'The total number of files associated with the Knowledge Graph.'\n }\n },\n required: [ 'completed',\n 'failed',\n 'in_progress',\n 'total'\n ]\n },\n name: {\n type: 'string',\n description: 'The name of the Knowledge Graph.'\n },\n type: {\n type: 'string',\n title: 'graph_type',\n description: 'The type of Knowledge Graph.\\n\\n- `manual`: files are uploaded via UI or API\\n- `connector`: files are uploaded via a data connector such as Google Drive or Confluence\\n- `web`: URLs are connected to the Knowledge Graph',\n enum: [ 'manual',\n 'connector',\n 'web'\n ]\n },\n description: {\n type: 'string',\n description: 'A description of the Knowledge Graph.'\n },\n urls: {\n type: 'array',\n description: 'An array of web connector URLs associated with this Knowledge Graph.',\n items: {\n type: 'object',\n title: 'web_connector_url',\n properties: {\n status: {\n type: 'object',\n title: 'web_connector_url_state',\n description: 'The current status of the URL processing.',\n properties: {\n status: {\n type: 'string',\n title: 'web_connector_url_status',\n description: 'The current status of the URL processing.',\n enum: [ 'validating',\n 'success',\n 'error'\n ]\n },\n error_type: {\n type: 'string',\n title: 'web_connector_url_error_type',\n description: 'The type of error that occurred during processing, if any.',\n enum: [ 'invalid_url',\n 'not_searchable',\n 'not_found',\n 'paywall_or_login_page',\n 'unexpected_error'\n ]\n }\n },\n required: [ 'status'\n ]\n },\n type: {\n type: 'string',\n title: 'web_connector_url_type',\n description: 'The type of web connector processing for this URL.',\n enum: [ 'single_page',\n 'sub_pages'\n ]\n },\n url: {\n type: 'string',\n description: 'The URL to be processed by the web connector.'\n },\n exclude_urls: {\n type: 'array',\n description: 'An array of URLs to exclude from processing within this web connector.',\n items: {\n type: 'string'\n }\n }\n },\n required: [ 'status',\n 'type',\n 'url'\n ]\n }\n }\n },\n required: [ 'id',\n 'created_at',\n 'file_status',\n 'name',\n 'type'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { From 54da4f964cae97a224763a29e851c4c63273953e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 19:05:33 +0000 Subject: [PATCH 19/26] fix(mcp): use raw responses for binary content --- packages/mcp-server/src/tools/files/download-files.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mcp-server/src/tools/files/download-files.ts b/packages/mcp-server/src/tools/files/download-files.ts index cf220c23..0afb4831 100644 --- a/packages/mcp-server/src/tools/files/download-files.ts +++ b/packages/mcp-server/src/tools/files/download-files.ts @@ -34,7 +34,7 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { file_id, ...body } = args as any; - return asBinaryContentResult(await client.files.download(file_id)); + return asBinaryContentResult(await client.files.download(file_id).asResponse()); }; export default { metadata, tool, handler }; From f833b8ffb35c9921f66939cafab7ddc1a6948096 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 19:07:57 +0000 Subject: [PATCH 20/26] fix(mcp): return tool execution error on jq failure --- packages/mcp-server/src/filtering.ts | 4 ++++ .../generate-content-applications.ts | 17 ++++++++++++----- .../graphs/list-applications-graphs.ts | 17 ++++++++++++----- .../graphs/update-applications-graphs.ts | 17 ++++++++++++----- .../jobs/create-applications-jobs.ts | 17 ++++++++++++----- .../applications/jobs/list-applications-jobs.ts | 13 ++++++++++--- .../jobs/retrieve-applications-jobs.ts | 13 ++++++++++--- .../jobs/retry-applications-jobs.ts | 13 ++++++++++--- .../src/tools/applications/list-applications.ts | 13 ++++++++++--- .../tools/applications/retrieve-applications.ts | 17 ++++++++++++----- .../src/tools/completions/create-completions.ts | 13 ++++++++++--- .../mcp-server/src/tools/files/delete-files.ts | 13 ++++++++++--- .../mcp-server/src/tools/files/list-files.ts | 13 ++++++++++--- .../src/tools/files/retrieve-files.ts | 13 ++++++++++--- .../mcp-server/src/tools/files/retry-files.ts | 13 ++++++++++--- .../mcp-server/src/tools/files/upload-files.ts | 13 ++++++++++--- .../tools/graphs/add-file-to-graph-graphs.ts | 17 ++++++++++++----- .../src/tools/graphs/create-graphs.ts | 13 ++++++++++--- .../src/tools/graphs/delete-graphs.ts | 13 ++++++++++--- .../mcp-server/src/tools/graphs/list-graphs.ts | 13 ++++++++++--- .../graphs/remove-file-from-graph-graphs.ts | 17 ++++++++++++----- .../src/tools/graphs/retrieve-graphs.ts | 13 ++++++++++--- .../src/tools/graphs/update-graphs.ts | 13 ++++++++++--- .../mcp-server/src/tools/models/list-models.ts | 13 ++++++++++--- .../src/tools/tools/ai-detect-tools.ts | 13 ++++++++++--- .../comprehend/medical-tools-comprehend.ts | 13 ++++++++++--- .../tools/context-aware-splitting-tools.ts | 13 ++++++++++--- .../src/tools/tools/parse-pdf-tools.ts | 13 ++++++++++--- .../src/tools/tools/web-search-tools.ts | 13 ++++++++++--- .../tools/translation/translate-translation.ts | 13 ++++++++++--- packages/mcp-server/src/tools/types.ts | 12 ++++++++++++ .../src/tools/vision/analyze-vision.ts | 13 ++++++++++--- 32 files changed, 330 insertions(+), 104 deletions(-) diff --git a/packages/mcp-server/src/filtering.ts b/packages/mcp-server/src/filtering.ts index 1aa9a40c..eaae0fcf 100644 --- a/packages/mcp-server/src/filtering.ts +++ b/packages/mcp-server/src/filtering.ts @@ -12,3 +12,7 @@ export async function maybeFilter(jqFilter: unknown | undefined, response: any): async function jq(json: any, jqFilter: string) { return (await initJq).json(json, jqFilter); } + +export function isJqError(error: any): error is Error { + return error instanceof Error && 'stderr' in error; +} diff --git a/packages/mcp-server/src/tools/applications/generate-content-applications.ts b/packages/mcp-server/src/tools/applications/generate-content-applications.ts index 6b9b5b70..6fd4a72b 100644 --- a/packages/mcp-server/src/tools/applications/generate-content-applications.ts +++ b/packages/mcp-server/src/tools/applications/generate-content-applications.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -113,9 +113,16 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { application_id, jq_filter, ...body } = args as any; - return asTextContentResult( - await maybeFilter(jq_filter, await client.applications.generateContent(application_id, body)), - ); + try { + return asTextContentResult( + await maybeFilter(jq_filter, await client.applications.generateContent(application_id, body)), + ); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/graphs/list-applications-graphs.ts b/packages/mcp-server/src/tools/applications/graphs/list-applications-graphs.ts index bb39401e..d0543c5f 100644 --- a/packages/mcp-server/src/tools/applications/graphs/list-applications-graphs.ts +++ b/packages/mcp-server/src/tools/applications/graphs/list-applications-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -40,9 +40,16 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { application_id, jq_filter, ...body } = args as any; - return asTextContentResult( - await maybeFilter(jq_filter, await client.applications.graphs.list(application_id)), - ); + try { + return asTextContentResult( + await maybeFilter(jq_filter, await client.applications.graphs.list(application_id)), + ); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/graphs/update-applications-graphs.ts b/packages/mcp-server/src/tools/applications/graphs/update-applications-graphs.ts index 4af1d43c..72625bcd 100644 --- a/packages/mcp-server/src/tools/applications/graphs/update-applications-graphs.ts +++ b/packages/mcp-server/src/tools/applications/graphs/update-applications-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -48,9 +48,16 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { application_id, jq_filter, ...body } = args as any; - return asTextContentResult( - await maybeFilter(jq_filter, await client.applications.graphs.update(application_id, body)), - ); + try { + return asTextContentResult( + await maybeFilter(jq_filter, await client.applications.graphs.update(application_id, body)), + ); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts b/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts index 1427d004..cd5a192b 100644 --- a/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts +++ b/packages/mcp-server/src/tools/applications/jobs/create-applications-jobs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -62,9 +62,16 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { application_id, jq_filter, ...body } = args as any; - return asTextContentResult( - await maybeFilter(jq_filter, await client.applications.jobs.create(application_id, body)), - ); + try { + return asTextContentResult( + await maybeFilter(jq_filter, await client.applications.jobs.create(application_id, body)), + ); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/jobs/list-applications-jobs.ts b/packages/mcp-server/src/tools/applications/jobs/list-applications-jobs.ts index fe57f862..a04bcc9e 100644 --- a/packages/mcp-server/src/tools/applications/jobs/list-applications-jobs.ts +++ b/packages/mcp-server/src/tools/applications/jobs/list-applications-jobs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -55,7 +55,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { application_id, jq_filter, ...body } = args as any; const response = await client.applications.jobs.list(application_id, body).asResponse(); - return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + try { + return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/jobs/retrieve-applications-jobs.ts b/packages/mcp-server/src/tools/applications/jobs/retrieve-applications-jobs.ts index 44ae4d79..bc431b5d 100644 --- a/packages/mcp-server/src/tools/applications/jobs/retrieve-applications-jobs.ts +++ b/packages/mcp-server/src/tools/applications/jobs/retrieve-applications-jobs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -40,7 +40,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { job_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.applications.jobs.retrieve(job_id))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.applications.jobs.retrieve(job_id))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts b/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts index 6874b919..f9b6f099 100644 --- a/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts +++ b/packages/mcp-server/src/tools/applications/jobs/retry-applications-jobs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -38,7 +38,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { job_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.applications.jobs.retry(job_id))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.applications.jobs.retry(job_id))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/list-applications.ts b/packages/mcp-server/src/tools/applications/list-applications.ts index 402063ef..9a2f628a 100644 --- a/packages/mcp-server/src/tools/applications/list-applications.ts +++ b/packages/mcp-server/src/tools/applications/list-applications.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -61,7 +61,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; const response = await client.applications.list(body).asResponse(); - return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + try { + return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/applications/retrieve-applications.ts b/packages/mcp-server/src/tools/applications/retrieve-applications.ts index c05e0b7c..a85120ec 100644 --- a/packages/mcp-server/src/tools/applications/retrieve-applications.ts +++ b/packages/mcp-server/src/tools/applications/retrieve-applications.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -40,9 +40,16 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { application_id, jq_filter, ...body } = args as any; - return asTextContentResult( - await maybeFilter(jq_filter, await client.applications.retrieve(application_id)), - ); + try { + return asTextContentResult( + await maybeFilter(jq_filter, await client.applications.retrieve(application_id)), + ); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/completions/create-completions.ts b/packages/mcp-server/src/tools/completions/create-completions.ts index c1593d85..9b9a4cad 100644 --- a/packages/mcp-server/src/tools/completions/create-completions.ts +++ b/packages/mcp-server/src/tools/completions/create-completions.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -157,7 +157,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.completions.create(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.completions.create(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/files/delete-files.ts b/packages/mcp-server/src/tools/files/delete-files.ts index ed9fe7cd..43050c44 100644 --- a/packages/mcp-server/src/tools/files/delete-files.ts +++ b/packages/mcp-server/src/tools/files/delete-files.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -41,7 +41,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { file_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.files.delete(file_id))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.files.delete(file_id))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/files/list-files.ts b/packages/mcp-server/src/tools/files/list-files.ts index ee94d844..d431202c 100644 --- a/packages/mcp-server/src/tools/files/list-files.ts +++ b/packages/mcp-server/src/tools/files/list-files.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -75,7 +75,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; const response = await client.files.list(body).asResponse(); - return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + try { + return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/files/retrieve-files.ts b/packages/mcp-server/src/tools/files/retrieve-files.ts index e9a55d10..e38b6800 100644 --- a/packages/mcp-server/src/tools/files/retrieve-files.ts +++ b/packages/mcp-server/src/tools/files/retrieve-files.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -41,7 +41,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { file_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.files.retrieve(file_id))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.files.retrieve(file_id))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/files/retry-files.ts b/packages/mcp-server/src/tools/files/retry-files.ts index 4470e40a..cc62a08b 100644 --- a/packages/mcp-server/src/tools/files/retry-files.ts +++ b/packages/mcp-server/src/tools/files/retry-files.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -43,7 +43,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.files.retry(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.files.retry(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/files/upload-files.ts b/packages/mcp-server/src/tools/files/upload-files.ts index 7babd137..06d6eda1 100644 --- a/packages/mcp-server/src/tools/files/upload-files.ts +++ b/packages/mcp-server/src/tools/files/upload-files.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -42,7 +42,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.files.upload(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.files.upload(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts b/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts index 98601626..24c5c107 100644 --- a/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -43,9 +43,16 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { graph_id, jq_filter, ...body } = args as any; - return asTextContentResult( - await maybeFilter(jq_filter, await client.graphs.addFileToGraph(graph_id, body)), - ); + try { + return asTextContentResult( + await maybeFilter(jq_filter, await client.graphs.addFileToGraph(graph_id, body)), + ); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/graphs/create-graphs.ts b/packages/mcp-server/src/tools/graphs/create-graphs.ts index 63706f7c..b24f68aa 100644 --- a/packages/mcp-server/src/tools/graphs/create-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/create-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -46,7 +46,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.create(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.create(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/graphs/delete-graphs.ts b/packages/mcp-server/src/tools/graphs/delete-graphs.ts index ca9207eb..f49d8e37 100644 --- a/packages/mcp-server/src/tools/graphs/delete-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/delete-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -41,7 +41,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { graph_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.delete(graph_id))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.delete(graph_id))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/graphs/list-graphs.ts b/packages/mcp-server/src/tools/graphs/list-graphs.ts index 98dd37e9..c9ed0dcc 100644 --- a/packages/mcp-server/src/tools/graphs/list-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/list-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -60,7 +60,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; const response = await client.graphs.list(body).asResponse(); - return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + try { + return asTextContentResult(await maybeFilter(jq_filter, await response.json())); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts b/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts index 9cec09d2..6a7ed9cd 100644 --- a/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/remove-file-from-graph-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -44,9 +44,16 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { file_id, jq_filter, ...body } = args as any; - return asTextContentResult( - await maybeFilter(jq_filter, await client.graphs.removeFileFromGraph(file_id, body)), - ); + try { + return asTextContentResult( + await maybeFilter(jq_filter, await client.graphs.removeFileFromGraph(file_id, body)), + ); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts b/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts index 4ed07bd7..a9641fe2 100644 --- a/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/retrieve-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -41,7 +41,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { graph_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.retrieve(graph_id))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.retrieve(graph_id))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/graphs/update-graphs.ts b/packages/mcp-server/src/tools/graphs/update-graphs.ts index 38c571a6..52c02654 100644 --- a/packages/mcp-server/src/tools/graphs/update-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/update-graphs.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -80,7 +80,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { graph_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.update(graph_id, body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.graphs.update(graph_id, body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/models/list-models.ts b/packages/mcp-server/src/tools/models/list-models.ts index 32fc949e..50163670 100644 --- a/packages/mcp-server/src/tools/models/list-models.ts +++ b/packages/mcp-server/src/tools/models/list-models.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -38,7 +38,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.models.list())); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.models.list())); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/tools/ai-detect-tools.ts b/packages/mcp-server/src/tools/tools/ai-detect-tools.ts index b7f07f11..d64dfbc7 100644 --- a/packages/mcp-server/src/tools/tools/ai-detect-tools.ts +++ b/packages/mcp-server/src/tools/tools/ai-detect-tools.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -40,7 +40,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.tools.aiDetect(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.tools.aiDetect(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts b/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts index 4e7ae07e..b5fe3146 100644 --- a/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts +++ b/packages/mcp-server/src/tools/tools/comprehend/medical-tools-comprehend.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -46,7 +46,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.tools.comprehend.medical(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.tools.comprehend.medical(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts b/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts index d5a582e3..18c7cc96 100644 --- a/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts +++ b/packages/mcp-server/src/tools/tools/context-aware-splitting-tools.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -46,7 +46,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.tools.contextAwareSplitting(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.tools.contextAwareSplitting(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts b/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts index 046ce377..a23ac88d 100644 --- a/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts +++ b/packages/mcp-server/src/tools/tools/parse-pdf-tools.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -44,7 +44,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { file_id, jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.tools.parsePdf(file_id, body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.tools.parsePdf(file_id, body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/tools/web-search-tools.ts b/packages/mcp-server/src/tools/tools/web-search-tools.ts index 14c18197..d8ae2a66 100644 --- a/packages/mcp-server/src/tools/tools/web-search-tools.ts +++ b/packages/mcp-server/src/tools/tools/web-search-tools.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -279,7 +279,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.tools.webSearch(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.tools.webSearch(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/translation/translate-translation.ts b/packages/mcp-server/src/tools/translation/translate-translation.ts index 6c0832f4..353055c8 100644 --- a/packages/mcp-server/src/tools/translation/translate-translation.ts +++ b/packages/mcp-server/src/tools/translation/translate-translation.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { maybeFilter } from 'writer-sdk-mcp/filtering'; -import { Metadata, asTextContentResult } from 'writer-sdk-mcp/tools/types'; +import { isJqError, maybeFilter } from 'writer-sdk-mcp/filtering'; +import { Metadata, asErrorResult, asTextContentResult } from 'writer-sdk-mcp/tools/types'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import Writer from 'writer-sdk'; @@ -77,7 +77,14 @@ export const tool: Tool = { export const handler = async (client: Writer, args: Record | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.translation.translate(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.translation.translate(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; diff --git a/packages/mcp-server/src/tools/types.ts b/packages/mcp-server/src/tools/types.ts index 17f01978..9993753a 100644 --- a/packages/mcp-server/src/tools/types.ts +++ b/packages/mcp-server/src/tools/types.ts @@ -87,6 +87,18 @@ export async function asBinaryContentResult(response: Response): Promise | undefined) => { const { jq_filter, ...body } = args as any; - return asTextContentResult(await maybeFilter(jq_filter, await client.vision.analyze(body))); + try { + return asTextContentResult(await maybeFilter(jq_filter, await client.vision.analyze(body))); + } catch (error) { + if (isJqError(error)) { + return asErrorResult(error.message); + } + throw error; + } }; export default { metadata, tool, handler }; From 9a0ac581162b2c59792d493e17cbe9d9cb0b5f60 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 20:50:16 +0000 Subject: [PATCH 21/26] chore(mcp): upgrade jq-web --- packages/mcp-server/package.json | 2 +- packages/mcp-server/yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 5a617c1c..86ec786a 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -37,7 +37,7 @@ "cors": "^2.8.5", "express": "^5.1.0", "fuse.js": "^7.1.0", - "jq-web": "https://github.com/stainless-api/jq-web/releases/download/v0.8.6/jq-web.tar.gz", + "jq-web": "https://github.com/stainless-api/jq-web/releases/download/v0.8.8/jq-web.tar.gz", "qs": "^6.14.0", "typescript": "5.8.3", "yargs": "^17.7.2", diff --git a/packages/mcp-server/yarn.lock b/packages/mcp-server/yarn.lock index 966d0575..2bb21c66 100644 --- a/packages/mcp-server/yarn.lock +++ b/packages/mcp-server/yarn.lock @@ -2494,9 +2494,9 @@ jest@^29.4.0: import-local "^3.0.2" jest-cli "^29.7.0" -"jq-web@https://github.com/stainless-api/jq-web/releases/download/v0.8.6/jq-web.tar.gz": - version "0.8.6" - resolved "https://github.com/stainless-api/jq-web/releases/download/v0.8.6/jq-web.tar.gz#14d0e126987736e82e964d675c3838b5944faa6f" +"jq-web@https://github.com/stainless-api/jq-web/releases/download/v0.8.8/jq-web.tar.gz": + version "0.8.8" + resolved "https://github.com/stainless-api/jq-web/releases/download/v0.8.8/jq-web.tar.gz#7849ef64bdfc28f70cbfc9888f886860e96da10d" js-tokens@^4.0.0: version "4.0.0" From 0c975f793c10f8f047c477ecde35f8e358b95e91 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 18:10:46 +0000 Subject: [PATCH 22/26] feat(mcp): add detail field to docs search tool --- packages/mcp-server/src/docs-search-tool.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/mcp-server/src/docs-search-tool.ts b/packages/mcp-server/src/docs-search-tool.ts index 4ec0c2c8..5bded3fb 100644 --- a/packages/mcp-server/src/docs-search-tool.ts +++ b/packages/mcp-server/src/docs-search-tool.ts @@ -13,8 +13,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'search_docs', - description: - 'Search for documentation for how to use the client to interact with the API.\nThe tool will return an array of Markdown-formatted documentation pages.', + description: 'Search for documentation for how to use the client to interact with the API.', inputSchema: { type: 'object', properties: { @@ -25,7 +24,12 @@ export const tool: Tool = { language: { type: 'string', description: 'The language for the SDK to search for.', - enum: ['http', 'python', 'go', 'typescript', 'terraform', 'ruby', 'java', 'kotlin'], + enum: ['http', 'python', 'go', 'typescript', 'javascript', 'terraform', 'ruby', 'java', 'kotlin'], + }, + detail: { + type: 'string', + description: 'The amount of detail to return.', + enum: ['default', 'verbose'], }, }, required: ['query', 'language'], From 69b36c97a708452f05522c9b81f0855fea0daadb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 30 Nov 2025 00:58:22 +0000 Subject: [PATCH 23/26] docs(api): updates to API spec --- .stats.yml | 4 +-- packages/mcp-server/README.md | 2 +- .../mcp-server/src/tools/chat/chat-chat.ts | 5 +-- .../mcp-server/src/tools/files/list-files.ts | 2 +- .../src/tools/files/retrieve-files.ts | 2 +- .../src/tools/files/upload-files.ts | 7 ++++- .../tools/graphs/add-file-to-graph-graphs.ts | 2 +- .../src/tools/vision/analyze-vision.ts | 6 ++-- src/resources/files.ts | 18 ++++++++++- src/resources/shared.ts | 12 ++++--- src/resources/vision.ts | 31 +++++++++++-------- tests/api-resources/files.test.ts | 1 + 12 files changed, 61 insertions(+), 31 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9ff96150..33ea12a4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 33 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/writerai%2Fwriter-4ec783072dd7f57c6e021a746df7650fb8d7a164d8ec25c7d5cab06c33bc114f.yml -openapi_spec_hash: ceab065d515f3681b0c33137da308968 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/writerai%2Fwriter-ea6ec4b34f6b7fdecc564f59b2e31482eee05830bf8dc1f389461b158de1548e.yml +openapi_spec_hash: ea89c1faed473908be2740efe6da255f config_hash: 886645f89dc98f04b8931eaf02854e5f diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md index ce6ef16f..b212d1a2 100644 --- a/packages/mcp-server/README.md +++ b/packages/mcp-server/README.md @@ -307,4 +307,4 @@ The following tools are available in this MCP server. ### Resource `vision`: -- `analyze_vision` (`write`): Submit images and a prompt to generate an analysis of the images. +- `analyze_vision` (`write`): Submit images and documents with a prompt to generate an analysis. Supports JPG, PNG, PDF, and TXT files up to 7MB each. diff --git a/packages/mcp-server/src/tools/chat/chat-chat.ts b/packages/mcp-server/src/tools/chat/chat-chat.ts index 9f460d75..42b3164b 100644 --- a/packages/mcp-server/src/tools/chat/chat-chat.ts +++ b/packages/mcp-server/src/tools/chat/chat-chat.ts @@ -823,7 +823,8 @@ export const tool: Tool = { function: { type: 'object', title: 'Vision function', - description: 'A tool that uses Palmyra Vision to analyze images.', + description: + 'A tool that uses Palmyra Vision to analyze images and documents. Supports JPG, PNG, PDF, and TXT files up to 7MB each.', properties: { model: { type: 'string', @@ -839,7 +840,7 @@ export const tool: Tool = { file_id: { type: 'string', description: - 'The File ID of the image to analyze. The file must be uploaded to the Writer platform before you use it with the Vision tool. The maximum allowed file size is 7MB.', + 'The File ID of the file to analyze. The file must be uploaded to the Writer platform before you use it with the Vision tool. Supported file types: JPG, PNG, PDF, TXT. The maximum allowed file size is 7MB.', }, name: { type: 'string', diff --git a/packages/mcp-server/src/tools/files/list-files.ts b/packages/mcp-server/src/tools/files/list-files.ts index d431202c..ce78108e 100644 --- a/packages/mcp-server/src/tools/files/list-files.ts +++ b/packages/mcp-server/src/tools/files/list-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'list_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet a paginated list of all uploaded files. Filter by processing status (in_progress, completed, failed), Knowledge Graph association, or file type. Use this to discover available files, monitor processing status, or find files to add to Knowledge Graphs.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'files_response',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: '#/$defs/file'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more files available beyond the current page.'\n },\n first_id: {\n type: 'string',\n description: 'The ID of the first file in the current response.'\n },\n last_id: {\n type: 'string',\n description: 'The ID of the last file in the current response.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet a paginated list of all uploaded files. Filter by processing status (in_progress, completed, failed), Knowledge Graph association, or file type. Use this to discover available files, monitor processing status, or find files to add to Knowledge Graphs.\n\n# Response Schema\n```json\n{\n type: 'object',\n title: 'files_response',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: '#/$defs/file'\n }\n },\n has_more: {\n type: 'boolean',\n description: 'Indicates if there are more files available beyond the current page.'\n },\n first_id: {\n type: 'string',\n description: 'The ID of the first file in the current response.'\n },\n last_id: {\n type: 'string',\n description: 'The ID of the last file in the current response.'\n }\n },\n required: [ 'data',\n 'has_more'\n ],\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.\\n\\nIf you provided a `graphId` during upload, the file is associated with that Knowledge Graph. However, the `graph_ids` field in the upload response is an empty list. The association will be visible in the `graph_ids` list when you retrieve the file using the file retrieval endpoint.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/files/retrieve-files.ts b/packages/mcp-server/src/tools/files/retrieve-files.ts index e38b6800..2621dd27 100644 --- a/packages/mcp-server/src/tools/files/retrieve-files.ts +++ b/packages/mcp-server/src/tools/files/retrieve-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'retrieve_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet metadata and status information for a specific file by its ID. Returns file name, creation date, processing status, and associated Knowledge Graph IDs. Use this to check if a file has finished processing or to find which Knowledge Graphs contain a specific file.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nGet metadata and status information for a specific file by its ID. Returns file name, creation date, processing status, and associated Knowledge Graph IDs. Use this to check if a file has finished processing or to find which Knowledge Graphs contain a specific file.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.\\n\\nIf you provided a `graphId` during upload, the file is associated with that Knowledge Graph. However, the `graph_ids` field in the upload response is an empty list. The association will be visible in the `graph_ids` list when you retrieve the file using the file retrieval endpoint.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/files/upload-files.ts b/packages/mcp-server/src/tools/files/upload-files.ts index 06d6eda1..4e9c7356 100644 --- a/packages/mcp-server/src/tools/files/upload-files.ts +++ b/packages/mcp-server/src/tools/files/upload-files.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'upload_files', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nUpload documents and files to Writer. Supports PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, XLSX, MP3, and MP4 formats. Once uploaded, files can be added to Knowledge Graphs for querying or used with Vision API for image analysis. Returns a file ID for subsequent operations.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nUpload documents and files to Writer. Supports PDF, DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, XLSX, MP3, and MP4 formats. Once uploaded, files can be added to Knowledge Graphs for querying or used with Vision API for image analysis. Returns a file ID for subsequent operations.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.\\n\\nIf you provided a `graphId` during upload, the file is associated with that Knowledge Graph. However, the `graph_ids` field in the upload response is an empty list. The association will be visible in the `graph_ids` list when you retrieve the file using the file retrieval endpoint.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { @@ -28,6 +28,11 @@ export const tool: Tool = { 'Content-Disposition': { type: 'string', }, + graphId: { + type: 'string', + description: + 'The unique identifier of the Knowledge Graph to associate the uploaded file with.\n\nNote: The response from the upload endpoint does not include the `graphId` field, but the association will be visible when you retrieve the file using the file retrieval endpoint.', + }, jq_filter: { type: 'string', title: 'jq Filter', diff --git a/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts b/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts index 24c5c107..a25705e1 100644 --- a/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts +++ b/packages/mcp-server/src/tools/graphs/add-file-to-graph-graphs.ts @@ -18,7 +18,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'add_file_to_graph_graphs', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nAdd an uploaded file to a Knowledge Graph to make it queryable. The file must already be uploaded using upload-file. Once added, the file's content becomes searchable when querying the Knowledge Graph. Files are processed asynchronously - check status using get-file-info.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nAdd an uploaded file to a Knowledge Graph to make it queryable. The file must already be uploaded using upload-file. Once added, the file's content becomes searchable when querying the Knowledge Graph. Files are processed asynchronously - check status using get-file-info.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/file',\n $defs: {\n file: {\n type: 'object',\n title: 'file_response',\n properties: {\n id: {\n type: 'string',\n description: 'A unique identifier of the file.'\n },\n created_at: {\n type: 'string',\n description: 'The timestamp when the file was uploaded.',\n format: 'date-time'\n },\n graph_ids: {\n type: 'array',\n description: 'A list of Knowledge Graph IDs that the file is associated with.\\n\\nIf you provided a `graphId` during upload, the file is associated with that Knowledge Graph. However, the `graph_ids` field in the upload response is an empty list. The association will be visible in the `graph_ids` list when you retrieve the file using the file retrieval endpoint.',\n items: {\n type: 'string'\n }\n },\n name: {\n type: 'string',\n description: 'The name of the file.'\n },\n status: {\n type: 'string',\n description: 'The processing status of the file.'\n }\n },\n required: [ 'id',\n 'created_at',\n 'graph_ids',\n 'name',\n 'status'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { diff --git a/packages/mcp-server/src/tools/vision/analyze-vision.ts b/packages/mcp-server/src/tools/vision/analyze-vision.ts index 00d161df..73f65385 100644 --- a/packages/mcp-server/src/tools/vision/analyze-vision.ts +++ b/packages/mcp-server/src/tools/vision/analyze-vision.ts @@ -17,7 +17,7 @@ export const metadata: Metadata = { export const tool: Tool = { name: 'analyze_vision', description: - "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nSubmit images and a prompt to generate an analysis of the images.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/vision_response',\n $defs: {\n vision_response: {\n type: 'object',\n title: 'Vision Response',\n properties: {\n data: {\n type: 'string',\n description: 'The result of the image analysis.'\n }\n },\n required: [ 'data'\n ]\n }\n }\n}\n```", + "When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nSubmit images and documents with a prompt to generate an analysis. Supports JPG, PNG, PDF, and TXT files up to 7MB each.\n\n# Response Schema\n```json\n{\n $ref: '#/$defs/vision_response',\n $defs: {\n vision_response: {\n type: 'object',\n title: 'Vision Response',\n properties: {\n data: {\n type: 'string',\n description: 'The result of the image analysis.'\n }\n },\n required: [ 'data'\n ]\n }\n }\n}\n```", inputSchema: { type: 'object', properties: { @@ -37,12 +37,12 @@ export const tool: Tool = { type: 'object', title: 'Vision Request File Variable', description: - 'An array of file variables required for the analysis. The image files must be uploaded to the Writer platform before they can be used in a vision request. Learn how to upload files using the [Files API](https://dev.writer.com/api-reference/file-api/upload-files).\n\nThe maximum allowed file size for each image is 7MB.', + 'An array of file variables required for the analysis. The files must be uploaded to the Writer platform before they can be used in a vision request. Learn how to upload files using the [Files API](https://dev.writer.com/api-reference/file-api/upload-files).\n\nSupported file types: JPG, PNG, PDF, TXT. The maximum allowed file size for each file is 7MB.', properties: { file_id: { type: 'string', description: - 'The File ID of the image to analyze. The file must be uploaded to the Writer platform before it can be used in a vision request.', + 'The File ID of the file to analyze. The file must be uploaded to the Writer platform before it can be used in a vision request. Supported file types: JPG, PNG, PDF, TXT (max 7MB each).', }, name: { type: 'string', diff --git a/src/resources/files.ts b/src/resources/files.ts index c1c5227b..13adaba3 100644 --- a/src/resources/files.ts +++ b/src/resources/files.ts @@ -60,8 +60,9 @@ export class Files extends APIResource { * DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, and XLSX. */ upload(params: FileUploadParams, options?: RequestOptions): APIPromise { - const { content, 'Content-Disposition': contentDisposition, 'Content-Type': contentType } = params; + const { content, 'Content-Disposition': contentDisposition, 'Content-Type': contentType, graphId } = params; return this._client.post('/v1/files', { + query: { graphId }, body: content, ...options, headers: { @@ -88,6 +89,11 @@ export interface File { /** * A list of Knowledge Graph IDs that the file is associated with. + * + * If you provided a `graphId` during upload, the file is associated with that + * Knowledge Graph. However, the `graph_ids` field in the upload response is an + * empty list. The association will be visible in the `graph_ids` list when you + * retrieve the file using the file retrieval endpoint. */ graph_ids: Array; @@ -176,6 +182,16 @@ export interface FileUploadParams { * Header param: The content type of the file. */ 'Content-Type': string; + + /** + * Query param: The unique identifier of the Knowledge Graph to associate the + * uploaded file with. + * + * Note: The response from the upload endpoint does not include the `graphId` + * field, but the association will be visible when you retrieve the file using the + * file retrieval endpoint. + */ + graphId?: string; } export declare namespace Files { diff --git a/src/resources/shared.ts b/src/resources/shared.ts index ca578942..c852af4e 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -492,7 +492,8 @@ export namespace ToolParam { export interface VisionTool { /** - * A tool that uses Palmyra Vision to analyze images. + * A tool that uses Palmyra Vision to analyze images and documents. Supports JPG, + * PNG, PDF, and TXT files up to 7MB each. */ function: VisionTool.Function; @@ -504,7 +505,8 @@ export namespace ToolParam { export namespace VisionTool { /** - * A tool that uses Palmyra Vision to analyze images. + * A tool that uses Palmyra Vision to analyze images and documents. Supports JPG, + * PNG, PDF, and TXT files up to 7MB each. */ export interface Function { /** @@ -518,9 +520,9 @@ export namespace ToolParam { export namespace Function { export interface Variable { /** - * The File ID of the image to analyze. The file must be uploaded to the Writer - * platform before you use it with the Vision tool. The maximum allowed file size - * is 7MB. + * The File ID of the file to analyze. The file must be uploaded to the Writer + * platform before you use it with the Vision tool. Supported file types: JPG, PNG, + * PDF, TXT. The maximum allowed file size is 7MB. */ file_id: string; diff --git a/src/resources/vision.ts b/src/resources/vision.ts index 01ac6fa1..87544c76 100644 --- a/src/resources/vision.ts +++ b/src/resources/vision.ts @@ -6,7 +6,8 @@ import { RequestOptions } from '../internal/request-options'; export class Vision extends APIResource { /** - * Submit images and a prompt to generate an analysis of the images. + * Submit images and documents with a prompt to generate an analysis. Supports JPG, + * PNG, PDF, and TXT files up to 7MB each. * * @example * ```ts @@ -44,17 +45,19 @@ export interface VisionRequest { export namespace VisionRequest { /** - * An array of file variables required for the analysis. The image files must be - * uploaded to the Writer platform before they can be used in a vision request. - * Learn how to upload files using the + * An array of file variables required for the analysis. The files must be uploaded + * to the Writer platform before they can be used in a vision request. Learn how to + * upload files using the * [Files API](https://dev.writer.com/api-reference/file-api/upload-files). * - * The maximum allowed file size for each image is 7MB. + * Supported file types: JPG, PNG, PDF, TXT. The maximum allowed file size for each + * file is 7MB. */ export interface Variable { /** - * The File ID of the image to analyze. The file must be uploaded to the Writer - * platform before it can be used in a vision request. + * The File ID of the file to analyze. The file must be uploaded to the Writer + * platform before it can be used in a vision request. Supported file types: JPG, + * PNG, PDF, TXT (max 7MB each). */ file_id: string; @@ -92,17 +95,19 @@ export interface VisionAnalyzeParams { export namespace VisionAnalyzeParams { /** - * An array of file variables required for the analysis. The image files must be - * uploaded to the Writer platform before they can be used in a vision request. - * Learn how to upload files using the + * An array of file variables required for the analysis. The files must be uploaded + * to the Writer platform before they can be used in a vision request. Learn how to + * upload files using the * [Files API](https://dev.writer.com/api-reference/file-api/upload-files). * - * The maximum allowed file size for each image is 7MB. + * Supported file types: JPG, PNG, PDF, TXT. The maximum allowed file size for each + * file is 7MB. */ export interface Variable { /** - * The File ID of the image to analyze. The file must be uploaded to the Writer - * platform before it can be used in a vision request. + * The File ID of the file to analyze. The file must be uploaded to the Writer + * platform before it can be used in a vision request. Supported file types: JPG, + * PNG, PDF, TXT (max 7MB each). */ file_id: string; diff --git a/tests/api-resources/files.test.ts b/tests/api-resources/files.test.ts index 9ba8965c..fd4b19c2 100644 --- a/tests/api-resources/files.test.ts +++ b/tests/api-resources/files.test.ts @@ -96,6 +96,7 @@ describe('resource files', () => { content: await toFile(Buffer.from('# my file contents'), 'README.md'), 'Content-Disposition': 'Content-Disposition', 'Content-Type': 'Content-Type', + graphId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', }); }); }); From 20209b8c6037de89117b4f9b0e690721380e2dbc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:39:11 +0000 Subject: [PATCH 24/26] chore(client): fix logger property type --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index b945426a..6cfe26e2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -202,7 +202,7 @@ export class Writer { baseURL: string; maxRetries: number; timeout: number; - logger: Logger | undefined; + logger: Logger; logLevel: LogLevel | undefined; fetchOptions: MergedRequestInit | undefined; From 12f49e62a666d57a934537bf8f25cef1338b3e27 Mon Sep 17 00:00:00 2001 From: Sarah Deaton Date: Mon, 1 Dec 2025 10:44:44 -0800 Subject: [PATCH 25/26] fix: Fix linting errors. (#238) --- src/resources/files.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/resources/files.ts b/src/resources/files.ts index 13adaba3..3f22a12a 100644 --- a/src/resources/files.ts +++ b/src/resources/files.ts @@ -60,7 +60,12 @@ export class Files extends APIResource { * DOC, DOCX, PPT, PPTX, JPG, PNG, EML, HTML, SRT, CSV, XLS, and XLSX. */ upload(params: FileUploadParams, options?: RequestOptions): APIPromise { - const { content, 'Content-Disposition': contentDisposition, 'Content-Type': contentType, graphId } = params; + const { + content, + 'Content-Disposition': contentDisposition, + 'Content-Type': contentType, + graphId, + } = params; return this._client.post('/v1/files', { query: { graphId }, body: content, From f0d6777e3498a99cf5eea22088c9aafd37e385b0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:00:27 +0000 Subject: [PATCH 26/26] release: 2.3.3-rc.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 44 +++++++++++++++++++++++++++++++ package.json | 2 +- packages/mcp-server/package.json | 2 +- packages/mcp-server/src/server.ts | 2 +- src/version.ts | 2 +- 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8d17a8e5..f42cb631 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.3.2" + ".": "2.3.3-rc.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f765c36..4ac567af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,49 @@ # Changelog +## 2.3.3-rc.1 (2025-12-01) + +Full Changelog: [v2.3.2...v2.3.3-rc.1](https://github.com/writer/writer-node/compare/v2.3.2...v2.3.3-rc.1) + +### Features + +* **api:** Improve MCP tool descriptions ([95aa714](https://github.com/writer/writer-node/commit/95aa71460549717420896fd47fcebbd603739743)) +* **mcp:** add detail field to docs search tool ([0c975f7](https://github.com/writer/writer-node/commit/0c975f793c10f8f047c477ecde35f8e358b95e91)) +* **mcp:** enable optional code execution tool on http mcp servers ([cad37b7](https://github.com/writer/writer-node/commit/cad37b70c93d26bdafdfdf6047e9591a1b27376e)) + + +### Bug Fixes + +* **client:** incorrect offset pagination check ([b7847ab](https://github.com/writer/writer-node/commit/b7847abd4a65c07090855fd674c6bd4ff15b9760)) +* Fix linting errors. ([#238](https://github.com/writer/writer-node/issues/238)) ([12f49e6](https://github.com/writer/writer-node/commit/12f49e62a666d57a934537bf8f25cef1338b3e27)) +* **mcpb:** pin @anthropic-ai/mcpb version ([43acbce](https://github.com/writer/writer-node/commit/43acbcefa5cdbabe670ef4a5687ef871a3acf9f6)) +* **mcp:** return tool execution error on jq failure ([f833b8f](https://github.com/writer/writer-node/commit/f833b8ffb35c9921f66939cafab7ddc1a6948096)) +* **mcp:** use raw responses for binary content ([54da4f9](https://github.com/writer/writer-node/commit/54da4f964cae97a224763a29e851c4c63273953e)) + + +### Chores + +* **client:** fix logger property type ([20209b8](https://github.com/writer/writer-node/commit/20209b8c6037de89117b4f9b0e690721380e2dbc)) +* extract some types in mcp docs ([de1e150](https://github.com/writer/writer-node/commit/de1e15096bb097df00cdee211b752487d364d977)) +* **internal:** codegen related update ([35b1a8f](https://github.com/writer/writer-node/commit/35b1a8fd3128b36cb3a99025547b3484e57ae318)) +* **internal:** codegen related update ([5e30270](https://github.com/writer/writer-node/commit/5e3027034d15d23909742ac7a65d5e1db6709631)) +* **internal:** grammar fix (it's -> its) ([7dfbe17](https://github.com/writer/writer-node/commit/7dfbe171aa29752dd3e42e15d045fde008d6e96c)) +* **internal:** remove .eslintcache ([f75e301](https://github.com/writer/writer-node/commit/f75e3010fb346dde47038f0e876549bc6eba301f)) +* **internal:** use npm pack for build uploads ([38c37a1](https://github.com/writer/writer-node/commit/38c37a1cfc2af919b9833344716ff5172a5076b3)) +* **jsdoc:** fix [@link](https://github.com/link) annotations to refer only to parts of the packageā€˜s public interface ([d227de6](https://github.com/writer/writer-node/commit/d227de61034910da49481c6ff488436fcfed61fd)) +* mcp code tool explicit error message when missing a run function ([16c1a44](https://github.com/writer/writer-node/commit/16c1a446e5f1cf853582afe76bbc21739855ca70)) +* **mcp:** add friendlier MCP code tool errors on incorrect method invocations ([e6a4a0c](https://github.com/writer/writer-node/commit/e6a4a0c0936a215c9aed87365108b3bcf59303fd)) +* **mcp:** add line numbers to code tool errors ([00af445](https://github.com/writer/writer-node/commit/00af445b63b9a0db2fb59202f7ed3c4d34887990)) +* **mcp:** clarify http auth error ([bd123e0](https://github.com/writer/writer-node/commit/bd123e075e8bd0b179f95d8f8513a53414f86ac6)) +* **mcp:** upgrade jq-web ([9a0ac58](https://github.com/writer/writer-node/commit/9a0ac581162b2c59792d493e17cbe9d9cb0b5f60)) +* use structured error when code execution tool errors ([e140047](https://github.com/writer/writer-node/commit/e140047e470588b4c18bccbdb752078f198d8374)) + + +### Documentation + +* **api:** updates to API spec ([69b36c9](https://github.com/writer/writer-node/commit/69b36c97a708452f05522c9b81f0855fea0daadb)) +* **mcp:** add a README button for one-click add to Cursor ([062b7d7](https://github.com/writer/writer-node/commit/062b7d73c91530ea083872b67036a77265db9a8d)) +* **mcp:** add a README link to add server to VS Code or Claude Code ([bb1991a](https://github.com/writer/writer-node/commit/bb1991af52bb810f9b69ec7d9d761d8b79aa6b15)) + ## 2.3.2 (2025-10-03) Full Changelog: [v2.3.2-rc.2...v2.3.2](https://github.com/writer/writer-node/compare/v2.3.2-rc.2...v2.3.2) diff --git a/package.json b/package.json index d8129e9d..33f406b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "writer-sdk", - "version": "2.3.2", + "version": "2.3.3-rc.1", "description": "The official TypeScript library for the Writer API", "author": "Writer ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 86ec786a..f081e3c6 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "writer-sdk-mcp", - "version": "2.3.2", + "version": "2.3.3-rc.1", "description": "The official MCP Server for the Writer API", "author": "Writer ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index 42e71b12..4ec8edfa 100644 --- a/packages/mcp-server/src/server.ts +++ b/packages/mcp-server/src/server.ts @@ -34,7 +34,7 @@ export const newMcpServer = () => new McpServer( { name: 'writer_sdk_api', - version: '2.3.2', + version: '2.3.3-rc.1', }, { capabilities: { tools: {}, logging: {} } }, ); diff --git a/src/version.ts b/src/version.ts index c6fe86de..539014d7 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '2.3.2'; // x-release-please-version +export const VERSION = '2.3.3-rc.1'; // x-release-please-version