Skip to content
Start free trial

Claude Code Skill

Install the HARi skill in Claude Code and manage your entire CRM through conversation. Create contacts, build pipelines, send emails, configure automations — Claude knows the full API.

Download Skill v1.23.0

Size: 44 KB · Released: 5 May 2026

9 reference files covering every part of the HARi API. Claude loads only what’s needed per conversation.

FileCovers
SKILL.mdMain entry point — auth, routing, safety gates, core rules
records.mdCRUD operations, filtering, search, restore, purge, audit log
schema.mdEntities, fields (25 types), relations, solutions
workflows.mdAutomation, pipelines, views, process templates, scoring
communications.mdEmail, inbox, mailboxes, templates, snippets, embed forms
dashboards.mdCharts, goals, activity feed, data hygiene, notifications
ai.mdAI enrichment, AI search, chat, next actions, recap
admin.mdUsers, API keys, webhooks, integrations, GDPR, billing
advisory.mdGuided setup, gap analysis, UI navigation, user-level detection

Click the download button above, or use the terminal:

Terminal window
curl -L https://haricrm.com/downloads/hari-claude-skill.zip -o hari-skill.zip

Unzip into the .claude/skills/hari/ folder at the root of your project. Claude Code discovers skills in this directory automatically.

Terminal window
# Navigate to your project root
cd ~/my-project
# Create the skills directory and extract
mkdir -p .claude/skills/hari
unzip hari-skill.zip -d .claude/skills/hari/

Your project should look like this:

my-project/
├── .claude/
│ └── skills/
│ └── hari/ ← skill lives here
│ ├── SKILL.md
│ ├── records.md
│ ├── schema.md
│ ├── advisory.md
│ └── ... (9 files total)
├── src/
└── ...

Open Claude Code in your project and type /hari to invoke the skill directly, or just ask Claude anything about your CRM data — it will activate automatically.

