@refrakt-md/mcp 0.10.1
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/bin.d.ts +12 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +61 -0
- package/dist/bin.js.map +1 -0
- package/dist/detect.d.ts +30 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +93 -0
- package/dist/detect.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/resources.d.ts +40 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +265 -0
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +48 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +108 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/core.d.ts +27 -0
- package/dist/tools/core.d.ts.map +1 -0
- package/dist/tools/core.js +217 -0
- package/dist/tools/core.js.map +1 -0
- package/dist/tools/plugins.d.ts +13 -0
- package/dist/tools/plugins.d.ts.map +1 -0
- package/dist/tools/plugins.js +106 -0
- package/dist/tools/plugins.js.map +1 -0
- package/package.json +41 -0
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Stdio entry point for the refrakt MCP server.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* refrakt-mcp [--cwd <path>]
|
|
7
|
+
*
|
|
8
|
+
* Reads the project root from `--cwd` (or `process.cwd()` by default), then
|
|
9
|
+
* starts the MCP server on stdio.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=bin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Stdio entry point for the refrakt MCP server.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* refrakt-mcp [--cwd <path>]
|
|
7
|
+
*
|
|
8
|
+
* Reads the project root from `--cwd` (or `process.cwd()` by default), then
|
|
9
|
+
* starts the MCP server on stdio.
|
|
10
|
+
*/
|
|
11
|
+
import { runStdioServer } from './server.js';
|
|
12
|
+
function parseArgs(argv) {
|
|
13
|
+
let cwd;
|
|
14
|
+
let help = false;
|
|
15
|
+
for (let i = 0; i < argv.length; i++) {
|
|
16
|
+
const a = argv[i];
|
|
17
|
+
if (a === '--cwd') {
|
|
18
|
+
cwd = argv[++i];
|
|
19
|
+
if (!cwd) {
|
|
20
|
+
console.error('Error: --cwd requires a path');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (a === '--help' || a === '-h') {
|
|
25
|
+
help = true;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.error(`Error: Unknown argument "${a}"`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { cwd, help };
|
|
33
|
+
}
|
|
34
|
+
const { cwd, help } = parseArgs(process.argv.slice(2));
|
|
35
|
+
if (help) {
|
|
36
|
+
console.log(`
|
|
37
|
+
Usage: refrakt-mcp [--cwd <path>]
|
|
38
|
+
|
|
39
|
+
A Model Context Protocol server that wraps the refrakt CLI. Speaks JSON-RPC
|
|
40
|
+
over stdio. Register it with your MCP client (Claude Desktop, Claude Code,
|
|
41
|
+
Cursor, etc.) by adding to the client's config:
|
|
42
|
+
|
|
43
|
+
"refrakt": {
|
|
44
|
+
"command": "npx",
|
|
45
|
+
"args": ["-y", "@refrakt-md/mcp"]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
Options:
|
|
49
|
+
--cwd <path> Project root the server operates against. Defaults to
|
|
50
|
+
process.cwd(). Useful when the MCP client launches the
|
|
51
|
+
server from a different directory.
|
|
52
|
+
|
|
53
|
+
--help, -h Show this help message.
|
|
54
|
+
`);
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
runStdioServer({ cwd }).catch((err) => {
|
|
58
|
+
process.stderr.write(`refrakt-mcp failed to start: ${err.message}\n`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,SAAS,SAAS,CAAC,IAAc;IAChC,IAAI,GAAuB,CAAC;IAC5B,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACnB,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;YACnB,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAChB,IAAI,CAAC,GAAG,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;gBAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACF,CAAC;aAAM,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACzC,IAAI,GAAG,IAAI,CAAC;QACb,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvD,IAAI,IAAI,EAAE,CAAC;IACV,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;CAkBZ,CAAC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-detection for the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Inspects the working directory once at startup to figure out which
|
|
5
|
+
* tool groups should be exposed:
|
|
6
|
+
* - `plan` context: a `plan/` directory exists.
|
|
7
|
+
* - `site` context: `refrakt.config.json` declares one or more sites.
|
|
8
|
+
*
|
|
9
|
+
* Both can be active in the same project. Neither being active leaves the
|
|
10
|
+
* server with diagnostic-only tools.
|
|
11
|
+
*/
|
|
12
|
+
import { type DiscoveredPlugin } from '@refrakt-md/cli/lib/plugins.js';
|
|
13
|
+
export interface DetectedPlanContext {
|
|
14
|
+
dir: string;
|
|
15
|
+
fileCount: number;
|
|
16
|
+
}
|
|
17
|
+
export interface DetectedSiteContext {
|
|
18
|
+
configPath: string;
|
|
19
|
+
sites: string[];
|
|
20
|
+
plugins: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface DetectionResult {
|
|
23
|
+
cwd: string;
|
|
24
|
+
plan: DetectedPlanContext | null;
|
|
25
|
+
site: DetectedSiteContext | null;
|
|
26
|
+
plugins: DiscoveredPlugin[];
|
|
27
|
+
configSource: 'config-file' | 'autodetect';
|
|
28
|
+
}
|
|
29
|
+
export declare function detect(cwd?: string): Promise<DetectionResult>;
|
|
30
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAExF,MAAM,WAAW,mBAAmB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACjC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,YAAY,EAAE,aAAa,GAAG,YAAY,CAAC;CAC3C;AAED,wBAAsB,MAAM,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,eAAe,CAAC,CA8ClF"}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-detection for the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Inspects the working directory once at startup to figure out which
|
|
5
|
+
* tool groups should be exposed:
|
|
6
|
+
* - `plan` context: a `plan/` directory exists.
|
|
7
|
+
* - `site` context: `refrakt.config.json` declares one or more sites.
|
|
8
|
+
*
|
|
9
|
+
* Both can be active in the same project. Neither being active leaves the
|
|
10
|
+
* server with diagnostic-only tools.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
13
|
+
import { resolve } from 'node:path';
|
|
14
|
+
import { loadRefraktConfigWithRaw } from '@refrakt-md/transform/node';
|
|
15
|
+
import { discoverPlugins } from '@refrakt-md/cli/lib/plugins.js';
|
|
16
|
+
export async function detect(cwd = process.cwd()) {
|
|
17
|
+
const result = {
|
|
18
|
+
cwd,
|
|
19
|
+
plan: null,
|
|
20
|
+
site: null,
|
|
21
|
+
plugins: [],
|
|
22
|
+
configSource: 'autodetect',
|
|
23
|
+
};
|
|
24
|
+
const configPath = resolve(cwd, 'refrakt.config.json');
|
|
25
|
+
if (existsSync(configPath)) {
|
|
26
|
+
try {
|
|
27
|
+
const { normalized } = loadRefraktConfigWithRaw(configPath);
|
|
28
|
+
result.configSource = 'config-file';
|
|
29
|
+
const siteNames = Object.keys(normalized.sites);
|
|
30
|
+
if (siteNames.length > 0) {
|
|
31
|
+
result.site = {
|
|
32
|
+
configPath,
|
|
33
|
+
sites: siteNames,
|
|
34
|
+
plugins: normalized.plugins ?? [],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (normalized.plan?.dir) {
|
|
38
|
+
const planDir = resolve(cwd, normalized.plan.dir);
|
|
39
|
+
result.plan = describePlanDir(planDir);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Malformed config — fall through to autodetect
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Autodetect plan/ if not declared in config
|
|
47
|
+
if (!result.plan) {
|
|
48
|
+
const planDir = resolve(cwd, 'plan');
|
|
49
|
+
if (existsSync(planDir) && safeIsDirectory(planDir)) {
|
|
50
|
+
result.plan = describePlanDir(planDir);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
result.plugins = await discoverPlugins({ cwd, warn: false });
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Discovery failures are non-fatal
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
function describePlanDir(dir) {
|
|
62
|
+
let fileCount = 0;
|
|
63
|
+
const stack = [dir];
|
|
64
|
+
while (stack.length > 0) {
|
|
65
|
+
const current = stack.pop();
|
|
66
|
+
if (!existsSync(current) || !safeIsDirectory(current))
|
|
67
|
+
continue;
|
|
68
|
+
try {
|
|
69
|
+
for (const entry of readdirSync(current)) {
|
|
70
|
+
const full = resolve(current, entry);
|
|
71
|
+
if (safeIsDirectory(full)) {
|
|
72
|
+
stack.push(full);
|
|
73
|
+
}
|
|
74
|
+
else if (entry.endsWith('.md')) {
|
|
75
|
+
fileCount++;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// keep counting what we can
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { dir, fileCount };
|
|
84
|
+
}
|
|
85
|
+
function safeIsDirectory(path) {
|
|
86
|
+
try {
|
|
87
|
+
return statSync(path).isDirectory();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @refrakt-md/mcp — Model Context Protocol server wrapping the refrakt CLI.
|
|
3
|
+
*
|
|
4
|
+
* Most users will install this and register `refrakt-mcp` (the bin entry) in
|
|
5
|
+
* their MCP client config. Programmatic consumers can import the server
|
|
6
|
+
* factory directly.
|
|
7
|
+
*/
|
|
8
|
+
export { createServer, runStdioServer } from './server.js';
|
|
9
|
+
export type { CreateServerOptions } from './server.js';
|
|
10
|
+
export { detect } from './detect.js';
|
|
11
|
+
export type { DetectionResult, DetectedPlanContext, DetectedSiteContext } from './detect.js';
|
|
12
|
+
export { CORE_TOOLS } from './tools/core.js';
|
|
13
|
+
export type { McpTool } from './tools/core.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @refrakt-md/mcp — Model Context Protocol server wrapping the refrakt CLI.
|
|
3
|
+
*
|
|
4
|
+
* Most users will install this and register `refrakt-mcp` (the bin entry) in
|
|
5
|
+
* their MCP client config. Programmatic consumers can import the server
|
|
6
|
+
* factory directly.
|
|
7
|
+
*/
|
|
8
|
+
export { createServer, runStdioServer } from './server.js';
|
|
9
|
+
export { detect } from './detect.js';
|
|
10
|
+
export { CORE_TOOLS } from './tools/core.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP resources — read-only addressable data the server exposes.
|
|
3
|
+
*
|
|
4
|
+
* Resources mirror the read-only subset of the tool surface so MCP clients
|
|
5
|
+
* that prefer pull semantics (ReadResource) get equivalent data without a
|
|
6
|
+
* tool invocation.
|
|
7
|
+
*
|
|
8
|
+
* URI scheme:
|
|
9
|
+
* refrakt://detect — full detection result
|
|
10
|
+
* refrakt://reference — rune syntax reference (JSON)
|
|
11
|
+
* refrakt://contracts — structure contracts (JSON)
|
|
12
|
+
* refrakt://rune/<name> — identity transform output for one rune
|
|
13
|
+
* refrakt://plan/index — list of plan entities
|
|
14
|
+
* refrakt://plan/<type>/<id> — Markdoc source for one plan entity
|
|
15
|
+
* refrakt://plan/status — plan status payload
|
|
16
|
+
*/
|
|
17
|
+
export interface McpResource {
|
|
18
|
+
uri: string;
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
mimeType: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ResourceContent {
|
|
24
|
+
uri: string;
|
|
25
|
+
mimeType: string;
|
|
26
|
+
text: string;
|
|
27
|
+
}
|
|
28
|
+
/** Static resource list — dynamic ones (e.g. refrakt://rune/<name>) are
|
|
29
|
+
* surfaced via templated entries the client can complete. */
|
|
30
|
+
export declare function listResources(ctx: {
|
|
31
|
+
cwd: string;
|
|
32
|
+
hasPlan: boolean;
|
|
33
|
+
hasSites: boolean;
|
|
34
|
+
}): McpResource[];
|
|
35
|
+
/** Read the contents of a resource by URI. Returns the text payload (always
|
|
36
|
+
* JSON for now — markdown could be added later for plan entity reads). */
|
|
37
|
+
export declare function readResource(uri: string, ctx: {
|
|
38
|
+
cwd: string;
|
|
39
|
+
}): Promise<ResourceContent>;
|
|
40
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,MAAM,WAAW,WAAW;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACb;AAED;8DAC8D;AAC9D,wBAAgB,aAAa,CAAC,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,EAAE,CA0CtG;AAED;2EAC2E;AAC3E,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAoD9F"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP resources — read-only addressable data the server exposes.
|
|
3
|
+
*
|
|
4
|
+
* Resources mirror the read-only subset of the tool surface so MCP clients
|
|
5
|
+
* that prefer pull semantics (ReadResource) get equivalent data without a
|
|
6
|
+
* tool invocation.
|
|
7
|
+
*
|
|
8
|
+
* URI scheme:
|
|
9
|
+
* refrakt://detect — full detection result
|
|
10
|
+
* refrakt://reference — rune syntax reference (JSON)
|
|
11
|
+
* refrakt://contracts — structure contracts (JSON)
|
|
12
|
+
* refrakt://rune/<name> — identity transform output for one rune
|
|
13
|
+
* refrakt://plan/index — list of plan entities
|
|
14
|
+
* refrakt://plan/<type>/<id> — Markdoc source for one plan entity
|
|
15
|
+
* refrakt://plan/status — plan status payload
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
18
|
+
import { resolve, join } from 'node:path';
|
|
19
|
+
/** Static resource list — dynamic ones (e.g. refrakt://rune/<name>) are
|
|
20
|
+
* surfaced via templated entries the client can complete. */
|
|
21
|
+
export function listResources(ctx) {
|
|
22
|
+
const list = [
|
|
23
|
+
{
|
|
24
|
+
uri: 'refrakt://detect',
|
|
25
|
+
name: 'detect',
|
|
26
|
+
description: 'Auto-detection summary for the current project (plan dir, sites, plugins).',
|
|
27
|
+
mimeType: 'application/json',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
if (ctx.hasSites) {
|
|
31
|
+
list.push({
|
|
32
|
+
uri: 'refrakt://reference',
|
|
33
|
+
name: 'reference',
|
|
34
|
+
description: 'Rune syntax reference for the active package set.',
|
|
35
|
+
mimeType: 'application/json',
|
|
36
|
+
}, {
|
|
37
|
+
uri: 'refrakt://contracts',
|
|
38
|
+
name: 'contracts',
|
|
39
|
+
description: 'Structure contracts for every rune in the active package set.',
|
|
40
|
+
mimeType: 'application/json',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (ctx.hasPlan) {
|
|
44
|
+
list.push({
|
|
45
|
+
uri: 'refrakt://plan/index',
|
|
46
|
+
name: 'plan-index',
|
|
47
|
+
description: 'Index of all plan entities (id, type, status, file path).',
|
|
48
|
+
mimeType: 'application/json',
|
|
49
|
+
}, {
|
|
50
|
+
uri: 'refrakt://plan/status',
|
|
51
|
+
name: 'plan-status',
|
|
52
|
+
description: 'Plan status summary (counts, milestone progress).',
|
|
53
|
+
mimeType: 'application/json',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return list;
|
|
57
|
+
}
|
|
58
|
+
/** Read the contents of a resource by URI. Returns the text payload (always
|
|
59
|
+
* JSON for now — markdown could be added later for plan entity reads). */
|
|
60
|
+
export async function readResource(uri, ctx) {
|
|
61
|
+
if (uri === 'refrakt://detect') {
|
|
62
|
+
const { detect } = await import('./detect.js');
|
|
63
|
+
const result = await detect(ctx.cwd);
|
|
64
|
+
return jsonContent(uri, result);
|
|
65
|
+
}
|
|
66
|
+
if (uri === 'refrakt://reference') {
|
|
67
|
+
return jsonContent(uri, await invokeCli(['reference', '--format', 'json'], ctx.cwd));
|
|
68
|
+
}
|
|
69
|
+
if (uri === 'refrakt://contracts') {
|
|
70
|
+
const stdout = await invokeCliText(['contracts', '-o', '/dev/stdout'], ctx.cwd);
|
|
71
|
+
const start = stdout.indexOf('{');
|
|
72
|
+
if (start === -1)
|
|
73
|
+
throw resourceError(uri, 'contracts produced no JSON output');
|
|
74
|
+
return { uri, mimeType: 'application/json', text: stdout.slice(start).trim() };
|
|
75
|
+
}
|
|
76
|
+
if (uri.startsWith('refrakt://rune/')) {
|
|
77
|
+
const rest = uri.slice('refrakt://rune/'.length);
|
|
78
|
+
const [name, query] = rest.split('?');
|
|
79
|
+
if (!name)
|
|
80
|
+
throw resourceError(uri, 'missing rune name');
|
|
81
|
+
const args = ['inspect', name, '--json'];
|
|
82
|
+
if (query) {
|
|
83
|
+
for (const pair of query.split('&')) {
|
|
84
|
+
const [k, v] = pair.split('=');
|
|
85
|
+
if (!k)
|
|
86
|
+
continue;
|
|
87
|
+
args.push(`--${k}=${v ?? ''}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return jsonContent(uri, await invokeCli(args, ctx.cwd));
|
|
91
|
+
}
|
|
92
|
+
if (uri === 'refrakt://plan/index') {
|
|
93
|
+
return jsonContent(uri, listPlanEntities(ctx.cwd));
|
|
94
|
+
}
|
|
95
|
+
if (uri === 'refrakt://plan/status') {
|
|
96
|
+
return jsonContent(uri, await invokeCli(['plan', 'status', '--format', 'json'], ctx.cwd));
|
|
97
|
+
}
|
|
98
|
+
if (uri.startsWith('refrakt://plan/')) {
|
|
99
|
+
// Single entity by type/id — refrakt://plan/work/WORK-001
|
|
100
|
+
const rest = uri.slice('refrakt://plan/'.length);
|
|
101
|
+
const slashIdx = rest.indexOf('/');
|
|
102
|
+
if (slashIdx === -1)
|
|
103
|
+
throw resourceError(uri, 'expected refrakt://plan/<type>/<id>');
|
|
104
|
+
const type = rest.slice(0, slashIdx);
|
|
105
|
+
const id = rest.slice(slashIdx + 1);
|
|
106
|
+
return readPlanEntity(uri, ctx.cwd, type, id);
|
|
107
|
+
}
|
|
108
|
+
throw resourceError(uri, `unknown resource URI`);
|
|
109
|
+
}
|
|
110
|
+
function listPlanEntities(cwd) {
|
|
111
|
+
const planDir = resolvePlanDir(cwd);
|
|
112
|
+
if (!planDir || !existsSync(planDir))
|
|
113
|
+
return { entities: [] };
|
|
114
|
+
const entities = [];
|
|
115
|
+
const stack = [planDir];
|
|
116
|
+
while (stack.length > 0) {
|
|
117
|
+
const current = stack.pop();
|
|
118
|
+
try {
|
|
119
|
+
for (const entry of readdirSync(current)) {
|
|
120
|
+
const full = join(current, entry);
|
|
121
|
+
if (statSync(full).isDirectory()) {
|
|
122
|
+
stack.push(full);
|
|
123
|
+
}
|
|
124
|
+
else if (entry.endsWith('.md')) {
|
|
125
|
+
try {
|
|
126
|
+
const text = readFileSync(full, 'utf-8');
|
|
127
|
+
const meta = parseFrontMatter(text);
|
|
128
|
+
if (meta) {
|
|
129
|
+
entities.push({
|
|
130
|
+
...meta,
|
|
131
|
+
file: full.slice(planDir.length + 1),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// skip unreadable
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// skip unreadable directory
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return { entities };
|
|
146
|
+
}
|
|
147
|
+
function parseFrontMatter(text) {
|
|
148
|
+
const match = text.match(/\{%\s*(work|bug|spec|decision|milestone)\s+([^%]+)%\}/);
|
|
149
|
+
if (!match)
|
|
150
|
+
return undefined;
|
|
151
|
+
const type = match[1];
|
|
152
|
+
const attrs = match[2];
|
|
153
|
+
const idMatch = attrs.match(/(?:id|name)="([^"]+)"/);
|
|
154
|
+
if (!idMatch)
|
|
155
|
+
return undefined;
|
|
156
|
+
const statusMatch = attrs.match(/status="([^"]+)"/);
|
|
157
|
+
return {
|
|
158
|
+
id: idMatch[1],
|
|
159
|
+
type,
|
|
160
|
+
...(statusMatch ? { status: statusMatch[1] } : {}),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function readPlanEntity(uri, cwd, type, id) {
|
|
164
|
+
const planDir = resolvePlanDir(cwd);
|
|
165
|
+
if (!planDir || !existsSync(planDir))
|
|
166
|
+
throw resourceError(uri, 'plan directory not found');
|
|
167
|
+
// Look in plan/<type>s/ first (the convention), then anywhere under plan/.
|
|
168
|
+
const candidates = [
|
|
169
|
+
join(planDir, `${type}s`),
|
|
170
|
+
join(planDir, type),
|
|
171
|
+
planDir,
|
|
172
|
+
];
|
|
173
|
+
for (const dir of candidates) {
|
|
174
|
+
if (!existsSync(dir))
|
|
175
|
+
continue;
|
|
176
|
+
const found = findEntityFile(dir, id);
|
|
177
|
+
if (found) {
|
|
178
|
+
return {
|
|
179
|
+
uri,
|
|
180
|
+
mimeType: 'text/markdown',
|
|
181
|
+
text: readFileSync(found, 'utf-8'),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
throw resourceError(uri, `plan entity ${id} not found`);
|
|
186
|
+
}
|
|
187
|
+
function findEntityFile(dir, id) {
|
|
188
|
+
const stack = [dir];
|
|
189
|
+
while (stack.length > 0) {
|
|
190
|
+
const current = stack.pop();
|
|
191
|
+
try {
|
|
192
|
+
for (const entry of readdirSync(current)) {
|
|
193
|
+
const full = join(current, entry);
|
|
194
|
+
try {
|
|
195
|
+
if (statSync(full).isDirectory())
|
|
196
|
+
stack.push(full);
|
|
197
|
+
else if (entry.endsWith('.md') && entry.includes(id))
|
|
198
|
+
return full;
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// skip
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// skip
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
function resolvePlanDir(cwd) {
|
|
212
|
+
const configPath = resolve(cwd, 'refrakt.config.json');
|
|
213
|
+
if (existsSync(configPath)) {
|
|
214
|
+
try {
|
|
215
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
216
|
+
if (config.plan?.dir)
|
|
217
|
+
return resolve(cwd, config.plan.dir);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// fall through to default
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const fallback = resolve(cwd, 'plan');
|
|
224
|
+
return existsSync(fallback) ? fallback : undefined;
|
|
225
|
+
}
|
|
226
|
+
function jsonContent(uri, payload) {
|
|
227
|
+
return { uri, mimeType: 'application/json', text: JSON.stringify(payload, null, 2) };
|
|
228
|
+
}
|
|
229
|
+
function resourceError(uri, message) {
|
|
230
|
+
const err = new Error(`${message} (${uri})`);
|
|
231
|
+
err.errorCode = 'RESOURCE_FAILED';
|
|
232
|
+
return err;
|
|
233
|
+
}
|
|
234
|
+
/** CLI invocation that returns parsed JSON. */
|
|
235
|
+
async function invokeCli(args, cwd) {
|
|
236
|
+
const text = await invokeCliText(args, cwd);
|
|
237
|
+
return JSON.parse(text);
|
|
238
|
+
}
|
|
239
|
+
/** CLI invocation that returns raw stdout text. */
|
|
240
|
+
async function invokeCliText(args, cwd) {
|
|
241
|
+
const { execFileSync } = await import('node:child_process');
|
|
242
|
+
const { createRequire } = await import('node:module');
|
|
243
|
+
const require_ = createRequire(import.meta.url);
|
|
244
|
+
let bin;
|
|
245
|
+
try {
|
|
246
|
+
const pkgJsonPath = require_.resolve('@refrakt-md/cli/package.json');
|
|
247
|
+
bin = pkgJsonPath.replace(/[\/\\]package\.json$/, '/dist/bin.js');
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
bin = 'refrakt';
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
return execFileSync('node', [bin, ...args], {
|
|
254
|
+
encoding: 'utf-8',
|
|
255
|
+
cwd,
|
|
256
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
257
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
const stderr = (err.stderr ?? '').toString();
|
|
262
|
+
throw new Error(`refrakt ${args[0]} failed: ${stderr.trim() || err.message}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAe1C;8DAC8D;AAC9D,MAAM,UAAU,aAAa,CAAC,GAAyD;IACtF,MAAM,IAAI,GAAkB;QAC3B;YACC,GAAG,EAAE,kBAAkB;YACvB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,4EAA4E;YACzF,QAAQ,EAAE,kBAAkB;SAC5B;KACD,CAAC;IACF,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CACR;YACC,GAAG,EAAE,qBAAqB;YAC1B,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,mDAAmD;YAChE,QAAQ,EAAE,kBAAkB;SAC5B,EACD;YACC,GAAG,EAAE,qBAAqB;YAC1B,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,+DAA+D;YAC5E,QAAQ,EAAE,kBAAkB;SAC5B,CACD,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CACR;YACC,GAAG,EAAE,sBAAsB;YAC3B,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,2DAA2D;YACxE,QAAQ,EAAE,kBAAkB;SAC5B,EACD;YACC,GAAG,EAAE,uBAAuB;YAC5B,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,mDAAmD;YAChE,QAAQ,EAAE,kBAAkB;SAC5B,CACD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;2EAC2E;AAC3E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,GAAoB;IACnE,IAAI,GAAG,KAAK,kBAAkB,EAAE,CAAC;QAChC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,GAAG,KAAK,qBAAqB,EAAE,CAAC;QACnC,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,GAAG,KAAK,qBAAqB,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAChF,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM,aAAa,CAAC,GAAG,EAAE,mCAAmC,CAAC,CAAC;QAChF,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IAChF,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI;YAAE,MAAM,aAAa,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAI,KAAK,EAAE,CAAC;YACX,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC/B,IAAI,CAAC,CAAC;oBAAE,SAAS;gBACjB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAChC,CAAC;QACF,CAAC;QACD,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,GAAG,KAAK,sBAAsB,EAAE,CAAC;QACpC,OAAO,WAAW,CAAC,GAAG,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,GAAG,KAAK,uBAAuB,EAAE,CAAC;QACrC,OAAO,WAAW,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACvC,0DAA0D;QAC1D,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,CAAC,CAAC;YAAE,MAAM,aAAa,CAAC,GAAG,EAAE,qCAAqC,CAAC,CAAC;QACrF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QACpC,OAAO,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,aAAa,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;AAClD,CAAC;AASD,SAAS,gBAAgB,CAAC,GAAW;IACpC,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC9D,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;IACxB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QAC7B,IAAI,CAAC;YACJ,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;oBAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClB,CAAC;qBAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBAClC,IAAI,CAAC;wBACJ,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;wBACzC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;wBACpC,IAAI,IAAI,EAAE,CAAC;4BACV,QAAQ,CAAC,IAAI,CAAC;gCACb,GAAG,IAAI;gCACP,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;6BACpC,CAAC,CAAC;wBACJ,CAAC;oBACF,CAAC;oBAAC,MAAM,CAAC;wBACR,kBAAkB;oBACnB,CAAC;gBACF,CAAC;YACF,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,4BAA4B;QAC7B,CAAC;IACF,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,CAAC;AACrB,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAClF,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;IACvB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;IACxB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACpD,OAAO;QACN,EAAE,EAAE,OAAO,CAAC,CAAC,CAAE;QACf,IAAI;QACJ,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnD,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW,EAAE,GAAW,EAAE,IAAY,EAAE,EAAU;IACzE,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,MAAM,aAAa,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;IAC3F,2EAA2E;IAC3E,MAAM,UAAU,GAAG;QAClB,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,CAAC;QACzB,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC;QACnB,OAAO;KACP,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,KAAK,EAAE,CAAC;YACX,OAAO;gBACN,GAAG;gBACH,QAAQ,EAAE,eAAe;gBACzB,IAAI,EAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC;aAClC,CAAC;QACH,CAAC;IACF,CAAC;IACD,MAAM,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,cAAc,CAAC,GAAW,EAAE,EAAU;IAC9C,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QAC7B,IAAI,CAAC;YACJ,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClC,IAAI,CAAC;oBACJ,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;wBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;yBAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAAE,OAAO,IAAI,CAAC;gBACnE,CAAC;gBAAC,MAAM,CAAC;oBACR,OAAO;gBACR,CAAC;YACF,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,OAAO;QACR,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;IACvD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAgC,CAAC;YAC5F,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG;gBAAE,OAAO,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACR,0BAA0B;QAC3B,CAAC;IACF,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,OAAgB;IACjD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AACtF,CAAC;AAED,SAAS,aAAa,CAAC,GAAW,EAAE,OAAe;IAClD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,GAAG,GAAG,CAAC,CAAC;IAC5C,GAA8B,CAAC,SAAS,GAAG,iBAAiB,CAAC;IAC9D,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,+CAA+C;AAC/C,KAAK,UAAU,SAAS,CAAC,IAAc,EAAE,GAAW;IACnD,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,mDAAmD;AACnD,KAAK,UAAU,aAAa,CAAC,IAAc,EAAE,GAAW;IACvD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC5D,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QACrE,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACR,GAAG,GAAG,SAAS,CAAC;IACjB,CAAC;IACD,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE;YAC3C,QAAQ,EAAE,OAAO;YACjB,GAAG;YACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;SAC3B,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;AACF,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server setup. Registers tools, hooks up the stdio transport, and
|
|
3
|
+
* dispatches incoming requests.
|
|
4
|
+
*
|
|
5
|
+
* The server reads `cwd` from process at start; a `--cwd <path>` flag on the
|
|
6
|
+
* bin handler can override it for clients that launch the server from outside
|
|
7
|
+
* the project root.
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
export interface CreateServerOptions {
|
|
11
|
+
cwd?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function createServer(options?: CreateServerOptions): Promise<Server<{
|
|
14
|
+
method: string;
|
|
15
|
+
params?: {
|
|
16
|
+
[x: string]: unknown;
|
|
17
|
+
_meta?: {
|
|
18
|
+
[x: string]: unknown;
|
|
19
|
+
progressToken?: string | number | undefined;
|
|
20
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
21
|
+
taskId: string;
|
|
22
|
+
} | undefined;
|
|
23
|
+
} | undefined;
|
|
24
|
+
} | undefined;
|
|
25
|
+
}, {
|
|
26
|
+
method: string;
|
|
27
|
+
params?: {
|
|
28
|
+
[x: string]: unknown;
|
|
29
|
+
_meta?: {
|
|
30
|
+
[x: string]: unknown;
|
|
31
|
+
progressToken?: string | number | undefined;
|
|
32
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
33
|
+
taskId: string;
|
|
34
|
+
} | undefined;
|
|
35
|
+
} | undefined;
|
|
36
|
+
} | undefined;
|
|
37
|
+
}, {
|
|
38
|
+
[x: string]: unknown;
|
|
39
|
+
_meta?: {
|
|
40
|
+
[x: string]: unknown;
|
|
41
|
+
progressToken?: string | number | undefined;
|
|
42
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
43
|
+
taskId: string;
|
|
44
|
+
} | undefined;
|
|
45
|
+
} | undefined;
|
|
46
|
+
}>>;
|
|
47
|
+
export declare function runStdioServer(options?: CreateServerOptions): Promise<void>;
|
|
48
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAanE,MAAM,WAAW,mBAAmB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,mBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+FnE;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrF"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server setup. Registers tools, hooks up the stdio transport, and
|
|
3
|
+
* dispatches incoming requests.
|
|
4
|
+
*
|
|
5
|
+
* The server reads `cwd` from process at start; a `--cwd <path>` flag on the
|
|
6
|
+
* bin handler can override it for clients that launch the server from outside
|
|
7
|
+
* the project root.
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
|
+
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
+
import { CORE_TOOLS } from './tools/core.js';
|
|
13
|
+
import { loadPluginTools } from './tools/plugins.js';
|
|
14
|
+
import { listResources, readResource } from './resources.js';
|
|
15
|
+
import { detect } from './detect.js';
|
|
16
|
+
export async function createServer(options = {}) {
|
|
17
|
+
const cwd = options.cwd ?? process.cwd();
|
|
18
|
+
// Detection happens once at startup so we can both decide which resources
|
|
19
|
+
// to expose and surface the detection result on `tools/list` for clients
|
|
20
|
+
// that want to understand the project before invoking anything.
|
|
21
|
+
const detection = await detect(cwd);
|
|
22
|
+
const pluginTools = await loadPluginTools(cwd);
|
|
23
|
+
const tools = [...CORE_TOOLS, ...pluginTools];
|
|
24
|
+
const server = new Server({
|
|
25
|
+
name: '@refrakt-md/mcp',
|
|
26
|
+
version: '0.10.1',
|
|
27
|
+
}, {
|
|
28
|
+
capabilities: {
|
|
29
|
+
tools: {},
|
|
30
|
+
resources: {},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
34
|
+
return {
|
|
35
|
+
tools: tools.map((tool) => ({
|
|
36
|
+
name: tool.name,
|
|
37
|
+
description: tool.description,
|
|
38
|
+
inputSchema: tool.inputSchema,
|
|
39
|
+
})),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
43
|
+
const tool = tools.find((t) => t.name === request.params.name);
|
|
44
|
+
if (!tool) {
|
|
45
|
+
return {
|
|
46
|
+
isError: true,
|
|
47
|
+
content: [
|
|
48
|
+
{ type: 'text', text: `Unknown tool: ${request.params.name}` },
|
|
49
|
+
],
|
|
50
|
+
_meta: {
|
|
51
|
+
errorCode: 'UNKNOWN_TOOL',
|
|
52
|
+
hint: `Available tools: ${tools.map((t) => t.name).join(', ')}`,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const result = await tool.handler(request.params.arguments ?? {}, { cwd });
|
|
58
|
+
return {
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
61
|
+
type: 'text',
|
|
62
|
+
text: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
structuredContent: result,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const error = err;
|
|
70
|
+
return {
|
|
71
|
+
isError: true,
|
|
72
|
+
content: [
|
|
73
|
+
{ type: 'text', text: error.message ?? 'Tool invocation failed' },
|
|
74
|
+
],
|
|
75
|
+
_meta: {
|
|
76
|
+
errorCode: error.errorCode ?? 'TOOL_FAILED',
|
|
77
|
+
...(error.hint ? { hint: error.hint } : {}),
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
83
|
+
return {
|
|
84
|
+
resources: listResources({
|
|
85
|
+
cwd,
|
|
86
|
+
hasPlan: detection.plan !== null,
|
|
87
|
+
hasSites: detection.site !== null,
|
|
88
|
+
}),
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
92
|
+
try {
|
|
93
|
+
const content = await readResource(request.params.uri, { cwd });
|
|
94
|
+
return { contents: [content] };
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
const error = err;
|
|
98
|
+
throw new Error(error.message ?? 'Failed to read resource');
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
return server;
|
|
102
|
+
}
|
|
103
|
+
export async function runStdioServer(options = {}) {
|
|
104
|
+
const server = await createServer(options);
|
|
105
|
+
const transport = new StdioServerTransport();
|
|
106
|
+
await server.connect(transport);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core refrakt CLI tools, exposed as MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Each tool delegates to the same underlying logic the `refrakt` CLI uses,
|
|
5
|
+
* but produces structured JSON output suitable for MCP. Where the underlying
|
|
6
|
+
* CLI command prints to stdout (rather than returning data), the tool here
|
|
7
|
+
* captures stdout via a child-process spawn — the cost is one extra fork per
|
|
8
|
+
* call but it preserves the exact output the user would see.
|
|
9
|
+
*/
|
|
10
|
+
import type { JSONSchema7 } from '@refrakt-md/types';
|
|
11
|
+
/** Shared shape exported by the MCP server for each registered tool. */
|
|
12
|
+
export interface McpTool {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: JSONSchema7;
|
|
16
|
+
handler: (input: unknown, ctx: {
|
|
17
|
+
cwd: string;
|
|
18
|
+
}) => Promise<unknown>;
|
|
19
|
+
}
|
|
20
|
+
export declare const referenceTool: McpTool;
|
|
21
|
+
export declare const contractsTool: McpTool;
|
|
22
|
+
export declare const inspectTool: McpTool;
|
|
23
|
+
export declare const inspectListTool: McpTool;
|
|
24
|
+
export declare const pluginsListTool: McpTool;
|
|
25
|
+
export declare const detectTool: McpTool;
|
|
26
|
+
export declare const CORE_TOOLS: McpTool[];
|
|
27
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/tools/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,wEAAwE;AACxE,MAAM,WAAW,OAAO;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAWD,eAAO,MAAM,aAAa,EAAE,OAwB3B,CAAC;AAMF,eAAO,MAAM,aAAa,EAAE,OAsB3B,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,OA8BzB,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,OAc7B,CAAC;AAMF,eAAO,MAAM,eAAe,EAAE,OAO7B,CAAC;AAMF,eAAO,MAAM,UAAU,EAAE,OAQxB,CAAC;AAMF,eAAO,MAAM,UAAU,EAAE,OAAO,EAO/B,CAAC"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core refrakt CLI tools, exposed as MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Each tool delegates to the same underlying logic the `refrakt` CLI uses,
|
|
5
|
+
* but produces structured JSON output suitable for MCP. Where the underlying
|
|
6
|
+
* CLI command prints to stdout (rather than returning data), the tool here
|
|
7
|
+
* captures stdout via a child-process spawn — the cost is one extra fork per
|
|
8
|
+
* call but it preserves the exact output the user would see.
|
|
9
|
+
*/
|
|
10
|
+
import { execFileSync } from 'node:child_process';
|
|
11
|
+
import { resolve } from 'node:path';
|
|
12
|
+
import { createRequire } from 'node:module';
|
|
13
|
+
const require_ = createRequire(import.meta.url);
|
|
14
|
+
const siteProp = {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Site name (required for multi-site projects).',
|
|
17
|
+
};
|
|
18
|
+
// ----------------------------------------------------------------------------
|
|
19
|
+
// refrakt.reference — emit the rune syntax reference
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
|
+
export const referenceTool = {
|
|
22
|
+
name: 'refrakt.reference',
|
|
23
|
+
description: 'Emit the rune syntax reference for the active package set. Useful for AI agents that need to know which runes are available and how to use them.',
|
|
24
|
+
inputSchema: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
properties: {
|
|
27
|
+
format: { type: 'string', enum: ['markdown', 'json'], description: 'Output format. Default: json.' },
|
|
28
|
+
site: siteProp,
|
|
29
|
+
rune: { type: 'string', description: 'When set, emit reference for a single rune by name.' },
|
|
30
|
+
},
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
},
|
|
33
|
+
async handler(input, ctx) {
|
|
34
|
+
const o = input;
|
|
35
|
+
const args = ['reference'];
|
|
36
|
+
if (o.rune)
|
|
37
|
+
args.push(o.rune);
|
|
38
|
+
args.push('--format', o.format ?? 'json');
|
|
39
|
+
if (o.site)
|
|
40
|
+
args.push('--site', o.site);
|
|
41
|
+
const stdout = invokeCli(args, ctx.cwd);
|
|
42
|
+
return o.format === 'markdown'
|
|
43
|
+
? { format: 'markdown', text: stdout }
|
|
44
|
+
: tryParseJson(stdout);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
// ----------------------------------------------------------------------------
|
|
48
|
+
// refrakt.contracts — generate structure contracts JSON
|
|
49
|
+
// ----------------------------------------------------------------------------
|
|
50
|
+
export const contractsTool = {
|
|
51
|
+
name: 'refrakt.contracts',
|
|
52
|
+
description: 'Generate the full structure contract for the active rune set: per-rune BEM block, modifiers, data attributes, structural elements. Useful for theme authors and CSS coverage tooling.',
|
|
53
|
+
inputSchema: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
site: siteProp,
|
|
57
|
+
},
|
|
58
|
+
additionalProperties: false,
|
|
59
|
+
},
|
|
60
|
+
async handler(input, ctx) {
|
|
61
|
+
const o = input;
|
|
62
|
+
const args = ['contracts', '-o', '/dev/stdout'];
|
|
63
|
+
if (o.site)
|
|
64
|
+
args.push('--site', o.site);
|
|
65
|
+
const stdout = invokeCli(args, ctx.cwd);
|
|
66
|
+
// `refrakt contracts -o /dev/stdout` writes the JSON contract to stdout
|
|
67
|
+
// followed by a "Written ..." line on stderr — we only want the JSON.
|
|
68
|
+
const start = stdout.indexOf('{');
|
|
69
|
+
if (start === -1)
|
|
70
|
+
throw new Error('contracts produced no JSON output');
|
|
71
|
+
return JSON.parse(stdout.slice(start));
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
// ----------------------------------------------------------------------------
|
|
75
|
+
// refrakt.inspect — see the identity transform output for a rune
|
|
76
|
+
// ----------------------------------------------------------------------------
|
|
77
|
+
export const inspectTool = {
|
|
78
|
+
name: 'refrakt.inspect',
|
|
79
|
+
description: 'Show the identity transform output for a rune: the HTML it produces with BEM classes and data attributes for a given attribute set. Returns the JSON view (--json) so MCP clients can consume the structured contract.',
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
required: ['rune'],
|
|
83
|
+
properties: {
|
|
84
|
+
rune: { type: 'string', description: 'Rune name (e.g. "hint", "hero").' },
|
|
85
|
+
attributes: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
additionalProperties: { type: 'string' },
|
|
88
|
+
description: 'Rune attributes to set (e.g. { type: "warning" }).',
|
|
89
|
+
},
|
|
90
|
+
site: siteProp,
|
|
91
|
+
},
|
|
92
|
+
additionalProperties: false,
|
|
93
|
+
},
|
|
94
|
+
async handler(input, ctx) {
|
|
95
|
+
const o = input;
|
|
96
|
+
const args = ['inspect', o.rune, '--json'];
|
|
97
|
+
if (o.attributes) {
|
|
98
|
+
for (const [k, v] of Object.entries(o.attributes)) {
|
|
99
|
+
args.push(`--${k}=${v}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (o.site)
|
|
103
|
+
args.push('--site', o.site);
|
|
104
|
+
const stdout = invokeCli(args, ctx.cwd);
|
|
105
|
+
return tryParseJson(stdout);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
// ----------------------------------------------------------------------------
|
|
109
|
+
// refrakt.inspect_list — list all available runes
|
|
110
|
+
// ----------------------------------------------------------------------------
|
|
111
|
+
export const inspectListTool = {
|
|
112
|
+
name: 'refrakt.inspect_list',
|
|
113
|
+
description: 'List every rune available in the active package set.',
|
|
114
|
+
inputSchema: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: { site: siteProp },
|
|
117
|
+
additionalProperties: false,
|
|
118
|
+
},
|
|
119
|
+
async handler(input, ctx) {
|
|
120
|
+
const o = input;
|
|
121
|
+
const args = ['inspect', '--list', '--json'];
|
|
122
|
+
if (o.site)
|
|
123
|
+
args.push('--site', o.site);
|
|
124
|
+
return tryParseJson(invokeCli(args, ctx.cwd));
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
// ----------------------------------------------------------------------------
|
|
128
|
+
// refrakt.plugins_list — list installed plugins
|
|
129
|
+
// ----------------------------------------------------------------------------
|
|
130
|
+
export const pluginsListTool = {
|
|
131
|
+
name: 'refrakt.plugins_list',
|
|
132
|
+
description: 'List installed refrakt plugin packages with their commands and MCP schema availability.',
|
|
133
|
+
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
134
|
+
async handler(_input, ctx) {
|
|
135
|
+
return tryParseJson(invokeCli(['plugins', 'list', '--json'], ctx.cwd));
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
// ----------------------------------------------------------------------------
|
|
139
|
+
// refrakt.detect — return the detection result (also exposed as a resource)
|
|
140
|
+
// ----------------------------------------------------------------------------
|
|
141
|
+
export const detectTool = {
|
|
142
|
+
name: 'refrakt.detect',
|
|
143
|
+
description: 'Report the detected refrakt context (plan dir, declared sites, installed plugins, config source).',
|
|
144
|
+
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
145
|
+
async handler(_input, ctx) {
|
|
146
|
+
const { detect } = await import('../detect.js');
|
|
147
|
+
return detect(ctx.cwd);
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
// ----------------------------------------------------------------------------
|
|
151
|
+
// Aggregate set
|
|
152
|
+
// ----------------------------------------------------------------------------
|
|
153
|
+
export const CORE_TOOLS = [
|
|
154
|
+
detectTool,
|
|
155
|
+
pluginsListTool,
|
|
156
|
+
referenceTool,
|
|
157
|
+
contractsTool,
|
|
158
|
+
inspectTool,
|
|
159
|
+
inspectListTool,
|
|
160
|
+
];
|
|
161
|
+
// ----------------------------------------------------------------------------
|
|
162
|
+
// Helpers
|
|
163
|
+
// ----------------------------------------------------------------------------
|
|
164
|
+
/** Resolve and invoke the refrakt CLI bin, returning stdout. Throws with the
|
|
165
|
+
* CLI's stderr on non-zero exit so the MCP handler surfaces the user-facing
|
|
166
|
+
* error message. */
|
|
167
|
+
function invokeCli(args, cwd) {
|
|
168
|
+
const bin = resolveCliBin();
|
|
169
|
+
try {
|
|
170
|
+
return execFileSync('node', [bin, ...args], {
|
|
171
|
+
encoding: 'utf-8',
|
|
172
|
+
cwd,
|
|
173
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
174
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
catch (err) {
|
|
178
|
+
const stderr = (err.stderr ?? '').toString();
|
|
179
|
+
const stdout = (err.stdout ?? '').toString();
|
|
180
|
+
const message = stderr || stdout || err.message;
|
|
181
|
+
const wrapped = new Error(`refrakt ${args[0]} failed: ${message.trim()}`);
|
|
182
|
+
wrapped.errorCode = 'CLI_INVOCATION_FAILED';
|
|
183
|
+
throw wrapped;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function resolveCliBin() {
|
|
187
|
+
// Resolve via package.json bin entry. Fall back to direct dist path for
|
|
188
|
+
// monorepo workspace setups where the package may not be globally linked.
|
|
189
|
+
try {
|
|
190
|
+
const pkgJsonPath = require_.resolve('@refrakt-md/cli/package.json');
|
|
191
|
+
const pkgDir = pkgJsonPath.replace(/[\/\\]package\.json$/, '');
|
|
192
|
+
return resolve(pkgDir, 'dist', 'bin.js');
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Last-resort: assume the bin is on PATH (works in installed projects).
|
|
196
|
+
return 'refrakt';
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function tryParseJson(text) {
|
|
200
|
+
const trimmed = text.trim();
|
|
201
|
+
if (!trimmed)
|
|
202
|
+
return null;
|
|
203
|
+
try {
|
|
204
|
+
return JSON.parse(trimmed);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// Some CLI commands print extra lines around the JSON; pull the first
|
|
208
|
+
// JSON-shaped substring.
|
|
209
|
+
const start = trimmed.indexOf('{');
|
|
210
|
+
const arrStart = trimmed.indexOf('[');
|
|
211
|
+
const idx = start === -1 ? arrStart : arrStart === -1 ? start : Math.min(start, arrStart);
|
|
212
|
+
if (idx === -1)
|
|
213
|
+
return { raw: trimmed };
|
|
214
|
+
return JSON.parse(trimmed.slice(idx));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/tools/core.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAUhD,MAAM,QAAQ,GAAgB;IAC7B,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,+CAA+C;CAC5D,CAAC;AAEF,+EAA+E;AAC/E,sDAAsD;AACtD,+EAA+E;AAE/E,MAAM,CAAC,MAAM,aAAa,GAAY;IACrC,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACV,kJAAkJ;IACnJ,WAAW,EAAE;QACZ,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACX,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE;YACpG,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qDAAqD,EAAE;SAC5F;QACD,oBAAoB,EAAE,KAAK;KAC3B;IACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACvB,MAAM,CAAC,GAAG,KAA0D,CAAC;QACrE,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU;YAC7B,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;YACtC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;CACD,CAAC;AAEF,+EAA+E;AAC/E,wDAAwD;AACxD,+EAA+E;AAE/E,MAAM,CAAC,MAAM,aAAa,GAAY;IACrC,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACV,uLAAuL;IACxL,WAAW,EAAE;QACZ,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACX,IAAI,EAAE,QAAQ;SACd;QACD,oBAAoB,EAAE,KAAK;KAC3B;IACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACvB,MAAM,CAAC,GAAG,KAA0B,CAAC;QACrC,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,wEAAwE;QACxE,sEAAsE;QACtE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC;CACD,CAAC;AAEF,+EAA+E;AAC/E,iEAAiE;AACjE,+EAA+E;AAE/E,MAAM,CAAC,MAAM,WAAW,GAAY;IACnC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACV,wNAAwN;IACzN,WAAW,EAAE;QACZ,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,UAAU,EAAE;YACX,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;YACzE,UAAU,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACxC,WAAW,EAAE,oDAAoD;aACjE;YACD,IAAI,EAAE,QAAQ;SACd;QACD,oBAAoB,EAAE,KAAK;KAC3B;IACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACvB,MAAM,CAAC,GAAG,KAA6E,CAAC;QACxF,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1B,CAAC;QACF,CAAC;QACD,IAAI,CAAC,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;CACD,CAAC;AAEF,+EAA+E;AAC/E,kDAAkD;AAClD,+EAA+E;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAY;IACvC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,sDAAsD;IACnE,WAAW,EAAE;QACZ,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC9B,oBAAoB,EAAE,KAAK;KAC3B;IACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACvB,MAAM,CAAC,GAAG,KAA0B,CAAC;QACrC,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;CACD,CAAC;AAEF,+EAA+E;AAC/E,gDAAgD;AAChD,+EAA+E;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAY;IACvC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,yFAAyF;IACtG,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE;IAC5E,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QACxB,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACxE,CAAC;CACD,CAAC;AAEF,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAE/E,MAAM,CAAC,MAAM,UAAU,GAAY;IAClC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,mGAAmG;IAChH,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE;IAC5E,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG;QACxB,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAChD,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;CACD,CAAC;AAEF,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,MAAM,CAAC,MAAM,UAAU,GAAc;IACpC,UAAU;IACV,eAAe;IACf,aAAa;IACb,aAAa;IACb,WAAW;IACX,eAAe;CACf,CAAC;AAEF,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E;;qBAEqB;AACrB,SAAS,SAAS,CAAC,IAAc,EAAE,GAAW;IAC7C,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC;QACJ,OAAO,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE;YAC3C,QAAQ,EAAE,OAAO;YACjB,GAAG;YACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;SAC3B,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,YAAY,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzE,OAAkC,CAAC,SAAS,GAAG,uBAAuB,CAAC;QACxE,MAAM,OAAO,CAAC;IACf,CAAC;AACF,CAAC;AAED,SAAS,aAAa;IACrB,wEAAwE;IACxE,0EAA0E;IAC1E,IAAI,CAAC;QACJ,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QACrE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACR,wEAAwE;QACxE,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACR,sEAAsE;QACtE,yBAAyB;QACzB,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC1F,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin-contributed MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Each command from a discovered plugin (e.g. @refrakt-md/plan) becomes an
|
|
5
|
+
* MCP tool under `<namespace>.<name>`. Commands that declare an `mcpHandler`
|
|
6
|
+
* are invoked directly with the structured input. Commands without one fall
|
|
7
|
+
* back to argv-shimming: the handler receives an object, we serialize it into
|
|
8
|
+
* argv strings, and call the existing CLI handler.
|
|
9
|
+
*/
|
|
10
|
+
import type { McpTool } from './core.js';
|
|
11
|
+
/** Discover installed plugins and convert each command into an MCP tool. */
|
|
12
|
+
export declare function loadPluginTools(cwd: string): Promise<McpTool[]>;
|
|
13
|
+
//# sourceMappingURL=plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/tools/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,4EAA4E;AAC5E,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAWrE"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin-contributed MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Each command from a discovered plugin (e.g. @refrakt-md/plan) becomes an
|
|
5
|
+
* MCP tool under `<namespace>.<name>`. Commands that declare an `mcpHandler`
|
|
6
|
+
* are invoked directly with the structured input. Commands without one fall
|
|
7
|
+
* back to argv-shimming: the handler receives an object, we serialize it into
|
|
8
|
+
* argv strings, and call the existing CLI handler.
|
|
9
|
+
*/
|
|
10
|
+
import { discoverPlugins } from '@refrakt-md/cli/lib/plugins.js';
|
|
11
|
+
/** Commands that should not be exposed via MCP — long-running servers,
|
|
12
|
+
* filesystem generators, etc. that don't fit the request/response model. */
|
|
13
|
+
const EXCLUDED_COMMANDS = new Set([
|
|
14
|
+
'plan.serve',
|
|
15
|
+
'plan.build',
|
|
16
|
+
]);
|
|
17
|
+
/** Discover installed plugins and convert each command into an MCP tool. */
|
|
18
|
+
export async function loadPluginTools(cwd) {
|
|
19
|
+
const discovered = await discoverPlugins({ cwd, warn: false });
|
|
20
|
+
const tools = [];
|
|
21
|
+
for (const plugin of discovered) {
|
|
22
|
+
for (const command of plugin.commands) {
|
|
23
|
+
const toolName = `${plugin.namespace}.${command.name}`;
|
|
24
|
+
if (EXCLUDED_COMMANDS.has(toolName))
|
|
25
|
+
continue;
|
|
26
|
+
tools.push(buildPluginTool(toolName, command));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return tools;
|
|
30
|
+
}
|
|
31
|
+
function buildPluginTool(name, command) {
|
|
32
|
+
const inputSchema = command.inputSchema ?? {
|
|
33
|
+
type: 'object',
|
|
34
|
+
additionalProperties: true,
|
|
35
|
+
description: 'Free-form arguments — this command has no inputSchema yet, so MCP cannot validate inputs.',
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
name,
|
|
39
|
+
description: command.description,
|
|
40
|
+
inputSchema,
|
|
41
|
+
handler: async (input) => {
|
|
42
|
+
if (command.mcpHandler) {
|
|
43
|
+
return command.mcpHandler(input);
|
|
44
|
+
}
|
|
45
|
+
// Fallback: serialize the input as argv and invoke the legacy
|
|
46
|
+
// handler. Captures stdout via a simple buffer hack.
|
|
47
|
+
const args = inputToArgv(input);
|
|
48
|
+
const captured = await captureStdout(() => command.handler(args));
|
|
49
|
+
return tryParseJson(captured);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Translate a structured input object into a flat argv array suitable for
|
|
54
|
+
* legacy `handler(args)` consumption. Boolean true → bare flag; everything
|
|
55
|
+
* else → `--key`, `value` pair. Nested objects/arrays are JSON-stringified. */
|
|
56
|
+
function inputToArgv(input) {
|
|
57
|
+
if (!input || typeof input !== 'object')
|
|
58
|
+
return [];
|
|
59
|
+
const args = [];
|
|
60
|
+
for (const [key, value] of Object.entries(input)) {
|
|
61
|
+
if (value === undefined || value === null)
|
|
62
|
+
continue;
|
|
63
|
+
if (value === true) {
|
|
64
|
+
args.push(`--${key}`);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (value === false)
|
|
68
|
+
continue;
|
|
69
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
70
|
+
args.push(`--${key}`, String(value));
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
args.push(`--${key}`, JSON.stringify(value));
|
|
74
|
+
}
|
|
75
|
+
return args;
|
|
76
|
+
}
|
|
77
|
+
/** Capture writes to process.stdout while running fn(). Restores stdout when
|
|
78
|
+
* done. Used as the legacy-handler fallback because most plugin commands
|
|
79
|
+
* print structured JSON to stdout when given `--format json`. */
|
|
80
|
+
async function captureStdout(fn) {
|
|
81
|
+
const chunks = [];
|
|
82
|
+
const originalWrite = process.stdout.write.bind(process.stdout);
|
|
83
|
+
process.stdout.write = (chunk) => {
|
|
84
|
+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
|
|
85
|
+
return true;
|
|
86
|
+
};
|
|
87
|
+
try {
|
|
88
|
+
await fn();
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
process.stdout.write = originalWrite;
|
|
92
|
+
}
|
|
93
|
+
return Buffer.concat(chunks).toString('utf-8');
|
|
94
|
+
}
|
|
95
|
+
function tryParseJson(text) {
|
|
96
|
+
const trimmed = text.trim();
|
|
97
|
+
if (!trimmed)
|
|
98
|
+
return null;
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(trimmed);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return { raw: trimmed };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/tools/plugins.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@refrakt-md/mcp",
|
|
3
|
+
"description": "Model Context Protocol server wrapping the refrakt CLI",
|
|
4
|
+
"version": "0.10.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/refrakt-md/refrakt.git",
|
|
10
|
+
"directory": "packages/mcp"
|
|
11
|
+
},
|
|
12
|
+
"bugs": "https://github.com/refrakt-md/refrakt/issues",
|
|
13
|
+
"homepage": "https://github.com/refrakt-md/refrakt",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"refrakt-mcp": "./dist/bin.js"
|
|
19
|
+
},
|
|
20
|
+
"main": "dist/index.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"default": "./dist/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
36
|
+
"@refrakt-md/cli": "0.10.1",
|
|
37
|
+
"@refrakt-md/runes": "0.10.1",
|
|
38
|
+
"@refrakt-md/transform": "0.10.1",
|
|
39
|
+
"@refrakt-md/types": "0.10.1"
|
|
40
|
+
}
|
|
41
|
+
}
|