@sit-onyx/modelcontextprotocol 0.0.0 → 0.1.0-dev-20260409084453

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sit-onyx/modelcontextprotocol",
3
- "version": "0.0.0",
3
+ "version": "0.1.0-dev-20260409084453",
4
4
  "description": "MCP (Model Context Protocol) Server that provide onyx specific tools and resources.",
5
5
  "homepage": "https://onyx.schwarz",
6
6
  "bugs": {
@@ -9,12 +9,13 @@
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "https://github.com/SchwarzIT/onyx",
12
- "directory": "apps/modelcontextprotocol"
12
+ "directory": "packages/modelcontextprotocol"
13
13
  },
14
14
  "license": "Apache-2.0",
15
15
  "author": "Schwarz IT KG",
16
16
  "type": "module",
17
- "main": "index.js",
17
+ "main": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
18
19
  "bin": {
19
20
  "onyx-mcp": "./dist/index.js"
20
21
  },
@@ -27,18 +28,21 @@
27
28
  "devDependencies": {
28
29
  "@types/node": "24.12.0",
29
30
  "@types/tar-stream": "^3.1.4",
30
- "pacote": "^21.5.0",
31
31
  "query-registry": "^4.3.0",
32
32
  "tar-stream": "^3.1.8",
33
33
  "typescript": "5.9.3",
34
- "url-join": "^5.0.0",
35
- "vue-component-meta": "^3.2.6"
34
+ "vite": "8.0.3",
35
+ "vite-plugin-dts": "^4.5.4",
36
+ "vue-component-meta": "^3.2.6",
37
+ "@sit-onyx/shared": "^0.1.0"
36
38
  },
37
39
  "engines": {
38
40
  "node": ">=20"
39
41
  },
40
42
  "scripts": {
41
- "build": "tsc",
42
- "test": "echo \"Error: no test specified\" && exit 1"
43
+ "dev": "pnpm run \"/build-dev|inspect-mcp/\"",
44
+ "build-dev": "vite build --ssr -w",
45
+ "inspect-mcp": "pnpm dlx @modelcontextprotocol/inspector node ./dist/index.js",
46
+ "build": "vite build --ssr"
43
47
  }
44
48
  }
