{"id":50745838,"url":"https://github.com/malloydata/malloyyo","last_synced_at":"2026-06-10T20:32:25.304Z","repository":{"id":359200211,"uuid":"1244858848","full_name":"malloydata/malloyyo","owner":"malloydata","description":"Turn any dataset into a Malloy MCP endpoint — powered by MotherDuck + Vercel","archived":false,"fork":false,"pushed_at":"2026-06-03T20:42:07.000Z","size":1299,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T22:14:38.946Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/malloydata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-20T17:06:34.000Z","updated_at":"2026-06-03T20:42:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/malloydata/malloyyo","commit_stats":null,"previous_names":["lloydtabb/mayolo","lloydtabb/malloyyo","malloydata/malloyyo"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/malloydata/malloyyo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malloydata%2Fmalloyyo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malloydata%2Fmalloyyo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malloydata%2Fmalloyyo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malloydata%2Fmalloyyo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/malloydata","download_url":"https://codeload.github.com/malloydata/malloyyo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/malloydata%2Fmalloyyo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34170162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-10T20:32:21.977Z","updated_at":"2026-06-10T20:32:25.288Z","avatar_url":"https://github.com/malloydata.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# malloyyo\n\nPoint at a GitHub repo with a Malloy model. Get a personal MCP endpoint for analytical queries.\n\nMalloyyo loads a [Malloy](https://malloydata.dev) semantic model from GitHub, compiles it against your MotherDuck database, and exposes it as an MCP server — so any MCP-capable AI (Claude Desktop, claude.ai, etc.) can run structured analytical queries against your data.\n\n## How it works\n\n```\n      ┌─────────────────────────────────────────────┐\n      │           GitHub repo (index.malloy)        │\n      │   your semantic model, developed with CLI   │\n      └────────────────────┬────────────────────────┘\n                           │  load + compile\n      ┌────────────────────▼────────────────────────┐\n      │                 Malloyyo                    │\n      │     GitHub → compile → store → ready        │\n      └──────┬─────────────────────────┬────────────┘\n             │                         │\n      ┌──────▼──────┐           ┌──────▼──────┐\n      │   Cloud DB  │           │    Neon     │\n      │  or S3/GCS  │           │  Postgres   │\n      │             │           │  metadata   │\n      │             │           │             │\n      │  your data  │           │  datasets   │\n      │  + queries  │           │  malloy_    │\n      └─────────────┘           │    models   │\n             │                  │  users      │\n             └──────────────────┘\n                           │\n      ┌────────────────────▼────────────────────────┐\n      │              MCP server  /mcp               │\n      │         OAuth 2.1 · 5 analytical tools      │\n      └─────────────────────────────────────────────┘\n```\n\n### Adding a dataset\n\nPoint Malloyyo at a GitHub repo that has an `index.malloy` at its root. Malloyyo fetches the file (and any imports it references), compiles the model, and stores all files. A webhook endpoint (`/api/datasets/\u003cid\u003e/webhook/github`) lets GitHub trigger an automatic refresh on every push.\n\n### The two databases\n\n| Database | What lives there |\n|---|---|\n| **Cloud database** (BigQuery, Snowflake, MotherDuck, MySQL, Postgres, Presto, Trino) or **S3/GCS** | Your analytical data |\n| **Neon Postgres** | Metadata — `datasets`, `malloy_models`, `malloy_model_files`, `users`, `accounts`, `sessions`, OAuth clients and tokens |\n\n### MCP tools served at `/mcp`\n\n| Tool | What it does |\n|---|---|\n| `list_datasets` | Names, schema summaries, and source names for every dataset |\n| `describe_semantic_model` | The full Malloy source for a dataset |\n| `sample_rows` | Up to 200 raw rows from MotherDuck |\n| `compile_analytical_query` | Compile a Malloy snippet → SQL (no execution) |\n| `run_analytical_query` | Compile + run; return rows |\n\nThe MCP endpoint speaks OAuth 2.1, so claude.ai's remote MCP integration can connect after a one-time authorization flow.\n\n## Developing Malloy models\n\nUse the [Malloy CLI](https://github.com/malloydata/malloy-cli) to write and test semantic models locally before deploying them to Malloyyo via GitHub.\n\n```bash\nnpm install -g @malloydata/cli\n```\n\n**1. Configure your database connection** in `malloy-config.json` at the root of your model repo — see the [Malloy connection config docs](https://docs.malloydata.dev/documentation/setup/config). Supported databases: BigQuery, DuckDB (incl. MotherDuck), MySQL, Postgres, Snowflake, Databricks, Trino, Presto. Malloyyo reads this same file from the root of your GitHub repo when loading a model, so one config works in both places.\n\n**2. Add `.mcp.json`** to your model repo so your AI assistant can compile and test Malloy directly:\n\n```json\n{\n  \"mcpServers\": {\n    \"malloy\": {\n      \"command\": \"malloy-cli\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n`malloy-cli mcp` runs an MCP server over stdio exposing a `compile_malloy` tool and bundled Malloy language-reference prompts. Claude Code, Claude Desktop, and other MCP clients will pick this up automatically.\n\n**3. Develop your model** — ask your AI to generate and test a Malloy semantic model against your database, or write it yourself and use `malloy-cli compile` / `malloy-cli run` to verify it.\n\nOnce the model compiles cleanly, push to GitHub and add the repo to Malloyyo.\n\n## Stack\n\n- **Next.js 16** App Router\n- **MotherDuck** — cloud DuckDB; analytical data storage and query engine\n- **Neon Postgres** + **DrizzleORM** — metadata and auth state\n- **Malloy** (`@malloydata/malloy` + `@malloydata/db-duckdb`) — semantic layer\n- **NextAuth v5** + **Google OAuth** — user authentication\n- **OAuth 2.1 provider** — MCP authorization for claude.ai\n\n## Running locally\n\nCopy `.env.local.example` to `local/\u003cinstance\u003e` and fill in the blanks:\n\n```bash\nDATABASE_URL=postgresql://...          # Neon (or any Postgres)\nMOTHERDUCK_TOKEN=...                   # MotherDuck personal token\nMOTHERDUCK_DATABASE=malloyyo           # Must be an existing MotherDuck database\nAPP_BASE_URL=http://localhost:3000\nAPP_ADMIN_EMAILS=you@example.com\nAUTH_SECRET=...                        # openssl rand -base64 32\nAUTH_GOOGLE_ID=...                     # Google OAuth client ID\nAUTH_GOOGLE_SECRET=...                 # Google OAuth client secret\n# GITHUB_TOKEN=github_pat_...          # Optional; needed for private repos\n```\n\n```bash\npnpm install\nnpx dotenv-cli -e local/main -- npx drizzle-kit push   # first run only\nnpx dotenv-cli -e local/main -- npm run dev\n```\n\nOpen \u003chttp://localhost:3000\u003e.\n\n## Code map\n\n1. **`src/lib/github.ts`** + **`src/lib/github-refresh.ts`** — GitHub model loading and webhook-triggered refresh.\n2. **`src/lib/malloy.ts`** — single-file and multi-file Malloy compilation and execution via `InMemoryURLReader`.\n3. **`src/lib/mcp-tools.ts`** + **`src/app/mcp/route.ts`** — the MCP server. Tools are pure functions; the route is a JSON-RPC dispatcher.\n4. **`src/db/schema.ts`** — Drizzle schema for all Postgres tables.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmalloydata%2Fmalloyyo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmalloydata%2Fmalloyyo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmalloydata%2Fmalloyyo/lists"}