dero-mcp-server 0.1.1 → 0.1.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 +79 -6
- package/data/docs-index.json +5694 -0
- package/dist/docs-parse.d.ts +30 -0
- package/dist/docs-parse.d.ts.map +1 -0
- package/dist/docs-parse.js +147 -0
- package/dist/docs-parse.js.map +1 -0
- package/dist/docs.d.ts +101 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +172 -0
- package/dist/docs.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +97 -2
- package/dist/server.js.map +1 -1
- package/package.json +11 -3
- package/.github/workflows/ci.yml +0 -62
- package/docs/example-agent-flows.md +0 -236
- package/docs/mcp-agent-ready-evidence.md +0 -108
- package/glama.json +0 -6
- package/scripts/doctor.sh +0 -85
- package/scripts/flow-test.ts +0 -257
- package/scripts/mcp-smoke-probes.ts +0 -168
- package/server.json +0 -23
- package/src/index.ts +0 -30
- package/src/rpc.ts +0 -60
- package/src/server.ts +0 -636
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare const DERO_DOC_PRODUCTS: readonly ["derod", "tela", "hologram", "deropay"];
|
|
2
|
+
export type DeroDocProduct = (typeof DERO_DOC_PRODUCTS)[number];
|
|
3
|
+
export declare const DOC_SITE_DIRS: Record<DeroDocProduct, string>;
|
|
4
|
+
export declare const DOC_BASE_URLS: Record<DeroDocProduct, string>;
|
|
5
|
+
export type DeroDocsPage = {
|
|
6
|
+
product: DeroDocProduct;
|
|
7
|
+
slug: string;
|
|
8
|
+
title: string;
|
|
9
|
+
description: string | null;
|
|
10
|
+
canonicalUrl: string;
|
|
11
|
+
sourcePath: string;
|
|
12
|
+
headings: string[];
|
|
13
|
+
plainText: string;
|
|
14
|
+
lastUpdated: string | null;
|
|
15
|
+
};
|
|
16
|
+
export type DocsIndexFile = {
|
|
17
|
+
version: 1;
|
|
18
|
+
generated_at: string;
|
|
19
|
+
page_count: number;
|
|
20
|
+
pages: DeroDocsPage[];
|
|
21
|
+
};
|
|
22
|
+
export declare function normalizeSlug(input: string): string;
|
|
23
|
+
export declare function pathExists(targetPath: string): Promise<boolean>;
|
|
24
|
+
export declare function parseFrontmatter(raw: string): Record<string, string>;
|
|
25
|
+
export declare function stripFrontmatter(raw: string): string;
|
|
26
|
+
export declare function extractHeadings(markdown: string): string[];
|
|
27
|
+
export declare function mdxToPlainText(raw: string): string;
|
|
28
|
+
export declare function indexDocsFromRoot(root: string): Promise<DeroDocsPage[]>;
|
|
29
|
+
export declare function resolveDeroDocsRoot(customRoot?: string): Promise<string | null>;
|
|
30
|
+
//# sourceMappingURL=docs-parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs-parse.d.ts","sourceRoot":"","sources":["../src/docs-parse.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,mDAAoD,CAAA;AAClF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAKxD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAKxD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,CAAC,CAAA;IACV,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAYD,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWpE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ1D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWlD;AAyBD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAqC7E;AAED,wBAAsB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkBrF"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export const DERO_DOC_PRODUCTS = ['derod', 'tela', 'hologram', 'deropay'];
|
|
4
|
+
export const DOC_SITE_DIRS = {
|
|
5
|
+
derod: 'derod-main',
|
|
6
|
+
tela: 'tela-main',
|
|
7
|
+
hologram: 'hologram-main',
|
|
8
|
+
deropay: 'deropay-main',
|
|
9
|
+
};
|
|
10
|
+
export const DOC_BASE_URLS = {
|
|
11
|
+
derod: 'https://derod.org',
|
|
12
|
+
tela: 'https://tela.derod.org',
|
|
13
|
+
hologram: 'https://hologram.derod.org',
|
|
14
|
+
deropay: 'https://pay.derod.org',
|
|
15
|
+
};
|
|
16
|
+
export function normalizeSlug(input) {
|
|
17
|
+
return input.trim().replace(/^\/+/, '').replace(/\/+$/, '');
|
|
18
|
+
}
|
|
19
|
+
function safeTitleFromSlug(slug) {
|
|
20
|
+
if (!slug)
|
|
21
|
+
return 'Home';
|
|
22
|
+
return slug
|
|
23
|
+
.split('/')
|
|
24
|
+
.at(-1)
|
|
25
|
+
.split('-')
|
|
26
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
27
|
+
.join(' ');
|
|
28
|
+
}
|
|
29
|
+
export async function pathExists(targetPath) {
|
|
30
|
+
try {
|
|
31
|
+
await fs.access(targetPath);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function parseFrontmatter(raw) {
|
|
39
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
40
|
+
if (!match)
|
|
41
|
+
return {};
|
|
42
|
+
const frontmatter = {};
|
|
43
|
+
for (const line of match[1].split('\n')) {
|
|
44
|
+
const keyValue = line.match(/^([A-Za-z0-9_]+):\s*(.+)$/);
|
|
45
|
+
if (!keyValue)
|
|
46
|
+
continue;
|
|
47
|
+
frontmatter[keyValue[1]] = keyValue[2].trim().replace(/^['"]|['"]$/g, '');
|
|
48
|
+
}
|
|
49
|
+
return frontmatter;
|
|
50
|
+
}
|
|
51
|
+
export function stripFrontmatter(raw) {
|
|
52
|
+
return raw.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
53
|
+
}
|
|
54
|
+
export function extractHeadings(markdown) {
|
|
55
|
+
const headings = [];
|
|
56
|
+
const headingRegex = /^#{1,3}\s+(.+)$/gm;
|
|
57
|
+
let match = null;
|
|
58
|
+
while ((match = headingRegex.exec(markdown)) !== null) {
|
|
59
|
+
headings.push(match[1].trim());
|
|
60
|
+
}
|
|
61
|
+
return headings;
|
|
62
|
+
}
|
|
63
|
+
export function mdxToPlainText(raw) {
|
|
64
|
+
return raw
|
|
65
|
+
.replace(/```[\s\S]*?```/g, ' ')
|
|
66
|
+
.replace(/^import\s+.*$/gm, ' ')
|
|
67
|
+
.replace(/<[^>\n]+>/g, ' ')
|
|
68
|
+
.replace(/!\[([^\]]*)\]\([^)]+\)/g, '$1')
|
|
69
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
70
|
+
.replace(/^#{1,6}\s+/gm, '')
|
|
71
|
+
.replace(/`([^`]+)`/g, '$1')
|
|
72
|
+
.replace(/\s+/g, ' ')
|
|
73
|
+
.trim();
|
|
74
|
+
}
|
|
75
|
+
async function walkMdxFiles(dir) {
|
|
76
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
77
|
+
const files = [];
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
const fullPath = path.join(dir, entry.name);
|
|
80
|
+
if (entry.isDirectory()) {
|
|
81
|
+
files.push(...(await walkMdxFiles(fullPath)));
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (entry.isFile() && entry.name.endsWith('.mdx')) {
|
|
85
|
+
files.push(fullPath);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return files;
|
|
89
|
+
}
|
|
90
|
+
function buildCanonicalUrl(product, slug) {
|
|
91
|
+
if (!slug)
|
|
92
|
+
return `${DOC_BASE_URLS[product]}/`;
|
|
93
|
+
return `${DOC_BASE_URLS[product]}/${slug}`;
|
|
94
|
+
}
|
|
95
|
+
export async function indexDocsFromRoot(root) {
|
|
96
|
+
const pages = [];
|
|
97
|
+
for (const product of DERO_DOC_PRODUCTS) {
|
|
98
|
+
const siteDir = DOC_SITE_DIRS[product];
|
|
99
|
+
const pagesDir = path.join(root, siteDir, 'pages');
|
|
100
|
+
if (!(await pathExists(pagesDir)))
|
|
101
|
+
continue;
|
|
102
|
+
const files = await walkMdxFiles(pagesDir);
|
|
103
|
+
for (const filePath of files) {
|
|
104
|
+
const raw = await fs.readFile(filePath, 'utf8');
|
|
105
|
+
const frontmatter = parseFrontmatter(raw);
|
|
106
|
+
const content = stripFrontmatter(raw);
|
|
107
|
+
const rel = path.relative(pagesDir, filePath).replace(/\\/g, '/');
|
|
108
|
+
const slug = normalizeSlug(rel.replace(/\.mdx$/, '').replace(/\/index$/, '').replace(/^index$/, ''));
|
|
109
|
+
const headings = extractHeadings(content);
|
|
110
|
+
pages.push({
|
|
111
|
+
product,
|
|
112
|
+
slug,
|
|
113
|
+
title: frontmatter.title || safeTitleFromSlug(slug),
|
|
114
|
+
description: frontmatter.description || null,
|
|
115
|
+
canonicalUrl: frontmatter.canonicalUrl || buildCanonicalUrl(product, slug),
|
|
116
|
+
sourcePath: path.relative(root, filePath).replace(/\\/g, '/'),
|
|
117
|
+
headings,
|
|
118
|
+
plainText: mdxToPlainText(content),
|
|
119
|
+
lastUpdated: frontmatter.lastUpdated || frontmatter.date || null,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
pages.sort((a, b) => {
|
|
124
|
+
if (a.product !== b.product)
|
|
125
|
+
return a.product.localeCompare(b.product);
|
|
126
|
+
return a.slug.localeCompare(b.slug);
|
|
127
|
+
});
|
|
128
|
+
return pages;
|
|
129
|
+
}
|
|
130
|
+
export async function resolveDeroDocsRoot(customRoot) {
|
|
131
|
+
const explicit = customRoot ?? process.env.DERO_DOCS_ROOT;
|
|
132
|
+
if (explicit) {
|
|
133
|
+
const derodPages = path.join(explicit, DOC_SITE_DIRS.derod, 'pages');
|
|
134
|
+
return (await pathExists(derodPages)) ? explicit : null;
|
|
135
|
+
}
|
|
136
|
+
const autoCandidates = [
|
|
137
|
+
path.resolve(process.cwd(), '../dero-docs'),
|
|
138
|
+
path.resolve(process.cwd(), '../../dero-docs'),
|
|
139
|
+
];
|
|
140
|
+
for (const candidate of autoCandidates) {
|
|
141
|
+
const derodPages = path.join(candidate, DOC_SITE_DIRS.derod, 'pages');
|
|
142
|
+
if (await pathExists(derodPages))
|
|
143
|
+
return candidate;
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=docs-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs-parse.js","sourceRoot":"","sources":["../src/docs-parse.ts"],"names":[],"mappings":"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"}
|
package/dist/docs.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { type DeroDocProduct } from './docs-parse.js';
|
|
2
|
+
export { DERO_DOC_PRODUCTS, type DeroDocProduct, resolveDeroDocsRoot } from './docs-parse.js';
|
|
3
|
+
type SearchArgs = {
|
|
4
|
+
query: string;
|
|
5
|
+
product?: DeroDocProduct;
|
|
6
|
+
section?: string;
|
|
7
|
+
limit?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function listDeroDocs(product?: DeroDocProduct): Promise<{
|
|
10
|
+
total: number;
|
|
11
|
+
products: readonly ["derod", "tela", "hologram", "deropay"];
|
|
12
|
+
pages: {
|
|
13
|
+
product: "derod" | "tela" | "hologram" | "deropay";
|
|
14
|
+
slug: string;
|
|
15
|
+
title: string;
|
|
16
|
+
canonical_url: string;
|
|
17
|
+
last_updated: string | null;
|
|
18
|
+
}[];
|
|
19
|
+
docs_source: "bundled";
|
|
20
|
+
bundled_index: string;
|
|
21
|
+
docs_root?: undefined;
|
|
22
|
+
} | {
|
|
23
|
+
total: number;
|
|
24
|
+
products: readonly ["derod", "tela", "hologram", "deropay"];
|
|
25
|
+
pages: {
|
|
26
|
+
product: "derod" | "tela" | "hologram" | "deropay";
|
|
27
|
+
slug: string;
|
|
28
|
+
title: string;
|
|
29
|
+
canonical_url: string;
|
|
30
|
+
last_updated: string | null;
|
|
31
|
+
}[];
|
|
32
|
+
docs_source: "filesystem";
|
|
33
|
+
docs_root: string;
|
|
34
|
+
bundled_index?: undefined;
|
|
35
|
+
}>;
|
|
36
|
+
export declare function searchDeroDocs(args: SearchArgs): Promise<{
|
|
37
|
+
query: string;
|
|
38
|
+
total_matches: number;
|
|
39
|
+
returned: number;
|
|
40
|
+
results: {
|
|
41
|
+
product: "derod" | "tela" | "hologram" | "deropay";
|
|
42
|
+
slug: string;
|
|
43
|
+
title: string;
|
|
44
|
+
description: string | null;
|
|
45
|
+
canonical_url: string;
|
|
46
|
+
headings: string[];
|
|
47
|
+
excerpt: string;
|
|
48
|
+
score: number;
|
|
49
|
+
}[];
|
|
50
|
+
docs_source: "bundled";
|
|
51
|
+
bundled_index: string;
|
|
52
|
+
docs_root?: undefined;
|
|
53
|
+
} | {
|
|
54
|
+
query: string;
|
|
55
|
+
total_matches: number;
|
|
56
|
+
returned: number;
|
|
57
|
+
results: {
|
|
58
|
+
product: "derod" | "tela" | "hologram" | "deropay";
|
|
59
|
+
slug: string;
|
|
60
|
+
title: string;
|
|
61
|
+
description: string | null;
|
|
62
|
+
canonical_url: string;
|
|
63
|
+
headings: string[];
|
|
64
|
+
excerpt: string;
|
|
65
|
+
score: number;
|
|
66
|
+
}[];
|
|
67
|
+
docs_source: "filesystem";
|
|
68
|
+
docs_root: string;
|
|
69
|
+
bundled_index?: undefined;
|
|
70
|
+
}>;
|
|
71
|
+
export declare function getDeroDocPage(params: {
|
|
72
|
+
product?: DeroDocProduct;
|
|
73
|
+
slug: string;
|
|
74
|
+
}): Promise<{
|
|
75
|
+
product: "derod" | "tela" | "hologram" | "deropay";
|
|
76
|
+
slug: string;
|
|
77
|
+
title: string;
|
|
78
|
+
description: string | null;
|
|
79
|
+
canonical_url: string;
|
|
80
|
+
last_updated: string | null;
|
|
81
|
+
headings: string[];
|
|
82
|
+
content: string;
|
|
83
|
+
source_path: string;
|
|
84
|
+
docs_source: "bundled";
|
|
85
|
+
bundled_index: string;
|
|
86
|
+
docs_root?: undefined;
|
|
87
|
+
} | {
|
|
88
|
+
product: "derod" | "tela" | "hologram" | "deropay";
|
|
89
|
+
slug: string;
|
|
90
|
+
title: string;
|
|
91
|
+
description: string | null;
|
|
92
|
+
canonical_url: string;
|
|
93
|
+
last_updated: string | null;
|
|
94
|
+
headings: string[];
|
|
95
|
+
content: string;
|
|
96
|
+
source_path: string;
|
|
97
|
+
docs_source: "filesystem";
|
|
98
|
+
docs_root: string;
|
|
99
|
+
bundled_index?: undefined;
|
|
100
|
+
}>;
|
|
101
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EAOpB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EAAE,iBAAiB,EAAE,KAAK,cAAc,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAkF7F,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAmBD,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;GAgB1D;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CpD;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BtF"}
|
package/dist/docs.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { DERO_DOC_PRODUCTS, indexDocsFromRoot, normalizeSlug, pathExists, } from './docs-parse.js';
|
|
5
|
+
export { DERO_DOC_PRODUCTS, resolveDeroDocsRoot } from './docs-parse.js';
|
|
6
|
+
const CACHE_TTL_MS = 15000;
|
|
7
|
+
let pageCache = null;
|
|
8
|
+
function bundledIndexPath() {
|
|
9
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
// dist/docs.js -> ../data/docs-index.json
|
|
11
|
+
return path.resolve(here, '../data/docs-index.json');
|
|
12
|
+
}
|
|
13
|
+
async function loadBundledPages(indexPath) {
|
|
14
|
+
if (!(await pathExists(indexPath)))
|
|
15
|
+
return null;
|
|
16
|
+
const raw = await fs.readFile(indexPath, 'utf8');
|
|
17
|
+
const parsed = JSON.parse(raw);
|
|
18
|
+
if (!parsed?.pages?.length)
|
|
19
|
+
return null;
|
|
20
|
+
return parsed.pages;
|
|
21
|
+
}
|
|
22
|
+
async function resolveDocsSource() {
|
|
23
|
+
const overrideRoot = process.env.DERO_DOCS_ROOT?.trim();
|
|
24
|
+
if (overrideRoot) {
|
|
25
|
+
const derodPages = path.join(overrideRoot, 'derod-main', 'pages');
|
|
26
|
+
if (await pathExists(derodPages)) {
|
|
27
|
+
return { kind: 'filesystem', root: overrideRoot };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const bundledPath = bundledIndexPath();
|
|
31
|
+
if (await pathExists(bundledPath)) {
|
|
32
|
+
return { kind: 'bundled', indexPath: bundledPath };
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
async function loadPages() {
|
|
37
|
+
const source = await resolveDocsSource();
|
|
38
|
+
if (!source) {
|
|
39
|
+
throw new Error('DERO docs unavailable. Bundled docs index missing and DERO_DOCS_ROOT is unset or invalid.');
|
|
40
|
+
}
|
|
41
|
+
const cacheKey = source.kind === 'bundled' ? `bundled:${source.indexPath}` : `fs:${source.root}`;
|
|
42
|
+
if (pageCache && pageCache.key === cacheKey && Date.now() - pageCache.loadedAt < CACHE_TTL_MS) {
|
|
43
|
+
return pageCache.data;
|
|
44
|
+
}
|
|
45
|
+
let pages;
|
|
46
|
+
if (source.kind === 'bundled') {
|
|
47
|
+
const bundled = await loadBundledPages(source.indexPath);
|
|
48
|
+
if (!bundled) {
|
|
49
|
+
throw new Error('DERO bundled docs index is missing or empty.');
|
|
50
|
+
}
|
|
51
|
+
pages = bundled;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
pages = await indexDocsFromRoot(source.root);
|
|
55
|
+
}
|
|
56
|
+
const data = { source, pages };
|
|
57
|
+
pageCache = { key: cacheKey, loadedAt: Date.now(), data };
|
|
58
|
+
return data;
|
|
59
|
+
}
|
|
60
|
+
function sourceMeta(source) {
|
|
61
|
+
if (source.kind === 'bundled') {
|
|
62
|
+
return { docs_source: 'bundled', bundled_index: path.basename(source.indexPath) };
|
|
63
|
+
}
|
|
64
|
+
return { docs_source: 'filesystem', docs_root: source.root };
|
|
65
|
+
}
|
|
66
|
+
function scorePage(page, terms) {
|
|
67
|
+
const title = page.title.toLowerCase();
|
|
68
|
+
const slug = page.slug.toLowerCase();
|
|
69
|
+
const headingBlob = page.headings.join(' ').toLowerCase();
|
|
70
|
+
const body = page.plainText.toLowerCase();
|
|
71
|
+
let score = 0;
|
|
72
|
+
for (const term of terms) {
|
|
73
|
+
if (title.includes(term))
|
|
74
|
+
score += 6;
|
|
75
|
+
if (slug.includes(term))
|
|
76
|
+
score += 4;
|
|
77
|
+
if (headingBlob.includes(term))
|
|
78
|
+
score += 2;
|
|
79
|
+
if (body.includes(term))
|
|
80
|
+
score += 1;
|
|
81
|
+
}
|
|
82
|
+
return score;
|
|
83
|
+
}
|
|
84
|
+
export async function listDeroDocs(product) {
|
|
85
|
+
const { source, pages } = await loadPages();
|
|
86
|
+
const filtered = product ? pages.filter((page) => page.product === product) : pages;
|
|
87
|
+
return {
|
|
88
|
+
...sourceMeta(source),
|
|
89
|
+
total: filtered.length,
|
|
90
|
+
products: DERO_DOC_PRODUCTS,
|
|
91
|
+
pages: filtered.map((page) => ({
|
|
92
|
+
product: page.product,
|
|
93
|
+
slug: page.slug,
|
|
94
|
+
title: page.title,
|
|
95
|
+
canonical_url: page.canonicalUrl,
|
|
96
|
+
last_updated: page.lastUpdated,
|
|
97
|
+
})),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export async function searchDeroDocs(args) {
|
|
101
|
+
const query = args.query.trim();
|
|
102
|
+
if (!query)
|
|
103
|
+
throw new Error('DERO docs search requires a non-empty query');
|
|
104
|
+
const { source, pages } = await loadPages();
|
|
105
|
+
let filtered = pages;
|
|
106
|
+
if (args.product) {
|
|
107
|
+
filtered = filtered.filter((page) => page.product === args.product);
|
|
108
|
+
}
|
|
109
|
+
if (args.section) {
|
|
110
|
+
const normalizedSection = normalizeSlug(args.section).toLowerCase();
|
|
111
|
+
filtered = filtered.filter((page) => {
|
|
112
|
+
const slug = page.slug.toLowerCase();
|
|
113
|
+
return slug === normalizedSection || slug.startsWith(`${normalizedSection}/`);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const terms = query
|
|
117
|
+
.toLowerCase()
|
|
118
|
+
.split(/\s+/)
|
|
119
|
+
.map((term) => term.trim())
|
|
120
|
+
.filter(Boolean);
|
|
121
|
+
const scored = filtered
|
|
122
|
+
.map((page) => ({ page, score: scorePage(page, terms) }))
|
|
123
|
+
.filter((entry) => entry.score > 0)
|
|
124
|
+
.sort((a, b) => b.score - a.score);
|
|
125
|
+
const limit = Math.max(1, Math.min(args.limit ?? 8, 25));
|
|
126
|
+
const results = scored.slice(0, limit).map(({ page, score }) => ({
|
|
127
|
+
product: page.product,
|
|
128
|
+
slug: page.slug,
|
|
129
|
+
title: page.title,
|
|
130
|
+
description: page.description,
|
|
131
|
+
canonical_url: page.canonicalUrl,
|
|
132
|
+
headings: page.headings.slice(0, 5),
|
|
133
|
+
excerpt: page.plainText.slice(0, 420),
|
|
134
|
+
score,
|
|
135
|
+
}));
|
|
136
|
+
return {
|
|
137
|
+
...sourceMeta(source),
|
|
138
|
+
query,
|
|
139
|
+
total_matches: scored.length,
|
|
140
|
+
returned: results.length,
|
|
141
|
+
results,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export async function getDeroDocPage(params) {
|
|
145
|
+
const slug = normalizeSlug(params.slug);
|
|
146
|
+
if (!slug)
|
|
147
|
+
throw new Error('DERO docs get page requires a non-empty slug');
|
|
148
|
+
const { source, pages } = await loadPages();
|
|
149
|
+
const target = pages.find((page) => {
|
|
150
|
+
if (params.product && page.product !== params.product)
|
|
151
|
+
return false;
|
|
152
|
+
return normalizeSlug(page.slug).toLowerCase() === slug.toLowerCase();
|
|
153
|
+
});
|
|
154
|
+
if (!target) {
|
|
155
|
+
throw new Error(params.product
|
|
156
|
+
? `Doc page not found for product=${params.product} slug=${slug}`
|
|
157
|
+
: `Doc page not found for slug=${slug}`);
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
...sourceMeta(source),
|
|
161
|
+
product: target.product,
|
|
162
|
+
slug: target.slug,
|
|
163
|
+
title: target.title,
|
|
164
|
+
description: target.description,
|
|
165
|
+
canonical_url: target.canonicalUrl,
|
|
166
|
+
last_updated: target.lastUpdated,
|
|
167
|
+
headings: target.headings,
|
|
168
|
+
content: target.plainText.slice(0, 20000),
|
|
169
|
+
source_path: target.sourcePath,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=docs.js.map
|
package/dist/docs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAmNnE,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAwiBpE"}
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { deroJsonRpc, jsonRpcEndpoint } from './rpc.js';
|
|
4
|
+
import { DERO_DOC_PRODUCTS, getDeroDocPage, listDeroDocs, searchDeroDocs, } from './docs.js';
|
|
4
5
|
const scRpcArgSchema = z.object({
|
|
5
6
|
name: z.string(),
|
|
6
7
|
datatype: z.enum(['S', 'U', 'H']),
|
|
@@ -31,6 +32,9 @@ const DERO_TOOL_NAMES = [
|
|
|
31
32
|
'dero_get_gas_estimate',
|
|
32
33
|
'dero_name_to_address',
|
|
33
34
|
'dero_get_block_template',
|
|
35
|
+
'dero_docs_search',
|
|
36
|
+
'dero_docs_get_page',
|
|
37
|
+
'dero_docs_list',
|
|
34
38
|
];
|
|
35
39
|
const DERO_RESOURCE_URIS = [
|
|
36
40
|
'dero://mcp/server-info',
|
|
@@ -42,6 +46,7 @@ const DERO_PROMPT_NAMES = [
|
|
|
42
46
|
'inspect_smart_contract',
|
|
43
47
|
'trace_transaction',
|
|
44
48
|
];
|
|
49
|
+
const deroDocProductSchema = z.enum(DERO_DOC_PRODUCTS);
|
|
45
50
|
function toolText(data) {
|
|
46
51
|
return {
|
|
47
52
|
content: [
|
|
@@ -61,6 +66,35 @@ function classifyToolError(error) {
|
|
|
61
66
|
retryable: false,
|
|
62
67
|
};
|
|
63
68
|
}
|
|
69
|
+
if (message.includes('DERO docs unavailable') ||
|
|
70
|
+
message.includes('bundled docs index is missing')) {
|
|
71
|
+
return {
|
|
72
|
+
code: 'DOCS_UNAVAILABLE',
|
|
73
|
+
hint: 'Bundled docs index is missing from this install. Reinstall dero-mcp-server or set DERO_DOCS_ROOT for local dev override.',
|
|
74
|
+
retryable: false,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (message.includes('DERO docs search requires a non-empty query')) {
|
|
78
|
+
return {
|
|
79
|
+
code: 'INVALID_INPUT',
|
|
80
|
+
hint: 'Pass a non-empty "query" string for dero_docs_search.',
|
|
81
|
+
retryable: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (message.includes('DERO docs get page requires a non-empty slug')) {
|
|
85
|
+
return {
|
|
86
|
+
code: 'INVALID_INPUT',
|
|
87
|
+
hint: 'Pass a non-empty "slug" for dero_docs_get_page.',
|
|
88
|
+
retryable: false,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (message.includes('Doc page not found')) {
|
|
92
|
+
return {
|
|
93
|
+
code: 'DOC_NOT_FOUND',
|
|
94
|
+
hint: 'Use dero_docs_search or dero_docs_list to discover valid slugs, then retry.',
|
|
95
|
+
retryable: false,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
64
98
|
if (message.includes('RPC error -32601')) {
|
|
65
99
|
return {
|
|
66
100
|
code: 'RPC_METHOD_NOT_FOUND',
|
|
@@ -138,7 +172,7 @@ export function createDeroMcpServer(daemonBaseUrl) {
|
|
|
138
172
|
const rpc = async (method, params) => deroJsonRpc(endpoint, method, params);
|
|
139
173
|
const server = new McpServer({
|
|
140
174
|
name: 'dero-daemon-mcp',
|
|
141
|
-
version: '0.1.
|
|
175
|
+
version: '0.1.2',
|
|
142
176
|
});
|
|
143
177
|
server.registerTool('dero_daemon_ping', {
|
|
144
178
|
description: 'DERO daemon connectivity check. Calls DERO.Ping. No parameters.',
|
|
@@ -332,6 +366,64 @@ export function createDeroMcpServer(daemonBaseUrl) {
|
|
|
332
366
|
params.miner = miner;
|
|
333
367
|
return rpc('DERO.GetBlockTemplate', params);
|
|
334
368
|
}));
|
|
369
|
+
server.registerTool('dero_docs_search', {
|
|
370
|
+
description: 'Search bundled DERO documentation (derod/tela/hologram/deropay). Ships with npm package; optional DERO_DOCS_ROOT overrides for local dev.',
|
|
371
|
+
inputSchema: {
|
|
372
|
+
query: z
|
|
373
|
+
.string()
|
|
374
|
+
.min(1)
|
|
375
|
+
.describe('Search text (e.g., "wallet rpc", "tela deployment", "deropay webhooks")'),
|
|
376
|
+
product: deroDocProductSchema
|
|
377
|
+
.optional()
|
|
378
|
+
.describe('Optional docs product filter: derod | tela | hologram | deropay'),
|
|
379
|
+
section: z
|
|
380
|
+
.string()
|
|
381
|
+
.optional()
|
|
382
|
+
.describe('Optional section slug prefix (e.g., "rpc-api", "guides", "dero-pay")'),
|
|
383
|
+
limit: z
|
|
384
|
+
.number()
|
|
385
|
+
.int()
|
|
386
|
+
.min(1)
|
|
387
|
+
.max(25)
|
|
388
|
+
.optional()
|
|
389
|
+
.describe('Max matches (default 8, max 25)'),
|
|
390
|
+
},
|
|
391
|
+
}, withStructuredErrors('dero_docs_search', async ({ query, product, section, limit }) => searchDeroDocs({ query, product, section, limit })));
|
|
392
|
+
server.registerTool('dero_docs_get_page', {
|
|
393
|
+
description: 'Get one docs page by slug (optionally scoped by product). Returns headings and normalized plain-text content.',
|
|
394
|
+
inputSchema: {
|
|
395
|
+
slug: z
|
|
396
|
+
.string()
|
|
397
|
+
.min(1)
|
|
398
|
+
.describe('Doc slug relative to pages/ (e.g., "rpc-api/daemon-rpc-api", "tutorials/first-app", "dero-pay/quick-start")'),
|
|
399
|
+
product: deroDocProductSchema
|
|
400
|
+
.optional()
|
|
401
|
+
.describe('Optional product scope to disambiguate duplicate slugs'),
|
|
402
|
+
},
|
|
403
|
+
}, withStructuredErrors('dero_docs_get_page', async ({ slug, product }) => getDeroDocPage({ slug, product })));
|
|
404
|
+
server.registerTool('dero_docs_list', {
|
|
405
|
+
description: 'List indexed docs pages across derod/tela/hologram/deropay with slugs and canonical URLs.',
|
|
406
|
+
inputSchema: {
|
|
407
|
+
product: deroDocProductSchema
|
|
408
|
+
.optional()
|
|
409
|
+
.describe('Optional docs product filter: derod | tela | hologram | deropay'),
|
|
410
|
+
limit: z
|
|
411
|
+
.number()
|
|
412
|
+
.int()
|
|
413
|
+
.min(1)
|
|
414
|
+
.max(500)
|
|
415
|
+
.optional()
|
|
416
|
+
.describe('Max pages returned (default 120, max 500)'),
|
|
417
|
+
},
|
|
418
|
+
}, withStructuredErrors('dero_docs_list', async ({ product, limit }) => {
|
|
419
|
+
const docsIndex = await listDeroDocs(product);
|
|
420
|
+
const capped = Math.max(1, Math.min(limit ?? 120, 500));
|
|
421
|
+
return {
|
|
422
|
+
...docsIndex,
|
|
423
|
+
returned: Math.min(capped, docsIndex.pages.length),
|
|
424
|
+
pages: docsIndex.pages.slice(0, capped),
|
|
425
|
+
};
|
|
426
|
+
}));
|
|
335
427
|
server.registerResource('dero_mcp_server_info', 'dero://mcp/server-info', {
|
|
336
428
|
description: 'Server metadata, tool list, resource list, and prompt names.',
|
|
337
429
|
mimeType: 'application/json',
|
|
@@ -342,9 +434,12 @@ export function createDeroMcpServer(daemonBaseUrl) {
|
|
|
342
434
|
mimeType: 'application/json',
|
|
343
435
|
text: JSON.stringify({
|
|
344
436
|
name: 'dero-daemon-mcp',
|
|
345
|
-
version: '0.1.
|
|
437
|
+
version: '0.1.2',
|
|
346
438
|
mode: 'read-only',
|
|
347
439
|
endpoint: endpoint,
|
|
440
|
+
docs_products: DERO_DOC_PRODUCTS,
|
|
441
|
+
docs_delivery: 'bundled-index',
|
|
442
|
+
docs_dev_override_env: 'DERO_DOCS_ROOT',
|
|
348
443
|
tools: DERO_TOOL_NAMES,
|
|
349
444
|
resources: DERO_RESOURCE_URIS,
|
|
350
445
|
prompts: DERO_PROMPT_NAMES,
|