@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 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.0";
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 fetch(url2, {
23034
- method: "GET",
23035
- headers: {
23036
- Accept: "application/json",
23037
- Authorization: `Bearer ${this.#apiKey}`,
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
- throw new ThesisApiError(503, "Could not reach the Thesis API.", "THESIS_API_UNAVAILABLE");
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
- return await response.json();
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.0";
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 fetch(url, {
19936
- method: "GET",
19937
- headers: {
19938
- Accept: "application/json",
19939
- Authorization: `Bearer ${this.#apiKey}`,
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
- throw new ThesisApiError(503, "Could not reach the Thesis API.", "THESIS_API_UNAVAILABLE");
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
- return await response.json();
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.2",
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
  }