@pharaoh-so/mcp 0.3.8 → 0.3.10

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/dist/helpers.js CHANGED
@@ -42,7 +42,7 @@ export function parseArgs(argv = process.argv.slice(2)) {
42
42
  return { server, logout };
43
43
  }
44
44
  export function printUsage() {
45
- printLines("Usage: pharaoh-mcp [options]", "", "Options:", " --server <url> Pharaoh server URL (default: https://mcp.pharaoh.so)", " --logout Clear stored credentials and exit", " --install-skills Force reinstall Pharaoh skills (Claude Code + OpenClaw)", " --help, -h Show this help", "", "Get started:", ` ${NPX_COMMAND}`, "");
45
+ printLines("Usage: pharaoh-mcp [options]", "", "Options:", " --server <url> Pharaoh server URL (default: https://mcp.pharaoh.so)", " --logout Clear credentials and MCP config, then exit", " --clean Remove all Pharaoh MCP entries from Claude Code config", " --install-skills Force reinstall Pharaoh skills (Claude Code + OpenClaw)", " --help, -h Show this help", "", "Get started:", ` ${NPX_COMMAND}`, "");
46
46
  }
47
47
  /**
48
48
  * Validate that a server-supplied SSE URL shares the same origin as the configured server.
package/dist/index.js CHANGED
@@ -41,10 +41,20 @@ async function main() {
41
41
  runInstallSkills();
42
42
  return;
43
43
  }
44
+ // Clean mode — remove all pharaoh traces from Claude Code config (MCP entries,
45
+ // disabled states, project-scoped configs). Useful for resetting broken installs.
46
+ if (args.includes("--clean")) {
47
+ const { cleanSlate } = await import("./setup.js");
48
+ cleanSlate();
49
+ printLines("Pharaoh: cleaned all MCP entries from Claude Code config");
50
+ process.exit(0);
51
+ }
44
52
  const { server, logout } = parseArgs(args);
45
53
  if (logout) {
54
+ const { cleanSlate } = await import("./setup.js");
55
+ cleanSlate();
46
56
  deleteCredentials();
47
- printLines("Pharaoh: credentials cleared");
57
+ printLines("Pharaoh: credentials and MCP config cleared");
48
58
  process.exit(0);
49
59
  }
50
60
  const creds = readCredentials();
package/dist/setup.d.ts CHANGED
@@ -1,5 +1,16 @@
1
1
  /**
2
- * Full automated setup: remove stale entries, register MCP server globally,
2
+ * Remove all traces of pharaoh from Claude Code's internal config (~/.claude.json).
3
+ *
4
+ * The `claude mcp remove` CLI only removes the server definition from one scope
5
+ * at a time and does NOT clear:
6
+ * - `disabledMcpServers` arrays (set when user disables via UI)
7
+ * - Project-scoped `mcpServers.pharaoh` entries in other workspaces
8
+ *
9
+ * This function handles what the CLI cannot — a true clean slate.
10
+ */
11
+ export declare function cleanSlate(home?: string): void;
12
+ /**
13
+ * Full automated setup: clean slate removal, register MCP server globally,
3
14
  * install skills. Requires valid credentials (caller handles auth first).
4
15
  *
5
16
  * @returns true if setup succeeded, false if Claude CLI not found.
package/dist/setup.js CHANGED
@@ -6,6 +6,9 @@
6
6
  * One command does everything: `npx @pharaoh-so/mcp`
7
7
  */
8
8
  import { execFileSync } from "node:child_process";
9
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
10
+ import { homedir } from "node:os";
11
+ import { join } from "node:path";
9
12
  import { NPX_COMMAND, printLines } from "./helpers.js";
10
13
  /** Check if `claude` CLI is available in PATH. */
11
14
  function hasClaude() {
@@ -41,7 +44,64 @@ function runClaude(args) {
41
44
  }
42
45
  }
