@chapterai/mcp 0.1.1 → 0.1.3
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 +251 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22439,6 +22439,29 @@ var api = {
|
|
|
22439
22439
|
return getClient().workspaces.getWorkspaceStats.query(input);
|
|
22440
22440
|
}
|
|
22441
22441
|
},
|
|
22442
|
+
intelligence: {
|
|
22443
|
+
scan(input) {
|
|
22444
|
+
return getClient().intelligence.scan.mutate(input);
|
|
22445
|
+
},
|
|
22446
|
+
query(input) {
|
|
22447
|
+
return getClient().intelligence.query.query(input);
|
|
22448
|
+
},
|
|
22449
|
+
findSymbol(input) {
|
|
22450
|
+
return getClient().intelligence.findSymbol.query(input);
|
|
22451
|
+
},
|
|
22452
|
+
findCopy(input) {
|
|
22453
|
+
return getClient().intelligence.findCopy.query(input);
|
|
22454
|
+
},
|
|
22455
|
+
contextForTask(input) {
|
|
22456
|
+
return getClient().intelligence.contextForTask.query(input);
|
|
22457
|
+
},
|
|
22458
|
+
fileMap(input) {
|
|
22459
|
+
return getClient().intelligence.fileMap.query(input);
|
|
22460
|
+
},
|
|
22461
|
+
deps(input) {
|
|
22462
|
+
return getClient().intelligence.deps.query(input);
|
|
22463
|
+
}
|
|
22464
|
+
},
|
|
22442
22465
|
sessions: {
|
|
22443
22466
|
list(input) {
|
|
22444
22467
|
return getClient().sessions.list.query(input);
|
|
@@ -23539,6 +23562,233 @@ ${lines.join("\n")}`);
|
|
|
23539
23562
|
);
|
|
23540
23563
|
}
|
|
23541
23564
|
|
|
23565
|
+
// src/tools/intelligence.ts
|
|
23566
|
+
function registerIntelligenceTools(server2) {
|
|
23567
|
+
server2.tool(
|
|
23568
|
+
"scan_codebase",
|
|
23569
|
+
"Scan and index a codebase to build a structured map of all files, symbols, routes, endpoints, models, and copy. Run this once per workspace to enable fast lookups. Accepts an optional projectPath for local directories.",
|
|
23570
|
+
{
|
|
23571
|
+
workspaceId: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
23572
|
+
workspaceName: external_exports.string().optional().describe("Workspace name (alternative to ID)"),
|
|
23573
|
+
projectPath: external_exports.string().optional().describe("Local filesystem path to scan (overrides workspace path)")
|
|
23574
|
+
},
|
|
23575
|
+
async ({ workspaceId, workspaceName, projectPath }) => {
|
|
23576
|
+
try {
|
|
23577
|
+
const id = await resolveWorkspaceId(workspaceId, workspaceName);
|
|
23578
|
+
const result = await api.intelligence.scan({
|
|
23579
|
+
workspaceId: id,
|
|
23580
|
+
projectPath
|
|
23581
|
+
});
|
|
23582
|
+
const lines = [
|
|
23583
|
+
`Codebase scanned in ${result.stats.durationMs}ms`,
|
|
23584
|
+
``,
|
|
23585
|
+
`Files: ${result.fileCount}`,
|
|
23586
|
+
`Symbols: ${result.symbolCount}`,
|
|
23587
|
+
`Routes: ${result.routeCount}`,
|
|
23588
|
+
`API endpoints: ${result.endpointCount}`,
|
|
23589
|
+
`DB models: ${result.modelCount}`,
|
|
23590
|
+
`Copy entries: ${result.copyCount}`,
|
|
23591
|
+
`Dependencies: ${result.dependencyCount}`,
|
|
23592
|
+
``,
|
|
23593
|
+
`Tech stack:`,
|
|
23594
|
+
` Languages: ${result.techStack.languages.join(", ")}`,
|
|
23595
|
+
` Frameworks: ${result.techStack.frameworks.join(", ")}`,
|
|
23596
|
+
` Databases: ${result.techStack.databases.join(", ")}`,
|
|
23597
|
+
` Package manager: ${result.techStack.packageManager ?? "unknown"}`
|
|
23598
|
+
];
|
|
23599
|
+
return success(lines.join("\n"));
|
|
23600
|
+
} catch (error2) {
|
|
23601
|
+
return formatError2(error2);
|
|
23602
|
+
}
|
|
23603
|
+
}
|
|
23604
|
+
);
|
|
23605
|
+
server2.tool(
|
|
23606
|
+
"query_codebase",
|
|
23607
|
+
"Search the codebase index for files, symbols, routes, endpoints, and copy matching a query. Returns ranked results with file paths and line numbers. The index must exist (run scan_codebase first).",
|
|
23608
|
+
{
|
|
23609
|
+
workspaceId: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
23610
|
+
workspaceName: external_exports.string().optional().describe("Workspace name (alternative to ID)"),
|
|
23611
|
+
query: external_exports.string().describe('Search query \u2014 e.g. "task creation", "auth middleware", "welcome page"'),
|
|
23612
|
+
limit: external_exports.number().optional().describe("Max results per category (default 20)")
|
|
23613
|
+
},
|
|
23614
|
+
async ({ workspaceId, workspaceName, query, limit }) => {
|
|
23615
|
+
try {
|
|
23616
|
+
const id = await resolveWorkspaceId(workspaceId, workspaceName);
|
|
23617
|
+
const result = await api.intelligence.query({ workspaceId: id, query, limit });
|
|
23618
|
+
const sections = [];
|
|
23619
|
+
if (result.files.length > 0) {
|
|
23620
|
+
sections.push("## Files");
|
|
23621
|
+
for (const f of result.files) {
|
|
23622
|
+
const exports = f.exports.length > 0 ? ` (exports: ${f.exports.slice(0, 3).join(", ")})` : "";
|
|
23623
|
+
sections.push(`- \`${f.path}\` [${f.category}]${exports}`);
|
|
23624
|
+
}
|
|
23625
|
+
}
|
|
23626
|
+
if (result.symbols.length > 0) {
|
|
23627
|
+
sections.push("\n## Symbols");
|
|
23628
|
+
for (const s of result.symbols) {
|
|
23629
|
+
const sig = s.signature ? ` \u2014 \`${s.signature}\`` : "";
|
|
23630
|
+
sections.push(`- \`${s.name}\` (${s.kind}) at \`${s.filePath}:${s.line}\`${sig}`);
|
|
23631
|
+
}
|
|
23632
|
+
}
|
|
23633
|
+
if (result.copy.length > 0) {
|
|
23634
|
+
sections.push("\n## Copy/Text");
|
|
23635
|
+
for (const c of result.copy) {
|
|
23636
|
+
sections.push(`- "${c.text}" at \`${c.filePath}:${c.line}\` in ${c.context}`);
|
|
23637
|
+
}
|
|
23638
|
+
}
|
|
23639
|
+
if (result.routes.length > 0) {
|
|
23640
|
+
sections.push("\n## Routes");
|
|
23641
|
+
for (const r of result.routes) {
|
|
23642
|
+
sections.push(`- ${r.method ?? "ANY"} \`${r.path}\` \u2192 ${r.handler} at \`${r.filePath}:${r.line}\``);
|
|
23643
|
+
}
|
|
23644
|
+
}
|
|
23645
|
+
if (result.endpoints.length > 0) {
|
|
23646
|
+
sections.push("\n## API Endpoints");
|
|
23647
|
+
for (const e of result.endpoints) {
|
|
23648
|
+
sections.push(`- \`${e.router ? e.router + "." : ""}${e.name}\` (${e.type}) at \`${e.filePath}:${e.line}\``);
|
|
23649
|
+
}
|
|
23650
|
+
}
|
|
23651
|
+
if (sections.length === 0) {
|
|
23652
|
+
return success(`No results found for "${query}". Try different keywords or run scan_codebase first.`);
|
|
23653
|
+
}
|
|
23654
|
+
return success(sections.join("\n"));
|
|
23655
|
+
} catch (error2) {
|
|
23656
|
+
return formatError2(error2);
|
|
23657
|
+
}
|
|
23658
|
+
}
|
|
23659
|
+
);
|
|
23660
|
+
server2.tool(
|
|
23661
|
+
"find_symbol",
|
|
23662
|
+
"Find a specific function, class, component, type, or other symbol by name. Returns exact file path and line number.",
|
|
23663
|
+
{
|
|
23664
|
+
workspaceId: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
23665
|
+
workspaceName: external_exports.string().optional().describe("Workspace name (alternative to ID)"),
|
|
23666
|
+
name: external_exports.string().describe('Symbol name to search for \u2014 e.g. "TaskCreateInline", "authorizeWorkspaceAccess"'),
|
|
23667
|
+
kind: external_exports.string().optional().describe("Filter by kind: function, class, component, type, interface, enum, hook, struct, method")
|
|
23668
|
+
},
|
|
23669
|
+
async ({ workspaceId, workspaceName, name, kind }) => {
|
|
23670
|
+
try {
|
|
23671
|
+
const id = await resolveWorkspaceId(workspaceId, workspaceName);
|
|
23672
|
+
const results = await api.intelligence.findSymbol({ workspaceId: id, name, kind });
|
|
23673
|
+
if (results.length === 0) {
|
|
23674
|
+
return success(`No symbol found matching "${name}"${kind ? ` (kind: ${kind})` : ""}`);
|
|
23675
|
+
}
|
|
23676
|
+
const lines = results.map((s) => {
|
|
23677
|
+
const sig = s.signature ? `
|
|
23678
|
+
${s.signature}` : "";
|
|
23679
|
+
return `- \`${s.name}\` (${s.kind}) at \`${s.filePath}:${s.line}\`${s.exported ? " [exported]" : ""}${sig}`;
|
|
23680
|
+
});
|
|
23681
|
+
return success(`Found ${results.length} match(es):
|
|
23682
|
+
${lines.join("\n")}`);
|
|
23683
|
+
} catch (error2) {
|
|
23684
|
+
return formatError2(error2);
|
|
23685
|
+
}
|
|
23686
|
+
}
|
|
23687
|
+
);
|
|
23688
|
+
server2.tool(
|
|
23689
|
+
"find_copy",
|
|
23690
|
+
"Find user-facing text/copy in the codebase by content. Returns the file path, line number, and surrounding component context. Use this to quickly locate where a specific string appears in the UI.",
|
|
23691
|
+
{
|
|
23692
|
+
workspaceId: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
23693
|
+
workspaceName: external_exports.string().optional().describe("Workspace name (alternative to ID)"),
|
|
23694
|
+
text: external_exports.string().describe('Text to search for \u2014 e.g. "Welcome to Chapter", "Sign in", "No tasks yet"')
|
|
23695
|
+
},
|
|
23696
|
+
async ({ workspaceId, workspaceName, text }) => {
|
|
23697
|
+
try {
|
|
23698
|
+
const id = await resolveWorkspaceId(workspaceId, workspaceName);
|
|
23699
|
+
const results = await api.intelligence.findCopy({ workspaceId: id, text });
|
|
23700
|
+
if (results.length === 0) {
|
|
23701
|
+
return success(`No copy found matching "${text}"`);
|
|
23702
|
+
}
|
|
23703
|
+
const lines = results.map(
|
|
23704
|
+
(c) => `- "${c.text}" at \`${c.filePath}:${c.line}\` in \`${c.context}\` (${c.type})`
|
|
23705
|
+
);
|
|
23706
|
+
return success(`Found ${results.length} match(es):
|
|
23707
|
+
${lines.join("\n")}`);
|
|
23708
|
+
} catch (error2) {
|
|
23709
|
+
return formatError2(error2);
|
|
23710
|
+
}
|
|
23711
|
+
}
|
|
23712
|
+
);
|
|
23713
|
+
server2.tool(
|
|
23714
|
+
"get_codebase_context",
|
|
23715
|
+
"Get relevant source code and structure for a task. Returns matching files, symbols, endpoints, AND the actual source code of the top matching files. Use the returned content to answer questions or start work directly \u2014 only read additional files if you need more detail on a specific aspect, but do not repeat the search.",
|
|
23716
|
+
{
|
|
23717
|
+
workspaceId: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
23718
|
+
workspaceName: external_exports.string().optional().describe("Workspace name (alternative to ID)"),
|
|
23719
|
+
taskDescription: external_exports.string().describe('Description of the task \u2014 e.g. "change the welcome message on the home page"')
|
|
23720
|
+
},
|
|
23721
|
+
async ({ workspaceId, workspaceName, taskDescription }) => {
|
|
23722
|
+
try {
|
|
23723
|
+
const id = await resolveWorkspaceId(workspaceId, workspaceName);
|
|
23724
|
+
const result = await api.intelligence.contextForTask({
|
|
23725
|
+
workspaceId: id,
|
|
23726
|
+
taskDescription
|
|
23727
|
+
});
|
|
23728
|
+
return success(result.context);
|
|
23729
|
+
} catch (error2) {
|
|
23730
|
+
return formatError2(error2);
|
|
23731
|
+
}
|
|
23732
|
+
}
|
|
23733
|
+
);
|
|
23734
|
+
server2.tool(
|
|
23735
|
+
"get_file_map",
|
|
23736
|
+
"Get a compact map of every file in the codebase with its category and key exports. Useful for understanding project structure at a glance.",
|
|
23737
|
+
{
|
|
23738
|
+
workspaceId: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
23739
|
+
workspaceName: external_exports.string().optional().describe("Workspace name (alternative to ID)")
|
|
23740
|
+
},
|
|
23741
|
+
async ({ workspaceId, workspaceName }) => {
|
|
23742
|
+
try {
|
|
23743
|
+
const id = await resolveWorkspaceId(workspaceId, workspaceName);
|
|
23744
|
+
const result = await api.intelligence.fileMap({ workspaceId: id });
|
|
23745
|
+
const lines = [
|
|
23746
|
+
`# File Map (${Object.keys(result.tree).length} files)`,
|
|
23747
|
+
`Tech stack: ${result.techStack.frameworks.join(", ")} | ${result.techStack.languages.join(", ")}`,
|
|
23748
|
+
""
|
|
23749
|
+
];
|
|
23750
|
+
for (const [path3, desc] of Object.entries(result.tree)) {
|
|
23751
|
+
lines.push(`${path3} \u2014 ${desc}`);
|
|
23752
|
+
}
|
|
23753
|
+
return success(lines.join("\n"));
|
|
23754
|
+
} catch (error2) {
|
|
23755
|
+
return formatError2(error2);
|
|
23756
|
+
}
|
|
23757
|
+
}
|
|
23758
|
+
);
|
|
23759
|
+
server2.tool(
|
|
23760
|
+
"get_file_deps",
|
|
23761
|
+
"Get the dependency graph for a specific file \u2014 what it imports (dependencies) or what imports it (dependents).",
|
|
23762
|
+
{
|
|
23763
|
+
workspaceId: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
23764
|
+
workspaceName: external_exports.string().optional().describe("Workspace name (alternative to ID)"),
|
|
23765
|
+
filePath: external_exports.string().describe('Relative file path \u2014 e.g. "src/components/task-card.tsx"'),
|
|
23766
|
+
direction: external_exports.enum(["dependents", "dependencies"]).optional().describe('Direction: "dependents" (what imports this file) or "dependencies" (what this file imports). Default: dependents')
|
|
23767
|
+
},
|
|
23768
|
+
async ({ workspaceId, workspaceName, filePath, direction }) => {
|
|
23769
|
+
try {
|
|
23770
|
+
const id = await resolveWorkspaceId(workspaceId, workspaceName);
|
|
23771
|
+
const result = await api.intelligence.deps({
|
|
23772
|
+
workspaceId: id,
|
|
23773
|
+
filePath,
|
|
23774
|
+
direction
|
|
23775
|
+
});
|
|
23776
|
+
const label = direction === "dependencies" ? "depends on" : "is imported by";
|
|
23777
|
+
if (result.files.length === 0) {
|
|
23778
|
+
return success(`\`${filePath}\` ${label} no other files`);
|
|
23779
|
+
}
|
|
23780
|
+
const lines = [`\`${filePath}\` ${label}:`];
|
|
23781
|
+
for (const f of result.files) {
|
|
23782
|
+
lines.push(` - \`${f}\``);
|
|
23783
|
+
}
|
|
23784
|
+
return success(lines.join("\n"));
|
|
23785
|
+
} catch (error2) {
|
|
23786
|
+
return formatError2(error2);
|
|
23787
|
+
}
|
|
23788
|
+
}
|
|
23789
|
+
);
|
|
23790
|
+
}
|
|
23791
|
+
|
|
23542
23792
|
// src/tools/index.ts
|
|
23543
23793
|
function registerAllTools(server2) {
|
|
23544
23794
|
registerWorkspaceTools(server2);
|
|
@@ -23549,6 +23799,7 @@ function registerAllTools(server2) {
|
|
|
23549
23799
|
registerSearchTools(server2);
|
|
23550
23800
|
registerTaskTools(server2);
|
|
23551
23801
|
registerActivityTools(server2);
|
|
23802
|
+
registerIntelligenceTools(server2);
|
|
23552
23803
|
}
|
|
23553
23804
|
|
|
23554
23805
|
// src/index.ts
|