@navigation-agent/mcp-server 0.1.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/app/createMcpServer.d.ts +18 -0
- package/dist/app/createMcpServer.js +152 -0
- package/dist/bin/navigation-mcp.d.ts +2 -0
- package/dist/bin/navigation-mcp.js +36 -0
- package/dist/contracts/public/code.d.ts +1106 -0
- package/dist/contracts/public/code.js +523 -0
- package/dist/contracts/public/common.d.ts +28 -0
- package/dist/contracts/public/common.js +23 -0
- package/dist/engine/protocol.d.ts +290 -0
- package/dist/engine/protocol.js +13 -0
- package/dist/engine/rustEngineClient.d.ts +16 -0
- package/dist/engine/rustEngineClient.js +138 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/services/findSymbolService.d.ts +11 -0
- package/dist/services/findSymbolService.js +224 -0
- package/dist/services/inspectTreeService.d.ts +11 -0
- package/dist/services/inspectTreeService.js +191 -0
- package/dist/services/listEndpointsService.d.ts +11 -0
- package/dist/services/listEndpointsService.js +233 -0
- package/dist/services/searchTextService.d.ts +11 -0
- package/dist/services/searchTextService.js +233 -0
- package/dist/services/traceCallersService.d.ts +11 -0
- package/dist/services/traceCallersService.js +256 -0
- package/dist/services/traceSymbolService.d.ts +11 -0
- package/dist/services/traceSymbolService.js +231 -0
- package/dist/tools/registerCodeTools.d.ts +20 -0
- package/dist/tools/registerCodeTools.js +188 -0
- package/package.json +51 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { normalizeTraceSymbolInput, } from "../contracts/public/code.js";
|
|
2
|
+
import { createResponseMeta, } from "../contracts/public/common.js";
|
|
3
|
+
import { nextRequestId, } from "../engine/protocol.js";
|
|
4
|
+
const TOOL_NAME = "code.trace_symbol";
|
|
5
|
+
export function createTraceSymbolService(options) {
|
|
6
|
+
return {
|
|
7
|
+
async execute(input) {
|
|
8
|
+
let response;
|
|
9
|
+
try {
|
|
10
|
+
response = await options.engineClient.request({
|
|
11
|
+
id: nextRequestId(),
|
|
12
|
+
capability: "workspace.trace_symbol",
|
|
13
|
+
workspaceRoot: options.workspaceRoot,
|
|
14
|
+
payload: {
|
|
15
|
+
path: input.path,
|
|
16
|
+
symbol: input.symbol,
|
|
17
|
+
analyzerLanguage: resolveAnalyzerLanguage(input.language, input.framework),
|
|
18
|
+
publicLanguageFilter: resolveEffectiveLanguage(input.language, input.framework),
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return buildEngineFailureResponse(input, error);
|
|
24
|
+
}
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
return buildMappedErrorResponse(input, response.error.code, response.error.message, response.error.details, response.error.retryable);
|
|
27
|
+
}
|
|
28
|
+
return buildSuccessResponse(input, response.result);
|
|
29
|
+
},
|
|
30
|
+
async validateAndExecute(payload) {
|
|
31
|
+
const normalized = normalizeTraceSymbolInput(payload);
|
|
32
|
+
if (!normalized.ok) {
|
|
33
|
+
return buildValidationErrorResponse(normalized.issues);
|
|
34
|
+
}
|
|
35
|
+
return this.execute(normalized.value);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function buildSuccessResponse(input, result) {
|
|
40
|
+
const entrypointPath = result.resolvedPath ?? input.path;
|
|
41
|
+
const effectiveLanguage = resolveEffectiveLanguage(input.language, input.framework);
|
|
42
|
+
const fileCount = result.items.length;
|
|
43
|
+
return {
|
|
44
|
+
tool: TOOL_NAME,
|
|
45
|
+
status: result.truncated ? "partial" : "ok",
|
|
46
|
+
summary: buildSummary(input.symbol, entrypointPath, result.totalMatched),
|
|
47
|
+
data: {
|
|
48
|
+
entrypoint: {
|
|
49
|
+
path: entrypointPath,
|
|
50
|
+
symbol: input.symbol,
|
|
51
|
+
language: inferLanguageFromPath(entrypointPath),
|
|
52
|
+
},
|
|
53
|
+
fileCount,
|
|
54
|
+
items: result.items.map((item) => ({
|
|
55
|
+
path: item.path,
|
|
56
|
+
language: item.language,
|
|
57
|
+
})),
|
|
58
|
+
},
|
|
59
|
+
errors: [],
|
|
60
|
+
meta: createResponseMeta({
|
|
61
|
+
query: { ...input },
|
|
62
|
+
resolvedPath: result.resolvedPath,
|
|
63
|
+
truncated: result.truncated,
|
|
64
|
+
counts: {
|
|
65
|
+
returnedCount: fileCount,
|
|
66
|
+
totalMatched: result.totalMatched,
|
|
67
|
+
},
|
|
68
|
+
detection: {
|
|
69
|
+
effectiveLanguage,
|
|
70
|
+
framework: input.framework ?? null,
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function buildValidationErrorResponse(issues) {
|
|
76
|
+
return {
|
|
77
|
+
tool: TOOL_NAME,
|
|
78
|
+
status: "error",
|
|
79
|
+
summary: "Request validation failed.",
|
|
80
|
+
data: emptyData(),
|
|
81
|
+
errors: [
|
|
82
|
+
{
|
|
83
|
+
code: "INVALID_INPUT",
|
|
84
|
+
message: "One or more input fields are invalid.",
|
|
85
|
+
retryable: false,
|
|
86
|
+
suggestion: "Correct the invalid fields and try again.",
|
|
87
|
+
details: { issues },
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
meta: createResponseMeta({ query: {} }),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function buildMappedErrorResponse(input, code, message, details, retryable) {
|
|
94
|
+
const query = { ...input };
|
|
95
|
+
if (code === "FILE_NOT_FOUND") {
|
|
96
|
+
return {
|
|
97
|
+
tool: TOOL_NAME,
|
|
98
|
+
status: "error",
|
|
99
|
+
summary: "Path not found.",
|
|
100
|
+
data: emptyData(input.path, input.symbol),
|
|
101
|
+
errors: [
|
|
102
|
+
{
|
|
103
|
+
code,
|
|
104
|
+
message,
|
|
105
|
+
retryable,
|
|
106
|
+
suggestion: "Provide an existing file path inside the workspace root.",
|
|
107
|
+
details,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
meta: createResponseMeta({ query }),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (code === "PATH_OUTSIDE_WORKSPACE") {
|
|
114
|
+
return {
|
|
115
|
+
tool: TOOL_NAME,
|
|
116
|
+
status: "error",
|
|
117
|
+
summary: "Path validation failed.",
|
|
118
|
+
data: emptyData(input.path, input.symbol),
|
|
119
|
+
errors: [
|
|
120
|
+
{
|
|
121
|
+
code,
|
|
122
|
+
message,
|
|
123
|
+
retryable,
|
|
124
|
+
suggestion: "Use a file path inside the workspace root.",
|
|
125
|
+
details,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
meta: createResponseMeta({ query }),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (code === "UNSUPPORTED_CAPABILITY") {
|
|
132
|
+
return {
|
|
133
|
+
tool: TOOL_NAME,
|
|
134
|
+
status: "error",
|
|
135
|
+
summary: "Symbol trace failed.",
|
|
136
|
+
data: emptyData(input.path, input.symbol),
|
|
137
|
+
errors: [
|
|
138
|
+
{
|
|
139
|
+
code: "BACKEND_EXECUTION_FAILED",
|
|
140
|
+
message,
|
|
141
|
+
retryable,
|
|
142
|
+
suggestion: "Verify the engine supports workspace.trace_symbol and retry.",
|
|
143
|
+
details,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
meta: createResponseMeta({ query }),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
tool: TOOL_NAME,
|
|
151
|
+
status: "error",
|
|
152
|
+
summary: "Symbol trace failed.",
|
|
153
|
+
data: emptyData(input.path, input.symbol),
|
|
154
|
+
errors: [
|
|
155
|
+
{
|
|
156
|
+
code,
|
|
157
|
+
message,
|
|
158
|
+
retryable,
|
|
159
|
+
details,
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
meta: createResponseMeta({ query }),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function buildEngineFailureResponse(input, error) {
|
|
166
|
+
return buildMappedErrorResponse(input, "BACKEND_EXECUTION_FAILED", error instanceof Error ? error.message : String(error), {}, false);
|
|
167
|
+
}
|
|
168
|
+
function emptyData(path = "", symbol = "") {
|
|
169
|
+
return {
|
|
170
|
+
entrypoint: {
|
|
171
|
+
path,
|
|
172
|
+
symbol,
|
|
173
|
+
language: inferLanguageFromPath(path),
|
|
174
|
+
},
|
|
175
|
+
fileCount: 0,
|
|
176
|
+
items: [],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function buildSummary(symbol, path, fileCount) {
|
|
180
|
+
if (fileCount === 0) {
|
|
181
|
+
return `Trace completed for '${symbol}' from '${path}' with no related files found.`;
|
|
182
|
+
}
|
|
183
|
+
if (fileCount === 1) {
|
|
184
|
+
return `Traced 1 related file for '${symbol}' from '${path}'.`;
|
|
185
|
+
}
|
|
186
|
+
return `Traced ${fileCount} related files for '${symbol}' from '${path}'.`;
|
|
187
|
+
}
|
|
188
|
+
function resolveEffectiveLanguage(language, framework) {
|
|
189
|
+
if (language) {
|
|
190
|
+
return language;
|
|
191
|
+
}
|
|
192
|
+
if (framework === "react-router") {
|
|
193
|
+
return "typescript";
|
|
194
|
+
}
|
|
195
|
+
if (framework === "spring") {
|
|
196
|
+
return "java";
|
|
197
|
+
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
function resolveAnalyzerLanguage(language, framework) {
|
|
201
|
+
const effective = resolveEffectiveLanguage(language, framework);
|
|
202
|
+
if (effective === "java") {
|
|
203
|
+
return "java";
|
|
204
|
+
}
|
|
205
|
+
if (effective === "python") {
|
|
206
|
+
return "python";
|
|
207
|
+
}
|
|
208
|
+
if (effective === "rust") {
|
|
209
|
+
return "rust";
|
|
210
|
+
}
|
|
211
|
+
return "typescript";
|
|
212
|
+
}
|
|
213
|
+
function inferLanguageFromPath(path) {
|
|
214
|
+
const normalized = path.toLowerCase();
|
|
215
|
+
if (normalized.endsWith(".ts") || normalized.endsWith(".tsx")) {
|
|
216
|
+
return "typescript";
|
|
217
|
+
}
|
|
218
|
+
if (normalized.endsWith(".js") || normalized.endsWith(".jsx")) {
|
|
219
|
+
return "javascript";
|
|
220
|
+
}
|
|
221
|
+
if (normalized.endsWith(".java")) {
|
|
222
|
+
return "java";
|
|
223
|
+
}
|
|
224
|
+
if (normalized.endsWith(".py")) {
|
|
225
|
+
return "python";
|
|
226
|
+
}
|
|
227
|
+
if (normalized.endsWith(".rs")) {
|
|
228
|
+
return "rust";
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type CodeToolName } from "../contracts/public/code.ts";
|
|
2
|
+
import type { ResponseEnvelope } from "../contracts/public/common.ts";
|
|
3
|
+
import * as z from "zod/v4";
|
|
4
|
+
export interface RegisteredCodeTool {
|
|
5
|
+
name: CodeToolName;
|
|
6
|
+
title: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputSchema: Record<string, unknown>;
|
|
9
|
+
sdkInputSchema: Record<string, z.ZodType>;
|
|
10
|
+
execute(payload: Record<string, unknown>): Promise<ResponseEnvelope<unknown>>;
|
|
11
|
+
}
|
|
12
|
+
export interface RegisterCodeToolsOptions {
|
|
13
|
+
inspectTreeHandler?: (payload: Record<string, unknown>) => Promise<ResponseEnvelope<unknown>>;
|
|
14
|
+
findSymbolHandler?: (payload: Record<string, unknown>) => Promise<ResponseEnvelope<unknown>>;
|
|
15
|
+
listEndpointsHandler?: (payload: Record<string, unknown>) => Promise<ResponseEnvelope<unknown>>;
|
|
16
|
+
searchTextHandler?: (payload: Record<string, unknown>) => Promise<ResponseEnvelope<unknown>>;
|
|
17
|
+
traceCallersHandler?: (payload: Record<string, unknown>) => Promise<ResponseEnvelope<unknown>>;
|
|
18
|
+
traceSymbolHandler?: (payload: Record<string, unknown>) => Promise<ResponseEnvelope<unknown>>;
|
|
19
|
+
}
|
|
20
|
+
export declare function registerCodeTools(options: RegisterCodeToolsOptions): RegisteredCodeTool[];
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { codeToolSchemas, MATCH_MODES, PUBLIC_ENDPOINT_KINDS, PUBLIC_FRAMEWORKS, PUBLIC_LANGUAGES, PUBLIC_SYMBOL_KINDS, } from "../contracts/public/code.js";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
const toolMetadata = [
|
|
4
|
+
{
|
|
5
|
+
name: "code.inspect_tree",
|
|
6
|
+
title: "Inspect workspace tree",
|
|
7
|
+
description: "Inspect the workspace file tree without reading file contents. Supports path scoping, depth limits, extension filters, filename globs, and optional stats.",
|
|
8
|
+
inputSchema: { ...codeToolSchemas["code.inspect_tree"] },
|
|
9
|
+
sdkInputSchema: {
|
|
10
|
+
path: z
|
|
11
|
+
.string()
|
|
12
|
+
.nullable()
|
|
13
|
+
.optional()
|
|
14
|
+
.default(null)
|
|
15
|
+
.describe("Optional workspace-relative or absolute file/directory scope."),
|
|
16
|
+
max_depth: z
|
|
17
|
+
.int()
|
|
18
|
+
.min(0)
|
|
19
|
+
.max(20)
|
|
20
|
+
.optional()
|
|
21
|
+
.default(3)
|
|
22
|
+
.describe("Maximum depth relative to the resolved scope root."),
|
|
23
|
+
extensions: z
|
|
24
|
+
.array(z.string())
|
|
25
|
+
.nullable()
|
|
26
|
+
.optional()
|
|
27
|
+
.default(null)
|
|
28
|
+
.describe("Optional file extension filter such as ['.py', '.ts']. Directories remain visible."),
|
|
29
|
+
file_pattern: z
|
|
30
|
+
.string()
|
|
31
|
+
.nullable()
|
|
32
|
+
.optional()
|
|
33
|
+
.default(null)
|
|
34
|
+
.describe("Optional filename glob such as '*.py'."),
|
|
35
|
+
include_stats: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.optional()
|
|
38
|
+
.default(false)
|
|
39
|
+
.describe("Include size, modified time, and symlink metadata."),
|
|
40
|
+
include_hidden: z
|
|
41
|
+
.boolean()
|
|
42
|
+
.optional()
|
|
43
|
+
.default(false)
|
|
44
|
+
.describe("Include hidden entries except the hard ignore list."),
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "code.list_endpoints",
|
|
49
|
+
title: "List endpoints and routes",
|
|
50
|
+
description: "List backend endpoints and frontend routes in the workspace. Supports path scoping plus language, framework, kind, and limit filters.",
|
|
51
|
+
inputSchema: { ...codeToolSchemas["code.list_endpoints"] },
|
|
52
|
+
sdkInputSchema: {
|
|
53
|
+
path: z.string().nullable().optional().default(null),
|
|
54
|
+
language: z.enum(PUBLIC_LANGUAGES).nullable().optional().default(null),
|
|
55
|
+
framework: z.enum(PUBLIC_FRAMEWORKS).nullable().optional().default(null),
|
|
56
|
+
kind: z.enum(PUBLIC_ENDPOINT_KINDS).optional().default("any"),
|
|
57
|
+
limit: z.int().min(1).max(200).optional().default(50),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "code.find_symbol",
|
|
62
|
+
title: "Find symbol definitions",
|
|
63
|
+
description: "Locate symbol definitions in the workspace by name. Supports exact or fuzzy matching, path scoping, and language/framework/kind filtering.",
|
|
64
|
+
inputSchema: { ...codeToolSchemas["code.find_symbol"] },
|
|
65
|
+
sdkInputSchema: {
|
|
66
|
+
symbol: z.string().trim().min(1),
|
|
67
|
+
language: z.enum(PUBLIC_LANGUAGES).nullable().optional().default(null),
|
|
68
|
+
framework: z.enum(PUBLIC_FRAMEWORKS).nullable().optional().default(null),
|
|
69
|
+
kind: z.enum(PUBLIC_SYMBOL_KINDS).optional().default("any"),
|
|
70
|
+
match: z.enum(MATCH_MODES).optional().default("exact"),
|
|
71
|
+
path: z.string().nullable().optional().default(null),
|
|
72
|
+
limit: z.int().min(1).max(200).optional().default(50),
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "code.search_text",
|
|
77
|
+
title: "Search text",
|
|
78
|
+
description: "Search text or regex patterns across the workspace with file, language, path, and context controls.",
|
|
79
|
+
inputSchema: { ...codeToolSchemas["code.search_text"] },
|
|
80
|
+
sdkInputSchema: {
|
|
81
|
+
query: z.string().trim().min(1),
|
|
82
|
+
path: z.string().nullable().optional().default(null),
|
|
83
|
+
language: z.enum(PUBLIC_LANGUAGES).nullable().optional().default(null),
|
|
84
|
+
framework: z.enum(PUBLIC_FRAMEWORKS).nullable().optional().default(null),
|
|
85
|
+
include: z.string().nullable().optional().default(null),
|
|
86
|
+
regex: z.boolean().optional().default(false),
|
|
87
|
+
context: z.int().min(0).max(10).optional().default(1),
|
|
88
|
+
limit: z.int().min(1).max(200).optional().default(50),
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "code.trace_symbol",
|
|
93
|
+
title: "Trace symbol forward",
|
|
94
|
+
description: "Trace a symbol forward from a starting file to related workspace files. The starting path must exist inside the workspace.",
|
|
95
|
+
inputSchema: { ...codeToolSchemas["code.trace_symbol"] },
|
|
96
|
+
sdkInputSchema: {
|
|
97
|
+
path: z.string().trim().min(1),
|
|
98
|
+
symbol: z.string().trim().min(1),
|
|
99
|
+
language: z.enum(PUBLIC_LANGUAGES).nullable().optional().default(null),
|
|
100
|
+
framework: z.enum(PUBLIC_FRAMEWORKS).nullable().optional().default(null),
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "code.trace_callers",
|
|
105
|
+
title: "Trace incoming callers",
|
|
106
|
+
description: "Trace incoming callers for a symbol from a starting file. Recursive mode supports reverse traversal up to a bounded max_depth and may return a partial response for safety.",
|
|
107
|
+
inputSchema: { ...codeToolSchemas["code.trace_callers"] },
|
|
108
|
+
sdkInputSchema: {
|
|
109
|
+
path: z.string().trim().min(1),
|
|
110
|
+
symbol: z.string().trim().min(1),
|
|
111
|
+
language: z.enum(PUBLIC_LANGUAGES).nullable().optional().default(null),
|
|
112
|
+
framework: z.enum(PUBLIC_FRAMEWORKS).nullable().optional().default(null),
|
|
113
|
+
recursive: z.boolean().optional().default(false),
|
|
114
|
+
max_depth: z.int().min(1).max(8).nullable().optional().default(null),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
export function registerCodeTools(options) {
|
|
119
|
+
return toolMetadata.map((tool) => {
|
|
120
|
+
if (tool.name === "code.inspect_tree") {
|
|
121
|
+
return {
|
|
122
|
+
...tool,
|
|
123
|
+
execute: async (payload) => {
|
|
124
|
+
if (!options.inspectTreeHandler) {
|
|
125
|
+
throw new Error("Inspect tree migrated handler is scaffolded but not yet wired.");
|
|
126
|
+
}
|
|
127
|
+
return options.inspectTreeHandler(payload);
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (tool.name === "code.find_symbol") {
|
|
132
|
+
return {
|
|
133
|
+
...tool,
|
|
134
|
+
execute: async (payload) => {
|
|
135
|
+
if (!options.findSymbolHandler) {
|
|
136
|
+
throw new Error("Find symbol migrated handler is scaffolded but not yet wired.");
|
|
137
|
+
}
|
|
138
|
+
return options.findSymbolHandler(payload);
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (tool.name === "code.list_endpoints") {
|
|
143
|
+
return {
|
|
144
|
+
...tool,
|
|
145
|
+
execute: async (payload) => {
|
|
146
|
+
if (!options.listEndpointsHandler) {
|
|
147
|
+
throw new Error("List endpoints migrated handler is scaffolded but not yet wired.");
|
|
148
|
+
}
|
|
149
|
+
return options.listEndpointsHandler(payload);
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (tool.name === "code.search_text") {
|
|
154
|
+
return {
|
|
155
|
+
...tool,
|
|
156
|
+
execute: async (payload) => {
|
|
157
|
+
if (!options.searchTextHandler) {
|
|
158
|
+
throw new Error("Search text migrated handler is scaffolded but not yet wired.");
|
|
159
|
+
}
|
|
160
|
+
return options.searchTextHandler(payload);
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (tool.name === "code.trace_symbol") {
|
|
165
|
+
return {
|
|
166
|
+
...tool,
|
|
167
|
+
execute: async (payload) => {
|
|
168
|
+
if (!options.traceSymbolHandler) {
|
|
169
|
+
throw new Error("Trace symbol migrated handler is scaffolded but not yet wired.");
|
|
170
|
+
}
|
|
171
|
+
return options.traceSymbolHandler(payload);
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (tool.name === "code.trace_callers") {
|
|
176
|
+
return {
|
|
177
|
+
...tool,
|
|
178
|
+
execute: async (payload) => {
|
|
179
|
+
if (!options.traceCallersHandler) {
|
|
180
|
+
throw new Error("Trace callers migrated handler is scaffolded but not yet wired.");
|
|
181
|
+
}
|
|
182
|
+
return options.traceCallersHandler(payload);
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
throw new Error(`Tool '${tool.name}' is not implemented.`);
|
|
187
|
+
});
|
|
188
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@navigation-agent/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for AI-assisted code navigation — find symbols, trace callers, list endpoints and more.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"navigation-mcp": "./dist/bin/navigation-mcp.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "node --experimental-strip-types ./src/bin/navigation-mcp.ts --transport stdio",
|
|
20
|
+
"build": "tsc -p tsconfig.build.json && node ../../scripts/add-shebang.mjs dist/bin/navigation-mcp.js",
|
|
21
|
+
"test": "node --experimental-strip-types --test ./test/**/*.spec.ts",
|
|
22
|
+
"check": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"optionalDependencies": {
|
|
25
|
+
"@navigation-agent/mcp-server-linux-x64": "0.1.0",
|
|
26
|
+
"@navigation-agent/mcp-server-linux-arm64": "0.1.0",
|
|
27
|
+
"@navigation-agent/mcp-server-darwin-x64": "0.1.0",
|
|
28
|
+
"@navigation-agent/mcp-server-darwin-arm64": "0.1.0",
|
|
29
|
+
"@navigation-agent/mcp-server-win32-x64": "0.1.0"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
33
|
+
"zod": "^4.3.6"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^22.0.0",
|
|
37
|
+
"typescript": "^5.8.0"
|
|
38
|
+
},
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/j0k3r-dev-rgl/navigation-agent-mcp.git"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"mcp",
|
|
46
|
+
"ai",
|
|
47
|
+
"code-navigation",
|
|
48
|
+
"typescript",
|
|
49
|
+
"rust"
|
|
50
|
+
]
|
|
51
|
+
}
|