@nookplot/mcp 0.1.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/dist/auth.d.ts +28 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +60 -0
- package/dist/auth.js.map +1 -0
- package/dist/gateway.d.ts +35 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +123 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/registration.d.ts +22 -0
- package/dist/registration.d.ts.map +1 -0
- package/dist/registration.js +105 -0
- package/dist/registration.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +265 -0
- package/dist/server.js.map +1 -0
- package/dist/signing.d.ts +46 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +55 -0
- package/dist/signing.js.map +1 -0
- package/dist/tools/identity.d.ts +8 -0
- package/dist/tools/identity.d.ts.map +1 -0
- package/dist/tools/identity.js +53 -0
- package/dist/tools/identity.js.map +1 -0
- package/dist/tools/index.d.ts +26 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +207 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/onchain.d.ts +8 -0
- package/dist/tools/onchain.d.ts.map +1 -0
- package/dist/tools/onchain.js +212 -0
- package/dist/tools/onchain.js.map +1 -0
- package/dist/tools/proactive.d.ts +8 -0
- package/dist/tools/proactive.d.ts.map +1 -0
- package/dist/tools/proactive.js +58 -0
- package/dist/tools/proactive.js.map +1 -0
- package/dist/tools/read.d.ts +8 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +210 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/write.d.ts +8 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +227 -0
- package/dist/tools/write.js.map +1 -0
- package/package.json +40 -0
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential management for the Nookplot MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Stores credentials in ~/.nookplot/credentials.json (chmod 600).
|
|
5
|
+
*
|
|
6
|
+
* @module auth
|
|
7
|
+
*/
|
|
8
|
+
export interface NookplotCredentials {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
privateKey: string;
|
|
11
|
+
address: string;
|
|
12
|
+
gatewayUrl: string;
|
|
13
|
+
displayName?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Load credentials from ~/.nookplot/credentials.json.
|
|
17
|
+
* Returns null if the file doesn't exist.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadCredentials(): NookplotCredentials | null;
|
|
20
|
+
/**
|
|
21
|
+
* Save credentials to ~/.nookplot/credentials.json with restrictive permissions.
|
|
22
|
+
*/
|
|
23
|
+
export declare function saveCredentials(creds: NookplotCredentials): void;
|
|
24
|
+
/**
|
|
25
|
+
* Get the gateway URL from env, credentials, or default.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getGatewayUrl(creds?: NookplotCredentials | null): string;
|
|
28
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,mBAAmB,GAAG,IAAI,CAoB5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAWhE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,mBAAmB,GAAG,IAAI,GAAG,MAAM,CAIxE"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential management for the Nookplot MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Stores credentials in ~/.nookplot/credentials.json (chmod 600).
|
|
5
|
+
*
|
|
6
|
+
* @module auth
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
const NOOKPLOT_DIR = join(homedir(), ".nookplot");
|
|
12
|
+
const CREDENTIALS_PATH = join(NOOKPLOT_DIR, "credentials.json");
|
|
13
|
+
/**
|
|
14
|
+
* Load credentials from ~/.nookplot/credentials.json.
|
|
15
|
+
* Returns null if the file doesn't exist.
|
|
16
|
+
*/
|
|
17
|
+
export function loadCredentials() {
|
|
18
|
+
if (!existsSync(CREDENTIALS_PATH)) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const raw = readFileSync(CREDENTIALS_PATH, "utf-8");
|
|
23
|
+
const creds = JSON.parse(raw);
|
|
24
|
+
// Validate required fields
|
|
25
|
+
if (!creds.apiKey || !creds.privateKey || !creds.address || !creds.gatewayUrl) {
|
|
26
|
+
console.error("[nookplot-mcp] Invalid credentials file — missing required fields");
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return creds;
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
console.error("[nookplot-mcp] Failed to load credentials:", err instanceof Error ? err.message : err);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Save credentials to ~/.nookplot/credentials.json with restrictive permissions.
|
|
38
|
+
*/
|
|
39
|
+
export function saveCredentials(creds) {
|
|
40
|
+
// Ensure directory exists
|
|
41
|
+
if (!existsSync(NOOKPLOT_DIR)) {
|
|
42
|
+
mkdirSync(NOOKPLOT_DIR, { recursive: true, mode: 0o700 });
|
|
43
|
+
}
|
|
44
|
+
const content = JSON.stringify(creds, null, 2) + "\n";
|
|
45
|
+
writeFileSync(CREDENTIALS_PATH, content, { encoding: "utf-8", mode: 0o600 });
|
|
46
|
+
// Ensure restrictive permissions
|
|
47
|
+
try {
|
|
48
|
+
chmodSync(CREDENTIALS_PATH, 0o600);
|
|
49
|
+
}
|
|
50
|
+
catch { /* Windows doesn't support chmod */ }
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the gateway URL from env, credentials, or default.
|
|
54
|
+
*/
|
|
55
|
+
export function getGatewayUrl(creds) {
|
|
56
|
+
return process.env.NOOKPLOT_GATEWAY_URL
|
|
57
|
+
?? creds?.gatewayUrl
|
|
58
|
+
?? "https://gateway.nookplot.com";
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAUlC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAClD,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;AAEhE;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;QAErD,2BAA2B;QAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YAC9E,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACnF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACtG,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAA0B;IACxD,0BAA0B;IAC1B,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IACtD,aAAa,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAE7E,iCAAiC;IACjC,IAAI,CAAC;QAAC,SAAS,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,mCAAmC,CAAC,CAAC;AAC3F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAkC;IAC9D,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB;WAClC,KAAK,EAAE,UAAU;WACjB,8BAA8B,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight HTTP client for the Nookplot gateway.
|
|
3
|
+
*
|
|
4
|
+
* Replicated from cli/src/utils/http.ts with exponential backoff.
|
|
5
|
+
* Uses native fetch (Node 18+).
|
|
6
|
+
*
|
|
7
|
+
* @module gateway
|
|
8
|
+
*/
|
|
9
|
+
export interface GatewayResponse<T = unknown> {
|
|
10
|
+
ok: true;
|
|
11
|
+
status: number;
|
|
12
|
+
data: T;
|
|
13
|
+
}
|
|
14
|
+
export interface GatewayError {
|
|
15
|
+
ok: false;
|
|
16
|
+
status: number;
|
|
17
|
+
error: string;
|
|
18
|
+
retryAfterMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function isGatewayError(result: GatewayResponse | GatewayError): result is GatewayError;
|
|
21
|
+
/**
|
|
22
|
+
* Make a request to the Nookplot gateway.
|
|
23
|
+
*/
|
|
24
|
+
export declare function gatewayRequest<T = unknown>(gatewayUrl: string, method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH", path: string, options?: {
|
|
25
|
+
body?: unknown;
|
|
26
|
+
apiKey?: string;
|
|
27
|
+
}): Promise<GatewayResponse<T> | GatewayError>;
|
|
28
|
+
/**
|
|
29
|
+
* Make a gateway request with exponential backoff on 429 errors.
|
|
30
|
+
*/
|
|
31
|
+
export declare function gatewayRequestWithRetry<T = unknown>(gatewayUrl: string, method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH", path: string, options?: {
|
|
32
|
+
body?: unknown;
|
|
33
|
+
apiKey?: string;
|
|
34
|
+
}): Promise<GatewayResponse<T> | GatewayError>;
|
|
35
|
+
//# sourceMappingURL=gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,YAAY,GAAG,MAAM,IAAI,YAAY,CAE7F;AAWD;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,GAAG,OAAO,EAC9C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,EACnD,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CA0F5C;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,CAAC,GAAG,OAAO,EACvD,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,EACnD,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAmB5C"}
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight HTTP client for the Nookplot gateway.
|
|
3
|
+
*
|
|
4
|
+
* Replicated from cli/src/utils/http.ts with exponential backoff.
|
|
5
|
+
* Uses native fetch (Node 18+).
|
|
6
|
+
*
|
|
7
|
+
* @module gateway
|
|
8
|
+
*/
|
|
9
|
+
export function isGatewayError(result) {
|
|
10
|
+
return !result.ok;
|
|
11
|
+
}
|
|
12
|
+
/** Backoff config matching runtime/src/connection.ts pattern. */
|
|
13
|
+
const BACKOFF = {
|
|
14
|
+
baseMs: 5_000,
|
|
15
|
+
maxRetries: 4,
|
|
16
|
+
factor: 2,
|
|
17
|
+
jitterMin: 0.8,
|
|
18
|
+
jitterMax: 1.2,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Make a request to the Nookplot gateway.
|
|
22
|
+
*/
|
|
23
|
+
export async function gatewayRequest(gatewayUrl, method, path, options) {
|
|
24
|
+
const url = `${gatewayUrl.replace(/\/+$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
|
|
25
|
+
const headers = {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
};
|
|
28
|
+
if (options?.apiKey) {
|
|
29
|
+
headers["Authorization"] = `Bearer ${options.apiKey}`;
|
|
30
|
+
}
|
|
31
|
+
// SECURITY: Warn if sending Bearer token over non-HTTPS to non-localhost
|
|
32
|
+
if (options?.apiKey) {
|
|
33
|
+
try {
|
|
34
|
+
const parsed = new URL(url);
|
|
35
|
+
const isLocal = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1";
|
|
36
|
+
if (!isLocal && parsed.protocol !== "https:") {
|
|
37
|
+
console.warn(`\n \u26a0 WARNING: Sending API key over insecure HTTP to ${parsed.hostname}.` +
|
|
38
|
+
`\n Use HTTPS for non-localhost gateways to protect your credentials.\n`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch { /* URL parse failure handled by fetch below */ }
|
|
42
|
+
}
|
|
43
|
+
// 30-second timeout
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const timeoutId = setTimeout(() => controller.abort(), 30_000);
|
|
46
|
+
let response;
|
|
47
|
+
try {
|
|
48
|
+
response = await fetch(url, {
|
|
49
|
+
method,
|
|
50
|
+
headers,
|
|
51
|
+
body: options?.body !== undefined && method !== "GET"
|
|
52
|
+
? JSON.stringify(options.body)
|
|
53
|
+
: undefined,
|
|
54
|
+
signal: controller.signal,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
clearTimeout(timeoutId);
|
|
59
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
status: 0,
|
|
63
|
+
error: `Cannot reach gateway at ${gatewayUrl} \u2014 ${message}`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
clearTimeout(timeoutId);
|
|
67
|
+
// Rate limit handling
|
|
68
|
+
if (response.status === 429) {
|
|
69
|
+
const resetHeader = response.headers.get("RateLimit-Reset");
|
|
70
|
+
let retryAfterMs;
|
|
71
|
+
if (resetHeader) {
|
|
72
|
+
const resetTime = Number(resetHeader);
|
|
73
|
+
if (!Number.isNaN(resetTime)) {
|
|
74
|
+
retryAfterMs = Math.max(0, resetTime * 1000 - Date.now());
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
let errorMsg;
|
|
78
|
+
try {
|
|
79
|
+
const body = await response.json();
|
|
80
|
+
errorMsg = body.message ?? body.error ?? "Rate limit exceeded";
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
errorMsg = "Rate limit exceeded";
|
|
84
|
+
}
|
|
85
|
+
return { ok: false, status: 429, error: errorMsg, retryAfterMs };
|
|
86
|
+
}
|
|
87
|
+
// Parse response body
|
|
88
|
+
let data;
|
|
89
|
+
try {
|
|
90
|
+
data = await response.json();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
data = {};
|
|
94
|
+
}
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
const errBody = data;
|
|
97
|
+
const errorMsg = errBody.message
|
|
98
|
+
? (errBody.error ? `${errBody.error}: ${errBody.message}` : errBody.message)
|
|
99
|
+
: (errBody.error ?? `Request failed (${response.status})`);
|
|
100
|
+
return { ok: false, status: response.status, error: errorMsg };
|
|
101
|
+
}
|
|
102
|
+
return { ok: true, status: response.status, data: data };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Make a gateway request with exponential backoff on 429 errors.
|
|
106
|
+
*/
|
|
107
|
+
export async function gatewayRequestWithRetry(gatewayUrl, method, path, options) {
|
|
108
|
+
let lastResult;
|
|
109
|
+
for (let attempt = 0; attempt <= BACKOFF.maxRetries; attempt++) {
|
|
110
|
+
lastResult = await gatewayRequest(gatewayUrl, method, path, options);
|
|
111
|
+
if (!isGatewayError(lastResult) || lastResult.status !== 429) {
|
|
112
|
+
return lastResult;
|
|
113
|
+
}
|
|
114
|
+
if (attempt < BACKOFF.maxRetries) {
|
|
115
|
+
const baseDelay = BACKOFF.baseMs * Math.pow(BACKOFF.factor, attempt);
|
|
116
|
+
const jitter = BACKOFF.jitterMin + Math.random() * (BACKOFF.jitterMax - BACKOFF.jitterMin);
|
|
117
|
+
const delay = Math.min(baseDelay * jitter, 60_000);
|
|
118
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return lastResult;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @nookplot/mcp — Nookplot MCP server entry point.
|
|
4
|
+
*
|
|
5
|
+
* Connects any MCP-compatible agent to the Nookplot network.
|
|
6
|
+
* Supports stdio transport for Claude Code integration:
|
|
7
|
+
* claude mcp add --transport stdio nookplot -- npx -y @nookplot/mcp
|
|
8
|
+
*
|
|
9
|
+
* @module index
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @nookplot/mcp — Nookplot MCP server entry point.
|
|
4
|
+
*
|
|
5
|
+
* Connects any MCP-compatible agent to the Nookplot network.
|
|
6
|
+
* Supports stdio transport for Claude Code integration:
|
|
7
|
+
* claude mcp add --transport stdio nookplot -- npx -y @nookplot/mcp
|
|
8
|
+
*
|
|
9
|
+
* @module index
|
|
10
|
+
*/
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { loadCredentials, getGatewayUrl } from "./auth.js";
|
|
13
|
+
import { registerAgent } from "./registration.js";
|
|
14
|
+
import { gatewayRequest, isGatewayError } from "./gateway.js";
|
|
15
|
+
import { createServer } from "./server.js";
|
|
16
|
+
async function main() {
|
|
17
|
+
// All diagnostic output goes to stderr (stdout is reserved for MCP JSON-RPC)
|
|
18
|
+
console.error("[nookplot-mcp] Starting Nookplot MCP server...");
|
|
19
|
+
// 1. Load or create credentials
|
|
20
|
+
let creds = loadCredentials();
|
|
21
|
+
const gatewayUrl = getGatewayUrl(creds);
|
|
22
|
+
if (!creds) {
|
|
23
|
+
console.error("[nookplot-mcp] No credentials found — starting registration...");
|
|
24
|
+
// Use env vars or defaults for non-interactive registration
|
|
25
|
+
const name = process.env.NOOKPLOT_AGENT_NAME || "MCP Agent";
|
|
26
|
+
const description = process.env.NOOKPLOT_AGENT_DESCRIPTION || "Agent connected via @nookplot/mcp";
|
|
27
|
+
creds = await registerAgent(gatewayUrl, name, description);
|
|
28
|
+
if (!creds) {
|
|
29
|
+
console.error("[nookplot-mcp] Registration failed. Set NOOKPLOT_GATEWAY_URL if using a custom gateway.");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// 2. Validate API key
|
|
34
|
+
console.error("[nookplot-mcp] Validating API key...");
|
|
35
|
+
const meResult = await gatewayRequest(creds.gatewayUrl, "GET", "/v1/agents/me", { apiKey: creds.apiKey });
|
|
36
|
+
if (isGatewayError(meResult)) {
|
|
37
|
+
console.error(`[nookplot-mcp] API key validation failed: ${meResult.error}`);
|
|
38
|
+
console.error("[nookplot-mcp] Delete ~/.nookplot/credentials.json and restart to re-register.");
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const agent = meResult.data;
|
|
42
|
+
console.error(`[nookplot-mcp] Connected as ${agent.display_name || agent.address}`);
|
|
43
|
+
// 3. Check for pending signals
|
|
44
|
+
try {
|
|
45
|
+
const signals = await gatewayRequest(creds.gatewayUrl, "GET", "/v1/proactive/approvals", { apiKey: creds.apiKey });
|
|
46
|
+
if (!isGatewayError(signals) && signals.data.pendingCount) {
|
|
47
|
+
console.error(`[nookplot-mcp] ${signals.data.pendingCount} pending signal(s) awaiting approval`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch { /* non-critical */ }
|
|
51
|
+
// 4. Create MCP server and connect via stdio
|
|
52
|
+
const server = createServer(creds);
|
|
53
|
+
const transport = new StdioServerTransport();
|
|
54
|
+
await server.connect(transport);
|
|
55
|
+
console.error("[nookplot-mcp] Server running on stdio transport");
|
|
56
|
+
}
|
|
57
|
+
main().catch((err) => {
|
|
58
|
+
console.error("[nookplot-mcp] Fatal error:", err);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent registration flow for the Nookplot MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Replicated from cli/src/commands/register.ts — non-custodial flow:
|
|
5
|
+
* 1. Generate wallet
|
|
6
|
+
* 2. Sign registration message
|
|
7
|
+
* 3. POST /v1/agents → get API key
|
|
8
|
+
* 4. POST /v1/prepare/register → unsigned ForwardRequest
|
|
9
|
+
* 5. Sign ForwardRequest (EIP-712)
|
|
10
|
+
* 6. POST /v1/relay
|
|
11
|
+
* 7. Poll confirm-registration
|
|
12
|
+
* 8. Save credentials
|
|
13
|
+
*
|
|
14
|
+
* @module registration
|
|
15
|
+
*/
|
|
16
|
+
import { type NookplotCredentials } from "./auth.js";
|
|
17
|
+
/**
|
|
18
|
+
* Run the full registration flow.
|
|
19
|
+
* Returns credentials on success, null on failure.
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerAgent(gatewayUrl: string, name: string, description: string): Promise<NookplotCredentials | null>;
|
|
22
|
+
//# sourceMappingURL=registration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../src/registration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAuCtE;;;GAGG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAgDrC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent registration flow for the Nookplot MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Replicated from cli/src/commands/register.ts — non-custodial flow:
|
|
5
|
+
* 1. Generate wallet
|
|
6
|
+
* 2. Sign registration message
|
|
7
|
+
* 3. POST /v1/agents → get API key
|
|
8
|
+
* 4. POST /v1/prepare/register → unsigned ForwardRequest
|
|
9
|
+
* 5. Sign ForwardRequest (EIP-712)
|
|
10
|
+
* 6. POST /v1/relay
|
|
11
|
+
* 7. Poll confirm-registration
|
|
12
|
+
* 8. Save credentials
|
|
13
|
+
*
|
|
14
|
+
* @module registration
|
|
15
|
+
*/
|
|
16
|
+
import { ethers } from "ethers";
|
|
17
|
+
import { gatewayRequest, isGatewayError } from "./gateway.js";
|
|
18
|
+
import { saveCredentials } from "./auth.js";
|
|
19
|
+
/** Must match gateway/src/routes/agents.ts REGISTRATION_MESSAGE */
|
|
20
|
+
const REGISTRATION_MESSAGE = "I am registering this address with the Nookplot Agent Gateway";
|
|
21
|
+
/**
|
|
22
|
+
* Run the full registration flow.
|
|
23
|
+
* Returns credentials on success, null on failure.
|
|
24
|
+
*/
|
|
25
|
+
export async function registerAgent(gatewayUrl, name, description) {
|
|
26
|
+
// 1. Generate wallet
|
|
27
|
+
const wallet = ethers.Wallet.createRandom();
|
|
28
|
+
console.error(`[nookplot-mcp] Generated wallet: ${wallet.address}`);
|
|
29
|
+
// 2. Sign registration message
|
|
30
|
+
const signature = await wallet.signMessage(REGISTRATION_MESSAGE);
|
|
31
|
+
// 3. POST /v1/agents
|
|
32
|
+
const regResult = await gatewayRequest(gatewayUrl, "POST", "/v1/agents", {
|
|
33
|
+
body: {
|
|
34
|
+
address: wallet.address,
|
|
35
|
+
signature,
|
|
36
|
+
agentType: 2,
|
|
37
|
+
name: name.slice(0, 100),
|
|
38
|
+
description: description.slice(0, 500),
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
if (isGatewayError(regResult)) {
|
|
42
|
+
console.error(`[nookplot-mcp] Registration failed: ${regResult.error}`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const agent = regResult.data;
|
|
46
|
+
console.error(`[nookplot-mcp] Registered with gateway (address: ${agent.address})`);
|
|
47
|
+
// 4-6. Prepare + sign + relay on-chain registration
|
|
48
|
+
await prepareSignRelayRegistration(gatewayUrl, agent.apiKey, wallet);
|
|
49
|
+
// 7. Poll for on-chain confirmation
|
|
50
|
+
await waitForOnChain(gatewayUrl, agent.apiKey);
|
|
51
|
+
// 8. Save credentials
|
|
52
|
+
const creds = {
|
|
53
|
+
apiKey: agent.apiKey,
|
|
54
|
+
privateKey: wallet.privateKey,
|
|
55
|
+
address: wallet.address,
|
|
56
|
+
gatewayUrl,
|
|
57
|
+
displayName: name,
|
|
58
|
+
};
|
|
59
|
+
saveCredentials(creds);
|
|
60
|
+
console.error("[nookplot-mcp] Credentials saved to ~/.nookplot/credentials.json");
|
|
61
|
+
return creds;
|
|
62
|
+
}
|
|
63
|
+
async function prepareSignRelayRegistration(gatewayUrl, apiKey, wallet) {
|
|
64
|
+
// Prepare
|
|
65
|
+
const prepResult = await gatewayRequest(gatewayUrl, "POST", "/v1/prepare/register", { apiKey, body: { profile: { agentType: 2 } } });
|
|
66
|
+
if (isGatewayError(prepResult)) {
|
|
67
|
+
console.error(`[nookplot-mcp] Could not prepare on-chain registration: ${prepResult.error}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const { forwardRequest, domain, types, didCid } = prepResult.data;
|
|
71
|
+
// Sign EIP-712
|
|
72
|
+
let typedSignature;
|
|
73
|
+
try {
|
|
74
|
+
typedSignature = await wallet.signTypedData(domain, types, forwardRequest);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
console.error(`[nookplot-mcp] Failed to sign transaction: ${err instanceof Error ? err.message : err}`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// Relay
|
|
81
|
+
const relayResult = await gatewayRequest(gatewayUrl, "POST", "/v1/relay", { apiKey, body: { ...forwardRequest, signature: typedSignature, didCid } });
|
|
82
|
+
if (isGatewayError(relayResult)) {
|
|
83
|
+
console.error(`[nookplot-mcp] Relay failed: ${relayResult.error}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
console.error(`[nookplot-mcp] On-chain registration submitted (tx: ${relayResult.data.txHash})`);
|
|
87
|
+
}
|
|
88
|
+
async function waitForOnChain(gatewayUrl, apiKey) {
|
|
89
|
+
const maxWaitMs = 120_000;
|
|
90
|
+
const pollInterval = 5_000;
|
|
91
|
+
const start = Date.now();
|
|
92
|
+
while (Date.now() - start < maxWaitMs) {
|
|
93
|
+
await new Promise((r) => setTimeout(r, pollInterval));
|
|
94
|
+
const confirmResult = await gatewayRequest(gatewayUrl, "POST", "/v1/agents/me/confirm-registration", { apiKey });
|
|
95
|
+
if (!isGatewayError(confirmResult)) {
|
|
96
|
+
const me = confirmResult.data;
|
|
97
|
+
if (me.didCid ?? me.did_cid ?? me.registeredOnChain) {
|
|
98
|
+
console.error("[nookplot-mcp] On-chain registration confirmed");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
console.error("[nookplot-mcp] On-chain confirmation taking longer than expected");
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=registration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../src/registration.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server setup — tool/resource/prompt registration.
|
|
3
|
+
*
|
|
4
|
+
* @module server
|
|
5
|
+
*/
|
|
6
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
7
|
+
import type { NookplotCredentials } from "./auth.js";
|
|
8
|
+
/** Create and configure the Nookplot MCP server. */
|
|
9
|
+
export declare function createServer(creds: NookplotCredentials): Server;
|
|
10
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAsR/D"}
|