AI coding agents

Teach Claude Code, Cursor, and Copilot how to use Lunora — agent skills, agent-aware dev mode, the docs server, and the MCP server.

Last updated:

Lunora ships five things for AI coding agents, addressing different problems:

You wantUse
The agent to write Lunora code correctlyAgent skills
The agent to run and inspect your dev serverAgent mode
The agent to look up the API while it writesThe docs server
One local endpoint carrying all of the aboveThe local server
The agent to query and call a live deploymentThe MCP server

If you only do one thing, run lunora mcp install — it wires the docs server and your project's local server into whichever editor you use.

Agent skills

Skills are portable instructions that teach an agent how Lunora works — the schema API, the procedure builders, indexing rules, the deploy flow. Install them into your project and any skill-aware agent picks them up:

lunora rules install              # copy the skills into .agents/skills/
lunora rules install --overwrite  # reinstall, replacing local edits
lunora rules check                # report which are present
lunora rules check --strict       # exit non-zero when missing — a CI gate

.agents/skills/ is the portable location Cursor, Claude Code, and GitHub Copilot all discover, so one install covers every agent on the project.

The shipped set is a router skill (lunora) plus focused skills it delegates to — quickstart, functions, realtime, auth setup, package authoring, migrations, deploy, and performance auditing. The router's presence is what marks the rule set as installed, because every other skill is reachable through it.

install leaves files you have edited alone, so local customisation survives a reinstall unless you pass --overwrite. lunora dev, the Vite plugin, and the Studio all nudge you when the rules are missing.

Agent mode

When the CLI detects it is being driven by a coding agent — Claude Code, Cursor, Codex, Gemini CLI, Cline, and others — it changes two defaults so the agent does not get stuck:

  • Background dev server. lunora dev detaches instead of blocking forever on a foreground process. It returns once the server accepts requests, printing the URL and PID.
  • JSON logging. Output becomes machine-readable.

Neither needs a flag in an agent workflow. Set LUNORA_AGENT_MODE=0 to opt out, or =1 to force it on.

The background server is managed rather than fire-and-forget. A state record at .lunora/dev.json acts as a lockfile, so starting twice reports the running instance instead of spawning a conflict, and every subcommand is idempotent — stopping when nothing runs succeeds silently:

lunora dev --background   # detach; blocks until ready, prints URL + PID
lunora dev status         # URL, PID, uptime (--json for machine-readable)
lunora dev logs           # captured output (--lines n, 0 = all)
lunora dev stop           # SIGTERM, then SIGKILL after 10s

Agents can also poll GET /_lunora/status on the running worker — a public, secret-free health probe answering {"ok":true}.

JSON logs are available to everyone, agent or not, via lunora dev --json or LUNORA_LOG_JSON=1.

The docs server

Skills teach an agent Lunora's shape; the docs server lets it look up specifics while it works. https://lunora.sh/mcp serves these docs over the Model Context Protocollunora_search_docs, lunora_get_doc, and lunora_list_docs. It reads published documentation only, so there is nothing to authenticate and no token to manage.

lunora mcp install                      # every MCP client already configured here
lunora mcp install claude-code cursor   # or name them
lunora mcp install --list               # supported clients and their config files
lunora mcp install --print              # show the config without writing it
lunora mcp uninstall                    # take them back out again

The docs server goes in your editor's machine-wide config, since it's the same URL in every project; this project's local server goes in the project config. --global / --project override that.

install knows where each client keeps its servers and what an entry looks like there — .mcp.json for Claude Code, .cursor/mcp.json for Cursor, .vscode/mcp.json (whose key is servers, not mcpServers) for VS Code, and so on. Existing entries are left alone unless you pass --force, comments in a JSONC config survive the edit, and a config it cannot parse is never rewritten. Clients configured in TOML (Codex) get a printed snippet instead.

Inside a Lunora project install also adds a second server, lunora, which runs lunora mcp serve — the local counterpart described next. Use --docs-only or --local-only to install just one.

Adding the docs server by hand takes one line:

claude mcp add --transport http lunora-docs https://lunora.sh/mcp

The local server

lunora mcp serve is the stdio server your editor spawns for a project. It carries the docs tools, two dev-server tools (lunora_dev_status, lunora_dev_logs), and — pointed at whatever lunora dev is running — the deployment tools below.

Its config takes no arguments and no environment:

{
    "mcpServers": {
        "lunora": {
            "command": "pnpm",
            "args": ["exec", "lunora", "mcp", "serve"],
        },
    },
}

The dev server's URL comes from .lunora/dev.json and the admin token from .dev.vars, both re-read per tool call. That matters because an editor spawns this process when the project opens — usually before lunora dev is running — and keeps it alive across every restart afterward. Start the dev server later and the deployment tools begin working without reconnecting.

The MCP server

@lunora/mcp exposes a deployed Lunora app to an agent over MCP. Where skills teach an agent to write Lunora code, this lets it introspect and call a running deployment: list functions and tables, read a function's schema, and run queries, mutations, and actions.

{
    "mcpServers": {
        "lunora": {
            "command": "lunora-mcp",
            "env": {
                "LUNORA_URL": "https://app.example.workers.dev",
                "LUNORA_ADMIN_TOKEN": "...",
            },
        },
    },
}

The server is read-only by default, and deliberately so — an agent gets introspection and queries, but not writes. Mutations and actions are exposed only when you set LUNORA_MCP_ALLOW_WRITES (lunora mcp serve --allow-writes locally), and agent tools only when you set LUNORA_MCP_ALLOW_AGENTS. Point it at a development deployment before you point it at production.

See @lunora/mcp for the full tool list, the createLunoraMcpServer API for other transports, and how to front durable @lunora/agent runs.

Keeping generated types honest

An agent editing your schema is an agent that can leave _generated/ stale. Gate it the same way you would a human contributor:

lunora verify              # wrangler validation + codegen dry-run + tsc --noEmit
lunora rules check --strict

See also