@schemyx/mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @schemyx/mcp
2
+
3
+ Local stdio MCP server for reading Schemyx project configs, Theme Forge artifacts, target-stack guidance, and implementation notes.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ SCHEMYX_API_KEY=skx_live_replace_me npx -y @schemyx/mcp
9
+ ```
10
+
11
+ MCP client config:
12
+
13
+ ```json
14
+ {
15
+ "mcpServers": {
16
+ "schemyx": {
17
+ "command": "npx",
18
+ "args": ["-y", "@schemyx/mcp@latest"],
19
+ "env": {
20
+ "SCHEMYX_API_KEY": "$SCHEMYX_API_KEY"
21
+ }
22
+ }
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Environment
28
+
29
+ - `SCHEMYX_API_KEY`: required Schemyx API key with `mcp:read` or `configs:read`
30
+ - `SCHEMYX_API_URL`: optional API base URL, defaults to `https://api.schemyx.com`
31
+ - `SCHEMYX_PROJECT_ID`: optional project filter
32
+ - `SCHEMYX_CONFIG_ID`: optional config filter
33
+ - `SCHEMYX_MCP_CACHE_TTL_MS`: optional discovery cache TTL, defaults to `10000`
34
+
35
+ ## Development
36
+
37
+ From the backend repo root:
38
+
39
+ ```bash
40
+ npm run build:mcp
41
+ SCHEMYX_API_URL=http://localhost:4000 \
42
+ SCHEMYX_API_KEY=skx_test_replace_me \
43
+ npm run mcp:local
44
+ ```
@@ -0,0 +1,17 @@
1
+ import { BackendConfigManifest, BackendResourceContent, BackendToolResult, DiscoveredConfig, LocalMcpConfig, McpConfigResponse, McpContextResponse } from './types';
2
+ export declare class SchemyxBackendClient {
3
+ private readonly config;
4
+ private contextCache;
5
+ private manifestCache;
6
+ constructor(config: LocalMcpConfig);
7
+ getContext(): Promise<McpContextResponse>;
8
+ listConfigs(): Promise<McpConfigResponse[]>;
9
+ discoverConfigs(): Promise<DiscoveredConfig[]>;
10
+ getManifest(configId: string): Promise<BackendConfigManifest>;
11
+ getLatestConfig(configId: string): Promise<McpConfigResponse>;
12
+ readResource(configId: string, resourceId: string): Promise<BackendResourceContent>;
13
+ executeTool(configId: string, toolName: string, args: Record<string, unknown>): Promise<BackendToolResult>;
14
+ resolveConfigId(configId: string | undefined): Promise<string>;
15
+ private request;
16
+ private cacheEntry;
17
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchemyxBackendClient = void 0;
4
+ class SchemyxBackendClient {
5
+ config;
6
+ contextCache = null;
7
+ manifestCache = new Map();
8
+ constructor(config) {
9
+ this.config = config;
10
+ }
11
+ async getContext() {
12
+ const cached = this.contextCache;
13
+ if (cached && cached.expiresAt > Date.now()) {
14
+ return cached.value;
15
+ }
16
+ const value = await this.request('/mcp/context');
17
+ this.contextCache = this.cacheEntry(value);
18
+ return value;
19
+ }
20
+ async listConfigs() {
21
+ const context = await this.getContext();
22
+ const configs = context.projects
23
+ .filter((project) => !this.config.projectId || project.id === this.config.projectId)
24
+ .flatMap((project) => project.configs);
25
+ if (this.config.configId) {
26
+ return configs.filter((config) => config.id === this.config.configId);
27
+ }
28
+ return configs;
29
+ }
30
+ async discoverConfigs() {
31
+ const configs = await this.listConfigs();
32
+ return Promise.all(configs.map(async (config) => ({
33
+ config,
34
+ manifest: await this.getManifest(config.id),
35
+ })));
36
+ }
37
+ async getManifest(configId) {
38
+ const cached = this.manifestCache.get(configId);
39
+ if (cached && cached.expiresAt > Date.now()) {
40
+ return cached.value;
41
+ }
42
+ const value = await this.request(`/mcp/configs/${configId}/manifest`);
43
+ this.manifestCache.set(configId, this.cacheEntry(value));
44
+ return value;
45
+ }
46
+ async getLatestConfig(configId) {
47
+ return this.request(`/mcp/configs/${configId}/latest`);
48
+ }
49
+ async readResource(configId, resourceId) {
50
+ return this.request(`/mcp/configs/${configId}/resources/${encodeURIComponent(resourceId)}`);
51
+ }
52
+ async executeTool(configId, toolName, args) {
53
+ return this.request(`/mcp/configs/${configId}/tools/${encodeURIComponent(toolName)}`, {
54
+ method: 'POST',
55
+ body: JSON.stringify({ arguments: args }),
56
+ });
57
+ }
58
+ async resolveConfigId(configId) {
59
+ if (configId) {
60
+ return configId;
61
+ }
62
+ const configs = await this.listConfigs();
63
+ if (configs.length === 1) {
64
+ return configs[0].id;
65
+ }
66
+ if (configs.length === 0) {
67
+ throw new Error('No Schemyx configs are available for this API key.');
68
+ }
69
+ throw new Error('Multiple configs are available. Pass configId to choose one.');
70
+ }
71
+ async request(path, init) {
72
+ const response = await fetch(`${this.config.apiUrl}${path}`, {
73
+ ...init,
74
+ headers: {
75
+ Accept: 'application/json',
76
+ Authorization: `Bearer ${this.config.apiKey}`,
77
+ ...(init?.body ? { 'Content-Type': 'application/json' } : {}),
78
+ ...init?.headers,
79
+ },
80
+ });
81
+ if (!response.ok) {
82
+ throw new Error(`Schemyx API request failed: ${response.status} ${response.statusText} ${await response.text()}`);
83
+ }
84
+ return (await response.json());
85
+ }
86
+ cacheEntry(value) {
87
+ return {
88
+ expiresAt: Date.now() + this.config.cacheTtlMs,
89
+ value,
90
+ };
91
+ }
92
+ }
93
+ exports.SchemyxBackendClient = SchemyxBackendClient;
94
+ //# sourceMappingURL=backend-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-client.js","sourceRoot":"","sources":["../src/backend-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { LocalMcpConfig } from './types';
2
+ export declare function loadLocalMcpConfig(env?: NodeJS.ProcessEnv): LocalMcpConfig;
package/dist/config.js ADDED
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadLocalMcpConfig = loadLocalMcpConfig;
4
+ const defaultApiUrl = 'https://api.schemyx.com';
5
+ const defaultCacheTtlMs = 10_000;
6
+ function loadLocalMcpConfig(env = process.env) {
7
+ const apiKey = env.SCHEMYX_API_KEY?.trim();
8
+ if (!apiKey) {
9
+ throw new Error('SCHEMYX_API_KEY is required to start the Schemyx MCP server.');
10
+ }
11
+ return {
12
+ apiUrl: normalizeApiUrl(env.SCHEMYX_API_URL ?? defaultApiUrl),
13
+ apiKey,
14
+ projectId: optionalValue(env.SCHEMYX_PROJECT_ID),
15
+ configId: optionalValue(env.SCHEMYX_CONFIG_ID),
16
+ cacheTtlMs: parseCacheTtl(env.SCHEMYX_MCP_CACHE_TTL_MS),
17
+ };
18
+ }
19
+ function normalizeApiUrl(value) {
20
+ const trimmed = value.trim();
21
+ if (!trimmed) {
22
+ return defaultApiUrl;
23
+ }
24
+ return trimmed.replace(/\/+$/, '');
25
+ }
26
+ function optionalValue(value) {
27
+ const trimmed = value?.trim();
28
+ return trimmed ? trimmed : undefined;
29
+ }
30
+ function parseCacheTtl(value) {
31
+ if (!value) {
32
+ return defaultCacheTtlMs;
33
+ }
34
+ const parsed = Number(value);
35
+ if (!Number.isFinite(parsed) || parsed < 0) {
36
+ throw new Error('SCHEMYX_MCP_CACHE_TTL_MS must be a non-negative number.');
37
+ }
38
+ return parsed;
39
+ }
40
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAKA,gDAcC;AAjBD,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAChD,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC,SAAgB,kBAAkB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAE3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IAED,OAAO;QACL,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC,eAAe,IAAI,aAAa,CAAC;QAC7D,MAAM;QACN,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAChD,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC9C,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,wBAAwB,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB;IAC9C,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAE9B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const backend_client_1 = require("./backend-client");
5
+ const config_1 = require("./config");
6
+ const server_1 = require("./server");
7
+ async function main() {
8
+ const config = (0, config_1.loadLocalMcpConfig)();
9
+ await (0, server_1.runLocalMcpServer)(new backend_client_1.SchemyxBackendClient(config));
10
+ }
11
+ main().catch((error) => {
12
+ console.error(error instanceof Error ? error.message : error);
13
+ process.exit(1);
14
+ });
15
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;AACA,qDAAwD;AACxD,qCAA8C;AAC9C,qCAA6C;AAE7C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAA,2BAAkB,GAAE,CAAC;IACpC,MAAM,IAAA,0BAAiB,EAAC,IAAI,qCAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { GetPromptResult, Prompt } from '@modelcontextprotocol/sdk/types.js';
2
+ import { SchemyxBackendClient } from './backend-client';
3
+ export declare const localPromptNames: {
4
+ readonly applyTheme: "schemyx_apply_theme";
5
+ };
6
+ export declare const localPrompts: Prompt[];
7
+ export declare function getLocalPrompt(client: SchemyxBackendClient, name: string, args: Record<string, string> | undefined): Promise<GetPromptResult>;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.localPrompts = exports.localPromptNames = void 0;
4
+ exports.getLocalPrompt = getLocalPrompt;
5
+ const text_1 = require("./text");
6
+ exports.localPromptNames = {
7
+ applyTheme: 'schemyx_apply_theme',
8
+ };
9
+ exports.localPrompts = [
10
+ {
11
+ name: exports.localPromptNames.applyTheme,
12
+ title: 'Apply Schemyx Theme',
13
+ description: 'Use the saved Schemyx theme contract before building or restyling UI.',
14
+ arguments: [
15
+ {
16
+ name: 'task',
17
+ description: 'The UI or product workflow to build.',
18
+ required: true,
19
+ },
20
+ {
21
+ name: 'configId',
22
+ description: 'Schemyx config id. Optional when only one config is available.',
23
+ required: false,
24
+ },
25
+ ],
26
+ },
27
+ ];
28
+ async function getLocalPrompt(client, name, args) {
29
+ if (name !== exports.localPromptNames.applyTheme) {
30
+ throw new Error(`Unknown Schemyx prompt: ${name}`);
31
+ }
32
+ const configId = await client.resolveConfigId(args?.configId);
33
+ const guide = await client.executeTool(configId, 'theme-forge.get-implementation-guide', {});
34
+ const task = args?.task ?? 'Build the requested UI.';
35
+ return {
36
+ description: 'Apply the saved Schemyx theme contract to a codebase.',
37
+ messages: [
38
+ {
39
+ role: 'user',
40
+ content: {
41
+ type: 'text',
42
+ text: [
43
+ `Task: ${task}`,
44
+ '',
45
+ 'Use the Schemyx config as source of truth before writing UI code.',
46
+ 'Read generated artifacts from this MCP server instead of inventing colors, radius, spacing, shadows, or typography.',
47
+ '',
48
+ (0, text_1.stringifyMcpContent)(guide.content),
49
+ ].join('\n'),
50
+ },
51
+ },
52
+ ],
53
+ };
54
+ }
55
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":";;;AA4BA,wCAgCC;AA1DD,iCAA6C;AAEhC,QAAA,gBAAgB,GAAG;IAC9B,UAAU,EAAE,qBAAqB;CACzB,CAAC;AAEE,QAAA,YAAY,GAAa;IACpC;QACE,IAAI,EAAE,wBAAgB,CAAC,UAAU;QACjC,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,uEAAuE;QACpF,SAAS,EAAE;YACT;gBACE,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,sCAAsC;gBACnD,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,gEAAgE;gBAC7E,QAAQ,EAAE,KAAK;aAChB;SACF;KACF;CACF,CAAC;AAEK,KAAK,UAAU,cAAc,CAClC,MAA4B,EAC5B,IAAY,EACZ,IAAwC;IAExC,IAAI,IAAI,KAAK,wBAAgB,CAAC,UAAU,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,sCAAsC,EAAE,EAAE,CAAC,CAAC;IAC7F,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,yBAAyB,CAAC;IAErD,OAAO;QACL,WAAW,EAAE,uDAAuD;QACpE,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,SAAS,IAAI,EAAE;wBACf,EAAE;wBACF,mEAAmE;wBACnE,qHAAqH;wBACrH,EAAE;wBACF,IAAA,0BAAmB,EAAC,KAAK,CAAC,OAAO,CAAC;qBACnC,CAAC,IAAI,CAAC,IAAI,CAAC;iBACb;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { SchemyxBackendClient } from './backend-client';
3
+ export declare function createLocalMcpServer(client: SchemyxBackendClient): Server;
4
+ export declare function runLocalMcpServer(client: SchemyxBackendClient): Promise<void>;
package/dist/server.js ADDED
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLocalMcpServer = createLocalMcpServer;
4
+ exports.runLocalMcpServer = runLocalMcpServer;
5
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
6
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
7
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
8
+ const prompts_1 = require("./prompts");
9
+ const text_1 = require("./text");
10
+ const uri_1 = require("./uri");
11
+ const tool_definitions_1 = require("./tool-definitions");
12
+ function createLocalMcpServer(client) {
13
+ const server = new index_js_1.Server({
14
+ name: 'schemyx-mcp',
15
+ version: '0.1.0',
16
+ }, {
17
+ capabilities: {
18
+ resources: { listChanged: true },
19
+ tools: { listChanged: true },
20
+ prompts: { listChanged: true },
21
+ },
22
+ instructions: 'Use Schemyx resources and tools to read approved project configs, Theme Forge artifacts, and implementation guides before generating UI code.',
23
+ });
24
+ server.setRequestHandler(types_js_1.ListResourcesRequestSchema, async () => ({
25
+ resources: await listResources(client),
26
+ }));
27
+ server.setRequestHandler(types_js_1.ReadResourceRequestSchema, async (request) => {
28
+ const { configId, resourceId } = (0, uri_1.parseLocalResourceUri)(request.params.uri);
29
+ const resource = await client.readResource(configId, resourceId);
30
+ return {
31
+ contents: [
32
+ {
33
+ uri: request.params.uri,
34
+ mimeType: resource.resource.mimeType,
35
+ text: (0, text_1.stringifyMcpContent)(resource.content),
36
+ _meta: {
37
+ backendUri: resource.resource.uri,
38
+ resourceId: resource.resource.id,
39
+ configId,
40
+ },
41
+ },
42
+ ],
43
+ };
44
+ });
45
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
46
+ tools: tool_definitions_1.localTools,
47
+ }));
48
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
49
+ try {
50
+ return await callLocalTool(client, request.params.name, request.params.arguments ?? {});
51
+ }
52
+ catch (error) {
53
+ return (0, text_1.errorToolResult)(error);
54
+ }
55
+ });
56
+ server.setRequestHandler(types_js_1.ListPromptsRequestSchema, async () => ({
57
+ prompts: prompts_1.localPrompts,
58
+ }));
59
+ server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => (0, prompts_1.getLocalPrompt)(client, request.params.name, request.params.arguments));
60
+ return server;
61
+ }
62
+ async function runLocalMcpServer(client) {
63
+ const server = createLocalMcpServer(client);
64
+ await server.connect(new stdio_js_1.StdioServerTransport());
65
+ }
66
+ async function listResources(client) {
67
+ const discovered = await client.discoverConfigs();
68
+ return discovered.flatMap(({ config, manifest }) => manifest.resources.map((resource) => toMcpResource(config, resource)));
69
+ }
70
+ function toMcpResource(config, resource) {
71
+ return {
72
+ uri: (0, uri_1.createLocalResourceUri)(config.id, resource.id),
73
+ name: `${config.key}.${resource.id}`,
74
+ title: `${config.name}: ${resource.name}`,
75
+ description: `${resource.description} Config: ${config.name} (${config.key}).`,
76
+ mimeType: resource.mimeType,
77
+ _meta: {
78
+ configId: config.id,
79
+ configKey: config.key,
80
+ resourceId: resource.id,
81
+ backendUri: resource.uri,
82
+ ...resource.metadata,
83
+ },
84
+ };
85
+ }
86
+ async function callLocalTool(client, name, args) {
87
+ switch (name) {
88
+ case tool_definitions_1.localToolNames.listConfigs:
89
+ return (0, text_1.textToolResult)(await client.listConfigs());
90
+ case tool_definitions_1.localToolNames.getLatestConfig:
91
+ return (0, text_1.textToolResult)(await client.getLatestConfig(await client.resolveConfigId(stringArg(args, 'configId'))));
92
+ case tool_definitions_1.localToolNames.getManifest:
93
+ return (0, text_1.textToolResult)(await client.getManifest(await client.resolveConfigId(stringArg(args, 'configId'))));
94
+ case tool_definitions_1.localToolNames.readResource:
95
+ return (0, text_1.textToolResult)((await client.readResource(requiredStringArg(args, 'configId'), requiredStringArg(args, 'resourceId'))).content);
96
+ case tool_definitions_1.localToolNames.callBackendTool:
97
+ return (0, text_1.textToolResult)(await client.executeTool(requiredStringArg(args, 'configId'), requiredStringArg(args, 'toolName'), recordArg(args, 'arguments')));
98
+ case tool_definitions_1.localToolNames.getThemeFile:
99
+ return (0, text_1.textToolResult)((await client.executeTool(await client.resolveConfigId(stringArg(args, 'configId')), 'theme-forge.get-file', {
100
+ fileName: stringArg(args, 'fileName'),
101
+ fileId: stringArg(args, 'fileId'),
102
+ })).content);
103
+ case tool_definitions_1.localToolNames.getImplementationGuide:
104
+ return (0, text_1.textToolResult)((await client.executeTool(await client.resolveConfigId(stringArg(args, 'configId')), 'theme-forge.get-implementation-guide', {})).content);
105
+ default:
106
+ throw new Error(`Unknown Schemyx local MCP tool: ${name}`);
107
+ }
108
+ }
109
+ function stringArg(args, key) {
110
+ const value = args[key];
111
+ return typeof value === 'string' && value.trim() ? value : undefined;
112
+ }
113
+ function requiredStringArg(args, key) {
114
+ const value = stringArg(args, key);
115
+ if (!value) {
116
+ throw new Error(`Tool argument "${key}" is required.`);
117
+ }
118
+ return value;
119
+ }
120
+ function recordArg(args, key) {
121
+ const value = args[key];
122
+ if (!value) {
123
+ return {};
124
+ }
125
+ if (typeof value !== 'object' || Array.isArray(value)) {
126
+ throw new Error(`Tool argument "${key}" must be an object.`);
127
+ }
128
+ return value;
129
+ }
130
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;AAkBA,oDA8DC;AAED,8CAGC;AArFD,wEAAmE;AACnE,wEAAiF;AACjF,iEAQ4C;AAE5C,uCAAyD;AACzD,iCAA8E;AAE9E,+BAAsE;AACtE,yDAAgE;AAEhE,SAAgB,oBAAoB,CAAC,MAA4B;IAC/D,MAAM,MAAM,GAAG,IAAI,iBAAM,CACvB;QACE,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,SAAS,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;YAChC,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;YAC5B,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;SAC/B;QACD,YAAY,EACV,+IAA+I;KAClJ,CACF,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,qCAA0B,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAChE,SAAS,EAAE,MAAM,aAAa,CAAC,MAAM,CAAC;KACvC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,oCAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACpE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAA,2BAAqB,EAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3E,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEjE,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG;oBACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,QAAQ;oBACpC,IAAI,EAAE,IAAA,0BAAmB,EAAC,QAAQ,CAAC,OAAO,CAAC;oBAC3C,KAAK,EAAE;wBACL,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG;wBACjC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE;wBAChC,QAAQ;qBACT;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,6BAAU;KAClB,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,gCAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,IAAI,CAAC;YACH,OAAO,MAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC1F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAA,sBAAe,EAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,iBAAiB,CAAC,mCAAwB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC9D,OAAO,EAAE,sBAAY;KACtB,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CACjE,IAAA,wBAAc,EAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CACtE,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,MAA4B;IAClE,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,+BAAoB,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,MAA4B;IACvD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;IAElD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CACjD,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CACtE,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAyB,EAAE,QAAmC;IACnF,OAAO;QACL,GAAG,EAAE,IAAA,4BAAsB,EAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC;QACnD,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC,EAAE,EAAE;QACpC,KAAK,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE;QACzC,WAAW,EAAE,GAAG,QAAQ,CAAC,WAAW,YAAY,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,IAAI;QAC9E,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,KAAK,EAAE;YACL,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,SAAS,EAAE,MAAM,CAAC,GAAG;YACrB,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,UAAU,EAAE,QAAQ,CAAC,GAAG;YACxB,GAAG,QAAQ,CAAC,QAAQ;SACrB;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,MAA4B,EAC5B,IAAY,EACZ,IAA6B;IAE7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,iCAAc,CAAC,WAAW;YAC7B,OAAO,IAAA,qBAAc,EAAC,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACpD,KAAK,iCAAc,CAAC,eAAe;YACjC,OAAO,IAAA,qBAAc,EACnB,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CACxF,CAAC;QACJ,KAAK,iCAAc,CAAC,WAAW;YAC7B,OAAO,IAAA,qBAAc,EACnB,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CACpF,CAAC;QACJ,KAAK,iCAAc,CAAC,YAAY;YAC9B,OAAO,IAAA,qBAAc,EACnB,CACE,MAAM,MAAM,CAAC,YAAY,CACvB,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,EACnC,iBAAiB,CAAC,IAAI,EAAE,YAAY,CAAC,CACtC,CACF,CAAC,OAAO,CACV,CAAC;QACJ,KAAK,iCAAc,CAAC,eAAe;YACjC,OAAO,IAAA,qBAAc,EACnB,MAAM,MAAM,CAAC,WAAW,CACtB,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,EACnC,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,EACnC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAC7B,CACF,CAAC;QACJ,KAAK,iCAAc,CAAC,YAAY;YAC9B,OAAO,IAAA,qBAAc,EACnB,CACE,MAAM,MAAM,CAAC,WAAW,CACtB,MAAM,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EACzD,sBAAsB,EACtB;gBACE,QAAQ,EAAE,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC;gBACrC,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC;aAClC,CACF,CACF,CAAC,OAAO,CACV,CAAC;QACJ,KAAK,iCAAc,CAAC,sBAAsB;YACxC,OAAO,IAAA,qBAAc,EACnB,CACE,MAAM,MAAM,CAAC,WAAW,CACtB,MAAM,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EACzD,sCAAsC,EACtC,EAAE,CACH,CACF,CAAC,OAAO,CACV,CAAC;QACJ;YACE,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAA6B,EAAE,GAAW;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvE,CAAC;AAED,SAAS,iBAAiB,CAAC,IAA6B,EAAE,GAAW;IACnE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAEnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,IAA6B,EAAE,GAAW;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IAExB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,sBAAsB,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,KAAgC,CAAC;AAC1C,CAAC"}
package/dist/text.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export declare function stringifyMcpContent(value: unknown): string;
2
+ export declare function textToolResult(value: unknown): {
3
+ content: {
4
+ type: "text";
5
+ text: string;
6
+ }[];
7
+ };
8
+ export declare function errorToolResult(error: unknown): {
9
+ isError: boolean;
10
+ content: {
11
+ type: "text";
12
+ text: string;
13
+ }[];
14
+ };
package/dist/text.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stringifyMcpContent = stringifyMcpContent;
4
+ exports.textToolResult = textToolResult;
5
+ exports.errorToolResult = errorToolResult;
6
+ function stringifyMcpContent(value) {
7
+ if (typeof value === 'string') {
8
+ return value;
9
+ }
10
+ return JSON.stringify(value, null, 2);
11
+ }
12
+ function textToolResult(value) {
13
+ return {
14
+ content: [
15
+ {
16
+ type: 'text',
17
+ text: stringifyMcpContent(value),
18
+ },
19
+ ],
20
+ };
21
+ }
22
+ function errorToolResult(error) {
23
+ return {
24
+ isError: true,
25
+ content: [
26
+ {
27
+ type: 'text',
28
+ text: error instanceof Error ? error.message : String(error),
29
+ },
30
+ ],
31
+ };
32
+ }
33
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":";;AAAA,kDAMC;AAED,wCASC;AAED,0CAUC;AA7BD,SAAgB,mBAAmB,CAAC,KAAc;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,cAAc,CAAC,KAAc;IAC3C,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,mBAAmB,CAAC,KAAK,CAAC;aACjC;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe,CAAC,KAAc;IAC5C,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC7D;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ export declare const localToolNames: {
3
+ readonly listConfigs: "schemyx_list_configs";
4
+ readonly getLatestConfig: "schemyx_get_latest_config";
5
+ readonly getManifest: "schemyx_get_manifest";
6
+ readonly readResource: "schemyx_read_resource";
7
+ readonly callBackendTool: "schemyx_call_backend_tool";
8
+ readonly getThemeFile: "schemyx_get_theme_file";
9
+ readonly getImplementationGuide: "schemyx_get_implementation_guide";
10
+ };
11
+ export declare const localTools: Tool[];
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.localTools = exports.localToolNames = void 0;
4
+ exports.localToolNames = {
5
+ listConfigs: 'schemyx_list_configs',
6
+ getLatestConfig: 'schemyx_get_latest_config',
7
+ getManifest: 'schemyx_get_manifest',
8
+ readResource: 'schemyx_read_resource',
9
+ callBackendTool: 'schemyx_call_backend_tool',
10
+ getThemeFile: 'schemyx_get_theme_file',
11
+ getImplementationGuide: 'schemyx_get_implementation_guide',
12
+ };
13
+ exports.localTools = [
14
+ {
15
+ name: exports.localToolNames.listConfigs,
16
+ title: 'List Schemyx Configs',
17
+ description: 'List configs available to this Schemyx API key.',
18
+ inputSchema: objectSchema(),
19
+ annotations: readOnlyAnnotations(),
20
+ },
21
+ {
22
+ name: exports.localToolNames.getLatestConfig,
23
+ title: 'Get Latest Schemyx Config',
24
+ description: 'Read the latest stored config version and metadata.',
25
+ inputSchema: objectSchema({
26
+ configId: {
27
+ type: 'string',
28
+ description: 'Schemyx config id. Optional when only one config is available.',
29
+ },
30
+ }),
31
+ annotations: readOnlyAnnotations(),
32
+ },
33
+ {
34
+ name: exports.localToolNames.getManifest,
35
+ title: 'Get Schemyx Config Manifest',
36
+ description: 'List providers, resources, tools, and prompts for a config.',
37
+ inputSchema: objectSchema({
38
+ configId: {
39
+ type: 'string',
40
+ description: 'Schemyx config id. Optional when only one config is available.',
41
+ },
42
+ }),
43
+ annotations: readOnlyAnnotations(),
44
+ },
45
+ {
46
+ name: exports.localToolNames.readResource,
47
+ title: 'Read Schemyx Resource',
48
+ description: 'Read a backend MCP resource by config id and resource id.',
49
+ inputSchema: objectSchema({
50
+ configId: {
51
+ type: 'string',
52
+ description: 'Schemyx config id.',
53
+ },
54
+ resourceId: {
55
+ type: 'string',
56
+ description: 'Resource id from the config manifest, such as theme-forge.file.theme-css.',
57
+ },
58
+ }, ['configId', 'resourceId']),
59
+ annotations: readOnlyAnnotations(),
60
+ },
61
+ {
62
+ name: exports.localToolNames.callBackendTool,
63
+ title: 'Call Schemyx Backend Tool',
64
+ description: 'Call a read-only tool exposed by the Schemyx backend config manifest.',
65
+ inputSchema: objectSchema({
66
+ configId: {
67
+ type: 'string',
68
+ description: 'Schemyx config id.',
69
+ },
70
+ toolName: {
71
+ type: 'string',
72
+ description: 'Backend tool name from the config manifest.',
73
+ },
74
+ arguments: {
75
+ type: 'object',
76
+ description: 'Arguments to send to the backend tool.',
77
+ additionalProperties: true,
78
+ },
79
+ }, ['configId', 'toolName']),
80
+ annotations: readOnlyAnnotations(),
81
+ },
82
+ {
83
+ name: exports.localToolNames.getThemeFile,
84
+ title: 'Get Theme Forge File',
85
+ description: 'Read a generated Theme Forge artifact by file name or artifact id.',
86
+ inputSchema: objectSchema({
87
+ configId: {
88
+ type: 'string',
89
+ description: 'Schemyx config id. Optional when only one config is available.',
90
+ },
91
+ fileName: {
92
+ type: 'string',
93
+ description: 'Generated file name, such as themeforge.json, theme.css, or shadcn-globals.css.',
94
+ },
95
+ fileId: {
96
+ type: 'string',
97
+ description: 'Generated file id from the manifest.',
98
+ },
99
+ }),
100
+ annotations: readOnlyAnnotations(),
101
+ },
102
+ {
103
+ name: exports.localToolNames.getImplementationGuide,
104
+ title: 'Get Theme Implementation Guide',
105
+ description: 'Read AI-facing instructions for applying a saved Theme Forge theme.',
106
+ inputSchema: objectSchema({
107
+ configId: {
108
+ type: 'string',
109
+ description: 'Schemyx config id. Optional when only one config is available.',
110
+ },
111
+ }),
112
+ annotations: readOnlyAnnotations(),
113
+ },
114
+ ];
115
+ function objectSchema(properties = {}, required) {
116
+ return {
117
+ type: 'object',
118
+ properties,
119
+ ...(required ? { required } : {}),
120
+ };
121
+ }
122
+ function readOnlyAnnotations() {
123
+ return {
124
+ readOnlyHint: true,
125
+ destructiveHint: false,
126
+ idempotentHint: true,
127
+ openWorldHint: true,
128
+ };
129
+ }
130
+ //# sourceMappingURL=tool-definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ export interface LocalMcpConfig {
2
+ apiUrl: string;
3
+ apiKey: string;
4
+ projectId?: string;
5
+ configId?: string;
6
+ cacheTtlMs: number;
7
+ }
8
+ export interface McpConfigResponse {
9
+ id: string;
10
+ projectId: string;
11
+ name: string;
12
+ key: string;
13
+ type: string;
14
+ status: string;
15
+ source: string;
16
+ description: string | null;
17
+ targetPath: string | null;
18
+ schema: unknown;
19
+ validation: unknown;
20
+ metadata: unknown;
21
+ createdAt: string;
22
+ updatedAt: string;
23
+ latestVersion: {
24
+ id: string;
25
+ version: number;
26
+ content: unknown;
27
+ createdAt: string;
28
+ } | null;
29
+ }
30
+ export interface McpContextResponse {
31
+ apiKey: {
32
+ id: string;
33
+ teamId: string;
34
+ projectId: string | null;
35
+ scopes: unknown;
36
+ };
37
+ team: {
38
+ id: string;
39
+ name: string;
40
+ slug: string;
41
+ };
42
+ projects: Array<{
43
+ id: string;
44
+ teamId: string;
45
+ name: string;
46
+ slug: string;
47
+ description: string | null;
48
+ configs: McpConfigResponse[];
49
+ }>;
50
+ }
51
+ export interface BackendResourceDescriptor {
52
+ id: string;
53
+ uri: string;
54
+ name: string;
55
+ description: string;
56
+ mimeType: string;
57
+ kind: 'json' | 'text';
58
+ metadata?: Record<string, unknown>;
59
+ }
60
+ export interface BackendToolDescriptor {
61
+ name: string;
62
+ title: string;
63
+ description: string;
64
+ inputSchema: {
65
+ type: string;
66
+ properties?: Record<string, unknown>;
67
+ required?: string[];
68
+ additionalProperties?: boolean;
69
+ };
70
+ readOnly: boolean;
71
+ metadata?: Record<string, unknown>;
72
+ }
73
+ export interface BackendPromptDescriptor {
74
+ id: string;
75
+ name: string;
76
+ description: string;
77
+ arguments?: Array<{
78
+ name: string;
79
+ description: string;
80
+ required?: boolean;
81
+ }>;
82
+ }
83
+ export interface BackendConfigManifest {
84
+ configId: string;
85
+ providers: Array<{
86
+ id: string;
87
+ name: string;
88
+ }>;
89
+ resources: BackendResourceDescriptor[];
90
+ tools: BackendToolDescriptor[];
91
+ prompts: BackendPromptDescriptor[];
92
+ }
93
+ export interface BackendResourceContent {
94
+ resource: BackendResourceDescriptor;
95
+ content: unknown;
96
+ }
97
+ export interface BackendToolResult {
98
+ tool: BackendToolDescriptor;
99
+ content: unknown;
100
+ contentType: 'json' | 'text';
101
+ metadata?: Record<string, unknown>;
102
+ }
103
+ export interface DiscoveredConfig {
104
+ config: McpConfigResponse;
105
+ manifest: BackendConfigManifest;
106
+ }
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/dist/uri.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare const localResourcePrefix = "schemyx://configs/";
2
+ export declare function createLocalResourceUri(configId: string, resourceId: string): string;
3
+ export declare function parseLocalResourceUri(uri: string): {
4
+ configId: string;
5
+ resourceId: string;
6
+ };
package/dist/uri.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.localResourcePrefix = void 0;
4
+ exports.createLocalResourceUri = createLocalResourceUri;
5
+ exports.parseLocalResourceUri = parseLocalResourceUri;
6
+ exports.localResourcePrefix = 'schemyx://configs/';
7
+ function createLocalResourceUri(configId, resourceId) {
8
+ return `${exports.localResourcePrefix}${encodeURIComponent(configId)}/resources/${encodeURIComponent(resourceId)}`;
9
+ }
10
+ function parseLocalResourceUri(uri) {
11
+ const parsed = new URL(uri);
12
+ if (parsed.protocol !== 'schemyx:' || parsed.hostname !== 'configs') {
13
+ throw new Error(`Unsupported Schemyx resource URI: ${uri}`);
14
+ }
15
+ const [configId, resourceSegment, resourceId] = parsed.pathname
16
+ .split('/')
17
+ .filter((segment) => segment.length > 0)
18
+ .map((segment) => decodeURIComponent(segment));
19
+ if (!configId || resourceSegment !== 'resources' || !resourceId) {
20
+ throw new Error(`Unsupported Schemyx resource URI: ${uri}`);
21
+ }
22
+ return { configId, resourceId };
23
+ }
24
+ //# sourceMappingURL=uri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.js","sourceRoot":"","sources":["../src/uri.ts"],"names":[],"mappings":";;;AAEA,wDAIC;AAED,sDAiBC;AAzBY,QAAA,mBAAmB,GAAG,oBAAoB,CAAC;AAExD,SAAgB,sBAAsB,CAAC,QAAgB,EAAE,UAAkB;IACzE,OAAO,GAAG,2BAAmB,GAAG,kBAAkB,CAAC,QAAQ,CAAC,cAAc,kBAAkB,CAC1F,UAAU,CACX,EAAE,CAAC;AACN,CAAC;AAED,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAE5B,IAAI,MAAM,CAAC,QAAQ,KAAK,UAAU,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,CAAC,QAAQ,EAAE,eAAe,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,QAAQ;SAC5D,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;SACvC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;IAEjD,IAAI,CAAC,QAAQ,IAAI,eAAe,KAAK,WAAW,IAAI,CAAC,UAAU,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAClC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@schemyx/mcp",
3
+ "version": "0.1.0",
4
+ "description": "Local stdio MCP server for reading Schemyx project configs and Theme Forge artifacts.",
5
+ "license": "Proprietary",
6
+ "type": "commonjs",
7
+ "main": "dist/main.js",
8
+ "types": "dist/main.d.ts",
9
+ "bin": {
10
+ "schemyx-mcp": "dist/main.js"
11
+ },
12
+ "files": ["dist", "README.md"],
13
+ "scripts": {
14
+ "build": "tsc -p tsconfig.json",
15
+ "clean": "rm -rf dist",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "engines": {
19
+ "node": ">=18"
20
+ },
21
+ "dependencies": {
22
+ "@modelcontextprotocol/sdk": "^1.29.0"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ }
27
+ }