@wireweave/mcp-server 1.5.1 → 1.6.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +187 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -137,6 +137,36 @@ var tools = [
|
|
|
137
137
|
]
|
|
138
138
|
}
|
|
139
139
|
},
|
|
140
|
+
{
|
|
141
|
+
name: "wireweave_render_html_code",
|
|
142
|
+
description: "Render Wireweave DSL to HTML code. Returns the HTML content directly. This is an alias for wireweave_render_html with explicit naming.",
|
|
143
|
+
inputSchema: {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"properties": {
|
|
146
|
+
"source": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"description": "The Wireweave DSL source code to render"
|
|
149
|
+
},
|
|
150
|
+
"theme": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"enum": [
|
|
153
|
+
"light",
|
|
154
|
+
"dark"
|
|
155
|
+
],
|
|
156
|
+
"description": "Color theme for rendering",
|
|
157
|
+
"default": "light"
|
|
158
|
+
},
|
|
159
|
+
"fullDocument": {
|
|
160
|
+
"type": "boolean",
|
|
161
|
+
"description": "Return a complete HTML document instead of fragment",
|
|
162
|
+
"default": false
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"required": [
|
|
166
|
+
"source"
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
},
|
|
140
170
|
{
|
|
141
171
|
name: "wireweave_validate_ux",
|
|
142
172
|
description: "Validate Wireweave DSL for UX best practices. Returns issues with severity levels and actionable recommendations.",
|
|
@@ -685,6 +715,7 @@ var toolEndpoints = {
|
|
|
685
715
|
wireweave_patterns: { method: "GET", path: "/tools/patterns" },
|
|
686
716
|
wireweave_examples: { method: "GET", path: "/tools/examples" },
|
|
687
717
|
wireweave_render_html: { method: "POST", path: "/tools/render/html" },
|
|
718
|
+
wireweave_render_html_code: { method: "POST", path: "/tools/render/html" },
|
|
688
719
|
wireweave_validate_ux: { method: "POST", path: "/tools/validate/ux" },
|
|
689
720
|
wireweave_ux_rules: { method: "GET", path: "/tools/ux-rules" },
|
|
690
721
|
wireweave_diff: { method: "POST", path: "/tools/diff" },
|
|
@@ -814,18 +845,18 @@ var resourceToTool = {
|
|
|
814
845
|
|
|
815
846
|
// src/api.ts
|
|
816
847
|
function buildRequest(config, endpoint, args) {
|
|
817
|
-
let
|
|
848
|
+
let path2 = endpoint.path;
|
|
818
849
|
const body = { ...args };
|
|
819
850
|
if (endpoint.pathParams && args) {
|
|
820
851
|
for (const param of endpoint.pathParams) {
|
|
821
852
|
const value = args[param];
|
|
822
853
|
if (value !== void 0) {
|
|
823
|
-
|
|
854
|
+
path2 = path2.replace(`:${param}`, String(value));
|
|
824
855
|
delete body[param];
|
|
825
856
|
}
|
|
826
857
|
}
|
|
827
858
|
}
|
|
828
|
-
let url = `${config.apiUrl}${
|
|
859
|
+
let url = `${config.apiUrl}${path2}`;
|
|
829
860
|
const options = {
|
|
830
861
|
method: endpoint.method,
|
|
831
862
|
headers: {
|
|
@@ -893,6 +924,152 @@ async function callApi(config, endpoint, args, fetchFn = fetch) {
|
|
|
893
924
|
return result;
|
|
894
925
|
}
|
|
895
926
|
|
|
927
|
+
// src/local-tools.ts
|
|
928
|
+
import * as fs from "fs";
|
|
929
|
+
import * as path from "path";
|
|
930
|
+
import * as os from "os";
|
|
931
|
+
var localTools = [
|
|
932
|
+
{
|
|
933
|
+
name: "wireweave_render_html_file",
|
|
934
|
+
description: "Render Wireweave DSL to HTML and save to a local file. Returns the file path. Use this when you need a persistent HTML file for preview or browser viewing. Credits are charged via internal API call.",
|
|
935
|
+
inputSchema: {
|
|
936
|
+
type: "object",
|
|
937
|
+
properties: {
|
|
938
|
+
source: {
|
|
939
|
+
type: "string",
|
|
940
|
+
description: "The Wireweave DSL source code to render"
|
|
941
|
+
},
|
|
942
|
+
theme: {
|
|
943
|
+
type: "string",
|
|
944
|
+
enum: ["light", "dark"],
|
|
945
|
+
description: "Color theme for rendering",
|
|
946
|
+
default: "light"
|
|
947
|
+
},
|
|
948
|
+
outputDir: {
|
|
949
|
+
type: "string",
|
|
950
|
+
description: "Output directory for the HTML file. Defaults to system temp directory."
|
|
951
|
+
},
|
|
952
|
+
filename: {
|
|
953
|
+
type: "string",
|
|
954
|
+
description: "Custom filename without extension. Defaults to wireframe-{timestamp}."
|
|
955
|
+
}
|
|
956
|
+
},
|
|
957
|
+
required: ["source"]
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
];
|
|
961
|
+
var LOCAL_TOOL_NAMES = new Set(localTools.map((t) => t.name));
|
|
962
|
+
async function handleLocalTool(name, args, apiConfig2) {
|
|
963
|
+
switch (name) {
|
|
964
|
+
case "wireweave_render_html_file":
|
|
965
|
+
return handleRenderHtmlFile(args, apiConfig2);
|
|
966
|
+
default:
|
|
967
|
+
return {
|
|
968
|
+
content: [
|
|
969
|
+
{
|
|
970
|
+
type: "text",
|
|
971
|
+
text: JSON.stringify({ error: `Unknown local tool: ${name}` }, null, 2)
|
|
972
|
+
}
|
|
973
|
+
],
|
|
974
|
+
isError: true
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
async function handleRenderHtmlFile(args, apiConfig2) {
|
|
979
|
+
const { source, theme = "light", outputDir, filename } = args;
|
|
980
|
+
if (!source || typeof source !== "string") {
|
|
981
|
+
return {
|
|
982
|
+
content: [
|
|
983
|
+
{
|
|
984
|
+
type: "text",
|
|
985
|
+
text: JSON.stringify({ error: "source is required" }, null, 2)
|
|
986
|
+
}
|
|
987
|
+
],
|
|
988
|
+
isError: true
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
try {
|
|
992
|
+
const endpoint = toolEndpoints["wireweave_render_html"];
|
|
993
|
+
if (!endpoint) {
|
|
994
|
+
return {
|
|
995
|
+
content: [
|
|
996
|
+
{
|
|
997
|
+
type: "text",
|
|
998
|
+
text: JSON.stringify(
|
|
999
|
+
{ error: "wireweave_render_html endpoint not found" },
|
|
1000
|
+
null,
|
|
1001
|
+
2
|
|
1002
|
+
)
|
|
1003
|
+
}
|
|
1004
|
+
],
|
|
1005
|
+
isError: true
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
const result = await callApi(apiConfig2, endpoint, {
|
|
1009
|
+
source,
|
|
1010
|
+
theme,
|
|
1011
|
+
fullDocument: true
|
|
1012
|
+
// Always request full document for file output
|
|
1013
|
+
});
|
|
1014
|
+
if (!result.success || !result.html) {
|
|
1015
|
+
return {
|
|
1016
|
+
content: [
|
|
1017
|
+
{
|
|
1018
|
+
type: "text",
|
|
1019
|
+
text: JSON.stringify(
|
|
1020
|
+
{ error: result.error || "No HTML content returned from API" },
|
|
1021
|
+
null,
|
|
1022
|
+
2
|
|
1023
|
+
)
|
|
1024
|
+
}
|
|
1025
|
+
],
|
|
1026
|
+
isError: true
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
const dir = typeof outputDir === "string" ? outputDir : os.tmpdir();
|
|
1030
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1031
|
+
const fname = typeof filename === "string" ? filename : `wireframe-${timestamp}`;
|
|
1032
|
+
const filePath = path.join(dir, `${fname}.html`);
|
|
1033
|
+
let htmlContent = result.html;
|
|
1034
|
+
if (result.css && !htmlContent.includes("<style>")) {
|
|
1035
|
+
htmlContent = htmlContent.replace("</head>", `<style>${result.css}</style></head>`);
|
|
1036
|
+
}
|
|
1037
|
+
fs.writeFileSync(filePath, htmlContent, "utf-8");
|
|
1038
|
+
return {
|
|
1039
|
+
content: [
|
|
1040
|
+
{
|
|
1041
|
+
type: "text",
|
|
1042
|
+
text: JSON.stringify(
|
|
1043
|
+
{
|
|
1044
|
+
success: true,
|
|
1045
|
+
filePath,
|
|
1046
|
+
message: `HTML file saved to: ${filePath}`
|
|
1047
|
+
},
|
|
1048
|
+
null,
|
|
1049
|
+
2
|
|
1050
|
+
)
|
|
1051
|
+
}
|
|
1052
|
+
]
|
|
1053
|
+
};
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
return {
|
|
1056
|
+
content: [
|
|
1057
|
+
{
|
|
1058
|
+
type: "text",
|
|
1059
|
+
text: JSON.stringify(
|
|
1060
|
+
{
|
|
1061
|
+
error: error instanceof Error ? error.message : "Failed to render HTML file"
|
|
1062
|
+
},
|
|
1063
|
+
null,
|
|
1064
|
+
2
|
|
1065
|
+
)
|
|
1066
|
+
}
|
|
1067
|
+
],
|
|
1068
|
+
isError: true
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
|
|
896
1073
|
// src/index.ts
|
|
897
1074
|
var API_URL = process.env.WIREWEAVE_API_URL || "https://api.wireweave.org";
|
|
898
1075
|
var API_KEY = process.env.WIREWEAVE_API_KEY || "";
|
|
@@ -918,19 +1095,23 @@ var server = new Server(
|
|
|
918
1095
|
}
|
|
919
1096
|
);
|
|
920
1097
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
921
|
-
return { tools };
|
|
1098
|
+
return { tools: [...tools, ...localTools] };
|
|
922
1099
|
});
|
|
923
1100
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
924
1101
|
const { name, arguments: args } = request.params;
|
|
1102
|
+
if (LOCAL_TOOL_NAMES.has(name)) {
|
|
1103
|
+
return handleLocalTool(name, args, apiConfig);
|
|
1104
|
+
}
|
|
925
1105
|
const endpoint = toolEndpoints[name];
|
|
926
1106
|
if (!endpoint) {
|
|
1107
|
+
const allTools = [...tools, ...localTools];
|
|
927
1108
|
return {
|
|
928
1109
|
content: [
|
|
929
1110
|
{
|
|
930
1111
|
type: "text",
|
|
931
1112
|
text: JSON.stringify({
|
|
932
1113
|
error: `Unknown tool: ${name}`,
|
|
933
|
-
availableTools:
|
|
1114
|
+
availableTools: allTools.map((t) => t.name)
|
|
934
1115
|
}, null, 2)
|
|
935
1116
|
}
|
|
936
1117
|
],
|
|
@@ -1037,7 +1218,7 @@ process.on("SIGINT", async () => {
|
|
|
1037
1218
|
async function main() {
|
|
1038
1219
|
const transport = new StdioServerTransport();
|
|
1039
1220
|
await server.connect(transport);
|
|
1040
|
-
log(`MCP server started with ${tools.length} tools, ${prompts.length} prompts, ${resources.length} resources`);
|
|
1221
|
+
log(`MCP server started with ${tools.length + localTools.length} tools (${localTools.length} local), ${prompts.length} prompts, ${resources.length} resources`);
|
|
1041
1222
|
if (!API_KEY) {
|
|
1042
1223
|
log("API key not configured. Get one at https://wireweave.org", "warn");
|
|
1043
1224
|
}
|