subgraph-registry-mcp 0.4.2 → 0.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/data/registry.db +0 -0
- package/package.json +1 -1
- package/src/index.js +54 -3
package/data/registry.db
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subgraph-registry-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"mcpName": "io.github.PaulieB14/subgraph-registry-mcp",
|
|
5
5
|
"description": "MCP server for agent-friendly subgraph discovery on The Graph Network. 14,733 classified subgraphs with query hints with domain, protocol type, and reliability scoring.",
|
|
6
6
|
"type": "module",
|
package/src/index.js
CHANGED
|
@@ -24,8 +24,9 @@ import Database from "better-sqlite3";
|
|
|
24
24
|
import express from "express";
|
|
25
25
|
import { fileURLToPath } from "url";
|
|
26
26
|
import { dirname, join } from "path";
|
|
27
|
-
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
27
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
28
28
|
import { get as httpsGet } from "https";
|
|
29
|
+
import { createHash } from "crypto";
|
|
29
30
|
|
|
30
31
|
const __filename = fileURLToPath(import.meta.url);
|
|
31
32
|
const __dirname = dirname(__filename);
|
|
@@ -34,8 +35,53 @@ const DB_PATH = join(DATA_DIR, "registry.db");
|
|
|
34
35
|
const GITHUB_DB_URL =
|
|
35
36
|
"https://github.com/PaulieB14/subgraph-registry/raw/main/python/data/registry.db";
|
|
36
37
|
|
|
38
|
+
// SHA-256 of the registry.db shipped with this npm version. Any download or
|
|
39
|
+
// pre-bundled copy that doesn't match this hash is rejected — protects users
|
|
40
|
+
// against a compromised GitHub repo or man-in-the-middle on the download.
|
|
41
|
+
//
|
|
42
|
+
// HOW TO UPDATE WHEN REBUILDING THE REGISTRY:
|
|
43
|
+
// 1. Run the crawler to rebuild python/data/registry.db
|
|
44
|
+
// 2. shasum -a 256 python/data/registry.db
|
|
45
|
+
// 3. Paste the new hash here and bump package.json version
|
|
46
|
+
// 4. Update SKILL.md "Verifying the registry" section
|
|
47
|
+
const EXPECTED_DB_SHA256 =
|
|
48
|
+
"f81b79c53cc13c3428472024187fc7fd502f7418f5da20f0a6e01807dd4011c6";
|
|
49
|
+
// Skip-verification escape hatch (set to "1" only if you're rebuilding the DB
|
|
50
|
+
// locally and know what you're doing — never set in agent-runtime defaults).
|
|
51
|
+
const SKIP_VERIFY = process.env.SUBGRAPH_REGISTRY_SKIP_VERIFY === "1";
|
|
52
|
+
|
|
37
53
|
// ── Download DB from GitHub if missing ─────────────────────
|
|
38
54
|
|
|
55
|
+
function sha256OfFile(path) {
|
|
56
|
+
const h = createHash("sha256");
|
|
57
|
+
h.update(readFileSync(path));
|
|
58
|
+
return h.digest("hex");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function verifyDbOrThrow(path) {
|
|
62
|
+
if (SKIP_VERIFY) {
|
|
63
|
+
console.error(
|
|
64
|
+
"SUBGRAPH_REGISTRY_SKIP_VERIFY=1 — skipping registry.db hash check."
|
|
65
|
+
);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const actual = sha256OfFile(path);
|
|
69
|
+
if (actual !== EXPECTED_DB_SHA256) {
|
|
70
|
+
// Refuse to load a registry that doesn't match the known-good hash.
|
|
71
|
+
// Delete the file so the next run gets a fresh download attempt instead
|
|
72
|
+
// of caching a poisoned copy.
|
|
73
|
+
try { unlinkSync(path); } catch (_) {}
|
|
74
|
+
throw new Error(
|
|
75
|
+
`registry.db SHA-256 mismatch.\n` +
|
|
76
|
+
` expected: ${EXPECTED_DB_SHA256}\n` +
|
|
77
|
+
` actual: ${actual}\n` +
|
|
78
|
+
`The downloaded registry does not match the version pinned to this ` +
|
|
79
|
+
`npm package. Refusing to load. If you intentionally rebuilt the DB ` +
|
|
80
|
+
`locally, set SUBGRAPH_REGISTRY_SKIP_VERIFY=1 to bypass.`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
39
85
|
function downloadFile(url, dest) {
|
|
40
86
|
return new Promise((resolve, reject) => {
|
|
41
87
|
const follow = (u) => {
|
|
@@ -62,11 +108,16 @@ function downloadFile(url, dest) {
|
|
|
62
108
|
}
|
|
63
109
|
|
|
64
110
|
async function ensureDb() {
|
|
65
|
-
if (existsSync(DB_PATH))
|
|
111
|
+
if (existsSync(DB_PATH)) {
|
|
112
|
+
verifyDbOrThrow(DB_PATH);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
66
115
|
mkdirSync(DATA_DIR, { recursive: true });
|
|
67
116
|
console.error("Registry not found locally. Downloading from GitHub...");
|
|
68
117
|
await downloadFile(GITHUB_DB_URL, DB_PATH);
|
|
69
|
-
console.error("Downloaded registry.db");
|
|
118
|
+
console.error("Downloaded registry.db — verifying SHA-256...");
|
|
119
|
+
verifyDbOrThrow(DB_PATH);
|
|
120
|
+
console.error("Registry verified OK.");
|
|
70
121
|
}
|
|
71
122
|
|
|
72
123
|
// ── Database ───────────────────────────────────────────────
|