Publisher is the open-source analytics engine for Malloy. It lets you define data models once — and use them everywhere.
Malloy Publisher
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
The Analytics Engine for Malloy
A post modern data stack — built for the AI era.
One data model, served over MCP and REST to AI agents, applications, and BI tools.
Created and maintained by Credible , the company behind the AI Analytics Engine.
AI agents: read AGENTS.md first (raw: https://raw.githubusercontent.com/malloydata/publisher/main/AGENTS.md ).
It covers starting the server, connecting over MCP, the bundled skills, and the package format. Fetch the raw file, not a summary of this page.
To learn the skills with nothing installed, read https://unpkg.com/@malloy-publisher/skills@latest/skills/malloy-getting-started/SKILL.md . With a shell, npx -y @malloy-publisher/skills@latest install copies them all into this project.
=20">
A 60-second walkthrough — model in your IDE with the Malloy skills, serve with Publisher, build a data app, materialize on a schedule, and analyze. Watch the video for playback controls.
Modeling, a query engine, materialization, access control, and an API — the pieces you used to assemble
from five projects — ship as one server, built assuming the first builder or consumer is an
agent.
Write down what your data means, in Malloy: the sources, the joins, the
measures, who may see what. The open-source Malloy skills ship alongside, so an agent can do
the writing — build the model, then the reports and data apps on top of it.
Publisher serves that model to every surface — over MCP to Claude, Cursor, Codex, or an agent you
build; over REST to applications and BI tools. Agents compose queries against the model instead of
writing SQL from scratch, so there is no wrong join, no invented column, no fan-out that double-counts
but looks plausible — and the same question returns the same numbers tomorrow.
- **Model** — an agent builds the model with the bundled open-source skills, from a
warehouse or a file, and validates each edit without a restart.
- **Analyze** — Claude, Cursor, Codex, or an agent you build asks over MCP; unattended agents and
applications use REST. Queries are Malloy, legible enough to review at a glance, and run against
the model, never your raw tables.
- **Surface** — reports declared in Malloy, read top to bottom or laid out as a grid and built by
dragging tiles if you like, and no-build HTML data apps, all shipped inside the package, plus the
Console for browsing it all.
- **Govern** — givens, #(authorize) and #(access_filter) decide who may query and who sees what; discovery curation
decides what is even visible.
- **Optimize** — one #@ persist annotation materializes an expensive source into a table and
#@ preaggregate rolls it up, rebuilt on demand or on a schedule.
- **Run anywhere** — DuckDB built in for CSV, Parquet, JSON, and Excel; BigQuery, Snowflake, Postgres,
Databricks, MotherDuck, and more by connection; npx, Docker, or Compose, in minutes.
Requirements
Node.js 20 or newer (the server refuses to start on anything older and says so). Building from a clone
also needs Bun 1.3.13+. The Docker image carries its own runtime and needs neither.
Quick start
Run the examples
Open **http://localhost:4000**. Three example packages are bundled — storefront
(a complete ecommerce model), governed-analytics (access control), and
html-data-app (a no-build dashboard) — all DuckDB-backed, no credentials
required. The first run fetches them from GitHub.
Start from your own data
Create a package
This writes a package to ./sales — plus, in the current directory, a small workspace: start and
reset scripts, an MCP config, agent instructions, and the Malloy skills as files your agent can read.
npm start serves the package in watch mode, so edits take effect as you save. Keep the @latest:
without it npm may reuse a cached, older version. The finer points of npm create — caching, workspace
layout, the bare npx form — are in docs/scaffolding.md.
Agents: AGENTS.md sections 1 and 2 have the same steps plus the pitfalls around @latest,