Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
spillwavesolutions avatar

Automating Contacts

  • 19 installs
  • 39 repo stars
  • Updated January 14, 2026
  • spillwavesolutions/automating-mac-apps-plugin

Helps with ai & agent building tasks during AI-assisted development.

About

automating-contacts is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.

  • automating-contacts
  • AI & Agent Building
  • AI-coding skill

Automating Contacts by the numbers

  • 19 all-time installs (skills.sh)
  • Ranked #10,571 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/spillwavesolutions/automating-mac-apps-plugin --skill automating-contacts

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs19
repo stars39
Last updatedJanuary 14, 2026
Repositoryspillwavesolutions/automating-mac-apps-plugin

What it does

Helps with ai & agent building tasks during AI-assisted development.

Files

SKILL.mdMarkdownGitHub ↗

Automating Contacts (JXA-first, AppleScript discovery)

Relationship to Other Skills

  • Standalone for Contacts: Use this skill for Contacts-specific operations (querying, CRUD, groups).
  • Reuse `automating-mac-apps` for: TCC permissions setup, shell command helpers, UI scripting fallbacks, and ObjC bridge patterns.
  • Integration: Load both skills when combining Contacts automation with broader macOS scripting.
  • PyXA Installation: To use PyXA examples in this skill, see the installation instructions in automating-mac-apps skill (PyXA Installation section).

Core Framing

  • Contacts dictionary is AppleScript-first; discover there, implement in JXA
  • Object specifiers: read with methods (name(), emails()), write with assignments
  • Multi-value fields (emails, phones, addresses) are elements; use constructor + .push()
  • Group membership: add ... to command or .people.push; handle duplicates defensively
  • TCC permissions required: running host must have Contacts access

Workflow (default)

1) Inspect the Contacts dictionary in Script Editor (JavaScript view). 2) Prototype minimal AppleScript to validate verbs; port to JXA with specifier reads/writes. 3) Use .whose for coarse filtering; fall back to hybrid (coarse filter + JS refine) when needed. 4) Create records with proxy + make, then assign primitives and push multi-values; Contacts.save() to persist. 5) Verify persistence: check person.id() exists after save; handle TCC permission errors. 6) Manage groups after person creation; guard against duplicate membership with existence checks. 7) For photos or broken bridges, use ObjC/clipboard fallback; for heavy queries, batch read or pre-filter. 8) Test operations: run→check results→fix errors in iterative loop.

Validation Checklist

  • [ ] Contacts permissions granted (System Settings > Privacy & Security > Contacts)
  • [ ] Dictionary inspected and verbs validated in Script Editor
  • [ ] AppleScript prototype runs without errors
  • [ ] JXA port handles specifiers correctly
  • [ ] Multi-value fields pushed to arrays properly
  • [ ] Groups existence checked before creation
  • [ ] Operations saved and verified with .id() checks
  • [ ] Error handling wraps all operations

Quickstart (upsert + group)

const Contacts = Application("Contacts");
const email = "ada@example.com";
try {
  const existing = Contacts.people.whose({ emails: { value: { _equals: email } } })();
  const person = existing.length ? existing[0] : Contacts.Person().make();
  person.firstName = "Ada";
  person.lastName = "Lovelace";
  
  // Handle multi-value email
  const work = Contacts.Email({ label: "Work", value: email });
  person.emails.push(work);
  Contacts.save();
  
  // Handle groups with error checking
  let grp;
  try { 
    grp = Contacts.groups.byName("VIP"); 
    grp.name(); // Verify exists
  } catch (e) {
    grp = Contacts.Group().make(); 
    grp.name = "VIP";
  }
  Contacts.add(person, { to: grp });
  Contacts.save();
  console.log("Contact upserted successfully");
} catch (error) {
  console.error("Contacts operation failed:", error);
}

Pitfalls

  • TCC Permissions: Photos/attachments require TCC + Accessibility; use clipboard fallback if blocked
  • Yearless birthdays: Not cleanly scriptable; use full dates
  • Advanced triggers: Delegate geofencing to Shortcuts app
  • Heavy queries: Batch read or pre-filter to avoid timeouts

When Not to Use

  • Non-macOS platforms (use platform-specific APIs)
  • Simple AppleScript-only solutions (skip JXA complexity)
  • iCloud sync operations (use native Contacts framework)
  • User-facing apps (use native Contacts framework)
  • Cross-platform contact management (use CardDAV or vCard APIs)

What to load

  • JXA basics & specifiers: automating-contacts/references/contacts-basics.md
  • Recipes (query, create, multi-values, groups): automating-contacts/references/contacts-recipes.md
  • Advanced (hybrid filters, clipboard image, TCC, date pitfalls): automating-contacts/references/contacts-advanced.md
  • Dictionary & type map: automating-contacts/references/contacts-dictionary.md
  • PyXA API Reference (complete class/method docs): automating-contacts/references/contacts-pyxa-api-reference.md

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.