Externa Core 1.4.0 — MCP, AI approvals, and accessibility
Externa Core v1.4.0 opens Externa to external AI agents through an optional MCP server, puts human approval in front of every AI write, and continues the admin accessibility work toward WCAG 2.2 AA. The admin is rebuilt on shadcn/ui and AI Elements, and every assistant answer now shows its reasoning, tool calls and sources. It also adds theme presets, Google Cloud Storage and Azure Blob file disks, and new Public API batch writes and filters. The MCP server and AI write tools are off by default. Notes will live at GitHub Release v1.4.0 · Changelog.
Who should upgrade
- Teams that want external AI agents and MCP clients to read (and, if you allow it, write) CMS content with the same permissions as the admin.
- Operators who need an audit trail and approval step before the assistant creates, changes, or deletes anything.
- Self-hosters storing files on Google Cloud Storage or Azure Blob.
- Frontends that need batch item writes, filters on system columns or related items, and sorting in the Public API.
- Anyone on 1.3.0 with scoped API keys or private files: 1.4.0 fixes how the Files API lists private files on upgraded installs (#434).
What matters
A rebuilt admin and transparent AI answers
- Rebuilt on shadcn/ui and AI Elements: pickers, lists, forms, loaders, tables and both chats now use standard shadcn/ui components, so the admin looks and behaves the same everywhere, in light and dark (#517–#586).
- See how the assistant got its answer: each answer shows the model's reasoning (open while it thinks, then "Thought for N seconds"), every tool call as a plain sentence such as "List collections" with its state, the sources it cited, and the tokens it used. It all streams live and is shown again after a reload (#565 / #566 / #570 / #572 / #615 / #621).
- Clear approvals: a write the assistant wants to make waits on an approval card with the call in words; Approve turns red only when the call deletes data (#619).
- Reasoning you can tune: the assistant asks OpenAI, Anthropic and Gemini for medium reasoning effort. Set
OPENAI_REASONING_EFFORT,ANTHROPIC_REASONING_EFFORT,GEMINI_REASONING_EFFORTorLOCAL_AI_REASONING_EFFORT, pick the assistant's provider withAI_ASSISTANT_PROVIDER, and set the context size shown next to token usage with*_CONTEXT_WINDOW(#570). - Team chat: reactions show who reacted, names and mentions open a user card with role and online status, and reply quotes and pinned messages jump to the original. Files are attachment cards and photos fill their bubble (#575 / #576 / #578 / #582).
- Files: square cards, Drive-style: the preview fills the card edge to edge on the image's focal point, with one row below for the name, the tags (on hover) and a ⋮ menu. Folders look the same. You set the focal point by clicking the image in the details panel, and the crop of every transform follows it (#583 / #592 / #596).
- Admin lists: users, groups, roles, API keys, permissions, the activity log and jobs are server-driven tables with sorting, filters and row actions, and deletes ask for confirmation (#522 / #523–#537 / #561).
AI: MCP server and human approval
- Optional MCP server at
/mcp(laravel/mcp), off until you setAI_MCP_ENABLED. Clients authenticate with owned API keys that carrymcp:read/mcp:writescopes, and the server has its ownmcprate limiter. Write tools are only registered whenAI_MCP_WRITE_ENABLEDis also on. OAuth is not part of this release (#121). - Same permissions as chat: MCP tools and resources share one permission-aware tool registry with the in-app assistant. Collection, item, field and file permissions apply, plus the API key's collection scopes,
files_scopeandread_only(#202 / #435). - Human approval for AI writes: write and destructive tools are denied by default. Turn them on with the
AI_WRITE_TOOLSswitch and a per-tool allowlist; each write then needs approval. Chat asks before it acts. MCP writes wait in an admin inbox of pending tool calls for 15 minutes. Tool calls land in a redactedai_toolaudit log, pruned withphp artisan ai:prune-tool-audit(#203). - With AI writes off, chat keeps the read actions (list, get, search) of the
Manage*tools (#439). - A prompt-injection and denied-permission test suite covers chat and MCP (#204).
- Context attachments: attach items, files, and project-level saved prompts to a conversation. Access is checked again at send time (#195). On-demand Agent Skills give the assistant CMS playbooks (#181).
Admin, theming, and accessibility
- Theme presets: six built-in presets (qiick Teal by default, Blue, Indigo, Violet, Rose, Slate) with a live preview, plus an optional custom brand color (#243 / #437).
- Accessibility work toward WCAG 2.2 AA: focus restore on overlays, focus moves to the main content after navigation, live announcements, reduced-motion rules, landmarks, and translated labels (#252–#254). The focus ring keeps 3:1 contrast even when a custom brand color is low contrast (#453).
- Accessibility checks in CI:
eslint-plugin-jsx-a11y, axe smoke tests on key admin routes (a required check on code PRs), and a theme-token contrast check (npm run a11y:contrast) (#255). - Shared empty states, shadcn form fields with linked errors, and table, sidebar and button cleanups across the admin (#229–#241).
- Safe field conversion for fields that already hold content, with a dry-run preview and
externa:field-convert(#220). - Server-side flash and validation messages in German and Italian (#282).
Files and storage
- Google Cloud Storage (
FILES_DISK=gcs) and Azure Blob (FILES_DISK=azure) disks for the file manager, alongside local and S3 (#188). - Per-project upload allowlist for extensions and MIME types, with SVG as an opt-in. Executables, HTML and SSI stay blocked (#327).
- Per-key
files_scope(none/read/all) to keep scoped API keys out of the Files API (#322).
Public CMS API
- Batch create / update / delete at
/api/v1/collections/{slug}/items/batch, capped byAPI_MAX_BATCH_SIZE(default 100) (#125). - Filters on system columns (
id,created_at,updated_at,published_at) and on depth-1 relations, e.g.filter[author.name][_eq]=…, on SQLite, MySQL/MariaDB and PostgreSQL (#333 / #124 / #436). sorton system and sortable fields (#224), and the new@qiick/externa-sdkTypeScript client, version0.1.0(#119).
Publishing and integrations
- Deploy hooks for Vercel, Netlify, Cloudflare Pages and Forge, with an optional deploy on publish (#196).
- Live Preview "Preview at…" shows scheduled content as of a future date (#222).
Security
- Security headers (CSP,
X-Frame-Options,Referrer-Policy,Permissions-Policy) on admin responses, configurable inconfig/security.php(#187 / #440). - Secure-by-default fresh installs (registration off, auth throttles) (#272), timestamped webhook signatures (#273), stricter SSRF checks including OIDC (#274), and Docker workers running as
www-data(#320). - API keys can be bound to an owner, so access is the key role ∩ scopes ∩ the owner's permissions (#215).
Upgrade steps (from 1.3.x)
- Back up the database,
.env, and file storage. - Move code to
v1.4.0(git tag, Packagistqiick/externa-core:1.4.0, or the Docker imageghcr.io/qiick-io/externa-core:1.4.0). - Install and build:
composer install
npm ci && npm run build
php artisan externa:upgrade
# or: migrate --force && permissions:sync && optimize:clear
- Restart Horizon / queue workers, the scheduler, and Reverb if enabled.
- Optional: set
AI_MCP_ENABLED,AI_WRITE_TOOLSand the tool allowlist, a theme preset in Settings → Appearance, orFILES_DISK=gcs/azure.
Behavior notes
- Inbound AI collection-import webhooks must now send
X-AI-Webhook-Timestamp(within 300 seconds) and sign"{timestamp}.{body}". Outbound webhooks addX-Externa-Signature-V2; the legacyX-Externa-Signaturestays for one minor (#273). - Docker: workers run as
www-data. Bind-mountedstorage/andbootstrap/cachecreated as root may need a one-timechown -R www-data:www-data storage bootstrap/cache(#320). - Files: the upgrade migration computes
files.effective_accessfor existing files, and files without a computed value are hidden from roles withoutread_private(#434). - API key owners: existing keys are bound to their creator, or to the first active super-admin when the creator is deactivated. Review those keys after the upgrade (#215 / #439).
- Permissions:
externa:upgradegrants the built-inadminrole the newdeploy.triggerandai.prompts.managepermissions (#439). - Security headers: if you embed the admin or load assets from other origins, set
SECURITY_CSP(#187). - AI reasoning: with a cloud provider the assistant now asks for medium reasoning effort, which makes answers slower and uses more tokens. Lower it, or turn it off, with the
*_REASONING_EFFORTvariables (#570). - Removed packages:
laravel/sail,@headlessui/react, the unused Radix packages and the Wayfinder Vite plugin are gone. Runcomposer installandnpm ciafter pulling (#520 / #568).
Sources
- GitHub Release v1.4.0 · Packagist
qiick/externa-core· coreCHANGELOG.md[1.4.0] - 2026-11-10 - Docs: Upgrade · AI configuration · AI chat · Files configuration · Accessibility
Verwandt
- PHP emergency security releases — Oct 2026
PHP CVEs 2026-109618 and 2026-109619 (CVSS 9.2 RCE). Update to 8.4.27 or 8.5.12; what Externa users must do.
- Externa Core 1.2.1 — field rename drafts & deps
Patch for draft/revision field renames, npm audit clean-up, and the repair-renamed-field-drafts artisan command.
- Nuxt starter 1.1.1 — NuxtPage and Node 22.13+
Why 1.1.1 matters: NuxtPage instead of slot, h3 pin for getQuery, engines ≥22.13.0 — plus what 1.1.0 tooling bumps included.