@vielzeug/codex 1.0.4 → 2.0.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 +46 -107
- package/data/catalog.json +1679 -0
- package/data/llms-full.txt +18826 -31876
- package/data/llms.txt +32 -114
- package/data/manifest.json +8 -0
- package/data/packages/arsenal.json +210 -0
- package/data/packages/assay.json +40 -0
- package/data/packages/clockwork.json +67 -0
- package/data/packages/codex.json +43 -0
- package/data/packages/coins.json +103 -0
- package/data/packages/conduit.json +60 -0
- package/data/packages/courier.json +58 -0
- package/data/packages/dnd.json +75 -0
- package/data/packages/familiar.json +30 -0
- package/data/packages/flux.json +93 -0
- package/data/packages/forge.json +84 -0
- package/data/packages/herald.json +122 -0
- package/data/packages/keymap.json +65 -0
- package/data/packages/ledger.json +54 -0
- package/data/packages/lingua.json +66 -0
- package/data/packages/orbit.json +112 -0
- package/data/packages/ore.json +73 -0
- package/data/packages/prism.json +70 -0
- package/data/packages/pulse.json +58 -0
- package/data/packages/refine.json +12 -0
- package/data/packages/ripple.json +79 -0
- package/data/packages/rune.json +81 -0
- package/data/packages/sandbox.json +39 -0
- package/data/packages/scout.json +60 -0
- package/data/packages/scroll.json +113 -0
- package/data/packages/sourcerer.json +74 -0
- package/data/packages/spell.json +134 -0
- package/data/packages/tempo.json +113 -0
- package/data/packages/vault.json +90 -0
- package/data/packages/ward.json +125 -0
- package/data/packages/wayfinder.json +113 -0
- package/data/refine.json +11752 -0
- package/data/search.json +1437 -0
- package/dist/catalog.js +149 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cli.js +33 -59
- package/dist/cli.js.map +1 -1
- package/dist/errors.js +0 -14
- package/dist/errors.js.map +1 -1
- package/dist/http.js +54 -96
- package/dist/http.js.map +1 -1
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/server.js +4 -9
- package/dist/server.js.map +1 -1
- package/dist/snapshot.js +233 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/tools/index.js +21 -42
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/packages.js +67 -166
- package/dist/tools/packages.js.map +1 -1
- package/dist/tools/refine.js +99 -305
- package/dist/tools/refine.js.map +1 -1
- package/dist/tools/schema.js +8 -8
- package/dist/tools/schema.js.map +1 -1
- package/dist/tools/shared.js +1 -26
- package/dist/tools/shared.js.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/mcp-setup.json +10 -0
- package/package.json +7 -7
- package/data/.cache.json +0 -34
- package/data/vielzeug-data.json +0 -16118
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { CodexError } from './errors.js';
|
|
4
|
+
import { parseContent } from './snapshot.js';
|
|
5
|
+
export class CatalogError extends CodexError {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function matches(haystack, terms) {
|
|
13
|
+
return terms.every((term) => haystack.includes(term));
|
|
14
|
+
}
|
|
15
|
+
function searchRecord(record, query) {
|
|
16
|
+
const terms = query.toLowerCase().replaceAll('-', ' ').split(/\s+/).filter(Boolean);
|
|
17
|
+
if (terms.length === 0)
|
|
18
|
+
throw new CatalogError('INVALID_ARG', 'query: required non-empty string.');
|
|
19
|
+
const matched = new Set();
|
|
20
|
+
const pages = [];
|
|
21
|
+
const examples = [];
|
|
22
|
+
if (matches(record.name.toLowerCase(), terms) ||
|
|
23
|
+
matches(record.category, terms) ||
|
|
24
|
+
matches(record.description, terms))
|
|
25
|
+
matched.add('metadata');
|
|
26
|
+
for (const field of ['keywords', 'exports', 'related', 'source']) {
|
|
27
|
+
if (record[field] && matches(record[field] ?? '', terms))
|
|
28
|
+
matched.add(field);
|
|
29
|
+
}
|
|
30
|
+
for (const [page, content] of Object.entries(record.docs)) {
|
|
31
|
+
if (matches(content, terms)) {
|
|
32
|
+
matched.add('docs');
|
|
33
|
+
pages.push(page);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const example of record.examples) {
|
|
37
|
+
if (matches(example.text, terms)) {
|
|
38
|
+
matched.add('examples');
|
|
39
|
+
examples.push(example.id);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (matched.size === 0)
|
|
43
|
+
return null;
|
|
44
|
+
const normalizedQuery = terms.join(' ');
|
|
45
|
+
const normalizedName = record.name.toLowerCase().replaceAll('-', ' ');
|
|
46
|
+
const normalizedSlug = record.slug.replaceAll('-', ' ');
|
|
47
|
+
const tier = normalizedSlug === normalizedQuery || normalizedName === normalizedQuery
|
|
48
|
+
? 0
|
|
49
|
+
: normalizedSlug.startsWith(normalizedQuery) || normalizedName.startsWith(normalizedQuery)
|
|
50
|
+
? 1
|
|
51
|
+
: matched.has('metadata') || matched.has('keywords') || matched.has('exports') || matched.has('related')
|
|
52
|
+
? 2
|
|
53
|
+
: 3;
|
|
54
|
+
return {
|
|
55
|
+
hit: {
|
|
56
|
+
...(examples.length > 0 && { matchedExamples: examples }),
|
|
57
|
+
matchedIn: [...matched].sort(),
|
|
58
|
+
...(pages.length > 0 && { matchedPages: pages }),
|
|
59
|
+
name: record.name,
|
|
60
|
+
slug: record.slug,
|
|
61
|
+
},
|
|
62
|
+
tier,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export class SnapshotCatalog {
|
|
66
|
+
bySlug;
|
|
67
|
+
componentsByTag;
|
|
68
|
+
contentCache = new Map();
|
|
69
|
+
snapshot;
|
|
70
|
+
constructor(snapshot) {
|
|
71
|
+
this.snapshot = snapshot;
|
|
72
|
+
this.bySlug = new Map(snapshot.catalog.packages.map((pkg) => [pkg.slug, pkg]));
|
|
73
|
+
this.componentsByTag = new Map(snapshot.refineComponents.flatMap((component) => component.tagName ? [[component.tagName, component]] : []));
|
|
74
|
+
}
|
|
75
|
+
getPackage(slug) {
|
|
76
|
+
const pkg = this.bySlug.get(slug);
|
|
77
|
+
if (!pkg)
|
|
78
|
+
throw new CatalogError('NOT_FOUND', `Package "${slug}" not found. Available slugs: ${[...this.bySlug.keys()].join(', ')}`);
|
|
79
|
+
return pkg;
|
|
80
|
+
}
|
|
81
|
+
getContent(slug) {
|
|
82
|
+
this.getPackage(slug);
|
|
83
|
+
const cached = this.contentCache.get(slug);
|
|
84
|
+
if (cached)
|
|
85
|
+
return cached;
|
|
86
|
+
const path = resolve(this.snapshot.contentDirectory, `${slug}.json`);
|
|
87
|
+
let content;
|
|
88
|
+
try {
|
|
89
|
+
content = parseContent(JSON.parse(readFileSync(path, 'utf8')), slug);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (error instanceof CodexError)
|
|
93
|
+
throw error;
|
|
94
|
+
throw new CodexError(`Failed to read snapshot content for ${slug}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
95
|
+
}
|
|
96
|
+
this.contentCache.set(slug, content);
|
|
97
|
+
return content;
|
|
98
|
+
}
|
|
99
|
+
listPackages() {
|
|
100
|
+
return [...this.bySlug.values()];
|
|
101
|
+
}
|
|
102
|
+
getDocs(slug, page) {
|
|
103
|
+
const content = this.getContent(slug).docs[page];
|
|
104
|
+
if (!content)
|
|
105
|
+
throw new CatalogError('NOT_FOUND', `No "${page}" page for "${slug}". Available: ${this.getPackage(slug).availableDocPages.join(', ') || 'none'}.`);
|
|
106
|
+
return content;
|
|
107
|
+
}
|
|
108
|
+
getSource(slug) {
|
|
109
|
+
const source = this.getContent(slug).apiSource;
|
|
110
|
+
if (!source)
|
|
111
|
+
throw new CatalogError('UNAVAILABLE', `Package "${slug}" has no bundled source.`);
|
|
112
|
+
return source;
|
|
113
|
+
}
|
|
114
|
+
listExamples(slug) {
|
|
115
|
+
return this.getContent(slug).examples.map(({ id, name }) => ({ id, name }));
|
|
116
|
+
}
|
|
117
|
+
getExample(slug, exampleId) {
|
|
118
|
+
const example = this.getContent(slug).examples.find((item) => item.id === exampleId);
|
|
119
|
+
if (!example)
|
|
120
|
+
throw new CatalogError('NOT_FOUND', `No example "${exampleId}" for "${slug}".`);
|
|
121
|
+
return example;
|
|
122
|
+
}
|
|
123
|
+
getTypeSignature(slug, symbol) {
|
|
124
|
+
const signature = this.getContent(slug).typeSignatures[symbol];
|
|
125
|
+
if (!signature)
|
|
126
|
+
throw new CatalogError('NOT_FOUND', `No exported symbol "${symbol}" for "${slug}".`);
|
|
127
|
+
return signature;
|
|
128
|
+
}
|
|
129
|
+
search(query) {
|
|
130
|
+
return this.snapshot.search
|
|
131
|
+
.map((record) => searchRecord(record, query))
|
|
132
|
+
.filter((result) => result !== null)
|
|
133
|
+
.sort((left, right) => left.tier - right.tier || left.hit.slug.localeCompare(right.hit.slug))
|
|
134
|
+
.map((result) => result.hit);
|
|
135
|
+
}
|
|
136
|
+
listComponents() {
|
|
137
|
+
if (this.snapshot.refineComponents.length === 0)
|
|
138
|
+
throw new CatalogError('UNAVAILABLE', 'Refine component metadata is unavailable in this snapshot.');
|
|
139
|
+
return this.snapshot.refineComponents;
|
|
140
|
+
}
|
|
141
|
+
getComponent(tagName) {
|
|
142
|
+
this.listComponents();
|
|
143
|
+
const component = this.componentsByTag.get(tagName);
|
|
144
|
+
if (!component)
|
|
145
|
+
throw new CatalogError('NOT_FOUND', `Component "${tagName}" not found.`);
|
|
146
|
+
return component;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -5,90 +5,64 @@ import { dirname, resolve } from 'node:path';
|
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
6
|
import { parseArgs } from 'node:util';
|
|
7
7
|
import { log } from './_log.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { SnapshotCatalog } from './catalog.js';
|
|
9
|
+
import { startHttpHost } from './http.js';
|
|
10
10
|
import { resolvePort } from './port.js';
|
|
11
|
-
import {
|
|
11
|
+
import { createMcpServer } from './server.js';
|
|
12
|
+
import { loadSnapshot } from './snapshot.js';
|
|
12
13
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
function
|
|
14
|
+
function usage() {
|
|
14
15
|
log([
|
|
15
|
-
'Usage: codex [--port
|
|
16
|
+
'Usage: codex [--port=<number>] [--snapshot=<directory>] [--debug]',
|
|
16
17
|
'',
|
|
17
18
|
'Options:',
|
|
18
|
-
' --port
|
|
19
|
-
' --
|
|
20
|
-
'
|
|
21
|
-
' -
|
|
19
|
+
' --port=<number> Run Streamable HTTP on loopback.',
|
|
20
|
+
' --snapshot=<directory> Load a snapshot directory.',
|
|
21
|
+
' --debug Log tool timings and expected tool errors.',
|
|
22
|
+
' -h, --help Show help.',
|
|
23
|
+
' -v, --version Print version.',
|
|
22
24
|
].join('\n'));
|
|
23
25
|
}
|
|
24
|
-
/** CLI entry point. Exported for testing — invoke directly with a custom argv instead of spawning a subprocess. */
|
|
25
26
|
export async function main(argv = process.argv.slice(2)) {
|
|
26
27
|
if (argv.includes('--help') || argv.includes('-h')) {
|
|
27
|
-
|
|
28
|
-
return;
|
|
28
|
+
usage();
|
|
29
|
+
return 0;
|
|
29
30
|
}
|
|
30
31
|
if (argv.includes('--version') || argv.includes('-v')) {
|
|
31
|
-
const
|
|
32
|
-
process.stdout.write(`${
|
|
33
|
-
return;
|
|
32
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf8'));
|
|
33
|
+
process.stdout.write(`${pkg.version}\n`);
|
|
34
|
+
return 0;
|
|
34
35
|
}
|
|
35
36
|
let values;
|
|
36
37
|
try {
|
|
37
38
|
({ values } = parseArgs({
|
|
38
39
|
args: argv,
|
|
39
|
-
options: {
|
|
40
|
+
options: { debug: { type: 'boolean' }, port: { type: 'string' }, snapshot: { type: 'string' } },
|
|
40
41
|
strict: true,
|
|
41
42
|
}));
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
let port;
|
|
50
|
-
let mcpServer;
|
|
51
|
-
let data;
|
|
52
|
-
try {
|
|
53
|
-
data = loadData(values.data);
|
|
54
|
-
port = resolvePort(values.port);
|
|
55
|
-
mcpServer = createServer(data);
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
log(`error: ${err instanceof Error ? err.message : String(err)}`);
|
|
59
|
-
process.exit(1);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (port !== null) {
|
|
63
|
-
let handle;
|
|
64
|
-
try {
|
|
65
|
-
handle = await startHttpServer(mcpServer, port, () => createServer(data), data.version);
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
const code = err instanceof Error ? err.code : undefined;
|
|
69
|
-
const detail = code === 'EADDRINUSE' ? `port ${port} is already in use.` : String(err);
|
|
70
|
-
log(`error: ${detail}`);
|
|
71
|
-
process.exit(1);
|
|
72
|
-
return;
|
|
43
|
+
const snapshot = loadSnapshot(values.snapshot);
|
|
44
|
+
const catalog = new SnapshotCatalog(snapshot);
|
|
45
|
+
const port = resolvePort(values.port);
|
|
46
|
+
if (port === null) {
|
|
47
|
+
await createMcpServer(catalog, { debug: values.debug, version: snapshot.manifest.version }).connect(new StdioServerTransport());
|
|
48
|
+
return 0;
|
|
73
49
|
}
|
|
50
|
+
const host = await startHttpHost({ catalog, debug: values.debug, port, version: snapshot.manifest.version });
|
|
74
51
|
const shutdown = () => {
|
|
75
|
-
|
|
52
|
+
void host.dispose().then(() => {
|
|
53
|
+
process.exitCode = 0;
|
|
54
|
+
});
|
|
76
55
|
};
|
|
77
|
-
process.once('SIGTERM', shutdown);
|
|
78
56
|
process.once('SIGINT', shutdown);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const transport = new StdioServerTransport();
|
|
82
|
-
try {
|
|
83
|
-
await mcpServer.connect(transport);
|
|
57
|
+
process.once('SIGTERM', shutdown);
|
|
58
|
+
return 0;
|
|
84
59
|
}
|
|
85
|
-
catch (
|
|
86
|
-
log(`error: ${
|
|
87
|
-
|
|
60
|
+
catch (error) {
|
|
61
|
+
log(`error: ${error instanceof Error ? error.message : String(error)}`);
|
|
62
|
+
return 1;
|
|
88
63
|
}
|
|
89
64
|
}
|
|
90
|
-
// Only auto-run when executed directly (e.g. `node dist/cli.js`), not when imported by tests.
|
|
91
65
|
if (import.meta.url === pathToFileURL(process.argv[1] ?? '').href) {
|
|
92
|
-
await main();
|
|
66
|
+
process.exitCode = await main();
|
|
93
67
|
}
|
|
94
68
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
CHANGED
|
@@ -9,18 +9,4 @@ export class CodexError extends Error {
|
|
|
9
9
|
return err instanceof CodexError;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
/**
|
|
13
|
-
* Thrown by tool `run()` implementations for any expected failure (bad argument, unknown
|
|
14
|
-
* slug/tag, missing bundled data). `registerTools()` catches this exclusively — via
|
|
15
|
-
* `instanceof CodexError`, not a `ToolError`-specific check — and turns it into a structured
|
|
16
|
-
* `{ code, message }` MCP error result. Anything else that throws is a real bug and is left to
|
|
17
|
-
* propagate as a protocol-level error instead of being silently swallowed.
|
|
18
|
-
*/
|
|
19
|
-
export class ToolError extends CodexError {
|
|
20
|
-
code;
|
|
21
|
-
constructor(code, message) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.code = code;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
12
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe,EAAE,IAAmB;QAC9C,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,EAAE,CAAC,GAAY;QACpB,OAAO,GAAG,YAAY,UAAU,CAAC;IACnC,CAAC;CACF
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe,EAAE,IAAmB;QAC9C,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,EAAE,CAAC,GAAY;QACpB,OAAO,GAAG,YAAY,UAAU,CAAC;IACnC,CAAC;CACF"}
|
package/dist/http.js
CHANGED
|
@@ -1,108 +1,66 @@
|
|
|
1
|
-
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
2
1
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
3
|
-
import { createServer
|
|
2
|
+
import { createServer } from 'node:http';
|
|
4
3
|
import { log } from './_log.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
12
|
-
if (res.headersSent) {
|
|
13
|
-
const ctx = req ? ` [${req.method} ${req.url}]` : '';
|
|
14
|
-
log(`MCP HTTP error (mid-stream${ctx}): ${message}`);
|
|
15
|
-
if (!res.writableEnded)
|
|
16
|
-
res.end();
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
res.statusCode = 500;
|
|
20
|
-
res.setHeader('content-type', 'application/json; charset=utf-8');
|
|
21
|
-
res.end(JSON.stringify({ error: message }));
|
|
4
|
+
import { createMcpServer } from './server.js';
|
|
5
|
+
function close(server) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
server.closeAllConnections?.();
|
|
8
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
9
|
+
});
|
|
22
10
|
}
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
res.statusCode = 204;
|
|
33
|
-
res.end();
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (req.method === 'GET' && url === '/health') {
|
|
37
|
-
res.statusCode = 200;
|
|
38
|
-
res.setHeader('content-type', 'application/json; charset=utf-8');
|
|
39
|
-
res.end(JSON.stringify({ status: 'ok', ...(version !== undefined && { version }) }));
|
|
11
|
+
/** Streamable HTTP host owns every transport and only listens on loopback addresses. */
|
|
12
|
+
export async function startHttpHost(options) {
|
|
13
|
+
const host = options.host ?? '127.0.0.1';
|
|
14
|
+
const mcpServer = createMcpServer(options.catalog, { debug: options.debug, version: options.version });
|
|
15
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
16
|
+
const httpServer = createServer((request, response) => {
|
|
17
|
+
if (request.method === 'GET' && request.url === '/health') {
|
|
18
|
+
response.writeHead(200, { 'content-type': 'application/json; charset=utf-8' });
|
|
19
|
+
response.end(JSON.stringify({ status: 'ok', version: options.version }));
|
|
40
20
|
return;
|
|
41
21
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const cleanup = () => {
|
|
47
|
-
sseSessions.delete(transport.sessionId);
|
|
48
|
-
};
|
|
49
|
-
sseSessions.set(transport.sessionId, transport);
|
|
50
|
-
transport.onclose = cleanup;
|
|
51
|
-
void sseServer.connect(transport);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
// Legacy SSE: receive a client message.
|
|
55
|
-
if (req.method === 'POST' && url.startsWith('/message')) {
|
|
56
|
-
const sessionId = new URL(url, 'http://localhost').searchParams.get('sessionId') ?? '';
|
|
57
|
-
const session = sseSessions.get(sessionId);
|
|
58
|
-
if (!session) {
|
|
59
|
-
res.statusCode = 404;
|
|
60
|
-
res.end(JSON.stringify({ error: 'Session not found' }));
|
|
61
|
-
return;
|
|
22
|
+
void transport.handleRequest(request, response).catch((error) => {
|
|
23
|
+
if (!response.headersSent) {
|
|
24
|
+
response.writeHead(500, { 'content-type': 'application/json; charset=utf-8' });
|
|
25
|
+
response.end(JSON.stringify({ error: 'MCP request failed' }));
|
|
62
26
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// Streamable HTTP (spec-compliant clients).
|
|
67
|
-
void streamableTransport.handleRequest(req, res).catch((err) => handleError(err, res, req));
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
export async function startHttpServer(mcpServer, port, createSseServer, version) {
|
|
71
|
-
// Legacy SSE sessions keyed by sessionId (for older MCP clients like Windsurf).
|
|
72
|
-
const sseSessions = new Map();
|
|
73
|
-
// Streamable HTTP transport (spec-compliant, newer clients).
|
|
74
|
-
const streamableTransport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
75
|
-
await mcpServer.connect(streamableTransport);
|
|
76
|
-
const httpServer = createHttpServer(createRequestHandler(streamableTransport, sseSessions, createSseServer, version));
|
|
77
|
-
await new Promise((resolve, reject) => {
|
|
78
|
-
const onError = (err) => reject(err);
|
|
79
|
-
httpServer.once('error', onError);
|
|
80
|
-
httpServer.listen(port, () => {
|
|
81
|
-
httpServer.off('error', onError);
|
|
82
|
-
log(`codex MCP server listening on http://localhost:${port}/`);
|
|
83
|
-
log(` SSE (legacy): GET http://localhost:${port}/sse`);
|
|
84
|
-
log(` Streamable HTTP: POST http://localhost:${port}/`);
|
|
85
|
-
resolve();
|
|
27
|
+
else if (!response.writableEnded)
|
|
28
|
+
response.end();
|
|
29
|
+
log(`HTTP MCP error: ${error instanceof Error ? error.message : String(error)}`);
|
|
86
30
|
});
|
|
87
31
|
});
|
|
32
|
+
let listening = false;
|
|
88
33
|
let disposed = false;
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
httpServer
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return disposed;
|
|
101
|
-
},
|
|
102
|
-
[Symbol.asyncDispose]() {
|
|
103
|
-
return this.dispose();
|
|
104
|
-
},
|
|
34
|
+
const dispose = async () => {
|
|
35
|
+
if (disposed)
|
|
36
|
+
return;
|
|
37
|
+
disposed = true;
|
|
38
|
+
try {
|
|
39
|
+
if (listening)
|
|
40
|
+
await close(httpServer);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
await mcpServer.close();
|
|
44
|
+
}
|
|
105
45
|
};
|
|
106
|
-
|
|
46
|
+
try {
|
|
47
|
+
await mcpServer.connect(transport);
|
|
48
|
+
await new Promise((resolve, reject) => {
|
|
49
|
+
httpServer.once('error', reject);
|
|
50
|
+
httpServer.listen(options.port, host, () => {
|
|
51
|
+
httpServer.off('error', reject);
|
|
52
|
+
listening = true;
|
|
53
|
+
resolve();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
await dispose();
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
const address = httpServer.address();
|
|
62
|
+
const port = address && typeof address === 'object' ? address.port : options.port;
|
|
63
|
+
log(`codex MCP HTTP host listening on http://${host}:${port}/`);
|
|
64
|
+
return { dispose, host, port, [Symbol.asyncDispose]: dispose };
|
|
107
65
|
}
|
|
108
66
|
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { CodexError
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
1
|
+
export { CatalogError, SnapshotCatalog } from './catalog.js';
|
|
2
|
+
export { CodexError } from './errors.js';
|
|
3
|
+
export { startHttpHost } from './http.js';
|
|
4
|
+
export { createMcpServer } from './server.js';
|
|
5
|
+
export { loadSnapshot, parseCatalog, parseContent, parseManifest, parsePointer, parseSearch, validateSnapshot, } from './snapshot.js';
|
|
6
|
+
export { DOC_PAGES, SNAPSHOT_SCHEMA_VERSION, } from './types.js';
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAgC,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAuC,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,SAAS,EACT,uBAAuB,GAcxB,MAAM,YAAY,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
registerTools(server, buildToolContext(data));
|
|
2
|
+
import { registerTools } from './tools/index.js';
|
|
3
|
+
export function createMcpServer(catalog, options) {
|
|
4
|
+
const server = new Server({ name: 'vielzeug', version: options.version }, { capabilities: { tools: {} } });
|
|
5
|
+
registerTools(server, catalog, options.debug);
|
|
7
6
|
return server;
|
|
8
7
|
}
|
|
9
|
-
/** Convenience factory: loads bundled data from disk and creates the MCP server in one call. */
|
|
10
|
-
export function createServerFromDisk() {
|
|
11
|
-
return createServer(loadData());
|
|
12
|
-
}
|
|
13
8
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,OAA6C;IAC7F,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAE3G,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE9C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|