From aa528d28433be57b8c452202eec3f024e86991d3 Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 3 Jan 2026 20:36:23 -0500 Subject: [PATCH] Extract upload-attachment script to separate file - Move embedded bash script to scripts/upload-attachment.sh - Update SKILL.md to reference external script with usage examples - Follows skill best practice: separate reusable tools from documentation --- SKILL.md | 69 +++++++----------------------------- scripts/upload-attachment.sh | 64 +++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 57 deletions(-) create mode 100755 scripts/upload-attachment.sh diff --git a/SKILL.md b/SKILL.md index 28cad38..8d19fa2 100644 --- a/SKILL.md +++ b/SKILL.md @@ -409,75 +409,30 @@ Attachments (invoices, receipts) are uploaded via the HTTP proxy endpoint, not M ### Upload Script -Save this script and run: `./upload-attachment.sh ` +Use `scripts/upload-attachment.sh` in this skill directory: ```bash -#!/bin/bash -# upload-attachment.sh - Upload file and link to Grist record -# Usage: ./upload-attachment.sh invoice.pdf Bills 13 +# Get session token first (via MCP request_session_token tool) +# Then run: +./scripts/upload-attachment.sh invoice.pdf Bills 13 -set -e +# Or pass token directly: +./scripts/upload-attachment.sh invoice.pdf Bills 13 sess_abc123... -FILE="$1" -TABLE="$2" -RECORD_ID="$3" - -if [[ -z "$FILE" || -z "$TABLE" || -z "$RECORD_ID" ]]; then - echo "Usage: $0 " - echo "Example: $0 invoice.pdf Bills 13" - exit 1 -fi - -# Get session token from Claude (copy from request_session_token response) -echo "Paste session token (from request_session_token MCP call):" -read -r TOKEN - -# Base URL for the grist-mcp proxy -BASE_URL="https://grist-mcp.bballou.com" - -# Upload attachment -echo "Uploading $FILE..." -RESPONSE=$(curl -s -X POST \ - -H "Authorization: Bearer $TOKEN" \ - -F "file=@$FILE" \ - "$BASE_URL/api/v1/attachments") - -# Extract attachment ID -ATTACHMENT_ID=$(echo "$RESPONSE" | jq -r '.data.attachment_id') - -if [[ "$ATTACHMENT_ID" == "null" || -z "$ATTACHMENT_ID" ]]; then - echo "Upload failed: $RESPONSE" - exit 1 -fi - -echo "Uploaded: attachment_id=$ATTACHMENT_ID" - -# Link to record via proxy -echo "Linking to $TABLE id=$RECORD_ID..." -curl -s -X POST \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"method\": \"update_records\", \"table\": \"$TABLE\", \"records\": [{\"id\": $RECORD_ID, \"fields\": {\"Attachment\": [\"L\", $ATTACHMENT_ID]}}]}" \ - "$BASE_URL/api/v1/proxy" | jq . - -echo "Done!" +# Environment variable for custom endpoint: +GRIST_MCP_URL=https://custom.example.com ./scripts/upload-attachment.sh ... ``` -### Linking Attachments +Run `./scripts/upload-attachment.sh` without arguments for full usage. -Grist attachment columns use a special format: `["L", attachment_id]` +### Linking Attachments Manually + +Grist attachment columns use format: `["L", attachment_id]` ```python -# Link attachment ID 1 to Bill ID 13 update_records("Bills", [{"id": 13, "fields": {"Attachment": ["L", 1]}}]) ``` -### Bills Table Attachment Column - -| Column | Type | Notes | -|--------|------|-------| -| Attachment | Attachments | Stores invoice/receipt files | - ## Formula Columns (Auto-Calculated) | Table.Column | Description | diff --git a/scripts/upload-attachment.sh b/scripts/upload-attachment.sh new file mode 100755 index 0000000..664b75b --- /dev/null +++ b/scripts/upload-attachment.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# upload-attachment.sh - Upload file and link to Grist record +# Usage: ./upload-attachment.sh
[token] +# +# Examples: +# ./upload-attachment.sh invoice.pdf Bills 13 +# ./upload-attachment.sh receipt.jpg Bills 13 sess_abc123... + +set -e + +FILE="$1" +TABLE="$2" +RECORD_ID="$3" +TOKEN="$4" + +if [[ -z "$FILE" || -z "$TABLE" || -z "$RECORD_ID" ]]; then + echo "Usage: $0
[token]" + echo "" + echo "Arguments:" + echo " file Path to file to upload" + echo " table Grist table name (e.g., Bills)" + echo " record_id Record ID to attach file to" + echo " token Session token (optional, will prompt if not provided)" + echo "" + echo "Example: $0 invoice.pdf Bills 13" + exit 1 +fi + +# Get token if not provided +if [[ -z "$TOKEN" ]]; then + echo "Paste session token (from request_session_token MCP call):" + read -r TOKEN +fi + +# Base URL for the grist-mcp proxy +BASE_URL="${GRIST_MCP_URL:-https://grist-mcp.bballou.com}" + +# Upload attachment +echo "Uploading $FILE..." +RESPONSE=$(curl -s -X POST \ + -H "Authorization: Bearer $TOKEN" \ + -F "file=@$FILE" \ + "$BASE_URL/api/v1/attachments") + +# Extract attachment ID +ATTACHMENT_ID=$(echo "$RESPONSE" | jq -r '.data.attachment_id') + +if [[ "$ATTACHMENT_ID" == "null" || -z "$ATTACHMENT_ID" ]]; then + echo "Upload failed: $RESPONSE" + exit 1 +fi + +echo "Uploaded: attachment_id=$ATTACHMENT_ID" + +# Link to record via proxy +echo "Linking to $TABLE id=$RECORD_ID..." +LINK_RESPONSE=$(curl -s -X POST \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"method\": \"update_records\", \"table\": \"$TABLE\", \"records\": [{\"id\": $RECORD_ID, \"fields\": {\"Attachment\": [\"L\", $ATTACHMENT_ID]}}]}" \ + "$BASE_URL/api/v1/proxy") + +echo "$LINK_RESPONSE" | jq . +echo "Done! Attachment $ATTACHMENT_ID linked to $TABLE record $RECORD_ID"