Skip to content

Commit 4c4f142

Browse files
committed
Fix tools explorer: pass skillGraph, projectDir, sessionContext to MCP server
Tools explorer was creating MCP server without skillGraph, projectDir, or sessionContext — causing get_context to return nulls, skill tools to be missing, and attachments to not work. Also fix startHttpServer signature and add missing TOOL_CATEGORIES entries (context, skills, attachments).
1 parent 837e95f commit 4c4f142

3 files changed

Lines changed: 30 additions & 9 deletions

File tree

src/api/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ export async function startHttpServer(
330330
fileIndexGraph?: FileIndexGraph,
331331
taskGraph?: TaskGraph,
332332
embedFn?: EmbedFn | Partial<EmbedFnMap>,
333+
projectDir?: string,
334+
skillGraph?: SkillGraph,
335+
sessionContext?: McpSessionContext,
333336
): Promise<http.Server> {
334337
const sessions = new Map<string, HttpSession>();
335338

@@ -381,7 +384,7 @@ export async function startHttpServer(
381384
const sid = transport.sessionId;
382385
if (sid) sessions.delete(sid);
383386
};
384-
const mcpServer = createMcpServer(docGraph, codeGraph, knowledgeGraph, fileIndexGraph, taskGraph, embedFn);
387+
const mcpServer = createMcpServer(docGraph, codeGraph, knowledgeGraph, fileIndexGraph, taskGraph, embedFn, undefined, projectDir, skillGraph, sessionContext);
385388
await mcpServer.connect(transport);
386389
await transport.handleRequest(req, res, body);
387390
});

src/api/rest/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export function createRestApp(projectManager: ProjectManager): express.Express {
9292
app.use('/api/projects/:projectId/code', createCodeRouter());
9393
app.use('/api/projects/:projectId/files', createFilesRouter());
9494
app.use('/api/projects/:projectId/graph', createGraphRouter());
95-
app.use('/api/projects/:projectId/tools', createToolsRouter());
95+
app.use('/api/projects/:projectId/tools', createToolsRouter(projectManager));
9696

9797
// Serve UI static files (ui/dist)
9898
const uiDist = path.resolve(__dirname, '../../../ui/dist');

src/api/rest/tools.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Router } from 'express';
22
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
33
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
4-
import type { ProjectInstance } from '@/lib/project-manager';
5-
import { createMcpServer } from '@/api/index';
4+
import type { ProjectInstance, ProjectManager } from '@/lib/project-manager';
5+
import { createMcpServer, type McpSessionContext } from '@/api/index';
66

77
// Tool category detection based on tool name
88
const TOOL_CATEGORIES: Record<string, string> = {
9+
get_context: 'context',
910
list_topics: 'docs', get_toc: 'docs', search: 'docs', get_node: 'docs',
1011
search_topic_files: 'docs', find_examples: 'docs', search_snippets: 'docs',
1112
list_snippets: 'docs', explain_symbol: 'docs', cross_references: 'cross-graph',
@@ -16,23 +17,40 @@ const TOOL_CATEGORIES: Record<string, string> = {
1617
get_note: 'knowledge', list_notes: 'knowledge', search_notes: 'knowledge',
1718
create_relation: 'knowledge', delete_relation: 'knowledge',
1819
list_relations: 'knowledge', find_linked_notes: 'knowledge',
20+
add_note_attachment: 'knowledge', remove_note_attachment: 'knowledge',
1921
create_task: 'tasks', update_task: 'tasks', delete_task: 'tasks',
2022
get_task: 'tasks', list_tasks: 'tasks', search_tasks: 'tasks',
2123
move_task: 'tasks', link_task: 'tasks', create_task_link: 'tasks',
2224
delete_task_link: 'tasks', find_linked_tasks: 'tasks',
25+
add_task_attachment: 'tasks', remove_task_attachment: 'tasks',
26+
create_skill: 'skills', update_skill: 'skills', delete_skill: 'skills',
27+
get_skill: 'skills', list_skills: 'skills', search_skills: 'skills',
28+
recall_skills: 'skills', bump_skill_usage: 'skills',
29+
link_skill: 'skills', create_skill_link: 'skills', delete_skill_link: 'skills',
30+
find_linked_skills: 'skills',
31+
add_skill_attachment: 'skills', remove_skill_attachment: 'skills',
2332
};
2433

2534
/**
2635
* Get or create a lazy MCP client for a project instance.
2736
* The client is cached on the instance for reuse.
2837
*/
29-
async function getClient(p: ProjectInstance): Promise<Client> {
38+
async function getClient(p: ProjectInstance, pm: ProjectManager): Promise<Client> {
3039
if (p.mcpClient) return p.mcpClient;
3140

41+
// Build session context for get_context tool
42+
const ws = p.workspaceId ? pm.getWorkspace(p.workspaceId) : undefined;
43+
const sessionCtx: McpSessionContext = {
44+
projectId: p.id,
45+
workspaceId: ws?.id,
46+
workspaceProjects: ws?.config.projects,
47+
};
48+
3249
const [serverTransport, clientTransport] = InMemoryTransport.createLinkedPair();
3350
const server = createMcpServer(
3451
p.docGraph, p.codeGraph, p.knowledgeGraph, p.fileIndexGraph,
3552
p.taskGraph, p.embedFns, p.mutationQueue,
53+
p.config.projectDir, p.skillGraph, sessionCtx,
3654
);
3755
await server.connect(serverTransport);
3856

@@ -49,7 +67,7 @@ async function getClient(p: ProjectInstance): Promise<Client> {
4967
return client;
5068
}
5169

52-
export function createToolsRouter(): Router {
70+
export function createToolsRouter(projectManager: ProjectManager): Router {
5371
const router = Router({ mergeParams: true });
5472

5573
function getProject(req: any): ProjectInstance {
@@ -60,7 +78,7 @@ export function createToolsRouter(): Router {
6078
router.get('/', async (req, res, next) => {
6179
try {
6280
const p = getProject(req);
63-
const client = await getClient(p);
81+
const client = await getClient(p, projectManager);
6482
const { tools } = await client.listTools();
6583
const results = tools.map(t => ({
6684
name: t.name,
@@ -76,7 +94,7 @@ export function createToolsRouter(): Router {
7694
router.get('/:toolName', async (req, res, next) => {
7795
try {
7896
const p = getProject(req);
79-
const client = await getClient(p);
97+
const client = await getClient(p, projectManager);
8098
const { tools } = await client.listTools();
8199
const tool = tools.find(t => t.name === req.params.toolName);
82100
if (!tool) return res.status(404).json({ error: `Tool "${req.params.toolName}" not found` });
@@ -93,7 +111,7 @@ export function createToolsRouter(): Router {
93111
router.post('/:toolName/call', async (req, res, next) => {
94112
try {
95113
const p = getProject(req);
96-
const client = await getClient(p);
114+
const client = await getClient(p, projectManager);
97115
const start = Date.now();
98116
const result = await client.callTool({
99117
name: req.params.toolName,

0 commit comments

Comments
 (0)