frappe-agent-architect
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing cross-app communication…
Use when writing Python code for ERPNext/Frappe Server Scripts including Document Events, API endpoints, Scheduler Events, and Permission Queries. Prevents the #1 AI mistake: using import statements in Server Scripts (sandbox blocks ALL imports). Covers frappe.* methods, event
$ npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-serverscripts --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/frappe-syntax-serverscriptsContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when writing Python code for ERPNext/Frappe Server Scripts including Document Events, API endpoints, Scheduler Events, and Permission Queries. Prevents the #1 AI mistake: using import statements in Server Scripts (sandbox blocks ALL imports). Covers frappe.* methods, event
name: frappe-syntax-serverscripts description: > Use when writing Python code for ERPNext/Frappe Server Scripts including Document Events, API endpoints, Scheduler Events, and Permission Queries. Prevents the #1 AI mistake: using import statements in Server Scripts (sandbox blocks ALL imports). Covers frappe.* methods, event name mapping, and correct v14/v15/v16 syntax. Keywords: Server Script, frappe, ERPNext, sandbox, import, doc event, validate, on_submit, before_save, server script example, import not allowed, sandbox rules, which script type to use. license: MIT compatibility: "Claude Code, Claude.ai Projects, Claude API. Frappe v14-v16." metadata: author: OpenAEC-Foundation version: "2.0"
Server Scripts are Python scripts managed via **Setup > Server Script** in the Frappe/ERPNext UI. They run inside a **RestrictedPython sandbox**.
┌──────────────────────────────────────────────────────────────────┐ │ ALL import STATEMENTS ARE BLOCKED │ │ │ │ import json → ImportError: __import__ not found │ │ from datetime import * → ImportError: __import__ not found │ │ import frappe → ImportError (even frappe itself!) │ │ │ │ EVERYTHING you need is pre-loaded in the frappe namespace. │ │ NEVER write an import line. ALWAYS use frappe.utils.*, etc. │ └──────────────────────────────────────────────────────────────────┘
**ALWAYS** use the pre-loaded namespace instead of imports:
| Blocked import | Use instead | |---|---| | `import json` | `frappe.parse_json()` / `frappe.as_json()` | | `from datetime import date` | `frappe.utils.today()` / `frappe.utils.now_datetime()` | | `from frappe.utils import cint` | `frappe.utils.cint()` (already loaded) | | `import requests` | `frappe.make_get_request()` / `frappe.make_post_request()` | | `import re` | Not available — restructure logic without regex | | `import os` / `import sys` | Not available — use a custom app instead |
# v14: enabled by default # v15+: DISABLED by default — you MUST enable explicitly: bench set-config -g server_script_enabled 1 # Or set server_script_enabled: true in site_config.json
**NEVER** expect Server Scripts to work on Frappe Cloud shared benches — they require a private bench.
| Type | Trigger | Key Variable | |---|---|---| | **Document Event** | Document lifecycle (save, submit, cancel) | `doc` | | **API** | HTTP request to `/api/method/{name}` | `frappe.form_dict` | | **Scheduler Event** | Cron schedule | (none) | | **Permission Query** | Document list filtering | `user`, `conditions` |
**CRITICAL**: The UI names differ from internal hook names:
| Server Script UI | Internal Hook | Fires When | |---|---|---| | Before Insert | `before_insert` | Before new doc saved to DB | | After Insert | `after_insert` | After first DB insert | | Before Validate | `before_validate` | Before framework validation | | **Before Save** | **`validate`** | Before save (new + update) | | After Save | `on_update` | After successful save | | Before Submit | `before_submit` | Before submit (docstatus 0→1) | | After Submit | `on_submit` | After submit completes | | Before Cancel | `before_cancel` | Before cancel (docstatus 1→2) | | After Cancel | `on_cancel` | After cancel completes | | Before Delete | `on_trash` | Before permanent delete | | After Delete | `after_delete` | After permanent delete |
**NEVER** confuse "Before Save" with `before_save` — the UI label "Before Save" maps to the `validate` hook. The actual `before_save` hook runs AFTER `validate`.
Need custom Python logic for a DocType?
│
├─► Can you install a custom Frappe app?
│ ├─► YES: Use a Document Controller when you need:
│ │ • import statements (any Python library)
│ │ • File system access
│ │ • Complex class inheritance
│ │ • autoname / before_naming hooks
│ │ • Unit-testable code
│ │
│ └─► NO: Use a Server Script when:
│ • You only have UI access (no bench CLI)
│ • Logic is simple validation / field calculation
│ • You need a quick API endpoint
│ • You need dynamic permission filtering
│
└─► Is logic > 50 lines or needs external libraries?
├─► YES → Document Controller in a custom app
└─► NO → Server Script is finedoc # Current document (Document Event only) frappe # Core namespace — ALWAYS available frappe.db # Database operations frappe.utils # Date, number, string utilities frappe.session # Current session (user, csrf_token) frappe.form_dict # Request parameters (API scripts) frappe.response # Response object (API scripts) frappe.request # Werkzeug request object frappe.qb # Query Builder (v14+) json # Python json module (pre-loaded)
# Documents frappe.get_doc(doctype, name) # Fetch document frappe.new_doc(doctype) # Create new document frappe.get_cached_doc(doctype, name) # Cached fetch (read-only) frappe.get_last_doc(doctype) # Most recent document frappe.get_mapped_doc(...) # Map fields between DocTypes frappe.delete_doc(doctype, name) # Delete document frappe.rename_doc(doctype, old, new) # Rename document # Querying frappe.get_all(doctype, filters, fields, order_by, limit) # No permission check frappe.get_list(doctype, filters, fields, order_by, limit) # With permission check frappe.db.get_value
60 deterministic Claude AI skills for Frappe Framework & ERPNext v14-v16 development and operations
Repo: Impertio-Studio/Frappe_Claude_Skill_Package
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing cross-app communication…
Use when debugging Frappe errors, using bench console for live inspection, analyzing tracebacks, or reading Frappe log files. Prevents wasted debugging time…
Use when receiving vague or unclear ERPNext/Frappe development requests that need interpretation. Transforms requirements like 'make invoice auto-calculate' or…
Use when migrating a Frappe app between major versions, detecting breaking API changes, or resolving post-migration errors. Prevents failed migrations from…
Use when reviewing or validating Frappe/ERPNext code against best practices and common pitfalls. Checks generated code before deployment, validates against all…
Use when building ERPNext/Frappe API integrations (v14/v15/v16) including REST API, RPC API, authentication, webhooks, and rate limiting. Covers external API…