@agentvalet/mcp-server 0.3.3 → 0.3.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.
- package/dist/index.js +65 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -325,6 +325,40 @@ async function fetchWithAuth(url, init) {
|
|
|
325
325
|
function errorContent(message) {
|
|
326
326
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
327
327
|
}
|
|
328
|
+
// Return helper that gives an MCP-aware host the structured content directly
|
|
329
|
+
// (no parse step), while still emitting the text-content envelope every MCP
|
|
330
|
+
// client understands. Avoids the "list of length 1 with empty fields → let me
|
|
331
|
+
// parse the wrapper" round-trip Claude does on tool results that are raw
|
|
332
|
+
// JSON strings — every read-heavy use_platform call pays that cost otherwise.
|
|
333
|
+
//
|
|
334
|
+
// If `body` isn't valid JSON, we just return the text envelope unchanged —
|
|
335
|
+
// callers that emit prose (summaries, error strings) get the old behaviour.
|
|
336
|
+
function jsonContent(body) {
|
|
337
|
+
const parsed = tryParseJson(body);
|
|
338
|
+
if (parsed === undefined) {
|
|
339
|
+
return { content: [{ type: "text", text: body }] };
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
content: [{ type: "text", text: body }],
|
|
343
|
+
structuredContent: parsed,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function tryParseJson(text) {
|
|
347
|
+
const trimmed = text.trim();
|
|
348
|
+
// Only attempt parse if it looks structured. Avoids parsing a stray "true"
|
|
349
|
+
// / number / etc. into structuredContent and confusing the host.
|
|
350
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("["))
|
|
351
|
+
return undefined;
|
|
352
|
+
try {
|
|
353
|
+
const v = JSON.parse(trimmed);
|
|
354
|
+
if (v && typeof v === "object")
|
|
355
|
+
return v;
|
|
356
|
+
return undefined;
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
328
362
|
// ---------------------------------------------------------------------------
|
|
329
363
|
// Tool handlers
|
|
330
364
|
// ---------------------------------------------------------------------------
|
|
@@ -343,7 +377,7 @@ async function handleListPlatforms() {
|
|
|
343
377
|
const body = await response.text();
|
|
344
378
|
if (!response.ok)
|
|
345
379
|
return errorContent(`Proxy error ${response.status}: ${body}`);
|
|
346
|
-
return
|
|
380
|
+
return jsonContent(body);
|
|
347
381
|
}
|
|
348
382
|
// Translates a fetch() failure into something an end-user can actually act on.
|
|
349
383
|
// The default "Network error: fetch failed" message tells a non-developer
|
|
@@ -409,7 +443,7 @@ async function handleUsePlatform(params, progressToken) {
|
|
|
409
443
|
}
|
|
410
444
|
if (!response.ok)
|
|
411
445
|
return errorContent(`Proxy error ${response.status}: ${body}`);
|
|
412
|
-
return
|
|
446
|
+
return jsonContent(body);
|
|
413
447
|
}
|
|
414
448
|
async function waitForApproval(approvalId, originalCall, progressToken) {
|
|
415
449
|
const startedAt = Date.now();
|
|
@@ -437,13 +471,27 @@ async function waitForApproval(approvalId, originalCall, progressToken) {
|
|
|
437
471
|
// Re-execution complete. Return the upstream response transparently —
|
|
438
472
|
// the agent sees this as if the original use_platform call just succeeded.
|
|
439
473
|
const r = status.result;
|
|
440
|
-
const summary = `[Owner approved after ${Math.round(elapsed / 1000)}s]\n` +
|
|
441
|
-
JSON.stringify(r.data ?? null);
|
|
442
474
|
// Mirror the non-2xx-from-upstream behaviour of the regular path.
|
|
443
475
|
if (r.status < 200 || r.status >= 300) {
|
|
444
476
|
return errorContent(`Upstream returned ${r.status}: ${JSON.stringify(r.data)}`);
|
|
445
477
|
}
|
|
446
|
-
|
|
478
|
+
// Two-channel return: the text envelope carries the human-readable
|
|
479
|
+
// "[Owner approved after Ns]" prefix (visible to non-structured-aware
|
|
480
|
+
// clients), and structuredContent carries the parsed upstream JSON
|
|
481
|
+
// directly so MCP-aware hosts (Claude Desktop ≥ MCP spec 2025-06-18)
|
|
482
|
+
// never have to strip-the-prefix-and-reparse. Without the second
|
|
483
|
+
// channel the prefix forces Claude into the same wrapper-parse
|
|
484
|
+
// round-trip the bare /v1/actions path used to.
|
|
485
|
+
const data = r.data ?? null;
|
|
486
|
+
const summary = `[Owner approved after ${Math.round(elapsed / 1000)}s]\n` +
|
|
487
|
+
JSON.stringify(data);
|
|
488
|
+
const result = {
|
|
489
|
+
content: [{ type: "text", text: summary }],
|
|
490
|
+
};
|
|
491
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
492
|
+
result.structuredContent = data;
|
|
493
|
+
}
|
|
494
|
+
return result;
|
|
447
495
|
}
|
|
448
496
|
if (status.status === "denied") {
|
|
449
497
|
return errorContent(`Owner denied this action${status.execution_error ? `: ${status.execution_error}` : "."}`);
|
|
@@ -465,18 +513,13 @@ async function waitForApproval(approvalId, originalCall, progressToken) {
|
|
|
465
513
|
// Timed out — fall through to async-recap path. The action is still
|
|
466
514
|
// queued and will run when the owner approves; the user is notified via
|
|
467
515
|
// push/email at that point. Layer 4's list_my_pending_actions surfaces it.
|
|
468
|
-
return {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
`The action is queued — your owner will be notified, and you'll see it ` +
|
|
476
|
-
`complete next time we chat (or you can ask me to check pending actions).`,
|
|
477
|
-
}),
|
|
478
|
-
}],
|
|
479
|
-
};
|
|
516
|
+
return jsonContent(JSON.stringify({
|
|
517
|
+
status: "pending_approval",
|
|
518
|
+
approval_id: approvalId,
|
|
519
|
+
message: `Owner hasn't approved within ${APPROVAL_POLL_BUDGET_MS / 1000}s. ` +
|
|
520
|
+
`The action is queued — your owner will be notified, and you'll see it ` +
|
|
521
|
+
`complete next time we chat (or you can ask me to check pending actions).`,
|
|
522
|
+
}));
|
|
480
523
|
}
|
|
481
524
|
function safeJsonParse(text) {
|
|
482
525
|
try {
|
|
@@ -517,7 +560,7 @@ async function handleAgentRegister(args) {
|
|
|
517
560
|
const body = await response.text();
|
|
518
561
|
if (!response.ok)
|
|
519
562
|
return errorContent(`Proxy error ${response.status}: ${body}`);
|
|
520
|
-
return
|
|
563
|
+
return jsonContent(body);
|
|
521
564
|
}
|
|
522
565
|
async function handleAgentStatus(token) {
|
|
523
566
|
let response;
|
|
@@ -533,7 +576,7 @@ async function handleAgentStatus(token) {
|
|
|
533
576
|
const body = await response.text();
|
|
534
577
|
if (!response.ok)
|
|
535
578
|
return errorContent(`Proxy error ${response.status}: ${body}`);
|
|
536
|
-
return
|
|
579
|
+
return jsonContent(body);
|
|
537
580
|
}
|
|
538
581
|
async function handleAuthzenEvaluate(platformId, scope) {
|
|
539
582
|
const authzenBody = {
|
|
@@ -554,7 +597,7 @@ async function handleAuthzenEvaluate(platformId, scope) {
|
|
|
554
597
|
const body = await response.text();
|
|
555
598
|
if (!response.ok)
|
|
556
599
|
return errorContent(`Proxy error ${response.status}: ${body}`);
|
|
557
|
-
return
|
|
600
|
+
return jsonContent(body);
|
|
558
601
|
}
|
|
559
602
|
async function handleListMyPendingActions() {
|
|
560
603
|
if (AGENT_PRIVATE_KEY_RAW === null) {
|
|
@@ -571,7 +614,7 @@ async function handleListMyPendingActions() {
|
|
|
571
614
|
const text = await response.text();
|
|
572
615
|
if (!response.ok)
|
|
573
616
|
return errorContent(`Proxy error ${response.status}: ${text}`);
|
|
574
|
-
return
|
|
617
|
+
return jsonContent(text);
|
|
575
618
|
}
|
|
576
619
|
async function handleReportSelfDiagnostic(args) {
|
|
577
620
|
if (AGENT_PRIVATE_KEY_RAW === null) {
|
|
@@ -600,7 +643,7 @@ async function handleReportSelfDiagnostic(args) {
|
|
|
600
643
|
const text = await response.text();
|
|
601
644
|
if (!response.ok)
|
|
602
645
|
return errorContent(`Proxy error ${response.status}: ${text}`);
|
|
603
|
-
return
|
|
646
|
+
return jsonContent(text);
|
|
604
647
|
}
|
|
605
648
|
// ---------------------------------------------------------------------------
|
|
606
649
|
// Connect transport
|