@xrpl-utilities/mcp 0.1.6

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 (41) hide show
  1. package/README.md +109 -0
  2. package/dist/dispatch.d.ts +53 -0
  3. package/dist/dispatch.js +158 -0
  4. package/dist/dispatch.js.map +1 -0
  5. package/dist/index.d.ts +13 -0
  6. package/dist/index.js +70 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/jsonschema.d.ts +19 -0
  9. package/dist/jsonschema.js +7 -0
  10. package/dist/jsonschema.js.map +1 -0
  11. package/dist/server.d.ts +9 -0
  12. package/dist/server.js +93 -0
  13. package/dist/server.js.map +1 -0
  14. package/dist/services/index.d.ts +28 -0
  15. package/dist/services/index.js +25 -0
  16. package/dist/services/index.js.map +1 -0
  17. package/dist/services/pulse.d.ts +12 -0
  18. package/dist/services/pulse.js +66 -0
  19. package/dist/services/pulse.js.map +1 -0
  20. package/dist/services/sentinel.d.ts +11 -0
  21. package/dist/services/sentinel.js +84 -0
  22. package/dist/services/sentinel.js.map +1 -0
  23. package/dist/services/telemetry.d.ts +21 -0
  24. package/dist/services/telemetry.js +118 -0
  25. package/dist/services/telemetry.js.map +1 -0
  26. package/dist/services/trust.d.ts +11 -0
  27. package/dist/services/trust.js +140 -0
  28. package/dist/services/trust.js.map +1 -0
  29. package/dist/transport/http.d.ts +18 -0
  30. package/dist/transport/http.js +106 -0
  31. package/dist/transport/http.js.map +1 -0
  32. package/dist/transport/stdio.d.ts +17 -0
  33. package/dist/transport/stdio.js +28 -0
  34. package/dist/transport/stdio.js.map +1 -0
  35. package/dist/types.d.ts +86 -0
  36. package/dist/types.js +11 -0
  37. package/dist/types.js.map +1 -0
  38. package/dist/validate.d.ts +29 -0
  39. package/dist/validate.js +88 -0
  40. package/dist/validate.js.map +1 -0
  41. package/package.json +50 -0
