@thehammer/schema-mcp-server 1.0.3 → 1.0.5

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.
@@ -15,10 +15,17 @@ if (!SCHEMA_ID) {
15
15
  console.error("SCHEMA_DEFINITION_ID is required");
16
16
  process.exit(1);
17
17
  }
18
- async function apiRequest(method, path, body) {
18
+ /** Default timeout for API requests (30s). Preview endpoints get longer. */
19
+ const DEFAULT_TIMEOUT_MS = 30_000;
20
+ const PREVIEW_TIMEOUT_MS = 60_000;
21
+ async function apiRequest(method, path, body, timeoutMs) {
19
22
  const url = `${API_URL}/api/${path}`;
23
+ const controller = new AbortController();
24
+ const resolvedTimeout = timeoutMs ?? DEFAULT_TIMEOUT_MS;
25
+ const timer = setTimeout(() => controller.abort(), resolvedTimeout);
20
26
  const options = {
21
27
  method,
28
+ signal: controller.signal,
22
29
  headers: {
23
30
  Authorization: `Bearer ${API_TOKEN}`,
24
31
  "Content-Type": "application/json",
@@ -28,13 +35,24 @@ async function apiRequest(method, path, body) {
28
35
  if (body && method !== "GET") {
29
36
  options.body = JSON.stringify(body);
30
37
  }
31
- const response = await fetch(url, options);
32
- const json = (await response.json());
33
- if (!response.ok) {
34
- const errorMessage = json.message || json.error || `HTTP ${response.status}`;
35
- throw new Error(`API Error: ${errorMessage}`);
38
+ try {
39
+ const response = await fetch(url, options);
40
+ const json = (await response.json());
41
+ if (!response.ok) {
42
+ const errorMessage = json.message || json.error || `HTTP ${response.status}`;
43
+ throw new Error(`API Error: ${errorMessage}`);
44
+ }
45
+ return json;
46
+ }
47
+ catch (err) {
48
+ if (err instanceof Error && err.name === "AbortError") {
49
+ throw new Error(`API timeout: ${method} ${path} did not respond within ${resolvedTimeout / 1000}s`);
50
+ }
51
+ throw err;
52
+ }
53
+ finally {
54
+ clearTimeout(timer);
36
55
  }
37
- return json;
38
56
  }
39
57
  // --- Schema MCP Endpoints ---
40
58
  export function mcpPath(endpoint) {
@@ -136,13 +154,13 @@ export async function getTemplatePreview(templateId, teamObjectId, message) {
136
154
  return apiRequest("POST", mcpPath(`templates/${templateId}/preview`), {
137
155
  ...(teamObjectId ? { team_object_id: teamObjectId } : {}),
138
156
  ...(message ? { message } : {}),
139
- });
157
+ }, PREVIEW_TIMEOUT_MS);
140
158
  }
141
159
  export async function getTemplatePreviewHtml(templateId, teamObjectId, message) {
142
160
  return apiRequest("POST", mcpPath(`templates/${templateId}/preview-html`), {
143
161
  ...(teamObjectId ? { team_object_id: teamObjectId } : {}),
144
162
  ...(message ? { message } : {}),
145
- });
163
+ }, PREVIEW_TIMEOUT_MS);
146
164
  }
147
165
  // --- Style Library Endpoints ---
148
166
  export async function getStyleList() {
package/dist/index.js CHANGED
@@ -413,7 +413,7 @@ if (shouldRegister("directive_create"))
413
413
  data_fragment_selector: z
414
414
  .record(z.string(), z.unknown())
415
415
  .optional()
416
- .describe("Fragment selector for which fields to extract (DataExtraction only). Auto-generated if omitted."),
416
+ .describe("Fragment selector for which fields to extract (DataExtraction only). REQUIRED for DataExtraction directives — must explicitly list every field this directive extracts. Not auto-generated."),
417
417
  prompt: z
418
418
  .string()
419
419
  .optional()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thehammer/schema-mcp-server",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "MCP server for Schema Builder - translates Claude Code tool calls into Laravel API requests",
5
5
  "license": "MIT",
6
6
  "repository": {