upload_attachment_via_url
Upload files to the AITable server using a web URL. Store file data for attaching to specific records via create_record or update_record tools.
Instructions
Upload an attachment to the AITable server using its web URL. Returns storage information that can be passed to create_record or update_record tools to associate with a specific records.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| attachment_name | No | Optional custom name for the attachment after upload. | |
| attachment_url | Yes | The complete web URL of the file to be uploaded. | |
| node_id | Yes | The ID of the datasheet where the attachment will be attached after upload. |
Implementation Reference
- src/index.ts:287-323 (registration)Registration of the 'upload_attachment_via_url' tool using server.tool(), including description, input schema, and handler function.server.tool("upload_attachment_via_url", "Upload an attachment to the AITable server using its web URL. Returns storage information that can be passed to create_record or update_record tools to associate with a specific records.", { node_id: z.string().describe('The ID of the datasheet where the attachment will be attached after upload.'), attachment_url: z.string().describe('The complete web URL of the file to be uploaded.'), attachment_name: z.string().optional().describe('Optional custom name for the attachment after upload.'), }, async ({ node_id, attachment_url, attachment_name }) => { try { if (!node_id) { throw new Error("The datasheet ID (node_id) is required."); } if (!attachment_url) { throw new Error("The attachment URL is required."); } const result: ResponseVO<attachmentVO[]> = await aitableService.uploadFileToSpace(node_id, attachment_url, attachment_name); if (!result.success) { throw new Error(result.message || "Failed to upload attachment"); } return formatToolResponse({ success: true, data: result }); } catch (error) { console.error("Error in upload_attachment_via_url:", error); return formatToolResponse({ success: false, message: error instanceof Error ? error.message : "Unknown error occurred" }, true); } } );
- src/index.ts:294-322 (handler)The handler function for the tool that performs input validation and delegates to AitableService.uploadFileToSpace for the upload logic.async ({ node_id, attachment_url, attachment_name }) => { try { if (!node_id) { throw new Error("The datasheet ID (node_id) is required."); } if (!attachment_url) { throw new Error("The attachment URL is required."); } const result: ResponseVO<attachmentVO[]> = await aitableService.uploadFileToSpace(node_id, attachment_url, attachment_name); if (!result.success) { throw new Error(result.message || "Failed to upload attachment"); } return formatToolResponse({ success: true, data: result }); } catch (error) { console.error("Error in upload_attachment_via_url:", error); return formatToolResponse({ success: false, message: error instanceof Error ? error.message : "Unknown error occurred" }, true); } }
- src/index.ts:289-293 (schema)Zod input schema defining the tool parameters: node_id (required string), attachment_url (required string), attachment_name (optional string).{ node_id: z.string().describe('The ID of the datasheet where the attachment will be attached after upload.'), attachment_url: z.string().describe('The complete web URL of the file to be uploaded.'), attachment_name: z.string().optional().describe('Optional custom name for the attachment after upload.'), },
- src/aitableService.ts:329-365 (helper)Core helper method in AitableService that implements the file upload: fetches file from URL as Blob, creates FormData, POSTs to AITable /attachments endpoint.public async uploadFileToSpace( node_id: string, file_url: string, file_name?: string, ): Promise<ResponseVO<attachmentVO[]>> { // get the file name from file_url if not provided if(!file_name) { const url = new URL(file_url); file_name = url.pathname.split("/").pop() ?? "file_"+new Date().getTime(); } // Fetch the file from the provided URL const fileBlob = await this._fetchFileViaURL(file_url); const formData = new FormData(); formData.append("file", fileBlob, file_name); const endpoint = `/v1/datasheets/${node_id}/attachments`; const response = await this.fetch(`${this.baseUrl}${endpoint}`, { headers: { Authorization: `Bearer ${this.apiKey}`, }, body: formData, method: "POST", }); const responseJson = (await response.json()) as ResponseVO<attachmentVO[]>; if (!response.ok) { throw new Error( `AITable API Error: ${response.statusText}. Response: ${responseJson.message}` ); } return responseJson; }
- src/aitableService.ts:314-327 (helper)Private helper method to fetch the remote file as a Blob from the provided URL.private async _fetchFileViaURL(file_url: string): Promise<Blob> { if (!file_url) { throw new Error("file_url is required."); } const response = await this.fetch(file_url) if (!response.ok) { throw new Error( `Fetch file error: ${response.statusText}. Response: ${await response.text()}` ); } return response.blob(); }