stables-mcp-server 2.4.0 → 2.5.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.
- package/README.md +27 -3
- package/build/http/handler.d.ts +9 -0
- package/build/http/handler.d.ts.map +1 -1
- package/build/http/handler.js +22 -8
- package/build/http/handler.js.map +1 -1
- package/build/lib/stables-client.d.ts +17 -1
- package/build/lib/stables-client.d.ts.map +1 -1
- package/build/lib/stables-client.js +23 -1
- package/build/lib/stables-client.js.map +1 -1
- package/build/oauth/auth0.d.ts +76 -0
- package/build/oauth/auth0.d.ts.map +1 -0
- package/build/oauth/auth0.js +163 -0
- package/build/oauth/auth0.js.map +1 -0
- package/build/oauth/handlers.d.ts +11 -0
- package/build/oauth/handlers.d.ts.map +1 -0
- package/build/oauth/handlers.js +195 -0
- package/build/oauth/handlers.js.map +1 -0
- package/build/oauth/pages.d.ts +10 -0
- package/build/oauth/pages.d.ts.map +1 -0
- package/build/oauth/pages.js +80 -0
- package/build/oauth/pages.js.map +1 -0
- package/build/oauth/provider.d.ts +21 -0
- package/build/oauth/provider.d.ts.map +1 -0
- package/build/oauth/provider.js +95 -0
- package/build/oauth/provider.js.map +1 -0
- package/build/oauth/types.d.ts +41 -0
- package/build/oauth/types.d.ts.map +1 -0
- package/build/oauth/types.js +14 -0
- package/build/oauth/types.js.map +1 -0
- package/build/tools/webhooks.d.ts +8 -0
- package/build/tools/webhooks.d.ts.map +1 -1
- package/build/tools/webhooks.js +15 -2
- package/build/tools/webhooks.js.map +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/build/worker.d.ts +20 -7
- package/build/worker.d.ts.map +1 -1
- package/build/worker.js +35 -7
- package/build/worker.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shapes for the hosted server's OAuth support.
|
|
3
|
+
*
|
|
4
|
+
* The Worker is the OAuth authorization server MCP clients talk to (Claude,
|
|
5
|
+
* ChatGPT, Cursor, ...). Behind it, Auth0 signs the user in exactly as the
|
|
6
|
+
* dashboard does, and the Worker then mints a Stables API key for the
|
|
7
|
+
* organisation the user picked. That key lives in the grant's encrypted
|
|
8
|
+
* props, so every later MCP request is served with it and the Auth0 token
|
|
9
|
+
* is never kept.
|
|
10
|
+
*/
|
|
11
|
+
import type { OAuthHelpers } from "@cloudflare/workers-oauth-provider";
|
|
12
|
+
/** The one scope the server grants; tool-level scopes can come later. */
|
|
13
|
+
export declare const SCOPE = "stables";
|
|
14
|
+
export declare const SUPPORTED_SCOPES: string[];
|
|
15
|
+
export type StablesEnvironment = "sandbox" | "production";
|
|
16
|
+
/** What a grant carries; handlers read it as ctx.props. */
|
|
17
|
+
export interface GrantProps {
|
|
18
|
+
apiKey: string;
|
|
19
|
+
environment: StablesEnvironment;
|
|
20
|
+
apiKeyId?: string;
|
|
21
|
+
email?: string;
|
|
22
|
+
orgId?: string;
|
|
23
|
+
clientName?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Bindings and settings the OAuth path needs. See wrangler.toml. */
|
|
26
|
+
export interface OAuthEnv {
|
|
27
|
+
/** KV namespace the provider stores clients, grants and tokens in. */
|
|
28
|
+
OAUTH_KV?: unknown;
|
|
29
|
+
/** Injected by the provider for the default handler. */
|
|
30
|
+
OAUTH_PROVIDER?: OAuthHelpers;
|
|
31
|
+
/** Canonical public origin; defaults to the request origin. */
|
|
32
|
+
MCP_PUBLIC_URL?: string;
|
|
33
|
+
/** Auth0 custom domain, e.g. login.stables.money. */
|
|
34
|
+
AUTH0_DOMAIN?: string;
|
|
35
|
+
AUTH0_CLIENT_ID?: string;
|
|
36
|
+
/** Worker secret. */
|
|
37
|
+
AUTH0_CLIENT_SECRET?: string;
|
|
38
|
+
/** Worker secret shared with api-lambda-authoriser; unset = unsigned. */
|
|
39
|
+
MCP_GATEWAY_SIGNING_SECRET?: string;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/oauth/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,yEAAyE;AACzE,eAAO,MAAM,KAAK,YAAY,CAAC;AAC/B,eAAO,MAAM,gBAAgB,UAA4B,CAAC;AAE1D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,YAAY,CAAC;AAE1D,2DAA2D;AAC3D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,kBAAkB,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qEAAqE;AACrE,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qBAAqB;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yEAAyE;IACzE,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shapes for the hosted server's OAuth support.
|
|
3
|
+
*
|
|
4
|
+
* The Worker is the OAuth authorization server MCP clients talk to (Claude,
|
|
5
|
+
* ChatGPT, Cursor, ...). Behind it, Auth0 signs the user in exactly as the
|
|
6
|
+
* dashboard does, and the Worker then mints a Stables API key for the
|
|
7
|
+
* organisation the user picked. That key lives in the grant's encrypted
|
|
8
|
+
* props, so every later MCP request is served with it and the Auth0 token
|
|
9
|
+
* is never kept.
|
|
10
|
+
*/
|
|
11
|
+
/** The one scope the server grants; tool-level scopes can come later. */
|
|
12
|
+
export const SCOPE = "stables";
|
|
13
|
+
export const SUPPORTED_SCOPES = [SCOPE, "offline_access"];
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/oauth/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,yEAAyE;AACzE,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC;AAC/B,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC"}
|
|
@@ -4,5 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
6
|
import { StablesApiClient } from "../lib/stables-client.js";
|
|
7
|
+
/**
|
|
8
|
+
* The tenant-facing subset the API accepts. Declared as an enum rather than
|
|
9
|
+
* free strings so a wrong value is caught before the request instead of coming
|
|
10
|
+
* back as a 400 the model has to guess its way out of. Must equal the
|
|
11
|
+
* `eventTypes` enum in the deployed spec; webhook-event-types.contract.test.ts
|
|
12
|
+
* checks that against reference/spec.json (npm run check:spec).
|
|
13
|
+
*/
|
|
14
|
+
export declare const WEBHOOK_EVENT_TYPES: readonly ["customer.created", "customer.updated", "kyc_link.updated.status_transitioned", "transfer.created", "transfer.updated.status_transitioned", "transfer.action_required", "quote.created", "quote.updated.status_transitioned", "virtual_account.created", "virtual_account.activity.created", "virtual_account.activity.updated.status_transitioned", "virtual_account.fee_charge_failed", "virtual_account.deactivated", "virtual_account.reactivated", "travel_rule.wallet_verification_required", "rfi.created", "rfi.updated", "rfi.resolved", "entitlement.requested", "entitlement.updated.status_transitioned", "entitlement.updated.requirements_changed", "prefund.wallet.created", "prefund.deposit.received", "prefund.withdrawal.completed", "prefund.withdrawal.failed", "all"];
|
|
7
15
|
export declare function registerWebhookTools(server: McpServer, client: StablesApiClient): void;
|
|
8
16
|
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,uwBA2BtB,CAAC;AAEX,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,QAuN/E"}
|
package/build/tools/webhooks.js
CHANGED
|
@@ -6,23 +6,36 @@ import { z } from "zod";
|
|
|
6
6
|
/**
|
|
7
7
|
* The tenant-facing subset the API accepts. Declared as an enum rather than
|
|
8
8
|
* free strings so a wrong value is caught before the request instead of coming
|
|
9
|
-
* back as a 400 the model has to guess its way out of.
|
|
9
|
+
* back as a 400 the model has to guess its way out of. Must equal the
|
|
10
|
+
* `eventTypes` enum in the deployed spec; webhook-event-types.contract.test.ts
|
|
11
|
+
* checks that against reference/spec.json (npm run check:spec).
|
|
10
12
|
*/
|
|
11
|
-
const WEBHOOK_EVENT_TYPES = [
|
|
13
|
+
export const WEBHOOK_EVENT_TYPES = [
|
|
12
14
|
"customer.created",
|
|
13
15
|
"customer.updated",
|
|
14
16
|
"kyc_link.updated.status_transitioned",
|
|
15
17
|
"transfer.created",
|
|
16
18
|
"transfer.updated.status_transitioned",
|
|
19
|
+
"transfer.action_required",
|
|
17
20
|
"quote.created",
|
|
18
21
|
"quote.updated.status_transitioned",
|
|
19
22
|
"virtual_account.created",
|
|
20
23
|
"virtual_account.activity.created",
|
|
21
24
|
"virtual_account.activity.updated.status_transitioned",
|
|
25
|
+
"virtual_account.fee_charge_failed",
|
|
26
|
+
"virtual_account.deactivated",
|
|
27
|
+
"virtual_account.reactivated",
|
|
22
28
|
"travel_rule.wallet_verification_required",
|
|
23
29
|
"rfi.created",
|
|
24
30
|
"rfi.updated",
|
|
25
31
|
"rfi.resolved",
|
|
32
|
+
"entitlement.requested",
|
|
33
|
+
"entitlement.updated.status_transitioned",
|
|
34
|
+
"entitlement.updated.requirements_changed",
|
|
35
|
+
"prefund.wallet.created",
|
|
36
|
+
"prefund.deposit.received",
|
|
37
|
+
"prefund.withdrawal.completed",
|
|
38
|
+
"prefund.withdrawal.failed",
|
|
26
39
|
"all",
|
|
27
40
|
];
|
|
28
41
|
export function registerWebhookTools(server, client) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"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"}
|
package/build/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SERVER_VERSION = "2.
|
|
1
|
+
export declare const SERVER_VERSION = "2.5.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/build/version.js
CHANGED
package/build/worker.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare Worker entry point for the hosted Stables MCP server.
|
|
3
3
|
*
|
|
4
|
-
* Deployed with `npm run deploy:worker` (see wrangler.toml). The Worker
|
|
5
|
-
* no
|
|
4
|
+
* Deployed with `npm run deploy:worker` (see wrangler.toml). The Worker
|
|
5
|
+
* holds no customer credentials: a request either carries the caller's own
|
|
6
|
+
* API key, or an OAuth token whose grant carries the API key minted when
|
|
7
|
+
* the user signed in (src/oauth). Its only secrets are the Auth0 client
|
|
8
|
+
* secret and the gateway signing secret.
|
|
6
9
|
*
|
|
7
|
-
* Requests are rate limited per caller before
|
|
8
|
-
* when one is sent, otherwise by client IP, so
|
|
9
|
-
* one IP cannot crowd out keyed callers.
|
|
10
|
+
* Requests are rate limited per caller before anything else runs: by API
|
|
11
|
+
* key or OAuth token when one is sent, otherwise by client IP, so
|
|
12
|
+
* unauthenticated probing from one IP cannot crowd out keyed callers.
|
|
10
13
|
*/
|
|
14
|
+
import type { OAuthEnv } from "./oauth/types.js";
|
|
11
15
|
export interface RateLimiter {
|
|
12
16
|
limit(options: {
|
|
13
17
|
key: string;
|
|
@@ -15,12 +19,21 @@ export interface RateLimiter {
|
|
|
15
19
|
success: boolean;
|
|
16
20
|
}>;
|
|
17
21
|
}
|
|
18
|
-
export interface Env {
|
|
22
|
+
export interface Env extends OAuthEnv {
|
|
19
23
|
RATE_LIMITER: RateLimiter;
|
|
20
24
|
}
|
|
25
|
+
export interface ExecutionContextLike {
|
|
26
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
27
|
+
passThroughOnException(): void;
|
|
28
|
+
}
|
|
21
29
|
export declare function rateLimitKey(request: Request): string;
|
|
30
|
+
/**
|
|
31
|
+
* The OAuth host reads the Authorization header only. Clients that can set
|
|
32
|
+
* just X-Api-Key (the Stables API accepts it too) are mapped onto it here.
|
|
33
|
+
*/
|
|
34
|
+
export declare function normaliseAuthorization(request: Request): Request;
|
|
22
35
|
declare const _default: {
|
|
23
|
-
fetch(request: Request, env: Env): Promise<Response>;
|
|
36
|
+
fetch(request: Request, env: Env, ctx?: ExecutionContextLike): Promise<Response>;
|
|
24
37
|
};
|
|
25
38
|
export default _default;
|
|
26
39
|
//# sourceMappingURL=worker.d.ts.map
|
package/build/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,GAAI,SAAQ,QAAQ;IACnC,YAAY,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3C,sBAAsB,IAAI,IAAI,CAAC;CAChC;AAOD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAIrD;AAeD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAOhE;;mBAGsB,OAAO,OAAO,GAAG,QAAQ,oBAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC;;AADxF,wBAiBE"}
|
package/build/worker.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare Worker entry point for the hosted Stables MCP server.
|
|
3
3
|
*
|
|
4
|
-
* Deployed with `npm run deploy:worker` (see wrangler.toml). The Worker
|
|
5
|
-
* no
|
|
4
|
+
* Deployed with `npm run deploy:worker` (see wrangler.toml). The Worker
|
|
5
|
+
* holds no customer credentials: a request either carries the caller's own
|
|
6
|
+
* API key, or an OAuth token whose grant carries the API key minted when
|
|
7
|
+
* the user signed in (src/oauth). Its only secrets are the Auth0 client
|
|
8
|
+
* secret and the gateway signing secret.
|
|
6
9
|
*
|
|
7
|
-
* Requests are rate limited per caller before
|
|
8
|
-
* when one is sent, otherwise by client IP, so
|
|
9
|
-
* one IP cannot crowd out keyed callers.
|
|
10
|
+
* Requests are rate limited per caller before anything else runs: by API
|
|
11
|
+
* key or OAuth token when one is sent, otherwise by client IP, so
|
|
12
|
+
* unauthenticated probing from one IP cannot crowd out keyed callers.
|
|
10
13
|
*/
|
|
11
14
|
import { extractApiKey } from "./http/auth.js";
|
|
12
15
|
import { handleRequest } from "./http/handler.js";
|
|
16
|
+
import { providerFor } from "./oauth/provider.js";
|
|
17
|
+
const noopContext = {
|
|
18
|
+
waitUntil() { },
|
|
19
|
+
passThroughOnException() { },
|
|
20
|
+
};
|
|
13
21
|
export function rateLimitKey(request) {
|
|
14
22
|
const apiKey = extractApiKey(request.headers);
|
|
15
23
|
if (apiKey)
|
|
@@ -25,12 +33,32 @@ function rateLimited() {
|
|
|
25
33
|
headers: { "content-type": "application/json", "retry-after": "60" },
|
|
26
34
|
});
|
|
27
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* The OAuth host reads the Authorization header only. Clients that can set
|
|
38
|
+
* just X-Api-Key (the Stables API accepts it too) are mapped onto it here.
|
|
39
|
+
*/
|
|
40
|
+
export function normaliseAuthorization(request) {
|
|
41
|
+
if (request.headers.get("authorization"))
|
|
42
|
+
return request;
|
|
43
|
+
const apiKey = request.headers.get("x-api-key")?.trim();
|
|
44
|
+
if (!apiKey)
|
|
45
|
+
return request;
|
|
46
|
+
const headers = new Headers(request.headers);
|
|
47
|
+
headers.set("authorization", `Bearer ${apiKey}`);
|
|
48
|
+
return new Request(request, { headers });
|
|
49
|
+
}
|
|
28
50
|
export default {
|
|
29
|
-
async fetch(request, env) {
|
|
51
|
+
async fetch(request, env, ctx) {
|
|
30
52
|
const { success } = await env.RATE_LIMITER.limit({ key: rateLimitKey(request) });
|
|
31
53
|
if (!success)
|
|
32
54
|
return rateLimited();
|
|
33
|
-
|
|
55
|
+
// Without the KV binding there is nowhere to keep grants, so the server
|
|
56
|
+
// runs bearer-key only (local `wrangler dev --local`, unit tests).
|
|
57
|
+
if (!env.OAUTH_KV)
|
|
58
|
+
return handleRequest(request);
|
|
59
|
+
const origin = (env.MCP_PUBLIC_URL ?? new URL(request.url).origin).replace(/\/$/, "");
|
|
60
|
+
const provider = providerFor(origin);
|
|
61
|
+
return provider.fetch(normaliseAuthorization(request), env, (ctx ?? noopContext));
|
|
34
62
|
},
|
|
35
63
|
};
|
|
36
64
|
//# sourceMappingURL=worker.js.map
|
package/build/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBlD,MAAM,WAAW,GAAyB;IACxC,SAAS,KAAI,CAAC;IACd,sBAAsB,KAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,MAAM;QAAE,OAAO,OAAO,MAAM,EAAE,CAAC;IACnC,OAAO,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC;QACb,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,4CAA4C;KACtD,CAAC,EACF;QACE,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,IAAI,EAAE;KACrE,CACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAAE,OAAO,OAAO,CAAC;IACzD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC;IACxD,IAAI,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,MAAM,EAAE,CAAC,CAAC;IACjD,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,eAAe;IACb,KAAK,CAAC,KAAK,CAAC,OAAgB,EAAE,GAAQ,EAAE,GAA0B;QAChE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,OAAO;YAAE,OAAO,WAAW,EAAE,CAAC;QAEnC,wEAAwE;QACxE,mEAAmE;QACnE,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACtF,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,QAAQ,CAAC,KAAK,CACnB,sBAAsB,CAAC,OAAO,CAAC,EAC/B,GAAG,EACH,CAAC,GAAG,IAAI,WAAW,CAAoD,CACxE,CAAC;IACJ,CAAC;CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stables-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "MCP server for the Stables fiat-to-crypto API, hosted at mcp.stables.money or run locally - enables AI agents to manage customers, quotes, transfers and payment routes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"format": "prettier --write 'src/**/*.ts'",
|
|
30
30
|
"format:check": "prettier --check 'src/**/*.ts'",
|
|
31
31
|
"prepublishOnly": "npm run build",
|
|
32
|
-
"check:spec": "node scripts/fetch-reference.mjs && vitest run src/contract.test.ts",
|
|
32
|
+
"check:spec": "node scripts/fetch-reference.mjs && vitest run src/contract.test.ts src/webhook-event-types.contract.test.ts",
|
|
33
33
|
"test:e2e": "vitest run src/e2e.test.ts",
|
|
34
34
|
"check:release": "node scripts/check-release-state.mjs",
|
|
35
35
|
"docs:reference": "node scripts/generate-tool-reference.mjs > docs/tool-reference.md",
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"access": "public"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
+
"@cloudflare/workers-oauth-provider": "^1.2.3",
|
|
72
73
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
73
74
|
"zod": "^3.23.8"
|
|
74
75
|
},
|