@with-thesis/mcp 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +63 -12
- package/dist/stdio.js +63 -12
- package/package.json +5 -6
package/dist/index.js
CHANGED
|
@@ -15348,7 +15348,7 @@ function setHeaders(ctx, headersToSet) {
|
|
|
15348
15348
|
}
|
|
15349
15349
|
|
|
15350
15350
|
// src/lib/config.ts
|
|
15351
|
-
var MCP_VERSION = "0.1.
|
|
15351
|
+
var MCP_VERSION = "0.1.4";
|
|
15352
15352
|
var DEFAULT_API_URL = "https://api.withthesis.dev";
|
|
15353
15353
|
var DEFAULT_MCP_PORT = 4100;
|
|
15354
15354
|
var DEFAULT_MCP_RATE_LIMIT_REQUESTS_PER_MIN = 300;
|
|
@@ -22970,6 +22970,10 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
22970
22970
|
}
|
|
22971
22971
|
};
|
|
22972
22972
|
|
|
22973
|
+
// src/lib/thesis-api.ts
|
|
22974
|
+
import { request as httpRequest } from "node:http";
|
|
22975
|
+
import { request as httpsRequest } from "node:https";
|
|
22976
|
+
|
|
22973
22977
|
// src/lib/errors.ts
|
|
22974
22978
|
class ThesisApiError extends Error {
|
|
22975
22979
|
status;
|
|
@@ -23005,12 +23009,57 @@ function formatErrorPayload(error2) {
|
|
|
23005
23009
|
}
|
|
23006
23010
|
|
|
23007
23011
|
// src/lib/thesis-api.ts
|
|
23012
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
23008
23013
|
function appendQueryParam(url2, key, value) {
|
|
23009
23014
|
if (value === undefined || value === "") {
|
|
23010
23015
|
return;
|
|
23011
23016
|
}
|
|
23012
23017
|
url2.searchParams.set(key, String(value));
|
|
23013
23018
|
}
|
|
23019
|
+
function createHeaderBag(headers) {
|
|
23020
|
+
return {
|
|
23021
|
+
get(name) {
|
|
23022
|
+
const value = headers[name.toLowerCase()];
|
|
23023
|
+
if (Array.isArray(value)) {
|
|
23024
|
+
return value.join(", ");
|
|
23025
|
+
}
|
|
23026
|
+
return value ?? null;
|
|
23027
|
+
}
|
|
23028
|
+
};
|
|
23029
|
+
}
|
|
23030
|
+
function createJsonResponse(status, headers, body) {
|
|
23031
|
+
return {
|
|
23032
|
+
ok: status >= 200 && status < 300,
|
|
23033
|
+
status,
|
|
23034
|
+
headers: createHeaderBag(headers),
|
|
23035
|
+
async json() {
|
|
23036
|
+
return JSON.parse(body);
|
|
23037
|
+
}
|
|
23038
|
+
};
|
|
23039
|
+
}
|
|
23040
|
+
async function fetchWithTimeout(url2, headers) {
|
|
23041
|
+
const request = url2.protocol === "https:" ? httpsRequest : httpRequest;
|
|
23042
|
+
return await new Promise((resolve, reject) => {
|
|
23043
|
+
const req = request(url2, {
|
|
23044
|
+
method: "GET",
|
|
23045
|
+
headers
|
|
23046
|
+
}, (response) => {
|
|
23047
|
+
const chunks = [];
|
|
23048
|
+
response.on("data", (chunk) => {
|
|
23049
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
23050
|
+
});
|
|
23051
|
+
response.on("end", () => {
|
|
23052
|
+
const body = Buffer.concat(chunks).toString("utf8");
|
|
23053
|
+
resolve(createJsonResponse(response.statusCode ?? 0, response.headers, body));
|
|
23054
|
+
});
|
|
23055
|
+
});
|
|
23056
|
+
req.setTimeout(REQUEST_TIMEOUT_MS, () => {
|
|
23057
|
+
req.destroy(new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms.`));
|
|
23058
|
+
});
|
|
23059
|
+
req.on("error", reject);
|
|
23060
|
+
req.end();
|
|
23061
|
+
});
|
|
23062
|
+
}
|
|
23014
23063
|
|
|
23015
23064
|
class ThesisApiClient {
|
|
23016
23065
|
#apiBaseUrl;
|
|
@@ -23030,23 +23079,25 @@ class ThesisApiClient {
|
|
|
23030
23079
|
}
|
|
23031
23080
|
let response;
|
|
23032
23081
|
try {
|
|
23033
|
-
response = await
|
|
23034
|
-
|
|
23035
|
-
|
|
23036
|
-
|
|
23037
|
-
|
|
23038
|
-
...this.#requestId ? { "X-Request-Id": this.#requestId } : {},
|
|
23039
|
-
...this.#userAgent ? { "User-Agent": this.#userAgent } : {}
|
|
23040
|
-
}
|
|
23082
|
+
response = await fetchWithTimeout(url2, {
|
|
23083
|
+
Accept: "application/json",
|
|
23084
|
+
Authorization: `Bearer ${this.#apiKey}`,
|
|
23085
|
+
...this.#requestId ? { "X-Request-Id": this.#requestId } : {},
|
|
23086
|
+
...this.#userAgent ? { "User-Agent": this.#userAgent } : {}
|
|
23041
23087
|
});
|
|
23042
|
-
} catch {
|
|
23043
|
-
|
|
23088
|
+
} catch (error2) {
|
|
23089
|
+
const reason = error2 instanceof Error ? error2.message : "Unknown error.";
|
|
23090
|
+
throw new ThesisApiError(503, `Could not reach the Thesis API. ${reason}`, "THESIS_API_UNAVAILABLE");
|
|
23044
23091
|
}
|
|
23045
23092
|
if (!response.ok) {
|
|
23046
23093
|
const body = await response.json().catch(() => null);
|
|
23047
23094
|
throw new ThesisApiError(response.status, body?.error || `Thesis API request failed with status ${response.status}.`, body?.code || "THESIS_API_ERROR", response.headers.get("retry-after") ?? undefined);
|
|
23048
23095
|
}
|
|
23049
|
-
|
|
23096
|
+
try {
|
|
23097
|
+
return await response.json();
|
|
23098
|
+
} catch {
|
|
23099
|
+
throw new ThesisApiError(502, "Thesis API returned invalid JSON.", "THESIS_API_INVALID_RESPONSE");
|
|
23100
|
+
}
|
|
23050
23101
|
}
|
|
23051
23102
|
}
|
|
23052
23103
|
|
package/dist/stdio.js
CHANGED
|
@@ -12459,7 +12459,7 @@ function requireStdioApiKey() {
|
|
|
12459
12459
|
}
|
|
12460
12460
|
|
|
12461
12461
|
// src/lib/config.ts
|
|
12462
|
-
var MCP_VERSION = "0.1.
|
|
12462
|
+
var MCP_VERSION = "0.1.4";
|
|
12463
12463
|
var DEFAULT_API_URL = "https://api.withthesis.dev";
|
|
12464
12464
|
function resolveApiBaseUrl() {
|
|
12465
12465
|
return process.env.THESIS_API_URL?.trim() || DEFAULT_API_URL;
|
|
@@ -19872,6 +19872,10 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
19872
19872
|
}
|
|
19873
19873
|
};
|
|
19874
19874
|
|
|
19875
|
+
// src/lib/thesis-api.ts
|
|
19876
|
+
import { request as httpRequest } from "node:http";
|
|
19877
|
+
import { request as httpsRequest } from "node:https";
|
|
19878
|
+
|
|
19875
19879
|
// src/lib/errors.ts
|
|
19876
19880
|
class ThesisApiError extends Error {
|
|
19877
19881
|
status;
|
|
@@ -19907,12 +19911,57 @@ function formatErrorPayload(error2) {
|
|
|
19907
19911
|
}
|
|
19908
19912
|
|
|
19909
19913
|
// src/lib/thesis-api.ts
|
|
19914
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
19910
19915
|
function appendQueryParam(url, key, value) {
|
|
19911
19916
|
if (value === undefined || value === "") {
|
|
19912
19917
|
return;
|
|
19913
19918
|
}
|
|
19914
19919
|
url.searchParams.set(key, String(value));
|
|
19915
19920
|
}
|
|
19921
|
+
function createHeaderBag(headers) {
|
|
19922
|
+
return {
|
|
19923
|
+
get(name) {
|
|
19924
|
+
const value = headers[name.toLowerCase()];
|
|
19925
|
+
if (Array.isArray(value)) {
|
|
19926
|
+
return value.join(", ");
|
|
19927
|
+
}
|
|
19928
|
+
return value ?? null;
|
|
19929
|
+
}
|
|
19930
|
+
};
|
|
19931
|
+
}
|
|
19932
|
+
function createJsonResponse(status, headers, body) {
|
|
19933
|
+
return {
|
|
19934
|
+
ok: status >= 200 && status < 300,
|
|
19935
|
+
status,
|
|
19936
|
+
headers: createHeaderBag(headers),
|
|
19937
|
+
async json() {
|
|
19938
|
+
return JSON.parse(body);
|
|
19939
|
+
}
|
|
19940
|
+
};
|
|
19941
|
+
}
|
|
19942
|
+
async function fetchWithTimeout(url, headers) {
|
|
19943
|
+
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
19944
|
+
return await new Promise((resolve, reject) => {
|
|
19945
|
+
const req = request(url, {
|
|
19946
|
+
method: "GET",
|
|
19947
|
+
headers
|
|
19948
|
+
}, (response) => {
|
|
19949
|
+
const chunks = [];
|
|
19950
|
+
response.on("data", (chunk) => {
|
|
19951
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
19952
|
+
});
|
|
19953
|
+
response.on("end", () => {
|
|
19954
|
+
const body = Buffer.concat(chunks).toString("utf8");
|
|
19955
|
+
resolve(createJsonResponse(response.statusCode ?? 0, response.headers, body));
|
|
19956
|
+
});
|
|
19957
|
+
});
|
|
19958
|
+
req.setTimeout(REQUEST_TIMEOUT_MS, () => {
|
|
19959
|
+
req.destroy(new Error(`Request timed out after ${REQUEST_TIMEOUT_MS}ms.`));
|
|
19960
|
+
});
|
|
19961
|
+
req.on("error", reject);
|
|
19962
|
+
req.end();
|
|
19963
|
+
});
|
|
19964
|
+
}
|
|
19916
19965
|
|
|
19917
19966
|
class ThesisApiClient {
|
|
19918
19967
|
#apiBaseUrl;
|
|
@@ -19932,23 +19981,25 @@ class ThesisApiClient {
|
|
|
19932
19981
|
}
|
|
19933
19982
|
let response;
|
|
19934
19983
|
try {
|
|
19935
|
-
response = await
|
|
19936
|
-
|
|
19937
|
-
|
|
19938
|
-
|
|
19939
|
-
|
|
19940
|
-
...this.#requestId ? { "X-Request-Id": this.#requestId } : {},
|
|
19941
|
-
...this.#userAgent ? { "User-Agent": this.#userAgent } : {}
|
|
19942
|
-
}
|
|
19984
|
+
response = await fetchWithTimeout(url, {
|
|
19985
|
+
Accept: "application/json",
|
|
19986
|
+
Authorization: `Bearer ${this.#apiKey}`,
|
|
19987
|
+
...this.#requestId ? { "X-Request-Id": this.#requestId } : {},
|
|
19988
|
+
...this.#userAgent ? { "User-Agent": this.#userAgent } : {}
|
|
19943
19989
|
});
|
|
19944
|
-
} catch {
|
|
19945
|
-
|
|
19990
|
+
} catch (error2) {
|
|
19991
|
+
const reason = error2 instanceof Error ? error2.message : "Unknown error.";
|
|
19992
|
+
throw new ThesisApiError(503, `Could not reach the Thesis API. ${reason}`, "THESIS_API_UNAVAILABLE");
|
|
19946
19993
|
}
|
|
19947
19994
|
if (!response.ok) {
|
|
19948
19995
|
const body = await response.json().catch(() => null);
|
|
19949
19996
|
throw new ThesisApiError(response.status, body?.error || `Thesis API request failed with status ${response.status}.`, body?.code || "THESIS_API_ERROR", response.headers.get("retry-after") ?? undefined);
|
|
19950
19997
|
}
|
|
19951
|
-
|
|
19998
|
+
try {
|
|
19999
|
+
return await response.json();
|
|
20000
|
+
} catch {
|
|
20001
|
+
throw new ThesisApiError(502, "Thesis API returned invalid JSON.", "THESIS_API_INVALID_RESPONSE");
|
|
20002
|
+
}
|
|
19952
20003
|
}
|
|
19953
20004
|
}
|
|
19954
20005
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@with-thesis/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "thesis MCP server for API-key-based AI client access.",
|
|
6
6
|
"homepage": "https://withthesis.dev",
|
|
@@ -28,16 +28,15 @@
|
|
|
28
28
|
"typecheck": "bun x tsc --project tsconfig.json --noEmit",
|
|
29
29
|
"test": "bun test"
|
|
30
30
|
},
|
|
31
|
-
"dependencies": {
|
|
31
|
+
"dependencies": {},
|
|
32
|
+
"devDependencies": {
|
|
32
33
|
"@hono/mcp": "^0.2.4",
|
|
33
34
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
35
|
+
"@types/bun": "^1.3.5",
|
|
36
|
+
"@types/node": "^24.5.2",
|
|
34
37
|
"hono": "^4.12.7",
|
|
35
38
|
"zod": "^4.3.6"
|
|
36
39
|
},
|
|
37
|
-
"devDependencies": {
|
|
38
|
-
"@types/bun": "^1.3.5",
|
|
39
|
-
"@types/node": "^24.5.2"
|
|
40
|
-
},
|
|
41
40
|
"peerDependencies": {
|
|
42
41
|
"typescript": "^5"
|
|
43
42
|
}
|