@pharaoh-so/mcp 0.2.11 → 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 +6 -16
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +7 -3
- package/dist/index.js +31 -1
- package/dist/setup.d.ts +7 -0
- package/dist/setup.js +76 -0
- package/package.json +1 -1
- package/skills/pharaoh/SKILL.md +4 -4
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ This displays a device code and a URL. Open the URL on **any device** (phone, la
|
|
|
26
26
|
### Step 2 — Add to Claude Code
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
|
|
29
|
+
npx @pharaoh-so/mcp --setup
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
Verify the connection:
|
|
@@ -43,19 +43,9 @@ If you previously added Pharaoh as an SSE server, remove it first:
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
claude mcp remove pharaoh
|
|
46
|
-
|
|
46
|
+
npx @pharaoh-so/mcp --setup
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
### Desktop with Browser (Alternative)
|
|
50
|
-
|
|
51
|
-
If you have a browser available (desktop, laptop), you can connect directly via SSE instead:
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
claude mcp add --transport sse --scope user pharaoh https://mcp.pharaoh.so/sse
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
This uses OAuth in the browser and doesn't require this package.
|
|
58
|
-
|
|
59
49
|
## How It Works
|
|
60
50
|
|
|
61
51
|
```
|
|
@@ -156,10 +146,10 @@ npx @pharaoh-so/mcp --logout
|
|
|
156
146
|
|
|
157
147
|
### Custom Server
|
|
158
148
|
|
|
159
|
-
For self-hosted Pharaoh instances or development:
|
|
149
|
+
For self-hosted Pharaoh instances or development, register manually:
|
|
160
150
|
|
|
161
151
|
```bash
|
|
162
|
-
claude mcp add pharaoh -- npx @pharaoh-so/mcp --server https://your-pharaoh-instance.com
|
|
152
|
+
claude mcp add --scope user pharaoh -- npx @pharaoh-so/mcp --server https://your-pharaoh-instance.com
|
|
163
153
|
```
|
|
164
154
|
|
|
165
155
|
### Environment Variables
|
|
@@ -213,7 +203,7 @@ npx @pharaoh-so/mcp
|
|
|
213
203
|
Make sure you added it with the correct command:
|
|
214
204
|
|
|
215
205
|
```bash
|
|
216
|
-
|
|
206
|
+
npx @pharaoh-so/mcp --setup
|
|
217
207
|
```
|
|
218
208
|
|
|
219
209
|
Note the `--` separator between `pharaoh` and `npx`.
|
|
@@ -230,7 +220,7 @@ The first run after installation may take a moment as npm downloads the package.
|
|
|
230
220
|
|
|
231
221
|
```bash
|
|
232
222
|
npm install -g @pharaoh-so/mcp
|
|
233
|
-
claude mcp add pharaoh -- pharaoh-mcp
|
|
223
|
+
claude mcp add --scope user pharaoh -- pharaoh-mcp
|
|
234
224
|
```
|
|
235
225
|
|
|
236
226
|
## How Pharaoh Works
|
package/dist/helpers.d.ts
CHANGED
package/dist/helpers.js
CHANGED
|
@@ -8,6 +8,7 @@ export function printLines(...lines) {
|
|
|
8
8
|
export function parseArgs(argv = process.argv.slice(2)) {
|
|
9
9
|
let server = DEFAULT_SERVER;
|
|
10
10
|
let logout = false;
|
|
11
|
+
let setup = false;
|
|
11
12
|
for (let i = 0; i < argv.length; i++) {
|
|
12
13
|
if (argv[i] === "--server" && argv[i + 1]) {
|
|
13
14
|
server = argv[i + 1];
|
|
@@ -16,6 +17,9 @@ export function parseArgs(argv = process.argv.slice(2)) {
|
|
|
16
17
|
else if (argv[i] === "--logout") {
|
|
17
18
|
logout = true;
|
|
18
19
|
}
|
|
20
|
+
else if (argv[i] === "--setup") {
|
|
21
|
+
setup = true;
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
// Strip trailing slash
|
|
21
25
|
server = server.replace(/\/+$/, "");
|
|
@@ -37,10 +41,10 @@ export function parseArgs(argv = process.argv.slice(2)) {
|
|
|
37
41
|
printLines(`Pharaoh: --server is not a valid URL: ${server}`);
|
|
38
42
|
process.exit(1);
|
|
39
43
|
}
|
|
40
|
-
return { server, logout };
|
|
44
|
+
return { server, logout, setup };
|
|
41
45
|
}
|
|
42
46
|
export function printUsage() {
|
|
43
|
-
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", "", "
|
|
47
|
+
printLines("Usage: pharaoh-mcp [options]", "", "Options:", " --setup Full install: auth, register MCP, install skills (start here)", " --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 @pharaoh-so/mcp --setup", "");
|
|
44
48
|
}
|
|
45
49
|
/**
|
|
46
50
|
* Validate that a server-supplied SSE URL shares the same origin as the configured server.
|
|
@@ -96,7 +100,7 @@ export function formatTtl(expiresAt) {
|
|
|
96
100
|
* after auth completes (or when credentials already exist).
|
|
97
101
|
*/
|
|
98
102
|
export function printSetupInstructions() {
|
|
99
|
-
printLines("", "┌───────────────────────────────────────────────────────┐", "│
|
|
103
|
+
printLines("", "┌───────────────────────────────────────────────────────┐", "│ To register Pharaoh in Claude Code, run: │", "│ npx @pharaoh-so/mcp --setup │", "│ │", "│ This removes stale entries, registers the MCP │", "│ server globally, and installs all skills. │", "└───────────────────────────────────────────────────────┘", "");
|
|
100
104
|
}
|
|
101
105
|
/** Format a credential identity string (e.g. "alice (my-org)"). */
|
|
102
106
|
export function formatIdentity(creds) {
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ async function main() {
|
|
|
33
33
|
runInstallSkills();
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
const { server, logout } = parseArgs(args);
|
|
36
|
+
const { server, logout, setup } = parseArgs(args);
|
|
37
37
|
if (logout) {
|
|
38
38
|
deleteCredentials();
|
|
39
39
|
printLines("Pharaoh: credentials cleared");
|
|
@@ -41,6 +41,36 @@ async function main() {
|
|
|
41
41
|
}
|
|
42
42
|
const creds = readCredentials();
|
|
43
43
|
const isInteractive = Boolean(process.stdin.isTTY);
|
|
44
|
+
// ── Setup mode (--setup): full automated install ──
|
|
45
|
+
// Auth → remove stale → register MCP → install skills → done.
|
|
46
|
+
if (setup) {
|
|
47
|
+
// Authenticate if needed
|
|
48
|
+
let activeCreds = creds && !isExpired(creds) ? creds : null;
|
|
49
|
+
if (activeCreds) {
|
|
50
|
+
printLines(`Pharaoh: authenticated as ${formatIdentity(activeCreds)} — token valid for ${formatTtl(activeCreds.expires_at)}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
printLines("Pharaoh: starting device authorization...");
|
|
54
|
+
const deviceCode = await requestDeviceCode(server);
|
|
55
|
+
printActivationPrompt(deviceCode.user_code, deviceCode.verification_uri);
|
|
56
|
+
const token = await pollForToken(server, deviceCode.device_code, deviceCode.interval);
|
|
57
|
+
if (token.provisional) {
|
|
58
|
+
printLines(`Pharaoh: provisional access — install the GitHub App to map your repos: ${token.install_url ?? ""}`);
|
|
59
|
+
}
|
|
60
|
+
const sseUrl = resolveSseUrl(token.sse_url, server);
|
|
61
|
+
const newCreds = tokenToCredentials(token, sseUrl);
|
|
62
|
+
writeCredentials(newCreds);
|
|
63
|
+
activeCreds = newCreds;
|
|
64
|
+
printAuthSuccess(token.github_login ?? null, token.tenant_name ?? null, token.repos?.length ?? 0);
|
|
65
|
+
}
|
|
66
|
+
// Register MCP server in Claude Code
|
|
67
|
+
const { runSetup } = await import("./setup.js");
|
|
68
|
+
runSetup();
|
|
69
|
+
// Install skills
|
|
70
|
+
runInstallSkills();
|
|
71
|
+
printLines("", "Pharaoh is ready. Start a new Claude Code conversation and ask:", ' "What modules does this codebase have?"', "");
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
44
74
|
// ── Interactive mode (user running in a terminal) ──
|
|
45
75
|
// Authenticate if needed, print setup instructions, and exit.
|
|
46
76
|
// The proxy is useless without Claude Code on the other end of stdin.
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full automated setup: remove stale entries, register MCP server globally,
|
|
3
|
+
* install skills. Requires valid credentials (caller handles auth first).
|
|
4
|
+
*
|
|
5
|
+
* @returns true if setup succeeded, false if Claude CLI not found.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runSetup(): boolean;
|
package/dist/setup.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --setup implementation for the Pharaoh MCP proxy CLI.
|
|
3
|
+
*
|
|
4
|
+
* Full automated install: authenticates via device flow, removes stale MCP
|
|
5
|
+
* entries, registers Pharaoh as a global stdio MCP server, and installs skills.
|
|
6
|
+
* One command does everything: `npx @pharaoh-so/mcp --setup`
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync } from "node:child_process";
|
|
9
|
+
import { printLines } from "./helpers.js";
|
|
10
|
+
/** Check if `claude` CLI is available in PATH. */
|
|
11
|
+
function hasClaude() {
|
|
12
|
+
try {
|
|
13
|
+
const which = process.platform === "win32" ? "where" : "which";
|
|
14
|
+
execFileSync(which, ["claude"], {
|
|
15
|
+
encoding: "utf-8",
|
|
16
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
17
|
+
});
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Run a claude CLI command, returning true on success. Surfaces stderr on failure. */
|
|
25
|
+
function runClaude(args) {
|
|
26
|
+
try {
|
|
27
|
+
execFileSync("claude", args, {
|
|
28
|
+
encoding: "utf-8",
|
|
29
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
30
|
+
timeout: 30_000,
|
|
31
|
+
});
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err && typeof err === "object" && "stderr" in err) {
|
|
36
|
+
const stderr = err.stderr?.toString().trim();
|
|
37
|
+
if (stderr)
|
|
38
|
+
printLines(` claude ${args.slice(0, 3).join(" ")}: ${stderr}`);
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Full automated setup: remove stale entries, register MCP server globally,
|
|
45
|
+
* install skills. Requires valid credentials (caller handles auth first).
|
|
46
|
+
*
|
|
47
|
+
* @returns true if setup succeeded, false if Claude CLI not found.
|
|
48
|
+
*/
|
|
49
|
+
export function runSetup() {
|
|
50
|
+
if (!hasClaude()) {
|
|
51
|
+
printLines("Pharaoh: Claude Code CLI not found.", "", "Install Claude Code first: https://claude.ai/download", "Then re-run: npx @pharaoh-so/mcp --setup", "");
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
printLines("Pharaoh: setting up...");
|
|
55
|
+
// Step 1: Remove any stale entry (ignore failures — may not exist)
|
|
56
|
+
runClaude(["mcp", "remove", "pharaoh"]);
|
|
57
|
+
// Step 2: Register as global stdio MCP server
|
|
58
|
+
const added = runClaude([
|
|
59
|
+
"mcp",
|
|
60
|
+
"add",
|
|
61
|
+
"--scope",
|
|
62
|
+
"user",
|
|
63
|
+
"pharaoh",
|
|
64
|
+
"--",
|
|
65
|
+
"npx",
|
|
66
|
+
"@pharaoh-so/mcp",
|
|
67
|
+
]);
|
|
68
|
+
if (!added) {
|
|
69
|
+
printLines("Pharaoh: failed to register MCP server.", "Try manually: npx @pharaoh-so/mcp --setup", "");
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
printLines("Pharaoh: registered as global MCP server (scope: user)");
|
|
73
|
+
// Step 3: Install skills (handled by caller via runInstallSkills)
|
|
74
|
+
// We just report the MCP registration success here.
|
|
75
|
+
return true;
|
|
76
|
+
}
|
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.
|
|
4
|
+
"version": "0.3.0",
|
|
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",
|
package/skills/pharaoh/SKILL.md
CHANGED
|
@@ -70,12 +70,12 @@ Full docs at [pharaoh.so/docs](https://pharaoh.so/docs).
|
|
|
70
70
|
|
|
71
71
|
## Connection options
|
|
72
72
|
|
|
73
|
-
**
|
|
73
|
+
**CLI** (Claude Code, OpenClaw — works everywhere):
|
|
74
74
|
```
|
|
75
|
-
|
|
75
|
+
npx @pharaoh-so/mcp --setup
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
**
|
|
78
|
+
**URL** (Claude.ai, Cursor, ChatGPT — paste in settings):
|
|
79
79
|
```
|
|
80
|
-
|
|
80
|
+
https://mcp.pharaoh.so/sse
|
|
81
81
|
```
|