@papyruslabsai/seshat-mcp 0.13.2 → 0.13.4
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 +14 -10
- package/dist/tools/functors.js +13 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ Use Seshat tools instead of grep/Read when you need to understand code structure
|
|
|
25
25
|
- "What breaks if I change this?" → get_blast_radius
|
|
26
26
|
- "What data does this read/write/mutate?" → get_data_flow
|
|
27
27
|
- "Which functions touch the DB / require auth / throw?" → find_by_constraint
|
|
28
|
+
- "What reads or writes the 'users' table?" → find_by_constraint(table="users")
|
|
28
29
|
- "Which endpoints require auth and which don't?" → get_auth_matrix
|
|
29
30
|
- "Where is sensitive data exposed without protection?" → find_exposure_leaks
|
|
30
31
|
- "What should I read before modifying X?" → get_optimal_context
|
|
@@ -33,7 +34,7 @@ Use Seshat tools instead of grep/Read when you need to understand code structure
|
|
|
33
34
|
All tools are read-only and safe to call speculatively — there is no cost to trying them.
|
|
34
35
|
|
|
35
36
|
get_blast_radius and get_optimal_context are designed to be called iteratively. Start with any entity, then feed discovered entities back in to expand your understanding. Each round reveals new structure that informs where to look next. When answering "what does this system do?" questions, a few rounds of blast_radius → get_entity → blast_radius on the newly discovered symbols will build a complete picture faster than reading files.`;
|
|
36
|
-
const TIER_ORDER = ['cartographer', 'analyst', 'architect'];
|
|
37
|
+
const TIER_ORDER = ['cartographer', 'pro', 'analyst', 'architect', 'founder'];
|
|
37
38
|
const TOOL_TIERS = {
|
|
38
39
|
// Cartographer (free) — explore, navigate, and assess security surface
|
|
39
40
|
list_projects: 'cartographer',
|
|
@@ -68,8 +69,10 @@ const TOOL_TIERS = {
|
|
|
68
69
|
};
|
|
69
70
|
const TIER_LABELS = {
|
|
70
71
|
cartographer: 'Cartographer (Free)',
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
pro: 'Seshat Pro',
|
|
73
|
+
analyst: 'Seshat Shield',
|
|
74
|
+
architect: 'Architect',
|
|
75
|
+
founder: 'Founder (All Access)',
|
|
73
76
|
};
|
|
74
77
|
function tierAtLeast(userTier, requiredTier) {
|
|
75
78
|
return TIER_ORDER.indexOf(userTier) >= TIER_ORDER.indexOf(requiredTier);
|
|
@@ -118,7 +121,7 @@ const TOOLS = [
|
|
|
118
121
|
},
|
|
119
122
|
{
|
|
120
123
|
name: 'get_entity',
|
|
121
|
-
description: 'Get everything about one function or class — its signature, callers, callees, data flow, constraints, and
|
|
124
|
+
description: 'Get everything about one function or class — its signature, callers, callees, data flow, constraints, source location, and database operations (which tables it reads/writes). Use this when you need to deeply understand a single symbol before modifying it. Returns more than reading the source file because it includes the dependency context.',
|
|
122
125
|
inputSchema: {
|
|
123
126
|
type: 'object',
|
|
124
127
|
properties: {
|
|
@@ -159,12 +162,13 @@ const TOOLS = [
|
|
|
159
162
|
},
|
|
160
163
|
{
|
|
161
164
|
name: 'find_by_constraint',
|
|
162
|
-
description: 'Find every function with a specific
|
|
165
|
+
description: 'Find every function with a specific syntactic constraint tag — AUTH (requires authentication), DB_ACCESS (touches database), THROWS (explicit throw statement), PURE (no side effects), NETWORK_IO (makes HTTP calls), VALIDATED (has input validation). Also supports table-level queries: pass table="walks" to find every function that reads or writes the walks table (answers "what touches this table?" for schema migrations). Constraints are extracted from source syntax, not inferred. For semantic/behavioral properties (e.g., "can fail transitively"), use query_traits instead.',
|
|
163
166
|
inputSchema: {
|
|
164
167
|
type: 'object',
|
|
165
168
|
properties: {
|
|
166
169
|
project: projectParam,
|
|
167
170
|
constraint: { type: 'string', description: 'Constraint tag to search for: AUTH, VALIDATED, PURE, THROWS, DB_ACCESS, NETWORK_IO, IMP, etc.' },
|
|
171
|
+
table: { type: 'string', description: 'Optional: filter to functions that touch a specific database table (e.g., "walks", "users"). Returns structured db_operations showing read/write/mutate per function.' },
|
|
168
172
|
},
|
|
169
173
|
required: ['constraint'],
|
|
170
174
|
},
|
|
@@ -243,7 +247,7 @@ const TOOLS = [
|
|
|
243
247
|
},
|
|
244
248
|
{
|
|
245
249
|
name: 'get_coupling_metrics',
|
|
246
|
-
description: 'Measure how tangled
|
|
250
|
+
description: 'Measure how tangled your code is. Returns coupling (cross-boundary dependencies), cohesion (within-group dependencies), and instability scores. High coupling + low cohesion = refactoring candidates. Start with group_by: "layer" for the architectural health view ("are my controllers more coupled than my services?"), then drill into group_by: "module" for specific hotspots.',
|
|
247
251
|
inputSchema: {
|
|
248
252
|
type: 'object',
|
|
249
253
|
properties: {
|
|
@@ -285,19 +289,19 @@ const TOOLS = [
|
|
|
285
289
|
},
|
|
286
290
|
{
|
|
287
291
|
name: 'find_runtime_violations',
|
|
288
|
-
description: 'Find architectural boundary leaks where framework-agnostic code imports framework-specific code. Use this when separating core logic from framework dependencies.',
|
|
292
|
+
description: 'Find architectural boundary leaks where framework-agnostic code imports framework-specific code. Use this when separating core logic from framework dependencies. Returns 0 for most JS/Python codebases — a non-zero result indicates a serious boundary violation worth investigating.',
|
|
289
293
|
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
290
294
|
annotations: READ_ONLY_OPEN,
|
|
291
295
|
},
|
|
292
296
|
{
|
|
293
297
|
name: 'find_ownership_violations',
|
|
294
|
-
description: 'Find memory and lifecycle issues — entities with complex ownership, unsafe blocks, escaping references, or illegal mutability on borrowed data. Most
|
|
298
|
+
description: 'Find memory and lifecycle issues — entities with complex ownership, unsafe blocks, escaping references, or illegal mutability on borrowed data. Returns 0 for most JS/Python codebases — a non-zero result in those languages indicates a serious boundary violation worth investigating. Most detailed results for Rust and C++.',
|
|
295
299
|
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
296
300
|
annotations: READ_ONLY_OPEN,
|
|
297
301
|
},
|
|
298
302
|
{
|
|
299
303
|
name: 'query_traits',
|
|
300
|
-
description: 'Find functions by
|
|
304
|
+
description: 'Find functions by inferred behavioral trait — "fallible" (can fail, including transitively via callees that throw), "asyncContext" (carries async state), "generator" (yields values). Traits are semantic properties inferred from the call graph, not just syntax. Use this when you need to find all code with a specific capability. For syntactic tags (explicit throw statements, DB access), use find_by_constraint instead.',
|
|
301
305
|
inputSchema: {
|
|
302
306
|
type: 'object',
|
|
303
307
|
properties: {
|
|
@@ -469,7 +473,7 @@ function getCloudUrl(path) {
|
|
|
469
473
|
async function main() {
|
|
470
474
|
const server = new Server({
|
|
471
475
|
name: 'seshat',
|
|
472
|
-
version: '0.13.
|
|
476
|
+
version: '0.13.4',
|
|
473
477
|
}, {
|
|
474
478
|
capabilities: { tools: {} },
|
|
475
479
|
instructions: SERVER_INSTRUCTIONS,
|
package/dist/tools/functors.js
CHANGED
|
@@ -135,6 +135,15 @@ export function findDeadCode(args, loader) {
|
|
|
135
135
|
if (!include_tests) {
|
|
136
136
|
deadEntities = deadEntities.filter((e) => entityLayer(e) !== 'test');
|
|
137
137
|
}
|
|
138
|
+
// Separate schemas — they're often registered dynamically (e.g., fastify.addSchema())
|
|
139
|
+
// and appear "dead" from a static call graph but are alive at runtime.
|
|
140
|
+
const SCHEMA_TYPES = new Set(['schema', 'typealias', 'interface', 'type']);
|
|
141
|
+
const schemaEntities = deadEntities.filter((e) => {
|
|
142
|
+
const type = (typeof e.struct === 'string' ? e.struct : e.struct?.type || '').toLowerCase();
|
|
143
|
+
const layer = entityLayer(e);
|
|
144
|
+
return SCHEMA_TYPES.has(type) || layer === 'schema';
|
|
145
|
+
});
|
|
146
|
+
deadEntities = deadEntities.filter((e) => !schemaEntities.includes(e));
|
|
138
147
|
// Group by layer for overview
|
|
139
148
|
const byLayer = new Map();
|
|
140
149
|
for (const e of deadEntities) {
|
|
@@ -148,6 +157,10 @@ export function findDeadCode(args, loader) {
|
|
|
148
157
|
deadCount: deadEntities.length,
|
|
149
158
|
deadByLayer: Object.fromEntries([...byLayer.entries()].sort((a, b) => b[1] - a[1])),
|
|
150
159
|
dead: deadEntities.slice(0, 100).map(entitySummary),
|
|
160
|
+
...(schemaEntities.length > 0 ? {
|
|
161
|
+
schemas_excluded: schemaEntities.length,
|
|
162
|
+
_note_schemas: `${schemaEntities.length} schema/type definitions excluded — no static references found, but schemas are often registered dynamically (e.g., fastify.addSchema()) and may be alive at runtime.`,
|
|
163
|
+
} : {}),
|
|
151
164
|
};
|
|
152
165
|
}
|
|
153
166
|
// ─── Tool: find_layer_violations ─────────────────────────────────
|
package/package.json
CHANGED