mindgraph-mcp 0.11.0 → 0.12.0

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.
Files changed (3) hide show
  1. package/dist/cli.js +108 -1
  2. package/dist/index.js +101 -1
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1546,6 +1546,99 @@ var init_generated_tools = __esm({
1546
1546
  }
1547
1547
  });
1548
1548
 
1549
+ // src/governance.ts
1550
+ function headers(apiKey, orgId) {
1551
+ const value = {
1552
+ authorization: `Bearer ${apiKey}`,
1553
+ "content-type": "application/json"
1554
+ };
1555
+ if (orgId) value["x-mindgraph-org"] = orgId;
1556
+ return value;
1557
+ }
1558
+ function unsupportedResponse(status, body) {
1559
+ if (status === 404 || status === 405) return true;
1560
+ if (status !== 400) return false;
1561
+ const lower = body.toLowerCase();
1562
+ return lower.includes("unknown governance action") || lower.includes("unknown action") || lower.includes("invalid_governance_action");
1563
+ }
1564
+ async function checkMcpGovernance(toolName, args, config) {
1565
+ if (config.disabled || capability === "unsupported") return { allowed: true };
1566
+ const fetchImpl = config.fetchImpl ?? fetch;
1567
+ let response;
1568
+ let body;
1569
+ try {
1570
+ response = await fetchImpl(`${config.baseUrl.replace(/\/$/, "")}/agent/governance`, {
1571
+ method: "POST",
1572
+ headers: headers(config.apiKey, config.orgId),
1573
+ body: JSON.stringify({
1574
+ action: "check",
1575
+ act: "tool_invoke",
1576
+ agent_id: String(args.agent_id || config.agentId),
1577
+ target: { tool_name: toolName },
1578
+ context: { adapter: "mindgraph-mcp" },
1579
+ tier: "checkpoint"
1580
+ })
1581
+ });
1582
+ body = await response.text();
1583
+ } catch (error) {
1584
+ return {
1585
+ allowed: false,
1586
+ message: `MindGraph governance could not establish permission: ${error instanceof Error ? error.message : String(error)}`
1587
+ };
1588
+ }
1589
+ if (!response.ok) {
1590
+ if (capability === "unknown" && unsupportedResponse(response.status, body)) {
1591
+ capability = "unsupported";
1592
+ return { allowed: true };
1593
+ }
1594
+ return {
1595
+ allowed: false,
1596
+ message: `MindGraph governance check failed (${response.status})`
1597
+ };
1598
+ }
1599
+ capability = "supported";
1600
+ let decision;
1601
+ try {
1602
+ decision = JSON.parse(body);
1603
+ } catch {
1604
+ return { allowed: false, message: "MindGraph governance returned an invalid decision" };
1605
+ }
1606
+ const obligations = Array.isArray(decision.obligations) ? decision.obligations : [];
1607
+ const unknownDuty = obligations.find((obligation) => {
1608
+ if (!obligation || typeof obligation !== "object") return true;
1609
+ const duty = obligation.duty;
1610
+ return typeof duty !== "string" || !KNOWN_DUTIES.has(duty);
1611
+ });
1612
+ if (unknownDuty) {
1613
+ return {
1614
+ allowed: false,
1615
+ decision: String(decision.decision || "conditional"),
1616
+ message: "MindGraph governance returned an obligation this adapter cannot safely enforce"
1617
+ };
1618
+ }
1619
+ const verdict = String(decision.decision || "deny");
1620
+ if (verdict === "permit") return { allowed: true };
1621
+ const fired = Array.isArray(decision.fired_policies) ? decision.fired_policies : [];
1622
+ const first = fired[0];
1623
+ const policy = first && typeof first.name === "string" ? first.name : void 0;
1624
+ const approvalUid = typeof decision.approval_uid === "string" ? decision.approval_uid : void 0;
1625
+ return {
1626
+ allowed: false,
1627
+ decision: verdict,
1628
+ approval_uid: approvalUid,
1629
+ policy,
1630
+ message: verdict === "conditional" ? `Approval is required${policy ? ` by policy ${policy}` : ""}${approvalUid ? ` (approval ${approvalUid})` : ""}` : `Denied by MindGraph governance${policy ? ` policy ${policy}` : ""}`
1631
+ };
1632
+ }
1633
+ var capability, KNOWN_DUTIES;
1634
+ var init_governance = __esm({
1635
+ "src/governance.ts"() {
1636
+ "use strict";
1637
+ capability = "unknown";
1638
+ KNOWN_DUTIES = /* @__PURE__ */ new Set(["log", "require_approval"]);
1639
+ }
1640
+ });
1641
+
1549
1642
  // src/index.ts