package/dist/config.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export declare const USER_AGENT: string;
2
- export declare const REGISTRY_URL: string;
3
- export declare const SIT_ONYX_MIN_VERSION = "1.0.0";
4
- export declare const SIT_ONYX_COMPONENT_META_FILE = "package/dist/component-meta.json";
package/dist/config.js DELETED
@@ -1,6 +0,0 @@
1
- import packageJson from "../package.json" with { type: "json" };
2
- const { version } = packageJson;
3
- export const USER_AGENT = `onyx-mcp/${version}`;
4
- export const REGISTRY_URL = process.env.REGISTRY_URL ?? "https://registry.npmjs.org";
5
- export const SIT_ONYX_MIN_VERSION = "1.0.0";
6
- export const SIT_ONYX_COMPONENT_META_FILE = "package/dist/component-meta.json";
@@ -1,2 +0,0 @@
1
- import type { RegisterableResource } from "../types.js";
2
- export declare const getComponentApi: RegisterableResource;
@@ -1,92 +0,0 @@
1
- import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { retrieveComponentMetaJsonFile } from "../util/component-meta-json.js";
3
- /**
4
- * Returns true if both parameters are defined and equal (ignoring surrounding whitespaces and case)
5
- */
6
- const compareDefined = (a, b) => a && b && a.trim().toLowerCase() === b.trim().toLowerCase();
7
- const tagsToList = (tags) => tags
8
- .filter(({ name }) => !!name)
9
- .map(({ text, name }) => `- ${name}: ${text}`)
10
- .join("\n");
11
- export const getComponentApi = [
12
- "get-component-api",
13
- new ResourceTemplate("components://sit-onyx/{version}/{component}", {
14
- list: undefined,
15
- }),
16
- {
17
- title: "Get Component API",
18
- description: "Get the component api for a specific component and version of onyx",
19
- mimeType: "text/markdown",
20
- },
21
- async (uri, { version: _version, component: _component }) => {
22
- const version = Array.isArray(_version) ? _version[0] : _version;
23
- const component = Array.isArray(_component) ? _component[0] : _component;
24
- const componentMetaJson = await retrieveComponentMetaJsonFile(version);
25
- const componentMeta = componentMetaJson.find(({ displayName, name }) => compareDefined(displayName, name) || compareDefined(name, component));
26
- if (!componentMeta) {
27
- throw new Error(`Component ${component} not found for version ${version}`);
28
- }
29
- // TODO: improve code readability through use of better templating
30
- const propsText = componentMeta.props
31
- .map((prop) => `### ${prop.name}
32
-
33
- - required: ${prop.required}
34
- - type: ${prop.type}
35
- ${tagsToList(prop.tags)}
36
-
37
- ${prop.description}`)
38
- .join("\n\n");
39
- const slotsText = componentMeta.slots
40
- .map((slot) => `### ${slot.name}
41
-
42
- ${tagsToList(slot.tags)}
43
-
44
- ${slot.description}`)
45
- .join("\n\n");
46
- const eventsText = componentMeta.events
47
- .map((event) => `### ${event.name}
48
-
49
- - type: ${event.type}
50
- ${tagsToList(event.tags)}
51
-
52
- ${event.description}`)
53
- .join("\n\n");
54
- const exposedText = componentMeta.exposed
55
- .map((exposed) => `### ${exposed.name}
56
-
57
- - type: ${exposed.type}
58
- ${tagsToList(exposed.tags)}
59
-
60
- ${exposed.description}`)
61
- .join("\n\n");
62
- const text = `# Component API of \`${componentMeta.displayName}\`
63
-
64
- *Version: \`sit-onyx@${version}\`*
65
-
66
- ## Props
67
-
68
- ${propsText}
69
-
70
- ## Slots
71
-
72
- ${slotsText}
73
-
74
- ## Events
75
-
76
- ${eventsText}
77
-
78
- ## Exposed
79
-
80
- ${exposedText}
81
- `;
82
- return {
83
- contents: [
84
- {
85
- uri: uri.href,
86
- text,
87
- mimeType: "text/markdown",
88
- },
89
- ],
90
- };
91
- },
92
- ];
@@ -1,2 +0,0 @@
1
- import type { RegisterableResource } from "../types.js";
2
- export declare const listComponents: RegisterableResource;
@@ -1,41 +0,0 @@
1
- import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { getAbbreviatedPackument } from "query-registry";
3
- import { REGISTRY_URL, SIT_ONYX_MIN_VERSION } from "../config.js";
4
- import { retrieveComponentMetaJsonFile } from "../util/component-meta-json.js";
5
- export const listComponents = [
6
- "list-components",
7
- new ResourceTemplate("components://sit-onyx/{version}", {
8
- list: async () => {
9
- const { versions } = await getAbbreviatedPackument("sit-onyx", REGISTRY_URL);
10
- const relevantVersions = Object.keys(versions).filter((version) => version.split("-").at(0) ?? "" >= SIT_ONYX_MIN_VERSION);
11
- const resources = relevantVersions.map((version) => ({
12
- uri: `components://sit-onyx/${version}`,
13
- name: version,
14
- }));
15
- return { resources };
16
- },
17
- }),
18
- {
19
- title: "Component Overview",
20
- description: "Lists all components for a specific version of onyx",
21
- mimeType: "text/markdown",
22
- },
23
- async (uri, { version: _version }) => {
24
- const version = Array.isArray(_version) ? _version[0] : _version;
25
- const componentMetaJson = await retrieveComponentMetaJsonFile(version);
26
- const componentsText = componentMetaJson
27
- .toSorted((a, b) => a.displayName.localeCompare(b.displayName))
28
- .map(({ displayName, description }) => `## ${displayName}\n\n${description ?? ""}\n`)
29
- .join("\n");
30
- const text = `# Components for \`sit-onyx@${version}\`\n\n${componentsText}`;
31
- return {
32
- contents: [
33
- {
34
- uri: uri.href,
35
- text,
36
- mimeType: "text/markdown",
37
- },
38
- ],
39
- };
40
- },
41
- ];
@@ -1 +0,0 @@
1
- export {};
@@ -1,118 +0,0 @@
1
- export {};
2
- /* import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
3
- import type { RegisterableResource } from "../types.js";
4
- import { retrieveComponentMetaJsonFile } from "../util/component-meta-json.js";
5
-
6
- const compareDefined = (a: string | undefined | null, b: string | undefined | null) =>
7
- a && b && a.trim().toLowerCase() === b.trim().toLowerCase();
8
-
9
- type Tag = {
10
- name?: string;
11
- text?: string;
12
- };
13
-
14
- const tagsToList = (tags: Tag[]) =>
15
- tags
16
- .filter(({ name }) => !!name)
17
- .map(({ text, name }) => `- ${name}: ${text}`)
18
- .join("\n");
19
-
20
- export const listIcons: RegisterableResource = [
21
- "list-icons",
22
- new ResourceTemplate("icons://sit-onyx/{version}", {
23
- list: undefined,
24
- }),
25
- {
26
- title: "List @sit-onyx/icons icons",
27
- description: "List all icons available in a specific version of @sit-onyx/icons",
28
- mimeType: "text/markdown",
29
- },
30
- async (uri, { version: _version }) => {
31
- const version = Array.isArray(_version) ? _version[0] : _version;
32
- const componentMetaJson = await retrieveComponentMetaJsonFile(version);
33
- const componentMeta = componentMetaJson.find(
34
- ({ displayName, name }) =>
35
- compareDefined(displayName, name) || compareDefined(name, component),
36
- );
37
-
38
- if (!componentMeta) {
39
- throw new Error(`Component ${component} not found for version ${version}`);
40
- }
41
-
42
- const propsText = componentMeta.props
43
- .map(
44
- (prop) => `### ${prop.name}
45
-
46
- - required: ${prop.required}
47
- - type: ${prop.type}
48
- ${tagsToList(prop.tags)}
49
-
50
- ${prop.description}`,
51
- )
52
- .join("\n\n");
53
-
54
- const slotsText = componentMeta.slots
55
- .map(
56
- (slot) => `### ${slot.name}
57
-
58
- ${tagsToList(slot.tags)}
59
-
60
- ${slot.description}`,
61
- )
62
- .join("\n\n");
63
-
64
- const eventsText = componentMeta.events
65
- .map(
66
- (event) => `### ${event.name}
67
-
68
- - type: ${event.type}
69
- ${tagsToList(event.tags)}
70
-
71
- ${event.description}`,
72
- )
73
- .join("\n\n");
74
-
75
- const exposedText = componentMeta.exposed
76
- .map(
77
- (exposed) => `### ${exposed.name}
78
-
79
- - type: ${exposed.type}
80
- ${tagsToList(exposed.tags)}
81
-
82
- ${exposed.description}`,
83
- )
84
- .join("\n\n");
85
-
86
- const text = `# Component API of \`${componentMeta.displayName}\`
87
-
88
- *Version: \`sit-onyx@${version}\`*
89
-
90
- ## Props
91
-
92
- ${propsText}
93
-
94
- ## Slots
95
-
96
- ${slotsText}
97
-
98
- ## Events
99
-
100
- ${eventsText}
101
-
102
- ## Exposed
103
-
104
- ${exposedText}
105
- `;
106
-
107
- return {
108
- contents: [
109
- {
110
- uri: uri.href,
111
- text,
112
- mimeType: "text/markdown",
113
- },
114
- ],
115
- };
116
- },
117
- ];
118
- */
@@ -1,5 +0,0 @@
1
- /**
2
- * MCP server running as a http server.
3
- * `HOST` and `PORT` environment variable can be used to change the server settings.
4
- */
5
- export declare const run: () => Promise<void>;
@@ -1,20 +0,0 @@
1
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
2
- import { randomUUID } from "node:crypto";
3
- import { createServer } from "node:http";
4
- import { server } from "./server.js";
5
- import { error } from "node:console";
6
- /**
7
- * MCP server running as a http server.
8
- * `HOST` and `PORT` environment variable can be used to change the server settings.
9
- */
10
- export const run = async () => {
11
- const transport = new StreamableHTTPServerTransport({
12
- sessionIdGenerator: () => randomUUID(),
13
- });
14
- await server.connect(transport);
15
- const httpServer = createServer(transport.handleRequest);
16
- const PORT = Number.parseInt(process.env["PORT"] ?? "3000");
17
- const HOST = process.env["HOST"] ?? "0.0.0.0";
18
- httpServer.listen(PORT, HOST);
19
- error(`MCP http server listening on ${HOST}:${PORT}.`);
20
- };
@@ -1,6 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- /**
3
- * Internal McpServer, which provides the MCP resources.
4
- */
5
- declare const server: McpServer;
6
- export { server };
@@ -1,17 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import packageJson from "../../package.json" with { type: "json" };
3
- import { getComponentApi } from "../resources/get-component-api.js";
4
- import { listComponents } from "../resources/list-components.js";
5
- const { name, version, description } = packageJson;
6
- /**
7
- * Internal McpServer, which provides the MCP resources.
8
- */
9
- const server = new McpServer({
10
- name,
11
- version,
12
- description,
13
- websiteUrl: "https://onyx.schwarz",
14
- });
15
- server.registerResource(...listComponents);
16
- server.registerResource(...getComponentApi);
17
- export { server };
@@ -1,5 +0,0 @@
1
- /**
2
- * MCP server running via stdio.
3
- * All logging has to use stderr, otherwise the logging to stdio will break the transport.
4
- */
5
- export declare const run: () => Promise<void>;
@@ -1,12 +0,0 @@
1
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
- import { error } from "node:console";
3
- import { server } from "./server.js";
4
- /**
5
- * MCP server running via stdio.
6
- * All logging has to use stderr, otherwise the logging to stdio will break the transport.
7
- */
8
- export const run = async () => {
9
- const transport = new StdioServerTransport();
10
- await server.connect(transport);
11
- error("MCP Server running on stdio.");
12
- };
@@ -1,10 +0,0 @@
1
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
2
- import { randomUUID } from "node:crypto";
3
- import { server } from "./server.js";
4
- export const run = async () => {
5
- const transport = new StreamableHTTPServerTransport({
6
- sessionIdGenerator: () => randomUUID(),
7
- });
8
- await server.connect(transport);
9
- console.error("Weather MCP Server running on stdio");
10
- };
package/dist/types.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { type ComponentMeta, type MetaCheckerOptions } from "vue-component-meta";
3
- export type RegisterableResource = Parameters<InstanceType<typeof McpServer>["registerResource"]>;
4
- export type MetaSource = {
5
- exportName: string;
6
- displayName: string;
7
- } & ComponentMeta & Exclude<MetaCheckerOptions["schema"], boolean>;
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- import type { MetaSource } from "../types.js";
2
- export declare function retrieveComponentMetaJsonFile(version: string): Promise<MetaSource[]>;
@@ -1,64 +0,0 @@
1
- import { Readable } from "node:stream";
2
- import { buffer } from "node:stream/consumers";
3
- import { pipeline } from "node:stream/promises";
4
- import { createGunzip } from "node:zlib";
5
- import { getPackageManifest } from "query-registry";
6
- import tarStream from "tar-stream";
7
- import { REGISTRY_URL, SIT_ONYX_COMPONENT_META_FILE } from "../config.js";
8
- class SuccessfulAbort {
9
- data;
10
- constructor(data) {
11
- this.data = data;
12
- }
13
- }
14
- // TODO: It's quite fast, but we should add caching nevertheless.
15
- export async function retrieveComponentMetaJsonFile(version) {
16
- const { dist } = await getPackageManifest("sit-onyx", version, REGISTRY_URL);
17
- const { body } = await fetch(dist.tarball);
18
- if (!body) {
19
- throw new Error(`No body in response for tarball request to "${dist.tarball}"!`);
20
- }
21
- /**
22
- * Allows us to stop the stream pipeline at any time.
23
- * We also use the abort reason to emit the result.
24
- */
25
- const abortController = new AbortController();
26
- const archiveDownload = Readable.fromWeb(body); // Incorrect typing, see: https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/65542#discussioncomment-6071004
27
- const decompress = createGunzip();
28
- const fileSearcher = createTarFileSearcher(abortController);
29
- try {
30
- await pipeline(archiveDownload, decompress, fileSearcher, { signal: abortController.signal });
31
- throw new Error("No 'component-meta.json' found!");
32
- }
33
- catch (error) {
34
- if (error instanceof Error &&
35
- error.name === "AbortError" &&
36
- error.cause instanceof SuccessfulAbort) {
37
- // Return the found data as parsed JSON
38
- const { data } = error.cause;
39
- return JSON.parse(data.toString("utf-8"));
40
- }
41
- // Re-throw any other error
42
- throw error;
43
- }
44
- }
45
- /**
46
- * Returns a writable stream, which searches a file in a tar archive by filename/filepath.
47
- * If found, will call the AbortController with the file content as reason.
48
- */
49
- function createTarFileSearcher(abortController) {
50
- const searchFile = tarStream.extract();
51
- searchFile.on("entry", async (headers, stream, next) => {
52
- if (headers.name === SIT_ONYX_COMPONENT_META_FILE) {
53
- const data = await buffer(stream);
54
- // found the relevant file, stop further processing
55
- abortController.abort(new SuccessfulAbort(data));
56
- }
57
- else {
58
- // continue searching
59
- stream.resume();
60
- next();
61
- }
62
- });
63
- return searchFile;
64
- }
@@ -1,2 +0,0 @@
1
- import type { MetaSource } from "../types.js";
2
- export declare function retrieveComponentMetaJsonFile(version: string): Promise<MetaSource[]>;
@@ -1,63 +0,0 @@
1
- import { Readable } from "node:stream";
2
- import { buffer } from "node:stream/consumers";
3
- import { pipeline } from "node:stream/promises";
4
- import { createGunzip } from "node:zlib";
5
- import { getPackageManifest } from "query-registry";
6
- import tarStream from "tar-stream";
7
- import { REGISTRY_URL, SIT_ONYX_COMPONENT_META_FILE } from "../config.js";
8
- class SuccessfulAbort {
9
- data;
10
- constructor(data) {
11
- this.data = data;
12
- }
13
- }
14
- export async function retrieveComponentMetaJsonFile(version) {
15
- const { dist } = await getPackageManifest("@sit-onyx/icons", version, REGISTRY_URL);
16
- const { body } = await fetch(dist.tarball);
17
- if (!body) {
18
- throw new Error(`No body in response for tarball request to "${dist.tarball}"!`);
19
- }
20
- /**
21
- * Allows us to stop the stream pipeline at any time.
22
- * We also use the abort reason to emit the result.
23
- */
24
- const abortController = new AbortController();
25
- const archiveDownload = Readable.fromWeb(body); // Incorrect typing, see: https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/65542#discussioncomment-6071004
26
- const decompress = createGunzip();
27
- const fileSearcher = createTarFileSearcher(abortController);
28
- try {
29
- await pipeline(archiveDownload, decompress, fileSearcher, { signal: abortController.signal });
30
- throw new Error("No 'component-meta.json' found!");
31
- }
32
- catch (error) {
33
- if (error instanceof Error &&
34
- error.name === "AbortError" &&
35
- error.cause instanceof SuccessfulAbort) {
36
- // Return the found data as parsed JSON
37
- const { data } = error.cause;
38
- return JSON.parse(data.toString("utf-8"));
39
- }
40
- // Re-throw any other error
41
- throw error;
42
- }
43
- }
44
- /**
45
- * Returns a writable stream, which searches a file in a tar archive by filename/filepath.
46
- * If found, will call the AbortController with the file content as reason.
47
- */
48
- function createTarFileSearcher(abortController) {
49
- const searchFile = tarStream.extract();
50
- searchFile.on("entry", async (headers, stream, next) => {
51
- if (headers.name === SIT_ONYX_COMPONENT_META_FILE) {
52
- const data = await buffer(stream);
53
- // found the relevant file, stop further processing
54
- abortController.abort(new SuccessfulAbort(data));
55
- }
56
- else {
57
- // continue searching
58
- stream.resume();
59
- next();
60
- }
61
- });
62
- return searchFile;
63
- }