Skip to main content
Glama
apitable

AITable MCP Server

Official

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
NameRequiredDescriptionDefault
attachment_nameNoOptional custom name for the attachment after upload.
attachment_urlYesThe complete web URL of the file to be uploaded.
node_idYesThe 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);
        }
      }
    );
  • 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);
      }
    }
  • 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.'),
    },
  • 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;
    }
  • 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();
    }
Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/apitable/aitable-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server