autorouter-mcp 0.2.5 → 0.2.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 +38 -1
- package/dist/cli.js +282 -16
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -364,12 +364,41 @@ autorouter adopt --target claude --servers-only # skip skills and plugins
|
|
|
364
364
|
autorouter adopt --target claude --keep project-tools --keep-plugin ui-toolkit
|
|
365
365
|
autorouter restore --target claude # undo the most recent adopt
|
|
366
366
|
|
|
367
|
+
autorouter update # upgrade in place
|
|
368
|
+
autorouter update --check # is there a newer version?
|
|
369
|
+
|
|
367
370
|
autorouter login # which servers need a grant
|
|
368
371
|
autorouter login remote-server # authorize one (opens a browser)
|
|
369
372
|
autorouter login remote-server --device # headless: enter a code elsewhere
|
|
373
|
+
autorouter login remote-server --no-reindex # authorize, index later
|
|
370
374
|
autorouter logout remote-server # forget a stored grant
|
|
371
375
|
```
|
|
372
376
|
|
|
377
|
+
## Updating
|
|
378
|
+
|
|
379
|
+
`autorouter update` upgrades in place, using the package manager that installed
|
|
380
|
+
the copy you are running:
|
|
381
|
+
|
|
382
|
+
```sh
|
|
383
|
+
autorouter update # detect, then upgrade
|
|
384
|
+
autorouter update --check # report the available version, install nothing
|
|
385
|
+
autorouter update --dry-run # print the command, do not run it
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Which manager to use is decided by where the running file sits on disk, not by
|
|
389
|
+
what happens to be on `PATH` — running `npm i -g` against a pnpm-managed global
|
|
390
|
+
installs a second copy that shadows the first, and you would then be upgrading
|
|
391
|
+
one install while running the other.
|
|
392
|
+
|
|
393
|
+
Three cases do not run a package manager, and say so instead: a copy unpacked by
|
|
394
|
+
`npx`/`bunx`/`pnpm dlx` (nothing to upgrade — those refetch every run), a git
|
|
395
|
+
checkout (`git pull && bun install && bun run build`), and a layout it cannot
|
|
396
|
+
identify. All three still report whether a newer version exists.
|
|
397
|
+
|
|
398
|
+
The router is a long-lived stdio server, so a harness that already has it
|
|
399
|
+
running keeps the old build until it respawns it — restart the harness, or
|
|
400
|
+
reconnect the MCP server, after updating.
|
|
401
|
+
|
|
373
402
|
## OAuth servers
|
|
374
403
|
|
|
375
404
|
Some remote MCP servers carry no credentials in their visible configuration.
|
|
@@ -382,9 +411,17 @@ has a token to borrow:
|
|
|
382
411
|
|
|
383
412
|
```sh
|
|
384
413
|
autorouter login remote-server
|
|
385
|
-
autorouter reindex
|
|
386
414
|
```
|
|
387
415
|
|
|
416
|
+
A new grant is followed by a reindex automatically, because the capabilities
|
|
417
|
+
behind it are not searchable until the catalog has seen them — a grant on its
|
|
418
|
+
own changes nothing the router can reach. `--no-reindex` skips it when you are
|
|
419
|
+
authorizing several servers in a row and would rather index once at the end.
|
|
420
|
+
|
|
421
|
+
Only a login that actually stores a new grant triggers it. `--list-scopes` and a
|
|
422
|
+
server that already had a grant both change nothing, so neither pays for an
|
|
423
|
+
index rebuild.
|
|
424
|
+
|
|
388
425
|
Registration is RFC 7591 dynamic client registration, so there is no app to
|
|
389
426
|
create first. Tokens live in `~/.autorouter/oauth/<server>.json` at `0600` and
|
|
390
427
|
are refreshed automatically; `logout` deletes them. The loopback redirect uses a
|
package/dist/cli.js
CHANGED
|
@@ -19474,6 +19474,18 @@ function run(command, args, opts = {}) {
|
|
|
19474
19474
|
child.stdin.end();
|
|
19475
19475
|
});
|
|
19476
19476
|
}
|
|
19477
|
+
function runStreaming(command, args, opts = {}) {
|
|
19478
|
+
return new Promise((resolve, reject) => {
|
|
19479
|
+
const child = spawn2(command, args, {
|
|
19480
|
+
stdio: "inherit",
|
|
19481
|
+
cwd: opts.cwd,
|
|
19482
|
+
env: opts.env,
|
|
19483
|
+
shell: process.platform === "win32"
|
|
19484
|
+
});
|
|
19485
|
+
child.on("error", reject);
|
|
19486
|
+
child.on("close", (code) => resolve(code));
|
|
19487
|
+
});
|
|
19488
|
+
}
|
|
19477
19489
|
function which(command) {
|
|
19478
19490
|
const isWindows = process.platform === "win32";
|
|
19479
19491
|
const exts = isWindows ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean) : [""];
|
|
@@ -22311,6 +22323,7 @@ async function runLogin(opts) {
|
|
|
22311
22323
|
return result;
|
|
22312
22324
|
return {
|
|
22313
22325
|
ok: true,
|
|
22326
|
+
authorized: true,
|
|
22314
22327
|
message: `${entry.name}: authorized.` + (result.grantedScope ? `
|
|
22315
22328
|
${summarizeScopes(result.grantedScope)}` : "")
|
|
22316
22329
|
};
|
|
@@ -22454,7 +22467,11 @@ Opening your browser to authorize ${entry.name}:
|
|
|
22454
22467
|
try {
|
|
22455
22468
|
const first = await auth(provider, { serverUrl: entry.url, scope });
|
|
22456
22469
|
if (first === "AUTHORIZED") {
|
|
22457
|
-
return {
|
|
22470
|
+
return {
|
|
22471
|
+
ok: true,
|
|
22472
|
+
authorized: true,
|
|
22473
|
+
message: `${entry.name}: already authorized (existing grant is still valid).`
|
|
22474
|
+
};
|
|
22458
22475
|
}
|
|
22459
22476
|
pendingState = (await readAuth(entry.name)).state;
|
|
22460
22477
|
const code = mode === "manual" ? await readPastedCode(pendingState) : await withTimeout2(codePromise, 5 * 60000, "waiting for the browser callback");
|
|
@@ -22466,8 +22483,12 @@ Opening your browser to authorize ${entry.name}:
|
|
|
22466
22483
|
await writeAuth(entry.name, { requestedScope: scope });
|
|
22467
22484
|
const stored = await readAuth(entry.name);
|
|
22468
22485
|
const granted = stored.tokens?.scope ?? scope;
|
|
22469
|
-
return {
|
|
22470
|
-
|
|
22486
|
+
return {
|
|
22487
|
+
ok: true,
|
|
22488
|
+
authorized: true,
|
|
22489
|
+
message: `${entry.name}: authorized.${granted ? `
|
|
22490
|
+
${summarizeScopes(granted)}` : ""}`
|
|
22491
|
+
};
|
|
22471
22492
|
} catch (err) {
|
|
22472
22493
|
return { ok: false, message: `${entry.name}: ${err instanceof Error ? err.message : String(err)}` };
|
|
22473
22494
|
} finally {
|
|
@@ -22585,8 +22606,224 @@ function summarizeScopes(scope, limit = 6) {
|
|
|
22585
22606
|
return `scope: ${all.length} granted, ${writes.length} of them write (${writes.slice(0, 3).join(", ") || "none"}${writes.length > 3 ? ", …" : ""})`;
|
|
22586
22607
|
}
|
|
22587
22608
|
|
|
22609
|
+
// src/cli/update.ts
|
|
22610
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
22611
|
+
import { fileURLToPath } from "node:url";
|
|
22612
|
+
import { dirname as dirname3, join as join18, resolve as resolve2, sep } from "node:path";
|
|
22613
|
+
var PACKAGE_NAME = "autorouter-mcp";
|
|
22614
|
+
function entryPath() {
|
|
22615
|
+
let raw;
|
|
22616
|
+
try {
|
|
22617
|
+
raw = fileURLToPath(import.meta.url);
|
|
22618
|
+
} catch {
|
|
22619
|
+
raw = process.argv[1] ?? "";
|
|
22620
|
+
}
|
|
22621
|
+
try {
|
|
22622
|
+
return realpathSync(raw);
|
|
22623
|
+
} catch {
|
|
22624
|
+
return raw;
|
|
22625
|
+
}
|
|
22626
|
+
}
|
|
22627
|
+
function packageRoot(from, exists) {
|
|
22628
|
+
let dir = dirname3(from);
|
|
22629
|
+
for (let i = 0;i < 12; i++) {
|
|
22630
|
+
if (exists(join18(dir, "package.json")))
|
|
22631
|
+
return dir;
|
|
22632
|
+
const parent = dirname3(dir);
|
|
22633
|
+
if (parent === dir)
|
|
22634
|
+
break;
|
|
22635
|
+
dir = parent;
|
|
22636
|
+
}
|
|
22637
|
+
return;
|
|
22638
|
+
}
|
|
22639
|
+
function managerFromLockfile(dir, exists) {
|
|
22640
|
+
if (exists(join18(dir, "bun.lock")) || exists(join18(dir, "bun.lockb")))
|
|
22641
|
+
return "bun";
|
|
22642
|
+
if (exists(join18(dir, "pnpm-lock.yaml")))
|
|
22643
|
+
return "pnpm";
|
|
22644
|
+
if (exists(join18(dir, "yarn.lock")))
|
|
22645
|
+
return "yarn";
|
|
22646
|
+
return "npm";
|
|
22647
|
+
}
|
|
22648
|
+
function detectInstall(entry, exists = existsSync) {
|
|
22649
|
+
const root = packageRoot(entry, exists);
|
|
22650
|
+
if (!root)
|
|
22651
|
+
return { kind: "unknown", dir: dirname3(entry) };
|
|
22652
|
+
const path = root.split(sep).join("/");
|
|
22653
|
+
if (exists(join18(root, ".git")))
|
|
22654
|
+
return { kind: "source", dir: root };
|
|
22655
|
+
const transient = path.includes("/_npx/") && "npx" || /\/dlx(-|\/)/.test(path) && "pnpm dlx" || path.includes("/.bun/install/cache/") && "bunx" || null;
|
|
22656
|
+
if (transient)
|
|
22657
|
+
return { kind: "transient", runner: transient, dir: root };
|
|
22658
|
+
const nodeModules = dirname3(root);
|
|
22659
|
+
const parent = dirname3(nodeModules);
|
|
22660
|
+
const globalManager = path.includes("/.bun/install/global/") ? "bun" : /\/pnpm\/global\/|\/pnpm\/[0-9]+\/node_modules\//.test(path) ? "pnpm" : /\/\.config\/yarn\/global\/|\/\.yarn\/global\//.test(path) ? "yarn" : null;
|
|
22661
|
+
if (globalManager)
|
|
22662
|
+
return { kind: "global", manager: globalManager, dir: root };
|
|
22663
|
+
if (nodeModules.split(sep).pop() === "node_modules") {
|
|
22664
|
+
if (exists(join18(parent, "package.json"))) {
|
|
22665
|
+
return {
|
|
22666
|
+
kind: "project",
|
|
22667
|
+
manager: managerFromLockfile(parent, exists),
|
|
22668
|
+
dir: root,
|
|
22669
|
+
projectDir: parent
|
|
22670
|
+
};
|
|
22671
|
+
}
|
|
22672
|
+
return { kind: "global", manager: "npm", dir: root };
|
|
22673
|
+
}
|
|
22674
|
+
return { kind: "unknown", dir: root };
|
|
22675
|
+
}
|
|
22676
|
+
function updateCommand(install, pkg, version = "latest") {
|
|
22677
|
+
const spec = `${pkg}@${version}`;
|
|
22678
|
+
if (install.kind === "global") {
|
|
22679
|
+
switch (install.manager) {
|
|
22680
|
+
case "bun":
|
|
22681
|
+
return ["bun", "add", "-g", spec];
|
|
22682
|
+
case "pnpm":
|
|
22683
|
+
return ["pnpm", "add", "-g", spec];
|
|
22684
|
+
case "yarn":
|
|
22685
|
+
return ["yarn", "global", "add", spec];
|
|
22686
|
+
default:
|
|
22687
|
+
return ["npm", "install", "-g", spec];
|
|
22688
|
+
}
|
|
22689
|
+
}
|
|
22690
|
+
if (install.kind === "project") {
|
|
22691
|
+
switch (install.manager) {
|
|
22692
|
+
case "bun":
|
|
22693
|
+
return ["bun", "add", spec];
|
|
22694
|
+
case "pnpm":
|
|
22695
|
+
return ["pnpm", "add", spec];
|
|
22696
|
+
case "yarn":
|
|
22697
|
+
return ["yarn", "add", spec];
|
|
22698
|
+
default:
|
|
22699
|
+
return ["npm", "install", spec];
|
|
22700
|
+
}
|
|
22701
|
+
}
|
|
22702
|
+
return null;
|
|
22703
|
+
}
|
|
22704
|
+
function compareVersions2(a, b) {
|
|
22705
|
+
const split = (v) => {
|
|
22706
|
+
const [core = "", pre] = v.replace(/^v/, "").split("-", 2);
|
|
22707
|
+
const parts = core.split(".").map((n) => Number.parseInt(n, 10) || 0);
|
|
22708
|
+
return { parts, pre };
|
|
22709
|
+
};
|
|
22710
|
+
const x = split(a);
|
|
22711
|
+
const y = split(b);
|
|
22712
|
+
for (let i = 0;i < 3; i++) {
|
|
22713
|
+
const d = (x.parts[i] ?? 0) - (y.parts[i] ?? 0);
|
|
22714
|
+
if (d !== 0)
|
|
22715
|
+
return d < 0 ? -1 : 1;
|
|
22716
|
+
}
|
|
22717
|
+
if (x.pre && !y.pre)
|
|
22718
|
+
return -1;
|
|
22719
|
+
if (!x.pre && y.pre)
|
|
22720
|
+
return 1;
|
|
22721
|
+
if (x.pre && y.pre && x.pre !== y.pre)
|
|
22722
|
+
return x.pre < y.pre ? -1 : 1;
|
|
22723
|
+
return 0;
|
|
22724
|
+
}
|
|
22725
|
+
async function latestVersion(pkg, fetchFn = fetch) {
|
|
22726
|
+
const base = (process.env.npm_config_registry ?? process.env.NPM_CONFIG_REGISTRY ?? "https://registry.npmjs.org").replace(/\/+$/, "");
|
|
22727
|
+
try {
|
|
22728
|
+
const res = await fetchFn(`${base}/${encodeURIComponent(pkg)}/latest`, {
|
|
22729
|
+
headers: { accept: "application/json" },
|
|
22730
|
+
signal: AbortSignal.timeout(1e4)
|
|
22731
|
+
});
|
|
22732
|
+
if (!res.ok)
|
|
22733
|
+
return { error: `registry returned ${res.status}` };
|
|
22734
|
+
const body = await res.json();
|
|
22735
|
+
return body.version ? { version: body.version } : { error: "registry returned no version" };
|
|
22736
|
+
} catch (err) {
|
|
22737
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
22738
|
+
}
|
|
22739
|
+
}
|
|
22740
|
+
function cannotUpdate(install, pkg) {
|
|
22741
|
+
if (install.kind === "transient") {
|
|
22742
|
+
return `This copy was unpacked by ${install.runner}, which fetches the package fresh on every run —
|
|
22743
|
+
` + ` there is no install here to upgrade. You are already getting the latest each time.
|
|
22744
|
+
` + ` To keep a copy that does not re-download: npm install -g ${pkg}`;
|
|
22745
|
+
}
|
|
22746
|
+
if (install.kind === "source") {
|
|
22747
|
+
return `This is a checkout running from source (${install.dir}), not a package install.
|
|
22748
|
+
` + ` Update it with: git -C ${install.dir} pull && bun install && bun run build`;
|
|
22749
|
+
}
|
|
22750
|
+
return `Could not tell which package manager installed this copy (${install.dir}).
|
|
22751
|
+
` + ` Upgrade it the way you installed it, e.g. npm install -g ${pkg}@latest`;
|
|
22752
|
+
}
|
|
22753
|
+
function describe2(install) {
|
|
22754
|
+
switch (install.kind) {
|
|
22755
|
+
case "global":
|
|
22756
|
+
return `${install.manager} global install at ${install.dir}`;
|
|
22757
|
+
case "project":
|
|
22758
|
+
return `${install.manager} dependency of ${install.projectDir}`;
|
|
22759
|
+
case "transient":
|
|
22760
|
+
return `${install.runner} temporary copy at ${install.dir}`;
|
|
22761
|
+
case "source":
|
|
22762
|
+
return `source checkout at ${install.dir}`;
|
|
22763
|
+
default:
|
|
22764
|
+
return `unrecognized install at ${install.dir}`;
|
|
22765
|
+
}
|
|
22766
|
+
}
|
|
22767
|
+
async function runUpdate(opts) {
|
|
22768
|
+
const entry = opts.entry ?? entryPath();
|
|
22769
|
+
const install = detectInstall(entry, opts.exists);
|
|
22770
|
+
const manifest = install.kind === "unknown" ? null : await readJson(join18(install.dir, "package.json"));
|
|
22771
|
+
const pkg = manifest?.name ?? PACKAGE_NAME;
|
|
22772
|
+
const latest = await latestVersion(pkg, opts.fetchFn);
|
|
22773
|
+
if ("error" in latest) {
|
|
22774
|
+
return { ok: false, message: `Could not reach the registry to check for updates: ${latest.error}` };
|
|
22775
|
+
}
|
|
22776
|
+
const behind = compareVersions2(opts.current, latest.version) < 0;
|
|
22777
|
+
const status = behind ? `autorouter ${opts.current} → ${latest.version} available` : `autorouter ${opts.current} is up to date (latest is ${latest.version})`;
|
|
22778
|
+
const command = updateCommand(install, pkg, latest.version);
|
|
22779
|
+
if (!command) {
|
|
22780
|
+
return { ok: !behind, message: `${status}
|
|
22781
|
+
|
|
22782
|
+
${cannotUpdate(install, pkg)}` };
|
|
22783
|
+
}
|
|
22784
|
+
const printable = command.join(" ");
|
|
22785
|
+
if (opts.check) {
|
|
22786
|
+
return { ok: true, message: `${status}
|
|
22787
|
+
${describe2(install)}
|
|
22788
|
+
Update with: ${printable}` };
|
|
22789
|
+
}
|
|
22790
|
+
if (!behind && !opts.force) {
|
|
22791
|
+
return { ok: true, message: `${status}
|
|
22792
|
+
${describe2(install)}
|
|
22793
|
+
Re-install anyway with: --force` };
|
|
22794
|
+
}
|
|
22795
|
+
if (opts.dryRun) {
|
|
22796
|
+
return { ok: true, message: `${status}
|
|
22797
|
+
${describe2(install)}
|
|
22798
|
+
Would run: ${printable}` };
|
|
22799
|
+
}
|
|
22800
|
+
console.log(`${status}
|
|
22801
|
+
${describe2(install)}
|
|
22802
|
+
Running: ${printable}
|
|
22803
|
+
`);
|
|
22804
|
+
const code = await runStreaming(command[0], command.slice(1), {
|
|
22805
|
+
cwd: install.kind === "project" ? install.projectDir : undefined
|
|
22806
|
+
}).catch((err) => err);
|
|
22807
|
+
if (code instanceof Error) {
|
|
22808
|
+
return {
|
|
22809
|
+
ok: false,
|
|
22810
|
+
message: `Could not run ${command[0]}: ${code.message}
|
|
22811
|
+
` + ` Run it yourself: ${printable}`
|
|
22812
|
+
};
|
|
22813
|
+
}
|
|
22814
|
+
if (code !== 0) {
|
|
22815
|
+
return { ok: false, message: `${command[0]} exited with code ${code}. Nothing was changed by autorouter.` };
|
|
22816
|
+
}
|
|
22817
|
+
return {
|
|
22818
|
+
ok: true,
|
|
22819
|
+
message: `
|
|
22820
|
+
Updated to ${latest.version}. Restart any harness with the router running to pick it up` + `
|
|
22821
|
+
(it is a long-lived stdio server, so an open session keeps the old build).`
|
|
22822
|
+
};
|
|
22823
|
+
}
|
|
22824
|
+
|
|
22588
22825
|
// src/cli.ts
|
|
22589
|
-
var VERSION2 = "0.2.
|
|
22826
|
+
var VERSION2 = "0.2.7";
|
|
22590
22827
|
var USAGE = `autorouter — one search tool instead of every tool
|
|
22591
22828
|
|
|
22592
22829
|
autorouter serve Run as an MCP server over stdio (default)
|
|
@@ -22596,6 +22833,9 @@ var USAGE = `autorouter — one search tool instead of every tool
|
|
|
22596
22833
|
autorouter list [--kind K] List everything in the catalog
|
|
22597
22834
|
autorouter reindex Rebuild the catalog now
|
|
22598
22835
|
autorouter doctor Show what is reachable and what it saves
|
|
22836
|
+
autorouter update Upgrade via the package manager that
|
|
22837
|
+
installed this copy. --check to look
|
|
22838
|
+
without installing.
|
|
22599
22839
|
autorouter login [server] Authorize an OAuth server (opens a browser,
|
|
22600
22840
|
or prints a code on a headless box);
|
|
22601
22841
|
with no argument, lists what needs one
|
|
@@ -22623,6 +22863,8 @@ Options
|
|
|
22623
22863
|
--json machine-readable output
|
|
22624
22864
|
--yes init/adopt: do not prompt
|
|
22625
22865
|
--dry-run adopt: show what would move, change nothing
|
|
22866
|
+
update: print the upgrade command without running it
|
|
22867
|
+
--check update: report the available version, install nothing
|
|
22626
22868
|
--force adopt: proceed even if a server is unreachable
|
|
22627
22869
|
--keep S adopt: leave server S registered in the harness (comma-separated)
|
|
22628
22870
|
--keep-skill S adopt: leave skill S loaded (comma-separated)
|
|
@@ -22637,6 +22879,7 @@ Options
|
|
|
22637
22879
|
any narrowing the previous grant carried
|
|
22638
22880
|
--scopes S login: request exactly these scopes (comma or space separated)
|
|
22639
22881
|
--list-scopes login: show what the server offers, authorize nothing
|
|
22882
|
+
--no-reindex login: skip the reindex that otherwise follows a new grant
|
|
22640
22883
|
--device login: RFC 8628 — print a code to enter on another device and
|
|
22641
22884
|
poll for the result. No browser or open port needed here.
|
|
22642
22885
|
--manual login: print the authorization URL, then read the redirect you
|
|
@@ -22666,18 +22909,23 @@ async function main(argv) {
|
|
|
22666
22909
|
return await cmdCall(positionals[0], flags);
|
|
22667
22910
|
case "list":
|
|
22668
22911
|
return await cmdList(flags);
|
|
22669
|
-
case "reindex":
|
|
22670
|
-
|
|
22671
|
-
console.log(`Reindexed: ${router.summary()}`);
|
|
22672
|
-
const failures = Object.entries(router.catalog.errors);
|
|
22673
|
-
for (const [name, err] of failures)
|
|
22674
|
-
console.error(` unreachable: ${name}: ${oneLine(err, 100)}`);
|
|
22675
|
-
await router.close();
|
|
22912
|
+
case "reindex":
|
|
22913
|
+
await cmdReindex();
|
|
22676
22914
|
return 0;
|
|
22677
|
-
}
|
|
22678
22915
|
case "doctor":
|
|
22679
22916
|
console.log(await runDoctor(process.cwd()));
|
|
22680
22917
|
return 0;
|
|
22918
|
+
case "update":
|
|
22919
|
+
case "upgrade": {
|
|
22920
|
+
const result = await runUpdate({
|
|
22921
|
+
current: VERSION2,
|
|
22922
|
+
check: Boolean(flags.check),
|
|
22923
|
+
dryRun: Boolean(flags["dry-run"]),
|
|
22924
|
+
force: Boolean(flags.force)
|
|
22925
|
+
});
|
|
22926
|
+
console.log(result.message);
|
|
22927
|
+
return result.ok ? 0 : 1;
|
|
22928
|
+
}
|
|
22681
22929
|
case "init":
|
|
22682
22930
|
return await cmdInit(flags);
|
|
22683
22931
|
case "login":
|
|
@@ -22745,6 +22993,14 @@ async function cmdRemove(name) {
|
|
|
22745
22993
|
console.log(await runRemove(name));
|
|
22746
22994
|
return 0;
|
|
22747
22995
|
}
|
|
22996
|
+
async function cmdReindex() {
|
|
22997
|
+
const router = await Router.create({ force: true });
|
|
22998
|
+
console.log(`Reindexed: ${router.summary()}`);
|
|
22999
|
+
for (const [name, err] of Object.entries(router.catalog.errors)) {
|
|
23000
|
+
console.error(` unreachable: ${name}: ${oneLine(err, 100)}`);
|
|
23001
|
+
}
|
|
23002
|
+
await router.close();
|
|
23003
|
+
}
|
|
22748
23004
|
async function cmdLogin(server, flags) {
|
|
22749
23005
|
if (!server) {
|
|
22750
23006
|
const resolved = await resolveConfig(process.cwd());
|
|
@@ -22794,10 +23050,20 @@ ${pending.length} need a grant; each is a separate authorization:`);
|
|
|
22794
23050
|
manual: Boolean(flags.manual)
|
|
22795
23051
|
});
|
|
22796
23052
|
console.log(result.message);
|
|
22797
|
-
if (result.
|
|
22798
|
-
|
|
23053
|
+
if (!result.authorized)
|
|
23054
|
+
return result.ok ? 0 : 1;
|
|
23055
|
+
if (flags["no-reindex"]) {
|
|
23056
|
+
console.log("Skipped the reindex; run `autorouter reindex` to pick up its capabilities.");
|
|
23057
|
+
return 0;
|
|
22799
23058
|
}
|
|
22800
|
-
|
|
23059
|
+
try {
|
|
23060
|
+
await cmdReindex();
|
|
23061
|
+
} catch (err) {
|
|
23062
|
+
console.error(`
|
|
23063
|
+
The grant was saved, but the reindex failed: ${oneLine(err instanceof Error ? err.message : String(err), 200)}
|
|
23064
|
+
` + ` Run \`autorouter reindex\` once that is resolved.`);
|
|
23065
|
+
}
|
|
23066
|
+
return 0;
|
|
22801
23067
|
}
|
|
22802
23068
|
async function cmdLogout(server) {
|
|
22803
23069
|
if (!server) {
|
|
@@ -23082,7 +23348,7 @@ function parseArgs(argv) {
|
|
|
23082
23348
|
command = `--${name}`;
|
|
23083
23349
|
continue;
|
|
23084
23350
|
}
|
|
23085
|
-
const boolean = ["raw", "json", "yes", "dry-run", "force", "servers-only", "read-only", "all-scopes", "list-scopes", "device", "manual"].includes(name) && !(name === "json" && command === "add");
|
|
23351
|
+
const boolean = ["raw", "json", "yes", "dry-run", "force", "servers-only", "read-only", "all-scopes", "list-scopes", "device", "manual", "check", "no-reindex"].includes(name) && !(name === "json" && command === "add");
|
|
23086
23352
|
if (boolean) {
|
|
23087
23353
|
flags[name] = true;
|
|
23088
23354
|
} else if (inline !== undefined) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autorouter-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "One search tool instead of every tool: an MCP capability router for Claude Code, Codex, Cursor and anything else that speaks MCP.",
|
|
5
5
|
"mcpName": "io.github.Webb-Ventures/autorouter",
|
|
6
6
|
"license": "MIT",
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.Webb-Ventures/autorouter",
|
|
4
4
|
"title": "autorouter",
|
|
5
5
|
"description": "An MCP capability router: one search tool instead of every server's tool schema.",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.7",
|
|
7
7
|
"websiteUrl": "https://github.com/Webb-Ventures/autorouter",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/Webb-Ventures/autorouter",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "autorouter-mcp",
|
|
17
|
-
"version": "0.2.
|
|
17
|
+
"version": "0.2.7",
|
|
18
18
|
"transport": { "type": "stdio" },
|
|
19
19
|
"packageArguments": [{ "type": "positional", "value": "serve" }],
|
|
20
20
|
"environmentVariables": [
|