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.
- package/dist/cli.js +108 -1
- package/dist/index.js +101 -1
- 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.
|
|
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.
|
|
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) {
|