Embed the runtime
The Metacore kernel is a Go library. You import it, configure it, and mount its routes onto your existing HTTP server. There's no agent, no daemon, no SaaS — your binary owns the runtime.
This page is the minimal embedding recipe. The deep dive — every config option, every subsystem, the full embedding API — lives in the Kernel docs.
Prerequisites
- Go 1.22+
- A database. SQLite for local dev, Postgres for production. The kernel detects the driver from the connection string.
- (Optional) TinyGo 0.30+ if you'll run WASM addons.
1. Initialize the module
mkdir my-host && cd my-host
go mod init github.com/me/my-host
go get github.com/asteby/metacore-kernel@latest2. The minimum viable host
// main.go
package main
import (
"log"
"net/http"
"github.com/asteby/metacore-kernel/host"
"github.com/asteby/metacore-kernel/kernel"
)
func main() {
app, err := host.NewApp(host.Config{
DatabaseURL: "postgres://user:pass@localhost/mydb?sslmode=disable",
BundleDir: "./bundles",
Listen: ":8080",
})
if err != nil {
log.Fatal(err)
}
defer app.Close()
// Mount kernel routes under /api.
app.Mount("/api", kernel.Router(app.Kernel))
// Your own routes alongside.
app.HTTP.Handle("/health", http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Write([]byte("ok"))
}))
log.Fatal(app.Run())
}That's the whole host. host.NewApp gives you a configured kernel, a database connection, a WASM runtime, the WebSocket hub, and the installer. kernel.Router returns an http.Handler you can mount anywhere.
3. What you just got
After running go run ., the host exposes:
| Path | What it is |
|---|---|
GET /api/addons | List installed addons |
POST /api/addons | Install a .mcbundle (multipart upload) |
DELETE /api/addons/:id | Uninstall |
GET /api/addons/:id/_meta/columns | Per-addon schema metadata |
GET/POST/PATCH/DELETE /api/addons/:id/:table | Dynamic CRUD per addon table |
POST /api/addons/:id/_actions/:action | Custom actions |
GET /api/ws | WebSocket hub (token-authenticated) |
GET /health | Your custom route |
No addon is loaded yet — drop a .mcbundle into ./bundles/ (or POST it) and the installer takes over.
4. Install your first addon
From a separate shell:
curl -F bundle=@tickets-0.1.0.mcbundle http://localhost:8080/api/addonsResponse includes the addon ID, the migration log, and the new endpoints. Hit one:
curl http://localhost:8080/api/addons/tickets/_meta/columns
curl -X POST http://localhost:8080/api/addons/tickets/tickets \
-H 'Content-Type: application/json' \
-d '{"title":"first ticket","status":"open"}'
curl http://localhost:8080/api/addons/tickets/ticketsYou have a working CRUD service. The kernel manages the schema, the routes, the validation, the permissions, and the WebSocket hub. You wrote 20 lines of Go.
5. Authenticate
The kernel stays out of your auth choice. You inject identity via a middleware that sets a kernel.Identity on the request context:
app.HTTP.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Resolve from JWT, session, mTLS — your call.
id := kernel.Identity{
UserID: "u_42",
OrgID: "org_acme",
Roles: []string{"operator"},
}
ctx := kernel.WithIdentity(r.Context(), id)
next.ServeHTTP(w, r.WithContext(ctx))
})
})The kernel's permission service uses Identity.Roles (or per-user grants in its DB) to decide whether a CRUD call is allowed.
6. Going further
- Custom routes alongside the kernel — keep your existing app, add Metacore on a sub-path.
- Multiple databases — separate the addon database from your business DB; the kernel's installer accepts a dedicated DSN.
- Embedded addons — register an addon in code (no
.mcbundle) for first-party features. Useful for addons that ship with the host binary. - Custom storage backends — implement
kernel.Storeto plug in something other than Postgres / SQLite (e.g. an existing data layer). - TLS, observability, graceful shutdown —
host.Appwraps these, see the kernel docs for the config matrix.
Continue in the Kernel docs → for the embedding reference, every config knob, and every subsystem.
Related
- Architecture — how the runtime fits between hosts and addons.
- Lifecycle concept — install / upgrade / uninstall internals.
- Permissions concept — what the enforcer does at every CRUD call.