استخدمه عندما يكون هدفك واضحًا في قواعد البيانات والبيانات وتستطيع تحديد البيانات والأفعال التي يحتاجها فقط.
Airtable
Airtable: مهارة ينشرها مجتمع Hermes. مجالها قراءة قواعد البيانات والاستعلام عنها. الرخصة MIT. الإصدار الموثّق 1.1.0. مثبّتة افتراضيًا مع Hermes، فلا تحتاج خطوة تثبيت. تدعم: linux، macos، windows.
ماذا يضيف إلى Hermes؟
Airtable: مهارة ينشرها مجتمع Hermes. مجالها قراءة قواعد البيانات والاستعلام عنها. الرخصة MIT. الإصدار الموثّق 1.1.0. مثبّتة افتراضيًا مع Hermes، فلا تحتاج خطوة تثبيت. تدعم: linux، macos، windows.
Airtable هي مهارة مرتبطة بمجال قواعد البيانات والبيانات. يمنح الوكيل طريقة منظمة لقراءة البيانات أو الاستعلام عنها. بعض الأدوات قد تسمح بالكتابة أيضًا، لذلك تحتاج إلى حدود واضحة.
هذا تفسير مبسّط مبني على وصف الناشر. أبقينا الوصف الإنجليزي بجانبه حتى تستطيع مقارنة المعنى بالمصدر.
لا تضفه لمجرد التجربة إذا كان لديك طريق أبسط داخل Hermes، أو إذا لم تستطع مراجعة المصدر والصلاحيات.
مناسب لمن يريد طريقة عمل قابلة للتكرار داخل Hermes.
استخدم قاعدة بيانات تجريبية وحساب قراءة فقط، ثم اطلب استعلامًا بسيطًا لا يغيّر أي سجل.
Airtable REST API via curl
فُهرس هذا الإدخال من Hermes Bundled Skills. الشرح العربي يفسّر النوع والمجال ولا يضيف وظيفة غير مذكورة في المصدر.
المصدر رسمي أو خضع لمراجعة تحريرية، لكن ذلك لا يغني عن مراجعة الصلاحيات والإصدار.
افحص، ثبّت، ثم اختبر.
- 01افتح المصدر
طابق اسم الناشر والرخصة والوصف مع حاجتك، وراجع آخر تحديث فعلي.
- 02راجع الصلاحيات والأسرار
لا تلصق قيمة سر داخل الموقع. استخدم أسماء متغيرات البيئة وامنح أقل نطاق ممكن.
- 03انسخ الإعداد فقط بعد المراجعة
الأزرار أدناه تنسخ نصًا إلى الحافظة ولا تشغّل أمرًا على جهازك.
- 04اختبر بمهمة غير حساسة
تحقق من الأدوات الظاهرة، ثم استبعد أدوات الكتابة أو الحذف التي لا تحتاجها.
مثبّتة مسبقًا مع Hermes.
تأتي هذه المهارة مع Hermes وتُحمَّل عندما يرى الوكيل أنها مناسبة. لا شيء لتثبيته؛ اقرأ التعريف أدناه لتعرف ما ستفعله.
افتح الصفحة الرسمية ↗ما الذي يحمّله Hermes بالضبط عند تشغيل هذه المهارة.
منقول من التوثيق الرسمي. اقرأه قبل تفعيل المهارة، فهذا النص يصبح تعليمات الوكيل نفسه.
Airtable REST API via curl. Records CRUD, filters, upserts.
Skill metadata
جدول مرجعي. لا تقرأه كله، ابحث عن السطر الذي يخصّك فقط.
| Source | Bundled (installed by default) |
| Path | skills/productivity/airtable |
| Version | 1.1.0 |
| Author | community |
| License | MIT |
| Platforms | linux, macos, windows |
| Tags | Airtable, Productivity, Database, API |
Reference: full SKILL.md
شرح للفكرة نفسها. اقرأه ببطء، فبقية الأقسام تبني عليه.
Work with Airtable's REST API directly via curl using the terminal tool. No MCP server, no OAuth flow, no Python SDK — just curl and a personal access token.
Prerequisites
إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. الأوامر هنا: hermes setup. تضبط AIRTABLE_API_KEY خارج المحادثة، في بيئة التشغيل.
- Create a Personal Access Token (PAT) at https://airtable.com/create/tokens (tokens start with
pat...). - Grant these scopes (minimum):
data.records:read— read rowsdata.records:write— create / update / delete rowsschema.bases:read— list bases and tables- Important: in the same token UI, add each base you want to access to the token's Access list. PATs are scoped per-base — a valid token on the wrong base returns
403. - Store the token in
${HERMES_HOME:-~/.hermes}/.env(or viahermes setup):
AIRTABLE_API_KEY=pat_your_token_hereNote: legacy key... API keys were deprecated Feb 2024. Only PATs and OAuth tokens work now.API Basics
إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط BASE_ID، AIRTABLE_API_KEY خارج المحادثة، في بيئة التشغيل.
- Endpoint:
https://api.airtable.com/v0 - Auth header:
Authorization: Bearer $AIRTABLE_API_KEY - All requests use JSON (
Content-Type: application/jsonfor any POST/PATCH/PUT body). - Object IDs: bases
app..., tablestbl..., recordsrec..., fieldsfld.... IDs never change; names can. Prefer IDs in automations. - Rate limit: 5 requests/sec/base.
429→ back off. Burst on a single base will be throttled.
Base curl pattern:
curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?maxRecords=5" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.tool-s suppresses curl's progress bar — keep it set for every call so the tool output stays clean for Hermes. Pipe through python3 -m json.tool (always present) or jq (if installed) for readable JSON.
Field Types (request body shapes)
جدول مرجعي. لا تقرأه كله، ابحث عن السطر الذي يخصّك فقط.
| Field type | Write shape |
|---|---|
| Single line text | "Name": "hello" |
| Long text | "Notes": "multinline" |
| Number | "Score": 42 |
| Checkbox | "Done": true |
| Single select | "Status": "Todo" (name must already exist unless typecast: true) |
| Multi-select | "Tags": ["urgent", "bug"] |
| Date | "Due": "2026-04-01" |
| DateTime (UTC) | "At": "2026-04-01T14:30:00.000Z" |
| URL / Email / Phone | "Link": "https://…" |
| Attachment | "Files": [{"url": "https://…"}] (Airtable fetches + rehosts) |
| Linked record | "Owner": ["recXXXXXXXXXXXXXX"] (array of record IDs) |
| User | "AssignedTo": {"id": "usrXXXXXXXXXXXXXX"} |
Pass "typecast": true at the top level of a create/update body to let Airtable auto-coerce values (e.g. create a new select option on the fly, convert "42" → 42).
Common Queries
إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط AIRTABLE_API_KEY، BASE_ID خارج المحادثة، في بيئة التشغيل.
List bases the token can see
curl -s "https://api.airtable.com/v0/meta/bases" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolList tables + schema for a base
curl -s "https://api.airtable.com/v0/meta/bases/$BASE_ID/tables" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolUse this BEFORE mutating — confirms exact field names and IDs, surfaces options.choices for select fields, and shows primary-field names.
List records (first 10)
curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?maxRecords=10" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolGet a single record
curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolFilter records (filterByFormula)
Airtable formulas must be URL-encoded. Let Python stdlib do it — never hand-encode:
FORMULA="{Status}='Todo'"
ENC=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$FORMULA")
curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?filterByFormula=$ENC&maxRecords=20" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolUseful formula patterns:
- Exact match:
{Email}='user@example.com' - Contains:
FIND('bug', LOWER({Title})) - Multiple conditions:
AND({Status}='Todo', {Priority}='High') - Or:
OR({Owner}='alice', {Owner}='bob') - Not empty:
NOT({Assignee}='') - Date comparison:
IS_AFTER({Due}, TODAY())
Sort + select specific fields
curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?sort%5B0%5D%5Bfield%5D=Priority&sort%5B0%5D%5Bdirection%5D=asc&fields%5B%5D=Name&fields%5B%5D=Status" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolSquare brackets in query params MUST be URL-encoded (%5B / %5D).
Use a named view
curl -s "https://api.airtable.com/v0/$BASE_ID/$TABLE?view=Grid%20view&maxRecords=50" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolViews apply their saved filter + sort server-side.
Common Mutations
إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط BASE_ID، AIRTABLE_API_KEY خارج المحادثة، في بيئة التشغيل.
Create a record
curl -s -X POST "https://api.airtable.com/v0/$BASE_ID/$TABLE" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fields":{"Name":"New task","Status":"Todo","Priority":"High"}}' | python3 -m json.toolCreate up to 10 records in one call
curl -s -X POST "https://api.airtable.com/v0/$BASE_ID/$TABLE" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"typecast": true,
"records": [
{"fields": {"Name": "Task A", "Status": "Todo"}},
{"fields": {"Name": "Task B", "Status": "In progress"}}
]
}' | python3 -m json.toolBatch endpoints are capped at 10 records per request. For larger inserts, loop in batches of 10 with a short sleep to respect 5 req/sec/base.
Update a record (PATCH — merges, preserves unchanged fields)
curl -s -X PATCH "https://api.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"fields":{"Status":"Done"}}' | python3 -m json.toolUpsert by a merge field (no ID needed)
curl -s -X PATCH "https://api.airtable.com/v0/$BASE_ID/$TABLE" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"performUpsert": {"fieldsToMergeOn": ["Email"]},
"records": [
{"fields": {"Email": "user@example.com", "Status": "Active"}}
]
}' | python3 -m json.toolperformUpsert creates records whose merge-field values are new, patches records whose merge-field values already exist. Great for idempotent syncs.
Delete a record
curl -s -X DELETE "https://api.airtable.com/v0/$BASE_ID/$TABLE/$RECORD_ID" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolDelete up to 10 records in one call
curl -s -X DELETE "https://api.airtable.com/v0/$BASE_ID/$TABLE?records%5B%5D=rec1&records%5B%5D=rec2" \
-H "Authorization: Bearer $AIRTABLE_API_KEY" | python3 -m json.toolPagination
إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط BASE_ID، AIRTABLE_API_KEY خارج المحادثة، في بيئة التشغيل.
List endpoints return at most 100 records per page. If the response includes "offset": "...", pass it back on the next call. Loop until the field is absent:
OFFSET=""
while :; do
URL="https://api.airtable.com/v0/$BASE_ID/$TABLE?pageSize=100"
[ -n "$OFFSET" ] && URL="$URL&offset=$OFFSET"
RESP=$(curl -s "$URL" -H "Authorization: Bearer $AIRTABLE_API_KEY")
echo "$RESP" | python3 -c 'import json,sys; d=json.load(sys.stdin); [print(r["id"], r["fields"].get("Name","")) for r in d["records"]]'
OFFSET=$(echo "$RESP" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("offset",""))')
[ -z "$OFFSET" ] && break
doneTypical Hermes Workflow
شرح للفكرة نفسها. اقرأه ببطء، فبقية الأقسام تبني عليه.
- Confirm auth.
curl -s -o /dev/null -w "%{http_code}\n" https://api.airtable.com/v0/meta/bases -H "Authorization: Bearer $AIRTABLE_API_KEY"— expect200. - Find the base. List bases (step above) OR ask the user for the
app...ID directly if the token lacksschema.bases:read. - Inspect the schema.
GET /v0/meta/bases/$BASE_ID/tables— cache the exact field names and primary-field name locally in the session before mutating anything. - Read before you write. For "update X where Y",
filterByFormulafirst to resolve therec...ID, thenPATCH /v0/$BASE_ID/$TABLE/$RECORD_ID. Never guess record IDs. - Batch writes. Combine related creates into one 10-record POST to stay under the 5 req/sec budget.
- Destructive ops. Deletions can't be undone via API. If the user says "delete all Xs", echo back the filter + record count and confirm before firing.
Pitfalls
إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط INVALID_MULTIPLE_CHOICE_OPTIONS خارج المحادثة، في بيئة التشغيل.
filterByFormulaMUST be URL-encoded. Field names with spaces or non-ASCII also need encoding ({My Field}→%7BMy%20Field%7D). Use Python stdlib (pattern above) — never hand-escape.- Empty fields are omitted from responses. A missing
"Assignee"key doesn't mean the field doesn't exist — it means this record's value is empty. Check the schema (step 3) before concluding a field is missing. - PATCH vs PUT.
PATCHmerges supplied fields into the record.PUTreplaces the record entirely and clears any field you didn't include. Default toPATCH. - Single-select options must exist. Writing
"Status": "Shipping"whenShippingisn't in the field's option list errors withINVALID_MULTIPLE_CHOICE_OPTIONSunless you pass"typecast": true(which auto-creates the option). - Per-base token scoping. A
403on one base while another works means the token's Access list doesn't include that base — not a scope or auth issue. Send the user to https://airtable.com/create/tokens to grant it. - Rate limits are per base, not per token. 5 req/sec on
baseAand 5 req/sec onbaseBis fine; 6 req/sec onbaseAalone will throttle. Monitor theRetry-Afterheader on429.
Important Notes for Hermes
إعدادات تضبطها مرة وتنساها. غيّر واحدًا في كل مرة حتى تعرف أثر كل تغيير. تضبط AIRTABLE_API_KEY، AUTHENTICATION_REQUIRED خارج المحادثة، في بيئة التشغيل.
- Always use the
terminaltool withcurl. Do NOT useweb_extract(it can't send auth headers) orbrowser_navigate(needs UI auth and is slow). AIRTABLE_API_KEYflows from${HERMES_HOME:-~/.hermes}/.envinto the subprocess automatically when this skill is loaded — no need to re-export it before eachcurlcall.- Escape curly braces in formulas carefully. In a heredoc body,
{Status}is literal. In a shell argument,{Status}is safe outside{...}brace-expansion context — but pass dynamic strings throughpython3 urllib.parse.quotebefore splicing into a URL. - Pretty-print with
python3 -m json.tool(always present) rather thanjq(optional). Only reach forjqwhen you need filtering/projection. - Pagination is per-page, not global. Airtable's 100-record cap is a hard limit; there is no way to bump it. Loop with
offsetuntil the field is absent. - Read the
errorsarray on non-2xx responses — Airtable returns structured error codes likeAUTHENTICATION_REQUIRED,INVALID_PERMISSIONS,MODEL_ID_NOT_FOUND,INVALID_MULTIPLE_CHOICE_OPTIONSthat tell you exactly what's wrong.