1550
1643
  var src_exports = {};
1551
1644
  async function main() {
@@ -1565,6 +1658,7 @@ var init_src = __esm({
1565
1658
  import_mindgraph = require("mindgraph");
1566
1659
  init_tools();
1567
1660
  init_generated_tools();
1661
+ init_governance();
1568
1662
  API_KEY = process.env.MINDGRAPH_API_KEY;
1569
1663
  BASE_URL = process.env.MINDGRAPH_BASE_URL || "https://api.mindgraph.cloud";
1570
1664
  AGENT_ID = process.env.MINDGRAPH_AGENT_ID || "mcp";
@@ -1658,7 +1752,7 @@ Capture knowledge when the user shares something worth remembering:
1658
1752
  server = new import_server.Server(
1659
1753
  {
1660
1754
  name: "mindgraph",
1661
- version: "0.10.0"
1755
+ version: "0.12.0"
1662
1756
  },
1663
1757
  {
1664
1758
  capabilities: {
@@ -1679,6 +1773,19 @@ Capture knowledge when the user shares something worth remembering:
1679
1773
  if (!toolArgs.agent_id) {
1680
1774
  toolArgs.agent_id = AGENT_ID;
1681
1775
  }
1776
+ const governance = await checkMcpGovernance(name, toolArgs, {
1777
+ baseUrl: BASE_URL,
1778
+ apiKey: API_KEY,
1779
+ orgId: ORG_ID,
1780
+ agentId: AGENT_ID,
1781
+ disabled: process.env.MINDGRAPH_GOVERNANCE === "off"
1782
+ });
1783
+ if (!governance.allowed) {
1784
+ return {
1785
+ content: [{ type: "text", text: JSON.stringify({ error: governance.message, ...governance }) }],
1786
+ isError: true
1787
+ };
1788
+ }
1682
1789
  const generated = await getGeneratedTools(client);
1683
1790
  const desc = generated.byName.get(name);
1684
1791
  if (desc) {
package/dist/index.js CHANGED
@@ -1514,6 +1514,93 @@ async function handleGeneratedTool(client2, desc, args) {
1514
1514
  }
1515
1515
  }
1516
1516
 
1517
+ // src/governance.ts
1518
+ var capability = "unknown";
1519
+ var KNOWN_DUTIES = /* @__PURE__ */ new Set(["log", "require_approval"]);
1520
+ function headers(apiKey, orgId) {
1521
+ const value = {
1522
+ authorization: `Bearer ${apiKey}`,
1523
+ "content-type": "application/json"
1524
+ };
1525
+ if (orgId) value["x-mindgraph-org"] = orgId;
1526
+ return value;
1527
+ }
1528
+ function unsupportedResponse(status, body) {
1529
+ if (status === 404 || status === 405) return true;
1530
+ if (status !== 400) return false;
1531
+ const lower = body.toLowerCase();
1532
+ return lower.includes("unknown governance action") || lower.includes("unknown action") || lower.includes("invalid_governance_action");
1533
+ }
1534
+ async function checkMcpGovernance(toolName, args, config) {
1535
+ if (config.disabled || capability === "unsupported") return { allowed: true };
1536
+ const fetchImpl = config.fetchImpl ?? fetch;
1537
+ let response;
1538
+ let body;
1539
+ try {
1540
+ response = await fetchImpl(`${config.baseUrl.replace(/\/$/, "")}/agent/governance`, {
1541
+ method: "POST",
1542
+ headers: headers(config.apiKey, config.orgId),
1543
+ body: JSON.stringify({
1544
+ action: "check",
1545
+ act: "tool_invoke",
1546
+ agent_id: String(args.agent_id || config.agentId),
1547
+ target: { tool_name: toolName },
1548
+ context: { adapter: "mindgraph-mcp" },
1549
+ tier: "checkpoint"
1550
+ })
1551
+ });
1552
+ body = await response.text();
1553
+ } catch (error) {
1554
+ return {
1555
+ allowed: false,
1556
+ message: `MindGraph governance could not establish permission: ${error instanceof Error ? error.message : String(error)}`
1557
+ };
1558
+ }
1559
+ if (!response.ok) {
1560
+ if (capability === "unknown" && unsupportedResponse(response.status, body)) {
1561
+ capability = "unsupported";
1562
+ return { allowed: true };
1563
+ }
1564
+ return {
1565
+ allowed: false,
1566
+ message: `MindGraph governance check failed (${response.status})`
1567
+ };
1568
+ }
1569
+ capability = "supported";
1570
+ let decision;
1571
+ try {
1572
+ decision = JSON.parse(body);
1573
+ } catch {
1574
+ return { allowed: false, message: "MindGraph governance returned an invalid decision" };
1575
+ }
1576
+ const obligations = Array.isArray(decision.obligations) ? decision.obligations : [];
1577
+ const unknownDuty = obligations.find((obligation) => {
1578
+ if (!obligation || typeof obligation !== "object") return true;
1579
+ const duty = obligation.duty;
1580
+ return typeof duty !== "string" || !KNOWN_DUTIES.has(duty);
1581
+ });
1582
+ if (unknownDuty) {
1583
+ return {
1584
+ allowed: false,
1585
+ decision: String(decision.decision || "conditional"),
1586
+ message: "MindGraph governance returned an obligation this adapter cannot safely enforce"
1587
+ };
1588
+ }
1589
+ const verdict = String(decision.decision || "deny");
1590
+ if (verdict === "permit") return { allowed: true };
1591
+ const fired = Array.isArray(decision.fired_policies) ? decision.fired_policies : [];
1592
+ const first = fired[0];
1593
+ const policy = first && typeof first.name === "string" ? first.name : void 0;
1594
+ const approvalUid = typeof decision.approval_uid === "string" ? decision.approval_uid : void 0;
1595
+ return {
1596
+ allowed: false,
1597
+ decision: verdict,
1598
+ approval_uid: approvalUid,
1599
+ policy,
1600
+ message: verdict === "conditional" ? `Approval is required${policy ? ` by policy ${policy}` : ""}${approvalUid ? ` (approval ${approvalUid})` : ""}` : `Denied by MindGraph governance${policy ? ` policy ${policy}` : ""}`
1601
+ };
1602
+ }
1603
+
1517
1604
  // src/index.ts
1518
1605
  var API_KEY = process.env.MINDGRAPH_API_KEY;
1519
1606
  var BASE_URL = process.env.MINDGRAPH_BASE_URL || "https://api.mindgraph.cloud";
@@ -1608,7 +1695,7 @@ Capture knowledge when the user shares something worth remembering:
1608
1695
  var server = new import_server.Server(
1609
1696
  {
1610
1697
  name: "mindgraph",
1611
- version: "0.10.0"
1698
+ version: "0.12.0"
1612
1699
  },
1613
1700
  {
1614
1701
  capabilities: {
@@ -1629,6 +1716,19 @@ server.setRequestHandler(import_types.CallToolRequestSchema, async (request) =>
1629
1716
  if (!toolArgs.agent_id) {
1630
1717
  toolArgs.agent_id = AGENT_ID;
1631
1718
  }
1719
+ const governance = await checkMcpGovernance(name, toolArgs, {
1720
+ baseUrl: BASE_URL,
1721
+ apiKey: API_KEY,
1722
+ orgId: ORG_ID,
1723
+ agentId: AGENT_ID,
1724
+ disabled: process.env.MINDGRAPH_GOVERNANCE === "off"
1725
+ });
1726
+ if (!governance.allowed) {
1727
+ return {
1728
+ content: [{ type: "text", text: JSON.stringify({ error: governance.message, ...governance }) }],
1729
+ isError: true
1730
+ };
1731
+ }
1632
1732
  const generated = await getGeneratedTools(client);
1633
1733
  const desc = generated.byName.get(name);
1634
1734
  if (desc) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindgraph-mcp",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "MCP server for MindGraph — connect Claude Desktop, Claude Code, and any MCP client to your knowledge graph",
5
5
  "repository": {
6
6
  "type": "git",