@modeltoolsprotocol/mtpcli 0.2.3 → 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.
Files changed (2) hide show
  1. package/dist/index.js +613 -92
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7341,6 +7341,31 @@ var init_search2 = __esm(() => {
7341
7341
  });
7342
7342
 
7343
7343
  // src/auth.ts
7344
+ var exports_auth = {};
7345
+ __export(exports_auth, {
7346
+ storeToken: () => storeToken,
7347
+ runToken: () => runToken,
7348
+ runStatus: () => runStatus,
7349
+ runRefresh: () => runRefresh,
7350
+ runLogout: () => runLogout,
7351
+ runLogin: () => runLogin,
7352
+ runEnv: () => runEnv,
7353
+ refreshAccessToken: () => refreshAccessToken,
7354
+ oauth2Login: () => oauth2Login,
7355
+ login: () => login,
7356
+ loadToken: () => loadToken,
7357
+ isTokenExpired: () => isTokenExpired,
7358
+ getProvider: () => getProvider,
7359
+ getEnvExport: () => getEnvExport,
7360
+ getEnvDict: () => getEnvDict,
7361
+ getAuthConfig: () => getAuthConfig,
7362
+ generatePkce: () => generatePkce,
7363
+ exchangeCode: () => exchangeCode,
7364
+ ensureValidToken: () => ensureValidToken,
7365
+ deleteToken: () => deleteToken,
7366
+ authStatus: () => authStatus,
7367
+ apiKeyLogin: () => apiKeyLogin
7368
+ });
7344
7369
  import { createHash, randomBytes } from "node:crypto";
