@master/css-mcp 2.0.0-rc.76
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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/bin/index.d.ts +1 -0
- package/dist/bin/index.js +60 -0
- package/dist/context.d.ts +60 -0
- package/dist/context.js +189 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/language.d.ts +25 -0
- package/dist/language.js +46 -0
- package/dist/lint.d.ts +56 -0
- package/dist/lint.js +132 -0
- package/dist/project.d.ts +32 -0
- package/dist/project.js +42 -0
- package/dist/result.d.ts +9 -0
- package/dist/result.js +22 -0
- package/dist/scan.d.ts +157 -0
- package/dist/scan.js +126 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.js +244 -0
- package/package.json +73 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import MasterCSSMCPContext from "./context.js";
|
|
2
|
+
|
|
3
|
+
//#region src/project.d.ts
|
|
4
|
+
declare function loadWorkspaceManifest(context: MasterCSSMCPContext): Promise<{
|
|
5
|
+
status: "loaded";
|
|
6
|
+
manifest: import("@master/css-engine").MasterCSSManifest;
|
|
7
|
+
entries: string[];
|
|
8
|
+
dependencies: string[];
|
|
9
|
+
warnings: string[];
|
|
10
|
+
error?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
status: "error";
|
|
13
|
+
entries: string[];
|
|
14
|
+
dependencies: string[];
|
|
15
|
+
warnings: string[];
|
|
16
|
+
error: string;
|
|
17
|
+
manifest?: undefined;
|
|
18
|
+
}>;
|
|
19
|
+
declare function getWorkspaceInfo(context: MasterCSSMCPContext): Promise<{
|
|
20
|
+
root: string;
|
|
21
|
+
roots: string[];
|
|
22
|
+
packages: import("@master/css-project/workspace").MasterCSSWorkspacePackageResolution;
|
|
23
|
+
manifest: {
|
|
24
|
+
error?: string | undefined;
|
|
25
|
+
status: "loaded" | "error";
|
|
26
|
+
entries: string[];
|
|
27
|
+
dependencies: string[];
|
|
28
|
+
warnings: string[];
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { getWorkspaceInfo, loadWorkspaceManifest };
|
package/dist/project.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { getErrorMessage } from "./result.js";
|
|
2
|
+
import { loadProjectManifest } from "@master/css-project/manifest";
|
|
3
|
+
import { findCSSManifestEntryFiles } from "@master/css-project/entries";
|
|
4
|
+
import { resolveMasterCSSWorkspacePackages } from "@master/css-project/workspace";
|
|
5
|
+
//#region src/project.ts
|
|
6
|
+
async function loadWorkspaceManifest(context) {
|
|
7
|
+
try {
|
|
8
|
+
const result = await loadProjectManifest(context.root);
|
|
9
|
+
return {
|
|
10
|
+
status: "loaded",
|
|
11
|
+
manifest: result.manifest,
|
|
12
|
+
entries: result.entries,
|
|
13
|
+
dependencies: result.dependencies ?? [],
|
|
14
|
+
warnings: result.warnings ?? []
|
|
15
|
+
};
|
|
16
|
+
} catch (error) {
|
|
17
|
+
return {
|
|
18
|
+
status: "error",
|
|
19
|
+
entries: [],
|
|
20
|
+
dependencies: [],
|
|
21
|
+
warnings: [],
|
|
22
|
+
error: getErrorMessage(error)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function getWorkspaceInfo(context) {
|
|
27
|
+
const [manifest, entries] = await Promise.all([loadWorkspaceManifest(context), findCSSManifestEntryFiles(context.root).catch(() => [])]);
|
|
28
|
+
return {
|
|
29
|
+
root: context.root,
|
|
30
|
+
roots: context.roots,
|
|
31
|
+
packages: resolveMasterCSSWorkspacePackages(context.root),
|
|
32
|
+
manifest: {
|
|
33
|
+
status: manifest.status,
|
|
34
|
+
entries: manifest.status === "loaded" ? manifest.entries : entries,
|
|
35
|
+
dependencies: manifest.dependencies,
|
|
36
|
+
warnings: manifest.warnings,
|
|
37
|
+
...manifest.status === "error" ? { error: manifest.error } : {}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { getWorkspaceInfo, loadWorkspaceManifest };
|
package/dist/result.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CallToolResult, ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/result.d.ts
|
|
4
|
+
declare function toJSONText(value: unknown): string;
|
|
5
|
+
declare function jsonToolResult(value: unknown): CallToolResult;
|
|
6
|
+
declare function jsonResourceResult(uri: URL | string, value: unknown): ReadResourceResult;
|
|
7
|
+
declare function getErrorMessage(error: unknown): string;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { getErrorMessage, jsonResourceResult, jsonToolResult, toJSONText };
|
package/dist/result.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/result.ts
|
|
2
|
+
function toJSONText(value) {
|
|
3
|
+
return JSON.stringify(value, null, 2);
|
|
4
|
+
}
|
|
5
|
+
function jsonToolResult(value) {
|
|
6
|
+
return { content: [{
|
|
7
|
+
type: "text",
|
|
8
|
+
text: toJSONText(value)
|
|
9
|
+
}] };
|
|
10
|
+
}
|
|
11
|
+
function jsonResourceResult(uri, value) {
|
|
12
|
+
return { contents: [{
|
|
13
|
+
uri: String(uri),
|
|
14
|
+
mimeType: "application/json",
|
|
15
|
+
text: toJSONText(value)
|
|
16
|
+
}] };
|
|
17
|
+
}
|
|
18
|
+
function getErrorMessage(error) {
|
|
19
|
+
return error instanceof Error ? error.message : String(error);
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { getErrorMessage, jsonResourceResult, jsonToolResult, toJSONText };
|
package/dist/scan.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import MasterCSSMCPContext from "./context.js";
|
|
2
|
+
|
|
3
|
+
//#region src/scan.d.ts
|
|
4
|
+
interface ScanProjectOptions {
|
|
5
|
+
patterns?: string[];
|
|
6
|
+
classes?: string[];
|
|
7
|
+
includeCss?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface RenderCSSOptions {
|
|
10
|
+
html?: string;
|
|
11
|
+
classList?: string;
|
|
12
|
+
}
|
|
13
|
+
interface InspectClassOptions {
|
|
14
|
+
className: string;
|
|
15
|
+
mode?: string;
|
|
16
|
+
}
|
|
17
|
+
declare function resolveSourceFiles(context: MasterCSSMCPContext, patterns?: string[], ignore?: string[]): Promise<string[]>;
|
|
18
|
+
declare function scanProject(context: MasterCSSMCPContext, options?: ScanProjectOptions): Promise<{
|
|
19
|
+
root: string;
|
|
20
|
+
manifest: {
|
|
21
|
+
error?: string | undefined;
|
|
22
|
+
status: "loaded" | "error";
|
|
23
|
+
entries: string[];
|
|
24
|
+
dependencies: string[];
|
|
25
|
+
warnings: string[];
|
|
26
|
+
};
|
|
27
|
+
version: typeof import("@master/css-diagnostics").MASTER_CSS_INSPECTION_REPORT_VERSION;
|
|
28
|
+
cwd: string;
|
|
29
|
+
inputs: {
|
|
30
|
+
patterns: string[];
|
|
31
|
+
files: string[];
|
|
32
|
+
classes: string[];
|
|
33
|
+
};
|
|
34
|
+
scanner: {
|
|
35
|
+
counts: {
|
|
36
|
+
latent: number;
|
|
37
|
+
valid: number;
|
|
38
|
+
invalid: number;
|
|
39
|
+
native: number;
|
|
40
|
+
usedNative: number;
|
|
41
|
+
safelist: number;
|
|
42
|
+
blocklist: number;
|
|
43
|
+
};
|
|
44
|
+
classes: {
|
|
45
|
+
latent: string[];
|
|
46
|
+
valid: string[];
|
|
47
|
+
invalid: string[];
|
|
48
|
+
native: string[];
|
|
49
|
+
usedNative: string[];
|
|
50
|
+
safelist: string[];
|
|
51
|
+
blocklist: string[];
|
|
52
|
+
};
|
|
53
|
+
resetDependencies: string[];
|
|
54
|
+
};
|
|
55
|
+
stylesheets: {
|
|
56
|
+
entries: import("@master/css-diagnostics").MasterCSSStylesheetInspection[];
|
|
57
|
+
dependencies: string[];
|
|
58
|
+
warnings: string[];
|
|
59
|
+
errors: import("@master/css-diagnostics").MasterCSSStylesheetError[];
|
|
60
|
+
};
|
|
61
|
+
css: {
|
|
62
|
+
bytes: number;
|
|
63
|
+
included: boolean;
|
|
64
|
+
text?: string;
|
|
65
|
+
emittedGlobals: {
|
|
66
|
+
variables: number;
|
|
67
|
+
animations: number;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
missingCSS: {
|
|
71
|
+
checked: string[];
|
|
72
|
+
present: import("@master/css-diagnostics").MasterCSSMissingCSSResult[];
|
|
73
|
+
missing: import("@master/css-diagnostics").MasterCSSMissingCSSResult[];
|
|
74
|
+
};
|
|
75
|
+
files: import("@master/css-diagnostics").MasterCSSSourceInspection[];
|
|
76
|
+
diagnostics: import("@master/css-diagnostics").MasterCSSInspectionDiagnostic[];
|
|
77
|
+
summary: {
|
|
78
|
+
files: number;
|
|
79
|
+
stylesheets: number;
|
|
80
|
+
diagnostics: number;
|
|
81
|
+
errors: number;
|
|
82
|
+
warnings: number;
|
|
83
|
+
missingCSS: number;
|
|
84
|
+
invalidClasses: number;
|
|
85
|
+
};
|
|
86
|
+
}>;
|
|
87
|
+
declare function renderCSS(context: MasterCSSMCPContext, options: RenderCSSOptions): Promise<{
|
|
88
|
+
manifest: {
|
|
89
|
+
error?: string | undefined;
|
|
90
|
+
status: "loaded" | "error";
|
|
91
|
+
entries: string[];
|
|
92
|
+
};
|
|
93
|
+
classes: string[];
|
|
94
|
+
invalid: string[];
|
|
95
|
+
css: {
|
|
96
|
+
bytes: number;
|
|
97
|
+
text: string;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
100
|
+
declare function inspectClass(context: MasterCSSMCPContext, options: InspectClassOptions): Promise<{
|
|
101
|
+
manifest: {
|
|
102
|
+
error?: string | undefined;
|
|
103
|
+
status: "loaded" | "error";
|
|
104
|
+
entries: string[];
|
|
105
|
+
};
|
|
106
|
+
className: string;
|
|
107
|
+
mode: string | undefined;
|
|
108
|
+
valid: boolean;
|
|
109
|
+
base: string;
|
|
110
|
+
suffix: string;
|
|
111
|
+
key: string | undefined;
|
|
112
|
+
value: string | undefined;
|
|
113
|
+
keyToken: string | undefined;
|
|
114
|
+
valueToken: string | undefined;
|
|
115
|
+
stateToken: string | undefined;
|
|
116
|
+
important: boolean | undefined;
|
|
117
|
+
matcherTypes: ("key" | "static" | "pattern" | "variable" | "value")[];
|
|
118
|
+
variables: {
|
|
119
|
+
key: string;
|
|
120
|
+
variable: import("@master/css-language").Variable;
|
|
121
|
+
}[];
|
|
122
|
+
rules: {
|
|
123
|
+
className: string;
|
|
124
|
+
layer: import("@master/css-engine").MasterCSSManifestUtilityLayerName;
|
|
125
|
+
type: import("@master/css-language").UtilityType;
|
|
126
|
+
text: string;
|
|
127
|
+
}[];
|
|
128
|
+
css: string;
|
|
129
|
+
}>;
|
|
130
|
+
declare function previewGeneratedCSS(context: MasterCSSMCPContext, options: ScanProjectOptions & {
|
|
131
|
+
outputPath: string;
|
|
132
|
+
ttlMs?: number;
|
|
133
|
+
}): Promise<{
|
|
134
|
+
mode: string;
|
|
135
|
+
outputPath: string;
|
|
136
|
+
preview: import("./context.js").PreviewResult;
|
|
137
|
+
scan: {
|
|
138
|
+
summary: {
|
|
139
|
+
files: number;
|
|
140
|
+
stylesheets: number;
|
|
141
|
+
diagnostics: number;
|
|
142
|
+
errors: number;
|
|
143
|
+
warnings: number;
|
|
144
|
+
missingCSS: number;
|
|
145
|
+
invalidClasses: number;
|
|
146
|
+
};
|
|
147
|
+
css: {
|
|
148
|
+
bytes: number;
|
|
149
|
+
emittedGlobals: {
|
|
150
|
+
variables: number;
|
|
151
|
+
animations: number;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
}>;
|
|
156
|
+
//#endregion
|
|
157
|
+
export { InspectClassOptions, RenderCSSOptions, ScanProjectOptions, inspectClass, previewGeneratedCSS, renderCSS, resolveSourceFiles, scanProject };
|
package/dist/scan.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { loadWorkspaceManifest } from "./project.js";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import fg from "fast-glob";
|
|
5
|
+
import { createMasterCSSInspectionReport } from "@master/css-diagnostics";
|
|
6
|
+
import { inspectMasterCSSClass } from "@master/css-engine/inspect";
|
|
7
|
+
import { createCSSWithNativeDeclarations } from "@master/css-validator/native-declaration";
|
|
8
|
+
import { parseHTML } from "@master/css-server";
|
|
9
|
+
//#region src/scan.ts
|
|
10
|
+
const DEFAULT_SOURCE_PATTERNS = ["**/*.{html,htm,js,jsx,cjs,ts,tsx,mts,cts,svelte,astro,vue,md,mdx,pug,php}"];
|
|
11
|
+
const DEFAULT_IGNORE_PATTERNS = ["**/node_modules/**", "node_modules"];
|
|
12
|
+
const defaultManifest = createRequire(import.meta.url)("@master/css-preset/default-manifest.json");
|
|
13
|
+
async function resolveSourceFiles(context, patterns = DEFAULT_SOURCE_PATTERNS, ignore = DEFAULT_IGNORE_PATTERNS) {
|
|
14
|
+
context.validateGlobPatterns(patterns);
|
|
15
|
+
const sources = await fg(patterns, {
|
|
16
|
+
cwd: context.root,
|
|
17
|
+
ignore,
|
|
18
|
+
onlyFiles: true
|
|
19
|
+
});
|
|
20
|
+
return Promise.all(sources.map((source) => context.resolveExistingFile(source)));
|
|
21
|
+
}
|
|
22
|
+
async function scanProject(context, options = {}) {
|
|
23
|
+
const [report, manifest] = await Promise.all([createMasterCSSInspectionReport({
|
|
24
|
+
cwd: context.root,
|
|
25
|
+
patterns: options.patterns,
|
|
26
|
+
classes: options.classes,
|
|
27
|
+
includeCss: options.includeCss,
|
|
28
|
+
resolveExistingFile: (filePath) => context.resolveExistingFile(filePath),
|
|
29
|
+
validatePatterns: (patterns) => context.validateGlobPatterns(patterns)
|
|
30
|
+
}), loadWorkspaceManifest(context)]);
|
|
31
|
+
return {
|
|
32
|
+
...report,
|
|
33
|
+
root: context.root,
|
|
34
|
+
manifest: {
|
|
35
|
+
status: manifest.status,
|
|
36
|
+
entries: manifest.entries,
|
|
37
|
+
dependencies: manifest.dependencies,
|
|
38
|
+
warnings: manifest.warnings,
|
|
39
|
+
...manifest.status === "error" ? { error: manifest.error } : {}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
async function renderCSS(context, options) {
|
|
44
|
+
const manifest = await loadWorkspaceManifest(context);
|
|
45
|
+
const css = createCSSWithNativeDeclarations(manifest.status === "loaded" ? manifest.manifest : defaultManifest);
|
|
46
|
+
const classes = options.html ? parseHTML(options.html).classes : (options.classList ?? "").split(/\s+/).map((className) => className.trim()).filter(Boolean);
|
|
47
|
+
const invalid = [];
|
|
48
|
+
for (const className of classes) {
|
|
49
|
+
const rules = css.generate(className);
|
|
50
|
+
if (rules.length) for (const rule of rules) rule.layer.insert(rule);
|
|
51
|
+
else invalid.push(className);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
manifest: {
|
|
55
|
+
status: manifest.status,
|
|
56
|
+
entries: manifest.entries,
|
|
57
|
+
...manifest.status === "error" ? { error: manifest.error } : {}
|
|
58
|
+
},
|
|
59
|
+
classes,
|
|
60
|
+
invalid,
|
|
61
|
+
css: {
|
|
62
|
+
bytes: css.text.length,
|
|
63
|
+
text: css.text
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function inspectClass(context, options) {
|
|
68
|
+
const manifest = await loadWorkspaceManifest(context);
|
|
69
|
+
const inspection = inspectMasterCSSClass(createCSSWithNativeDeclarations(manifest.status === "loaded" ? manifest.manifest : defaultManifest), options.className, options.mode);
|
|
70
|
+
const rules = inspection.rules.map((rule) => ({
|
|
71
|
+
className: rule.name,
|
|
72
|
+
layer: rule.layerName,
|
|
73
|
+
type: rule.type,
|
|
74
|
+
text: rule.text
|
|
75
|
+
}));
|
|
76
|
+
return {
|
|
77
|
+
manifest: {
|
|
78
|
+
status: manifest.status,
|
|
79
|
+
entries: manifest.entries,
|
|
80
|
+
...manifest.status === "error" ? { error: manifest.error } : {}
|
|
81
|
+
},
|
|
82
|
+
className: options.className,
|
|
83
|
+
mode: options.mode,
|
|
84
|
+
valid: rules.length > 0,
|
|
85
|
+
base: inspection.base,
|
|
86
|
+
suffix: inspection.suffix,
|
|
87
|
+
key: inspection.key,
|
|
88
|
+
value: inspection.value,
|
|
89
|
+
keyToken: inspection.keyToken,
|
|
90
|
+
valueToken: inspection.valueToken,
|
|
91
|
+
stateToken: inspection.stateToken,
|
|
92
|
+
important: inspection.important,
|
|
93
|
+
matcherTypes: inspection.matcherTypes,
|
|
94
|
+
variables: inspection.variableEntries.map(({ key, variable }) => ({
|
|
95
|
+
key,
|
|
96
|
+
variable
|
|
97
|
+
})),
|
|
98
|
+
rules,
|
|
99
|
+
css: rules.map((rule) => rule.text).join("")
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function previewGeneratedCSS(context, options) {
|
|
103
|
+
const report = await scanProject(context, {
|
|
104
|
+
patterns: options.patterns,
|
|
105
|
+
classes: options.classes,
|
|
106
|
+
includeCss: true
|
|
107
|
+
});
|
|
108
|
+
const preview = await context.createPreview([{
|
|
109
|
+
filePath: resolve(context.root, options.outputPath),
|
|
110
|
+
afterText: report.css.text ?? ""
|
|
111
|
+
}], options.ttlMs);
|
|
112
|
+
return {
|
|
113
|
+
mode: "generated-css",
|
|
114
|
+
outputPath: await context.resolveWritableFile(options.outputPath),
|
|
115
|
+
preview,
|
|
116
|
+
scan: {
|
|
117
|
+
summary: report.summary,
|
|
118
|
+
css: {
|
|
119
|
+
bytes: report.css.bytes,
|
|
120
|
+
emittedGlobals: report.css.emittedGlobals
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
export { inspectClass, previewGeneratedCSS, renderCSS, resolveSourceFiles, scanProject };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import MasterCSSMCPContext, { MasterCSSMCPContextOptions } from "./context.js";
|
|
3
|
+
|
|
4
|
+
//#region src/server.d.ts
|
|
5
|
+
interface MasterCSSMCPServerInstance {
|
|
6
|
+
server: McpServer;
|
|
7
|
+
context: MasterCSSMCPContext;
|
|
8
|
+
}
|
|
9
|
+
declare function createMasterCSSMCPServer(options?: MasterCSSMCPContextOptions): MasterCSSMCPServerInstance;
|
|
10
|
+
declare function startStdioServer(options?: MasterCSSMCPContextOptions): Promise<McpServer>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { MasterCSSMCPServerInstance, createMasterCSSMCPServer, startStdioServer };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import MasterCSSMCPContext from "./context.js";
|
|
2
|
+
import { jsonResourceResult, jsonToolResult } from "./result.js";
|
|
3
|
+
import { getWorkspaceInfo, loadWorkspaceManifest } from "./project.js";
|
|
4
|
+
import { inspectClass, previewGeneratedCSS, renderCSS, scanProject } from "./scan.js";
|
|
5
|
+
import { suggestSyntax } from "./language.js";
|
|
6
|
+
import { lintContent, lintProject, previewLintFixes } from "./lint.js";
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { dirname, resolve } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import * as z from "zod/v4";
|
|
13
|
+
//#region src/server.ts
|
|
14
|
+
function readPackageVersion() {
|
|
15
|
+
const directory = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(readFileSync(resolve(directory, "../package.json"), "utf8")).version || "0.0.0";
|
|
18
|
+
} catch {
|
|
19
|
+
return "0.0.0";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function registerResources(server, context) {
|
|
23
|
+
server.registerResource("mastercss-workspace-manifest", "mastercss://workspace/manifest", {
|
|
24
|
+
title: "Master CSS Workspace Manifest",
|
|
25
|
+
description: "Loaded Master CSS project manifest status and entries.",
|
|
26
|
+
mimeType: "application/json"
|
|
27
|
+
}, async (uri) => jsonResourceResult(uri, await loadWorkspaceManifest(context)));
|
|
28
|
+
server.registerResource("mastercss-workspace-entries", "mastercss://workspace/entries", {
|
|
29
|
+
title: "Master CSS Workspace Entries",
|
|
30
|
+
description: "Discovered Master CSS manifest entry files.",
|
|
31
|
+
mimeType: "application/json"
|
|
32
|
+
}, async (uri) => {
|
|
33
|
+
const manifest = await loadWorkspaceManifest(context);
|
|
34
|
+
return jsonResourceResult(uri, {
|
|
35
|
+
root: context.root,
|
|
36
|
+
entries: manifest.entries
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
server.registerResource("mastercss-workspace-packages", "mastercss://workspace/packages", {
|
|
40
|
+
title: "Master CSS Workspace Packages",
|
|
41
|
+
description: "Resolved Master CSS package locations for this workspace.",
|
|
42
|
+
mimeType: "application/json"
|
|
43
|
+
}, async (uri) => {
|
|
44
|
+
return jsonResourceResult(uri, (await getWorkspaceInfo(context)).packages);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function registerPrompts(server) {
|
|
48
|
+
server.registerPrompt("debug-missing-css", {
|
|
49
|
+
title: "Debug Missing CSS",
|
|
50
|
+
description: "Guide an assistant through debugging classes that are not producing CSS."
|
|
51
|
+
}, () => ({ messages: [{
|
|
52
|
+
role: "user",
|
|
53
|
+
content: {
|
|
54
|
+
type: "text",
|
|
55
|
+
text: "Use the Master CSS MCP tools to scan the project, inspect the missing class names, compare generated CSS, and identify whether the issue is extraction, manifest loading, invalid syntax, native CSS pruning, or stylesheet entry configuration."
|
|
56
|
+
}
|
|
57
|
+
}] }));
|
|
58
|
+
server.registerPrompt("review-mastercss-classes", {
|
|
59
|
+
title: "Review Master CSS Classes",
|
|
60
|
+
description: "Review class lists for invalid, conflicting, non-canonical, or unsorted classes."
|
|
61
|
+
}, () => ({ messages: [{
|
|
62
|
+
role: "user",
|
|
63
|
+
content: {
|
|
64
|
+
type: "text",
|
|
65
|
+
text: "Run Master CSS lint diagnostics through the MCP server, lead with bugs or CSS output risks, and only propose write previews when fixes are safe and scoped to the workspace."
|
|
66
|
+
}
|
|
67
|
+
}] }));
|
|
68
|
+
server.registerPrompt("migrate-to-mastercss", {
|
|
69
|
+
title: "Migrate To Master CSS",
|
|
70
|
+
description: "Plan a migration from existing markup/styles to Master CSS classes."
|
|
71
|
+
}, () => ({ messages: [{
|
|
72
|
+
role: "user",
|
|
73
|
+
content: {
|
|
74
|
+
type: "text",
|
|
75
|
+
text: "Inspect the workspace with Master CSS MCP tools, identify current stylesheet entries and class extraction coverage, then plan migration steps that preserve CSS output unless a deliberate behavior change is requested."
|
|
76
|
+
}
|
|
77
|
+
}] }));
|
|
78
|
+
}
|
|
79
|
+
function registerTools(server, context) {
|
|
80
|
+
server.registerTool("mastercss_workspace_info", {
|
|
81
|
+
title: "Master CSS Workspace Info",
|
|
82
|
+
description: "Report workspace roots, resolved Master CSS packages, and project manifest status.",
|
|
83
|
+
annotations: {
|
|
84
|
+
readOnlyHint: true,
|
|
85
|
+
destructiveHint: false,
|
|
86
|
+
idempotentHint: true,
|
|
87
|
+
openWorldHint: false
|
|
88
|
+
}
|
|
89
|
+
}, async () => jsonToolResult(await getWorkspaceInfo(context)));
|
|
90
|
+
server.registerTool("mastercss_inspect_class", {
|
|
91
|
+
title: "Inspect Master CSS Class",
|
|
92
|
+
description: "Inspect one Master CSS class and return semantic parts, generated rules, variables, and CSS text.",
|
|
93
|
+
inputSchema: {
|
|
94
|
+
className: z.string().min(1),
|
|
95
|
+
mode: z.string().optional()
|
|
96
|
+
},
|
|
97
|
+
annotations: {
|
|
98
|
+
readOnlyHint: true,
|
|
99
|
+
destructiveHint: false,
|
|
100
|
+
idempotentHint: true,
|
|
101
|
+
openWorldHint: false
|
|
102
|
+
}
|
|
103
|
+
}, async (input) => jsonToolResult(await inspectClass(context, input)));
|
|
104
|
+
server.registerTool("mastercss_render_css", {
|
|
105
|
+
title: "Render Master CSS",
|
|
106
|
+
description: "Generate CSS from an HTML fragment or a whitespace-separated class list.",
|
|
107
|
+
inputSchema: {
|
|
108
|
+
html: z.string().optional(),
|
|
109
|
+
classList: z.string().optional()
|
|
110
|
+
},
|
|
111
|
+
annotations: {
|
|
112
|
+
readOnlyHint: true,
|
|
113
|
+
destructiveHint: false,
|
|
114
|
+
idempotentHint: true,
|
|
115
|
+
openWorldHint: false
|
|
116
|
+
}
|
|
117
|
+
}, async (input) => jsonToolResult(await renderCSS(context, input)));
|
|
118
|
+
server.registerTool("mastercss_scan_project", {
|
|
119
|
+
title: "Scan Master CSS Project",
|
|
120
|
+
description: "Scan source files, register stylesheet entries, and report scanner state and generated CSS metadata.",
|
|
121
|
+
inputSchema: {
|
|
122
|
+
patterns: z.array(z.string()).optional(),
|
|
123
|
+
classes: z.array(z.string()).optional(),
|
|
124
|
+
includeCss: z.boolean().optional()
|
|
125
|
+
},
|
|
126
|
+
annotations: {
|
|
127
|
+
readOnlyHint: true,
|
|
128
|
+
destructiveHint: false,
|
|
129
|
+
idempotentHint: true,
|
|
130
|
+
openWorldHint: false
|
|
131
|
+
}
|
|
132
|
+
}, async (input) => jsonToolResult(await scanProject(context, input)));
|
|
133
|
+
server.registerTool("mastercss_lint_project", {
|
|
134
|
+
title: "Lint Master CSS Project",
|
|
135
|
+
description: "Run Master CSS class-list diagnostics and return fix proposals without writing files.",
|
|
136
|
+
inputSchema: {
|
|
137
|
+
patterns: z.array(z.string()).optional(),
|
|
138
|
+
rules: z.string().optional()
|
|
139
|
+
},
|
|
140
|
+
annotations: {
|
|
141
|
+
readOnlyHint: true,
|
|
142
|
+
destructiveHint: false,
|
|
143
|
+
idempotentHint: true,
|
|
144
|
+
openWorldHint: false
|
|
145
|
+
}
|
|
146
|
+
}, async (input) => jsonToolResult(await lintProject(context, input)));
|
|
147
|
+
server.registerTool("mastercss_lint_content", {
|
|
148
|
+
title: "Lint Master CSS Content",
|
|
149
|
+
description: "Run Master CSS class-list diagnostics on an in-memory source buffer without writing files.",
|
|
150
|
+
inputSchema: {
|
|
151
|
+
content: z.string(),
|
|
152
|
+
filePath: z.string(),
|
|
153
|
+
rules: z.string().optional()
|
|
154
|
+
},
|
|
155
|
+
annotations: {
|
|
156
|
+
readOnlyHint: true,
|
|
157
|
+
destructiveHint: false,
|
|
158
|
+
idempotentHint: true,
|
|
159
|
+
openWorldHint: false
|
|
160
|
+
}
|
|
161
|
+
}, async (input) => jsonToolResult(await lintContent(context, input)));
|
|
162
|
+
server.registerTool("mastercss_suggest_syntax", {
|
|
163
|
+
title: "Suggest Master CSS Syntax",
|
|
164
|
+
description: "Return language-service completions and hover context for a document position.",
|
|
165
|
+
inputSchema: {
|
|
166
|
+
content: z.string(),
|
|
167
|
+
filePath: z.string(),
|
|
168
|
+
position: z.object({
|
|
169
|
+
line: z.number().int().min(0),
|
|
170
|
+
character: z.number().int().min(0)
|
|
171
|
+
}),
|
|
172
|
+
triggerCharacter: z.string().optional(),
|
|
173
|
+
limit: z.number().int().min(1).max(200).optional()
|
|
174
|
+
},
|
|
175
|
+
annotations: {
|
|
176
|
+
readOnlyHint: true,
|
|
177
|
+
destructiveHint: false,
|
|
178
|
+
idempotentHint: true,
|
|
179
|
+
openWorldHint: false
|
|
180
|
+
}
|
|
181
|
+
}, async (input) => jsonToolResult(await suggestSyntax(context, input)));
|
|
182
|
+
server.registerTool("mastercss_preview_fixes", {
|
|
183
|
+
title: "Preview Master CSS Fixes",
|
|
184
|
+
description: "Create a diff preview for lint fixes or generated CSS output and return a confirmation token.",
|
|
185
|
+
inputSchema: {
|
|
186
|
+
mode: z.enum(["lint-fixes", "generated-css"]).optional(),
|
|
187
|
+
patterns: z.array(z.string()).optional(),
|
|
188
|
+
rules: z.string().optional(),
|
|
189
|
+
includeDirectiveFixes: z.boolean().optional(),
|
|
190
|
+
outputPath: z.string().optional(),
|
|
191
|
+
ttlMs: z.number().int().min(1e3).max(3600 * 1e3).optional()
|
|
192
|
+
},
|
|
193
|
+
annotations: {
|
|
194
|
+
readOnlyHint: false,
|
|
195
|
+
destructiveHint: false,
|
|
196
|
+
idempotentHint: false,
|
|
197
|
+
openWorldHint: false
|
|
198
|
+
}
|
|
199
|
+
}, async (input) => {
|
|
200
|
+
if (input.mode === "generated-css") {
|
|
201
|
+
if (!input.outputPath) throw new Error("outputPath is required when mode is \"generated-css\".");
|
|
202
|
+
return jsonToolResult(await previewGeneratedCSS(context, {
|
|
203
|
+
patterns: input.patterns,
|
|
204
|
+
includeCss: true,
|
|
205
|
+
outputPath: input.outputPath,
|
|
206
|
+
ttlMs: input.ttlMs
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
return jsonToolResult(await previewLintFixes(context, input));
|
|
210
|
+
});
|
|
211
|
+
server.registerTool("mastercss_apply_preview", {
|
|
212
|
+
title: "Apply Master CSS Preview",
|
|
213
|
+
description: "Apply a previously generated preview token after validating hashes and workspace containment.",
|
|
214
|
+
inputSchema: { confirmToken: z.string().min(1) },
|
|
215
|
+
annotations: {
|
|
216
|
+
readOnlyHint: false,
|
|
217
|
+
destructiveHint: true,
|
|
218
|
+
idempotentHint: false,
|
|
219
|
+
openWorldHint: false
|
|
220
|
+
}
|
|
221
|
+
}, async (input) => jsonToolResult(await context.applyPreview(input.confirmToken)));
|
|
222
|
+
}
|
|
223
|
+
function createMasterCSSMCPServer(options = {}) {
|
|
224
|
+
const context = new MasterCSSMCPContext(options);
|
|
225
|
+
const server = new McpServer({
|
|
226
|
+
name: "@master/css-mcp",
|
|
227
|
+
version: readPackageVersion()
|
|
228
|
+
});
|
|
229
|
+
registerResources(server, context);
|
|
230
|
+
registerPrompts(server);
|
|
231
|
+
registerTools(server, context);
|
|
232
|
+
return {
|
|
233
|
+
server,
|
|
234
|
+
context
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
async function startStdioServer(options = {}) {
|
|
238
|
+
const { server } = createMasterCSSMCPServer(options);
|
|
239
|
+
const transport = new StdioServerTransport();
|
|
240
|
+
await server.connect(transport);
|
|
241
|
+
return server;
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
export { createMasterCSSMCPServer, startStdioServer };
|