mcpcost 0.3.0 → 0.3.1
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 +1 -1
- package/dist/auth-cli.d.ts +2 -0
- package/dist/auth-cli.js +16 -10
- package/dist/core.d.ts +2 -2
- package/dist/core.js +1 -1
- package/dist/credentials.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Every MCP server you configure hands your agent its tool definitions at the star
|
|
|
11
11
|
```
|
|
12
12
|
$ npx mcpcost --config .mcp.json --tools 3
|
|
13
13
|
|
|
14
|
-
mcpcost 0.3.
|
|
14
|
+
mcpcost 0.3.1 · tool definitions your agent loads before the first prompt
|
|
15
15
|
.mcp.json
|
|
16
16
|
|
|
17
17
|
server source result tools tokens of 200k
|
package/dist/auth-cli.d.ts
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
+
/** The default callback port. Fixed, because the registered client's redirect URI carries it; a random port would need a new registration every time. */
|
|
2
|
+
export declare const DEFAULT_CALLBACK_PORT = 41379;
|
|
1
3
|
export declare function authCommand(argv: string[]): Promise<number>;
|
package/dist/auth-cli.js
CHANGED
|
@@ -20,8 +20,9 @@ Usage
|
|
|
20
20
|
Options
|
|
21
21
|
--credentials <file> the credentials file (default ~/.mcpcost/credentials.json, or $MCPCOST_CREDENTIALS)
|
|
22
22
|
--scope <scope> scope to ask for in the OAuth flow
|
|
23
|
+
--port <n> local port for the callback (default 41379; the registered client is bound to it)
|
|
23
24
|
--no-open print the authorization URL, do not open the browser
|
|
24
|
-
--timeout <ms> how long to wait for the consent (default
|
|
25
|
+
--timeout <ms> how long to wait for the consent (default 600000)
|
|
25
26
|
|
|
26
27
|
After the consent the server is measured once with the new credentials, so you see that it works.
|
|
27
28
|
The daily board uses the same file through its MCPCOST credentials table; see the README.`;
|
|
@@ -36,8 +37,10 @@ function openBrowser(url) {
|
|
|
36
37
|
// The URL is printed too.
|
|
37
38
|
}
|
|
38
39
|
}
|
|
40
|
+
/** The default callback port. Fixed, because the registered client's redirect URI carries it; a random port would need a new registration every time. */
|
|
41
|
+
export const DEFAULT_CALLBACK_PORT = 41379;
|
|
39
42
|
/** Waits for one GET /callback?code=…&state=… on a local port. */
|
|
40
|
-
function callbackServer(expectedState, timeoutMs) {
|
|
43
|
+
function callbackServer(expectedState, timeoutMs, port) {
|
|
41
44
|
return new Promise((resolveServer, rejectServer) => {
|
|
42
45
|
let resolveCode = () => undefined;
|
|
43
46
|
let rejectCode = () => undefined;
|
|
@@ -70,10 +73,12 @@ function callbackServer(expectedState, timeoutMs) {
|
|
|
70
73
|
});
|
|
71
74
|
const timer = setTimeout(() => rejectCode(new Error(`no callback within ${Math.round(timeoutMs / 1000)} s`)), timeoutMs);
|
|
72
75
|
timer.unref();
|
|
73
|
-
server.on('error',
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
server.on('error', (err) => {
|
|
77
|
+
rejectServer(err.code === 'EADDRINUSE' ? new Error(`port ${port} is in use; pass --port <n> (the registered client is bound to the port)`) : err);
|
|
78
|
+
});
|
|
79
|
+
server.listen(port, '127.0.0.1', () => {
|
|
80
|
+
const bound = server.address().port;
|
|
81
|
+
resolveServer({ redirectUrl: `http://127.0.0.1:${bound}/callback`, code, close: () => { clearTimeout(timer); server.close(); } });
|
|
77
82
|
});
|
|
78
83
|
});
|
|
79
84
|
}
|
|
@@ -86,8 +91,9 @@ export async function authCommand(argv) {
|
|
|
86
91
|
list: { type: 'boolean', default: false },
|
|
87
92
|
remove: { type: 'boolean', default: false },
|
|
88
93
|
scope: { type: 'string' },
|
|
94
|
+
port: { type: 'string' },
|
|
89
95
|
'no-open': { type: 'boolean', default: false },
|
|
90
|
-
timeout: { type: 'string', default: '
|
|
96
|
+
timeout: { type: 'string', default: '600000' },
|
|
91
97
|
help: { type: 'boolean', default: false }
|
|
92
98
|
},
|
|
93
99
|
allowPositionals: true
|
|
@@ -145,8 +151,8 @@ export async function authCommand(argv) {
|
|
|
145
151
|
return verify(store, key);
|
|
146
152
|
}
|
|
147
153
|
// The OAuth flow: discovery, registration, the consent in the browser, the token.
|
|
148
|
-
const timeoutMs = Number(values.timeout) ||
|
|
149
|
-
const cb = await callbackServer(() => provider.lastState, timeoutMs);
|
|
154
|
+
const timeoutMs = Number(values.timeout) || 600_000;
|
|
155
|
+
const cb = await callbackServer(() => provider.lastState, timeoutMs, Number(values.port) || DEFAULT_CALLBACK_PORT);
|
|
150
156
|
const provider = createProvider(store, key, {
|
|
151
157
|
redirectUrl: cb.redirectUrl,
|
|
152
158
|
scope: values.scope,
|
|
@@ -154,7 +160,7 @@ export async function authCommand(argv) {
|
|
|
154
160
|
console.log(`\nOpen this URL and allow the access:\n ${url}\n`);
|
|
155
161
|
if (!values['no-open'])
|
|
156
162
|
openBrowser(url.toString());
|
|
157
|
-
console.log(
|
|
163
|
+
console.log(`Waiting for the consent, up to ${Math.round(timeoutMs / 60_000)} minutes…`);
|
|
158
164
|
}
|
|
159
165
|
});
|
|
160
166
|
try {
|
package/dist/core.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
2
2
|
import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
3
3
|
import type { ProbeResult, ProbeStatus, RemoteTransport } from './types.js';
|
|
4
|
-
export declare const VERSION = "0.3.
|
|
5
|
-
export declare const USER_AGENT = "mcpcost/0.3.
|
|
4
|
+
export declare const VERSION = "0.3.1";
|
|
5
|
+
export declare const USER_AGENT = "mcpcost/0.3.1 (mcpcost; +https://github.com/ondraulehla/mcpcost)";
|
|
6
6
|
export interface RawTool {
|
|
7
7
|
name: string;
|
|
8
8
|
description?: string;
|
package/dist/core.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
7
7
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
8
8
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
9
|
-
export const VERSION = '0.3.
|
|
9
|
+
export const VERSION = '0.3.1';
|
|
10
10
|
export const USER_AGENT = `mcpcost/${VERSION} (mcpcost; +https://github.com/ondraulehla/mcpcost)`;
|
|
11
11
|
export function emptyResult(url, transport) {
|
|
12
12
|
return { url, transport, probedAt: new Date().toISOString(), status: 'error', latencyMs: {} };
|
package/dist/credentials.js
CHANGED
|
@@ -69,6 +69,14 @@ export function createProvider(store, url, options = {}) {
|
|
|
69
69
|
oauth.scope = options.scope;
|
|
70
70
|
const redirectUrl = options.redirectUrl ?? 'http://127.0.0.1/callback';
|
|
71
71
|
let changed = false;
|
|
72
|
+
// A client registered for another redirect URI (an earlier port) cannot be used; register again.
|
|
73
|
+
if (options.onRedirect && oauth.clientInformation && !oauth.tokens) {
|
|
74
|
+
const uris = oauth.clientInformation.redirect_uris;
|
|
75
|
+
if (uris && !uris.includes(redirectUrl)) {
|
|
76
|
+
delete oauth.clientInformation;
|
|
77
|
+
changed = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
72
80
|
let verifier;
|
|
73
81
|
let state;
|
|
74
82
|
const touched = () => {
|
package/package.json
CHANGED