@getmarrow/mcp 3.9.91 → 3.9.93

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
@@ -326,6 +326,15 @@ async function safeJsonResponse(res) {
326
326
  }
327
327
  return json;
328
328
  }
329
+ async function fetchJsonResponse(url, init = {}) {
330
+ return fetch(url, init, { consumeResponse: safeJsonResponse });
331
+ }
332
+ function requireObjectData(value) {
333
+ if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).length === 0) {
334
+ throw (0, request_reliability_1.invalidResponseError)();
335
+ }
336
+ return value;
337
+ }
329
338
  function requireRuntimeResult(value) {
330
339
  const runtime = (0, runtime_contract_1.normalizeRuntimeResult)(value);
331
340
  if (!runtime)
@@ -372,17 +381,20 @@ async function drainRetryQueue() {
372
381
  }
373
382
  async function fetchWithRetryQueue(url, init, queueable = false) {
374
383
  await drainRetryQueue();
384
+ let queued = false;
375
385
  try {
376
- const res = await fetch(url, init);
377
- if (queueable && !res.ok && isRetryableStatus(res.status)) {
378
- if (retryQueue.length >= 25)
379
- retryQueue.shift();
380
- retryQueue.push({ url, init, attempts: 0 });
381
- }
382
- return res;
386
+ return await fetch(url, init, { consumeResponse: async (res) => {
387
+ if (queueable && !res.ok && isRetryableStatus(res.status)) {
388
+ if (retryQueue.length >= 25)
389
+ retryQueue.shift();
390
+ retryQueue.push({ url, init, attempts: 0 });
391
+ queued = true;
392
+ }
393
+ return safeJsonResponse(res);
394
+ } });
383
395
  }
384
396
  catch (error) {
385
- if (queueable && isRetryableError(error)) {
397
+ if (queueable && !queued && isRetryableError(error)) {
386
398
  if (retryQueue.length >= 25)
387
399
  retryQueue.shift();
388
400
  retryQueue.push({ url, init, attempts: 0 });
@@ -983,12 +995,11 @@ async function marrowModelUsage(apiKey, baseUrl, input, sessionId, agentId) {
983
995
  session_id: input.session_id || sessionId,
984
996
  source: input.source || 'mcp',
985
997
  });
986
- const res = await fetchWithRetryQueue(`${baseUrl}/v1/agent/model-usage`, {
998
+ const json = await fetchWithRetryQueue(`${baseUrl}/v1/agent/model-usage`, {
987
999
  method: 'POST',
988
1000
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
989
1001
  body: JSON.stringify(body),
990
1002
  }, true);
991
- const json = await safeJsonResponse(res);
992
1003
  return json.data;
993
1004
  }
994
1005
  function createTimeoutSignal(timeoutMs, startedAt) {
@@ -1533,10 +1544,9 @@ async function marrowAgentPatterns(apiKey, baseUrl, params, sessionId, agentId)
1533
1544
  }
1534
1545
  const url = `${baseUrl}/v1/agent/patterns` +
1535
1546
  (qs.toString() ? '?' + qs.toString() : '');
1536
- const res = await fetch(url, {
1547
+ const json = await fetchJsonResponse(url, {
1537
1548
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1538
1549
  });
1539
- const json = await safeJsonResponse(res);
1540
1550
  return json.data;
1541
1551
  }
1542
1552
  /**
@@ -1646,7 +1656,7 @@ async function marrowOrient(apiKey, baseUrl, params, sessionId, agentId, signal)
1646
1656
  * Query the collective hive for failure patterns and recommendations.
1647
1657
  */
1648
1658
  async function marrowAsk(apiKey, baseUrl, params, sessionId, agentId, signal) {
1649
- const res = await fetch(`${baseUrl}/v1/analytics/decision-brief`, {
1659
+ const json = await fetchJsonResponse(`${baseUrl}/v1/analytics/decision-brief`, {
1650
1660
  method: 'POST',
1651
1661
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
1652
1662
  body: JSON.stringify({
@@ -1658,7 +1668,6 @@ async function marrowAsk(apiKey, baseUrl, params, sessionId, agentId, signal) {
1658
1668
  }),
1659
1669
  signal,
1660
1670
  });
1661
- const json = await safeJsonResponse(res);
1662
1671
  const brief = json.data;
1663
1672
  const topOutcomes = Array.isArray(brief.top_outcomes) && brief.top_outcomes.length
1664
1673
  ? brief.top_outcomes
@@ -1690,19 +1699,21 @@ async function marrowAsk(apiKey, baseUrl, params, sessionId, agentId, signal) {
1690
1699
  * Get API health status.
1691
1700
  */
1692
1701
  async function marrowStatus(apiKey, baseUrl, sessionId, agentId, signal) {
1693
- const res = await fetch(`${baseUrl}/v1/agent/status?fast=1&compact=1`, {
1702
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/status?fast=1&compact=1`, {
1694
1703
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1695
1704
  signal,
1696
1705
  });
1697
- const json = await safeJsonResponse(res);
1698
1706
  return json.data;
1699
1707
  }
1700
1708
  // ─── Workflow Registry API ───────────────────────────────────────
1701
1709
  async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1702
1710
  const headers = buildHeaders(apiKey, sessionId, 'application/json', agentId);
1711
+ const fetchWorkflowJson = (url, init) => fetch(url, init, {
1712
+ consumeResponse: (response) => response.json(),
1713
+ });
1703
1714
  switch (params.action) {
1704
1715
  case 'register': {
1705
- const res = await fetch(`${baseUrl}/v1/workflows/register`, {
1716
+ const json = await fetchWorkflowJson(`${baseUrl}/v1/workflows/register`, {
1706
1717
  method: 'POST',
1707
1718
  headers,
1708
1719
  body: JSON.stringify({
@@ -1712,7 +1723,6 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1712
1723
  tags: params.tags,
1713
1724
  }),
1714
1725
  });
1715
- const json = await res.json();
1716
1726
  if (json.error)
1717
1727
  return { success: false, error: json.error };
1718
1728
  return { success: true, data: json.data };
@@ -1723,8 +1733,7 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1723
1733
  qs.set('status', params.status);
1724
1734
  if (params.tags && params.tags.length > 0)
1725
1735
  qs.set('tags', params.tags.join(','));
1726
- const res = await fetch(`${baseUrl}/v1/workflows?${qs.toString()}`, { headers });
1727
- const json = await res.json();
1736
+ const json = await fetchWorkflowJson(`${baseUrl}/v1/workflows?${qs.toString()}`, { headers });
1728
1737
  if (json.error)
1729
1738
  return { success: false, error: json.error };
1730
1739
  return { success: true, data: json.data };
@@ -1733,8 +1742,7 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1733
1742
  if (!params.workflowId)
1734
1743
  return { success: false, error: 'workflowId required' };
1735
1744
  const safeId = validatePathParam(params.workflowId, 'workflowId');
1736
- const res = await fetch(`${baseUrl}/v1/workflows/${safeId}`, { headers });
1737
- const json = await res.json();
1745
+ const json = await fetchWorkflowJson(`${baseUrl}/v1/workflows/${safeId}`, { headers });
1738
1746
  if (json.error)
1739
1747
  return { success: false, error: json.error };
1740
1748
  return { success: true, data: json.data };
@@ -1743,7 +1751,7 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1743
1751
  if (!params.workflowId)
1744
1752
  return { success: false, error: 'workflowId required' };
1745
1753
  const safeId = validatePathParam(params.workflowId, 'workflowId');
1746
- const res = await fetch(`${baseUrl}/v1/workflows/${safeId}`, {
1754
+ const json = await fetchWorkflowJson(`${baseUrl}/v1/workflows/${safeId}`, {
1747
1755
  method: 'PUT',
1748
1756
  headers,
1749
1757
  body: JSON.stringify({
@@ -1753,7 +1761,6 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1753
1761
  status: params.status,
1754
1762
  }),
1755
1763
  });
1756
- const json = await res.json();
1757
1764
  if (json.error)
1758
1765
  return { success: false, error: json.error };
1759
1766
  return { success: true, data: json.data };
@@ -1764,7 +1771,7 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1764
1771
  if (!params.agentId)
1765
1772
  return { success: false, error: 'agentId required' };
1766
1773
  const safeId = validatePathParam(params.workflowId, 'workflowId');
1767
- const res = await fetch(`${baseUrl}/v1/workflows/${safeId}/start`, {
1774
+ const json = await fetchWorkflowJson(`${baseUrl}/v1/workflows/${safeId}/start`, {
1768
1775
  method: 'POST',
1769
1776
  headers,
1770
1777
  body: JSON.stringify({
@@ -1773,7 +1780,6 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1773
1780
  inputs: params.inputs,
1774
1781
  }),
1775
1782
  });
1776
- const json = await res.json();
1777
1783
  if (json.error)
1778
1784
  return { success: false, error: json.error };
1779
1785
  return { success: true, data: json.data };
@@ -1789,7 +1795,7 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1789
1795
  return { success: false, error: 'outcome required' };
1790
1796
  const safeWorkflowId = validatePathParam(params.workflowId, 'workflowId');
1791
1797
  const safeInstanceId = validatePathParam(params.instanceId, 'instanceId');
1792
- const res = await fetch(`${baseUrl}/v1/workflows/${safeWorkflowId}/instances/${safeInstanceId}/step`, {
1798
+ const json = await fetchWorkflowJson(`${baseUrl}/v1/workflows/${safeWorkflowId}/instances/${safeInstanceId}/step`, {
1793
1799
  method: 'PUT',
1794
1800
  headers,
1795
1801
  body: JSON.stringify({
@@ -1799,7 +1805,6 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1799
1805
  context_update: params.contextUpdate,
1800
1806
  }),
1801
1807
  });
1802
- const json = await res.json();
1803
1808
  if (json.error)
1804
1809
  return { success: false, error: json.error };
1805
1810
  return { success: true, data: json.data };
@@ -1811,8 +1816,7 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1811
1816
  const qs = new URLSearchParams();
1812
1817
  if (params.status)
1813
1818
  qs.set('status', params.status);
1814
- const res = await fetch(`${baseUrl}/v1/workflows/${safeId}/instances?${qs.toString()}`, { headers });
1815
- const json = await res.json();
1819
+ const json = await fetchWorkflowJson(`${baseUrl}/v1/workflows/${safeId}/instances?${qs.toString()}`, { headers });
1816
1820
  if (json.error)
1817
1821
  return { success: false, error: json.error };
1818
1822
  return { success: true, data: json.data };
@@ -1826,10 +1830,9 @@ async function marrowWorkflow(apiKey, baseUrl, params, sessionId, agentId) {
1826
1830
  * Get operator dashboard — account health, top failures, workflow status, saves.
1827
1831
  */
1828
1832
  async function marrowDashboard(apiKey, baseUrl, sessionId, agentId) {
1829
- const res = await fetch(`${baseUrl}/v1/dashboard`, {
1833
+ const json = await fetchJsonResponse(`${baseUrl}/v1/dashboard`, {
1830
1834
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1831
1835
  });
1832
- const json = await safeJsonResponse(res);
1833
1836
  return json.data;
1834
1837
  }
1835
1838
  /**
@@ -1837,10 +1840,9 @@ async function marrowDashboard(apiKey, baseUrl, sessionId, agentId) {
1837
1840
  */
1838
1841
  async function marrowDigest(apiKey, baseUrl, period = '7d', sessionId, agentId) {
1839
1842
  const days = parseInt(period) || 7;
1840
- const res = await fetch(`${baseUrl}/v1/digest?period=${days}`, {
1843
+ const json = await fetchJsonResponse(`${baseUrl}/v1/digest?period=${days}`, {
1841
1844
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1842
1845
  });
1843
- const json = await safeJsonResponse(res);
1844
1846
  return json.data;
1845
1847
  }
1846
1848
  /**
@@ -1851,11 +1853,10 @@ async function marrowAgentStatus(apiKey, baseUrl, period = '7d', agentIdFilter,
1851
1853
  const qs = new URLSearchParams({ period: String(days) });
1852
1854
  if (agentIdFilter)
1853
1855
  qs.set('agent_id', agentIdFilter);
1854
- const res = await fetch(`${baseUrl}/v1/analytics/agent-status?${qs.toString()}`, {
1856
+ const json = await fetchJsonResponse(`${baseUrl}/v1/analytics/agent-status?${qs.toString()}`, {
1855
1857
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1856
1858
  signal,
1857
1859
  });
1858
- const json = await safeJsonResponse(res);
1859
1860
  return json.data;
1860
1861
  }
1861
1862
  /**
@@ -1863,11 +1864,10 @@ async function marrowAgentStatus(apiKey, baseUrl, period = '7d', agentIdFilter,
1863
1864
  */
1864
1865
  async function marrowRuntimeStatus(apiKey, baseUrl, fast = true, sessionId, agentId, signal) {
1865
1866
  const qs = fast ? '?fast=1' : '';
1866
- const res = await fetch(`${baseUrl}/v1/agent/status${qs}`, {
1867
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/status${qs}`, {
1867
1868
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1868
1869
  signal,
1869
1870
  });
1870
- const json = await safeJsonResponse(res);
1871
1871
  return json.data;
1872
1872
  }
1873
1873
  /**
@@ -1877,11 +1877,10 @@ async function marrowAgentContext(apiKey, baseUrl, sessionId, agentId, signal) {
1877
1877
  const query = new URLSearchParams({ compact: '1' });
1878
1878
  if (agentId)
1879
1879
  query.set('agent_id', agentId);
1880
- const res = await fetch(`${baseUrl}/v1/agent/context?${query.toString()}`, {
1880
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/context?${query.toString()}`, {
1881
1881
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1882
1882
  signal,
1883
1883
  });
1884
- const json = await safeJsonResponse(res);
1885
1884
  return json.data;
1886
1885
  }
1887
1886
  /**
@@ -1892,10 +1891,9 @@ async function marrowValueReport(apiKey, baseUrl, period = '7d', agentIdFilter,
1892
1891
  const qs = new URLSearchParams({ period: String(days) });
1893
1892
  if (agentIdFilter)
1894
1893
  qs.set('agent_id', agentIdFilter);
1895
- const res = await fetch(`${baseUrl}/v1/analytics/value-report?${qs.toString()}`, {
1894
+ const json = await fetchJsonResponse(`${baseUrl}/v1/analytics/value-report?${qs.toString()}`, {
1896
1895
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
1897
1896
  });
1898
- const json = await safeJsonResponse(res);
1899
1897
  return json.data;
1900
1898
  }
1901
1899
  /**
@@ -1907,21 +1905,19 @@ async function marrowDecisionBrief(apiKey, baseUrl, input, sessionId, agentId) {
1907
1905
  agent_id: input.agent_id || agentId,
1908
1906
  session_id: input.session_id || sessionId,
1909
1907
  };
1910
- const res = await fetch(`${baseUrl}/v1/analytics/decision-brief`, {
1908
+ const json = await fetchJsonResponse(`${baseUrl}/v1/analytics/decision-brief`, {
1911
1909
  method: 'POST',
1912
1910
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
1913
1911
  body: JSON.stringify(body),
1914
1912
  });
1915
- const json = await safeJsonResponse(res);
1916
1913
  return json.data;
1917
1914
  }
1918
1915
  async function marrowWorkflowGate(apiKey, baseUrl, input, sessionId, agentId) {
1919
- const res = await fetch(`${baseUrl}/v1/workflow/gate`, {
1916
+ const json = await fetchJsonResponse(`${baseUrl}/v1/workflow/gate`, {
1920
1917
  method: 'POST',
1921
1918
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
1922
1919
  body: JSON.stringify(input),
1923
1920
  });
1924
- const json = await safeJsonResponse(res);
1925
1921
  return json.data;
1926
1922
  }
1927
1923
  async function marrowAgentRuntime(apiKey, baseUrl, input, sessionId, agentId, signal, idempotencyKeyOverride) {
@@ -1931,7 +1927,7 @@ async function marrowAgentRuntime(apiKey, baseUrl, input, sessionId, agentId, si
1931
1927
  session_id: input.session_id || sessionId,
1932
1928
  };
1933
1929
  const idempotencyKey = idempotencyKeyOverride || `mcp-runtime-${(0, node_crypto_1.randomUUID)()}`;
1934
- const res = await fetch(`${baseUrl}/v1/agent/runtime`, {
1930
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/runtime`, {
1935
1931
  method: 'POST',
1936
1932
  headers: {
1937
1933
  ...buildHeaders(apiKey, sessionId, 'application/json', agentId),
@@ -1940,7 +1936,6 @@ async function marrowAgentRuntime(apiKey, baseUrl, input, sessionId, agentId, si
1940
1936
  body: JSON.stringify(body),
1941
1937
  signal,
1942
1938
  });
1943
- const json = await safeJsonResponse(res);
1944
1939
  const runtime = requireRuntimeResult(json.data);
1945
1940
  if (!runtime.action && typeof input.action === 'string' && input.action.trim()) {
1946
1941
  runtime.action = input.action;
@@ -1953,13 +1948,12 @@ async function marrowEnforcement(apiKey, baseUrl, input, sessionId, agentId, sig
1953
1948
  agent_id: input.agent_id || agentId,
1954
1949
  session_id: input.session_id || sessionId,
1955
1950
  };
1956
- const res = await fetch(`${baseUrl}/v1/agent/enforcement`, {
1951
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/enforcement`, {
1957
1952
  method: 'POST',
1958
1953
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
1959
1954
  body: JSON.stringify(body),
1960
1955
  signal,
1961
1956
  });
1962
- const json = await safeJsonResponse(res);
1963
1957
  return json.data;
1964
1958
  }
1965
1959
  /**
@@ -2018,33 +2012,29 @@ async function marrowArbitrate(apiKey, baseUrl, input, sessionId, agentId) {
2018
2012
  }, sessionId, agentId);
2019
2013
  }
2020
2014
  async function marrowGovernanceControlPlane(apiKey, baseUrl, sessionId, agentId) {
2021
- const res = await fetch(`${baseUrl}/v1/agent/governance/control-plane`, {
2015
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/control-plane`, {
2022
2016
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2023
2017
  });
2024
- const json = await safeJsonResponse(res);
2025
2018
  return json.data;
2026
2019
  }
2027
2020
  async function marrowHermesIntegration(apiKey, baseUrl, sessionId, agentId) {
2028
- const res = await fetch(`${baseUrl}/v1/agent/integrations/hermes`, {
2021
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/integrations/hermes`, {
2029
2022
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2030
2023
  });
2031
- const json = await safeJsonResponse(res);
2032
2024
  return json.data;
2033
2025
  }
2034
2026
  async function marrowCompletionContracts(apiKey, baseUrl, sessionId, agentId) {
2035
- const res = await fetch(`${baseUrl}/v1/agent/governance/completion-contracts`, {
2027
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/completion-contracts`, {
2036
2028
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2037
2029
  });
2038
- const json = await safeJsonResponse(res);
2039
2030
  return json.data;
2040
2031
  }
2041
2032
  async function marrowEvaluateCompletionContract(apiKey, baseUrl, input, sessionId, agentId) {
2042
- const res = await fetch(`${baseUrl}/v1/agent/governance/completion-contracts/evaluate`, {
2033
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/completion-contracts/evaluate`, {
2043
2034
  method: 'POST',
2044
2035
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2045
2036
  body: JSON.stringify(input),
2046
2037
  });
2047
- const json = await safeJsonResponse(res);
2048
2038
  return json.data;
2049
2039
  }
2050
2040
  async function marrowGovernanceTimeline(apiKey, baseUrl, options = {}, sessionId, agentId) {
@@ -2053,10 +2043,9 @@ async function marrowGovernanceTimeline(apiKey, baseUrl, options = {}, sessionId
2053
2043
  qs.set('agent_id', options.agentId || agentId || '');
2054
2044
  if (options.limit)
2055
2045
  qs.set('limit', String(options.limit));
2056
- const res = await fetch(`${baseUrl}/v1/agent/governance/timeline${qs.toString() ? `?${qs.toString()}` : ''}`, {
2046
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/timeline${qs.toString() ? `?${qs.toString()}` : ''}`, {
2057
2047
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2058
2048
  });
2059
- const json = await safeJsonResponse(res);
2060
2049
  return json.data;
2061
2050
  }
2062
2051
  async function marrowBuyerProof(apiKey, baseUrl, options = {}, sessionId, agentId) {
@@ -2065,11 +2054,10 @@ async function marrowBuyerProof(apiKey, baseUrl, options = {}, sessionId, agentI
2065
2054
  qs.set('agent_id', options.agentId || agentId || '');
2066
2055
  if (options.periodDays)
2067
2056
  qs.set('period_days', String(options.periodDays));
2068
- const res = await fetch(`${baseUrl}/v1/agent/governance/buyer-proof${qs.toString() ? `?${qs.toString()}` : ''}`, {
2057
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/buyer-proof${qs.toString() ? `?${qs.toString()}` : ''}`, {
2069
2058
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2070
2059
  });
2071
- const json = await safeJsonResponse(res);
2072
- return json.data;
2060
+ return requireObjectData(json.data);
2073
2061
  }
2074
2062
  /**
2075
2063
  * Coordinate tenant agents through resource leases and compact proof packets.
@@ -2084,8 +2072,8 @@ async function marrowCoordinate(apiKey, baseUrl, input, sessionId, agentId) {
2084
2072
  qs.set('status', input.status);
2085
2073
  if (Number.isFinite(Number(input.limit)))
2086
2074
  qs.set('limit', String(input.limit));
2087
- const res = await fetch(`${baseUrl}/v1/agent/governance/leases${qs.toString() ? `?${qs}` : ''}`, { headers });
2088
- return (await safeJsonResponse(res)).data;
2075
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/leases${qs.toString() ? `?${qs}` : ''}`, { headers });
2076
+ return json.data;
2089
2077
  }
2090
2078
  if (action === 'acquire_lease') {
2091
2079
  const boundAgentId = boundCoordinationAgent(input, agentId);
@@ -2096,17 +2084,17 @@ async function marrowCoordinate(apiKey, baseUrl, input, sessionId, agentId) {
2096
2084
  workflow_id: input.workflow_id,
2097
2085
  ttl_seconds: input.ttl_seconds,
2098
2086
  };
2099
- const res = await fetch(`${baseUrl}/v1/agent/governance/leases/acquire`, {
2087
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/leases/acquire`, {
2100
2088
  method: 'POST', headers, body: JSON.stringify(body),
2101
2089
  });
2102
- return (await safeJsonResponse(res)).data;
2090
+ return json.data;
2103
2091
  }
2104
2092
  if (action === 'release_lease') {
2105
2093
  const boundAgentId = boundCoordinationAgent(input, agentId);
2106
2094
  const leaseId = validatePathParam(String(input.lease_id || ''), 'lease_id');
2107
2095
  if (!leaseId.startsWith('lease_'))
2108
2096
  throw new TypeError('lease_id must be a Marrow lease identifier.');
2109
- const res = await fetch(`${baseUrl}/v1/agent/governance/leases/${leaseId}/release`, {
2097
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/leases/${leaseId}/release`, {
2110
2098
  method: 'POST',
2111
2099
  headers,
2112
2100
  body: JSON.stringify({
@@ -2114,14 +2102,14 @@ async function marrowCoordinate(apiKey, baseUrl, input, sessionId, agentId) {
2114
2102
  lease_token: input.lease_token,
2115
2103
  }),
2116
2104
  });
2117
- return (await safeJsonResponse(res)).data;
2105
+ return json.data;
2118
2106
  }
2119
2107
  if (action === 'list_proof_packets') {
2120
2108
  const qs = new URLSearchParams();
2121
2109
  if (Number.isFinite(Number(input.limit)))
2122
2110
  qs.set('limit', String(input.limit));
2123
- const res = await fetch(`${baseUrl}/v1/agent/governance/proof-packets${qs.toString() ? `?${qs}` : ''}`, { headers });
2124
- return (await safeJsonResponse(res)).data;
2111
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/proof-packets${qs.toString() ? `?${qs}` : ''}`, { headers });
2112
+ return json.data;
2125
2113
  }
2126
2114
  if (action === 'create_proof_packet') {
2127
2115
  const boundAgentId = boundCoordinationAgent(input, agentId);
@@ -2138,10 +2126,10 @@ async function marrowCoordinate(apiKey, baseUrl, input, sessionId, agentId) {
2138
2126
  summary: input.summary,
2139
2127
  evidence_refs: input.evidence_refs,
2140
2128
  });
2141
- const res = await fetch(`${baseUrl}/v1/agent/governance/proof-packets`, {
2129
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/proof-packets`, {
2142
2130
  method: 'POST', headers, body: JSON.stringify(body),
2143
2131
  });
2144
- return (await safeJsonResponse(res)).data;
2132
+ return json.data;
2145
2133
  }
2146
2134
  throw new TypeError('Unsupported coordination action.');
2147
2135
  }
@@ -2172,10 +2160,10 @@ async function marrowReplayCompare(apiKey, baseUrl, input, sessionId, agentId) {
2172
2160
  const safeId = validatePathParam(comparisonId, 'comparison_id');
2173
2161
  if (!safeId.startsWith('replay_'))
2174
2162
  throw new TypeError('comparison_id must be a Marrow replay identifier.');
2175
- const res = await fetch(`${baseUrl}/v1/agent/governance/replay-comparisons/${safeId}`, {
2163
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/replay-comparisons/${safeId}`, {
2176
2164
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2177
2165
  });
2178
- return (await safeJsonResponse(res)).data;
2166
+ return json.data;
2179
2167
  }
2180
2168
  const sourceDecisionId = requiredReplayDecisionId(input.source_decision_id, 'source_decision_id');
2181
2169
  const baseline = normalizeReplayOutcomeReference(input.baseline, 'baseline');
@@ -2190,55 +2178,50 @@ async function marrowReplayCompare(apiKey, baseUrl, input, sessionId, agentId) {
2190
2178
  baseline,
2191
2179
  candidate,
2192
2180
  });
2193
- const res = await fetch(`${baseUrl}/v1/agent/governance/replay-comparisons`, {
2181
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/replay-comparisons`, {
2194
2182
  method: 'POST',
2195
2183
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2196
2184
  body: JSON.stringify(body),
2197
2185
  });
2198
- return (await safeJsonResponse(res)).data;
2186
+ return json.data;
2199
2187
  }
2200
2188
  async function marrowRecommendGovernanceMode(apiKey, baseUrl, input, sessionId, agentId) {
2201
- const res = await fetch(`${baseUrl}/v1/agent/mode/recommend`, {
2189
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/mode/recommend`, {
2202
2190
  method: 'POST',
2203
2191
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2204
2192
  body: JSON.stringify(input),
2205
2193
  });
2206
- const json = await safeJsonResponse(res);
2207
2194
  return json.data;
2208
2195
  }
2209
2196
  async function marrowListPolicyProfiles(apiKey, baseUrl, sessionId, agentId) {
2210
- const res = await fetch(`${baseUrl}/v1/agent/policy-profiles`, {
2197
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/policy-profiles`, {
2211
2198
  method: 'GET',
2212
2199
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2213
2200
  });
2214
- const json = await safeJsonResponse(res);
2215
2201
  return json.data;
2216
2202
  }
2217
2203
  async function marrowCreatePolicyProfile(apiKey, baseUrl, input, sessionId, agentId) {
2218
- const res = await fetch(`${baseUrl}/v1/agent/policy-profiles`, {
2204
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/policy-profiles`, {
2219
2205
  method: 'POST',
2220
2206
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2221
2207
  body: JSON.stringify(input),
2222
2208
  });
2223
- const json = await safeJsonResponse(res);
2224
2209
  return json.data;
2225
2210
  }
2226
2211
  async function marrowAssignProjectPolicyProfile(apiKey, baseUrl, input, sessionId, agentId) {
2227
- const res = await fetch(`${baseUrl}/v1/agent/project-policy-profile`, {
2212
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/project-policy-profile`, {
2228
2213
  method: 'POST',
2229
2214
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2230
2215
  body: JSON.stringify(input),
2231
2216
  });
2232
- const json = await safeJsonResponse(res);
2233
2217
  return json.data;
2234
2218
  }
2235
2219
  async function marrowResolvePolicy(apiKey, baseUrl, input, sessionId, agentId) {
2236
- const res = await fetch(`${baseUrl}/v1/agent/policy/resolve`, {
2220
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/policy/resolve`, {
2237
2221
  method: 'POST',
2238
2222
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2239
2223
  body: JSON.stringify(input),
2240
2224
  });
2241
- const json = await safeJsonResponse(res);
2242
2225
  return json.data;
2243
2226
  }
2244
2227
  async function marrowFirstValue(apiKey, baseUrl, input = {}, sessionId, agentId) {
@@ -2247,22 +2230,20 @@ async function marrowFirstValue(apiKey, baseUrl, input = {}, sessionId, agentId)
2247
2230
  agent_id: input.agent_id || agentId,
2248
2231
  session_id: input.session_id || sessionId,
2249
2232
  };
2250
- const res = await fetch(`${baseUrl}/v1/agent/first-value`, {
2233
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/first-value`, {
2251
2234
  method: 'POST',
2252
2235
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2253
2236
  body: JSON.stringify(body),
2254
2237
  });
2255
- const json = await safeJsonResponse(res);
2256
- return json.data;
2238
+ return requireObjectData(json.data);
2257
2239
  }
2258
2240
  async function marrowAgentPerformance(apiKey, baseUrl, period = '7d', agentIdFilter, sessionId, agentId) {
2259
2241
  const qs = new URLSearchParams({ period: String(clampPeriodDays(period)) });
2260
2242
  if (agentIdFilter || agentId)
2261
2243
  qs.set('agent_id', agentIdFilter || agentId || '');
2262
- const res = await fetch(`${baseUrl}/v1/analytics/agent-performance?${qs.toString()}`, {
2244
+ const json = await fetchJsonResponse(`${baseUrl}/v1/analytics/agent-performance?${qs.toString()}`, {
2263
2245
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
2264
2246
  });
2265
- const json = await safeJsonResponse(res);
2266
2247
  return json.data;
2267
2248
  }
2268
2249
  async function marrowFleetLessons(apiKey, baseUrl, options = {}, sessionId, agentId) {
@@ -2275,14 +2256,13 @@ async function marrowFleetLessons(apiKey, baseUrl, options = {}, sessionId, agen
2275
2256
  qs.set('agent_id', options.agentId || agentId || '');
2276
2257
  if (options.limit)
2277
2258
  qs.set('limit', String(options.limit));
2278
- const res = await fetch(`${baseUrl}/v1/fleet/lessons${qs.toString() ? `?${qs.toString()}` : ''}`, {
2259
+ const json = await fetchJsonResponse(`${baseUrl}/v1/fleet/lessons${qs.toString() ? `?${qs.toString()}` : ''}`, {
2279
2260
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
2280
2261
  });
2281
- const json = await safeJsonResponse(res);
2282
2262
  return json.data;
2283
2263
  }
2284
2264
  async function marrowRecordDeploymentMemory(apiKey, baseUrl, input, sessionId, agentId) {
2285
- const res = await fetch(`${baseUrl}/v1/fleet/deployment-memory`, {
2265
+ const json = await fetchJsonResponse(`${baseUrl}/v1/fleet/deployment-memory`, {
2286
2266
  method: 'POST',
2287
2267
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2288
2268
  body: JSON.stringify({
@@ -2291,11 +2271,10 @@ async function marrowRecordDeploymentMemory(apiKey, baseUrl, input, sessionId, a
2291
2271
  tests: Array.isArray(input.tests) ? input.tests : undefined,
2292
2272
  }),
2293
2273
  });
2294
- const json = await safeJsonResponse(res);
2295
2274
  return json.data;
2296
2275
  }
2297
2276
  async function marrowCreateHandoff(apiKey, baseUrl, input, sessionId, agentId) {
2298
- const res = await fetch(`${baseUrl}/v1/fleet/handoffs`, {
2277
+ const json = await fetchJsonResponse(`${baseUrl}/v1/fleet/handoffs`, {
2299
2278
  method: 'POST',
2300
2279
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2301
2280
  body: JSON.stringify({
@@ -2305,12 +2284,11 @@ async function marrowCreateHandoff(apiKey, baseUrl, input, sessionId, agentId) {
2305
2284
  task: String(input.task || ''),
2306
2285
  }),
2307
2286
  });
2308
- const json = await safeJsonResponse(res);
2309
2287
  return json.data;
2310
2288
  }
2311
2289
  async function marrowUpdateHandoff(apiKey, baseUrl, handoffId, input, sessionId, agentId) {
2312
2290
  const safeId = validatePathParam(handoffId, 'handoffId');
2313
- const res = await fetch(`${baseUrl}/v1/fleet/handoffs/${safeId}`, {
2291
+ const json = await fetchJsonResponse(`${baseUrl}/v1/fleet/handoffs/${safeId}`, {
2314
2292
  method: 'PATCH',
2315
2293
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2316
2294
  body: JSON.stringify({
@@ -2319,7 +2297,6 @@ async function marrowUpdateHandoff(apiKey, baseUrl, handoffId, input, sessionId,
2319
2297
  result_summary: typeof input.result_summary === 'string' ? input.result_summary : undefined,
2320
2298
  }),
2321
2299
  });
2322
- const json = await safeJsonResponse(res);
2323
2300
  return json.data;
2324
2301
  }
2325
2302
  async function marrowHandoffStatus(apiKey, baseUrl, options = {}, sessionId, agentId, signal) {
@@ -2330,34 +2307,31 @@ async function marrowHandoffStatus(apiKey, baseUrl, options = {}, sessionId, age
2330
2307
  qs.set('agent_id', options.agentId || agentId || '');
2331
2308
  if (options.limit)
2332
2309
  qs.set('limit', String(options.limit));
2333
- const res = await fetch(`${baseUrl}/v1/fleet/handoffs/status${qs.toString() ? `?${qs.toString()}` : ''}`, {
2310
+ const json = await fetchJsonResponse(`${baseUrl}/v1/fleet/handoffs/status${qs.toString() ? `?${qs.toString()}` : ''}`, {
2334
2311
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
2335
2312
  signal,
2336
2313
  });
2337
- const json = await safeJsonResponse(res);
2338
2314
  return json.data;
2339
2315
  }
2340
2316
  /**
2341
2317
  * Get a periodic improvement nudge when Marrow has something worth surfacing.
2342
2318
  */
2343
2319
  async function marrowNudge(apiKey, baseUrl, sessionId, agentId) {
2344
- const res = await fetch(`${baseUrl}/v1/agent/nudge`, {
2320
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/nudge`, {
2345
2321
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
2346
2322
  });
2347
- const json = await safeJsonResponse(res);
2348
2323
  return json.data;
2349
2324
  }
2350
2325
  /**
2351
2326
  * Explicitly end the current session.
2352
2327
  */
2353
2328
  async function marrowSessionEnd(apiKey, baseUrl, autoCommitOpen = false, sessionId, agentId, signal) {
2354
- const res = await fetch(`${baseUrl}/v1/agent/session/end`, {
2329
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/session/end`, {
2355
2330
  method: 'POST',
2356
2331
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2357
2332
  body: JSON.stringify({ auto_commit_open: autoCommitOpen }),
2358
2333
  signal,
2359
2334
  });
2360
- const json = await safeJsonResponse(res);
2361
2335
  return json.data;
2362
2336
  }
2363
2337
  async function marrowIntegrationEvent(apiKey, baseUrl, event, sessionId, agentId) {
@@ -2373,10 +2347,9 @@ async function marrowIntegrationEvent(apiKey, baseUrl, event, sessionId, agentId
2373
2347
  }
2374
2348
  async function marrowDecisionTrace(apiKey, baseUrl, decisionId, sessionId, agentId) {
2375
2349
  const safeId = validatePathParam(decisionId, 'decisionId');
2376
- const response = await fetch(`${baseUrl}/v1/agent/governance/trace/${safeId}`, {
2350
+ const json = await fetchJsonResponse(`${baseUrl}/v1/agent/governance/trace/${safeId}`, {
2377
2351
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
2378
2352
  });
2379
- const json = await safeJsonResponse(response);
2380
2353
  return json.data || json;
2381
2354
  }
2382
2355
  /**
@@ -2384,12 +2357,11 @@ async function marrowDecisionTrace(apiKey, baseUrl, decisionId, sessionId, agent
2384
2357
  */
2385
2358
  async function marrowAcceptDetected(apiKey, baseUrl, detectedId, sessionId, agentId) {
2386
2359
  const safeId = validatePathParam(detectedId, 'detectedId');
2387
- const res = await fetch(`${baseUrl}/v1/workflows/accept-detected`, {
2360
+ const json = await fetchJsonResponse(`${baseUrl}/v1/workflows/accept-detected`, {
2388
2361
  method: 'POST',
2389
2362
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2390
2363
  body: JSON.stringify({ detected_id: safeId }),
2391
2364
  });
2392
- const json = await safeJsonResponse(res);
2393
2365
  return json.data;
2394
2366
  }
2395
2367
  // ============= Template Marketplace (MCP v3.1.3) =============
@@ -2405,10 +2377,9 @@ async function marrowListTemplates(apiKey, baseUrl, params, sessionId, agentId)
2405
2377
  if (params?.limit)
2406
2378
  qs.set('limit', String(params.limit));
2407
2379
  const query = qs.toString();
2408
- const res = await fetch(`${baseUrl}/v1/templates${query ? '?' + query : ''}`, {
2380
+ const json = await fetchJsonResponse(`${baseUrl}/v1/templates${query ? '?' + query : ''}`, {
2409
2381
  headers: buildHeaders(apiKey, sessionId, undefined, agentId),
2410
2382
  });
2411
- const json = await safeJsonResponse(res);
2412
2383
  return json.data;
2413
2384
  }
2414
2385
  /**
@@ -2416,11 +2387,10 @@ async function marrowListTemplates(apiKey, baseUrl, params, sessionId, agentId)
2416
2387
  */
2417
2388
  async function marrowInstallTemplate(apiKey, baseUrl, slug, sessionId, agentId) {
2418
2389
  const safeSlug = validatePathParam(slug, 'slug');
2419
- const res = await fetch(`${baseUrl}/v1/templates/${safeSlug}/install`, {
2390
+ const json = await fetchJsonResponse(`${baseUrl}/v1/templates/${safeSlug}/install`, {
2420
2391
  method: 'POST',
2421
2392
  headers: buildHeaders(apiKey, sessionId, 'application/json', agentId),
2422
2393
  });
2423
- const json = await safeJsonResponse(res);
2424
2394
  return json.data;
2425
2395
  }
2426
2396
  //# sourceMappingURL=index.js.map