@usethrottle/mcp 0.2.0 → 0.2.2
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 +9 -2
- package/dist/contract-index.json +1 -1
- package/dist/docs-index.json +1 -1
- package/dist/lib.cjs +1784 -153
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +58 -4
- package/dist/lib.d.ts +58 -4
- package/dist/lib.js +1784 -153
- package/dist/lib.js.map +1 -1
- package/dist/mcp.js +1784 -153
- package/dist/mcp.js.map +1 -1
- package/package.json +3 -3
package/dist/lib.d.cts
CHANGED
|
@@ -14,6 +14,21 @@ interface RequestOptions {
|
|
|
14
14
|
* `(workspace, application, environment, key, method, path)`.
|
|
15
15
|
*/
|
|
16
16
|
idempotencyKey?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Sent as `X-Throttle-Application-Id` on this one request only — see
|
|
19
|
+
* `PerCallOptions`.
|
|
20
|
+
*/
|
|
21
|
+
applicationId?: string;
|
|
22
|
+
}
|
|
23
|
+
interface PerCallOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Overrides which application a single `get`/`list` call reads from (the
|
|
26
|
+
* `oauth_token` auth branch validates this against the grant's own
|
|
27
|
+
* workspace membership; see `resolveOAuthApplication`). Scoped to this one
|
|
28
|
+
* request — never stored on the client instance — so concurrent calls with
|
|
29
|
+
* different application ids cannot bleed into each other.
|
|
30
|
+
*/
|
|
31
|
+
applicationId?: string;
|
|
17
32
|
}
|
|
18
33
|
interface Pagination {
|
|
19
34
|
cursor: string | null;
|
|
@@ -25,14 +40,26 @@ interface ListResult<T> {
|
|
|
25
40
|
}
|
|
26
41
|
type Fetcher = typeof fetch;
|
|
27
42
|
declare class ThrottleClient {
|
|
28
|
-
private
|
|
43
|
+
private auth;
|
|
29
44
|
private readonly fetchImpl;
|
|
30
45
|
constructor(auth: AuthCtx, fetchImpl?: Fetcher);
|
|
46
|
+
/**
|
|
47
|
+
* Swap the credential every later request is sent with. The hosted remote
|
|
48
|
+
* server builds one client per MCP session at `initialize`, but an OAuth
|
|
49
|
+
* access token lives one hour and the MCP client refreshes it underneath
|
|
50
|
+
* the session — each request then arrives with a newer bearer than the one
|
|
51
|
+
* the session was opened with. Without this, the session keeps calling the
|
|
52
|
+
* REST API with the token it was born with and every tool fails with a 401
|
|
53
|
+
* the moment that first token expires, even though the caller is still
|
|
54
|
+
* perfectly authenticated.
|
|
55
|
+
*/
|
|
56
|
+
setApiKey(apiKey: string): void;
|
|
31
57
|
private requestJson;
|
|
32
58
|
/** Unwraps the `{ data }` envelope. Key presence, not `??` — `{data: null}` unwraps to null. */
|
|
33
|
-
get<T>(path: string, query?: Record<string, unknown
|
|
34
|
-
list<T>(path: string, query?: Record<string, unknown
|
|
59
|
+
get<T>(path: string, query?: Record<string, unknown>, options?: PerCallOptions): Promise<T>;
|
|
60
|
+
list<T>(path: string, query?: Record<string, unknown>, options?: PerCallOptions): Promise<ListResult<T>>;
|
|
35
61
|
post<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
62
|
+
patch<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
36
63
|
}
|
|
37
64
|
|
|
38
65
|
/**
|
|
@@ -67,7 +94,8 @@ interface ContractIndex {
|
|
|
67
94
|
}
|
|
68
95
|
|
|
69
96
|
/**
|
|
70
|
-
* `search_docs`, answered from an index of
|
|
97
|
+
* `search_docs`, answered from an index of the docs pages in `apps/web`,
|
|
98
|
+
* bundled at build time.
|
|
71
99
|
*
|
|
72
100
|
* Scoring mirrors the CLI's proven approach: title hits beat heading hits, which
|
|
73
101
|
* beat body hits, and an exact phrase beats scattered terms. Deliberately simple —
|
|
@@ -122,6 +150,22 @@ interface RegistrationPolicy {
|
|
|
122
150
|
identity: Identity;
|
|
123
151
|
allowWrites: boolean;
|
|
124
152
|
allowLiveWrites: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Whether sandbox-only writes (`seed_test_data`) register without
|
|
155
|
+
* `allowWrites`. Defaults to true — the documented CLI behaviour, where
|
|
156
|
+
* seeding a non-production environment needs no flag. The hosted remote
|
|
157
|
+
* server passes false: it is published as strictly read-only, and a
|
|
158
|
+
* directory reviewer connecting with a non-production credential must not
|
|
159
|
+
* find a tool that creates customers and orders.
|
|
160
|
+
*/
|
|
161
|
+
allowSandboxWrites?: boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Whether `credentialScoped` actions (`api_get`) register. Defaults to true
|
|
164
|
+
* for the CLI. The hosted server passes false: on an OAuth surface every
|
|
165
|
+
* tool declares the scopes it asks consent for, and a tool that reads any
|
|
166
|
+
* path cannot.
|
|
167
|
+
*/
|
|
168
|
+
allowCredentialScoped?: boolean;
|
|
125
169
|
}
|
|
126
170
|
/**
|
|
127
171
|
* Which tools this session gets. Pure and exported so the policy is testable
|
|
@@ -156,6 +200,16 @@ interface CreateServerOptions extends RegistrationPolicy {
|
|
|
156
200
|
client: ThrottleClient;
|
|
157
201
|
contract: ContractIndex;
|
|
158
202
|
docs: DocsIndex;
|
|
203
|
+
/**
|
|
204
|
+
* The `WWW-Authenticate` challenge value the hosting transport advertises
|
|
205
|
+
* (RFC 9728 `Bearer resource_metadata="..."`). When set, a tool call that
|
|
206
|
+
* fails because the REST API rejected the credential (HTTP 401 — an expired
|
|
207
|
+
* or revoked OAuth access token) carries it back as
|
|
208
|
+
* `_meta["mcp/www_authenticate"]`, which is what ChatGPT and other remote
|
|
209
|
+
* clients key their re-authorization UI on. The stdio CLI leaves it unset:
|
|
210
|
+
* its operator-provided key has no re-auth flow to trigger.
|
|
211
|
+
*/
|
|
212
|
+
authChallenge?: string;
|
|
159
213
|
}
|
|
160
214
|
declare function createServer(options: CreateServerOptions): McpServer;
|
|
161
215
|
|
package/dist/lib.d.ts
CHANGED
|
@@ -14,6 +14,21 @@ interface RequestOptions {
|
|
|
14
14
|
* `(workspace, application, environment, key, method, path)`.
|
|
15
15
|
*/
|
|
16
16
|
idempotencyKey?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Sent as `X-Throttle-Application-Id` on this one request only — see
|
|
19
|
+
* `PerCallOptions`.
|
|
20
|
+
*/
|
|
21
|
+
applicationId?: string;
|
|
22
|
+
}
|
|
23
|
+
interface PerCallOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Overrides which application a single `get`/`list` call reads from (the
|
|
26
|
+
* `oauth_token` auth branch validates this against the grant's own
|
|
27
|
+
* workspace membership; see `resolveOAuthApplication`). Scoped to this one
|
|
28
|
+
* request — never stored on the client instance — so concurrent calls with
|
|
29
|
+
* different application ids cannot bleed into each other.
|
|
30
|
+
*/
|
|
31
|
+
applicationId?: string;
|
|
17
32
|
}
|
|
18
33
|
interface Pagination {
|
|
19
34
|
cursor: string | null;
|
|
@@ -25,14 +40,26 @@ interface ListResult<T> {
|
|
|
25
40
|
}
|
|
26
41
|
type Fetcher = typeof fetch;
|
|
27
42
|
declare class ThrottleClient {
|
|
28
|
-
private
|
|
43
|
+
private auth;
|
|
29
44
|
private readonly fetchImpl;
|
|
30
45
|
constructor(auth: AuthCtx, fetchImpl?: Fetcher);
|
|
46
|
+
/**
|
|
47
|
+
* Swap the credential every later request is sent with. The hosted remote
|
|
48
|
+
* server builds one client per MCP session at `initialize`, but an OAuth
|
|
49
|
+
* access token lives one hour and the MCP client refreshes it underneath
|
|
50
|
+
* the session — each request then arrives with a newer bearer than the one
|
|
51
|
+
* the session was opened with. Without this, the session keeps calling the
|
|
52
|
+
* REST API with the token it was born with and every tool fails with a 401
|
|
53
|
+
* the moment that first token expires, even though the caller is still
|
|
54
|
+
* perfectly authenticated.
|
|
55
|
+
*/
|
|
56
|
+
setApiKey(apiKey: string): void;
|
|
31
57
|
private requestJson;
|
|
32
58
|
/** Unwraps the `{ data }` envelope. Key presence, not `??` — `{data: null}` unwraps to null. */
|
|
33
|
-
get<T>(path: string, query?: Record<string, unknown
|
|
34
|
-
list<T>(path: string, query?: Record<string, unknown
|
|
59
|
+
get<T>(path: string, query?: Record<string, unknown>, options?: PerCallOptions): Promise<T>;
|
|
60
|
+
list<T>(path: string, query?: Record<string, unknown>, options?: PerCallOptions): Promise<ListResult<T>>;
|
|
35
61
|
post<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
62
|
+
patch<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
36
63
|
}
|
|
37
64
|
|
|
38
65
|
/**
|
|
@@ -67,7 +94,8 @@ interface ContractIndex {
|
|
|
67
94
|
}
|
|
68
95
|
|
|
69
96
|
/**
|
|
70
|
-
* `search_docs`, answered from an index of
|
|
97
|
+
* `search_docs`, answered from an index of the docs pages in `apps/web`,
|
|
98
|
+
* bundled at build time.
|
|
71
99
|
*
|
|
72
100
|
* Scoring mirrors the CLI's proven approach: title hits beat heading hits, which
|
|
73
101
|
* beat body hits, and an exact phrase beats scattered terms. Deliberately simple —
|
|
@@ -122,6 +150,22 @@ interface RegistrationPolicy {
|
|
|
122
150
|
identity: Identity;
|
|
123
151
|
allowWrites: boolean;
|
|
124
152
|
allowLiveWrites: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Whether sandbox-only writes (`seed_test_data`) register without
|
|
155
|
+
* `allowWrites`. Defaults to true — the documented CLI behaviour, where
|
|
156
|
+
* seeding a non-production environment needs no flag. The hosted remote
|
|
157
|
+
* server passes false: it is published as strictly read-only, and a
|
|
158
|
+
* directory reviewer connecting with a non-production credential must not
|
|
159
|
+
* find a tool that creates customers and orders.
|
|
160
|
+
*/
|
|
161
|
+
allowSandboxWrites?: boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Whether `credentialScoped` actions (`api_get`) register. Defaults to true
|
|
164
|
+
* for the CLI. The hosted server passes false: on an OAuth surface every
|
|
165
|
+
* tool declares the scopes it asks consent for, and a tool that reads any
|
|
166
|
+
* path cannot.
|
|
167
|
+
*/
|
|
168
|
+
allowCredentialScoped?: boolean;
|
|
125
169
|
}
|
|
126
170
|
/**
|
|
127
171
|
* Which tools this session gets. Pure and exported so the policy is testable
|
|
@@ -156,6 +200,16 @@ interface CreateServerOptions extends RegistrationPolicy {
|
|
|
156
200
|
client: ThrottleClient;
|
|
157
201
|
contract: ContractIndex;
|
|
158
202
|
docs: DocsIndex;
|
|
203
|
+
/**
|
|
204
|
+
* The `WWW-Authenticate` challenge value the hosting transport advertises
|
|
205
|
+
* (RFC 9728 `Bearer resource_metadata="..."`). When set, a tool call that
|
|
206
|
+
* fails because the REST API rejected the credential (HTTP 401 — an expired
|
|
207
|
+
* or revoked OAuth access token) carries it back as
|
|
208
|
+
* `_meta["mcp/www_authenticate"]`, which is what ChatGPT and other remote
|
|
209
|
+
* clients key their re-authorization UI on. The stdio CLI leaves it unset:
|
|
210
|
+
* its operator-provided key has no re-auth flow to trigger.
|
|
211
|
+
*/
|
|
212
|
+
authChallenge?: string;
|
|
159
213
|
}
|
|
160
214
|
declare function createServer(options: CreateServerOptions): McpServer;
|
|
161
215
|
|