7345
7370
  import {
7346
7371
  chmodSync,
@@ -7350,8 +7375,10 @@ import {
7350
7375
  unlinkSync,
7351
7376
  writeFileSync as writeFileSync2
7352
7377
  } from "node:fs";
7378
+ import { createServer } from "node:http";
7353
7379
  import { homedir as homedir2 } from "node:os";
7354
7380
  import { dirname, join as join2 } from "node:path";
7381
+ import { createInterface } from "node:readline";
7355
7382
  function tokensDir(baseDir) {
7356
7383
  return join2(baseDir ?? join2(homedir2(), ".mtpcli"), "tokens");
7357
7384
  }
@@ -7371,6 +7398,13 @@ function loadToken(toolName, providerId, baseDir) {
7371
7398
  return null;
7372
7399
  return JSON.parse(readFileSync2(path2, "utf-8"));
7373
7400
  }
7401
+ function deleteToken(toolName, providerId, baseDir) {
7402
+ const path2 = tokenPath(toolName, providerId, baseDir);
7403
+ if (!existsSync2(path2))
7404
+ return false;
7405
+ unlinkSync(path2);
7406
+ return true;
7407
+ }
7374
7408
  function isTokenExpired(token) {
7375
7409
  if (!token.expires_at)
7376
7410
  return false;
@@ -7378,12 +7412,66 @@ function isTokenExpired(token) {
7378
7412
  const buffer = 5 * 60 * 1000;
7379
7413
  return exp.getTime() - buffer < Date.now();
7380
7414
  }
7415
+ async function getAuthConfig(toolName) {
7416
+ const schema = await getToolSchema2(toolName);
7417
+ return schema?.auth ?? null;
7418
+ }
7419
+ function getProvider(auth, providerId) {
7420
+ if (providerId)
7421
+ return auth.providers.find((p) => p.id === providerId);
7422
+ return auth.providers[0];
7423
+ }
7381
7424
  function generatePkce() {
7382
7425
  const bytes = randomBytes(64);
7383
7426
  const verifier = bytes.toString("base64url").slice(0, 128);
7384
7427
  const challenge = createHash("sha256").update(verifier).digest("base64url");
7385
7428
  return { verifier, challenge };
7386
7429
  }
7430
+ function waitForCallback(port, timeoutSecs) {
7431
+ return new Promise((resolve, reject) => {
7432
+ const timer = setTimeout(() => {
7433
+ server.close();
7434
+ reject(new Error("OAuth callback timed out"));
7435
+ }, timeoutSecs * 1000);
7436
+ const server = createServer((req, res) => {
7437
+ const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
7438
+ const code = url.searchParams.get("code");
7439
+ const error = url.searchParams.get("error");
7440
+ if (code) {
7441
+ const html = "<html><body><h2>Authentication successful!</h2>" + "<p>You can close this tab and return to your terminal.</p>" + "<script>window.close()</script></body></html>";
7442
+ res.writeHead(200, {
7443
+ "Content-Type": "text/html",
7444
+ "Content-Length": Buffer.byteLength(html).toString()
7445
+ });
7446
+ res.end(html);
7447
+ clearTimeout(timer);
7448
+ server.close();
7449
+ resolve({ code });
7450
+ return;
7451
+ }
7452
+ if (error) {
7453
+ const desc = url.searchParams.get("error_description") ?? "Unknown error";
7454
+ const html = `<html><body><h2>Authentication failed</h2><p>${desc}</p></body></html>`;
7455
+ res.writeHead(400, {
7456
+ "Content-Type": "text/html",
7457
+ "Content-Length": Buffer.byteLength(html).toString()
7458
+ });
7459
+ res.end(html);
7460
+ clearTimeout(timer);
7461
+ server.close();
7462
+ resolve({ error });
7463
+ return;
7464
+ }
7465
+ res.writeHead(404);
7466
+ res.end();
7467
+ });
7468
+ server.listen(port, "127.0.0.1", () => {});
7469
+ server.on("error", (e) => {
7470
+ clearTimeout(timer);
7471
+ reject(new Error(`failed to bind callback server: ${e.message}`));
7472
+ });
7473
+ });
7474
+ }
7387
7475
  async function exchangeCode(tokenUrl, code, clientId, redirectUri, codeVerifier, resource) {
7388
7476
  const params = new URLSearchParams({
7389
7477
  grant_type: "authorization_code",
@@ -7449,6 +7537,112 @@ function parseTokenResponse(text) {
7449
7537
  created_at: new Date().toISOString()
7450
7538
  };
7451
7539
  }
7540
+ async function oauth2Login(toolName, provider, port) {
7541
+ if (!provider.authorizationUrl)
7542
+ throw new Error("provider missing authorizationUrl");
7543
+ if (!provider.tokenUrl)
7544
+ throw new Error("provider missing tokenUrl");
7545
+ if (!provider.clientId)
7546
+ throw new Error("provider missing clientId");
7547
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
7548
+ const state = randomBytes(32).toString("base64url");
7549
+ const params = new URLSearchParams({
7550
+ client_id: provider.clientId,
7551
+ redirect_uri: redirectUri,
7552
+ response_type: "code",
7553
+ state
7554
+ });
7555
+ if (provider.scopes?.length) {
7556
+ params.set("scope", provider.scopes.join(" "));
7557
+ }
7558
+ let codeVerifier;
7559
+ if (provider.type === "oauth2-pkce") {
7560
+ const pkce = generatePkce();
7561
+ codeVerifier = pkce.verifier;
7562
+ params.set("code_challenge", pkce.challenge);
7563
+ params.set("code_challenge_method", "S256");
7564
+ }
7565
+ const fullUrl = `${provider.authorizationUrl}?${params.toString()}`;
7566
+ const display = provider.displayName ?? provider.id;
7567
+ process.stderr.write(`Opening browser for ${display} login...
7568
+ `);
7569
+ process.stderr.write(`If the browser doesn't open, visit:
7570
+ ${fullUrl}
7571
+
7572
+ `);
7573
+ open_default(fullUrl).catch(() => {});
7574
+ process.stderr.write(`Waiting for authentication callback on port ${port}...
7575
+ `);
7576
+ const result = await waitForCallback(port, 120);
7577
+ if (result.error)
7578
+ throw new Error(`OAuth error: ${result.error}`);
7579
+ if (!result.code)
7580
+ throw new Error("no authorization code received (timed out?)");
7581
+ process.stderr.write(`Exchanging authorization code for tokens...
7582
+ `);
7583
+ const token = await exchangeCode(provider.tokenUrl, result.code, provider.clientId, redirectUri, codeVerifier);
7584
+ token.provider_id = provider.id;
7585
+ storeToken(toolName, provider.id, token);
7586
+ process.stderr.write(`Authenticated with ${display}
7587
+ `);
7588
+ return token;
7589
+ }
7590
+ function apiKeyLogin(toolName, provider, tokenValue) {
7591
+ return new Promise((resolve, reject) => {
7592
+ const finish = (value) => {
7593
+ if (!value) {
7594
+ reject(new Error("no token provided"));
7595
+ return;
7596
+ }
7597
+ const token = {
7598
+ access_token: value,
7599
+ token_type: provider.type,
7600
+ refresh_token: undefined,
7601
+ expires_at: undefined,
7602
+ scopes: undefined,
7603
+ provider_id: provider.id,
7604
+ created_at: new Date().toISOString()
7605
+ };
7606
+ storeToken(toolName, provider.id, token);
7607
+ const display = provider.displayName ?? provider.id;
7608
+ process.stderr.write(`Token stored for ${display}
7609
+ `);
7610
+ resolve(token);
7611
+ };
7612
+ if (tokenValue) {
7613
+ finish(tokenValue);
7614
+ return;
7615
+ }
7616
+ if (provider.registrationUrl) {
7617
+ process.stderr.write(`Get your API key at: ${provider.registrationUrl}
7618
+ `);
7619
+ }
7620
+ if (provider.instructions) {
7621
+ process.stderr.write(`${provider.instructions}
7622
+ `);
7623
+ }
7624
+ process.stderr.write("Enter your token/API key: ");
7625
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
7626
+ rl.question("", (answer) => {
7627
+ rl.close();
7628
+ finish(answer.trim());
7629
+ });
7630
+ });
7631
+ }
7632
+ async function login(toolName, provider, token, port = 8914) {
7633
+ switch (provider.type) {
7634
+ case "oauth2":
7635
+ case "oauth2-pkce":
7636
+ if (token)
7637
+ return apiKeyLogin(toolName, provider, token);
7638
+ return oauth2Login(toolName, provider, port);
7639
+ case "api-key":
7640
+ case "bearer":
7641
+ return apiKeyLogin(toolName, provider, token);
7642
+ default:
7643
+ throw new Error(`unknown auth type: ${provider.type}`);
7644
+ }
7645
+ }
7452
7646
  async function ensureValidToken(toolName, auth) {
7453
7647
  const provider = auth.providers[0];
7454
7648
  if (!provider)
@@ -7482,7 +7676,121 @@ async function getEnvDict(toolName, auth) {
7482
7676
  return {};
7483
7677
  return { [auth.envVar]: token };
7484
7678
  }
7679
+ async function getEnvExport(toolName, auth) {
7680
+ const env = await getEnvDict(toolName, auth);
7681
+ if (Object.keys(env).length === 0) {
7682
+ return "# No token available. Run: mtpcli auth login <tool>";
7683
+ }
7684
+ return Object.entries(env).map(([key, value]) => {
7685
+ const escaped = value.replace(/'/g, "'\\''");
7686
+ return `export ${key}='${escaped}'`;
7687
+ }).join(`
7688
+ `);
7689
+ }
7690
+ async function authStatus(toolName, auth) {
7691
+ const providers = [];
7692
+ for (const provider of auth.providers) {
7693
+ const token = loadToken(toolName, provider.id);
7694
+ const status = {
7695
+ id: provider.id,
7696
+ type: provider.type,
7697
+ display_name: provider.displayName ?? provider.id,
7698
+ authenticated: token !== null
7699
+ };
7700
+ if (token) {
7701
+ status.expired = isTokenExpired(token);
7702
+ status.has_refresh = !!token.refresh_token;
7703
+ if (token.expires_at)
7704
+ status.expires_at = token.expires_at;
7705
+ if (token.scopes)
7706
+ status.scopes = token.scopes;
7707
+ }
7708
+ providers.push(status);
7709
+ }
7710
+ return {
7711
+ tool: toolName,
7712
+ env_var: auth.envVar,
7713
+ required: auth.required,
7714
+ providers
7715
+ };
7716
+ }
7717
+ async function runLogin(toolName, providerId, token) {
7718
+ const auth = await getAuthConfig(toolName);
7719
+ if (!auth)
7720
+ throw new Error(`tool '${toolName}' does not declare auth`);
7721
+ const provider = getProvider(auth, providerId);
7722
+ if (!provider)
7723
+ throw new Error("no matching auth provider found");
7724
+ await login(toolName, provider, token, 8914);
7725
+ }
7726
+ async function runLogout(toolName) {
7727
+ const auth = await getAuthConfig(toolName);
7728
+ if (!auth)
7729
+ throw new Error(`tool '${toolName}' does not declare auth`);
7730
+ let deleted = false;
7731
+ for (const provider of auth.providers) {
7732
+ if (deleteToken(toolName, provider.id)) {
7733
+ const display = provider.displayName ?? provider.id;
7734
+ process.stderr.write(`Logged out from ${display}
7735
+ `);
7736
+ deleted = true;
7737
+ }
7738
+ }
7739
+ if (!deleted)
7740
+ process.stderr.write(`No tokens found for '${toolName}'
7741
+ `);
7742
+ }
7743
+ async function runStatus(toolName) {
7744
+ const auth = await getAuthConfig(toolName);
7745
+ if (!auth)
7746
+ throw new Error(`tool '${toolName}' does not declare auth`);
7747
+ const status = await authStatus(toolName, auth);
7748
+ console.log(JSON.stringify(status, null, 2));
7749
+ }
7750
+ async function runToken(toolName) {
7751
+ const auth = await getAuthConfig(toolName);
7752
+ if (!auth)
7753
+ throw new Error(`tool '${toolName}' does not declare auth`);
7754
+ const t = await ensureValidToken(toolName, auth);
7755
+ if (!t)
7756
+ throw new Error(`no valid token for '${toolName}'. Run: mtpcli auth login ${toolName}`);
7757
+ console.log(t);
7758
+ }
7759
+ async function runEnv(toolName) {
7760
+ const auth = await getAuthConfig(toolName);
7761
+ if (!auth)
7762
+ throw new Error(`tool '${toolName}' does not declare auth`);
7763
+ console.log(await getEnvExport(toolName, auth));
7764
+ }
7765
+ async function runRefresh(toolName) {
7766
+ const authConfig = await getAuthConfig(toolName);
7767
+ if (!authConfig)
7768
+ throw new Error(`tool '${toolName}' does not declare auth`);
7769
+ const provider = authConfig.providers[0];
7770
+ if (!provider)
7771
+ throw new Error("no auth provider configured");
7772
+ const token = loadToken(toolName, provider.id);
7773
+ if (!token) {
7774
+ throw new Error(`no stored token for '${toolName}'. Run: mtpcli auth login ${toolName}`);
7775
+ }
7776
+ if (!token.refresh_token) {
7777
+ throw new Error(`token for '${toolName}' has no refresh_token (provider type: ${provider.type})`);
7778
+ }
7779
+ if (!provider.tokenUrl || !provider.clientId) {
7780
+ throw new Error("provider missing tokenUrl or clientId for refresh");
7781
+ }
7782
+ const newToken = await refreshAccessToken(provider.tokenUrl, token.refresh_token, provider.clientId);
7783
+ if (!newToken.refresh_token) {
7784
+ newToken.refresh_token = token.refresh_token;
7785
+ }
7786
+ newToken.provider_id = provider.id;
7787
+ storeToken(toolName, provider.id, newToken);
7788
+ const display = provider.displayName ?? provider.id;
7789
+ process.stderr.write(`Token refreshed for ${display}
7790
+ `);
7791
+ }
7485
7792
  var init_auth = __esm(() => {
7793
+ init_open();
7486
7794
  init_search2();
7487
7795
  });
7488
7796
 
@@ -7495,6 +7803,10 @@ __export(exports_mcp_oauth, {
7495
7803
  promptForClientId: () => promptForClientId,
7496
7804
  parseWwwAuthenticate: () => parseWwwAuthenticate,
7497
7805
  mcpOAuthFlow: () => mcpOAuthFlow,
7806
+ mcpAuthToken: () => mcpAuthToken,
7807
+ mcpAuthStatus: () => mcpAuthStatus,
7808
+ mcpAuthRefresh: () => mcpAuthRefresh,
7809
+ mcpAuthLogout: () => mcpAuthLogout,
7498
7810
  loadOrRefreshMcpToken: () => loadOrRefreshMcpToken,
7499
7811
  loadClientRegistration: () => loadClientRegistration,
7500
7812
  fetchResourceMetadata: () => fetchResourceMetadata,
@@ -7508,10 +7820,10 @@ import {
7508
7820
  writeFileSync as writeFileSync3,
7509
7821
  chmodSync as chmodSync2
7510
7822
  } from "node:fs";
7511
- import { createServer } from "node:http";
7823
+ import { createServer as createServer2 } from "node:http";
7512
7824
  import { homedir as homedir3 } from "node:os";
7513
7825
  import { dirname as dirname2, join as join3 } from "node:path";
7514
- import { createInterface } from "node:readline";
7826
+ import { createInterface as createInterface2 } from "node:readline";
7515
7827
  function serverStorageKey(url) {
7516
7828
  const u = new URL(url);
7517
7829
  return `mcp_${u.host}`;
@@ -7612,7 +7924,7 @@ function promptForClientId(serverUrl) {
7612
7924
  No dynamic registration available for ${serverUrl}.
7613
7925
  ` + `You need to register a client manually and provide the client_id.
7614
7926
  ` + `Enter client_id: `);
7615
- const rl = createInterface({ input: process.stdin, output: process.stderr });
7927
+ const rl = createInterface2({ input: process.stdin, output: process.stderr });
7616
7928
  rl.question("", (answer) => {
7617
7929
  rl.close();
7618
7930
  const trimmed = answer.trim();
@@ -7660,7 +7972,7 @@ function startCallbackServer() {
7660
7972
  codeResolve = res;
7661
7973
  codeReject = rej;
7662
7974
  });
7663
- const server = createServer((req, res) => {
7975
+ const server = createServer2((req, res) => {
7664
7976
  const url = new URL(req.url ?? "/", `http://127.0.0.1`);
7665
7977
  const code = url.searchParams.get("code");
7666
7978
  const error = url.searchParams.get("error");
@@ -7792,6 +8104,58 @@ ${authUrl}
7792
8104
  `);
7793
8105
  return token.access_token;
7794
8106
  }
8107
+ function mcpAuthStatus(serverUrl) {
8108
+ const storageKey = serverStorageKey(serverUrl);
8109
+ const origin = new URL(serverUrl).origin;
8110
+ const token = loadToken(storageKey, "mcp-oauth");
8111
+ const reg = loadClientRegistration(origin);
8112
+ const result = {
8113
+ url: serverUrl,
8114
+ authenticated: token !== null
8115
+ };
8116
+ if (token) {
8117
+ result.expired = isTokenExpired(token);
8118
+ result.has_refresh = !!token.refresh_token;
8119
+ if (token.expires_at)
8120
+ result.expires_at = token.expires_at;
8121
+ if (token.scopes)
8122
+ result.scopes = token.scopes;
8123
+ }
8124
+ if (reg) {
8125
+ result.client_id = reg.client.clientId;
8126
+ }
8127
+ return result;
8128
+ }
8129
+ function mcpAuthLogout(serverUrl) {
8130
+ const storageKey = serverStorageKey(serverUrl);
8131
+ return deleteToken(storageKey, "mcp-oauth");
8132
+ }
8133
+ async function mcpAuthToken(serverUrl) {
8134
+ return loadOrRefreshMcpToken(serverUrl);
8135
+ }
8136
+ async function mcpAuthRefresh(serverUrl) {
8137
+ const storageKey = serverStorageKey(serverUrl);
8138
+ const origin = new URL(serverUrl).origin;
8139
+ const token = loadToken(storageKey, "mcp-oauth");
8140
+ if (!token) {
8141
+ throw new Error(`no stored token for '${serverUrl}'. Run: mtpcli auth login --url ${serverUrl}`);
8142
+ }
8143
+ if (!token.refresh_token) {
8144
+ throw new Error(`token for '${serverUrl}' has no refresh_token`);
8145
+ }
8146
+ const cached = loadClientRegistration(origin);
8147
+ if (!cached) {
8148
+ throw new Error(`no cached client registration for ${origin}. Run: mtpcli auth login --url ${serverUrl}`);
8149
+ }
8150
+ const newToken = await refreshAccessToken(cached.metadata.token_endpoint, token.refresh_token, cached.client.clientId);
8151
+ if (!newToken.refresh_token) {
8152
+ newToken.refresh_token = token.refresh_token;
8153
+ }
8154
+ newToken.provider_id = "mcp-oauth";
8155
+ storeToken(storageKey, "mcp-oauth", newToken);
8156
+ process.stderr.write(`Token refreshed for ${serverUrl}
8157
+ `);
8158
+ }
7795
8159
  async function loadOrRefreshMcpToken(serverUrl) {
7796
8160
  const storageKey = serverStorageKey(serverUrl);
7797
8161
  const token = loadToken(storageKey, "mcp-oauth");
@@ -7826,30 +8190,30 @@ var init_mcp_oauth = __esm(() => {
7826
8190
  });
7827
8191
 
7828
8192
  // src/auth.ts
7829
- var exports_auth = {};
7830
- __export(exports_auth, {
8193
+ var exports_auth2 = {};
8194
+ __export(exports_auth2, {
7831
8195
  storeToken: () => storeToken2,
7832
- runToken: () => runToken,
7833
- runStatus: () => runStatus,
7834
- runRefresh: () => runRefresh,
7835
- runLogout: () => runLogout,
7836
- runLogin: () => runLogin,
7837
- runEnv: () => runEnv,
8196
+ runToken: () => runToken2,
8197
+ runStatus: () => runStatus2,
8198
+ runRefresh: () => runRefresh2,
8199
+ runLogout: () => runLogout2,
8200
+ runLogin: () => runLogin2,
8201
+ runEnv: () => runEnv2,
7838
8202
  refreshAccessToken: () => refreshAccessToken2,
7839
- oauth2Login: () => oauth2Login,
7840
- login: () => login,
8203
+ oauth2Login: () => oauth2Login2,
8204
+ login: () => login2,
7841
8205
  loadToken: () => loadToken2,
7842
8206
  isTokenExpired: () => isTokenExpired2,
7843
- getProvider: () => getProvider,
7844
- getEnvExport: () => getEnvExport,
8207
+ getProvider: () => getProvider2,
8208
+ getEnvExport: () => getEnvExport2,
7845
8209
  getEnvDict: () => getEnvDict2,
7846
- getAuthConfig: () => getAuthConfig,
8210
+ getAuthConfig: () => getAuthConfig2,
7847
8211
  generatePkce: () => generatePkce2,
7848
8212
  exchangeCode: () => exchangeCode2,
7849
8213
  ensureValidToken: () => ensureValidToken2,
7850
- deleteToken: () => deleteToken,
7851
- authStatus: () => authStatus,
7852
- apiKeyLogin: () => apiKeyLogin
8214
+ deleteToken: () => deleteToken2,
8215
+ authStatus: () => authStatus2,
8216
+ apiKeyLogin: () => apiKeyLogin2
7853
8217
  });
7854
8218
  import { createHash as createHash2, randomBytes as randomBytes3 } from "node:crypto";
7855
8219
  import {
@@ -7860,10 +8224,10 @@ import {
7860
8224
  unlinkSync as unlinkSync2,
7861
8225
  writeFileSync as writeFileSync4
7862
8226
  } from "node:fs";
7863
- import { createServer as createServer2 } from "node:http";
8227
+ import { createServer as createServer3 } from "node:http";
7864
8228
  import { homedir as homedir4 } from "node:os";
7865
8229
  import { dirname as dirname3, join as join4 } from "node:path";
7866
- import { createInterface as createInterface2 } from "node:readline";
8230
+ import { createInterface as createInterface3 } from "node:readline";
7867
8231
  function tokensDir2(baseDir) {
7868
8232
  return join4(baseDir ?? join4(homedir4(), ".mtpcli"), "tokens");
7869
8233
  }
@@ -7883,7 +8247,7 @@ function loadToken2(toolName, providerId, baseDir) {
7883
8247
  return null;
7884
8248
  return JSON.parse(readFileSync4(path2, "utf-8"));
7885
8249
  }
7886
- function deleteToken(toolName, providerId, baseDir) {
8250
+ function deleteToken2(toolName, providerId, baseDir) {
7887
8251
  const path2 = tokenPath2(toolName, providerId, baseDir);
7888
8252
  if (!existsSync4(path2))
7889
8253
  return false;
@@ -7897,11 +8261,11 @@ function isTokenExpired2(token) {
7897
8261
  const buffer = 5 * 60 * 1000;
7898
8262
  return exp.getTime() - buffer < Date.now();
7899
8263
  }
7900
- async function getAuthConfig(toolName) {
8264
+ async function getAuthConfig2(toolName) {
7901
8265
  const schema = await getToolSchema2(toolName);
7902
8266
  return schema?.auth ?? null;
7903
8267
  }
7904
- function getProvider(auth, providerId) {
8268
+ function getProvider2(auth, providerId) {
7905
8269
  if (providerId)
7906
8270
  return auth.providers.find((p) => p.id === providerId);
7907
8271
  return auth.providers[0];
@@ -7912,13 +8276,13 @@ function generatePkce2() {
7912
8276
  const challenge = createHash2("sha256").update(verifier).digest("base64url");
7913
8277
  return { verifier, challenge };
7914
8278
  }
7915
- function waitForCallback(port, timeoutSecs) {
8279
+ function waitForCallback2(port, timeoutSecs) {
7916
8280
  return new Promise((resolve, reject) => {
7917
8281
  const timer = setTimeout(() => {
7918
8282
  server.close();
7919
8283
  reject(new Error("OAuth callback timed out"));
7920
8284
  }, timeoutSecs * 1000);
7921
- const server = createServer2((req, res) => {
8285
+ const server = createServer3((req, res) => {
7922
8286
  const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
7923
8287
  const code = url.searchParams.get("code");
7924
8288
  const error = url.searchParams.get("error");
@@ -8022,7 +8386,7 @@ function parseTokenResponse2(text) {
8022
8386
  created_at: new Date().toISOString()
8023
8387
  };
8024
8388
  }
8025
- async function oauth2Login(toolName, provider, port) {
8389
+ async function oauth2Login2(toolName, provider, port) {
8026
8390
  if (!provider.authorizationUrl)
8027
8391
  throw new Error("provider missing authorizationUrl");
8028
8392
  if (!provider.tokenUrl)
@@ -8058,7 +8422,7 @@ ${fullUrl}
8058
8422
  open_default(fullUrl).catch(() => {});
8059
8423
  process.stderr.write(`Waiting for authentication callback on port ${port}...
8060
8424
  `);
8061
- const result = await waitForCallback(port, 120);
8425
+ const result = await waitForCallback2(port, 120);
8062
8426
  if (result.error)
8063
8427
  throw new Error(`OAuth error: ${result.error}`);
8064
8428
  if (!result.code)
@@ -8072,7 +8436,7 @@ ${fullUrl}
8072
8436
  `);
8073
8437
  return token;
8074
8438
  }
8075
- function apiKeyLogin(toolName, provider, tokenValue) {
8439
+ function apiKeyLogin2(toolName, provider, tokenValue) {
8076
8440
  return new Promise((resolve, reject) => {
8077
8441
  const finish = (value) => {
8078
8442
  if (!value) {
@@ -8107,23 +8471,23 @@ function apiKeyLogin(toolName, provider, tokenValue) {
8107
8471
  `);
8108
8472
  }
8109
8473
  process.stderr.write("Enter your token/API key: ");
8110
- const rl = createInterface2({ input: process.stdin, output: process.stderr });
8474
+ const rl = createInterface3({ input: process.stdin, output: process.stderr });
8111
8475
  rl.question("", (answer) => {
8112
8476
  rl.close();
8113
8477
  finish(answer.trim());
8114
8478
  });
8115
8479
  });
8116
8480
  }
8117
- async function login(toolName, provider, token, port = 8914) {
8481
+ async function login2(toolName, provider, token, port = 8914) {
8118
8482
  switch (provider.type) {
8119
8483
  case "oauth2":
8120
8484
  case "oauth2-pkce":
8121
8485
  if (token)
8122
- return apiKeyLogin(toolName, provider, token);
8123
- return oauth2Login(toolName, provider, port);
8486
+ return apiKeyLogin2(toolName, provider, token);
8487
+ return oauth2Login2(toolName, provider, port);
8124
8488
  case "api-key":
8125
8489
  case "bearer":
8126
- return apiKeyLogin(toolName, provider, token);
8490
+ return apiKeyLogin2(toolName, provider, token);
8127
8491
  default:
8128
8492
  throw new Error(`unknown auth type: ${provider.type}`);
8129
8493
  }
@@ -8161,7 +8525,7 @@ async function getEnvDict2(toolName, auth) {
8161
8525
  return {};
8162
8526
  return { [auth.envVar]: token };
8163
8527
  }
8164
- async function getEnvExport(toolName, auth) {
8528
+ async function getEnvExport2(toolName, auth) {
8165
8529
  const env = await getEnvDict2(toolName, auth);
8166
8530
  if (Object.keys(env).length === 0) {
8167
8531
  return "# No token available. Run: mtpcli auth login <tool>";
@@ -8172,7 +8536,7 @@ async function getEnvExport(toolName, auth) {
8172
8536
  }).join(`
8173
8537
  `);
8174
8538
  }
8175
- async function authStatus(toolName, auth) {
8539
+ async function authStatus2(toolName, auth) {
8176
8540
  const providers = [];
8177
8541
  for (const provider of auth.providers) {
8178
8542
  const token = loadToken2(toolName, provider.id);
@@ -8199,22 +8563,22 @@ async function authStatus(toolName, auth) {
8199
8563
  providers
8200
8564
  };
8201
8565
  }
8202
- async function runLogin(toolName, providerId, token) {
8203
- const auth = await getAuthConfig(toolName);
8566
+ async function runLogin2(toolName, providerId, token) {
8567
+ const auth = await getAuthConfig2(toolName);
8204
8568
  if (!auth)
8205
8569
  throw new Error(`tool '${toolName}' does not declare auth`);
8206
- const provider = getProvider(auth, providerId);
8570
+ const provider = getProvider2(auth, providerId);
8207
8571
  if (!provider)
8208
8572
  throw new Error("no matching auth provider found");
8209
- await login(toolName, provider, token, 8914);
8573
+ await login2(toolName, provider, token, 8914);
8210
8574
  }
8211
- async function runLogout(toolName) {
8212
- const auth = await getAuthConfig(toolName);
8575
+ async function runLogout2(toolName) {
8576
+ const auth = await getAuthConfig2(toolName);
8213
8577
  if (!auth)
8214
8578
  throw new Error(`tool '${toolName}' does not declare auth`);
8215
8579
  let deleted = false;
8216
8580
  for (const provider of auth.providers) {
8217
- if (deleteToken(toolName, provider.id)) {
8581
+ if (deleteToken2(toolName, provider.id)) {
8218
8582
  const display = provider.displayName ?? provider.id;
8219
8583
  process.stderr.write(`Logged out from ${display}
8220
8584
  `);
@@ -8225,15 +8589,15 @@ async function runLogout(toolName) {
8225
8589
  process.stderr.write(`No tokens found for '${toolName}'
8226
8590
  `);
8227
8591
  }
8228
- async function runStatus(toolName) {
8229
- const auth = await getAuthConfig(toolName);
8592
+ async function runStatus2(toolName) {
8593
+ const auth = await getAuthConfig2(toolName);
8230
8594
  if (!auth)
8231
8595
  throw new Error(`tool '${toolName}' does not declare auth`);
8232
- const status = await authStatus(toolName, auth);
8596
+ const status = await authStatus2(toolName, auth);
8233
8597
  console.log(JSON.stringify(status, null, 2));
8234
8598
  }
8235
- async function runToken(toolName) {
8236
- const auth = await getAuthConfig(toolName);
8599
+ async function runToken2(toolName) {
8600
+ const auth = await getAuthConfig2(toolName);
8237
8601
  if (!auth)
8238
8602
  throw new Error(`tool '${toolName}' does not declare auth`);
8239
8603
  const t = await ensureValidToken2(toolName, auth);
@@ -8241,14 +8605,14 @@ async function runToken(toolName) {
8241
8605
  throw new Error(`no valid token for '${toolName}'. Run: mtpcli auth login ${toolName}`);
8242
8606
  console.log(t);
8243
8607
  }
8244
- async function runEnv(toolName) {
8245
- const auth = await getAuthConfig(toolName);
8608
+ async function runEnv2(toolName) {
8609
+ const auth = await getAuthConfig2(toolName);
8246
8610
  if (!auth)
8247
8611
  throw new Error(`tool '${toolName}' does not declare auth`);
8248
- console.log(await getEnvExport(toolName, auth));
8612
+ console.log(await getEnvExport2(toolName, auth));
8249
8613
  }
8250
- async function runRefresh(toolName) {
8251
- const authConfig = await getAuthConfig(toolName);
8614
+ async function runRefresh2(toolName) {
8615
+ const authConfig = await getAuthConfig2(toolName);
8252
8616
  if (!authConfig)
8253
8617
  throw new Error(`tool '${toolName}' does not declare auth`);
8254
8618
  const provider = authConfig.providers[0];
@@ -8340,7 +8704,7 @@ __export(exports_serve, {
8340
8704
  argToJsonSchema: () => argToJsonSchema
8341
8705
  });
8342
8706
  import { execFile as execFile9, spawn } from "node:child_process";
8343
- import { createInterface as createInterface3 } from "node:readline";
8707
+ import { createInterface as createInterface4 } from "node:readline";
8344
8708
  import { promisify as promisify9 } from "node:util";
8345
8709
  function argToJsonSchema(arg) {
8346
8710
  const schema = {};
@@ -8563,7 +8927,7 @@ async function run(toolNames) {
8563
8927
  schemas: allSchemas,
8564
8928
  authConfigs: allAuth
8565
8929
  };
8566
- const rl = createInterface3({ input: process.stdin, crlfDelay: Infinity });
8930
+ const rl = createInterface4({ input: process.stdin, crlfDelay: Infinity });
8567
8931
  for await (const line of rl) {
8568
8932
  const trimmed = line.trim();
8569
8933
  if (!trimmed)
@@ -8602,6 +8966,10 @@ __export(exports_mcp_oauth2, {
8602
8966
  promptForClientId: () => promptForClientId2,
8603
8967
  parseWwwAuthenticate: () => parseWwwAuthenticate2,
8604
8968
  mcpOAuthFlow: () => mcpOAuthFlow2,
8969
+ mcpAuthToken: () => mcpAuthToken2,
8970
+ mcpAuthStatus: () => mcpAuthStatus2,
8971
+ mcpAuthRefresh: () => mcpAuthRefresh2,
8972
+ mcpAuthLogout: () => mcpAuthLogout2,
8605
8973
  loadOrRefreshMcpToken: () => loadOrRefreshMcpToken2,
8606
8974
  loadClientRegistration: () => loadClientRegistration2,
8607
8975
  fetchResourceMetadata: () => fetchResourceMetadata2,
@@ -8615,10 +8983,10 @@ import {
8615
8983
  writeFileSync as writeFileSync5,
8616
8984
  chmodSync as chmodSync4
8617
8985
  } from "node:fs";
8618
- import { createServer as createServer3 } from "node:http";
8986
+ import { createServer as createServer4 } from "node:http";
8619
8987
  import { homedir as homedir5 } from "node:os";
8620
8988
  import { dirname as dirname4, join as join5 } from "node:path";
8621
- import { createInterface as createInterface4 } from "node:readline";
8989
+ import { createInterface as createInterface5 } from "node:readline";
8622
8990
  function serverStorageKey2(url) {
8623
8991
  const u = new URL(url);
8624
8992
  return `mcp_${u.host}`;
@@ -8719,7 +9087,7 @@ function promptForClientId2(serverUrl) {
8719
9087
  No dynamic registration available for ${serverUrl}.
8720
9088
  ` + `You need to register a client manually and provide the client_id.
8721
9089
  ` + `Enter client_id: `);
8722
- const rl = createInterface4({ input: process.stdin, output: process.stderr });
9090
+ const rl = createInterface5({ input: process.stdin, output: process.stderr });
8723
9091
  rl.question("", (answer) => {
8724
9092
  rl.close();
8725
9093
  const trimmed = answer.trim();
@@ -8767,7 +9135,7 @@ function startCallbackServer2() {
8767
9135
  codeResolve = res;
8768
9136
  codeReject = rej;
8769
9137
  });
8770
- const server = createServer3((req, res) => {
9138
+ const server = createServer4((req, res) => {
8771
9139
  const url = new URL(req.url ?? "/", `http://127.0.0.1`);
8772
9140
  const code = url.searchParams.get("code");
8773
9141
  const error = url.searchParams.get("error");
@@ -8899,6 +9267,58 @@ ${authUrl}
8899
9267
  `);
8900
9268
  return token.access_token;
8901
9269
  }
9270
+ function mcpAuthStatus2(serverUrl) {
9271
+ const storageKey = serverStorageKey2(serverUrl);
9272
+ const origin = new URL(serverUrl).origin;
9273
+ const token = loadToken(storageKey, "mcp-oauth");
9274
+ const reg = loadClientRegistration2(origin);
9275
+ const result = {
9276
+ url: serverUrl,
9277
+ authenticated: token !== null
9278
+ };
9279
+ if (token) {
9280
+ result.expired = isTokenExpired(token);
9281
+ result.has_refresh = !!token.refresh_token;
9282
+ if (token.expires_at)
9283
+ result.expires_at = token.expires_at;
9284
+ if (token.scopes)
9285
+ result.scopes = token.scopes;
9286
+ }
9287
+ if (reg) {
9288
+ result.client_id = reg.client.clientId;
9289
+ }
9290
+ return result;
9291
+ }
9292
+ function mcpAuthLogout2(serverUrl) {
9293
+ const storageKey = serverStorageKey2(serverUrl);
9294
+ return deleteToken(storageKey, "mcp-oauth");
9295
+ }
9296
+ async function mcpAuthToken2(serverUrl) {
9297
+ return loadOrRefreshMcpToken2(serverUrl);
9298
+ }
9299
+ async function mcpAuthRefresh2(serverUrl) {
9300
+ const storageKey = serverStorageKey2(serverUrl);
9301
+ const origin = new URL(serverUrl).origin;
9302
+ const token = loadToken(storageKey, "mcp-oauth");
9303
+ if (!token) {
9304
+ throw new Error(`no stored token for '${serverUrl}'. Run: mtpcli auth login --url ${serverUrl}`);
9305
+ }
9306
+ if (!token.refresh_token) {
9307
+ throw new Error(`token for '${serverUrl}' has no refresh_token`);
9308
+ }
9309
+ const cached = loadClientRegistration2(origin);
9310
+ if (!cached) {
9311
+ throw new Error(`no cached client registration for ${origin}. Run: mtpcli auth login --url ${serverUrl}`);
9312
+ }
9313
+ const newToken = await refreshAccessToken(cached.metadata.token_endpoint, token.refresh_token, cached.client.clientId);
9314
+ if (!newToken.refresh_token) {
9315
+ newToken.refresh_token = token.refresh_token;
9316
+ }
9317
+ newToken.provider_id = "mcp-oauth";
9318
+ storeToken(storageKey, "mcp-oauth", newToken);
9319
+ process.stderr.write(`Token refreshed for ${serverUrl}
9320
+ `);
9321
+ }
8902
9322
  async function loadOrRefreshMcpToken2(serverUrl) {
8903
9323
  const storageKey = serverStorageKey2(serverUrl);
8904
9324
  const token = loadToken(storageKey, "mcp-oauth");
@@ -8944,7 +9364,7 @@ __export(exports_wrap, {
8944
9364
  HttpMcpClient: () => HttpMcpClient
8945
9365
  });
8946
9366
  import { spawn as spawn2 } from "node:child_process";
8947
- import { createInterface as createInterface5 } from "node:readline";
9367
+ import { createInterface as createInterface6 } from "node:readline";
8948
9368
  function jsonSchemaToArg(name, prop, required) {
8949
9369
  let argType = "string";
8950
9370
  let values;
@@ -9096,7 +9516,7 @@ class McpClient {
9096
9516
  if (!child.stdout || !child.stdin) {
9097
9517
  throw new Error("failed to start MCP server");
9098
9518
  }
9099
- const rl = createInterface5({ input: child.stdout, crlfDelay: Infinity });
9519
+ const rl = createInterface6({ input: child.stdout, crlfDelay: Infinity });
9100
9520
  const client = new McpClient(child, rl);
9101
9521
  client.sendRequest("initialize", {
9102
9522
  protocolVersion: "2024-11-05",
@@ -9226,6 +9646,16 @@ class HttpMcpClient {
9226
9646
  throw new Error(`HTTP 401 from ${this.url} (OAuth already attempted, not retrying)`);
9227
9647
  }
9228
9648
  this.oauthAttempted = true;
9649
+ try {
9650
+ const { mcpAuthRefresh: mcpAuthRefresh3, serverStorageKey: serverStorageKey3 } = await Promise.resolve().then(() => (init_mcp_oauth2(), exports_mcp_oauth2));
9651
+ const { loadToken: loadToken3 } = await Promise.resolve().then(() => (init_auth(), exports_auth));
9652
+ await mcpAuthRefresh3(this.url);
9653
+ const token = loadToken3(serverStorageKey3(this.url), "mcp-oauth");
9654
+ if (token) {
9655
+ this.accessToken = token.access_token;
9656
+ return;
9657
+ }
9658
+ } catch {}
9229
9659
  const wwwAuth = resp.headers.get("www-authenticate") ?? "";
9230
9660
  const { mcpOAuthFlow: mcpOAuthFlow3 } = await Promise.resolve().then(() => (init_mcp_oauth2(), exports_mcp_oauth2));
9231
9661
  this.accessToken = await mcpOAuthFlow3(this.url, wwwAuth, this.clientId);
@@ -10134,7 +10564,7 @@ function cleanJson(obj) {
10134
10564
  }
10135
10565
 
10136
10566
  // src/index.ts
10137
- var VERSION3 = "0.2.3";
10567
+ var VERSION3 = "0.3.0";
10138
10568
  function selfDescribe() {
10139
10569
  const schema = {
10140
10570
  name: "mtpcli",
@@ -10234,11 +10664,21 @@ function selfDescribe() {
10234
10664
  {
10235
10665
  name: "tool",
10236
10666
  type: "string",
10237
- required: true,
10238
- description: "Tool name"
10667
+ description: "Tool name (required unless --url is used)"
10668
+ },
10669
+ {
10670
+ name: "--url",
10671
+ type: "string",
10672
+ description: "HTTP MCP server URL"
10239
10673
  }
10240
10674
  ],
10241
- examples: [{ command: "mtpcli auth logout gh-tool" }]
10675
+ examples: [
10676
+ { command: "mtpcli auth logout gh-tool" },
10677
+ {
10678
+ description: "Logout from HTTP MCP server",
10679
+ command: "mtpcli auth logout --url https://mcp.example.com/v1/mcp"
10680
+ }
10681
+ ]
10242
10682
  },
10243
10683
  {
10244
10684
  name: "auth status",
@@ -10247,11 +10687,21 @@ function selfDescribe() {
10247
10687
  {
10248
10688
  name: "tool",
10249
10689
  type: "string",
10250
- required: true,
10251
- description: "Tool name"
10690
+ description: "Tool name (required unless --url is used)"
10691
+ },
10692
+ {
10693
+ name: "--url",
10694
+ type: "string",
10695
+ description: "HTTP MCP server URL"
10252
10696
  }
10253
10697
  ],
10254
- examples: [{ command: "mtpcli auth status gh-tool" }]
10698
+ examples: [
10699
+ { command: "mtpcli auth status gh-tool" },
10700
+ {
10701
+ description: "Status for HTTP MCP server",
10702
+ command: "mtpcli auth status --url https://mcp.example.com/v1/mcp"
10703
+ }
10704
+ ]
10255
10705
  },
10256
10706
  {
10257
10707
  name: "auth token",
@@ -10260,11 +10710,21 @@ function selfDescribe() {
10260
10710
  {
10261
10711
  name: "tool",
10262
10712
  type: "string",
10263
- required: true,
10264
- description: "Tool name"
10713
+ description: "Tool name (required unless --url is used)"
10714
+ },
10715
+ {
10716
+ name: "--url",
10717
+ type: "string",
10718
+ description: "HTTP MCP server URL"
10265
10719
  }
10266
10720
  ],
10267
- examples: [{ command: "mtpcli auth token gh-tool" }]
10721
+ examples: [
10722
+ { command: "mtpcli auth token gh-tool" },
10723
+ {
10724
+ description: "Token for HTTP MCP server",
10725
+ command: "mtpcli auth token --url https://mcp.example.com/v1/mcp"
10726
+ }
10727
+ ]
10268
10728
  },
10269
10729
  {
10270
10730
  name: "auth env",
@@ -10286,11 +10746,21 @@ function selfDescribe() {
10286
10746
  {
10287
10747
  name: "tool",
10288
10748
  type: "string",
10289
- required: true,
10290
- description: "Tool name"
10749
+ description: "Tool name (required unless --url is used)"
10750
+ },
10751
+ {
10752
+ name: "--url",
10753
+ type: "string",
10754
+ description: "HTTP MCP server URL"
10291
10755
  }
10292
10756
  ],
10293
- examples: [{ command: "mtpcli auth refresh gh-tool" }]
10757
+ examples: [
10758
+ { command: "mtpcli auth refresh gh-tool" },
10759
+ {
10760
+ description: "Refresh token for HTTP MCP server",
10761
+ command: "mtpcli auth refresh --url https://mcp.example.com/v1/mcp"
10762
+ }
10763
+ ]
10294
10764
  },
10295
10765
  {
10296
10766
  name: "serve",
@@ -10489,28 +10959,79 @@ authCmd.command("login").description("Log in to a tool").argument("[tool]", "Too
10489
10959
  `);
10490
10960
  process.exit(1);
10491
10961
  }
10492
- const { runLogin: runLogin2 } = await Promise.resolve().then(() => (init_auth2(), exports_auth));
10493
- await runLogin2(tool, opts.provider, opts.token);
10962
+ const { runLogin: runLogin3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
10963
+ await runLogin3(tool, opts.provider, opts.token);
10494
10964
  });
10495
- authCmd.command("logout").description("Log out from a tool").argument("<tool>", "Tool name").action(async (tool) => {
10496
- const { runLogout: runLogout2 } = await Promise.resolve().then(() => (init_auth2(), exports_auth));
10497
- await runLogout2(tool);
10965
+ authCmd.command("logout").description("Log out from a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
10966
+ if (opts.url) {
10967
+ const { mcpAuthLogout: mcpAuthLogout3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
10968
+ const deleted = mcpAuthLogout3(opts.url);
10969
+ if (deleted) {
10970
+ process.stderr.write(`Logged out from ${opts.url}
10971
+ `);
10972
+ } else {
10973
+ process.stderr.write(`No tokens found for ${opts.url}
10974
+ `);
10975
+ }
10976
+ return;
10977
+ }
10978
+ if (!tool) {
10979
+ process.stderr.write(`error: tool name is required (or use --url)
10980
+ `);
10981
+ process.exit(1);
10982
+ }
10983
+ const { runLogout: runLogout3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
10984
+ await runLogout3(tool);
10498
10985
  });
10499
- authCmd.command("status").description("Show auth status for a tool").argument("<tool>", "Tool name").action(async (tool) => {
10500
- const { runStatus: runStatus2 } = await Promise.resolve().then(() => (init_auth2(), exports_auth));
10501
- await runStatus2(tool);
10986
+ authCmd.command("status").description("Show auth status for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
10987
+ if (opts.url) {
10988
+ const { mcpAuthStatus: mcpAuthStatus3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
10989
+ console.log(JSON.stringify(mcpAuthStatus3(opts.url), null, 2));
10990
+ return;
10991
+ }
10992
+ if (!tool) {
10993
+ process.stderr.write(`error: tool name is required (or use --url)
10994
+ `);
10995
+ process.exit(1);
10996
+ }
10997
+ const { runStatus: runStatus3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
10998
+ await runStatus3(tool);
10502
10999
  });
10503
- authCmd.command("token").description("Print the access token for a tool").argument("<tool>", "Tool name").action(async (tool) => {
10504
- const { runToken: runToken2 } = await Promise.resolve().then(() => (init_auth2(), exports_auth));
10505
- await runToken2(tool);
11000
+ authCmd.command("token").description("Print the access token for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11001
+ if (opts.url) {
11002
+ const { mcpAuthToken: mcpAuthToken3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11003
+ const t = await mcpAuthToken3(opts.url);
11004
+ if (!t) {
11005
+ throw new Error(`no valid token for '${opts.url}'. Run: mtpcli auth login --url ${opts.url}`);
11006
+ }
11007
+ console.log(t);
11008
+ return;
11009
+ }
11010
+ if (!tool) {
11011
+ process.stderr.write(`error: tool name is required (or use --url)
11012
+ `);
11013
+ process.exit(1);
11014
+ }
11015
+ const { runToken: runToken3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11016
+ await runToken3(tool);
10506
11017
  });
10507
11018
  authCmd.command("env").description("Print shell export statement for eval").argument("<tool>", "Tool name").action(async (tool) => {
10508
- const { runEnv: runEnv2 } = await Promise.resolve().then(() => (init_auth2(), exports_auth));
10509
- await runEnv2(tool);
11019
+ const { runEnv: runEnv3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11020
+ await runEnv3(tool);
10510
11021
  });
10511
- authCmd.command("refresh").description("Force-refresh the stored OAuth token for a tool").argument("<tool>", "Tool name").action(async (tool) => {
10512
- const { runRefresh: runRefresh2 } = await Promise.resolve().then(() => (init_auth2(), exports_auth));
10513
- await runRefresh2(tool);
11022
+ authCmd.command("refresh").description("Force-refresh the stored OAuth token for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11023
+ if (opts.url) {
11024
+ const { mcpAuthRefresh: mcpAuthRefresh3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11025
+ await mcpAuthRefresh3(opts.url);
11026
+ return;
11027
+ }
11028
+ if (!tool) {
11029
+ process.stderr.write(`error: tool name is required (or use --url)
11030
+ `);
11031
+ process.exit(1);
11032
+ }
11033
+ const { runRefresh: runRefresh3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11034
+ await runRefresh3(tool);
10514
11035
  });
10515
11036
  program2.command("serve").description("Serve CLI tools as an MCP server (cli2mcp bridge)").requiredOption("--tool <names...>", "Tool(s) to serve").addHelpText("after", `
10516
11037
  This command is meant to be used as an MCP server, not run directly.
@@ -10551,7 +11072,7 @@ Multiple tools can be combined into a single MCP server:
10551
11072
  const { run: run5 } = await Promise.resolve().then(() => (init_serve(), exports_serve));
10552
11073
  await run5(opts.tool);
10553
11074
  });
10554
- program2.command("wrap").description("Wrap an MCP server as a CLI tool (mcp2cli bridge)").option("--server <cmd>", "MCP server command to run (stdio transport)").option("--url <url>", "MCP server URL (Streamable HTTP transport)").option("-H, --header <header...>", "HTTP header(s) for --url (e.g. 'Authorization: Bearer tok')").option("--client-id <id>", "Pre-registered OAuth client ID (for --url)").option("--describe", "Output --describe JSON instead of invoking", false).argument("[tool_name]", "Tool name to invoke").argument("[args...]", "Arguments for the tool (after --)").action(async (toolName, args, opts) => {
11075
+ program2.command("wrap").description("Wrap an MCP server as a CLI tool (mcp2cli bridge)").option("--server <cmd>", "MCP server command to run (stdio transport)").option("--url <url>", "MCP server URL (Streamable HTTP / SSE transport)").option("-H, --header <header...>", "HTTP header(s) for --url (e.g. 'Authorization: Bearer tok')").option("--client-id <id>", "Pre-registered OAuth client ID (for --url)").option("--describe", "Output --describe JSON instead of invoking", false).argument("[tool_name]", "Tool name to invoke").argument("[args...]", "Arguments for the tool (after --)").action(async (toolName, args, opts) => {
10555
11076
  if (opts.server && opts.url) {
10556
11077
  process.stderr.write(`error: --server and --url are mutually exclusive
10557
11078
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modeltoolsprotocol/mtpcli",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "bin": {