katman-mcp 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -44
- package/dist/cli.js +27 -14
- package/dist/license.js +331 -98
- package/dist/meta.js +29 -7
- package/dist/plans.js +54 -0
- package/dist/tools/account/account.js +60 -30
- package/dist/tools/account/cli.js +5 -2
- package/dist/tools/account/index.js +7 -7
- package/dist/tools/account/sync.js +2 -2
- package/dist/tools/account/upsell.js +423 -118
- package/dist/tools/crawl/audit/report.js +2 -2
- package/dist/tools/crawl/cli.js +17 -5
- package/dist/tools/crawl/index.js +52 -18
- package/dist/tools/crawl/scan/framework.js +4 -1
- package/dist/tools/method/core/lint.js +15 -1
- package/dist/tools/method/core/prompt.js +2 -1
- package/dist/tools/method/core/start.js +1 -1
- package/dist/tools/method/data/_store.js +17 -0
- package/dist/tools/method/data/anatomy.js +12 -141
- package/dist/tools/method/data/appendices.js +22 -202
- package/dist/tools/method/data/cloudflare.js +28 -192
- package/dist/tools/method/data/evidence.js +18 -137
- package/dist/tools/method/data/geo-jobs.js +8 -128
- package/dist/tools/method/data/landing.js +14 -67
- package/dist/tools/method/data/lessons.js +16 -127
- package/dist/tools/method/data/measurement.js +38 -142
- package/dist/tools/method/data/offsite.js +16 -148
- package/dist/tools/method/data/pages.js +16 -167
- package/dist/tools/method/data/prompts.js +8 -633
- package/dist/tools/method/data/publish.js +14 -113
- package/dist/tools/method/data/research.js +14 -131
- package/dist/tools/method/data/roadmap.js +12 -105
- package/dist/tools/method/data/traps.js +6 -74
- package/dist/tools/method/data/verify.js +12 -88
- package/dist/tools/method/data/viral-list.js +12 -39
- package/dist/tools/method/index.js +27 -17
- package/dist/tools/method/lib/prompt-lookup.js +18 -0
- package/dist/tools/method/mcp/prompts.js +6 -6
- package/dist/tools/method/mcp/resources.js +21 -17
- package/dist/tools/visibility/index.js +10 -10
- package/dist/tools/visibility/monitoring.js +6 -3
- package/package.json +5 -3
- package/server.json +4 -4
package/README.md
CHANGED
|
@@ -11,13 +11,22 @@ Katman is an MCP server that works inside your AI coding tool (Cursor, Claude Co
|
|
|
11
11
|
|
|
12
12
|
## Pricing
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Katman needs a licence key (`KATMAN_KEY`) with an active plan. Every tool except `katman_account` needs it. Katman Pro comes in two sizes, monthly, and both include every tool:
|
|
15
|
+
|
|
16
|
+
| Plan | Price | Each calendar month |
|
|
15
17
|
|---|---|---|
|
|
16
|
-
| **
|
|
17
|
-
| **
|
|
18
|
-
|
|
18
|
+
| **Katman Pro, 1 site** | **$49/month** | 1 site, 5 audits |
|
|
19
|
+
| **Katman Pro, 3 sites** | **$88/month** | 3 sites, 30 audits |
|
|
20
|
+
|
|
21
|
+
Every tool is in both plans, and so is the full course and the private community: `katman_start`, `katman_research`, `katman_scan_code`, `katman_audit_site`, `katman_keywords`, `katman_plan`, `katman_lint_content`, `katman_visibility_run`, `katman_manual_check`, `katman_report`, the prompts P0–P14 with acceptance checks (`katman_prompt` and the `katman://prompts/*` resources), `katman_page_brief`, `katman_generate`, `katman_indexnow`, `katman_setup_monitoring` and the katman.pro dashboard sync (`katman_sync`).
|
|
22
|
+
|
|
23
|
+
**What counts.** An audit is one run of `katman_audit_site` on a live site (or the CLI `audit`). Sites and audits are counted per calendar month (UTC): a site is a domain you audited that month. Re-reading earlier results, the other tools and visibility runs are not counted. Counts start again on the 1st. When the month's audits or sites are used up, `katman_audit_site` says so, shows when the counts start again and does not run; every other tool keeps working. `katman_account` shows what you have used this month.
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
Choose a plan at https://katman.pro/pricing, then sign in at https://katman.pro/app → **MCP → Create key** and add the key to your MCP config (below). Without a key, or without an active plan, a tool tells you what it would do for your project and how to get the plan, instead of running. `katman_account` always works and shows your plan, this month's audits and sites, and how to upgrade.
|
|
26
|
+
|
|
27
|
+
Accounts that bought an older plan keep what they bought: an Audit Week (no longer sold) until it ends, with the audit and recommendation tools, and an earlier Katman Pro subscription as it was, without these monthly limits.
|
|
28
|
+
|
|
29
|
+
The Katman book and workbook PDFs are sold separately at https://katman.pro/guide; the MCP plans don't include them.
|
|
21
30
|
|
|
22
31
|
---
|
|
23
32
|
|
|
@@ -31,20 +40,20 @@ AI assistants recommend a site only when three gates are open:
|
|
|
31
40
|
| **Quote** | The first 1–3 sentences answer the question on their own, with the same one sentence everywhere | Pages that open with "Welcome to…", llms.txt contradicting the pricing page |
|
|
32
41
|
| **Fit** | There's a page for the situation the customer describes to the assistant | Pages named after the product instead of the customer's problem |
|
|
33
42
|
|
|
34
|
-
Our own sample site, an AI-powered consumer web app we launched on 21 September 2026, went through these gates in its first week. It got **333 real ChatGPT visitors in 7 days**, and **11 of its 17 paying customers** came from ChatGPT
|
|
43
|
+
Our own sample site, an AI-powered consumer web app we launched on 21 September 2026, went through these gates in its first week. It got **333 real ChatGPT visitors in 7 days**, and **11 of its 17 paying customers** came from ChatGPT (the site's own analytics, human sessions only, 21–27 September 2026). By 1 October 2026, **503 distinct visitors** had come from ChatGPT, about 416 after removing bots, with 40–90 a day since 23 September. The site is our own product, not a client. The full story is at https://katman.pro/case-studies/sample-site-first-7-days.
|
|
35
44
|
|
|
36
45
|
## Install
|
|
37
46
|
|
|
38
|
-
Katman runs locally with `npx`.
|
|
47
|
+
Katman runs locally with `npx`. It reads two keys from its environment:
|
|
39
48
|
|
|
40
|
-
- `KATMAN_KEY` (`km_live_…`)
|
|
41
|
-
- `OPENROUTER_API_KEY
|
|
49
|
+
- `KATMAN_KEY` (`km_live_…`), **required**: your licence key. Get it at https://katman.pro/app → **MCP → Create key** once you have a plan (https://katman.pro/pricing). Step by step for each editor: https://katman.pro/docs/getting-started.
|
|
50
|
+
- `OPENROUTER_API_KEY`, optional: only for AI-visibility runs through APIs, paid with your own OpenRouter credits.
|
|
42
51
|
|
|
43
52
|
**Claude Code**
|
|
44
53
|
```bash
|
|
45
54
|
claude mcp add katman --scope user -e KATMAN_KEY=km_live_... -e OPENROUTER_API_KEY=sk-or-... -- npx -y katman-mcp
|
|
46
55
|
```
|
|
47
|
-
Already added without a key? Run `claude mcp remove katman --scope user` first. With the Katman Claude Code plugin, set its `katman_key` and `openrouter_api_key` options instead.
|
|
56
|
+
Already added without a key? Run `claude mcp remove katman --scope user` first. With the Katman Claude Code plugin, set its `katman_key` and `openrouter_api_key` options instead (`/plugin configure katman@katman`).
|
|
48
57
|
|
|
49
58
|
**Cursor**: add this to `~/.cursor/mcp.json` (your user file, so the key never lands in a repository), or use the "Add to Cursor" button on https://katman.pro/mcp.
|
|
50
59
|
```json
|
|
@@ -55,7 +64,7 @@ Already added without a key? Run `claude mcp remove katman --scope user` first.
|
|
|
55
64
|
```json
|
|
56
65
|
{
|
|
57
66
|
"inputs": [
|
|
58
|
-
{ "type": "promptString", "id": "katman_key", "description": "Katman key from katman.pro/app
|
|
67
|
+
{ "type": "promptString", "id": "katman_key", "description": "Katman key from katman.pro/app/mcp", "password": true },
|
|
59
68
|
{ "type": "promptString", "id": "openrouter_api_key", "description": "OpenRouter API key (optional)", "password": true }
|
|
60
69
|
],
|
|
61
70
|
"servers": { "katman": { "type": "stdio", "command": "npx", "args": ["-y", "katman-mcp"], "env": { "KATMAN_KEY": "${input:katman_key}", "OPENROUTER_API_KEY": "${input:openrouter_api_key}" } } }
|
|
@@ -82,7 +91,7 @@ Open your project in your editor and tell your AI:
|
|
|
82
91
|
|
|
83
92
|
> Use Katman to make this site recommendable by ChatGPT. Start with katman_start.
|
|
84
93
|
|
|
85
|
-
Katman then walks your agent through four steps
|
|
94
|
+
Katman then walks your agent through four steps:
|
|
86
95
|
|
|
87
96
|
1. **Research** (`katman_research`): your one sentence (what the customer brings, what you do, what they get, which fear is unnecessary), a not-X note, 10–12 customer situations written without your brand name, competitors (with source and date), proof and a question set.
|
|
88
97
|
2. **Plan** (`katman_scan_code`, `katman_audit_site`, `katman_plan`): a report of what's broken, with no code changes. Then a page plan and a task list ordered like a 30-day plan.
|
|
@@ -93,40 +102,42 @@ Measure every 14 days with `katman_visibility_run` (API) or `katman_manual_check
|
|
|
93
102
|
|
|
94
103
|
## Tools
|
|
95
104
|
|
|
105
|
+
Every tool is in both Katman Pro plans. Only `katman_audit_site` is counted: each run uses one audit of the month.
|
|
106
|
+
|
|
96
107
|
| Tool | Plan | What it does | Writes |
|
|
97
108
|
|---|---|---|---|
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `katman_plan` | Pro | Page plan and task list with P-codes and acceptance criteria (keeps your checkboxes) | `plan.json`, `plan.md` |
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `katman_sync` | Pro | Sends your progress to your katman.pro dashboard: gate pass counts, visibility rates by assistant and language, plan progress, top 10 issue titles, dates, Katman version. Never code, file contents, answers, questions or prompts. Dry run (the exact JSON) by default | — |
|
|
115
|
-
|
|
116
|
-
Slash-command prompts: `katman-start`, `katman-audit`, `katman-situation-page`, `katman-measure`.
|
|
109
|
+
| `katman_account` | Always | Your plan (none, Katman Pro 1 site or 3 sites with this month's audits and sites used, or an older Audit Week with the days left), the tools it unlocks, masked account email, last key check, how to get a key or upgrade. Works without a key | — |
|
|
110
|
+
| `katman_start` | Katman Pro | Shows where you are in the method and the exact next call, with a one-line plan status. Without a plan: what Katman does, the two plans and how to set the key | `config.json` (site URL) |
|
|
111
|
+
| `katman_research` | Katman Pro | Research template, merge and validation, 12+2 question set | `research.json`, `research.md` |
|
|
112
|
+
| `katman_keywords` | Katman Pro | Google autocomplete expansion into situation and single-question page ideas (≤40 throttled requests) | `research.json` (optional) |
|
|
113
|
+
| `katman_scan_code` | Katman Pro | Framework, rendering (SSR/SSG/CSR), routes, head tags, robots/sitemap/llms.txt, JSON-LD, links, images, analytics | `scan.json` |
|
|
114
|
+
| `katman_audit_site` | Katman Pro | Live audit as AI crawlers see it: bot access through your CDN, JS-off text, 404s, canonicals, sitemap, hreflang, JSON-LD, internal links. Counted: one run = one audit of the month. Re-read the last result in `audit.md` for free | `audits/`, `audit.md` |
|
|
115
|
+
| `katman_plan` | Katman Pro | Page plan and task list with P-codes and acceptance criteria (keeps your checkboxes) | `plan.json`, `plan.md` |
|
|
116
|
+
| `katman_lint_content` | Katman Pro | Checks a page against the content rules: answer-first, same one sentence, no hype, sourced numbers, FAQ, not-for, links | — |
|
|
117
|
+
| `katman_visibility_run` | Katman Pro | Asks your question set to ChatGPT, Claude, Gemini, Perplexity and Grok models with live web search via OpenRouter and your own key (API answers are a proxy for the consumer apps). Dry run and cost estimate first; presets economy/full/probe; `samples` for stability | `runs/`, `measurements.md` |
|
|
118
|
+
| `katman_manual_check` | Katman Pro | Records an answer you paste from a consumer app (logged out, search on); no API cost | `runs/`, `measurements.md` |
|
|
119
|
+
| `katman_report` | Katman Pro | Shareable report: gates, visibility deltas, competitors, cited domains, next 7 days | `report.md` |
|
|
120
|
+
| `katman_prompt` | Katman Pro | Prompt P0–P14 filled with your data, plus Accept / Why / How Katman verifies | — |
|
|
121
|
+
| `katman_page_brief` | Katman Pro | Brief for a situation, comparison, pricing, FAQ or about page, and where the file goes in your framework | — |
|
|
122
|
+
| `katman_generate` | Katman Pro | robots.txt, llms.txt, Organization/WebSite/SoftwareApplication/FAQ/Breadcrumb JSON-LD, AI-channel analytics snippet, server-side bot counter, IndexNow key | only with `write: true`, never overwrites without `overwrite: true` |
|
|
123
|
+
| `katman_indexnow` | Katman Pro | Submits only new or changed URLs to IndexNow, plus a Search Console / Bing / Brave checklist | `indexnow.json` |
|
|
124
|
+
| `katman_setup_monitoring` | Katman Pro | GitHub Actions workflow that re-measures weekly with your own keys | `.github/workflows/katman.yml` only with `write: true` |
|
|
125
|
+
| `katman_sync` | Katman Pro | Sends your progress to your katman.pro dashboard: gate pass counts, visibility rates by assistant and language, plan progress, top 10 issue titles, dates, Katman version. Never code, file contents, answers, questions or prompts. Dry run (the exact JSON) by default | — |
|
|
126
|
+
|
|
127
|
+
Slash-command prompts: `katman-start`, `katman-audit`, `katman-situation-page`, `katman-measure` (each tool they call checks the plan). Resources: the method, the checklists and the content rules, this project's `research.md` and the raw prompts `katman://prompts/P0`…`P14`.
|
|
117
128
|
|
|
118
129
|
## What Katman can and can't do
|
|
119
130
|
|
|
120
131
|
- **Reads** files in your project, but skips `node_modules`, `.git` and build output, and **never** reads `.env*`, `.dev.vars*`, keys, certificates or credential files.
|
|
121
132
|
- **Writes** only to `.katman/` in your project, except `katman_generate` and `katman_setup_monitoring` when you pass `write: true`.
|
|
122
|
-
- **Network**: your own site (audits), `openrouter.ai` (visibility runs, with your key, after a dry run), `api.indexnow.org` (only when you submit), `suggestqueries.google.com` (only `katman_keywords`), and `katman.pro` only for
|
|
123
|
-
- **Your keys** (`KATMAN_KEY`, `OPENROUTER_API_KEY`) are read from the environment and are never printed or written to disk. The
|
|
133
|
+
- **Network**: your own site (audits), `openrouter.ai` (visibility runs, with your key, after a dry run), `api.indexnow.org` (only when you submit), `suggestqueries.google.com` (only `katman_keywords`), and `katman.pro` only for four things: checking your `KATMAN_KEY` (at most once a day, and again when a plan ends; only when the key is set), loading Katman's method (the prompts, page briefs and checklists; once per session, before the first tool your plan includes; it sends the key and the Katman version, and the method stays in memory, never on disk), counting an audit (right before each `katman_audit_site` run or CLI `audit`: it sends the key, the domain being audited and the Katman version, and nothing else) and `katman_sync` (only with `dry_run: false`). **No telemetry**: without a key, nothing is sent to Katman; the key check sends only the key and the Katman version. If katman.pro can't be reached when an audit is about to be counted, the audit runs anyway and its result says the count wasn't checked. The method itself needs katman.pro once per session: if it can't be reached then, the tool says so and you can try again.
|
|
134
|
+
- **Your keys** (`KATMAN_KEY`, `OPENROUTER_API_KEY`) are read from the environment and are never printed or written to disk. The licence check is cached in `~/.katman/license.json` under the key's SHA-256 hash (never the key); if katman.pro can't be reached, your plan keeps working for 7 days after the last successful check, never past the end of an older Audit Week.
|
|
124
135
|
- **No automation of consumer chat apps.** Katman doesn't drive chatgpt.com, claude.ai or perplexity.ai with a headless browser: their terms forbid programmatic extraction, and it gets accounts banned. It uses the providers' own web-search models through OpenRouter. For the consumer apps, you paste answers into `katman_manual_check`.
|
|
125
136
|
- **No ranking guarantees.** A single measurement run is a small sample, so re-run the same questions every 14 days.
|
|
126
137
|
|
|
127
138
|
## Costs
|
|
128
139
|
|
|
129
|
-
Katman itself:
|
|
140
|
+
Katman itself: Katman Pro, 1 site is $49/month and Katman Pro, 3 sites is $88/month. On top of that, API visibility runs use your own OpenRouter credits (the same with either plan, and not counted as audits); search results are billed as input tokens, so they're not pennies:
|
|
130
141
|
|
|
131
142
|
| Panel | What | Typical cost per run (14 questions) |
|
|
132
143
|
|---|---|---|
|
|
@@ -139,21 +150,22 @@ The exact estimate is shown before anything runs, and `max_cost_usd` (default $3
|
|
|
139
150
|
## CLI
|
|
140
151
|
|
|
141
152
|
```bash
|
|
142
|
-
npx -y katman-mcp
|
|
143
|
-
npx -y katman-mcp
|
|
144
|
-
npx -y katman-mcp
|
|
145
|
-
npx -y katman-mcp
|
|
146
|
-
npx -y katman-mcp
|
|
147
|
-
npx -y katman-mcp
|
|
148
|
-
npx -y katman-mcp plan --root .
|
|
149
|
-
npx -y katman-mcp report --root .
|
|
153
|
+
npx -y katman-mcp account [--refresh] # always: your plan, this month's audits and sites, how to get a key
|
|
154
|
+
npx -y katman-mcp scan [path]
|
|
155
|
+
npx -y katman-mcp audit https://your.site --max 50 # counted: one run = one audit of the month
|
|
156
|
+
npx -y katman-mcp keywords "invoice software" --lang en
|
|
157
|
+
npx -y katman-mcp check --root . [--yes] [--max-cost 2] # visibility run; dry run without --yes
|
|
158
|
+
npx -y katman-mcp models # the default visibility models and prices
|
|
159
|
+
npx -y katman-mcp plan --root .
|
|
160
|
+
npx -y katman-mcp report --root .
|
|
161
|
+
npx -y katman-mcp indexnow --root . [--submit]
|
|
150
162
|
```
|
|
151
163
|
|
|
152
|
-
|
|
164
|
+
Every command except `account`, `--help` and `--version` reads `KATMAN_KEY` from the environment (`KATMAN_KEY=km_live_... npx -y katman-mcp report --root .`; in GitHub Actions, a repository secret) and, without an active plan (or when `audit` finds the month's audits or sites used up), exits with code 4 and a short explanation. A scheduled `audit` (a CI job, the workflow from `katman_setup_monitoring`) uses one audit per run: weekly is 4–5 a month.
|
|
153
165
|
|
|
154
166
|
## Files
|
|
155
167
|
|
|
156
|
-
Everything Katman learns about your project lives in `.katman/`: `research.json`/`.md`, `scan.json`, `audits/`, `runs/`, `measurements.md`, `plan.md`, `report.md`, `log.md`. It contains no secrets, and it's worth committing, because it's the history of what you changed and what happened. The only file outside the project is the
|
|
168
|
+
Everything Katman learns about your project lives in `.katman/`: `research.json`/`.md`, `scan.json`, `audits/`, `runs/`, `measurements.md`, `plan.md`, `report.md`, `log.md`. It contains no secrets, and it's worth committing, because it's the history of what you changed and what happened. The only file outside the project is the licence cache `~/.katman/license.json` (key hash, plan, plan end, last check).
|
|
157
169
|
|
|
158
170
|
---
|
|
159
171
|
|
package/dist/cli.js
CHANGED
|
@@ -5,35 +5,48 @@ import * as method from "./tools/method/cli.js";
|
|
|
5
5
|
import * as crawl from "./tools/crawl/cli.js";
|
|
6
6
|
import * as visibility from "./tools/visibility/cli.js";
|
|
7
7
|
import * as account from "./tools/account/cli.js";
|
|
8
|
-
import {
|
|
8
|
+
import { EXIT_NEEDS_PLAN, OPEN_COMMANDS, cliFeature, defaultLicense, requireFeature, toolForFeature } from "./license.js";
|
|
9
9
|
import { projectFacts, renderUpsell } from "./tools/account/upsell.js";
|
|
10
|
+
/** Every CLI command by name (built on call: the module CLIs import this file). */
|
|
11
|
+
export function cliCommands() {
|
|
12
|
+
return { ...method.commands, ...crawl.commands, ...visibility.commands, ...account.commands };
|
|
13
|
+
}
|
|
10
14
|
export async function runCli(args, deps = {}) {
|
|
11
15
|
const [cmd, ...rest] = args;
|
|
12
16
|
if (cmd === "--version" || cmd === "-v" || cmd === "version") {
|
|
13
17
|
console.log(VERSION);
|
|
14
18
|
return 0;
|
|
15
19
|
}
|
|
16
|
-
const all =
|
|
17
|
-
const fn = all[cmd];
|
|
18
|
-
|
|
20
|
+
const all = cliCommands();
|
|
21
|
+
const fn = cmd !== undefined && Object.hasOwn(all, cmd) ? all[cmd] : undefined;
|
|
22
|
+
// --help anywhere only prints the help: it never runs a command, so it can't get past the gate.
|
|
23
|
+
if (!fn || rest.includes("--help") || rest.includes("-h")) {
|
|
19
24
|
printHelp();
|
|
20
|
-
return cmd === "help" || cmd === "--help" || cmd === "-h" ? 0 : 1;
|
|
25
|
+
return fn || cmd === "help" || cmd === "--help" || cmd === "-h" ? 0 : 1;
|
|
21
26
|
}
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
// Every command except account needs a plan with its feature: the same gate as the MCP tools.
|
|
28
|
+
if (!OPEN_COMMANDS.includes(cmd)) {
|
|
29
|
+
const feature = cliFeature(cmd);
|
|
30
|
+
if (!feature) {
|
|
31
|
+
console.error(`katman-mcp ${cmd}: no licence rule for this command.`);
|
|
32
|
+
return EXIT_NEEDS_PLAN;
|
|
33
|
+
}
|
|
34
|
+
const gate = await requireFeature(feature, deps.license ?? defaultLicense());
|
|
26
35
|
if (!gate.allowed) {
|
|
27
36
|
const { _, flags } = parseArgs(rest);
|
|
28
|
-
const
|
|
29
|
-
const facts = await projectFacts(
|
|
30
|
-
const
|
|
31
|
-
console.error(renderUpsell({ tool: toolForFeature(feature), feature, status: gate.status, facts, surface: "cli", command }));
|
|
32
|
-
return
|
|
37
|
+
const rootArg = typeof flags.root === "string" ? flags.root : cmd === "scan" || cmd === "plan" || cmd === "report" ? _[0] : undefined;
|
|
38
|
+
const facts = await projectFacts(path.resolve(rootArg ?? process.cwd())).catch(() => undefined);
|
|
39
|
+
const example = ["katman-mcp", cmd, ...rest].map(shellWord).join(" ");
|
|
40
|
+
console.error(renderUpsell({ tool: toolForFeature(feature), feature, status: gate.status, facts, surface: "cli", command: `katman-mcp ${cmd}`, example }));
|
|
41
|
+
return EXIT_NEEDS_PLAN;
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
return fn(rest, deps);
|
|
36
45
|
}
|
|
46
|
+
/** Quote an argument for the "run it again with the key" example when the shell would split or expand it. */
|
|
47
|
+
function shellWord(a) {
|
|
48
|
+
return /^[\w./:@%+,=-]+$/.test(a) ? a : `'${a.replace(/'/g, `'\\''`)}'`;
|
|
49
|
+
}
|
|
37
50
|
function printHelp() {
|
|
38
51
|
const lines = [
|
|
39
52
|
`katman-mcp ${VERSION} — make your site readable, quotable and recommendable by AI assistants`,
|