$ claude
> List my top 10 contacts by deal value
Reading .claude/skills/hari/SKILL.md...
Reading .claude/skills/hari/records.md...
Here are your top 10 contacts:
1. Sarah Chen — HK$450,000 (3 opportunities)
2. James Wong — HK$380,000 (2 opportunities)
3. ...
CategoryExample prompts
Manage records”Create a contact for Alice at Acme Corp”, “Show me all open deals above HK$100k”
Build your data model”I need to track projects with tasks”, “Add a money field for budget”
Set up automations”When a deal reaches Proposal stage, notify the manager”
Email & templates”Send a follow-up to all contacts I met last week”, “Create a PDF quote template”
Dashboards”Show me pipeline value by stage”, “How many new contacts this month?”
AI enrichment”Enrich this company with AI”, “Fill in missing data for all new contacts”
  • Claude Code — Available as CLI, desktop app, or IDE extension. Get Claude Code
  • A HARi CRM account — The skill needs your credentials or API key. Start free trial
  • Inline campaign filter source (type: 'inline_filter') — campaigns can now reference a filter directly on the campaign instead of requiring a saved view round-trip. The skill documents the new shape, the one-hop relation filter syntax (<relation_name>.<column> where <relation_name> comes from _meta_relation.name — NOT the related entity name and NOT the FK column), the email_fields array for multi-email-field expansion (one candidate per row × email field), and the first-source-wins attribution rule. Cross-source / cross-entity dedup is automatic via the existing _campaign_send_log UNIQUE(campaign_id, lower(email)) constraint — same email shared between a contact and a company source ships exactly once.
  • Campaign recipient inspection (GET /api/email/campaigns/{id}/recipients)communications.md now documents the new paginated send-log endpoint. Returns _campaign_send_log rows with full pagination {page, limit, total, pages} and a status_counts block (sent / pending / sending / failed / cancelled / bounced / opened / clicked / unsubscribed) computed across the whole campaign — not just the visible page — so the campaign UI can render tab badges in a single round-trip. Optional ?status= filter narrows the rows on the page only; counts stay stable. AI-readable, so Claude can answer questions like “who actually got the THINKDROP 39 send?” without guessing from the top-level recipient_count aggregate.
  • Campaign reopen (POST /api/email/campaigns/{id}/reopen) — admin-only revive endpoint for campaigns that ended up in a terminal cancelled or failed state. Flips the campaign back to draft AND wipes its _campaign_send_log rows so the recipient list re-resolves on the next send (Layer-1 gates — blocklist, unsubscribe, dedup — fire on fresh data, not stale snapshots from the failed run). Returns 200 {reopened, status}, 409 if the campaign is not in a terminal state, 404 if not found. The skill marks it AI-cannot-call — users trigger it from the campaign UI’s “Reopen as draft” button.
  • Campaign abort endpoint documentedcommunications.md now documents the new admin-only POST /api/email/campaigns/{id}/abort for stopping a campaign that’s currently in sending status. Closes the gap where neither DELETE (drafts only) nor cancel-schedule (scheduled only) could halt an in-flight send. The skill marks the endpoint as AI-cannot-call — admins trigger it from the Campaigns UI (“Abort campaign” button on rows in sending status). Returns 200 {aborted, status, cancelled_recipients, preserved_sent} on success, 409 if not in sending, 404 if not found.
  • Tool denial protocol — when the platform’s AI gates (capability allowlist, rate limit, recipient visibility check, loop detector, AI freeze) reject a tool call, the skill now instructs the AI Assistant to surface the structured denial message + remediation directly to the user instead of retrying. Defense-in-depth alongside the C-07 + C-22 + C-23 + C-26 server gates: code remains the primary boundary, but the skill makes friendly cooperation the default. The denial bubble in the in-app AI chat now deep-links to the relevant /settings/ai-permissions#capability-{name} anchor so admins can fix the underlying permission with one click.
  • Email send caution — the new “Email send caution” section in communications.md codifies the per-user rate limits (2/hour, 5/day, 10/week) and reinforces the existing rule against looping compose over recipient lists (use the campaign pipeline instead). Documents the structured 429 rate_limited and 403 capability_denied responses so the AI knows exactly what to say to the user when blocked.
  • Lead entity retired in favour of contact.lifecycle_stage — DECIDE-05 ruled that the historical split between Lead and Contact creates more friction than value for SMEs. The lead entity is no longer in fresh-install schemas; existing tenants migrate via bin/migrate-lead-to-contact.php (per-tenant CLI, opt-in during a maintenance window). Prospects now live on contact with the new lifecycle_stage select field — values lead, qualified, customer, lost. The skill’s records.md opens with a v1.19.0 banner explaining the change so Claude doesn’t try to query a lead entity that no longer exists. Common queries that used to filter entity=lead should now filter entity=contact with ?filter=lifecycle_stage,eq,lead (or ?filter=lifecycle_stage,in,lead,qualified for the broader sales-pipeline view). The “Active Leads” view that ships with fresh CRM installs is entity=contact with that filter pre-applied.
  • Compose vs campaign — decision tree added to the skillcommunications.md now opens with a mandatory decision tree distinguishing 1-to-1 transactional sends (POST /api/email/compose) from bulk/marketing sends (campaign pipeline: POST /api/email/campaigns then /{id}/send). Looping compose over a list is now explicitly called out as forbidden — it bypassed opt-out enforcement, deduplication, and campaign counters, and on one customer tenant this produced 432 untracked sends with the campaign UI showing 0/432. The skill now points Claude at the right endpoint before the send happens.
  • Campaign pipeline endpoints documented for the first time — previous versions of the skill only mentioned compose. The new section covers draft creation, recipient preview, async send, progress polling, statistics, exclusions, test sends, spam-check, and the associated subscription-list / blocklist / sending-domain admin endpoints.
  • Server-side enforcement (landing with this release) — compose now rejects sends to blocklisted or globally-unsubscribed recipients, throttles bulk bursts with 429 compose_burst, and honors the Idempotency-Key header (24 h window). The skill documents these so Claude knows how to recover from a throttle without retrying against the brick wall.
  • send_email workflow action — server-side template rendering — supplying a template_id now renders the saved template body on the server side (fixes a silent empty-body bug where template_id alone produced emails with no content). Three valid shapes are now documented: inline HTML, template render (with optional variables), and template override (body_html wins).
  • workflows.md corrected — the misleading { "type": "send_email", "template_id": "<uuid>" } example has been fixed to include the required to field, and a new contract block documents all three valid shapes explicitly.
  • Silent version-check at session start — the skill now fetches https://haricrm.com/downloads/hari-claude-skill-version.json on its first call of a conversation and informs the user once if a newer version is available. Fully silent on network errors; never blocks API work.
  • Entity sort_order and batch reorder API — new PUT /api/schema/entities/reorder endpoint accepts an ordered array of entity names and sets sort_order on each. Entities are now displayed in sidebar and schema lists by sort_order ASC, name ASC. Individual entities can also be updated via PUT /api/schema/entities/{name} with sort_order field.
  • Comprehensive solution export/import documentation — the Solutions section in schema.md is now a full operational guide: what gets exported (entities, fields, relations, forms, views, BPFs, workflows, charts, templates, seed data), step-by-step cross-tenant migration workflow (export → ZIP → import), what happens during import (new entities created, existing entity/field metadata updated, dependencies auto-detected), version management (semver, upgrade vs downgrade), and troubleshooting table for common errors. Previously the section only listed endpoint names without explaining the workflow or edge cases.
  • New field type secret — stores TEXT, renders masked in edit (password input + Eye/EyeOff reveal toggle) and display (fixed 9-dot mask + Show/Copy buttons with 2s confirmation). Not encrypted — presentational mask only. For API keys, tokens, passwords that a user types into a record.
  • Field display style picker (options.display_style) — Schema Editor UI now writes a per-field style key that the renderer resolves in order options.widgetoptions.display_style → default. Options: selectdropdown / cards / pipeline / radio, multiselectcheckboxes / chip_grid / tags, percentnumber / progress_bar, booleancheckbox / toggle. Ships CardSelectField wired to the cards key; radio and toggle widgets fall through to defaults until the widget pairs are added.
  • Visible-when condition builder — Form Editor gets an Eye/EyeOff icon on every tab row and section header. Inline builder: field picker → operator → value. 10 operators: eq, neq, gt, lt, gte, lte, contains, not_contains, is_null, is_not_null. Numeric operators wrap both operands with Number() and return false when either side is NaN — so rules work correctly even when form values arrive as strings. in/nin remain valid in stored JSONB but aren’t yet exposed in the builder UI.
  • Formula field editing in the Schema Editortype: 'formula' fields now show a dedicated formula textarea plus a format picker (currency / percent / integer / text) next to the existing relation-context picker. Stored as options.formula + options.formula_format. No more hand-editing the JSON options blob.
  • Two new built-in sidebar components layered on the v1.10.0 sidebar DSL:
    • ActivityTimeline — condensed 3–5 item vertical timeline of the record’s most recent activity entries (coloured dot + summary + relative timestamp). Clamped limit 1–10.
    • RelatedRecordsList — inline list of records from a child entity filtered by FK, with count badge and “View all” link when truncated. Props: entity_name, relation, limit, display_field.
  • Record page right sidebar — forms can now declare a layout.sidebar block with ordered cells[] (bare field name, {type:"field"}, {type:"heading"}, {type:"spacer"}, {type:"component"}). Built-in sidebar component KeyFacts renders a compact read-only label/value stack reusing the same display components as the main form (colored pills, currency formatting, relation links). Width is clamped 240–360 px (default 280). Desktop-only; mobile falls back to single column.
  • Relation-aware formula fields — formulas can now reach beyond the current record’s scalars. Declare options.formula_context: ["transactions"] and reference related records directly: sum(pluck(where(transactions, 'deal_stage', 'eq', 'closed'), 'prix_bien')). Works for both belongs_to relations (exposed as an associative array — company.name) and reverse has_many (exposed as a list). Naive plural matching accepts transaction, transactions, transactiones. Backend batches one query per relation per list/get call — never N+1.
  • Collection helpers in formulas — new read-only functions in Symfony ExpressionLanguage: count, sum, min, max, avg, first, last, pluck(arr, field), where(arr, field, op, value) with ops eq · neq · gt · gte · lt · lte · in · nin · is_null · is_not_null · contains, plus today_minus_days(n) for date-range comparisons. Safety caps: max expression length 2000 chars, max related rows 5000 per relation, related records filtered to _state = 0.
  • Rewritten formulas referencedocs/reference/field-types.md §4 now matches the actual engine (Symfony ExpressionLanguage, bare field-name identifiers, no curly braces), documents collection helpers, relation-context syntax, safety limits, and known gaps (no reactive preview, no dependency-ordering between formulas, no writable computed values, no irregular-plural matching).
  • Section title size — sections now accept a label_size property (100 / 125 / 150 / 175 / 200) that scales the section label as a percentage of the default 12px. Configurable visually in the Form Editor alongside colour / icon / collapse / divider.
  • Comprehensive Form Layouts referenceschema.md rewritten with a full section-presentation reference table, brand-aligned colour palette, complete lucide icon list, field-entry formats (subgrids, components, spacers), full-layout PUT pattern for updates, and per-user personalisation flow. Claude sessions can now drive the Form Editor end-to-end from the skill without external context.
  • Section dividers — sections now accept a divider property ("none", "line", "thick") that renders a visible separator above the section on the record page. Thick dividers are tinted with the section’s colour when one is set. Configurable visually from the Form Editor.
  • Form layouts — documented the complete endpoint set (GET/POST /api/schema/entities/{entity}/forms, PUT /api/schema/forms/{id}, per-user personalization) so Claude can create and update detail/create/quick_view forms directly.
  • Section presentation metadata — sections now accept optional color (hex left-border accent), icon (lucide name), and collapsed (absent = not collapsible; present = click-to-toggle). Documented supported icon set and validation rules.
  • header_image_field on entities — documented how to pin an image/file field as the hero thumbnail on the record detail page. Validation: referenced field must exist and be of type image or file.
  • Entity update endpoint — corrected from PATCH to PUT /api/schema/entities/{name} and expanded the body spec.
  • Phone field country code selector — phone fields on embed forms now show a dropdown with 19 country codes (flag + dial code). Default auto-detected from browser locale. Configurable per field via options.default_country_code.
  • Embed form field-level validation errors — submissions now return per-field error details instead of a generic message. Frontend shows inline errors with red highlighting.
  • Embed form field type docs — documented all field type rendering behaviors (phone, select, email, boolean, textarea) and validation error response format.
  • Schema field types cleaned up — removed internal DB column types from skill reference, replaced with API-relevant behavior notes.
  • Added version field to SKILL.md frontmatter for tracking.
  • Find-or-Create patternfor_each now supports else_actions for zero-match branching
  • New update_trigger action — write back to the triggering record from inside for_each
  • create_record now returns the new ID, chainable via {{last_created_id}}
  • New placeholder namespaces: {{trigger.field}}, {{item.field}} inside for_each
  • Complete action types reference with JSON schemas and recipes
  • Fixed for_each placeholder resolution (sub-actions now resolve against iterated row)
  • Added 25 field types including money/multi-currency support
  • Added UI navigation discovery (API-first, never hardcoded)
  • Added currency settings and exchange rate endpoints
  • Improved advisory with disambiguation for ambiguous terms
  • Added communication safety gate for outbound actions
  • Added solution gate for schema changes
  • Added embed forms and OAuth endpoints
  • Initial release with full CRUD, schema, workflows, AI, dashboards