@skeletiq/mcp 0.7.0 → 0.7.2
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 +2 -0
- package/dist/index.js +41 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,6 +56,8 @@ Run `npx -y @skeletiq/mcp` over stdio with `SKELETIQ_API_KEY` in the environment
|
|
|
56
56
|
| `SKELETIQ_API_KEY` | yes | — | A personal API token, starting `skq_`. Not a browser session token. |
|
|
57
57
|
| `SKELETIQ_API_URL` | no | `https://api.skeletiq.com` | For self-hosted installs. A trailing `/api/v1` is accepted and trimmed. |
|
|
58
58
|
|
|
59
|
+
Every request carries a User-Agent of the form `skeletiq-mcp/<version> (<host name>/<host version>)`, naming the MCP host that launched the server.
|
|
60
|
+
|
|
59
61
|
## Scopes
|
|
60
62
|
|
|
61
63
|
A token grants only what you tick. The server's tools need:
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
|
5
5
|
|
|
6
6
|
// src/config.ts
|
|
7
7
|
var SERVER_NAME = "skeletiq";
|
|
8
|
-
var SERVER_VERSION = "0.7.
|
|
8
|
+
var SERVER_VERSION = "0.7.2";
|
|
9
9
|
var AGENT_SCHEMA_VERSION = 2;
|
|
10
10
|
function schemaNote(serverVersion) {
|
|
11
11
|
if (serverVersion === void 0 || serverVersion <= AGENT_SCHEMA_VERSION) return null;
|
|
@@ -43,7 +43,7 @@ function normalizeApiUrl(raw) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// src/server.ts
|
|
46
|
-
import { McpServer } from "@modelcontextprotocol/server";
|
|
46
|
+
import { CLIENT_INFO_META_KEY, McpServer } from "@modelcontextprotocol/server";
|
|
47
47
|
|
|
48
48
|
// src/http/errors.ts
|
|
49
49
|
var SkeletiqApiError = class extends Error {
|
|
@@ -199,12 +199,28 @@ function describeApiError(error) {
|
|
|
199
199
|
|
|
200
200
|
// src/http/client.ts
|
|
201
201
|
var API_PREFIX = "/api/v1";
|
|
202
|
+
var HOST_TOKEN_MAX = 64;
|
|
203
|
+
function hostToken(value) {
|
|
204
|
+
return value.replace(/[^A-Za-z0-9._~+-]/g, "-").slice(0, HOST_TOKEN_MAX);
|
|
205
|
+
}
|
|
206
|
+
function userAgent(host) {
|
|
207
|
+
const base = `${SERVER_NAME}-mcp/${SERVER_VERSION}`;
|
|
208
|
+
const name = hostToken(host?.name ?? "");
|
|
209
|
+
if (!name) return base;
|
|
210
|
+
const version = hostToken(host?.version ?? "");
|
|
211
|
+
return version ? `${base} (${name}/${version})` : `${base} (${name})`;
|
|
212
|
+
}
|
|
202
213
|
var READ_TIMEOUT_MS = 6e5;
|
|
203
214
|
var SkeletiqClient = class {
|
|
204
215
|
config;
|
|
216
|
+
hostSource;
|
|
205
217
|
constructor(config) {
|
|
206
218
|
this.config = config;
|
|
207
219
|
}
|
|
220
|
+
/** Where to read the connected host's name and version from, for the User-Agent. */
|
|
221
|
+
setHostSource(source) {
|
|
222
|
+
this.hostSource = source;
|
|
223
|
+
}
|
|
208
224
|
/** A parsed JSON response, or a thrown `SkeletiqApiError` carrying the server's own words. */
|
|
209
225
|
async request(path2, options = {}) {
|
|
210
226
|
const response = await this.fetch(path2, options);
|
|
@@ -223,7 +239,7 @@ var SkeletiqClient = class {
|
|
|
223
239
|
headers: {
|
|
224
240
|
Authorization: `Bearer ${this.config.apiKey}`,
|
|
225
241
|
Accept: "application/json",
|
|
226
|
-
"User-Agent":
|
|
242
|
+
"User-Agent": userAgent(this.hostSource?.()),
|
|
227
243
|
...options.body === void 0 ? {} : { "Content-Type": "application/json" },
|
|
228
244
|
...options.headers
|
|
229
245
|
},
|
|
@@ -2839,6 +2855,11 @@ function buildServer(client, resolver) {
|
|
|
2839
2855
|
{ name: SERVER_NAME, version: SERVER_VERSION },
|
|
2840
2856
|
{ instructions: INSTRUCTIONS, capabilities: { tools: {} } }
|
|
2841
2857
|
);
|
|
2858
|
+
let envelopeHost;
|
|
2859
|
+
recordEnvelopeHost(server, (host) => {
|
|
2860
|
+
envelopeHost = host;
|
|
2861
|
+
});
|
|
2862
|
+
client.setHostSource(() => envelopeHost ?? server.server.getClientVersion());
|
|
2842
2863
|
registerListProjects(server, resolver);
|
|
2843
2864
|
registerGetDesign(server, client, resolver);
|
|
2844
2865
|
registerGenerate(server, client, resolver);
|
|
@@ -2847,6 +2868,23 @@ function buildServer(client, resolver) {
|
|
|
2847
2868
|
registerRequestDecisionChange(server, client, resolver);
|
|
2848
2869
|
return server;
|
|
2849
2870
|
}
|
|
2871
|
+
function recordEnvelopeHost(server, record4) {
|
|
2872
|
+
const register = server.registerTool.bind(server);
|
|
2873
|
+
const registerRecording = (name, config, handler) => register(name, config, (...args) => {
|
|
2874
|
+
const host = envelopeHostOf(args.at(-1));
|
|
2875
|
+
if (host) record4(host);
|
|
2876
|
+
return handler(...args);
|
|
2877
|
+
});
|
|
2878
|
+
server.registerTool = registerRecording;
|
|
2879
|
+
}
|
|
2880
|
+
function envelopeHostOf(ctx) {
|
|
2881
|
+
const envelope = ctx?.mcpReq?.envelope;
|
|
2882
|
+
const info = envelope?.[CLIENT_INFO_META_KEY];
|
|
2883
|
+
if (typeof info !== "object" || info === null) return void 0;
|
|
2884
|
+
const { name, version } = info;
|
|
2885
|
+
if (typeof name !== "string" || !name) return void 0;
|
|
2886
|
+
return { name, version: typeof version === "string" ? version : "" };
|
|
2887
|
+
}
|
|
2850
2888
|
|
|
2851
2889
|
// src/index.ts
|
|
2852
2890
|
function main() {
|
package/package.json
CHANGED