43
46
  /**
44
- * Full automated setup: remove stale entries, register MCP server globally,
47
+ * Remove all traces of pharaoh from Claude Code's internal config (~/.claude.json).
48
+ *
49
+ * The `claude mcp remove` CLI only removes the server definition from one scope
50
+ * at a time and does NOT clear:
51
+ * - `disabledMcpServers` arrays (set when user disables via UI)
52
+ * - Project-scoped `mcpServers.pharaoh` entries in other workspaces
53
+ *
54
+ * This function handles what the CLI cannot — a true clean slate.
55
+ */
56
+ export function cleanSlate(home = homedir()) {
57
+ const claudeJsonPath = join(home, ".claude.json");
58
+ if (!existsSync(claudeJsonPath))
59
+ return;
60
+ let raw;
61
+ let data;
62
+ try {
63
+ raw = readFileSync(claudeJsonPath, "utf-8");
64
+ data = JSON.parse(raw);
65
+ }
66
+ catch {
67
+ // Corrupt or unreadable — don't risk making it worse
68
+ return;
69
+ }
70
+ let changed = false;
71
+ // Remove global User MCP server definition
72
+ if (data.mcpServers?.pharaoh) {
73
+ delete data.mcpServers.pharaoh;
74
+ changed = true;
75
+ }
76
+ // Walk all project/workspace entries
77
+ if (data.projects) {
78
+ for (const proj of Object.values(data.projects)) {
79
+ // Remove project-scoped pharaoh server definitions
80
+ if (proj.mcpServers?.pharaoh) {
81
+ delete proj.mcpServers.pharaoh;
82
+ changed = true;
83
+ }
84
+ // Remove pharaoh from disabled lists (UI "disable" state).
85
+ // filter() handles duplicates — indexOf+splice would leave extras.
86
+ if (Array.isArray(proj.disabledMcpServers)) {
87
+ const before = proj.disabledMcpServers.length;
88
+ proj.disabledMcpServers = proj.disabledMcpServers.filter((s) => s !== "pharaoh");
89
+ if (proj.disabledMcpServers.length !== before)
90
+ changed = true;
91
+ }
92
+ }
93
+ }
94
+ if (changed) {
95
+ try {
96
+ writeFileSync(claudeJsonPath, JSON.stringify(data, null, " "));
97
+ }
98
+ catch {
99
+ // Read-only file or permissions issue — fall through to CLI removal
100
+ }
101
+ }
102
+ }
103
+ /**
104
+ * Full automated setup: clean slate removal, register MCP server globally,
45
105
  * install skills. Requires valid credentials (caller handles auth first).
46
106
  *
47
107
  * @returns true if setup succeeded, false if Claude CLI not found.
@@ -54,9 +114,13 @@ export function runSetup(options) {
54
114
  }
55
115
  if (!silent)
56
116
  printLines("Pharaoh: setting up...");
57
- // Step 1: Remove any stale entry (ignore failures may not exist)
58
- runClaude(["mcp", "remove", "pharaoh"]);
59
- // Step 2: Register as global stdio MCP server
117
+ // Step 1: Clean slate remove pharaoh from all scopes, disabled lists,
118
+ // and project-scoped configs. Direct file edit handles what CLI cannot.
119
+ cleanSlate();
120
+ // Step 2: Belt-and-suspenders — also remove via CLI (both scopes)
121
+ runClaude(["mcp", "remove", "pharaoh", "-s", "user"]);
122
+ runClaude(["mcp", "remove", "pharaoh", "-s", "project"]);
123
+ // Step 3: Register as global stdio MCP server
60
124
  const added = runClaude([
61
125
  "mcp",
62
126
  "add",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pharaoh-so/mcp",
3
3
  "mcpName": "so.pharaoh/pharaoh",
4
- "version": "0.3.8",
4
+ "version": "0.3.10",
5
5
  "description": "MCP proxy for Pharaoh — maps codebases into queryable knowledge graphs for AI agents. Enables Claude Code in headless environments (VPS, SSH, CI) via device flow auth.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: plan
3
3
  prompt-name: plan-with-pharaoh
4
- description: "Deep plan review before implementing any feature, refactor, or significant code change. Enters plan mode no code changes, just evaluation and interactive decision-making."
5
- version: 0.4.0
4
+ description: Deep plan review with Pharaoh reconnaissance, wiring verification, and structured issue tracking. Use before implementing any feature, refactor, or significant code change. Enters plan mode (no code changes) and provides structured review with decision points.
5
+ version: 0.5.0
6
6
  homepage: https://pharaoh.so
7
7
  user-invocable: true
8
8
  metadata: {"emoji": "☥", "tags": ["planning", "architecture", "blast-radius", "pharaoh", "review", "interactive"]}
@@ -10,18 +10,16 @@ metadata: {"emoji": "☥", "tags": ["planning", "architecture", "blast-radius",
10
10
 
11
11
  # Plan Review
12
12
 
13
- Architecture-aware plan review before implementation. Adapted from [Garry Tan's planning framework](https://www.youtube.com/watch?v=bMknfKXIFA8) for AI-assisted development.
13
+ **You are now in plan mode. Do NOT make any code changes. Think, evaluate, and present decisions.**
14
14
 
15
- **You are in plan mode. Do NOT make any code changes. Think, evaluate, present decisions.**
15
+ ## Document Review
16
+
17
+ If the user provides a document, PRD, prompt, or artifact alongside this command, that IS the plan to review. Apply all review sections to that document. Do not treat it as background context — it is the subject of evaluation.
16
18
 
17
19
  ## Project Overrides
18
20
 
19
21
  If a `.claude/plan-review.md` file exists in this project, read it now and apply those rules on top of this baseline. Project rules take precedence where they conflict.
20
22
 
21
- ## Document Review
22
-
23
- If the user provides a document, PRD, prompt, or artifact alongside this command, that IS the plan to review. Still run Step 1 (Reconnaissance) — always verify against the actual codebase. Then apply all review sections to that document. Do not treat it as background context — it is the subject of evaluation.
24
-
25
23
  ## Engineering Preferences (guide all recommendations)
26
24
 
27
25
  - DRY: flag repetition aggressively
@@ -32,61 +30,64 @@ If the user provides a document, PRD, prompt, or artifact alongside this command
32
30
  - Subtraction > addition; target zero or negative net LOC
33
31
  - Every export must have a caller; unwired code doesn't exist
34
32
 
35
- ## Step 1: Reconnaissance (Required — do this BEFORE reviewing)
36
-
37
- Do NOT review from memory or assumptions. Query the actual codebase first.
33
+ ## Step 1: Pharaoh Reconnaissance (Required — do this BEFORE reviewing)
38
34
 
39
- ### If Pharaoh MCP tools are available:
35
+ Do NOT review from memory or assumptions. Query the actual codebase first:
40
36
 
41
37
  1. `get_codebase_map` — current modules, hot files, dependency graph
42
38
  2. `search_functions` for keywords related to the plan — find existing code to reuse/extend
43
39
  3. `get_module_context` on affected modules — entry points, patterns, conventions
44
40
  4. `query_dependencies` between affected modules — coupling, circular deps
45
- 5. `get_blast_radius` on the primary target of the change
46
- 6. `check_reachability` on the primary target to verify it's reachable from entry points
47
41
 
48
- ### Without Pharaoh:
42
+ Ground every recommendation in what actually exists. If you propose adding something, confirm it doesn't already exist. If you propose changing something, know its blast radius.
49
43
 
50
- 1. Search the codebase for files and functions related to the plan (grep, glob)
51
- 2. Read the entry points and module structure of affected areas
52
- 3. Check existing tests for the modules you'll touch
44
+ ## Step 1b: Reconnaissance Dashboard
53
45
 
54
- Ground every recommendation in what actually exists. If you propose adding something, confirm it doesn't already exist. If you propose changing something, know its blast radius.
46
+ After running recon, present a visual summary before proceeding. This shows the user what Pharaoh found.
47
+
48
+ **Surface all ★ Pharaoh insight blocks verbatim** — they contain pre-formatted bar charts, risk meters, and flow diagrams. Do not summarize or paraphrase them.
55
49
 
56
- ## Step 2: Mode Selection (MANDATORY — ask before proceeding)
50
+ Then compose a **Recon Summary** table:
57
51
 
58
- **STOP and ask the user which mode before starting the review.** This is a hard gate — do not infer, assume, or skip this question even if the user says "yes", "go ahead", or "yes to all". Present both options and wait for an explicit choice:
52
+ | Signal | Value | Source |
53
+ |--------|-------|--------|
54
+ | Modules affected | N | get_codebase_map |
55
+ | Blast radius | LOW/MED/HIGH + caller count | get_blast_radius |
56
+ | Existing functions found | N matches | search_functions |
57
+ | Cross-module coupling | deps + circular? | query_dependencies |
59
58
 
60
- > **BIG CHANGE or SMALL CHANGE?**
61
- >
62
- > - **BIG CHANGE**: Full interactive review, all relevant sections, up to 4 top issues per section
63
- > - **SMALL CHANGE**: One question per section, only sections 2-4
59
+ If any signal is surprising (high blast radius, circular deps, existing code that overlaps the plan), call it out before moving to Mode Selection.
64
60
 
65
- If the user's response is ambiguous (e.g. "just do it", "yes to all"), ask again: "I need to know — BIG or SMALL change?" Do not proceed to Step 3 without an answer.
61
+ ## Step 2: Mode Selection
62
+
63
+ Ask the user which mode before starting the review:
64
+
65
+ **BIG CHANGE**: Full interactive review, all relevant sections, up to 4 top issues per section.
66
+ **SMALL CHANGE**: One question per section, only sections 2-4.
66
67
 
67
68
  ## Step 3: Review Sections
68
69
 
69
- Adapt depth to change size. Skip sections that don't apply. **After each section, pause and ask for feedback before moving on.**
70
+ Adapt depth to change size. Skip sections that don't apply.
70
71
 
71
72
  ### Section 1 — Architecture (skip for small/single-file changes)
72
73
 
73
74
  - Component boundaries and coupling concerns
74
75
  - Dependency graph: does this change shrink or expand surface area?
75
76
  - Data flow bottlenecks and single points of failure
76
- - Does this need new code at all, or can an existing pattern solve it?
77
+ - Does this need new code at all, or can a human process / existing pattern solve it?
77
78
 
78
79
  ### Section 2 — Code Quality (always)
79
80
 
80
81
  - Organization, module structure, DRY violations (be aggressive)
81
82
  - Error handling gaps and missing edge cases (call out explicitly)
82
83
  - Technical debt: shortcuts, hardcoded values, magic strings
83
- - Over-engineered or under-engineered relative to preferences above
84
+ - Over-engineered or under-engineered relative to my preferences
84
85
  - Reuse: does code for this already exist somewhere?
85
86
 
86
87
  ### Section 3 — Wiring & Integration (always)
87
88
 
88
89
  - Are all new exports called from a production entry point?
89
- - Run `get_blast_radius` on new/changed functions — zero callers = not done
90
+ - Run `get_blast_radius` on any new/changed functions — zero callers = not done
90
91
  - `check_reachability` on new exports — verify reachable from API handlers, crons, or event handlers
91
92
  - Does the plan declare WHERE new code gets called from? If not, flag it
92
93
  - Integration points: how does this connect to what already exists?
@@ -104,14 +105,14 @@ Adapt depth to change size. Skip sections that don't apply. **After each section
104
105
  - Memory concerns, caching opportunities
105
106
  - Slow or high-complexity code paths
106
107
 
107
- ### Section 6 — Security & Attack Surface (only for new endpoints/routes/APIs)
108
+ ### Section 6 — Security & Attack Surface (always for new endpoints/routes/APIs; skip for pure refactors)
108
109
 
109
- - **Authentication model** — what authenticates requests? Where validated? What happens on failure?
110
- - **Sensitive data in URLs** — tokens, session IDs, or tenant identifiers in URL paths/params leak via Referer, history, logs
111
- - **Authorization boundaries** — what prevents User A from accessing User B's data?
112
- - **Input trust boundary** — user input flowing into shell commands, queries, HTML rendering, or file paths
113
- - **Error and response surface** — do error responses expose internals to unauthenticated callers?
114
- - **New attack surface** — new public URLs, webhooks, API routes each need rate limiting, auth, and input validation
110
+ - **Authentication model** — what authenticates requests in this plan? Where is it validated? What happens on auth failure (redirect, 401, silent pass-through)? Use `search_functions` to find existing auth middleware and confirm reuse.
111
+ - **Sensitive data in URLs** — does the design put tokens, session IDs, or tenant identifiers in URL paths or query params? These leak via Referer headers, browser history, logs, and link sharing.
112
+ - **Authorization boundaries** — what prevents User A from accessing User B's data? Is there an ownership check, or just an "is logged in" check? Use `get_blast_radius` on existing ownership-check functions to see where they're already enforced.
113
+ - **Input trust boundary** — does the plan accept user input that flows into shell commands, database queries, HTML rendering, or file paths? Each is an injection vector.
114
+ - **Error and response surface** — will error responses or API payloads expose internals (stack traces, DB schemas, internal IDs) to unauthenticated callers?
115
+ - **New attack surface** — does the plan introduce new public URLs, webhooks, API routes, or WebSocket endpoints? Each needs: rate limiting, authentication, and input validation. Use `get_module_context` on the receiving module to check what protections exist.
115
116
 
116
117
  ## For Each Issue Found
117
118
 
@@ -120,23 +121,21 @@ For every specific issue (bug, smell, design concern, risk, missing wiring):
120
121
  1. **Describe concretely** — file, line/function reference, what's wrong
121
122
  2. **Present 2-3 options** including "do nothing" where reasonable
122
123
  3. **For each option** — implementation effort, risk, blast radius, maintenance burden
123
- 4. **Recommend one** mapped to the preferences above, and say why
124
- 5. **Ask** whether the user agrees or wants a different direction
125
-
126
- Number each issue (1, 2, 3...) and letter each option (A, B, C...). Recommended option listed first.
124
+ 4. **Recommend one** mapped to my preferences above, and say why
125
+ 5. **Ask** whether I agree or want a different direction
127
126
 
128
- ## Wiring Checkpoints
127
+ Number each issue (1, 2, 3...) and letter each option (A, B, C...). Recommended option is always listed first. Use AskUserQuestion with clear labels like "Issue 1 Option A", "Issue 1 Option B".
129
128
 
130
- Use these throughout the review, not just at the end:
129
+ ## Pharaoh Checkpoints (use throughout, not just at the end)
131
130
 
132
131
  - **Before reviewing**: recon (Step 1 above)
133
- - **During review**: check blast radius when evaluating impact; search for existing functions before suggesting new code
134
- - **After decisions**: verify all new exports are reachable; check for disconnected code
135
- - **Final sweep**: every new export must have a caller from a production entry point, or the plan is incomplete
132
+ - **During review**: `get_blast_radius` when evaluating impact of changes; `search_functions` before suggesting new code
133
+ - **After decisions**: `check_reachability` on all new exports; `get_unused_code` to catch disconnections
134
+ - **Final sweep**: `get_blast_radius` on ALL new exports zero callers on non-entry-points = plan is incomplete
136
135
 
137
136
  ## Workflow Rules
138
137
 
139
- - **After each section, pause and ask for feedback before moving on**
138
+ - After each section, pause and ask for feedback before moving on
140
139
  - Do not assume priorities on timeline or scale
141
140
  - If you see a better approach to the entire plan, say so BEFORE section-by-section review
142
- - Challenge the approach if you see a better one — your job is to find problems the user will regret later
141
+ - Challenge the approach if you see a better one — your job is to find problems I'll regret later