@genrupt/cli 0.1.5 → 0.1.7
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 +23 -12
- package/dist/auth.js +22 -6
- package/dist/cli.js +7 -2
- package/dist/constants.js +1 -1
- package/dist/doctor.js +1 -1
- package/dist/globalCli.js +4 -3
- package/dist/localMcpServer.js +36 -1
- package/dist/mcpClient.js +11 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,20 +6,14 @@ Genrupt CLI for local-file workflows and local MCP clients.
|
|
|
6
6
|
|
|
7
7
|
Use this when setting up Genrupt for an agent:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```powershell
|
|
12
|
-
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "irm https://genrupt.com/downloads/genrupt-cli/install.ps1 | iex"
|
|
13
|
-
genrupt agent install
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Universal one-time run:
|
|
9
|
+
Install the CLI:
|
|
17
10
|
|
|
18
11
|
```bash
|
|
19
|
-
|
|
12
|
+
npm install -g @genrupt/cli@latest
|
|
13
|
+
genrupt agent install
|
|
20
14
|
```
|
|
21
15
|
|
|
22
|
-
This checks auth, installs Genrupt skills for the detected agent, and writes a local runtime manifest.
|
|
16
|
+
This checks auth, installs Genrupt skills for the detected agent, and writes a local runtime manifest.
|
|
23
17
|
|
|
24
18
|
## Install
|
|
25
19
|
|
|
@@ -35,10 +29,10 @@ macOS/Linux:
|
|
|
35
29
|
curl -fsSL https://genrupt.com/downloads/genrupt-cli/install.sh | sh
|
|
36
30
|
```
|
|
37
31
|
|
|
38
|
-
|
|
32
|
+
If global npm install is restricted, run without installing globally:
|
|
39
33
|
|
|
40
34
|
```bash
|
|
41
|
-
|
|
35
|
+
npx -y @genrupt/cli@latest agent install
|
|
42
36
|
```
|
|
43
37
|
|
|
44
38
|
## Login
|
|
@@ -61,6 +55,15 @@ If Genrupt is unreachable and you only want to remove the local file, run:
|
|
|
61
55
|
genrupt auth logout --local
|
|
62
56
|
```
|
|
63
57
|
|
|
58
|
+
If Claude Code or another local MCP client keeps reusing stale credentials after you remove and
|
|
59
|
+
re-add the connector, force a local credential reset:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
genrupt auth reset
|
|
63
|
+
genrupt auth login
|
|
64
|
+
genrupt setup claude-code --replace
|
|
65
|
+
```
|
|
66
|
+
|
|
64
67
|
## Claude Code
|
|
65
68
|
|
|
66
69
|
```bash
|
|
@@ -85,6 +88,14 @@ genrupt doctor
|
|
|
85
88
|
|
|
86
89
|
Checks CLI freshness, auth, remote MCP reachability, installed skills, and the local Genrupt runtime manifest.
|
|
87
90
|
|
|
91
|
+
If the remote MCP check fails, run:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
genrupt auth reset
|
|
95
|
+
genrupt auth login
|
|
96
|
+
genrupt doctor
|
|
97
|
+
```
|
|
98
|
+
|
|
88
99
|
## Runtime Health
|
|
89
100
|
|
|
90
101
|
The CLI sends small best-effort runtime health events for failed agent installs, stale CLI detection, doctor failures, and upload failures. Events are sanitized and do not include local paths, filenames, prompts, uploaded content, or tokens.
|
package/dist/auth.js
CHANGED
|
@@ -126,12 +126,23 @@ export async function login(options = {}) {
|
|
|
126
126
|
}
|
|
127
127
|
export async function refreshAccessToken(config) {
|
|
128
128
|
const endpoints = getAuthEndpoints(config.origin);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
let token;
|
|
130
|
+
try {
|
|
131
|
+
token = await postJson(endpoints.token, {
|
|
132
|
+
grant_type: "refresh_token",
|
|
133
|
+
client_id: config.clientId,
|
|
134
|
+
refresh_token: config.refreshToken,
|
|
135
|
+
resource: config.mcpServerUrl,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (error instanceof HttpError &&
|
|
140
|
+
["invalid_grant", "invalid_client", "invalid_target"].includes(getErrorCode(error.payload) ?? "")) {
|
|
141
|
+
await clearConfig();
|
|
142
|
+
throw new Error(`Genrupt auth expired or was revoked. Cleared local credentials at ${getConfigPath()}. Run \`genrupt auth login\` to reconnect.`);
|
|
143
|
+
}
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
135
146
|
const nextConfig = {
|
|
136
147
|
...config,
|
|
137
148
|
accessToken: token.access_token,
|
|
@@ -201,6 +212,11 @@ export async function logout(options = {}) {
|
|
|
201
212
|
await clearConfig();
|
|
202
213
|
console.log("Logged out.");
|
|
203
214
|
}
|
|
215
|
+
export async function resetLocalAuth() {
|
|
216
|
+
await clearConfig();
|
|
217
|
+
console.log(`Cleared local Genrupt credentials at ${getConfigPath()}.`);
|
|
218
|
+
console.log("Run `genrupt auth login` to reconnect.");
|
|
219
|
+
}
|
|
204
220
|
export async function assertLoggedIn() {
|
|
205
221
|
await getValidAccessToken();
|
|
206
222
|
}
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import { CLI_VERSION } from "./constants.js";
|
|
4
4
|
import { installAgentRuntime } from "./agent.js";
|
|
5
|
-
import { login, logout, printAuthStatus } from "./auth.js";
|
|
5
|
+
import { login, logout, printAuthStatus, resetLocalAuth } from "./auth.js";
|
|
6
6
|
import { callRemoteMcpTool, assertSuccessfulToolPayload } from "./mcpClient.js";
|
|
7
7
|
import { serveLocalMcp } from "./localMcpServer.js";
|
|
8
8
|
import { setupClaudeCode } from "./setup.js";
|
|
@@ -76,6 +76,7 @@ Usage:
|
|
|
76
76
|
genrupt auth login [--origin https://genrupt.com] [--no-open]
|
|
77
77
|
genrupt auth status
|
|
78
78
|
genrupt auth logout [--local]
|
|
79
|
+
genrupt auth reset
|
|
79
80
|
genrupt version
|
|
80
81
|
|
|
81
82
|
genrupt agent install [--agent claude|codex|cursor] [--target PATH] [--skip-auth] [--skip-global-install]
|
|
@@ -153,6 +154,10 @@ async function handleAuth(args) {
|
|
|
153
154
|
});
|
|
154
155
|
return;
|
|
155
156
|
}
|
|
157
|
+
if (subcommand === "reset") {
|
|
158
|
+
await resetLocalAuth();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
156
161
|
throw new Error("Unknown auth command. Run `genrupt --help`.");
|
|
157
162
|
}
|
|
158
163
|
async function handleSetup(args) {
|
|
@@ -360,5 +365,5 @@ main().catch(async (error) => {
|
|
|
360
365
|
? await buildUnknownCommandUpdateHint()
|
|
361
366
|
: "";
|
|
362
367
|
console.error(`${message}${updateHint}`);
|
|
363
|
-
process.
|
|
368
|
+
process.exitCode = 1;
|
|
364
369
|
});
|
package/dist/constants.js
CHANGED
|
@@ -3,5 +3,5 @@ export const DEFAULT_MCP_SERVER_URL = `${DEFAULT_ORIGIN}/api/agent/mcp`;
|
|
|
3
3
|
export const OAUTH_DEVICE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
|
|
4
4
|
export const OAUTH_SCOPE = "mcp";
|
|
5
5
|
export const CLI_CLIENT_NAME = "Genrupt CLI";
|
|
6
|
-
export const CLI_VERSION = "0.1.
|
|
6
|
+
export const CLI_VERSION = "0.1.7";
|
|
7
7
|
export const ACCESS_TOKEN_REFRESH_SKEW_MS = 60_000;
|
package/dist/doctor.js
CHANGED
|
@@ -234,7 +234,7 @@ export async function runDoctor(options = {}) {
|
|
|
234
234
|
label: "Remote MCP",
|
|
235
235
|
status: "fail",
|
|
236
236
|
detail: message,
|
|
237
|
-
remediation: "Run: genrupt auth login, then retry genrupt doctor",
|
|
237
|
+
remediation: "Run: genrupt auth reset, then genrupt auth login, then retry genrupt doctor",
|
|
238
238
|
});
|
|
239
239
|
}
|
|
240
240
|
}
|
package/dist/globalCli.js
CHANGED
|
@@ -180,10 +180,11 @@ export function buildGlobalCliDiagnosticsLines(diagnostics) {
|
|
|
180
180
|
}
|
|
181
181
|
export function buildNoGlobalInstallRemediation() {
|
|
182
182
|
return [
|
|
183
|
-
|
|
184
|
-
`
|
|
183
|
+
`Update the global CLI:`,
|
|
184
|
+
` npm install -g ${CLI_PACKAGE_NAME}@latest`,
|
|
185
185
|
"Or keep using npx:",
|
|
186
186
|
` npx -y ${CLI_PACKAGE_NAME}@latest doctor`,
|
|
187
|
-
"If
|
|
187
|
+
"If global npm install is restricted, install the user-local launcher:",
|
|
188
|
+
` powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "irm https://genrupt.com/downloads/genrupt-cli/install.ps1 | iex"`,
|
|
188
189
|
];
|
|
189
190
|
}
|
package/dist/localMcpServer.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
4
4
|
import { CLI_VERSION } from "./constants.js";
|
|
5
|
+
import { getConfigPath, readConfig } from "./config.js";
|
|
5
6
|
import { listRemoteMcpTools, callRemoteMcpTool } from "./mcpClient.js";
|
|
6
7
|
import { uploadProductReferenceImages, uploadReferenceMedia, } from "./upload.js";
|
|
7
8
|
import { classifyCliError, emitRuntimeTelemetry } from "./telemetry.js";
|
|
@@ -43,6 +44,16 @@ const LOCAL_UPLOAD_TOOL = {
|
|
|
43
44
|
additionalProperties: false,
|
|
44
45
|
},
|
|
45
46
|
};
|
|
47
|
+
const LOCAL_AUTH_STATUS_TOOL = {
|
|
48
|
+
name: "get_genrupt_cli_auth_status",
|
|
49
|
+
title: "Get Genrupt CLI auth status",
|
|
50
|
+
description: "Use when Genrupt MCP tools are missing, failing to connect, or asking for auth repair. This local diagnostic tool checks whether this machine has cached Genrupt CLI credentials and returns the credential file path plus exact repair commands. It does not validate credentials with the server or expose tokens.",
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {},
|
|
54
|
+
additionalProperties: false,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
46
57
|
const LOCAL_REFERENCE_MEDIA_UPLOAD_TOOL = {
|
|
47
58
|
name: "upload_reference_media",
|
|
48
59
|
title: "Upload local reference media",
|
|
@@ -144,6 +155,26 @@ async function handleLocalReferenceMediaUploadTool(args) {
|
|
|
144
155
|
});
|
|
145
156
|
return buildToolResult(payload);
|
|
146
157
|
}
|
|
158
|
+
async function handleLocalAuthStatusTool() {
|
|
159
|
+
const config = await readConfig();
|
|
160
|
+
return buildToolResult({
|
|
161
|
+
hasLocalCredentials: Boolean(config),
|
|
162
|
+
configPath: getConfigPath(),
|
|
163
|
+
origin: config?.origin ?? null,
|
|
164
|
+
mcpServerUrl: config?.mcpServerUrl ?? null,
|
|
165
|
+
accessTokenExpiresAt: config?.accessTokenExpiresAt ?? null,
|
|
166
|
+
scope: config?.scope ?? null,
|
|
167
|
+
nextActions: config
|
|
168
|
+
? [
|
|
169
|
+
"Run `genrupt doctor` to validate the remote MCP connection.",
|
|
170
|
+
"If Claude Code still fails, run `genrupt auth reset`, then `genrupt auth login`, then restart Claude Code.",
|
|
171
|
+
]
|
|
172
|
+
: [
|
|
173
|
+
"Run `genrupt auth login` to connect this machine.",
|
|
174
|
+
"Run `genrupt setup claude-code --replace` after login if Claude Code does not show Genrupt.",
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
}
|
|
147
178
|
export async function serveLocalMcp() {
|
|
148
179
|
const server = new Server({
|
|
149
180
|
name: "genrupt-cli",
|
|
@@ -159,6 +190,7 @@ export async function serveLocalMcp() {
|
|
|
159
190
|
const remote = await listRemoteMcpTools();
|
|
160
191
|
return {
|
|
161
192
|
tools: [
|
|
193
|
+
LOCAL_AUTH_STATUS_TOOL,
|
|
162
194
|
LOCAL_UPLOAD_TOOL,
|
|
163
195
|
LOCAL_REFERENCE_MEDIA_UPLOAD_TOOL,
|
|
164
196
|
...remote.tools.filter((tool) => tool.name !== LOCAL_UPLOAD_TOOL.name &&
|
|
@@ -169,7 +201,7 @@ export async function serveLocalMcp() {
|
|
|
169
201
|
catch (error) {
|
|
170
202
|
console.error(`[genrupt] Failed to list remote MCP tools: ${error instanceof Error ? error.message : String(error)}`);
|
|
171
203
|
return {
|
|
172
|
-
tools: [
|
|
204
|
+
tools: [LOCAL_AUTH_STATUS_TOOL],
|
|
173
205
|
};
|
|
174
206
|
}
|
|
175
207
|
});
|
|
@@ -184,6 +216,9 @@ export async function serveLocalMcp() {
|
|
|
184
216
|
if (request.params.name === LOCAL_REFERENCE_MEDIA_UPLOAD_TOOL.name) {
|
|
185
217
|
return await handleLocalReferenceMediaUploadTool(args);
|
|
186
218
|
}
|
|
219
|
+
if (request.params.name === LOCAL_AUTH_STATUS_TOOL.name) {
|
|
220
|
+
return await handleLocalAuthStatusTool();
|
|
221
|
+
}
|
|
187
222
|
return await callRemoteMcpTool(request.params.name, args);
|
|
188
223
|
}
|
|
189
224
|
catch (error) {
|
package/dist/mcpClient.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getValidAccessToken, getValidConfig, refreshAccessToken } from "./auth.js";
|
|
2
|
+
import { clearConfig, getConfigPath } from "./config.js";
|
|
2
3
|
import { HttpError, getErrorDescription } from "./http.js";
|
|
3
4
|
let nextJsonRpcId = 1;
|
|
4
5
|
function parseEventStreamPayload(text) {
|
|
@@ -53,7 +54,16 @@ async function withAuthRetry(call) {
|
|
|
53
54
|
throw error;
|
|
54
55
|
}
|
|
55
56
|
const refreshed = await refreshAccessToken(config);
|
|
56
|
-
|
|
57
|
+
try {
|
|
58
|
+
return await call(refreshed.accessToken, refreshed.mcpServerUrl);
|
|
59
|
+
}
|
|
60
|
+
catch (retryError) {
|
|
61
|
+
if (retryError instanceof HttpError && retryError.status === 401) {
|
|
62
|
+
await clearConfig();
|
|
63
|
+
throw new Error(`Genrupt auth is no longer valid. Cleared local credentials at ${getConfigPath()}. Run \`genrupt auth login\` to reconnect.`);
|
|
64
|
+
}
|
|
65
|
+
throw retryError;
|
|
66
|
+
}
|
|
57
67
|
}
|
|
58
68
|
}
|
|
59
69
|
export async function listRemoteMcpTools() {
|