@mgodata/mgo
v0.3.1
Published
DT 1.5 by MGO Data in your terminal: real AI-visibility audits and JSON-LD schema suggestions from a live crawl, plus bring-your-own-key answer-engine scans. Honest command surface: gated commands say so.
Readme
mgo, DT 1.5 by MGO Data in your terminal
DT 1.5 is MGO Data's agent and system: the thing that does the SEO, AI-SEO,
and drafting work. mgo is DT 1.5 in your terminal. Real crawls, real
findings, copy-paste-ready JSON-LD, a deterministic plan, and a real
approve-then-apply loop.
Honest about what powers it: DT 1.5 is not a foundation model MGO trained. Its audits and schema drafts are deterministic (no LLM at all), and its AI lanes run on the leading models you connect with your own key, the same bring-your-own-key model as Claude Code and Codex. Your API keys stay on your machine and go provider-direct; they are never sent to MGO.
One npm dependency: @supabase/supabase-js, used by the signed-in approval
loop and executor lanes (audits and drafts themselves add nothing else).
Requires Node 22+ (the same floor Claude Code's npm package declares); hard
technical minimum is Node 18 for built-in fetch, and 18-21 run with a warning.
Install
@mgodata/mgo is live on the npm registry. One global install and you have
the mgo command (bare mgo is taken by an unrelated package on npm; the
scoped name is ours):
npm install -g @mgodata/mgoThen from anywhere:
mgo --helpUninstall with npm uninstall -g @mgodata/mgo.
First run
Product commands (audit, plan, schema, ai-scan, draft, director,
the approval loop, connect, execute) need a signed-in MGO account with an
active subscription; the CLI fails closed on billing and says so plainly.
Meta commands (login, logout, whoami, help, doctor, status,
config, log) stay open.
mgo login # browser device sign-in to your MGO account
mgo # the conversational agent: plain language over every
# lane, real tool calls shown live (needs your LLM key)
mgo audit yourstore.com # full AI-visibility audit from a live crawl
mgo plan yourstore.com # deterministic prioritized worklist from the same crawl
mgo schema yourstore.com # just the JSON-LD blocks, ready to paste
mgo ai-scan "Your Brand" # what AI engines say about you (needs your key)
mgo draft meta yourstore.com # LLM-drafted title+meta into the approval loop (needs your key)
mgo director yourstore.com # LLM weekly plan from real findings + queue (needs your key)
mgo doctor # config + environment healthWhat works today
mgo(bare, on a terminal) ormgo agent: the conversational agent, the Claude Code / Codex CLI model. Type what you want in plain language; the agent plans on your own Anthropic or OpenAI key (tool calling, provider direct, never through MGO), runs the real lanes below as tools (audit, ai-scan, plan, drafts, the approval loop, apply, status, connect), shows every tool call live, and answers in terminal markdown. Slash commands (/help,/audit,/approvals,/status,/clear,/exit, ...) are direct shortcuts into the same dispatch the scripted commands use. Piped stdin works for scripting: one agent turn per input line.mgo audit <url>: live crawl of the homepage, robots.txt AI-crawler rules (GPTBot, ClaudeBot, OAI-SearchBot, PerplexityBot, Google-Extended, CCBot, Bytespider), sitemap.xml, llms.txt, Open Graph, and JSON-LD. Prints ranked findings plus deterministic schema suggestions. Add--jsonfor raw output. Every crawl is cached locally soplan --cachedworks offline.mgo plan <url>: Director-lite. Ranks the real findings from a fresh crawl (or--cachedprior crawl) into a prioritized worklist using a fixed, documented scoring table (severity base + category bonus, ties broken by lower effort). Purely deterministic, no LLM: same crawl in, same plan out.--jsonfor the machine-readable plan.mgo schema <url>: only the JSON-LD suggestions from the same real crawl, as<script type="application/ld+json">blocks. Every placeholder is markedREPLACE_ME; fill in real business facts before publishing.--queuefiles each suggestion as an action request in the approval loop.The approval loop (
approvals,approve,reject,apply,log): a local mirror of the MGO dashboard's task queue, running the real action_request state machine from the control-plane schema:draft -> pending -> approved -> executed -> verified, non-terminal states may move tofailed, terminal rows are immutable. Illegal transitions are rejected. Every transition is appended to a local append-only audit log.mgo apply <id> --file <local file>executes an approved action against a LOCAL file and verifies by re-reading it from disk. Executors: JSON-LD schema patch (insert block, verify it parses back out), meta tags patch (replace/insert<title>+ meta description, verify both read back), llms.txt file (write it, backing up any different existing file, verify exact match). Only a real round-trip moves an action toverified.- Content drafts (ad copy, review reply, brand voice) refuse to apply with the honest reason (no platform write lane exists; publishing is manual) and exit code 2. Action types that need platform approval (ads, gbp) refuse the same way. They are never faked.
mgo status: local snapshot (mode, config path, keys present/absent, queue counts, cached crawls). Zero network.mgo doctor: health checks: Node version, config file, state-file and audit-log integrity, provider keys (reported present/absent only, values are never printed), and one optional network probe of the live audit worker (skip it with--offline).mgo config: view and set local config. Keys:default_provider(anthropic|openai|perplexity), which decides the engineai-scanqueries first when several keys are set.mgo login/mgo logout/mgo whoami: browser device sign-in to your MGO account (the same flow asgh auth login: the CLI prints a code, you approve it at mgodata.com/dashboard/cli-auth), with the session stored locally (mode 600) and auto-refreshed. Advanced: pointing the CLI at your OWN Supabase control plane via env still works, see "Supabase control-plane mode" below.mgo ai-scan <brand>: asks AI answer engines about your brand and prints the real responses;--jsonemits the full machine-readable scan report (including real provider errors, never fabricated answers). Bring your own key via environment variables:| Env var | Provider | Grounding | Default model | Override | |---|---|---|---|---| |
ANTHROPIC_API_KEY(orANTHROPIC_AUTH_TOKEN) | Anthropic Claude | model knowledge, no live web in this build |claude-opus-4-8|MGO_ANTHROPIC_MODEL| |OPENAI_API_KEY| OpenAI | model knowledge, no live web in this build |gpt-5.6-luna|MGO_OPENAI_MODEL| |PERPLEXITY_API_KEY| Perplexity Sonar | web-grounded, cites sources |sonar|MGO_PPLX_MODEL|Defaults confirmed against provider docs 2026-07-10. Some project-scoped OpenAI keys are gated off newer models and return 401 "insufficient permissions" for them (observed live 2026-07-15, intermittently); on that specific error the scan retries once with a stable fallback model (
gpt-4.1-mini, overrideMGO_OPENAI_FALLBACK_MODEL) and reports the model actually used. Keys are read from your environment and sent directly to the provider you pay. Add--prompt "your question"(repeatable) to ask your own questions. Honest caveat: API answers approximate but do not exactly equal the consumer apps; treat scans as directional.mgo draft <kind>(same bring-your-own-key table as ai-scan; pick a specific engine with--provider anthropic|openai|perplexity): LLM drafting lanes. Where a URL is given, the draft is grounded in the same real crawl asmgo audit(live, falling back to the local cache). Every draft is filed into the approval loop aspendingand NOTHING is ever auto-published.- file-patch drafts, completed by
mgo apply <id> --file <local file>(write, then verify by re-reading the file; deploying stays yours):mgo draft meta <url>: improved<title>+ meta descriptionmgo draft llmstxt <url>: curated llms.txt (an existing different file at the target path is backed up before overwrite)
- content-only drafts (approve/reject in the loop; PUBLISHING IS MANUAL,
because ad-platform and GBP write APIs are review-gated, so
mgo applyrefuses these honestly instead of pretending to post):mgo draft adcopy <url-or-brand>: 5 headlines (Google RSA 30-char limit, over-limit ones are flagged) + 3 direct-response primary textsmgo draft reply "<review text>": a review reply; automatically written in your stored brand-voice guide when one exists in the queuemgo draft voice <url-or-brand>: a short brand-voice guide The queued payload records provider id + model name for the audit trail; key values are never stored anywhere.
- file-patch drafts, completed by
mgo director <url>: the LLM Director. Feeds the real audit findings, the deterministicmgo planranking, and your current approval queue to the LLM on your key, and writes a prioritized, reasoned weekly plan to a local markdown artifact (<config dir>/plans/<host>-<date>-director.md, with a provenance stamp). Advisory only: it never queues, approves, applies, or publishes anything, and the deterministic keylessmgo planis unchanged. Supports--cached,--provider,--json.
Local files
Everything lives under one config directory, resolved in this order:
$MGO_CONFIG_DIR, then $XDG_CONFIG_HOME/mgo, then ~/.mgo.
config.json: your settings (whitelisted keys only, never secrets)state.json: the offline action-request storeaudit.log: append-only JSONL audit trail; the CLI only ever appendscache/: one JSON file per crawled hostsession.json: created only bymgo login, mode 600. The ONE secret-bearing file the CLI writes, and the secrets in it are your own Supabase session tokens (access + refresh), never provider API keys. Removed bymgo logout.
Provider API keys are never written to disk; they stay in your environment.
Supabase control-plane mode (optional, off by default)
The approval loop has two interchangeable backends behind one contract, mirroring the dashboard's adapter swap rule:
offline (default): local files, zero network (loads none of the package's one npm dependency; it uses only Node built-ins)
supabase: the same commands read/write the real MGO control-plane schema (action_requests state machine, RLS, append-only audit_log). Activate by exporting
MGO_SUPABASE_URL,MGO_SUPABASE_KEY(the anon key), andMGO_TENANT_ID, then sign in once:mgo login # prompts for email + password (password never echoed) mgo whoami # who is signed in, project, token expiry mgo logout # remove the stored sessionmgo loginperforms a GoTrue password grant against your own project (built-in fetch, no extra dependency) and stores the session at<config dir>/session.jsonwith mode 600. Supabase-mode commands then run RLS-scoped as that user, and the CLI silently refreshes the access token via the refresh-token grant when it expires; if the refresh fails you are told to runmgo loginagain.--emailand--passwordflags exist for scripts, but the interactive prompt is safer (nothing lands in shell history or the process list).Token precedence: the stored login session wins; the old manual
MGO_SUPABASE_ACCESS_TOKENexport still works as the fallback (not auto-refreshed). A service-role key asMGO_SUPABASE_KEYalso still works without any user session (server-side use only; never ship it). With an anon key and no session at all, tenant commands stop with a clear "run 'mgo login'" error instead of returning RLS-empty results, because the anon key alone is locked out of every tenant table by design. This mode lazily loads@supabase/supabase-jsfor the data calls; it is not bundled, and the CLI tells you the exact install command if it is missing. Offline mode never loads it, andmgo loginitself does not need it.
The supabase path is verified end to end without any hosted project by
verify/supabase/run.sh (also npm run verify:supabase): it boots a local
PostgreSQL 17, applies the five real control-plane migrations, runs PostgREST
with locally minted GoTrue-shaped JWTs, and drives the CLI store + executor
through queue -> approve -> apply -> verified, RLS isolation, gated-type
refusal, and audit-log immutability. Prerequisites for the harness (not for
the CLI): brew install postgresql@17 postgrest and the seome-app checkout.
Rolling out (honestly gated, the CLI says so if you try)
seo report: designed, not built yet. No approval blocks it; it simply has not shipped. It will run on your own keys. (loginandconnectHAVE shipped:loginis the browser device sign-in to your MGO account, andconnect <provider>hands a platform secret to connect.mgodata.com for server-side envelope encryption, never writing it to disk locally. Gated ad/GBP secrets are stored but stay pending platform approval.)gbp ...: Google gates ALL Business Profile API access (even read) behind an application review with 0 quota until approved. Ships when approval lands.ads ...: Google Ads is on the approval track: it requires a reviewed developer token (Explorer access is instant but capped and feature-blocked; Basic/Standard are reviewed), and real ad spend also means a mandatory human-approval gate before any write. The Meta ads lane is parked and coming in a later update (it will still require Meta App Review plus Business Verification when it lands). Ships when those are true.
Running any gated or unbuilt command prints the honest reason and exits with code 2. Nothing in this CLI fakes success.
Exit codes
0success1real error (bad URL, network failure, provider API error, illegal state transition)2command exists but is honestly not available yet (or an apply was honestly refused)
Privacy
audit, schema, plan, and the crawl step of draft/director call the
MGO audit service, which crawls only the public pages of the URL you name.
The LLM step of ai-scan, draft, and director never touches an MGO
server: your prompt and your key go from your machine straight to the LLM
provider you pay. doctor makes one optional reachability check of the
audit service and nothing else. status, config, and the offline approval
loop are fully local. Drafts queued into the approval loop record provider
id and model name only; key values are never written to disk by this CLI.
