@polygraphso/litmus 0.2.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/LICENSE +190 -0
- package/README.md +114 -0
- package/dist/chunk-2K6T4FZX.js +1458 -0
- package/dist/chunk-6QM4RK25.js +180 -0
- package/dist/chunk-MQC54LFV.js +218 -0
- package/dist/chunk-SAZKXB35.js +120 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +119 -0
- package/dist/docker/egress-sniff.Dockerfile +13 -0
- package/dist/docker/sink-entrypoint.sh +9 -0
- package/dist/docker/sinkhole.mjs +90 -0
- package/dist/index.d.ts +594 -0
- package/dist/index.js +130 -0
- package/dist/mcp.d.ts +16 -0
- package/dist/mcp.js +230 -0
- package/dist/src-XIEFSTXC.js +29 -0
- package/package.json +75 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LITMUS_SCHEMA,
|
|
3
|
+
NETWORKS,
|
|
4
|
+
RUN_LITMUS_TOOL_DESCRIPTION,
|
|
5
|
+
RUN_LITMUS_TOOL_NAME,
|
|
6
|
+
RUN_LITMUS_TOOL_TITLE,
|
|
7
|
+
decodeLitmusAttestation,
|
|
8
|
+
encodeLitmusAttestation,
|
|
9
|
+
handleRunLitmus,
|
|
10
|
+
litmusFields,
|
|
11
|
+
litmusSchemaUID,
|
|
12
|
+
networkConfig,
|
|
13
|
+
readAttestation,
|
|
14
|
+
rpcUrl,
|
|
15
|
+
runLitmusInputShape,
|
|
16
|
+
selectedNetwork
|
|
17
|
+
} from "./chunk-MQC54LFV.js";
|
|
18
|
+
import {
|
|
19
|
+
parseAuthFlags,
|
|
20
|
+
resolveTarget
|
|
21
|
+
} from "./chunk-6QM4RK25.js";
|
|
22
|
+
import {
|
|
23
|
+
assembleBundle,
|
|
24
|
+
canaryMatch,
|
|
25
|
+
classifyTool,
|
|
26
|
+
connectTarget,
|
|
27
|
+
fingerprintToolDefs,
|
|
28
|
+
gradeFromCategories,
|
|
29
|
+
hasHighSeverity,
|
|
30
|
+
instructionMimicry,
|
|
31
|
+
invisibleUnicode,
|
|
32
|
+
markdownTricks,
|
|
33
|
+
runLitmus,
|
|
34
|
+
stateChangingToolNames
|
|
35
|
+
} from "./chunk-2K6T4FZX.js";
|
|
36
|
+
import {
|
|
37
|
+
BUNDLE_SCHEMA_VERSION,
|
|
38
|
+
CATEGORY_STATUS_UINT8,
|
|
39
|
+
METHODOLOGY_VERSION,
|
|
40
|
+
ServerRefParseError,
|
|
41
|
+
canonicalStringify,
|
|
42
|
+
formatServerRef,
|
|
43
|
+
parseServerRef,
|
|
44
|
+
serverKey
|
|
45
|
+
} from "./chunk-SAZKXB35.js";
|
|
46
|
+
|
|
47
|
+
// ../agent/src/gate.ts
|
|
48
|
+
function sameServer(a, b) {
|
|
49
|
+
return a.trim().toLowerCase() === b.trim().toLowerCase();
|
|
50
|
+
}
|
|
51
|
+
var DEFAULT_PASSING = /* @__PURE__ */ new Set(["A", "B", "C"]);
|
|
52
|
+
function gateDecision(attestation, live, passing = DEFAULT_PASSING, now = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
53
|
+
if (!attestation) {
|
|
54
|
+
return { action: "refuse", reason: "no attestation \u2014 unevaluated server" };
|
|
55
|
+
}
|
|
56
|
+
if (attestation.revoked) {
|
|
57
|
+
return { action: "refuse", reason: "attestation revoked" };
|
|
58
|
+
}
|
|
59
|
+
const exp = attestation.expirationTime ?? 0n;
|
|
60
|
+
if (exp !== 0n && now >= exp) {
|
|
61
|
+
return { action: "refuse", reason: "attestation expired" };
|
|
62
|
+
}
|
|
63
|
+
if (!sameServer(attestation.serverRef, live.serverRef)) {
|
|
64
|
+
return { action: "refuse", reason: "attestation is for a different server than the one being gated" };
|
|
65
|
+
}
|
|
66
|
+
if (attestation.toolDefsFingerprint.toLowerCase() !== live.fingerprint.toLowerCase()) {
|
|
67
|
+
return { action: "refuse", reason: "rug pull \u2014 live tool surface differs from the graded one" };
|
|
68
|
+
}
|
|
69
|
+
if (!passing.has(attestation.overallGrade)) {
|
|
70
|
+
return { action: "refuse", reason: `failing grade ${attestation.overallGrade}` };
|
|
71
|
+
}
|
|
72
|
+
const versionNote = attestation.resolvedVersion ? ` (graded version ${attestation.resolvedVersion})` : "";
|
|
73
|
+
return { action: "pay", reason: `grade ${attestation.overallGrade}; live fingerprint matches${versionNote}` };
|
|
74
|
+
}
|
|
75
|
+
async function liveFingerprint(target) {
|
|
76
|
+
const conn = await connectTarget(target);
|
|
77
|
+
try {
|
|
78
|
+
const { tools } = await conn.client.listTools();
|
|
79
|
+
const defs = (tools ?? []).map((t) => ({
|
|
80
|
+
name: t.name,
|
|
81
|
+
description: t.description ?? "",
|
|
82
|
+
inputSchema: t.inputSchema ?? null
|
|
83
|
+
}));
|
|
84
|
+
return { fingerprint: fingerprintToolDefs(defs).fingerprint, serverRef: conn.serverRef };
|
|
85
|
+
} finally {
|
|
86
|
+
await conn.teardown();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export {
|
|
90
|
+
BUNDLE_SCHEMA_VERSION,
|
|
91
|
+
CATEGORY_STATUS_UINT8,
|
|
92
|
+
DEFAULT_PASSING,
|
|
93
|
+
LITMUS_SCHEMA,
|
|
94
|
+
METHODOLOGY_VERSION,
|
|
95
|
+
NETWORKS,
|
|
96
|
+
RUN_LITMUS_TOOL_DESCRIPTION,
|
|
97
|
+
RUN_LITMUS_TOOL_NAME,
|
|
98
|
+
RUN_LITMUS_TOOL_TITLE,
|
|
99
|
+
ServerRefParseError,
|
|
100
|
+
assembleBundle,
|
|
101
|
+
canaryMatch,
|
|
102
|
+
canonicalStringify,
|
|
103
|
+
classifyTool,
|
|
104
|
+
connectTarget,
|
|
105
|
+
decodeLitmusAttestation,
|
|
106
|
+
encodeLitmusAttestation,
|
|
107
|
+
fingerprintToolDefs,
|
|
108
|
+
formatServerRef,
|
|
109
|
+
gateDecision,
|
|
110
|
+
gradeFromCategories,
|
|
111
|
+
handleRunLitmus,
|
|
112
|
+
hasHighSeverity,
|
|
113
|
+
instructionMimicry,
|
|
114
|
+
invisibleUnicode,
|
|
115
|
+
litmusFields,
|
|
116
|
+
litmusSchemaUID,
|
|
117
|
+
liveFingerprint,
|
|
118
|
+
markdownTricks,
|
|
119
|
+
networkConfig,
|
|
120
|
+
parseAuthFlags,
|
|
121
|
+
parseServerRef,
|
|
122
|
+
readAttestation,
|
|
123
|
+
resolveTarget,
|
|
124
|
+
rpcUrl,
|
|
125
|
+
runLitmus,
|
|
126
|
+
runLitmusInputShape,
|
|
127
|
+
selectedNetwork,
|
|
128
|
+
serverKey,
|
|
129
|
+
stateChangingToolNames
|
|
130
|
+
};
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `polygraphso-litmus-mcp` — the polygraph litmus MCP server. Stdio transport.
|
|
6
|
+
* Exposes two tools to any MCP client (Claude Desktop, Cursor, …):
|
|
7
|
+
*
|
|
8
|
+
* • `run_litmus` — actively grade an MCP server A–F, then hand off to mint.
|
|
9
|
+
* • `verify_attestation` — passively read a server's published onchain grade.
|
|
10
|
+
*
|
|
11
|
+
* Also exported as `@polygraphso/litmus/mcp` for embedding in a custom server.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
declare function buildServer(): McpServer;
|
|
15
|
+
|
|
16
|
+
export { buildServer };
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
RUN_LITMUS_TOOL_DESCRIPTION,
|
|
4
|
+
RUN_LITMUS_TOOL_NAME,
|
|
5
|
+
RUN_LITMUS_TOOL_TITLE,
|
|
6
|
+
handleRunLitmus,
|
|
7
|
+
readAttestation,
|
|
8
|
+
runLitmusInputShape,
|
|
9
|
+
selectedNetwork
|
|
10
|
+
} from "./chunk-MQC54LFV.js";
|
|
11
|
+
import "./chunk-6QM4RK25.js";
|
|
12
|
+
import "./chunk-2K6T4FZX.js";
|
|
13
|
+
import {
|
|
14
|
+
parseServerRef,
|
|
15
|
+
serverKey
|
|
16
|
+
} from "./chunk-SAZKXB35.js";
|
|
17
|
+
|
|
18
|
+
// src/mcp.ts
|
|
19
|
+
import { realpathSync } from "fs";
|
|
20
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
21
|
+
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
22
|
+
import { StdioServerTransport as StdioServerTransport2 } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
23
|
+
|
|
24
|
+
// ../mcp/src/index.ts
|
|
25
|
+
import { fileURLToPath } from "url";
|
|
26
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
27
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
28
|
+
|
|
29
|
+
// ../mcp/src/tools/verify-attestation.ts
|
|
30
|
+
import { z } from "zod";
|
|
31
|
+
function canonicalRef(ref) {
|
|
32
|
+
try {
|
|
33
|
+
return serverKey(parseServerRef(ref)).toLowerCase();
|
|
34
|
+
} catch {
|
|
35
|
+
return ref.trim().toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
var VERIFY_TOOL_NAME = "verify_attestation";
|
|
39
|
+
var VERIFY_TOOL_TITLE = "Verify a server's polygraph attestation";
|
|
40
|
+
var VERIFY_TOOL_DESCRIPTION = [
|
|
41
|
+
"Read the onchain polygraph (litmus) attestation for an MCP server before an",
|
|
42
|
+
"agent trusts \u2014 or, in agentic commerce, pays \u2014 it.",
|
|
43
|
+
"",
|
|
44
|
+
"Returns the behavioral grade (A\u2013F), the attestation UID, the evidence CID,",
|
|
45
|
+
"and the graded tool-surface fingerprint. The caller must still recompute the",
|
|
46
|
+
"LIVE fingerprint and require it to equal the attested one before paying \u2014 a",
|
|
47
|
+
"passing attestation can otherwise front for a tool surface the server no",
|
|
48
|
+
"longer serves (rug pull).",
|
|
49
|
+
"",
|
|
50
|
+
"Input: server_ref \u2014 e.g. npm/@modelcontextprotocol/server-filesystem. Returns",
|
|
51
|
+
"not_available when there is no attestation: treat that as unevaluated \u2014",
|
|
52
|
+
"neither safe nor unsafe."
|
|
53
|
+
].join("\n");
|
|
54
|
+
var verifyInputShape = {
|
|
55
|
+
server_ref: z.string().min(1).max(512).describe("Registry-prefixed server identifier, e.g. npm/@scope/server.")
|
|
56
|
+
};
|
|
57
|
+
async function handleVerify({ server_ref }) {
|
|
58
|
+
const uid = await resolveUid(server_ref);
|
|
59
|
+
const att = uid ? await readAttestation(uid) : null;
|
|
60
|
+
if (!att) {
|
|
61
|
+
return {
|
|
62
|
+
content: [{ type: "text", text: `not_available \u2014 no polygraph attestation for ${server_ref}` }]
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (canonicalRef(att.serverRef) !== canonicalRef(server_ref)) {
|
|
66
|
+
return {
|
|
67
|
+
content: [
|
|
68
|
+
{
|
|
69
|
+
type: "text",
|
|
70
|
+
text: `not_available \u2014 the resolved attestation is for ${att.serverRef}, not ${server_ref} (discovery mismatch; treat as unevaluated)`
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const payload = {
|
|
76
|
+
status: "attested",
|
|
77
|
+
grade: att.overallGrade,
|
|
78
|
+
attestationUid: att.uid,
|
|
79
|
+
serverRef: att.serverRef,
|
|
80
|
+
// The version the grade was run against (null for HTTP/unresolved targets).
|
|
81
|
+
// Advisory: the live fingerprint, not this string, is the trust anchor.
|
|
82
|
+
resolvedVersion: att.resolvedVersion,
|
|
83
|
+
reportCID: att.reportCID,
|
|
84
|
+
toolDefsFingerprint: att.toolDefsFingerprint,
|
|
85
|
+
revoked: att.revoked,
|
|
86
|
+
network: selectedNetwork(),
|
|
87
|
+
liveFingerprintCheckRequired: "Recompute the live tool-surface fingerprint and require it to equal toolDefsFingerprint before paying."
|
|
88
|
+
};
|
|
89
|
+
return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
|
|
90
|
+
}
|
|
91
|
+
async function resolveUid(serverRef) {
|
|
92
|
+
const base = process.env.POLYGRAPH_API_URL ?? "https://polygraph.so";
|
|
93
|
+
try {
|
|
94
|
+
const res = await fetch(`${base}/api/attestations?ref=${encodeURIComponent(serverRef)}`);
|
|
95
|
+
if (!res.ok) return null;
|
|
96
|
+
const row = await res.json();
|
|
97
|
+
return row?.attestation_uid ?? null;
|
|
98
|
+
} catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ../mcp/src/index.ts
|
|
104
|
+
function buildServer() {
|
|
105
|
+
const server = new McpServer(
|
|
106
|
+
{ name: "polygraph", version: "0.0.0" },
|
|
107
|
+
{
|
|
108
|
+
instructions: [
|
|
109
|
+
"polygraph issues behavioral litmus grades for MCP servers, published",
|
|
110
|
+
"onchain. Use `verify_attestation` to read a server's grade before",
|
|
111
|
+
"recommending, installing, or paying it. A server with no attestation is",
|
|
112
|
+
"unevaluated \u2014 neither safe nor unsafe; say so."
|
|
113
|
+
].join("\n")
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
server.registerTool(
|
|
117
|
+
VERIFY_TOOL_NAME,
|
|
118
|
+
{
|
|
119
|
+
title: VERIFY_TOOL_TITLE,
|
|
120
|
+
description: VERIFY_TOOL_DESCRIPTION,
|
|
121
|
+
inputSchema: verifyInputShape,
|
|
122
|
+
annotations: {
|
|
123
|
+
title: VERIFY_TOOL_TITLE,
|
|
124
|
+
readOnlyHint: true,
|
|
125
|
+
destructiveHint: false,
|
|
126
|
+
idempotentHint: true,
|
|
127
|
+
openWorldHint: true
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
handleVerify
|
|
131
|
+
);
|
|
132
|
+
return server;
|
|
133
|
+
}
|
|
134
|
+
async function main() {
|
|
135
|
+
const server = buildServer();
|
|
136
|
+
await server.connect(new StdioServerTransport());
|
|
137
|
+
}
|
|
138
|
+
var invokedDirectly = (() => {
|
|
139
|
+
try {
|
|
140
|
+
return process.argv[1] === fileURLToPath(import.meta.url);
|
|
141
|
+
} catch {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
})();
|
|
145
|
+
if (invokedDirectly) {
|
|
146
|
+
main().catch((err) => {
|
|
147
|
+
process.stderr.write(`polygraph-mcp: fatal: ${err instanceof Error ? err.message : String(err)}
|
|
148
|
+
`);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// src/mcp.ts
|
|
154
|
+
function buildServer2() {
|
|
155
|
+
const server = new McpServer2(
|
|
156
|
+
{ name: "polygraph-litmus", version: "0.1.0" },
|
|
157
|
+
{
|
|
158
|
+
instructions: [
|
|
159
|
+
"polygraph issues behavioral litmus grades (A\u2013F) for MCP servers.",
|
|
160
|
+
"",
|
|
161
|
+
"Use `run_litmus` to grade a server now: it runs the open harness against",
|
|
162
|
+
"the target and returns the grade, the evidence, and \u2014 when configured \u2014 a",
|
|
163
|
+
"mint hand-off URL the human opens to publish the grade onchain. It launches",
|
|
164
|
+
"the target's code (egress-sandboxed when Docker is present), so it is not a",
|
|
165
|
+
"passive read.",
|
|
166
|
+
"",
|
|
167
|
+
"Use `verify_attestation` to read a server's already-published grade before",
|
|
168
|
+
"recommending, installing, or paying it. A server with no attestation is",
|
|
169
|
+
"unevaluated \u2014 neither safe nor unsafe; say so."
|
|
170
|
+
].join("\n")
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
server.registerTool(
|
|
174
|
+
RUN_LITMUS_TOOL_NAME,
|
|
175
|
+
{
|
|
176
|
+
title: RUN_LITMUS_TOOL_TITLE,
|
|
177
|
+
description: RUN_LITMUS_TOOL_DESCRIPTION,
|
|
178
|
+
inputSchema: runLitmusInputShape,
|
|
179
|
+
annotations: {
|
|
180
|
+
title: RUN_LITMUS_TOOL_TITLE,
|
|
181
|
+
readOnlyHint: false,
|
|
182
|
+
// launches the target server's code (and maybe Docker)
|
|
183
|
+
destructiveHint: false,
|
|
184
|
+
// sandboxed; does not intentionally mutate the user's system
|
|
185
|
+
idempotentHint: false,
|
|
186
|
+
// re-running re-spawns + re-pins
|
|
187
|
+
openWorldHint: true
|
|
188
|
+
// reaches arbitrary external servers
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
handleRunLitmus
|
|
192
|
+
);
|
|
193
|
+
server.registerTool(
|
|
194
|
+
VERIFY_TOOL_NAME,
|
|
195
|
+
{
|
|
196
|
+
title: VERIFY_TOOL_TITLE,
|
|
197
|
+
description: VERIFY_TOOL_DESCRIPTION,
|
|
198
|
+
inputSchema: verifyInputShape,
|
|
199
|
+
annotations: {
|
|
200
|
+
title: VERIFY_TOOL_TITLE,
|
|
201
|
+
readOnlyHint: true,
|
|
202
|
+
destructiveHint: false,
|
|
203
|
+
idempotentHint: true,
|
|
204
|
+
openWorldHint: true
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
handleVerify
|
|
208
|
+
);
|
|
209
|
+
return server;
|
|
210
|
+
}
|
|
211
|
+
async function main2() {
|
|
212
|
+
await buildServer2().connect(new StdioServerTransport2());
|
|
213
|
+
}
|
|
214
|
+
var invokedDirectly2 = (() => {
|
|
215
|
+
try {
|
|
216
|
+
return realpathSync(process.argv[1] ?? "") === fileURLToPath2(import.meta.url);
|
|
217
|
+
} catch {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
})();
|
|
221
|
+
if (invokedDirectly2) {
|
|
222
|
+
main2().catch((err) => {
|
|
223
|
+
process.stderr.write(`polygraphso-litmus-mcp: fatal: ${err instanceof Error ? err.message : String(err)}
|
|
224
|
+
`);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
export {
|
|
229
|
+
buildServer2 as buildServer
|
|
230
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assembleBundle,
|
|
3
|
+
canaryMatch,
|
|
4
|
+
classifyTool,
|
|
5
|
+
connectTarget,
|
|
6
|
+
fingerprintToolDefs,
|
|
7
|
+
gradeFromCategories,
|
|
8
|
+
hasHighSeverity,
|
|
9
|
+
instructionMimicry,
|
|
10
|
+
invisibleUnicode,
|
|
11
|
+
markdownTricks,
|
|
12
|
+
runLitmus,
|
|
13
|
+
stateChangingToolNames
|
|
14
|
+
} from "./chunk-2K6T4FZX.js";
|
|
15
|
+
import "./chunk-SAZKXB35.js";
|
|
16
|
+
export {
|
|
17
|
+
assembleBundle,
|
|
18
|
+
canaryMatch,
|
|
19
|
+
classifyTool,
|
|
20
|
+
connectTarget,
|
|
21
|
+
fingerprintToolDefs,
|
|
22
|
+
gradeFromCategories,
|
|
23
|
+
hasHighSeverity,
|
|
24
|
+
instructionMimicry,
|
|
25
|
+
invisibleUnicode,
|
|
26
|
+
markdownTricks,
|
|
27
|
+
runLitmus,
|
|
28
|
+
stateChangingToolNames
|
|
29
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@polygraphso/litmus",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Behavioral litmus harness for MCP servers — grade a server A–F (tool-output injection, egress, sensitive-data), then hand off to mint an onchain attestation. Ships a CLI and an MCP server with a run_litmus tool for AI agents.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://polygraph.so",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/polygraphso/litmus.git",
|
|
10
|
+
"directory": "packages/litmus"
|
|
11
|
+
},
|
|
12
|
+
"bugs": "https://github.com/polygraphso/litmus/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"polygraph",
|
|
15
|
+
"mcp",
|
|
16
|
+
"model-context-protocol",
|
|
17
|
+
"trust",
|
|
18
|
+
"ai-agents",
|
|
19
|
+
"security",
|
|
20
|
+
"litmus"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"module": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./mcp": {
|
|
32
|
+
"types": "./dist/mcp.d.ts",
|
|
33
|
+
"import": "./dist/mcp.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"bin": {
|
|
37
|
+
"polygraphso-litmus": "dist/cli.js",
|
|
38
|
+
"polygraphso-litmus-mcp": "dist/mcp.js"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
44
|
+
],
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
50
|
+
"@ethereum-attestation-service/eas-sdk": "^2.9.1",
|
|
51
|
+
"ethers": "^6.16.0",
|
|
52
|
+
"zod": "^3.23.8",
|
|
53
|
+
"tsx": "^4.19.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^20.16.0",
|
|
57
|
+
"tsup": "^8.3.0",
|
|
58
|
+
"typescript": "^5.9.3",
|
|
59
|
+
"vitest": "^2.1.0",
|
|
60
|
+
"@polygraph/core": "0.0.0",
|
|
61
|
+
"@polygraph/probes": "0.0.0",
|
|
62
|
+
"@polygraph/onchain": "0.0.0",
|
|
63
|
+
"@polygraph/agent": "0.0.0",
|
|
64
|
+
"@polygraph/mcp": "0.0.0",
|
|
65
|
+
"@polygraph/cli": "0.0.0"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsup",
|
|
72
|
+
"typecheck": "tsc --noEmit",
|
|
73
|
+
"test": "vitest run --passWithNoTests"
|
|
74
|
+
}
|
|
75
|
+
}
|