@sit-onyx/modelcontextprotocol 0.1.0-dev-20260409103041 → 0.1.0-dev-20260410085526

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,65 @@
1
+ # onyx MCP
2
+
3
+ This is the official [onyx](https://onyx.schwarz/) Model Context Protocol (or "MCP" for short) server.
4
+
5
+ ## Prerequisites
6
+
7
+ - [Node.js](https://nodejs.org/en) version as specified in [.node-version](./.node-version) file
8
+
9
+ ## Getting started
10
+
11
+ Install the CLI globally:
12
+
13
+ ```shell
14
+ # npm
15
+ npm install -g @sit-onyx/modelcontextprotocol
16
+
17
+ # pnpm
18
+ pnpm install -g @sit-onyx/modelcontextprotocol
19
+
20
+ ```
21
+
22
+ Now you can run the `onyx-mcp` command:
23
+
24
+ ```shell
25
+ onyx-mcp -h
26
+ ```
27
+
28
+ ### Using with the Gemini CLI
29
+
30
+ Add this entry to your Gemini settings (in `~/.gemini/settings.json`):
31
+
32
+ ```json
33
+ {
34
+ "$schema": "https://raw.githubusercontent.com/google-gemini/gemini-cli/main/schemas/settings.schema.json",
35
+ "mcp": {
36
+ "allowed": ["onyx-mcp"]
37
+ },
38
+ "mcpServers": {
39
+ "onyx-mcp": {
40
+ "description": "Information about components of the onyx UI component library",
41
+ "command": "onyx-mcp",
42
+ "args": ["-r"]
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ Save the file and confirm that the MCP has been set up correctly:
49
+
50
+ ```shell
51
+ gemini mcp list
52
+ ```
53
+
54
+ ## Development
55
+
56
+ Run this command in the monorepo root:
57
+
58
+ ```shell
59
+ pnpm run dev modelcontextprotocol
60
+ ```
61
+
62
+ This starts the "build" watcher and the [`@modelcontextprotocol/inspector`](https://github.com/modelcontextprotocol/inspector) locally.
63
+
64
+ You must reload the inspector browser website after changes to the `@sit-onyx/modelcontextprotocol` source code.
65
+ **Using the "Reconnect" button does not suffice!**
package/dist/index.d.ts CHANGED
@@ -1,20 +1,22 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { McpServer as McpServer_2 } from '@modelcontextprotocol/sdk/server/mcp';
3
+
4
+ export declare const createServer: ({ resourcesAsTools }: CreateServerOptions) => McpServer;
5
+
6
+ declare type CreateServerOptions = {
7
+ resourcesAsTools: boolean;
8
+ };
2
9
 
3
10
  /**
4
11
  * MCP server running as a http server.
5
12
  * `HOST` and `PORT` environment variable can be used to change the server settings.
6
13
  */
7
- export declare const http: () => Promise<void>;
8
-
9
- /**
10
- * Internal McpServer, which provides the MCP resources.
11
- */
12
- export declare const server: McpServer;
14
+ export declare const http: (server: McpServer_2) => Promise<void>;
13
15
 
14
16
  /**
15
17
  * MCP server running via stdio.
16
18
  * All logging has to use stderr, otherwise the logging to stdio will break the transport.
17
19
  */
18
- export declare const stdio: () => Promise<void>;
20
+ export declare const stdio: (server: McpServer_2) => Promise<void>;
19
21
 
20
22
  export { }
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { error, log } from "node:console";
4
4
  import { parseArgs } from "node:util";
5
5
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
6
  import { randomUUID } from "node:crypto";
7
- import { createServer } from "node:http";
7
+ import { createServer as createServer$1 } from "node:http";
8
8
  import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
9
9
  import { Readable } from "node:stream";
10
10
  import { buffer } from "node:stream/consumers";
@@ -66,7 +66,7 @@ var package_default = {
66
66
  scripts: {
67
67
  "dev": "pnpm run \"/build-dev|inspect-mcp/\"",
68
68
  "build-dev": "vite build --ssr -w",
69
- "inspect-mcp": "pnpm dlx @modelcontextprotocol/inspector node ./dist/index.js",
69
+ "inspect-mcp": "pnpm dlx @modelcontextprotocol/inspector --config inspector.json",
70
70
  "build": "vite build --ssr"
71
71
  },
72
72
  dependencies: { "@modelcontextprotocol/sdk": "^1.29.0" },
@@ -79,10 +79,37 @@ var package_default = {
79
79
  "typescript": "catalog:",
80
80
  "vite": "catalog:",
81
81
  "vite-plugin-dts": "^4.5.4",
82
- "vue-component-meta": "^3.2.6"
82
+ "vue-component-meta": "^3.2.6",
83
+ "zod": "^4.3.6"
83
84
  },
84
85
  engines: { "node": ">=20" }
85
86
  };
87
+ //#endregion
88
+ //#region src/server/http.ts
89
+ /**
90
+ * MCP server running as a http server.
91
+ * `HOST` and `PORT` environment variable can be used to change the server settings.
92
+ */
93
+ var run = async (server) => {
94
+ const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID() });
95
+ await server.connect(transport);
96
+ const httpServer = createServer$1(transport.handleRequest);
97
+ const PORT = Number.parseInt(process.env["PORT"] ?? "3000");
98
+ const HOST = process.env["HOST"] ?? "0.0.0.0";
99
+ httpServer.listen(PORT, HOST);
100
+ log(`MCP http server listening on ${HOST}:${PORT}.`);
101
+ };
102
+ //#endregion
103
+ //#region src/config.ts
104
+ var { version: version$2 } = package_default;
105
+ var USER_AGENT = `onyx-mcp/${version$2}`;
106
+ var REGISTRY_URL = process.env.REGISTRY_URL ?? "https://registry.npmjs.org";
107
+ /**
108
+ * Minimum `sit-onyx` version that provides the `component-meta.json` file
109
+ */
110
+ var SIT_ONYX_MIN_VERSION = "1.12.0";
111
+ var SIT_ONYX_COMPONENT_META_FILE = "package/dist/component-meta.json";
112
+ var SIT_ONYX_ICONS_METADATA_FILE = "package/dist/metadata.json";
86
113
  Object.freeze({ status: "aborted" });
87
114
  function $constructor(name, initializer, params) {
88
115
  function init(inst, def) {
@@ -522,6 +549,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
522
549
  }
523
550
  return result.value;
524
551
  };
552
+ var parse$1 = /* @__PURE__ */ _parse($ZodRealError);
525
553
  var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
526
554
  const ctx = _ctx ? Object.assign(_ctx, { async: true }) : { async: true };
527
555
  let result = schema._zod.run({
@@ -536,6 +564,7 @@ var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
536
564
  }
537
565
  return result.value;
538
566
  };
567
+ var parseAsync$1 = /* @__PURE__ */ _parseAsync($ZodRealError);
539
568
  var _safeParse = (_Err) => (schema, value, _ctx) => {
540
569
  const ctx = _ctx ? {
541
570
  ..._ctx,
@@ -648,7 +677,7 @@ function datetime$1(args) {
648
677
  const timeRegex = `${time}(?:${opts.join("|")})`;
649
678
  return new RegExp(`^${dateSource}T(?:${timeRegex})$`);
650
679
  }
651
- var string$1 = (params) => {
680
+ var string$2 = (params) => {
652
681
  const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
653
682
  return new RegExp(`^${regex}$`);
654
683
  };
@@ -1049,7 +1078,7 @@ var Doc = class {
1049
1078
  };
1050
1079
  //#endregion
1051
1080
  //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/versions.js
1052
- var version$2 = {
1081
+ var version$1 = {
1053
1082
  major: 4,
1054
1083
  minor: 3,
1055
1084
  patch: 6
@@ -1061,7 +1090,7 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
1061
1090
  inst ?? (inst = {});
1062
1091
  inst._zod.def = def;
1063
1092
  inst._zod.bag = inst._zod.bag || {};
1064
- inst._zod.version = version$2;
1093
+ inst._zod.version = version$1;
1065
1094
  const checks = [...inst._zod.def.checks ?? []];
1066
1095
  if (inst._zod.traits.has("$ZodCheck")) checks.unshift(inst);
1067
1096
  for (const ch of checks) for (const fn of ch._zod.onattach) fn(inst);
@@ -1146,7 +1175,7 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
1146
1175
  });
1147
1176
  var $ZodString = /* @__PURE__ */ $constructor("$ZodString", (inst, def) => {
1148
1177
  $ZodType.init(inst, def);
1149
- inst._zod.pattern = [...inst?._zod.bag?.patterns ?? []].pop() ?? string$1(inst._zod.bag);
1178
+ inst._zod.pattern = [...inst?._zod.bag?.patterns ?? []].pop() ?? string$2(inst._zod.bag);
1150
1179
  inst._zod.parse = (payload, _) => {
1151
1180
  if (def.coerce) try {
1152
1181
  payload.value = String(payload.value);
@@ -3529,7 +3558,7 @@ var ZodString = /* @__PURE__ */ $constructor("ZodString", (inst, def) => {
3529
3558
  inst.time = (params) => inst.check(time(params));
3530
3559
  inst.duration = (params) => inst.check(duration(params));
3531
3560
  });
3532
- function string(params) {
3561
+ function string$1(params) {
3533
3562
  return /* @__PURE__ */ _string(ZodString, params);
3534
3563
  }
3535
3564
  var ZodStringFormat = /* @__PURE__ */ $constructor("ZodStringFormat", (inst, def) => {
@@ -4008,34 +4037,34 @@ function superRefine(fn) {
4008
4037
  }
4009
4038
  //#endregion
4010
4039
  //#region ../../node_modules/.pnpm/zod-package-json@2.1.0_zod@4.3.6/node_modules/zod-package-json/dist/package-json.js
4011
- var Bugs = union([string(), object({
4012
- url: optional(string()),
4013
- email: optional(string())
4040
+ var Bugs = union([string$1(), object({
4041
+ url: optional(string$1()),
4042
+ email: optional(string$1())
4014
4043
  })]);
4015
4044
  var Funding = union([
4016
- string(),
4045
+ string$1(),
4017
4046
  object({
4018
- url: string(),
4019
- type: optional(string())
4047
+ url: string$1(),
4048
+ type: optional(string$1())
4020
4049
  }),
4021
- array(union([string(), object({
4022
- url: string(),
4023
- type: optional(string())
4050
+ array(union([string$1(), object({
4051
+ url: string$1(),
4052
+ type: optional(string$1())
4024
4053
  })]))
4025
4054
  ]);
4026
- var Person = union([string(), object({
4027
- name: string(),
4028
- email: optional(string()),
4029
- url: optional(string())
4055
+ var Person = union([string$1(), object({
4056
+ name: string$1(),
4057
+ email: optional(string$1()),
4058
+ url: optional(string$1())
4030
4059
  })]);
4031
- var Repository = union([string(), object({
4032
- type: string(),
4033
- url: string(),
4034
- directory: optional(string())
4060
+ var Repository = union([string$1(), object({
4061
+ type: string$1(),
4062
+ url: string$1(),
4063
+ directory: optional(string$1())
4035
4064
  })]);
4036
4065
  var DevEngineDependency = object({
4037
- name: string(),
4038
- version: optional(string()),
4066
+ name: string$1(),
4067
+ version: optional(string$1()),
4039
4068
  onFail: optional(literal([
4040
4069
  "ignore",
4041
4070
  "warn",
@@ -4051,57 +4080,57 @@ var DevEngines = object({
4051
4080
  packageManager: optional(DevEngineDependencies)
4052
4081
  });
4053
4082
  var PackageJson = looseObject({
4054
- name: string(),
4055
- version: string(),
4056
- description: optional(string()),
4057
- keywords: optional(array(string())),
4058
- homepage: optional(string()),
4083
+ name: string$1(),
4084
+ version: string$1(),
4085
+ description: optional(string$1()),
4086
+ keywords: optional(array(string$1())),
4087
+ homepage: optional(string$1()),
4059
4088
  bugs: optional(Bugs),
4060
- license: optional(string()),
4089
+ license: optional(string$1()),
4061
4090
  author: optional(Person),
4062
4091
  contributors: optional(array(Person)),
4063
4092
  maintainers: optional(array(Person)),
4064
4093
  funding: optional(Funding),
4065
- files: optional(array(string())),
4094
+ files: optional(array(string$1())),
4066
4095
  exports: optional(union([
4067
4096
  _null(),
4068
- string(),
4069
- array(string()),
4070
- record(string(), unknown())
4097
+ string$1(),
4098
+ array(string$1()),
4099
+ record(string$1(), unknown())
4071
4100
  ])),
4072
4101
  type: optional(literal(["module", "commonjs"])),
4073
- main: optional(string()),
4074
- browser: optional(union([string(), record(string(), union([string(), boolean()]))])),
4075
- bin: optional(union([string(), record(string(), string())])),
4076
- man: optional(union([string(), array(string())])),
4077
- directories: optional(record(string(), string())),
4102
+ main: optional(string$1()),
4103
+ browser: optional(union([string$1(), record(string$1(), union([string$1(), boolean()]))])),
4104
+ bin: optional(union([string$1(), record(string$1(), string$1())])),
4105
+ man: optional(union([string$1(), array(string$1())])),
4106
+ directories: optional(record(string$1(), string$1())),
4078
4107
  repository: optional(Repository),
4079
- scripts: optional(record(string(), string())),
4080
- config: optional(record(string(), unknown())),
4081
- dependencies: optional(record(string(), string())),
4082
- devDependencies: optional(record(string(), string())),
4083
- peerDependencies: optional(record(string(), string())),
4084
- peerDependenciesMeta: optional(record(string(), object({ optional: boolean() }))),
4085
- bundleDependencies: optional(union([boolean(), array(string())])),
4086
- bundledDependencies: optional(union([boolean(), array(string())])),
4087
- optionalDependencies: optional(record(string(), string())),
4088
- overrides: optional(record(string(), unknown())),
4089
- engines: optional(record(string(), string())),
4090
- os: optional(array(string())),
4091
- cpu: optional(array(string())),
4092
- libc: optional(string()),
4108
+ scripts: optional(record(string$1(), string$1())),
4109
+ config: optional(record(string$1(), unknown())),
4110
+ dependencies: optional(record(string$1(), string$1())),
4111
+ devDependencies: optional(record(string$1(), string$1())),
4112
+ peerDependencies: optional(record(string$1(), string$1())),
4113
+ peerDependenciesMeta: optional(record(string$1(), object({ optional: boolean() }))),
4114
+ bundleDependencies: optional(union([boolean(), array(string$1())])),
4115
+ bundledDependencies: optional(union([boolean(), array(string$1())])),
4116
+ optionalDependencies: optional(record(string$1(), string$1())),
4117
+ overrides: optional(record(string$1(), unknown())),
4118
+ engines: optional(record(string$1(), string$1())),
4119
+ os: optional(array(string$1())),
4120
+ cpu: optional(array(string$1())),
4121
+ libc: optional(string$1()),
4093
4122
  devEngines: optional(DevEngines),
4094
4123
  private: optional(boolean()),
4095
- publishConfig: optional(record(string(), unknown())),
4096
- workspaces: optional(array(string())),
4097
- deprecated: optional(string()),
4098
- module: optional(string()),
4099
- types: optional(string()),
4100
- typings: optional(string()),
4101
- typesVersions: optional(record(string(), record(string(), array(string())))),
4102
- packageManager: optional(string()),
4103
- sideEffects: optional(union([boolean(), array(string())])),
4104
- imports: optional(record(string(), unknown()))
4124
+ publishConfig: optional(record(string$1(), unknown())),
4125
+ workspaces: optional(array(string$1())),
4126
+ deprecated: optional(string$1()),
4127
+ module: optional(string$1()),
4128
+ types: optional(string$1()),
4129
+ typings: optional(string$1()),
4130
+ typesVersions: optional(record(string$1(), record(string$1(), array(string$1())))),
4131
+ packageManager: optional(string$1()),
4132
+ sideEffects: optional(union([boolean(), array(string$1())])),
4133
+ imports: optional(record(string$1(), unknown()))
4105
4134
  });
4106
4135
  //#endregion
4107
4136
  //#region ../../node_modules/.pnpm/quick-lru@7.3.0/node_modules/quick-lru/index.js
@@ -4502,14 +4531,14 @@ function assertValidPackageName(name) {
4502
4531
  (e.g., `{ "latest": "1.0.0" }`).
4503
4532
  */
4504
4533
  var DistTags = object({
4505
- latest: string(),
4506
- next: string().optional(),
4507
- alpha: string().optional(),
4508
- beta: string().optional(),
4509
- rc: string().optional(),
4510
- canary: string().optional(),
4511
- dev: string().optional()
4512
- }).catchall(string());
4534
+ latest: string$1(),
4535
+ next: string$1().optional(),
4536
+ alpha: string$1().optional(),
4537
+ beta: string$1().optional(),
4538
+ rc: string$1().optional(),
4539
+ canary: string$1().optional(),
4540
+ dev: string$1().optional()
4541
+ }).catchall(string$1());
4513
4542
  //#endregion
4514
4543
  //#region ../../node_modules/.pnpm/query-registry@4.3.0_zod@4.3.6/node_modules/query-registry/dist/fetch-data.js
4515
4544
  async function fetchData(schema, url, headers) {
@@ -4534,36 +4563,36 @@ var npmRegistryUrl = "https://registry.npmjs.org";
4534
4563
  @see {@link https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md#dist}
4535
4564
  */
4536
4565
  var Dist = object({
4537
- tarball: string(),
4538
- shasum: string(),
4539
- integrity: string().optional(),
4566
+ tarball: string$1(),
4567
+ shasum: string$1(),
4568
+ integrity: string$1().optional(),
4540
4569
  fileCount: number().optional(),
4541
4570
  unpackedSize: number().optional(),
4542
- "npm-signature": string().optional(),
4571
+ "npm-signature": string$1().optional(),
4543
4572
  signatures: array(object({
4544
- keyid: string(),
4545
- sig: string()
4573
+ keyid: string$1(),
4574
+ sig: string$1()
4546
4575
  })).optional()
4547
4576
  });
4548
4577
  var PackageManifest = object({
4549
4578
  ...PackageJson.shape,
4550
- _id: string(),
4579
+ _id: string$1(),
4551
4580
  dist: Dist,
4552
- readme: string().optional(),
4553
- readmeFilename: string().optional(),
4554
- gitHead: string().optional(),
4581
+ readme: string$1().optional(),
4582
+ readmeFilename: string$1().optional(),
4583
+ gitHead: string$1().optional(),
4555
4584
  _hasShrinkwrap: boolean().optional(),
4556
- _nodeVersion: string().optional(),
4557
- _npmVersion: string().optional(),
4585
+ _nodeVersion: string$1().optional(),
4586
+ _npmVersion: string$1().optional(),
4558
4587
  _npmUser: PackageJson.shape.author.optional(),
4559
4588
  _npmOperationalInternal: object({
4560
- host: string().optional(),
4561
- tmp: string().optional()
4589
+ host: string$1().optional(),
4590
+ tmp: string$1().optional()
4562
4591
  }).optional(),
4563
- engines: record(string(), string()).optional().catch(void 0),
4564
- license: string().optional().catch(void 0),
4565
- homepage: string().optional().catch(void 0),
4566
- deprecated: union([string(), boolean()]).optional(),
4592
+ engines: record(string$1(), string$1()).optional().catch(void 0),
4593
+ license: string$1().optional().catch(void 0),
4594
+ homepage: string$1().optional().catch(void 0),
4595
+ deprecated: union([string$1(), boolean()]).optional(),
4567
4596
  type: literal(["module", "commonjs"]).optional().catch(void 0)
4568
4597
  });
4569
4598
  /**
@@ -4582,10 +4611,10 @@ async function getPackageManifest(name, versionOrTag = "latest", registry = npmR
4582
4611
  //#endregion
4583
4612
  //#region ../../node_modules/.pnpm/query-registry@4.3.0_zod@4.3.6/node_modules/query-registry/dist/get-abbreviated-packument.js
4584
4613
  var AbbreviatedPackument = object({
4585
- name: string(),
4586
- modified: string(),
4614
+ name: string$1(),
4615
+ modified: string$1(),
4587
4616
  "dist-tags": DistTags,
4588
- versions: record(string(), object({
4617
+ versions: record(string$1(), object({
4589
4618
  ...PackageManifest.pick({
4590
4619
  name: true,
4591
4620
  version: true,
@@ -6848,28 +6877,19 @@ var require_pack = /* @__PURE__ */ __commonJSMin(((exports, module) => {
6848
6877
  }
6849
6878
  }));
6850
6879
  //#endregion
6851
- //#region src/config.ts
6880
+ //#region src/util/package.ts
6852
6881
  var import_tar_stream = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports) => {
6853
6882
  exports.extract = require_extract();
6854
6883
  exports.pack = require_pack();
6855
6884
  })))(), 1);
6856
- var { version: version$1 } = package_default;
6857
- var USER_AGENT = `onyx-mcp/${version$1}`;
6858
- var REGISTRY_URL = process.env.REGISTRY_URL ?? "https://registry.npmjs.org";
6859
- /**
6860
- * Minimum `sit-onyx` version that provides `vue-component-meta`
6861
- */
6862
- var SIT_ONYX_MIN_VERSION = "1.12.0";
6863
- //#endregion
6864
- //#region src/util/component-meta-json.ts
6865
6885
  var SuccessfulAbort = class {
6866
6886
  constructor(data) {
6867
6887
  this.data = data;
6868
6888
  }
6869
6889
  };
6870
- async function retrieveComponentMetaJsonFile(version) {
6871
- const { dist } = await getPackageManifest("sit-onyx", version, REGISTRY_URL);
6872
- const { body } = await fetch(dist.tarball, { headers: { "User-Agent": USER_AGENT } });
6890
+ async function getSingleFileFromPackage(packageIdent, matcher, userAgent) {
6891
+ const { dist } = await getPackageManifest(packageIdent.name, packageIdent.versionOrTag, packageIdent.registry);
6892
+ const { body } = await fetch(dist.tarball, { headers: { "User-Agent": userAgent } });
6873
6893
  if (!body) throw new Error(`No body in response for tarball request to "${dist.tarball}"!`);
6874
6894
  /**
6875
6895
  * Allows us to stop the stream pipeline at any time.
@@ -6878,26 +6898,23 @@ async function retrieveComponentMetaJsonFile(version) {
6878
6898
  const abortController = new AbortController();
6879
6899
  const archiveDownload = Readable.fromWeb(body);
6880
6900
  const decompress = createGunzip();
6881
- const fileSearcher = createTarFileSearcher(abortController);
6901
+ const fileSearcher = createTarFileSearcher(matcher, abortController);
6882
6902
  try {
6883
6903
  await pipeline(archiveDownload, decompress, fileSearcher, { signal: abortController.signal });
6884
- throw new Error("No 'component-meta.json' found!");
6904
+ throw new Error("No matching file found!");
6885
6905
  } catch (error) {
6886
- if (error instanceof Error && error.name === "AbortError" && error.cause instanceof SuccessfulAbort) {
6887
- const { data } = error.cause;
6888
- return JSON.parse(data.toString("utf-8"));
6889
- }
6906
+ if (error instanceof Error && error.name === "AbortError" && error.cause instanceof SuccessfulAbort) return error.cause.data;
6890
6907
  throw error;
6891
6908
  }
6892
6909
  }
6893
6910
  /**
6894
- * Returns a writable stream, which searches a file in a tar archive by filename/filepath.
6911
+ * Returns a writable stream, which searches a file in a tar archive.
6895
6912
  * If found, will call the AbortController with the file content as reason.
6896
6913
  */
6897
- function createTarFileSearcher(abortController) {
6914
+ function createTarFileSearcher(matcher, abortController) {
6898
6915
  const searchFile = import_tar_stream.extract();
6899
6916
  searchFile.on("entry", async (headers, stream, next) => {
6900
- if (headers.name === "package/dist/component-meta.json") {
6917
+ if (matcher(headers)) {
6901
6918
  const data = await buffer(stream);
6902
6919
  abortController.abort(new SuccessfulAbort(data));
6903
6920
  } else {
@@ -6908,6 +6925,15 @@ function createTarFileSearcher(abortController) {
6908
6925
  return searchFile;
6909
6926
  }
6910
6927
  //#endregion
6928
+ //#region src/util/component-meta-json.ts
6929
+ async function retrieveComponentMetaJsonFile(versionOrTag) {
6930
+ const data = await getSingleFileFromPackage({
6931
+ name: "sit-onyx",
6932
+ versionOrTag
6933
+ }, (header) => header.name === SIT_ONYX_COMPONENT_META_FILE, USER_AGENT);
6934
+ return JSON.parse(data.toString("utf-8"));
6935
+ }
6936
+ //#endregion
6911
6937
  //#region src/resources/get-component-api.ts
6912
6938
  /**
6913
6939
  * Returns true if both parameters are defined and equal (ignoring surrounding whitespaces and case)
@@ -6919,7 +6945,7 @@ var getComponentApi = [
6919
6945
  new ResourceTemplate("components://sit-onyx/{version}/{component}", { list: void 0 }),
6920
6946
  {
6921
6947
  title: "Get Component API",
6922
- description: "Get the component api for a specific component and version of onyx",
6948
+ description: "Gets the component API for a specific component and version of onyx",
6923
6949
  mimeType: "text/markdown"
6924
6950
  },
6925
6951
  async (uri, { version: _version, component: _component }) => {
@@ -7015,33 +7041,138 @@ var listComponents = [
7015
7041
  }
7016
7042
  ];
7017
7043
  //#endregion
7044
+ //#region src/util/icons-metadata-json.ts
7045
+ async function retrieveIconsMetadataJsonFile(versionOrTag) {
7046
+ const data = await getSingleFileFromPackage({
7047
+ name: "@sit-onyx/icons",
7048
+ versionOrTag
7049
+ }, (header) => header.name === SIT_ONYX_ICONS_METADATA_FILE, USER_AGENT);
7050
+ return JSON.parse(data.toString("utf-8"));
7051
+ }
7052
+ //#endregion
7053
+ //#region src/resources/list-icons.ts
7054
+ var listIcons = [
7055
+ "list-icons",
7056
+ new ResourceTemplate("icons://sit-onyx/{version}", { list: void 0 }),
7057
+ {
7058
+ title: "List @sit-onyx/icons icons",
7059
+ description: "List all icons available in a specific version of @sit-onyx/icons",
7060
+ mimeType: "text/markdown"
7061
+ },
7062
+ async (uri, { version: _version }) => {
7063
+ const version = Array.isArray(_version) ? _version[0] : _version;
7064
+ const iconsMetadata = await retrieveIconsMetadataJsonFile(version);
7065
+ const categoryMap = /* @__PURE__ */ new Map();
7066
+ Object.entries(iconsMetadata).forEach(([name, data]) => {
7067
+ if (!categoryMap.has(data.category)) categoryMap.set(data.category, []);
7068
+ categoryMap.get(data.category).push({
7069
+ name,
7070
+ ...data
7071
+ });
7072
+ });
7073
+ const text = `# Icons for \`@sit-onyx/icons@${version}\`
7074
+
7075
+ This is a list of all icons offered by the \`@sit-onyx/icons@${version}\` package.
7076
+ The icons are grouped by category.
7077
+
7078
+ ${categoryMap.entries().toArray().toSorted(([a], [b]) => a.localeCompare(b)).map(([category, icons]) => {
7079
+ return `## ${category}
7080
+
7081
+ ${icons.map(({ aliases, name }) => `- \`${name}\` (aliases: ${aliases.join(", ")})`).join("\n")}`;
7082
+ }).join("\n\n")}`;
7083
+ return { contents: [{
7084
+ uri: uri.href,
7085
+ text,
7086
+ mimeType: "text/markdown"
7087
+ }] };
7088
+ }
7089
+ ];
7090
+ //#endregion
7091
+ //#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/mini/schemas.js
7092
+ var ZodMiniType = /* @__PURE__ */ $constructor("ZodMiniType", (inst, def) => {
7093
+ if (!inst._zod) throw new Error("Uninitialized schema in ZodMiniType.");
7094
+ $ZodType.init(inst, def);
7095
+ inst.def = def;
7096
+ inst.type = def.type;
7097
+ inst.parse = (data, params) => parse$1(inst, data, params, { callee: inst.parse });
7098
+ inst.safeParse = (data, params) => safeParse$1(inst, data, params);
7099
+ inst.parseAsync = async (data, params) => parseAsync$1(inst, data, params, { callee: inst.parseAsync });
7100
+ inst.safeParseAsync = async (data, params) => safeParseAsync$1(inst, data, params);
7101
+ inst.check = (...checks) => {
7102
+ return inst.clone({
7103
+ ...def,
7104
+ checks: [...def.checks ?? [], ...checks.map((ch) => typeof ch === "function" ? { _zod: {
7105
+ check: ch,
7106
+ def: { check: "custom" },
7107
+ onattach: []
7108
+ } } : ch)]
7109
+ }, { parent: true });
7110
+ };
7111
+ inst.with = inst.check;
7112
+ inst.clone = (_def, params) => clone(inst, _def, params);
7113
+ inst.brand = () => inst;
7114
+ inst.register = ((reg, meta) => {
7115
+ reg.add(inst, meta);
7116
+ return inst;
7117
+ });
7118
+ inst.apply = (fn) => fn(inst);
7119
+ });
7120
+ var ZodMiniString = /* @__PURE__ */ $constructor("ZodMiniString", (inst, def) => {
7121
+ $ZodString.init(inst, def);
7122
+ ZodMiniType.init(inst, def);
7123
+ });
7124
+ /* @__NO_SIDE_EFFECTS__ */
7125
+ function string(params) {
7126
+ return /* @__PURE__ */ _string(ZodMiniString, params);
7127
+ }
7128
+ //#endregion
7129
+ //#region src/util/mcp-server.ts
7130
+ var resourceToTool = (resource) => {
7131
+ const [name, template, { title, description }, cb] = resource;
7132
+ const hasInputSchema = !!template.uriTemplate.variableNames.length;
7133
+ return [
7134
+ name,
7135
+ {
7136
+ title,
7137
+ description,
7138
+ inputSchema: hasInputSchema ? Object.fromEntries(template.uriTemplate.variableNames.map((v) => [v, /* @__PURE__ */ string()])) : void 0,
7139
+ annotations: {
7140
+ readOnlyHint: true,
7141
+ destructiveHint: false,
7142
+ idempotentHint: true
7143
+ }
7144
+ },
7145
+ (async (...args) => {
7146
+ const [vars, extra] = hasInputSchema ? args : [{}, args.at(0)];
7147
+ const { contents } = await cb(new URL(template.uriTemplate.expand(vars)), vars, extra);
7148
+ return { content: contents.map((resource) => ({
7149
+ type: "resource",
7150
+ resource
7151
+ })) };
7152
+ })
7153
+ ];
7154
+ };
7155
+ //#endregion
7018
7156
  //#region src/server/server.ts