@@ -0,0 +1,28 @@
1
+ /**
2
+ * stdio transport. Used when Claude Desktop (or any MCP client that
3
+ * launches the server as a subprocess) spawns this binary directly.
4
+ *
5
+ * {
6
+ * "mcpServers": {
7
+ * "xrpl-utilities": {
8
+ * "command": "npx",
9
+ * "args": ["-y", "@xrpl-utilities/mcp", "--transport", "stdio"]
10
+ * }
11
+ * }
12
+ * }
13
+ *
14
+ * Single-tenant: the user's MCP_BYPASS_KEY (if set) and any pre-signed
15
+ * payment_signature live on their machine, never leave it.
16
+ */
17
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
+ import { buildServer } from "../server.js";
19
+ export async function runStdio() {
20
+ const server = buildServer({
21
+ bypassKey: process.env["MCP_BYPASS_KEY"],
22
+ userAgent: `xrpl-utilities-mcp/0.1.6 (stdio)`,
23
+ });
24
+ const transport = new StdioServerTransport();
25
+ await server.connect(transport);
26
+ // Server runs until the client closes stdio.
27
+ }
28
+ //# sourceMappingURL=stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/transport/stdio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,MAAM,GAAG,WAAW,CAAC;QACzB,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACxC,SAAS,EAAE,kCAAkC;KAC9C,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,6CAA6C;AAC/C,CAAC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Shared types for the XRPL-Utilities MCP server.
3
+ *
4
+ * Each registered service has a base URL, a manifest URL (for the
5
+ * startup schema-discipline check), and a list of tools that wrap
6
+ * specific endpoints. Tools are MCP-callable functions; the server
7
+ * dispatches incoming MCP tool calls to the underlying HTTP endpoint
8
+ * and forwards the response.
9
+ */
10
+ import type { JSONSchema7 } from "./jsonschema.js";
11
+ export type HttpMethod = "GET" | "POST";
12
+ /**
13
+ * Three auth modes are possible per tool:
14
+ *
15
+ * - inline_x402: caller passes `payment_signature` in tool args; the
16
+ * dispatcher forwards it as the PAYMENT-SIGNATURE
17
+ * header on the underlying call. Standard x402 v2
18
+ * verify-then-work-then-settle. $0.10 USD lands on
19
+ * the operator wallet per successful call.
20
+ *
21
+ * - async_invoice: this MCP tool wraps one step of the Telemetry
22
+ * three-step flow (quote -> pay -> status -> results).
23
+ * The MCP wrapper itself doesn't need a payment header
24
+ * - the actual XRPL Payment happens out-of-band via
25
+ * the deeplink / QR returned by quote. The operator
26
+ * still earns $0.10 per snapshot, just settled via a
27
+ * regular Payment instead of an inline x402 header.
28
+ *
29
+ * - free: truly free. Reserved for endpoints like /healthz
30
+ * or /schema mirrors. Not used today; placeholder for
31
+ * future XR-* services that may expose pure metadata.
32
+ *
33
+ * The `paid` field has been retained as a deprecated alias - true was
34
+ * inline_x402, false was async_invoice or free. New code should switch
35
+ * on authMode.
36
+ */
37
+ export type AuthMode = "inline_x402" | "async_invoice" | "free";
38
+ /**
39
+ * A single tool definition. The MCP server exposes one MCP tool per
40
+ * entry. Auth/payment is handled per-call by the dispatcher based on
41
+ * the tool's authMode and the caller-supplied `payment_signature` arg.
42
+ */
43
+ export interface ToolDef {
44
+ /** MCP tool name. Convention: xrpl_<service>_<verb>. */
45
+ name: string;
46
+ /** Description shown to the LLM. Be specific about pricing + return shape. */
47
+ description: string;
48
+ /** JSON Schema for the input arguments the LLM provides. */
49
+ inputSchema: JSONSchema7;
50
+ /** Underlying HTTP method on the target service. */
51
+ method: HttpMethod;
52
+ /**
53
+ * Path template on the target service. May contain {param} placeholders
54
+ * that get substituted from the input args before the request fires.
55
+ * Example: "/domain/{domain_id}".
56
+ */
57
+ path: string;
58
+ /** Auth model for this tool. See AuthMode docs above. */
59
+ authMode: AuthMode;
60
+ /**
61
+ * If true, the body of the HTTP request comes from the input args
62
+ * (minus payment_signature). If false, args go in the query string
63
+ * for GETs and there is no body. Only meaningful on POST.
64
+ */
65
+ bodyFromArgs?: boolean;
66
+ /**
67
+ * Args to drop from the body/query before sending. Used to strip
68
+ * payment_signature so it doesn't leak into the API call as a
69
+ * regular field.
70
+ */
71
+ stripArgs?: string[];
72
+ }
73
+ export interface ServiceDef {
74
+ /** Service identifier. Lowercased, used as a tool name prefix. */
75
+ id: string;
76
+ /** Human label for logs / errors. */
77
+ label: string;
78
+ /** Live HTTPS base. e.g. "https://sentinel.xrpl-utilities.io". */
79
+ baseUrl: string;
80
+ /** /agents.json URL — fetched at startup for schema-discipline check. */
81
+ manifestUrl: string;
82
+ /** Schema versions this MCP build is known to be compatible with. */
83
+ knownSchemaVersions: string[];
84
+ /** All tools this service exposes. */
85
+ tools: ToolDef[];
86
+ }
package/dist/types.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shared types for the XRPL-Utilities MCP server.
3
+ *
4
+ * Each registered service has a base URL, a manifest URL (for the
5
+ * startup schema-discipline check), and a list of tools that wrap
6
+ * specific endpoints. Tools are MCP-callable functions; the server
7
+ * dispatches incoming MCP tool calls to the underlying HTTP endpoint
8
+ * and forwards the response.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Startup schema-discipline check.
3
+ *
4
+ * For each registered service, fetch its live /agents.json and verify
5
+ *
6
+ * 1. The reported schema_version is one we've seen before
7
+ * (knownSchemaVersions). An unrecognized version means the
8
+ * upstream service may have added/renamed/removed fields the
9
+ * MCP build is not aware of - the operator should bump and re-
10
+ * release this MCP package after auditing the changes.
11
+ *
12
+ * 2. Each tool's path appears somewhere in the manifest's endpoints
13
+ * block. If a service renames /scan to /scan/v2 we want to fail
14
+ * LOUD here, not silently 404 every agent call.
15
+ *
16
+ * On dev / first-launch we may want to tolerate manifest fetch failures
17
+ * (so the MCP server still starts when networking is flaky); on
18
+ * production we want to fail-closed. STRICT_VALIDATE=1 toggles that.
19
+ */
20
+ export interface ValidationResult {
21
+ service: string;
22
+ ok: boolean;
23
+ warnings: string[];
24
+ errors: string[];
25
+ }
26
+ export declare function validateAllServices(opts: {
27
+ strict: boolean;
28
+ fetchTimeoutMs?: number;
29
+ }): Promise<ValidationResult[]>;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Startup schema-discipline check.
3
+ *
4
+ * For each registered service, fetch its live /agents.json and verify
5
+ *
6
+ * 1. The reported schema_version is one we've seen before
7
+ * (knownSchemaVersions). An unrecognized version means the
8
+ * upstream service may have added/renamed/removed fields the
9
+ * MCP build is not aware of - the operator should bump and re-
10
+ * release this MCP package after auditing the changes.
11
+ *
12
+ * 2. Each tool's path appears somewhere in the manifest's endpoints
13
+ * block. If a service renames /scan to /scan/v2 we want to fail
14
+ * LOUD here, not silently 404 every agent call.
15
+ *
16
+ * On dev / first-launch we may want to tolerate manifest fetch failures
17
+ * (so the MCP server still starts when networking is flaky); on
18
+ * production we want to fail-closed. STRICT_VALIDATE=1 toggles that.
19
+ */
20
+ import { SERVICES } from "./services/index.js";
21
+ export async function validateAllServices(opts) {
22
+ const results = await Promise.all(SERVICES.map((s) => validateService(s, opts.fetchTimeoutMs ?? 8_000)));
23
+ return results;
24
+ }
25
+ async function validateService(svc, timeoutMs) {
26
+ const out = {
27
+ service: svc.label,
28
+ ok: true,
29
+ warnings: [],
30
+ errors: [],
31
+ };
32
+ let manifest = null;
33
+ try {
34
+ const ctl = new AbortController();
35
+ const tId = setTimeout(() => ctl.abort(), timeoutMs);
36
+ const r = await fetch(svc.manifestUrl, { signal: ctl.signal });
37
+ clearTimeout(tId);
38
+ if (!r.ok) {
39
+ out.warnings.push(`manifest fetch returned HTTP ${r.status}`);
40
+ }
41
+ else {
42
+ manifest = (await r.json());
43
+ }
44
+ }
45
+ catch (e) {
46
+ out.warnings.push(`manifest fetch failed: ${e.message}`);
47
+ }
48
+ if (!manifest) {
49
+ // No live manifest - we can still start, but flag it so the
50
+ // operator knows the validator didn't actually verify anything.
51
+ return out;
52
+ }
53
+ const liveVersion = String(manifest["schema_version"] ?? "");
54
+ if (liveVersion && !svc.knownSchemaVersions.includes(liveVersion)) {
55
+ const msg = `${svc.label} reports schema_version=${liveVersion}; this MCP build ` +
56
+ `expects one of [${svc.knownSchemaVersions.join(", ")}]. Audit upstream ` +
57
+ `changes and bump knownSchemaVersions.`;
58
+ if (svc.knownSchemaVersions.length === 0) {
59
+ out.warnings.push(msg);
60
+ }
61
+ else {
62
+ out.errors.push(msg);
63
+ out.ok = false;
64
+ }
65
+ }
66
+ // Endpoint-presence check. The manifest's endpoints block is a flat
67
+ // map of names to URLs/paths. We consider a tool valid if ANY entry
68
+ // in the manifest contains the tool's path as a substring (covers
69
+ // entries like '/events?since=<event_id>&limit=...').
70
+ const endpoints = manifest["endpoints"];
71
+ if (endpoints && typeof endpoints === "object") {
72
+ const flat = Object.values(endpoints)
73
+ .map((v) => String(v))
74
+ .join(" ");
75
+ for (const tool of svc.tools) {
76
+ // Strip path params for the substring match.
77
+ const skeleton = tool.path.replace(/\{[^}]+\}/g, "").replace(/\/+$/, "");
78
+ if (skeleton && !flat.includes(skeleton)) {
79
+ out.errors.push(`tool ${tool.name} declares path ${tool.path} but the manifest ` +
80
+ `does not advertise that endpoint. Either rename the tool or add ` +
81
+ `the new path to ${svc.label}'s endpoints.`);
82
+ out.ok = false;
83
+ }
84
+ }
85
+ }
86
+ return out;
87
+ }
88
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAU/C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAGzC;IACC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IACzG,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAe,EAAE,SAAiB;IAC/D,MAAM,GAAG,GAAqB;QAC5B,OAAO,EAAE,GAAG,CAAC,KAAK;QAClB,EAAE,EAAE,IAAI;QACR,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,EAAE;KACX,CAAC;IAEF,IAAI,QAAQ,GAAmC,IAAI,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,eAAe,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/D,YAAY,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAA4B,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,0BAA2B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,4DAA4D;QAC5D,gEAAgE;QAChE,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7D,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAClE,MAAM,GAAG,GACP,GAAG,GAAG,CAAC,KAAK,2BAA2B,WAAW,mBAAmB;YACrE,mBAAmB,GAAG,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB;YACzE,uCAAuC,CAAC;QAC1C,IAAI,GAAG,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,oEAAoE;IACpE,kEAAkE;IAClE,sDAAsD;IACtD,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,SAAoC,CAAC;aAC7D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aACrB,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC7B,6CAA6C;YAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACzE,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzC,GAAG,CAAC,MAAM,CAAC,IAAI,CACb,QAAQ,IAAI,CAAC,IAAI,kBAAkB,IAAI,CAAC,IAAI,oBAAoB;oBAC9D,kEAAkE;oBAClE,mBAAmB,GAAG,CAAC,KAAK,eAAe,CAC9C,CAAC;gBACF,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@xrpl-utilities/mcp",
3
+ "version": "0.1.6",
4
+ "description": "Model Context Protocol server for the XRPL-Utilities portfolio: Sentinel (wallet classifier), Pulse (signal feed), Telemetry (supply + utility floor), and Trust (XLS-70/80/81 directory). Exposes each service's read endpoints as MCP tools so AI agents can discover and use them via stdio (Claude Desktop) or HTTP/SSE (hosted at mcp.xrpl-utilities.io). Stateless passthrough — caller provides their own x402 payment header.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "xrpl-utilities-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "start": "node dist/index.js",
17
+ "start:stdio": "node dist/index.js --transport stdio",
18
+ "start:http": "node dist/index.js --transport http",
19
+ "dev": "tsc --watch",
20
+ "test": "node --test dist/tests/*.test.js",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.0.0",
25
+ "express": "^4.21.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/express": "^4.17.21",
29
+ "@types/node": "^22.0.0",
30
+ "typescript": "^5.6.0"
31
+ },
32
+ "engines": {
33
+ "node": ">=20"
34
+ },
35
+ "keywords": [
36
+ "mcp",
37
+ "model-context-protocol",
38
+ "xrpl",
39
+ "x402",
40
+ "ai-agents",
41
+ "xrp",
42
+ "rlusd",
43
+ "xrpl-utilities"
44
+ ],
45
+ "homepage": "https://xrpl-utilities.com",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/XRPL-Utilities/xrpl-utilities-mcp.git"
49
+ }
50
+ }