@papyruslabsai/seshat-mcp 0.12.3 → 0.13.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/index.d.ts +4 -4
- package/dist/index.js +106 -48
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @papyruslabs/seshat-mcp —
|
|
3
|
+
* @papyruslabs/seshat-mcp — Structural Code Analysis MCP Server (Cloud Proxy)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Declares the Seshat tool suite to Claude/AI clients. All tool calls are
|
|
6
|
+
* proxied to the Ptah Cloud API. Tool descriptions are written as triggers —
|
|
7
|
+
* they tell the LLM *when* to reach for each tool, not just what it does.
|
|
8
8
|
*/
|
|
9
9
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @papyruslabs/seshat-mcp —
|
|
3
|
+
* @papyruslabs/seshat-mcp — Structural Code Analysis MCP Server (Cloud Proxy)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Declares the Seshat tool suite to Claude/AI clients. All tool calls are
|
|
6
|
+
* proxied to the Ptah Cloud API. Tool descriptions are written as triggers —
|
|
7
|
+
* they tell the LLM *when* to reach for each tool, not just what it does.
|
|
8
8
|
*/
|
|
9
9
|
import fs from 'fs';
|
|
10
10
|
import path from 'path';
|
|
11
11
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
12
12
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
13
13
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
14
|
+
// ─── Server Instructions ─────────────────────────────────────────
|
|
15
|
+
// Sent to the LLM at connection time. This is the "first contact" pitch.
|
|
16
|
+
const SERVER_INSTRUCTIONS = `Seshat provides structural code analysis backed by a compiled intermediate representation — not heuristic guesses or text search. Every function, class, and route in the synced codebase has been extracted into a typed symbol graph with dependency edges, data flow, constraints, and architectural layer tags.
|
|
17
|
+
|
|
18
|
+
Use these tools instead of grep/Read when you need to understand code structure:
|
|
19
|
+
- "Who calls this function?" → get_dependencies (not grep for the function name)
|
|
20
|
+
- "What breaks if I change this?" → get_blast_radius (not guessing from imports)
|
|
21
|
+
- "Which functions touch the database?" → find_by_constraint with DB_ACCESS
|
|
22
|
+
- "How is this codebase organized?" → list_modules or get_topology
|
|
23
|
+
|
|
24
|
+
Start with list_projects to see what's loaded. All tools are read-only and safe to call speculatively.
|
|
25
|
+
|
|
26
|
+
get_blast_radius and get_optimal_context are designed for iterative use. As you learn more about the codebase from other tools, call them again with new targets — each call refines your understanding. 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.`;
|
|
14
27
|
const TIER_ORDER = ['cartographer', 'analyst', 'architect'];
|
|
15
28
|
const TOOL_TIERS = {
|
|
16
29
|
// Cartographer (free) — explore and navigate
|
|
@@ -52,41 +65,51 @@ const TIER_LABELS = {
|
|
|
52
65
|
function tierAtLeast(userTier, requiredTier) {
|
|
53
66
|
return TIER_ORDER.indexOf(userTier) >= TIER_ORDER.indexOf(requiredTier);
|
|
54
67
|
}
|
|
55
|
-
// ───
|
|
68
|
+
// ─── Shared Definitions ──────────────────────────────────────────
|
|
56
69
|
const projectParam = {
|
|
57
70
|
type: 'string',
|
|
58
71
|
description: 'Project name (required in multi-project mode). Use list_projects to see available projects.',
|
|
59
72
|
};
|
|
73
|
+
const READ_ONLY = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
74
|
+
const READ_ONLY_OPEN = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true };
|
|
60
75
|
// ─── Tool Definitions ─────────────────────────────────────────────
|
|
76
|
+
// Descriptions are written as TRIGGERS: they tell the LLM when to
|
|
77
|
+
// reach for the tool, what it returns, and how it compares to built-in
|
|
78
|
+
// alternatives like grep/Read.
|
|
61
79
|
const TOOLS = [
|
|
80
|
+
// ─── Always Visible ───────────────────────────────────────────────
|
|
62
81
|
{
|
|
63
82
|
name: 'get_account_status',
|
|
64
|
-
description: '
|
|
83
|
+
description: 'See your current plan, available tools, and credit balance. Call this if a tool returns a tier error or you want to know what tools are available.',
|
|
65
84
|
inputSchema: { type: 'object', properties: {} },
|
|
85
|
+
annotations: READ_ONLY_OPEN,
|
|
66
86
|
},
|
|
87
|
+
// ─── Cartographer (Free Tier) ─────────────────────────────────────
|
|
67
88
|
{
|
|
68
89
|
name: 'list_projects',
|
|
69
|
-
description: '
|
|
90
|
+
description: 'Start here. Returns all synced codebases with their size, language, and project name. You need the project name for every other tool.',
|
|
70
91
|
inputSchema: { type: 'object', properties: {} },
|
|
92
|
+
annotations: READ_ONLY_OPEN,
|
|
71
93
|
},
|
|
72
94
|
{
|
|
73
95
|
name: 'query_entities',
|
|
74
|
-
description: '
|
|
96
|
+
description: 'Like grep but for code structure. Find functions, classes, and routes by name, architectural layer (route/service/component), or module. Returns matching symbols with their type, file, and layer — use this instead of grep when you need to find code by what it does, not by text content.',
|
|
75
97
|
inputSchema: {
|
|
76
98
|
type: 'object',
|
|
77
99
|
properties: {
|
|
78
100
|
project: projectParam,
|
|
79
|
-
query: { type: 'string', description: 'Search term — matches against
|
|
101
|
+
query: { type: 'string', description: 'Search term — matches against symbol name, ID, source file, and module' },
|
|
80
102
|
layer: { type: 'string', description: 'Filter by architectural layer: route, controller, service, repository, utility, hook, component, schema' },
|
|
81
103
|
module: { type: 'string', description: 'Filter by module (partial match)' },
|
|
82
104
|
language: { type: 'string', description: 'Filter by source language: javascript, typescript, python, go, rust, etc.' },
|
|
83
105
|
limit: { type: 'number', description: 'Max results to return (default: 50)' },
|
|
84
106
|
},
|
|
85
107
|
},
|
|
108
|
+
annotations: READ_ONLY_OPEN,
|
|
86
109
|
},
|
|
87
110
|
{
|
|
88
111
|
name: 'get_entity',
|
|
89
|
-
description: 'Get
|
|
112
|
+
description: 'Get everything about one function or class — its signature, callers, callees, data flow, constraints, and source location. 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.',
|
|
90
113
|
inputSchema: {
|
|
91
114
|
type: 'object',
|
|
92
115
|
properties: {
|
|
@@ -95,10 +118,11 @@ const TOOLS = [
|
|
|
95
118
|
},
|
|
96
119
|
required: ['id'],
|
|
97
120
|
},
|
|
121
|
+
annotations: READ_ONLY_OPEN,
|
|
98
122
|
},
|
|
99
123
|
{
|
|
100
124
|
name: 'get_dependencies',
|
|
101
|
-
description: '
|
|
125
|
+
description: 'Trace who calls a function and what it calls, up to N levels deep. Use this instead of grep-for-function-name when you need the actual call chain — returns the dependency graph, not text matches. Covers callers (upstream), callees (downstream), or both.',
|
|
102
126
|
inputSchema: {
|
|
103
127
|
type: 'object',
|
|
104
128
|
properties: {
|
|
@@ -109,10 +133,11 @@ const TOOLS = [
|
|
|
109
133
|
},
|
|
110
134
|
required: ['entity_id'],
|
|
111
135
|
},
|
|
136
|
+
annotations: READ_ONLY_OPEN,
|
|
112
137
|
},
|
|
113
138
|
{
|
|
114
139
|
name: 'get_data_flow',
|
|
115
|
-
description: '
|
|
140
|
+
description: 'See what data a function reads, returns, and mutates (DB writes, state changes). Use this when debugging data bugs or when you need to verify whether a function has side effects before refactoring it.',
|
|
116
141
|
inputSchema: {
|
|
117
142
|
type: 'object',
|
|
118
143
|
properties: {
|
|
@@ -121,10 +146,11 @@ const TOOLS = [
|
|
|
121
146
|
},
|
|
122
147
|
required: ['entity_id'],
|
|
123
148
|
},
|
|
149
|
+
annotations: READ_ONLY_OPEN,
|
|
124
150
|
},
|
|
125
151
|
{
|
|
126
152
|
name: 'find_by_constraint',
|
|
127
|
-
description: '
|
|
153
|
+
description: 'Find every function with a specific behavior tag — AUTH (requires authentication), DB_ACCESS (touches database), THROWS (can throw), PURE (no side effects), NETWORK_IO (makes HTTP calls), VALIDATED (has input validation). Use this when you need to answer questions like "which functions write to the database?" or "what endpoints lack auth?"',
|
|
128
154
|
inputSchema: {
|
|
129
155
|
type: 'object',
|
|
130
156
|
properties: {
|
|
@@ -133,10 +159,11 @@ const TOOLS = [
|
|
|
133
159
|
},
|
|
134
160
|
required: ['constraint'],
|
|
135
161
|
},
|
|
162
|
+
annotations: READ_ONLY_OPEN,
|
|
136
163
|
},
|
|
137
164
|
{
|
|
138
165
|
name: 'get_blast_radius',
|
|
139
|
-
description: '
|
|
166
|
+
description: 'Before modifying a function, call this to see everything that could break. Returns all transitively affected symbols — both upstream callers and downstream callees — with distance from the change point. Like git log --follow but for runtime impact. Designed for repeated use: as you discover new symbols with other tools, call this again on them to expand your understanding of the affected surface.',
|
|
140
167
|
inputSchema: {
|
|
141
168
|
type: 'object',
|
|
142
169
|
properties: {
|
|
@@ -145,10 +172,11 @@ const TOOLS = [
|
|
|
145
172
|
},
|
|
146
173
|
required: ['entity_ids'],
|
|
147
174
|
},
|
|
175
|
+
annotations: READ_ONLY_OPEN,
|
|
148
176
|
},
|
|
149
177
|
{
|
|
150
178
|
name: 'list_modules',
|
|
151
|
-
description: '
|
|
179
|
+
description: 'Get a bird\'s-eye view of how the codebase is organized. Groups all symbols by architectural layer (route/service/component), module, file, or language with counts. Use this to orient yourself in an unfamiliar codebase before diving into specifics.',
|
|
152
180
|
inputSchema: {
|
|
153
181
|
type: 'object',
|
|
154
182
|
properties: {
|
|
@@ -156,18 +184,20 @@ const TOOLS = [
|
|
|
156
184
|
group_by: { type: 'string', enum: ['layer', 'module', 'file', 'language'], description: 'How to group entities (default: layer)' },
|
|
157
185
|
},
|
|
158
186
|
},
|
|
187
|
+
annotations: READ_ONLY_OPEN,
|
|
159
188
|
},
|
|
160
189
|
{
|
|
161
190
|
name: 'get_topology',
|
|
162
|
-
description: 'Get the API
|
|
191
|
+
description: 'Get the full API surface map in one call — all routes, middleware, auth patterns, and database tables. Use this when you need to understand the overall architecture without reading every file. Returns the information you\'d normally piece together from dozens of file reads.',
|
|
163
192
|
inputSchema: {
|
|
164
193
|
type: 'object',
|
|
165
194
|
properties: { project: projectParam },
|
|
166
195
|
},
|
|
196
|
+
annotations: READ_ONLY_OPEN,
|
|
167
197
|
},
|
|
168
198
|
{
|
|
169
199
|
name: 'get_optimal_context',
|
|
170
|
-
description: '
|
|
200
|
+
description: 'Before working on a function, call this to get the most relevant related code ranked by importance and fitted to a token budget. Returns a prioritized reading list of symbols you should understand — better than guessing which files to open. Designed for iterative use: call it on your target, read the top results, then call it again on any surprising dependencies to build a complete picture.',
|
|
171
201
|
inputSchema: {
|
|
172
202
|
type: 'object',
|
|
173
203
|
properties: {
|
|
@@ -178,11 +208,12 @@ const TOOLS = [
|
|
|
178
208
|
},
|
|
179
209
|
required: ['target_entity'],
|
|
180
210
|
},
|
|
211
|
+
annotations: READ_ONLY_OPEN,
|
|
181
212
|
},
|
|
182
213
|
// ─── Analyst Tools (Tier 2) ───────────────────────────────────────
|
|
183
214
|
{
|
|
184
215
|
name: 'find_dead_code',
|
|
185
|
-
description: 'Find
|
|
216
|
+
description: 'Find functions that nothing calls. Walks the call graph from all entry points (routes, exports, tests) and flags symbols that are unreachable. Use this during cleanup or before a release to find safe deletion candidates.',
|
|
186
217
|
inputSchema: {
|
|
187
218
|
type: 'object',
|
|
188
219
|
properties: {
|
|
@@ -190,18 +221,20 @@ const TOOLS = [
|
|
|
190
221
|
include_tests: { type: 'boolean', description: 'Include test entities in dead code results (default: false)' },
|
|
191
222
|
},
|
|
192
223
|
},
|
|
224
|
+
annotations: READ_ONLY_OPEN,
|
|
193
225
|
},
|
|
194
226
|
{
|
|
195
227
|
name: 'find_layer_violations',
|
|
196
|
-
description: '
|
|
228
|
+
description: 'Find places where the architecture is broken — a database repository calling a route handler, a utility importing a component. Returns every backward or skip-layer dependency that violates clean architecture.',
|
|
197
229
|
inputSchema: {
|
|
198
230
|
type: 'object',
|
|
199
231
|
properties: { project: projectParam },
|
|
200
232
|
},
|
|
233
|
+
annotations: READ_ONLY_OPEN,
|
|
201
234
|
},
|
|
202
235
|
{
|
|
203
236
|
name: 'get_coupling_metrics',
|
|
204
|
-
description: '
|
|
237
|
+
description: 'Measure how tangled modules are. Returns coupling (cross-module dependencies), cohesion (within-module dependencies), and instability scores. High coupling + low cohesion = refactoring candidates. Use this when planning a refactor to find the worst offenders.',
|
|
205
238
|
inputSchema: {
|
|
206
239
|
type: 'object',
|
|
207
240
|
properties: {
|
|
@@ -209,26 +242,29 @@ const TOOLS = [
|
|
|
209
242
|
group_by: { type: 'string', enum: ['module', 'layer'], description: 'Group entities by module or layer (default: module)' },
|
|
210
243
|
},
|
|
211
244
|
},
|
|
245
|
+
annotations: READ_ONLY_OPEN,
|
|
212
246
|
},
|
|
213
247
|
{
|
|
214
248
|
name: 'get_auth_matrix',
|
|
215
|
-
description: '
|
|
249
|
+
description: 'Audit authentication coverage. Shows which API routes and controllers require auth and which don\'t, plus inconsistencies like database access without auth checks. Use this for security reviews.',
|
|
216
250
|
inputSchema: {
|
|
217
251
|
type: 'object',
|
|
218
252
|
properties: { project: projectParam },
|
|
219
253
|
},
|
|
254
|
+
annotations: READ_ONLY_OPEN,
|
|
220
255
|
},
|
|
221
256
|
{
|
|
222
257
|
name: 'find_error_gaps',
|
|
223
|
-
description: 'Find
|
|
258
|
+
description: 'Find crash risks: functions that throw or have network/DB side effects whose callers don\'t catch errors. Returns the specific caller→callee pairs where exceptions can propagate unhandled. Use this before shipping to find missing error handling.',
|
|
224
259
|
inputSchema: {
|
|
225
260
|
type: 'object',
|
|
226
261
|
properties: { project: projectParam },
|
|
227
262
|
},
|
|
263
|
+
annotations: READ_ONLY_OPEN,
|
|
228
264
|
},
|
|
229
265
|
{
|
|
230
266
|
name: 'get_test_coverage',
|
|
231
|
-
description: '
|
|
267
|
+
description: 'See which production functions are actually exercised by tests via the call graph — semantic coverage, not line coverage. Optionally ranks uncovered functions by blast radius so you know which missing tests are riskiest.',
|
|
232
268
|
inputSchema: {
|
|
233
269
|
type: 'object',
|
|
234
270
|
properties: {
|
|
@@ -236,20 +272,23 @@ const TOOLS = [
|
|
|
236
272
|
weight_by_blast_radius: { type: 'boolean', description: 'Rank uncovered entities by blast radius to prioritize testing (default: false, slower)' },
|
|
237
273
|
},
|
|
238
274
|
},
|
|
275
|
+
annotations: READ_ONLY_OPEN,
|
|
239
276
|
},
|
|
240
277
|
{
|
|
241
278
|
name: 'find_runtime_violations',
|
|
242
|
-
description: '
|
|
279
|
+
description: 'Find architectural boundary leaks where framework-agnostic code imports framework-specific code. Use this when separating core logic from framework dependencies.',
|
|
243
280
|
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
281
|
+
annotations: READ_ONLY_OPEN,
|
|
244
282
|
},
|
|
245
283
|
{
|
|
246
284
|
name: 'find_ownership_violations',
|
|
247
|
-
description: '
|
|
285
|
+
description: 'Find memory and lifecycle issues — entities with complex ownership, unsafe blocks, escaping references, or illegal mutability on borrowed data. Most useful for Rust and C++ codebases.',
|
|
248
286
|
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
287
|
+
annotations: READ_ONLY_OPEN,
|
|
249
288
|
},
|
|
250
289
|
{
|
|
251
290
|
name: 'query_traits',
|
|
252
|
-
description: '
|
|
291
|
+
description: 'Find functions by abstract capability regardless of syntax — "fallible" (can fail), "asyncContext" (carries async state), "generator" (yields values). Use this when you need to find all code with a specific behavioral trait across the entire codebase.',
|
|
253
292
|
inputSchema: {
|
|
254
293
|
type: 'object',
|
|
255
294
|
properties: {
|
|
@@ -258,27 +297,30 @@ const TOOLS = [
|
|
|
258
297
|
},
|
|
259
298
|
required: ['trait'],
|
|
260
299
|
},
|
|
300
|
+
annotations: READ_ONLY_OPEN,
|
|
261
301
|
},
|
|
262
302
|
{
|
|
263
303
|
name: 'find_exposure_leaks',
|
|
264
|
-
description: '
|
|
304
|
+
description: 'Find places where public/API code directly accesses private internals, bypassing the intended abstraction boundary. Use this during API design reviews or before extracting a module.',
|
|
265
305
|
inputSchema: { type: 'object', properties: { project: projectParam } },
|
|
306
|
+
annotations: READ_ONLY_OPEN,
|
|
266
307
|
},
|
|
267
308
|
{
|
|
268
309
|
name: 'find_semantic_clones',
|
|
269
|
-
description: '
|
|
310
|
+
description: 'Find duplicated logic across the codebase. Normalizes variable names and compares code structure to catch identical algorithms in different files — even across different languages. Use this before a DRY refactor.',
|
|
270
311
|
inputSchema: {
|
|
271
312
|
type: 'object',
|
|
272
313
|
properties: {
|
|
273
314
|
project: projectParam,
|
|
274
|
-
min_complexity: { type: 'number', description: 'Minimum
|
|
315
|
+
min_complexity: { type: 'number', description: 'Minimum logic expressions to count as a match (default: 5)' },
|
|
275
316
|
},
|
|
276
317
|
},
|
|
318
|
+
annotations: READ_ONLY_OPEN,
|
|
277
319
|
},
|
|
278
320
|
// ─── Architect Tools (Tier 3) ─────────────────────────────────────
|
|
279
321
|
{
|
|
280
322
|
name: 'estimate_task_cost',
|
|
281
|
-
description: '
|
|
323
|
+
description: 'Before starting a code change, estimate how many tokens it will consume. Computes the blast radius, sums source tokens across all affected symbols, and projects total burn including iteration cycles. Use this to check if a task fits your context budget before committing to it.',
|
|
282
324
|
inputSchema: {
|
|
283
325
|
type: 'object',
|
|
284
326
|
properties: {
|
|
@@ -288,10 +330,11 @@ const TOOLS = [
|
|
|
288
330
|
},
|
|
289
331
|
required: ['target_entities'],
|
|
290
332
|
},
|
|
333
|
+
annotations: READ_ONLY_OPEN,
|
|
291
334
|
},
|
|
292
335
|
{
|
|
293
336
|
name: 'simulate_mutation',
|
|
294
|
-
description: '
|
|
337
|
+
description: 'Simulate a hypothetical code change without writing anything. Propose adding or removing constraints/traits on a symbol and see which other symbols would break and what fixes they\'d need. Use this to plan a change before making it.',
|
|
295
338
|
inputSchema: {
|
|
296
339
|
type: 'object',
|
|
297
340
|
properties: {
|
|
@@ -315,10 +358,11 @@ const TOOLS = [
|
|
|
315
358
|
},
|
|
316
359
|
required: ['entity_id', 'mutation'],
|
|
317
360
|
},
|
|
361
|
+
annotations: READ_ONLY_OPEN,
|
|
318
362
|
},
|
|
319
363
|
{
|
|
320
364
|
name: 'create_symbol',
|
|
321
|
-
description: 'Register a new
|
|
365
|
+
description: 'Register a planned new symbol in the graph before it exists on disk. This lets simulate_mutation and conflict_matrix reason about code you haven\'t written yet. Nothing is written to disk.',
|
|
322
366
|
inputSchema: {
|
|
323
367
|
type: 'object',
|
|
324
368
|
properties: {
|
|
@@ -330,23 +374,25 @@ const TOOLS = [
|
|
|
330
374
|
},
|
|
331
375
|
required: ['id', 'source_file'],
|
|
332
376
|
},
|
|
377
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
333
378
|
},
|
|
334
379
|
{
|
|
335
380
|
name: 'diff_bundle',
|
|
336
|
-
description: 'Compare
|
|
381
|
+
description: 'Compare a worktree against the loaded project to see what changed structurally — not a line diff, but which symbols were added, removed, or had their signatures/dependencies changed. Use this after making changes to verify the structural impact.',
|
|
337
382
|
inputSchema: {
|
|
338
383
|
type: 'object',
|
|
339
384
|
properties: {
|
|
340
385
|
project: projectParam,
|
|
341
|
-
worktree_path: { type: 'string', description: 'Absolute path to the worktree or branch checkout to compare
|
|
386
|
+
worktree_path: { type: 'string', description: 'Absolute path to the worktree or branch checkout to compare' },
|
|
342
387
|
include_unchanged: { type: 'boolean', description: 'Include unchanged entities in the output (default: false)' },
|
|
343
388
|
},
|
|
344
389
|
required: ['worktree_path'],
|
|
345
390
|
},
|
|
391
|
+
annotations: READ_ONLY_OPEN,
|
|
346
392
|
},
|
|
347
393
|
{
|
|
348
394
|
name: 'conflict_matrix',
|
|
349
|
-
description: 'Given multiple tasks,
|
|
395
|
+
description: 'Given multiple planned tasks, check which ones can run in parallel safely. Classifies every task pair: Tier 1 (different files, safe), Tier 2 (same file different symbols, careful), Tier 3 (same symbol, must sequence). Returns a matrix and suggested execution order.',
|
|
350
396
|
inputSchema: {
|
|
351
397
|
type: 'object',
|
|
352
398
|
properties: {
|
|
@@ -363,23 +409,25 @@ const TOOLS = [
|
|
|
363
409
|
},
|
|
364
410
|
required: ['id', 'entity_ids'],
|
|
365
411
|
},
|
|
366
|
-
description: 'Array of tasks to check for conflicts.
|
|
412
|
+
description: 'Array of tasks to check for conflicts.',
|
|
367
413
|
},
|
|
368
414
|
},
|
|
369
415
|
required: ['tasks'],
|
|
370
416
|
},
|
|
417
|
+
annotations: READ_ONLY_OPEN,
|
|
371
418
|
},
|
|
372
419
|
{
|
|
373
420
|
name: 'query_data_targets',
|
|
374
|
-
description: '
|
|
421
|
+
description: 'Find every function that reads from or writes to a specific database table, state object, or data source. Use this when you need to understand all the code paths that touch a particular data store.',
|
|
375
422
|
inputSchema: {
|
|
376
423
|
type: 'object',
|
|
377
424
|
properties: {
|
|
378
425
|
project: projectParam,
|
|
379
|
-
target_name: { type: 'string', description: 'The name of the database table, state object, or data source
|
|
426
|
+
target_name: { type: 'string', description: 'The name of the database table, state object, or data source (e.g., "users", "auth_token").' },
|
|
380
427
|
},
|
|
381
428
|
required: ['target_name'],
|
|
382
429
|
},
|
|
430
|
+
annotations: READ_ONLY_OPEN,
|
|
383
431
|
},
|
|
384
432
|
];
|
|
385
433
|
// ─── Project Resolution (Fallback) ────────────────────────────────
|
|
@@ -411,12 +459,13 @@ function getCloudUrl(path) {
|
|
|
411
459
|
// ─── Server Setup ─────────────────────────────────────────────────
|
|
412
460
|
async function main() {
|
|
413
461
|
const server = new Server({
|
|
414
|
-
name: 'seshat
|
|
415
|
-
version: '0.
|
|
462
|
+
name: 'seshat',
|
|
463
|
+
version: '0.13.0',
|
|
416
464
|
}, {
|
|
417
465
|
capabilities: { tools: {} },
|
|
466
|
+
instructions: SERVER_INSTRUCTIONS,
|
|
418
467
|
});
|
|
419
|
-
// ───
|
|
468
|
+
// ─── Dynamic ListTools — only expose tools the user can access ──
|
|
420
469
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
421
470
|
const apiKey = process.env.SESHAT_API_KEY;
|
|
422
471
|
let userTier = 'cartographer';
|
|
@@ -445,17 +494,17 @@ async function main() {
|
|
|
445
494
|
});
|
|
446
495
|
return { tools: visibleTools };
|
|
447
496
|
});
|
|
448
|
-
// ─── CallTool handler
|
|
497
|
+
// ─── CallTool handler ──────────────────────────────────────────
|
|
449
498
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
450
499
|
const { name, arguments: args } = request.params;
|
|
451
500
|
const apiKey = process.env.SESHAT_API_KEY;
|
|
452
501
|
if (!apiKey) {
|
|
453
502
|
return {
|
|
454
|
-
content: [{ type: 'text', text: JSON.stringify({ error: 'SESHAT_API_KEY environment variable is required
|
|
503
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'SESHAT_API_KEY environment variable is required. Get your free key at https://ptah.papyruslabs.ai' }, null, 2) }],
|
|
455
504
|
isError: true,
|
|
456
505
|
};
|
|
457
506
|
}
|
|
458
|
-
// ───
|
|
507
|
+
// ─── get_account_status ──────────────────────────────────────
|
|
459
508
|
if (name === 'get_account_status') {
|
|
460
509
|
try {
|
|
461
510
|
const res = await fetch(getCloudUrl('/api/mcp/account'), {
|
|
@@ -525,9 +574,18 @@ async function main() {
|
|
|
525
574
|
};
|
|
526
575
|
}
|
|
527
576
|
const result = await res.json();
|
|
528
|
-
//
|
|
529
|
-
//
|
|
530
|
-
|
|
577
|
+
// Separate _meta into assistant-only content so it doesn't clutter
|
|
578
|
+
// the user-visible response. The LLM still sees it for context.
|
|
579
|
+
if (result._meta) {
|
|
580
|
+
const meta = result._meta;
|
|
581
|
+
delete result._meta;
|
|
582
|
+
return {
|
|
583
|
+
content: [
|
|
584
|
+
{ type: 'text', text: JSON.stringify(result, null, 2) },
|
|
585
|
+
{ type: 'text', text: JSON.stringify({ _meta: meta }), annotations: { audience: ['assistant'], priority: 0.2 } },
|
|
586
|
+
],
|
|
587
|
+
};
|
|
588
|
+
}
|
|
531
589
|
return {
|
|
532
590
|
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
533
591
|
};
|
|
@@ -541,7 +599,7 @@ async function main() {
|
|
|
541
599
|
});
|
|
542
600
|
const transport = new StdioServerTransport();
|
|
543
601
|
await server.connect(transport);
|
|
544
|
-
process.stderr.write(`Seshat
|
|
602
|
+
process.stderr.write(`Seshat MCP v0.13.0 connected. Structural code analysis ready.\n`);
|
|
545
603
|
}
|
|
546
604
|
main().catch((err) => {
|
|
547
605
|
process.stderr.write(`Fatal: ${err.message}\n`);
|
package/package.json
CHANGED