7019
7157
  var { name, version, description } = package_default;
7020
- /**
7021
- * Internal McpServer, which provides the MCP resources.
7022
- */
7023
- var server = new McpServer({
7024
- name,
7025
- version,
7026
- description,
7027
- websiteUrl: "https://onyx.schwarz"
7028
- });
7029
- server.registerResource(...listComponents);
7030
- server.registerResource(...getComponentApi);
7031
- //#endregion
7032
- //#region src/server/http.ts
7033
- /**
7034
- * MCP server running as a http server.
7035
- * `HOST` and `PORT` environment variable can be used to change the server settings.
7036
- */
7037
- var run = async () => {
7038
- const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID() });
7039
- await server.connect(transport);
7040
- const httpServer = createServer(transport.handleRequest);
7041
- const PORT = Number.parseInt(process.env["PORT"] ?? "3000");
7042
- const HOST = process.env["HOST"] ?? "0.0.0.0";
7043
- httpServer.listen(PORT, HOST);
7044
- log(`MCP http server listening on ${HOST}:${PORT}.`);
7158
+ var resources = [
7159
+ listComponents,
7160
+ getComponentApi,
7161
+ listIcons
7162
+ ];
7163
+ var createServer = ({ resourcesAsTools }) => {
7164
+ /**
7165
+ * Internal McpServer, which provides the MCP resources.
7166
+ */
7167
+ const server = new McpServer({
7168
+ name,
7169
+ version,
7170
+ description,
7171
+ websiteUrl: "https://onyx.schwarz"
7172
+ });
7173
+ resources.forEach((resource) => server.registerResource(...resource));
7174
+ if (resourcesAsTools) resources.map((r) => resourceToTool(r)).forEach((t) => server.registerTool(...t));
7175
+ return server;
7045
7176
  };
