@papyruslabsai/seshat-mcp 0.12.0 → 0.12.1
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.d.ts +8 -0
- package/dist/index.js +118 -488
- package/dist/tools/diff.d.ts +1 -0
- package/dist/tools/functors.d.ts +15 -15
- package/dist/tools/functors.js +7 -7
- package/dist/tools/index.d.ts +1 -1
- package/package.json +8 -1
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @papyruslabs/seshat-mcp — Semantic Code Analysis MCP Server (Cloud Proxy)
|
|
4
|
+
*
|
|
5
|
+
* This CLI server declares the full suite of Seshat tools to Claude/AI clients,
|
|
6
|
+
* but executes all logic remotely on the Ptah Cloud API for zero-conflict
|
|
7
|
+
* collaboration and deep analytics.
|
|
8
|
+
*/
|
|
1
9
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,84 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
node;
|
|
1
|
+
#!/usr/bin/env node
|
|
3
2
|
/**
|
|
4
|
-
* @papyruslabs/seshat-mcp — Semantic Code Analysis MCP Server
|
|
3
|
+
* @papyruslabs/seshat-mcp — Semantic Code Analysis MCP Server (Cloud Proxy)
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Multi-project mode:
|
|
10
|
-
* Set SESHAT_PROJECTS env var to comma-separated paths or a glob pattern.
|
|
11
|
-
* In multi-project mode, all tools require a `project` parameter.
|
|
12
|
-
* Use `list_projects` to see available projects.
|
|
13
|
-
*
|
|
14
|
-
* Single-project mode (default):
|
|
15
|
-
* When SESHAT_PROJECTS is not set, loads from CWD. No `project` param needed.
|
|
16
|
-
*
|
|
17
|
-
* 20 tools across 4 categories:
|
|
18
|
-
* Discovery: list_projects, query_entities, get_entity, list_modules, get_topology
|
|
19
|
-
* Graph: get_dependencies, get_data_flow, find_by_constraint, get_blast_radius
|
|
20
|
-
* Analysis: find_dead_code, find_layer_violations, get_coupling_metrics,
|
|
21
|
-
* get_auth_matrix, find_error_gaps, get_test_coverage,
|
|
22
|
-
* get_optimal_context, estimate_task_cost, report_actual_burn
|
|
23
|
-
* Diff: diff_bundle, conflict_matrix
|
|
24
|
-
*
|
|
25
|
-
* Usage:
|
|
26
|
-
* npx @papyruslabs/seshat-mcp # single project (CWD)
|
|
27
|
-
* SESHAT_PROJECTS=/path/a,/path/b npx @papyruslabs/seshat-mcp # multi-project
|
|
28
|
-
* SESHAT_PROJECTS="/home/user/projects/*" npx @papyruslabs/seshat-mcp # glob
|
|
5
|
+
* This CLI server declares the full suite of Seshat tools to Claude/AI clients,
|
|
6
|
+
* but executes all logic remotely on the Ptah Cloud API for zero-conflict
|
|
7
|
+
* collaboration and deep analytics.
|
|
29
8
|
*/
|
|
30
9
|
import fs from 'fs';
|
|
31
10
|
import path from 'path';
|
|
32
11
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
33
12
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
34
13
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
35
|
-
|
|
36
|
-
import { bootstrap } from './bootstrap.js';
|
|
37
|
-
import { logTelemetry, isSupabaseConfigured } from './supabase.js';
|
|
38
|
-
import { queryEntities, getEntity, getDependencies, getDataFlow, findByConstraint, getBlastRadius, listModules, getTopology, } from './tools/index.js';
|
|
39
|
-
import { findDeadCode, findLayerViolations, getCouplingMetrics, getAuthMatrix, findErrorGaps, getTestCoverage, getOptimalContext, estimateTaskCost, reportActualBurn, find_runtime_violations, find_ownership_violations, query_traits, simulate_mutation, query_data_targets, find_exposure_leaks, find_semantic_clones, create_symbol, } from './tools/functors.js';
|
|
40
|
-
import { diffBundle, conflictMatrix, } from './tools/diff.js';
|
|
41
|
-
// ─── Project Discovery ───────────────────────────────────────────
|
|
42
|
-
/**
|
|
43
|
-
* Discover project directories from SESHAT_PROJECTS env var.
|
|
44
|
-
*
|
|
45
|
-
* - Not set → [process.cwd()] (backward compat)
|
|
46
|
-
* - Comma-separated paths → resolve each
|
|
47
|
-
* - Glob pattern (contains *) → scan parent dir for subdirs with .seshat/_bundle.json
|
|
48
|
-
*/
|
|
49
|
-
function discoverProjects() {
|
|
50
|
-
const env = process.env.SESHAT_PROJECTS;
|
|
51
|
-
if (!env)
|
|
52
|
-
return [process.cwd()];
|
|
53
|
-
const trimmed = env.trim();
|
|
54
|
-
// Glob pattern: /path/to/projects/*
|
|
55
|
-
if (trimmed.includes('*')) {
|
|
56
|
-
const globDir = trimmed.replace(/\/?\*$/, '');
|
|
57
|
-
const resolved = path.resolve(globDir);
|
|
58
|
-
if (!fs.existsSync(resolved)) {
|
|
59
|
-
process.stderr.write(`SESHAT_PROJECTS glob dir not found: ${resolved}\n`);
|
|
60
|
-
return [process.cwd()];
|
|
61
|
-
}
|
|
62
|
-
const dirs = [];
|
|
63
|
-
for (const entry of fs.readdirSync(resolved, { withFileTypes: true })) {
|
|
64
|
-
if (!entry.isDirectory())
|
|
65
|
-
continue;
|
|
66
|
-
const candidate = path.join(resolved, entry.name);
|
|
67
|
-
const bundlePath = path.join(candidate, '.seshat', '_bundle.json');
|
|
68
|
-
if (fs.existsSync(bundlePath)) {
|
|
69
|
-
dirs.push(candidate);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (dirs.length === 0) {
|
|
73
|
-
process.stderr.write(`SESHAT_PROJECTS: no dirs with .seshat/_bundle.json found in ${resolved}\n`);
|
|
74
|
-
return [process.cwd()];
|
|
75
|
-
}
|
|
76
|
-
return dirs;
|
|
77
|
-
}
|
|
78
|
-
// Comma-separated paths
|
|
79
|
-
return trimmed.split(',').map(p => path.resolve(p.trim())).filter(p => p.length > 0);
|
|
80
|
-
}
|
|
81
|
-
// ─── Project param definition (injected into all tool schemas) ───
|
|
14
|
+
// ─── Project param definition ───
|
|
82
15
|
const projectParam = {
|
|
83
16
|
type: 'string',
|
|
84
17
|
description: 'Project name (required in multi-project mode). Use list_projects to see available projects.',
|
|
@@ -88,10 +21,7 @@ const TOOLS = [
|
|
|
88
21
|
{
|
|
89
22
|
name: 'list_projects',
|
|
90
23
|
description: 'List all loaded projects with entity counts, languages, and metadata. Call this first to see what projects are available, then pass the project name to other tools.',
|
|
91
|
-
inputSchema: {
|
|
92
|
-
type: 'object',
|
|
93
|
-
properties: {},
|
|
94
|
-
},
|
|
24
|
+
inputSchema: { type: 'object', properties: {} },
|
|
95
25
|
},
|
|
96
26
|
{
|
|
97
27
|
name: 'query_entities',
|
|
@@ -100,26 +30,11 @@ const TOOLS = [
|
|
|
100
30
|
type: 'object',
|
|
101
31
|
properties: {
|
|
102
32
|
project: projectParam,
|
|
103
|
-
query: {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
type: 'string',
|
|
109
|
-
description: 'Filter by architectural layer: route, controller, service, repository, utility, hook, component, schema',
|
|
110
|
-
},
|
|
111
|
-
module: {
|
|
112
|
-
type: 'string',
|
|
113
|
-
description: 'Filter by module (partial match)',
|
|
114
|
-
},
|
|
115
|
-
language: {
|
|
116
|
-
type: 'string',
|
|
117
|
-
description: 'Filter by source language: javascript, typescript, python, go, rust, etc.',
|
|
118
|
-
},
|
|
119
|
-
limit: {
|
|
120
|
-
type: 'number',
|
|
121
|
-
description: 'Max results to return (default: 50)',
|
|
122
|
-
},
|
|
33
|
+
query: { type: 'string', description: 'Search term — matches against entity name, ID, source file, and module' },
|
|
34
|
+
layer: { type: 'string', description: 'Filter by architectural layer: route, controller, service, repository, utility, hook, component, schema' },
|
|
35
|
+
module: { type: 'string', description: 'Filter by module (partial match)' },
|
|
36
|
+
language: { type: 'string', description: 'Filter by source language: javascript, typescript, python, go, rust, etc.' },
|
|
37
|
+
limit: { type: 'number', description: 'Max results to return (default: 50)' },
|
|
123
38
|
},
|
|
124
39
|
},
|
|
125
40
|
},
|
|
@@ -130,10 +45,7 @@ const TOOLS = [
|
|
|
130
45
|
type: 'object',
|
|
131
46
|
properties: {
|
|
132
47
|
project: projectParam,
|
|
133
|
-
id: {
|
|
134
|
-
type: 'string',
|
|
135
|
-
description: 'Entity ID or name',
|
|
136
|
-
},
|
|
48
|
+
id: { type: 'string', description: 'Entity ID or name' },
|
|
137
49
|
},
|
|
138
50
|
required: ['id'],
|
|
139
51
|
},
|
|
@@ -145,19 +57,9 @@ const TOOLS = [
|
|
|
145
57
|
type: 'object',
|
|
146
58
|
properties: {
|
|
147
59
|
project: projectParam,
|
|
148
|
-
entity_id: {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
},
|
|
152
|
-
direction: {
|
|
153
|
-
type: 'string',
|
|
154
|
-
enum: ['callers', 'callees', 'both'],
|
|
155
|
-
description: 'Which direction to traverse (default: both)',
|
|
156
|
-
},
|
|
157
|
-
depth: {
|
|
158
|
-
type: 'number',
|
|
159
|
-
description: 'How many levels deep to traverse (default: 2)',
|
|
160
|
-
},
|
|
60
|
+
entity_id: { type: 'string', description: 'Entity ID or name' },
|
|
61
|
+
direction: { type: 'string', enum: ['callers', 'callees', 'both'], description: 'Which direction to traverse (default: both)' },
|
|
62
|
+
depth: { type: 'number', description: 'How many levels deep to traverse (default: 2)' },
|
|
161
63
|
},
|
|
162
64
|
required: ['entity_id'],
|
|
163
65
|
},
|
|
@@ -169,10 +71,7 @@ const TOOLS = [
|
|
|
169
71
|
type: 'object',
|
|
170
72
|
properties: {
|
|
171
73
|
project: projectParam,
|
|
172
|
-
entity_id: {
|
|
173
|
-
type: 'string',
|
|
174
|
-
description: 'Entity ID or name',
|
|
175
|
-
},
|
|
74
|
+
entity_id: { type: 'string', description: 'Entity ID or name' },
|
|
176
75
|
},
|
|
177
76
|
required: ['entity_id'],
|
|
178
77
|
},
|
|
@@ -184,10 +83,7 @@ const TOOLS = [
|
|
|
184
83
|
type: 'object',
|
|
185
84
|
properties: {
|
|
186
85
|
project: projectParam,
|
|
187
|
-
constraint: {
|
|
188
|
-
type: 'string',
|
|
189
|
-
description: 'Constraint tag to search for: AUTH, VALIDATED, PURE, THROWS, DB_ACCESS, NETWORK_IO, IMP, etc.',
|
|
190
|
-
},
|
|
86
|
+
constraint: { type: 'string', description: 'Constraint tag to search for: AUTH, VALIDATED, PURE, THROWS, DB_ACCESS, NETWORK_IO, IMP, etc.' },
|
|
191
87
|
},
|
|
192
88
|
required: ['constraint'],
|
|
193
89
|
},
|
|
@@ -199,11 +95,7 @@ const TOOLS = [
|
|
|
199
95
|
type: 'object',
|
|
200
96
|
properties: {
|
|
201
97
|
project: projectParam,
|
|
202
|
-
entity_ids: {
|
|
203
|
-
type: 'array',
|
|
204
|
-
items: { type: 'string' },
|
|
205
|
-
description: 'Array of entity IDs or names to compute blast radius for',
|
|
206
|
-
},
|
|
98
|
+
entity_ids: { type: 'array', items: { type: 'string' }, description: 'Array of entity IDs or names to compute blast radius for' },
|
|
207
99
|
},
|
|
208
100
|
required: ['entity_ids'],
|
|
209
101
|
},
|
|
@@ -215,11 +107,7 @@ const TOOLS = [
|
|
|
215
107
|
type: 'object',
|
|
216
108
|
properties: {
|
|
217
109
|
project: projectParam,
|
|
218
|
-
group_by: {
|
|
219
|
-
type: 'string',
|
|
220
|
-
enum: ['layer', 'module', 'file', 'language'],
|
|
221
|
-
description: 'How to group entities (default: layer)',
|
|
222
|
-
},
|
|
110
|
+
group_by: { type: 'string', enum: ['layer', 'module', 'file', 'language'], description: 'How to group entities (default: layer)' },
|
|
223
111
|
},
|
|
224
112
|
},
|
|
225
113
|
},
|
|
@@ -228,9 +116,7 @@ const TOOLS = [
|
|
|
228
116
|
description: 'Get the API topology: routes, plugins, auth patterns, and database tables. Built from architectural context and dependency analysis across all entities.',
|
|
229
117
|
inputSchema: {
|
|
230
118
|
type: 'object',
|
|
231
|
-
properties: {
|
|
232
|
-
project: projectParam,
|
|
233
|
-
},
|
|
119
|
+
properties: { project: projectParam },
|
|
234
120
|
},
|
|
235
121
|
},
|
|
236
122
|
// ─── Analysis Tools ─────────────────────────────────────────────
|
|
@@ -241,21 +127,16 @@ const TOOLS = [
|
|
|
241
127
|
type: 'object',
|
|
242
128
|
properties: {
|
|
243
129
|
project: projectParam,
|
|
244
|
-
include_tests: {
|
|
245
|
-
type: 'boolean',
|
|
246
|
-
description: 'Include test entities in dead code results (default: false)',
|
|
247
|
-
},
|
|
130
|
+
include_tests: { type: 'boolean', description: 'Include test entities in dead code results (default: false)' },
|
|
248
131
|
},
|
|
249
132
|
},
|
|
250
133
|
},
|
|
251
134
|
{
|
|
252
135
|
name: 'find_layer_violations',
|
|
253
|
-
description: 'Detect architectural layer violations in the call graph. Finds backward calls (lower layer calling higher layer, e.g. repository → route) and skip-layer calls (jumping over multiple layers).
|
|
136
|
+
description: 'Detect architectural layer violations in the call graph. Finds backward calls (lower layer calling higher layer, e.g. repository → route) and skip-layer calls (jumping over multiple layers).',
|
|
254
137
|
inputSchema: {
|
|
255
138
|
type: 'object',
|
|
256
|
-
properties: {
|
|
257
|
-
project: projectParam,
|
|
258
|
-
},
|
|
139
|
+
properties: { project: projectParam },
|
|
259
140
|
},
|
|
260
141
|
},
|
|
261
142
|
{
|
|
@@ -265,11 +146,7 @@ const TOOLS = [
|
|
|
265
146
|
type: 'object',
|
|
266
147
|
properties: {
|
|
267
148
|
project: projectParam,
|
|
268
|
-
group_by: {
|
|
269
|
-
type: 'string',
|
|
270
|
-
enum: ['module', 'layer'],
|
|
271
|
-
description: 'Group entities by module or layer (default: module)',
|
|
272
|
-
},
|
|
149
|
+
group_by: { type: 'string', enum: ['module', 'layer'], description: 'Group entities by module or layer (default: module)' },
|
|
273
150
|
},
|
|
274
151
|
},
|
|
275
152
|
},
|
|
@@ -278,9 +155,7 @@ const TOOLS = [
|
|
|
278
155
|
description: 'Analyze authentication coverage across all API-facing entities. Shows which routes/controllers have auth requirements and which don\'t. Detects inconsistencies like DB access without auth.',
|
|
279
156
|
inputSchema: {
|
|
280
157
|
type: 'object',
|
|
281
|
-
properties: {
|
|
282
|
-
project: projectParam,
|
|
283
|
-
},
|
|
158
|
+
properties: { project: projectParam },
|
|
284
159
|
},
|
|
285
160
|
},
|
|
286
161
|
{
|
|
@@ -288,9 +163,7 @@ const TOOLS = [
|
|
|
288
163
|
description: 'Find error handling gaps: entities that throw or have network/db side effects whose callers lack try/catch. These are crash risk points where exceptions can propagate unhandled.',
|
|
289
164
|
inputSchema: {
|
|
290
165
|
type: 'object',
|
|
291
|
-
properties: {
|
|
292
|
-
project: projectParam,
|
|
293
|
-
},
|
|
166
|
+
properties: { project: projectParam },
|
|
294
167
|
},
|
|
295
168
|
},
|
|
296
169
|
{
|
|
@@ -300,10 +173,7 @@ const TOOLS = [
|
|
|
300
173
|
type: 'object',
|
|
301
174
|
properties: {
|
|
302
175
|
project: projectParam,
|
|
303
|
-
weight_by_blast_radius: {
|
|
304
|
-
type: 'boolean',
|
|
305
|
-
description: 'Rank uncovered entities by blast radius to prioritize testing (default: false, slower)',
|
|
306
|
-
},
|
|
176
|
+
weight_by_blast_radius: { type: 'boolean', description: 'Rank uncovered entities by blast radius to prioritize testing (default: false, slower)' },
|
|
307
177
|
},
|
|
308
178
|
},
|
|
309
179
|
},
|
|
@@ -314,19 +184,9 @@ const TOOLS = [
|
|
|
314
184
|
type: 'object',
|
|
315
185
|
properties: {
|
|
316
186
|
project: projectParam,
|
|
317
|
-
target_entity: {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
},
|
|
321
|
-
max_tokens: {
|
|
322
|
-
type: 'number',
|
|
323
|
-
description: 'Token budget for the context window (default: 8000)',
|
|
324
|
-
},
|
|
325
|
-
strategy: {
|
|
326
|
-
type: 'string',
|
|
327
|
-
enum: ['bfs', 'blast_radius'],
|
|
328
|
-
description: 'Traversal strategy: bfs (faster, local neighborhood) or blast_radius (full affected set)',
|
|
329
|
-
},
|
|
187
|
+
target_entity: { type: 'string', description: 'Entity ID or name to build context around' },
|
|
188
|
+
max_tokens: { type: 'number', description: 'Token budget for the context window (default: 8000)' },
|
|
189
|
+
strategy: { type: 'string', enum: ['bfs', 'blast_radius'], description: 'Traversal strategy: bfs (faster, local neighborhood) or blast_radius (full affected set)' },
|
|
330
190
|
},
|
|
331
191
|
required: ['target_entity'],
|
|
332
192
|
},
|
|
@@ -338,78 +198,39 @@ const TOOLS = [
|
|
|
338
198
|
type: 'object',
|
|
339
199
|
properties: {
|
|
340
200
|
project: projectParam,
|
|
341
|
-
target_entities: {
|
|
342
|
-
|
|
343
|
-
items: { type: 'string' },
|
|
344
|
-
description: 'Entity IDs or names that will be modified',
|
|
345
|
-
},
|
|
346
|
-
context_budget: {
|
|
347
|
-
type: 'number',
|
|
348
|
-
description: 'LLM context window token budget (default: 200000)',
|
|
349
|
-
},
|
|
201
|
+
target_entities: { type: 'array', items: { type: 'string' }, description: 'Entity IDs or names that will be modified' },
|
|
202
|
+
context_budget: { type: 'number', description: 'LLM context window token budget (default: 200000)' },
|
|
350
203
|
},
|
|
351
204
|
required: ['target_entities'],
|
|
352
205
|
},
|
|
353
206
|
},
|
|
354
207
|
{
|
|
355
208
|
name: 'report_actual_burn',
|
|
356
|
-
description: 'Close the calibration feedback loop: report actual token usage against a prior prediction from estimate_task_cost.
|
|
209
|
+
description: 'Close the calibration feedback loop: report actual token usage against a prior prediction from estimate_task_cost.',
|
|
357
210
|
inputSchema: {
|
|
358
211
|
type: 'object',
|
|
359
212
|
properties: {
|
|
360
|
-
prediction_id: {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
},
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
description: 'Actual input tokens consumed (from LLM usage metadata).',
|
|
367
|
-
},
|
|
368
|
-
actual_output_tokens: {
|
|
369
|
-
type: 'number',
|
|
370
|
-
description: 'Actual output tokens consumed (from LLM usage metadata).',
|
|
371
|
-
},
|
|
372
|
-
actual_total_tokens: {
|
|
373
|
-
type: 'number',
|
|
374
|
-
description: 'Actual total tokens consumed (input + output).',
|
|
375
|
-
},
|
|
376
|
-
model: {
|
|
377
|
-
type: 'string',
|
|
378
|
-
description: 'Model used (e.g. claude-opus-4-6, claude-sonnet-4-6).',
|
|
379
|
-
},
|
|
380
|
-
action: {
|
|
381
|
-
type: 'string',
|
|
382
|
-
enum: ['complete', 'abandon', 'list'],
|
|
383
|
-
description: 'Action: "complete" reports actuals (default), "abandon" marks prediction as cancelled, "list" shows recent predictions with calibration stats.',
|
|
384
|
-
},
|
|
213
|
+
prediction_id: { type: 'string', description: 'The prediction ID returned by estimate_task_cost. Required for complete/abandon actions.' },
|
|
214
|
+
actual_input_tokens: { type: 'number', description: 'Actual input tokens consumed (from LLM usage metadata).' },
|
|
215
|
+
actual_output_tokens: { type: 'number', description: 'Actual output tokens consumed (from LLM usage metadata).' },
|
|
216
|
+
actual_total_tokens: { type: 'number', description: 'Actual total tokens consumed (input + output).' },
|
|
217
|
+
model: { type: 'string', description: 'Model used (e.g. claude-opus-4-6, claude-sonnet-4-6).' },
|
|
218
|
+
action: { type: 'string', enum: ['complete', 'abandon', 'list'], description: 'Action: "complete" reports actuals (default), "abandon" marks prediction as cancelled, "list" shows recent predictions with calibration stats.' },
|
|
385
219
|
project: projectParam,
|
|
386
|
-
notes: {
|
|
387
|
-
type: 'string',
|
|
388
|
-
description: 'Optional notes about the task outcome.',
|
|
389
|
-
},
|
|
220
|
+
notes: { type: 'string', description: 'Optional notes about the task outcome.' },
|
|
390
221
|
},
|
|
391
222
|
},
|
|
392
223
|
},
|
|
393
224
|
// ─── Analysis & Impact Tools ───────────────────────────────────
|
|
394
225
|
{
|
|
395
226
|
name: 'find_runtime_violations',
|
|
396
|
-
description: 'Analyze the call graph for runtime environment leaks. Finds architectural boundary issues where framework-agnostic code improperly imports framework-specific code
|
|
397
|
-
inputSchema: {
|
|
398
|
-
type: 'object',
|
|
399
|
-
properties: {
|
|
400
|
-
project: projectParam,
|
|
401
|
-
},
|
|
402
|
-
},
|
|
227
|
+
description: 'Analyze the call graph for runtime environment leaks. Finds architectural boundary issues where framework-agnostic code improperly imports framework-specific code.',
|
|
228
|
+
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
403
229
|
},
|
|
404
230
|
{
|
|
405
231
|
name: 'find_ownership_violations',
|
|
406
232
|
description: 'Analyze the codebase for memory and lifecycle constraints. Flags entities with complex ownership rules, unsafe blocks, escaping boundaries, or illegal mutability patterns on borrowed references.',
|
|
407
|
-
inputSchema: {
|
|
408
|
-
type: 'object',
|
|
409
|
-
properties: {
|
|
410
|
-
project: projectParam,
|
|
411
|
-
},
|
|
412
|
-
},
|
|
233
|
+
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
413
234
|
},
|
|
414
235
|
{
|
|
415
236
|
name: 'query_traits',
|
|
@@ -418,25 +239,19 @@ const TOOLS = [
|
|
|
418
239
|
type: 'object',
|
|
419
240
|
properties: {
|
|
420
241
|
project: projectParam,
|
|
421
|
-
trait: {
|
|
422
|
-
type: 'string',
|
|
423
|
-
description: 'The trait or capability to search for (e.g., "fallible", "asyncContext")',
|
|
424
|
-
},
|
|
242
|
+
trait: { type: 'string', description: 'The trait or capability to search for (e.g., "fallible", "asyncContext")' },
|
|
425
243
|
},
|
|
426
244
|
required: ['trait'],
|
|
427
245
|
},
|
|
428
246
|
},
|
|
429
247
|
{
|
|
430
248
|
name: 'simulate_mutation',
|
|
431
|
-
description: 'The Impact Simulator. Proposes a hypothetical change to an entity
|
|
249
|
+
description: 'The Impact Simulator. Proposes a hypothetical change to an entity and simulates the architectural fallout upstream and downstream. Returns a blueprint of exactly which other entities will break and what fixes they require.',
|
|
432
250
|
inputSchema: {
|
|
433
251
|
type: 'object',
|
|
434
252
|
properties: {
|
|
435
253
|
project: projectParam,
|
|
436
|
-
entity_id: {
|
|
437
|
-
type: 'string',
|
|
438
|
-
description: 'The target entity to analyze.',
|
|
439
|
-
},
|
|
254
|
+
entity_id: { type: 'string', description: 'The target entity to analyze.' },
|
|
440
255
|
mutation: {
|
|
441
256
|
type: 'object',
|
|
442
257
|
description: 'The hypothetical change to apply.',
|
|
@@ -458,28 +273,20 @@ const TOOLS = [
|
|
|
458
273
|
},
|
|
459
274
|
{
|
|
460
275
|
name: 'query_data_targets',
|
|
461
|
-
description: 'Search the codebase for data interactions to find all entities that read or write to a specific database table, state object, or data source.
|
|
276
|
+
description: 'Search the codebase for data interactions to find all entities that read or write to a specific database table, state object, or data source.',
|
|
462
277
|
inputSchema: {
|
|
463
278
|
type: 'object',
|
|
464
279
|
properties: {
|
|
465
280
|
project: projectParam,
|
|
466
|
-
target_name: {
|
|
467
|
-
type: 'string',
|
|
468
|
-
description: 'The name of the database table, state object, or data source to query (e.g., "users", "auth_token").',
|
|
469
|
-
},
|
|
281
|
+
target_name: { type: 'string', description: 'The name of the database table, state object, or data source to query (e.g., "users", "auth_token").' },
|
|
470
282
|
},
|
|
471
283
|
required: ['target_name'],
|
|
472
284
|
},
|
|
473
285
|
},
|
|
474
286
|
{
|
|
475
287
|
name: 'find_exposure_leaks',
|
|
476
|
-
description: 'Analyze the call graph for architectural visibility leaks. Flags paths where a "public" or "api" entity directly accesses a "private" internal entity
|
|
477
|
-
inputSchema: {
|
|
478
|
-
type: 'object',
|
|
479
|
-
properties: {
|
|
480
|
-
project: projectParam,
|
|
481
|
-
},
|
|
482
|
-
},
|
|
288
|
+
description: 'Analyze the call graph for architectural visibility leaks. Flags paths where a "public" or "api" entity directly accesses a "private" internal entity.',
|
|
289
|
+
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
483
290
|
},
|
|
484
291
|
{
|
|
485
292
|
name: 'find_semantic_clones',
|
|
@@ -488,36 +295,21 @@ const TOOLS = [
|
|
|
488
295
|
type: 'object',
|
|
489
296
|
properties: {
|
|
490
297
|
project: projectParam,
|
|
491
|
-
min_complexity: {
|
|
492
|
-
type: 'number',
|
|
493
|
-
description: 'Minimum number of logic expressions required to constitute a match (default: 5).',
|
|
494
|
-
},
|
|
298
|
+
min_complexity: { type: 'number', description: 'Minimum number of logic expressions required to constitute a match (default: 5).' },
|
|
495
299
|
},
|
|
496
300
|
},
|
|
497
301
|
},
|
|
498
302
|
{
|
|
499
303
|
name: 'create_symbol',
|
|
500
|
-
description: 'Register a new code symbol in the architectural graph. This does not write to disk, but allows the Impact Simulator and Conflict Matrix to reason about a symbol that is pending creation.
|
|
304
|
+
description: 'Register a new code symbol in the architectural graph. This does not write to disk, but allows the Impact Simulator and Conflict Matrix to reason about a symbol that is pending creation.',
|
|
501
305
|
inputSchema: {
|
|
502
306
|
type: 'object',
|
|
503
307
|
properties: {
|
|
504
308
|
project: projectParam,
|
|
505
|
-
id: {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
},
|
|
509
|
-
source_file: {
|
|
510
|
-
type: 'string',
|
|
511
|
-
description: 'The relative path to the file where this symbol will be created.',
|
|
512
|
-
},
|
|
513
|
-
layer: {
|
|
514
|
-
type: 'string',
|
|
515
|
-
description: 'The architectural layer (e.g., "service", "route", "component").',
|
|
516
|
-
},
|
|
517
|
-
description: {
|
|
518
|
-
type: 'string',
|
|
519
|
-
description: 'Brief description of the symbol\'s purpose.',
|
|
520
|
-
},
|
|
309
|
+
id: { type: 'string', description: 'The unique ID or name for the new symbol.' },
|
|
310
|
+
source_file: { type: 'string', description: 'The relative path to the file where this symbol will be created.' },
|
|
311
|
+
layer: { type: 'string', description: 'The architectural layer (e.g., "service", "route", "component").' },
|
|
312
|
+
description: { type: 'string', description: 'Brief description of the symbol\'s purpose.' },
|
|
521
313
|
},
|
|
522
314
|
required: ['id', 'source_file'],
|
|
523
315
|
},
|
|
@@ -530,14 +322,8 @@ const TOOLS = [
|
|
|
530
322
|
type: 'object',
|
|
531
323
|
properties: {
|
|
532
324
|
project: projectParam,
|
|
533
|
-
worktree_path: {
|
|
534
|
-
|
|
535
|
-
description: 'Absolute path to the worktree or branch checkout to compare against the loaded project',
|
|
536
|
-
},
|
|
537
|
-
include_unchanged: {
|
|
538
|
-
type: 'boolean',
|
|
539
|
-
description: 'Include unchanged entities in the output (default: false)',
|
|
540
|
-
},
|
|
325
|
+
worktree_path: { type: 'string', description: 'Absolute path to the worktree or branch checkout to compare against the loaded project' },
|
|
326
|
+
include_unchanged: { type: 'boolean', description: 'Include unchanged entities in the output (default: false)' },
|
|
541
327
|
},
|
|
542
328
|
required: ['worktree_path'],
|
|
543
329
|
},
|
|
@@ -554,24 +340,10 @@ const TOOLS = [
|
|
|
554
340
|
items: {
|
|
555
341
|
type: 'object',
|
|
556
342
|
properties: {
|
|
557
|
-
id: {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
},
|
|
561
|
-
entity_ids: {
|
|
562
|
-
type: 'array',
|
|
563
|
-
items: { type: 'string' },
|
|
564
|
-
description: 'Symbol names or IDs that this task will modify',
|
|
565
|
-
},
|
|
566
|
-
dimensions: {
|
|
567
|
-
type: 'array',
|
|
568
|
-
items: { type: 'string' },
|
|
569
|
-
description: 'Optional: Code scopes this task will modify. (Legacy support, no longer required for Tier 2 safety).',
|
|
570
|
-
},
|
|
571
|
-
expand_blast_radius: {
|
|
572
|
-
type: 'boolean',
|
|
573
|
-
description: 'Include transitively affected symbols in the conflict check (default: false)',
|
|
574
|
-
},
|
|
343
|
+
id: { type: 'string', description: 'Unique task identifier (e.g. "add-dark-mode")' },
|
|
344
|
+
entity_ids: { type: 'array', items: { type: 'string' }, description: 'Symbol names or IDs that this task will modify' },
|
|
345
|
+
dimensions: { type: 'array', items: { type: 'string' }, description: 'Optional: Code scopes this task will modify.' },
|
|
346
|
+
expand_blast_radius: { type: 'boolean', description: 'Include transitively affected symbols in the conflict check (default: false)' },
|
|
575
347
|
},
|
|
576
348
|
required: ['id', 'entity_ids'],
|
|
577
349
|
},
|
|
@@ -582,229 +354,87 @@ const TOOLS = [
|
|
|
582
354
|
},
|
|
583
355
|
},
|
|
584
356
|
];
|
|
585
|
-
// ───
|
|
586
|
-
|
|
587
|
-
//
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
try {
|
|
591
|
-
loader.load();
|
|
592
|
-
}
|
|
593
|
-
catch (err) {
|
|
594
|
-
process.stderr.write(`Warning: ${err.message}\n`);
|
|
357
|
+
// ─── Project Resolution (Fallback) ────────────────────────────────
|
|
358
|
+
function resolveProjectName() {
|
|
359
|
+
// If SESHAT_PROJECTS is set to a single name, use it
|
|
360
|
+
if (process.env.SESHAT_PROJECTS && !process.env.SESHAT_PROJECTS.includes(',') && !process.env.SESHAT_PROJECTS.includes('*')) {
|
|
361
|
+
return path.basename(process.env.SESHAT_PROJECTS);
|
|
595
362
|
}
|
|
596
|
-
//
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
const result = await bootstrap(cwd);
|
|
604
|
-
if (result.success) {
|
|
605
|
-
// Re-create loader and retry
|
|
606
|
-
loader = new MultiLoader([cwd]);
|
|
607
|
-
try {
|
|
608
|
-
loader.load();
|
|
609
|
-
process.stderr.write(`[seshat-mcp] Auto-bootstrap succeeded: ${loader.totalEntities()} entities loaded\n`);
|
|
610
|
-
}
|
|
611
|
-
catch (err) {
|
|
612
|
-
process.stderr.write(`[seshat-mcp] Auto-bootstrap produced files but load failed: ${err.message}\n`);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
else {
|
|
616
|
-
process.stderr.write(`[seshat-mcp] Auto-bootstrap failed: ${result.error || 'unknown error'}\n`);
|
|
617
|
-
process.stderr.write(`[seshat-mcp] Starting with 0 entities. Run extraction manually or push to trigger CI.\n`);
|
|
618
|
-
}
|
|
363
|
+
// Fallback to reading local manifest if it exists
|
|
364
|
+
const manifestPath = path.join(process.cwd(), '.seshat', 'manifest.json');
|
|
365
|
+
if (fs.existsSync(manifestPath)) {
|
|
366
|
+
try {
|
|
367
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
368
|
+
if (manifest.projectName)
|
|
369
|
+
return manifest.projectName;
|
|
619
370
|
}
|
|
371
|
+
catch { }
|
|
620
372
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
let serverLabel;
|
|
627
|
-
if (!loader.isLoaded()) {
|
|
628
|
-
serverLabel = 'seshat-mcp (no projects loaded)';
|
|
629
|
-
}
|
|
630
|
-
else if (isMulti) {
|
|
631
|
-
serverLabel = `seshat-mcp (${projectNames.length} projects, ${totalEntities} entities)`;
|
|
632
|
-
}
|
|
633
|
-
else {
|
|
634
|
-
const manifest = loader.getManifest();
|
|
635
|
-
serverLabel = `seshat-mcp (${manifest?.projectName || projectNames[0] || 'unknown'})`;
|
|
636
|
-
}
|
|
373
|
+
// Ultimate fallback to directory name
|
|
374
|
+
return path.basename(process.cwd());
|
|
375
|
+
}
|
|
376
|
+
// ─── Server Setup ─────────────────────────────────────────────────
|
|
377
|
+
async function main() {
|
|
637
378
|
const server = new Server({
|
|
638
|
-
name:
|
|
639
|
-
version: '0.
|
|
379
|
+
name: 'seshat-mcp-cloud-proxy',
|
|
380
|
+
version: '1.0.0',
|
|
640
381
|
}, {
|
|
641
|
-
capabilities: {
|
|
642
|
-
tools: {},
|
|
643
|
-
},
|
|
382
|
+
capabilities: { tools: {} },
|
|
644
383
|
});
|
|
645
|
-
// List available tools
|
|
646
384
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
647
385
|
tools: TOOLS,
|
|
648
386
|
}));
|
|
649
|
-
// Handle tool calls
|
|
650
387
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
651
388
|
const { name, arguments: args } = request.params;
|
|
652
|
-
|
|
389
|
+
// We expect the user to provide an API key for the cloud service
|
|
390
|
+
const apiKey = process.env.SESHAT_API_KEY;
|
|
391
|
+
if (!apiKey) {
|
|
392
|
+
return {
|
|
393
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'SESHAT_API_KEY environment variable is required to use Ptah Cloud tools.' }, null, 2) }],
|
|
394
|
+
isError: true,
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
// Determine the project hash for this workspace
|
|
398
|
+
const project_hash = (args && typeof args === 'object' && 'project' in args)
|
|
399
|
+
? String(args.project)
|
|
400
|
+
: resolveProjectName();
|
|
401
|
+
const PTAH_CLOUD_URL = process.env.PTAH_CLOUD_URL || 'https://api.papyruslabs.ai/api/mcp/execute';
|
|
653
402
|
try {
|
|
654
|
-
|
|
403
|
+
// Blindly proxy the tool call to the cloud
|
|
404
|
+
const res = await fetch(PTAH_CLOUD_URL, {
|
|
405
|
+
method: 'POST',
|
|
406
|
+
headers: {
|
|
407
|
+
'Content-Type': 'application/json',
|
|
408
|
+
'x-api-key': apiKey
|
|
409
|
+
},
|
|
410
|
+
body: JSON.stringify({
|
|
411
|
+
tool: name,
|
|
412
|
+
project_hash,
|
|
413
|
+
args
|
|
414
|
+
})
|
|
415
|
+
});
|
|
416
|
+
if (!res.ok) {
|
|
417
|
+
const errorText = await res.text();
|
|
655
418
|
return {
|
|
656
|
-
content: [{
|
|
657
|
-
|
|
658
|
-
text: JSON.stringify({
|
|
659
|
-
error: 'No projects loaded. Ensure .seshat/_bundle.json exists or set SESHAT_PROJECTS env var.',
|
|
660
|
-
}, null, 2),
|
|
661
|
-
}],
|
|
419
|
+
content: [{ type: 'text', text: JSON.stringify({ error: `Cloud API Error (${res.status}): ${errorText}` }, null, 2) }],
|
|
420
|
+
isError: true
|
|
662
421
|
};
|
|
663
422
|
}
|
|
664
|
-
|
|
665
|
-
switch (name) { // Meta
|
|
666
|
-
case 'list_projects':
|
|
667
|
-
result = {
|
|
668
|
-
multiProject: isMulti,
|
|
669
|
-
projects: loader.getProjectInfo(),
|
|
670
|
-
totalEntities,
|
|
671
|
-
hint: isMulti
|
|
672
|
-
? 'Pass the project name as the "project" parameter to all other tools.'
|
|
673
|
-
: 'Single project mode — the "project" parameter is optional.',
|
|
674
|
-
};
|
|
675
|
-
break;
|
|
676
|
-
// Core tools
|
|
677
|
-
case 'query_entities':
|
|
678
|
-
result = queryEntities(args);
|
|
679
|
-
break;
|
|
680
|
-
case 'get_entity':
|
|
681
|
-
result = getEntity(args);
|
|
682
|
-
break;
|
|
683
|
-
case 'get_dependencies':
|
|
684
|
-
result = getDependencies(args);
|
|
685
|
-
break;
|
|
686
|
-
case 'get_data_flow':
|
|
687
|
-
result = getDataFlow(args);
|
|
688
|
-
break;
|
|
689
|
-
case 'find_by_constraint':
|
|
690
|
-
result = findByConstraint(args);
|
|
691
|
-
break;
|
|
692
|
-
case 'get_blast_radius':
|
|
693
|
-
result = getBlastRadius(args);
|
|
694
|
-
break;
|
|
695
|
-
case 'list_modules':
|
|
696
|
-
result = listModules(args);
|
|
697
|
-
break;
|
|
698
|
-
case 'get_topology':
|
|
699
|
-
result = getTopology(args);
|
|
700
|
-
break;
|
|
701
|
-
// Analysis Tools
|
|
702
|
-
case 'find_dead_code':
|
|
703
|
-
result = findDeadCode(args);
|
|
704
|
-
break;
|
|
705
|
-
case 'find_layer_violations':
|
|
706
|
-
result = findLayerViolations(args);
|
|
707
|
-
break;
|
|
708
|
-
case 'get_coupling_metrics':
|
|
709
|
-
result = getCouplingMetrics(args);
|
|
710
|
-
break;
|
|
711
|
-
case 'get_auth_matrix':
|
|
712
|
-
result = getAuthMatrix(args);
|
|
713
|
-
break;
|
|
714
|
-
case 'find_error_gaps':
|
|
715
|
-
result = findErrorGaps(args);
|
|
716
|
-
break;
|
|
717
|
-
case 'get_test_coverage':
|
|
718
|
-
result = getTestCoverage(args);
|
|
719
|
-
break;
|
|
720
|
-
case 'get_optimal_context':
|
|
721
|
-
result = getOptimalContext(args);
|
|
722
|
-
break;
|
|
723
|
-
case 'estimate_task_cost':
|
|
724
|
-
result = await estimateTaskCost(args);
|
|
725
|
-
break;
|
|
726
|
-
case 'report_actual_burn':
|
|
727
|
-
result = await reportActualBurn(args);
|
|
728
|
-
break;
|
|
729
|
-
// Analysis & Impact Tools
|
|
730
|
-
case 'find_runtime_violations':
|
|
731
|
-
result = find_runtime_violations(args);
|
|
732
|
-
break;
|
|
733
|
-
case 'find_ownership_violations':
|
|
734
|
-
result = find_ownership_violations(args);
|
|
735
|
-
break;
|
|
736
|
-
case 'query_traits':
|
|
737
|
-
result = query_traits(args);
|
|
738
|
-
break;
|
|
739
|
-
case 'simulate_mutation':
|
|
740
|
-
result = simulate_mutation(args);
|
|
741
|
-
break;
|
|
742
|
-
case 'query_data_targets':
|
|
743
|
-
result = query_data_targets(args);
|
|
744
|
-
break;
|
|
745
|
-
case 'find_exposure_leaks':
|
|
746
|
-
result = find_exposure_leaks(args);
|
|
747
|
-
break;
|
|
748
|
-
case 'find_semantic_clones':
|
|
749
|
-
result = find_semantic_clones(args);
|
|
750
|
-
break;
|
|
751
|
-
case 'create_symbol':
|
|
752
|
-
result = create_symbol(args);
|
|
753
|
-
break;
|
|
754
|
-
// Diff Tools
|
|
755
|
-
case 'diff_bundle':
|
|
756
|
-
result = await diffBundle(args);
|
|
757
|
-
break;
|
|
758
|
-
case 'conflict_matrix':
|
|
759
|
-
result = conflictMatrix(args);
|
|
760
|
-
break;
|
|
761
|
-
default:
|
|
762
|
-
result = { error: `Unknown tool: ${name}` };
|
|
763
|
-
}
|
|
764
|
-
// Log telemetry for the tool execution
|
|
765
|
-
if (isSupabaseConfigured() && name !== 'list_projects') {
|
|
766
|
-
const executionMs = Date.now() - startTime;
|
|
767
|
-
const projectHash = args && typeof args === 'object' && 'project' in args
|
|
768
|
-
? String(args.project)
|
|
769
|
-
: loader.getProjectNames()[0] || 'unknown';
|
|
770
|
-
// Fire-and-forget telemetry log
|
|
771
|
-
logTelemetry({
|
|
772
|
-
tool_name: name,
|
|
773
|
-
project_hash: projectHash,
|
|
774
|
-
execution_ms: executionMs,
|
|
775
|
-
// user_id will be added by the Ptah API gateway if passing through there,
|
|
776
|
-
// or stay null if running strictly local CLI without an injected token.
|
|
777
|
-
}).catch(() => { });
|
|
778
|
-
}
|
|
423
|
+
const result = await res.json();
|
|
779
424
|
return {
|
|
780
|
-
content: [{
|
|
781
|
-
type: 'text',
|
|
782
|
-
text: JSON.stringify(result, null, 2),
|
|
783
|
-
}],
|
|
425
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
784
426
|
};
|
|
785
427
|
}
|
|
786
428
|
catch (err) {
|
|
787
429
|
return {
|
|
788
|
-
content: [{
|
|
789
|
-
type: 'text',
|
|
790
|
-
text: JSON.stringify({
|
|
791
|
-
error: `Tool ${name} failed: ${err.message}`,
|
|
792
|
-
}, null, 2),
|
|
793
|
-
}],
|
|
430
|
+
content: [{ type: 'text', text: JSON.stringify({ error: `Cloud proxy failed: ${err.message}` }, null, 2) }],
|
|
794
431
|
isError: true,
|
|
795
432
|
};
|
|
796
433
|
}
|
|
797
434
|
});
|
|
798
|
-
// Start stdio transport
|
|
799
435
|
const transport = new StdioServerTransport();
|
|
800
436
|
await server.connect(transport);
|
|
801
|
-
|
|
802
|
-
process.stderr.write(`Seshat MCP server started: ${projectNames.length} projects (${totalEntities} entities) — ${projectNames.join(', ')}\n`);
|
|
803
|
-
}
|
|
804
|
-
else {
|
|
805
|
-
const manifest = loader.getManifest();
|
|
806
|
-
process.stderr.write(`Seshat MCP server started: ${manifest?.projectName || 'unknown'} (${totalEntities} entities)\n`);
|
|
807
|
-
}
|
|
437
|
+
process.stderr.write(`Seshat Cloud Proxy started. Routing requests to Ptah API...\n`);
|
|
808
438
|
}
|
|
809
439
|
main().catch((err) => {
|
|
810
440
|
process.stderr.write(`Fatal: ${err.message}\n`);
|
package/dist/tools/diff.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* These tools compare TWO entity sets (base vs branch, or task vs task),
|
|
8
8
|
* unlike the single-bundle queries in index.ts and functors.ts.
|
|
9
9
|
*/
|
|
10
|
+
import type { ProjectLoader } from '../types.js';
|
|
10
11
|
export declare function diffBundle(args: {
|
|
11
12
|
worktree_path: string;
|
|
12
13
|
project?: string;
|
package/dist/tools/functors.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Each tool computes derived insights (dead code, layer violations,
|
|
6
6
|
* coupling metrics, auth coverage, etc.) from the entity data.
|
|
7
7
|
*/
|
|
8
|
-
import type { JstfEntity } from '../types.js';
|
|
8
|
+
import type { JstfEntity, ProjectLoader } from '../types.js';
|
|
9
9
|
/**
|
|
10
10
|
* Estimate the token cost of loading an entity's source code into an LLM context.
|
|
11
11
|
* Uses real sourceTokens from the extraction pipeline when available (v0.3.2+),
|
|
@@ -16,19 +16,19 @@ export declare function findDeadCode(args: {
|
|
|
16
16
|
include_tests?: boolean;
|
|
17
17
|
project?: string;
|
|
18
18
|
}, loader: ProjectLoader): unknown;
|
|
19
|
-
export declare function findLayerViolations(args
|
|
19
|
+
export declare function findLayerViolations(args: {
|
|
20
20
|
project?: string;
|
|
21
|
-
}): unknown;
|
|
21
|
+
}, loader: ProjectLoader): unknown;
|
|
22
22
|
export declare function getCouplingMetrics(args: {
|
|
23
23
|
group_by?: 'module' | 'layer';
|
|
24
24
|
project?: string;
|
|
25
25
|
}, loader: ProjectLoader): unknown;
|
|
26
|
-
export declare function getAuthMatrix(args
|
|
26
|
+
export declare function getAuthMatrix(args: {
|
|
27
27
|
project?: string;
|
|
28
|
-
}): unknown;
|
|
29
|
-
export declare function findErrorGaps(args
|
|
28
|
+
}, loader: ProjectLoader): unknown;
|
|
29
|
+
export declare function findErrorGaps(args: {
|
|
30
30
|
project?: string;
|
|
31
|
-
}): unknown;
|
|
31
|
+
}, loader: ProjectLoader): unknown;
|
|
32
32
|
export declare function getTestCoverage(args: {
|
|
33
33
|
weight_by_blast_radius?: boolean;
|
|
34
34
|
project?: string;
|
|
@@ -66,12 +66,12 @@ export declare function reportActualBurn(args: {
|
|
|
66
66
|
project?: string;
|
|
67
67
|
notes?: string;
|
|
68
68
|
}, loader: ProjectLoader): Promise<unknown>;
|
|
69
|
-
export declare function find_runtime_violations(args
|
|
69
|
+
export declare function find_runtime_violations(args: {
|
|
70
70
|
project?: string;
|
|
71
|
-
}): unknown;
|
|
72
|
-
export declare function find_ownership_violations(args
|
|
71
|
+
}, loader: ProjectLoader): unknown;
|
|
72
|
+
export declare function find_ownership_violations(args: {
|
|
73
73
|
project?: string;
|
|
74
|
-
}): unknown;
|
|
74
|
+
}, loader: ProjectLoader): unknown;
|
|
75
75
|
export declare function query_traits(args: {
|
|
76
76
|
trait: string;
|
|
77
77
|
project?: string;
|
|
@@ -91,13 +91,13 @@ export declare function query_data_targets(args: {
|
|
|
91
91
|
target_name: string;
|
|
92
92
|
project?: string;
|
|
93
93
|
}, loader: ProjectLoader): unknown;
|
|
94
|
-
export declare function find_exposure_leaks(args
|
|
94
|
+
export declare function find_exposure_leaks(args: {
|
|
95
95
|
project?: string;
|
|
96
|
-
}): unknown;
|
|
97
|
-
export declare function find_semantic_clones(args
|
|
96
|
+
}, loader: ProjectLoader): unknown;
|
|
97
|
+
export declare function find_semantic_clones(args: {
|
|
98
98
|
project?: string;
|
|
99
99
|
min_complexity?: number;
|
|
100
|
-
}): unknown;
|
|
100
|
+
}, loader: ProjectLoader): unknown;
|
|
101
101
|
export declare function create_symbol(args: {
|
|
102
102
|
id: string;
|
|
103
103
|
source_file: string;
|
package/dist/tools/functors.js
CHANGED
|
@@ -151,7 +151,7 @@ export function findDeadCode(args, loader) {
|
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
// ─── Tool: find_layer_violations ─────────────────────────────────
|
|
154
|
-
export function findLayerViolations(args) {
|
|
154
|
+
export function findLayerViolations(args, loader) {
|
|
155
155
|
const projErr = validateProject(args?.project, loader);
|
|
156
156
|
if (projErr)
|
|
157
157
|
return { error: projErr };
|
|
@@ -278,7 +278,7 @@ export function getCouplingMetrics(args, loader) {
|
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
280
|
// ─── Tool: get_auth_matrix ───────────────────────────────────────
|
|
281
|
-
export function getAuthMatrix(args) {
|
|
281
|
+
export function getAuthMatrix(args, loader) {
|
|
282
282
|
const projErr = validateProject(args?.project, loader);
|
|
283
283
|
if (projErr)
|
|
284
284
|
return { error: projErr };
|
|
@@ -335,7 +335,7 @@ export function getAuthMatrix(args) {
|
|
|
335
335
|
};
|
|
336
336
|
}
|
|
337
337
|
// ─── Tool: find_error_gaps ───────────────────────────────────────
|
|
338
|
-
export function findErrorGaps(args) {
|
|
338
|
+
export function findErrorGaps(args, loader) {
|
|
339
339
|
const projErr = validateProject(args?.project, loader);
|
|
340
340
|
if (projErr)
|
|
341
341
|
return { error: projErr };
|
|
@@ -822,7 +822,7 @@ export async function reportActualBurn(args, loader) {
|
|
|
822
822
|
};
|
|
823
823
|
}
|
|
824
824
|
// ─── Tool: find_runtime_violations (Runtime Context) ────────────
|
|
825
|
-
export function find_runtime_violations(args) {
|
|
825
|
+
export function find_runtime_violations(args, loader) {
|
|
826
826
|
const projErr = validateProject(args?.project, loader);
|
|
827
827
|
if (projErr)
|
|
828
828
|
return { error: projErr };
|
|
@@ -863,7 +863,7 @@ export function find_runtime_violations(args) {
|
|
|
863
863
|
};
|
|
864
864
|
}
|
|
865
865
|
// ─── Tool: find_ownership_violations (Ownership & Lifetimes) ─────
|
|
866
|
-
export function find_ownership_violations(args) {
|
|
866
|
+
export function find_ownership_violations(args, loader) {
|
|
867
867
|
const projErr = validateProject(args?.project, loader);
|
|
868
868
|
if (projErr)
|
|
869
869
|
return { error: projErr };
|
|
@@ -1079,7 +1079,7 @@ export function query_data_targets(args, loader) {
|
|
|
1079
1079
|
};
|
|
1080
1080
|
}
|
|
1081
1081
|
// ─── Tool: find_exposure_leaks (Architectural Visibility) ───────
|
|
1082
|
-
export function find_exposure_leaks(args) {
|
|
1082
|
+
export function find_exposure_leaks(args, loader) {
|
|
1083
1083
|
const projErr = validateProject(args?.project, loader);
|
|
1084
1084
|
if (projErr)
|
|
1085
1085
|
return { error: projErr };
|
|
@@ -1114,7 +1114,7 @@ export function find_exposure_leaks(args) {
|
|
|
1114
1114
|
}
|
|
1115
1115
|
// ─── Tool: find_semantic_clones (Logic Analysis) ────────────────
|
|
1116
1116
|
import { createHash } from 'crypto';
|
|
1117
|
-
export function find_semantic_clones(args) {
|
|
1117
|
+
export function find_semantic_clones(args, loader) {
|
|
1118
1118
|
const projErr = validateProject(args?.project, loader);
|
|
1119
1119
|
if (projErr)
|
|
1120
1120
|
return { error: projErr };
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Multi-project: when multiple projects are loaded, each tool accepts an optional
|
|
8
8
|
* `project` parameter. In multi-project mode, `project` is required.
|
|
9
9
|
*/
|
|
10
|
-
import type { JstfEntity } from '../types.js';
|
|
10
|
+
import type { JstfEntity, ProjectLoader } from '../types.js';
|
|
11
11
|
import { type CallGraph } from '../graph.js';
|
|
12
12
|
export declare function getGraph(project: string | undefined, loader: ProjectLoader): CallGraph;
|
|
13
13
|
/**
|
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@papyruslabsai/seshat-mcp",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Semantic MCP server — exposes a codebase's structure, dependencies, and constraints as queryable tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"seshat-mcp": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./dist/index.js",
|
|
12
|
+
"./tools": "./dist/tools/index.js",
|
|
13
|
+
"./functors": "./dist/tools/functors.js",
|
|
14
|
+
"./diff": "./dist/tools/diff.js",
|
|
15
|
+
"./types": "./dist/types.js"
|
|
16
|
+
},
|
|
10
17
|
"scripts": {
|
|
11
18
|
"build": "tsc",
|
|
12
19
|
"dev": "tsc --watch",
|