Heisenberg

mcp
Security Audit
Pass
Health Pass
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 54 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

A block-based content engine and bilingual blog backend for Laravel Gutenberg-style editor, media library, post templates, roles, and an AI writing assistant, with zero host coupling.

README.md

Heisenberg

Heisenberg

A block-based content engine and bilingual blog backend for Laravel.
Drop a full Gutenberg-style editor, media library, taxonomy, post templates and an AI writing assistant into any Laravel app.

Latest version PHP version Laravel License


Heisenberg has no users, no theme lock-in and no frontend framework. Your app keeps its users, its routes and its pages — Heisenberg brings the editor at /editor, the content model, and narrow contracts you bind to make everything yours.

Installation

composer require heisenberg/heisenberg
php artisan migrate
php artisan storage:link   # public media URLs (the uploads link is pre-registered)

That's it — open /editor. The service provider is auto-discovered, migrations load automatically, and every seam ships a working default. On a machine where APP_ENV=local, everything works anonymously out of the box; real deployments authorize through your own users (below).

Optional but recommended:

composer require intervention/image:^3.9   # responsive image variants (v4 is NOT compatible)

Connecting your users

Heisenberg never creates users. Your existing users get abilities through the RoleGate contract, with four canonical roles — WordPress-familiar:

Role Can
admin everything, including AI/provider settings
editor publish, schedule, archive; manage anyone's media
author write and draft; upload media; edit own files
viewer browse and pick media, read-only

The bundled gate reads either Spatie permissions (getRoleNames()) or a plain role string column on your user model:

Schema::table('users', fn (Blueprint $t) => $t->string('role')->nullable());
// then: $user->role = 'editor';

Different role names in your app? Remap them in config/heisenberg.php under roles, or bind your own RoleGate implementation entirely. Production apps should also wrap the route groups in their own auth middleware (heisenberg.middleware.editor / .media / .ai, all default ['web']).

Publishing content with your own templates

Heisenberg renders block content; you own the page around it. A post template is a JSON contract declaring which chrome capabilities the page has — featured image, authored table of contents, reading time, breadcrumbs, share buttons, comments, and more:

// config/heisenberg.php (php artisan vendor:publish --tag=heisenberg-config)
'template_root' => resource_path('heisenberg-templates'),
// resources/heisenberg-templates/mysite/mysite.json
{
  "name": "heisenberg/mysite",
  "render": { "view": "blog.show" },   // YOUR Blade view
  "capabilities": {
    "featuredImage":   { "enabled": true, "source": "post-attribute", "context": "hero" },
    "tableOfContents": { "enabled": true, "source": "entries" },
    "comments":        { "enabled": true, "allowGuests": true, "sortOrder": "newest" }
  }
}

Validate with php artisan templates:verify. In your controller, resolve PostTemplateRegistryService from the container, read the contract, and render the body exactly like the built-in preview does (BlockRenderer::renderBlocks() plus the block/theme stylesheets). The full schema — all 11 capabilities and the render-vs-adapter decision for each — is in docs/post-template-schema.md.

Data Heisenberg doesn't own arrives through provider contracts with null defaults — bind yours in the published config:

'post_template' => [
    'comments_provider' => App\Support\MyCommentProvider::class,  // implements PostCommentProvider
    // post_views_provider, related_posts_provider, seo_meta_provider
],

What the editor gives your authors

  • Twelve block types — headings, paragraphs, images, buttons, quotes, lists, icons, separators, embeds, and nestable groups/columns — each defined by a JSON contract, validated server-side, rendered through a sanitizing pipeline.
  • Full-page authoring chrome — inspector, floating toolbar, navigator tree, undo/redo, revisions, autosave with optimistic locking, drag & drop, dark mode, en/fr UI.
  • Post management — status lifecycle (draft → review → published/scheduled/archived, tier-gated), categories & tags, featured image, authored table of contents, page layout and discussion settings.
  • Media library — drag-drop uploads with per-file progress, responsive variants, bilingual alt/caption metadata, virus-scan seam (VirusScanner contract), collision-safe naming (photo(1).jpg), role-scoped permissions.
  • Visual ⇄ Code view — the whole document round-trips through a compact shortcode dialect (see docs/code-view.md).
  • AI writing assistant — bring your own provider (Anthropic, OpenAI, or any OpenAI-compatible endpoint; keys stored write-only and encrypted). The assistant writes to the live canvas through a validated tool call, streams its reasoning, and remembers conversations. Works with MCP in both directions: connect external MCP servers to the assistant, and/or expose Heisenberg itself as an MCP server so external agents can author drafts via bearer token.

Configuration surface

php artisan vendor:publish --tag=heisenberg-config gives you config/heisenberg.php: table names and model classes (all swappable), role map, lifecycle transitions, media rules (size caps, allowed extensions, virus scanner), template root, AI provider settings, and the middleware stacks for each route group. Every contract (RoleGate, MediaResolver, VirusScanner, AuditSink, IconProvider, the four template providers) is a config-named binding with a working default.

Security posture

  • Every content write funnels through one validated, sanitizing pipeline (HTML Purifier at the XSS boundary); nothing bypasses it — including AI- and MCP-authored content.
  • Media uploads: extension allowlist, size caps, scan-before-write, no PHP in the public read path (see docs/media-library-backend-blueprint.md for the web-server hardening snippets).
  • The anonymous local-dev convenience is structurally incapable of activating outside APP_ENV=local.
  • The inbound MCP server is disabled by default and draft-only when enabled.

Documentation

Doc What it covers
docs/BLUEPRINT.md The full specification — every class, column, contract key and security gate
docs/block-schema.md Writing block contracts
docs/post-template-schema.md Writing post templates
docs/code-view.md The shortcode dialect
docs/media-library-backend-blueprint.md The media subsystem, end to end
docs/ai-mcp-plan.md The AI assistant and MCP integration

Requirements

PHP ^8.2 · Laravel 11 / 12 / 13 · Livewire ^4.3

License

Apache-2.0

Reviews (0)

No results found