7046
7177
  //#endregion
7047
7178
  //#region src/server/stdio.ts
@@ -7049,7 +7180,7 @@ var run = async () => {
7049
7180
  * MCP server running via stdio.
7050
7181
  * All logging has to use stderr, otherwise the logging to stdio will break the transport.
7051
7182
  */
7052
- var run$1 = async () => {
7183
+ var run$1 = async (server) => {
7053
7184
  const transport = new StdioServerTransport();
7054
7185
  await server.connect(transport);
7055
7186
  error("MCP Server running on stdio.");
@@ -7061,7 +7192,7 @@ var SUPPORTED_TRANSPORTS = {
7061
7192
  http: run
7062
7193
  };
7063
7194
  if (import.meta.main) {
7064
- const { values: { transport, version, help } } = parseArgs({
7195
+ const { values: { transport, version, help, resourcesAsTools } } = parseArgs({
7065
7196
  args: process.argv.slice(2),
7066
7197
  options: {
7067
7198
  transport: {
@@ -7069,6 +7200,11 @@ if (import.meta.main) {
7069
7200
  short: "t",
7070
7201
  default: "stdio"
7071
7202
  },
7203
+ resourcesAsTools: {
7204
+ type: "boolean",
7205
+ short: "r",
7206
+ default: false
7207
+ },
7072
7208
  help: {
7073
7209
  type: "boolean",
7074
7210
  short: "h",
@@ -7091,17 +7227,20 @@ Usage:
7091
7227
  onyx-mcp [options]
7092
7228
 
7093
7229
  Options:
7094
- -t, --transport <stdio|http> Which kind of MCP server should be started (default: stdio)
7095
- -h, --help This help text
7096
- -v, --version Show version number and quit`);
7230
+ -t, --transport <stdio|http> Which kind of MCP server should be started (default: stdio).
7231
+ -r, --resourcesAsTools Some LLM Coding Assistants (e.g. Gemini) are not able to to use MCP resources (yet).
7232
+ This setting makes resources also available as tools to support these Coding Assistants.
7233
+ -h, --help Show this help text and quit.
7234
+ -v, --version Show version number and quit.`);
7097
7235
  process.exit(0);
7098
7236
  } else if (version) {
7099
7237
  log(package_default.version);
7100
7238
  process.exit(0);
7101
7239
  } else {
7102
7240
  if (!Object.keys(SUPPORTED_TRANSPORTS).includes(transport)) throw new Error(`Unsupported transport: ${transport}`);
7103
- await SUPPORTED_TRANSPORTS[transport]();
7241
+ const server = createServer({ resourcesAsTools });
7242
+ await SUPPORTED_TRANSPORTS[transport](server);
7104
7243
  }
7105
7244
  }
7106
7245
  //#endregion
7107
- export { run as http, server, run$1 as stdio };
7246
+ export { createServer, run as http, run$1 as stdio };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sit-onyx/modelcontextprotocol",
3
- "version": "0.1.0-dev-20260409103041",
3
+ "version": "0.1.0-dev-20260410085526",
4
4
  "description": "MCP (Model Context Protocol) Server that provide onyx specific tools and resources.",
5
5
  "homepage": "https://onyx.schwarz",
6
6
  "bugs": {
@@ -34,6 +34,7 @@
34
34
  "vite": "8.0.5",
35
35
  "vite-plugin-dts": "^4.5.4",
36
36
  "vue-component-meta": "^3.2.6",
37
+ "zod": "^4.3.6",
37
38
  "@sit-onyx/shared": "^0.1.0"
38
39
  },
39
40
  "engines": {
@@ -42,7 +43,7 @@
42
43
  "scripts": {
43
44
  "dev": "pnpm run \"/build-dev|inspect-mcp/\"",
44
45
  "build-dev": "vite build --ssr -w",
45
- "inspect-mcp": "pnpm dlx @modelcontextprotocol/inspector node ./dist/index.js",
46
+ "inspect-mcp": "pnpm dlx @modelcontextprotocol/inspector --config inspector.json",
46
47
  "build": "vite build --ssr"
47
48
  }
48
49
  }