@lorrylurui/code-intelligence-mcp 1.0.1

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.
@@ -0,0 +1,55 @@
1
+ // 按结构字段检索(匹配 meta.props / meta.params / meta.properties / meta.hooks)
2
+ import { z } from "zod";
3
+ import { rankSymbols } from "../services/ranking.js";
4
+ export const searchByStructureInput = z.object({
5
+ fields: z.array(z.string().min(1)).min(1),
6
+ type: z.enum(["component", "util", "selector", "type"]).optional(),
7
+ category: z.string().optional(),
8
+ limit: z.number().int().min(1).max(100).optional().default(20),
9
+ ranked: z.boolean().optional().default(true)
10
+ });
11
+ export function createSearchByStructureTool(repository) {
12
+ return {
13
+ name: "search_by_structure",
14
+ description: "Search symbols by structured fields like props/params/properties/hooks. Use for API-shape queries.",
15
+ inputSchema: searchByStructureInput.shape,
16
+ handler: async (input) => {
17
+ const rows = await repository.searchByStructure(input.fields, {
18
+ type: input.type,
19
+ category: input.category,
20
+ limit: input.limit
21
+ });
22
+ const query = input.fields.join(" ");
23
+ const resultRows = input.ranked
24
+ ? rankSymbols(query, rows).map((item) => ({
25
+ name: item.symbol.name,
26
+ type: item.symbol.type,
27
+ category: item.symbol.category,
28
+ path: item.symbol.path,
29
+ description: item.symbol.description,
30
+ usageCount: item.symbol.usageCount,
31
+ score: item.score,
32
+ reason: item.reason.summary,
33
+ reasonDetail: item.reason,
34
+ meta: item.symbol.meta
35
+ }))
36
+ : rows.map((r) => ({
37
+ name: r.name,
38
+ type: r.type,
39
+ category: r.category,
40
+ path: r.path,
41
+ description: r.description,
42
+ usageCount: r.usageCount,
43
+ meta: r.meta
44
+ }));
45
+ return {
46
+ content: [
47
+ {
48
+ type: "text",
49
+ text: JSON.stringify(resultRows, null, 2)
50
+ }
51
+ ]
52
+ };
53
+ }
54
+ };
55
+ }
@@ -0,0 +1,81 @@
1
+ import { z } from 'zod';
2
+ import { rankSemanticHits, rankSymbols } from '../services/ranking.js';
3
+ export const searchSymbolsInput = z.object({
4
+ query: z.string().min(1),
5
+ type: z.enum(['component', 'util', 'selector', 'type']).optional(),
6
+ ranked: z.boolean().optional().default(true),
7
+ /** Phase 5:自然语言 / 描述句检索(需 EMBEDDING_SERVICE_URL + 索引已写入 embedding) */
8
+ semantic: z.boolean().optional().default(false),
9
+ limit: z.number().int().min(1).max(100).optional().default(20),
10
+ });
11
+ export function createSearchSymbolsTool(repository) {
12
+ return {
13
+ name: 'search_symbols',
14
+ description: '通过关键词和可选的类型搜索代码块。设置 semantic=true 可进行自然语言/意图式搜索(此功能需要 embedding 服务 + 已索引的向量)。',
15
+ inputSchema: searchSymbolsInput.shape,
16
+ handler: async (input) => {
17
+ if (input.semantic) {
18
+ const hits = await repository.searchSemanticHits(input.query, {
19
+ type: input.type,
20
+ limit: input.limit,
21
+ });
22
+ const simById = new Map(hits.map((h) => [h.symbol.id, h.similarity]));
23
+ const resultRows = input.ranked
24
+ ? rankSemanticHits(hits).map((item) => ({
25
+ name: item.symbol.name,
26
+ type: item.symbol.type,
27
+ path: item.symbol.path,
28
+ description: item.symbol.description,
29
+ usageCount: item.symbol.usageCount,
30
+ score: item.score,
31
+ reason: item.reason.summary,
32
+ reasonDetail: item.reason,
33
+ semanticSimilarity: Number((simById.get(item.symbol.id) ?? 0).toFixed(4)),
34
+ }))
35
+ : hits.map((h) => ({
36
+ name: h.symbol.name,
37
+ type: h.symbol.type,
38
+ path: h.symbol.path,
39
+ description: h.symbol.description,
40
+ usageCount: h.symbol.usageCount,
41
+ semanticSimilarity: Number(h.similarity.toFixed(4)),
42
+ }));
43
+ return {
44
+ content: [
45
+ {
46
+ type: 'text',
47
+ text: JSON.stringify(resultRows, null, 2),
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ const rows = await repository.search(input.query, input.type);
53
+ const resultRows = input.ranked
54
+ ? rankSymbols(input.query, rows).map((item) => ({
55
+ name: item.symbol.name,
56
+ type: item.symbol.type,
57
+ path: item.symbol.path,
58
+ description: item.symbol.description,
59
+ usageCount: item.symbol.usageCount,
60
+ score: item.score,
61
+ reason: item.reason.summary,
62
+ reasonDetail: item.reason,
63
+ }))
64
+ : rows.map((r) => ({
65
+ name: r.name,
66
+ type: r.type,
67
+ path: r.path,
68
+ description: r.description,
69
+ usageCount: r.usageCount,
70
+ }));
71
+ return {
72
+ content: [
73
+ {
74
+ type: 'text',
75
+ text: JSON.stringify(resultRows, null, 2),
76
+ },
77
+ ],
78
+ };
79
+ },
80
+ };
81
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@lorrylurui/code-intelligence-mcp",
3
+ "version": "1.0.1",
4
+ "private": false,
5
+ "description": "MCP server for code intelligence with symbol search and reusable code recommendation",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "bin": {
12
+ "code-intelligence-mcp": "./dist/index.js"
13
+ },
14
+ "scripts": {
15
+ "dev": "tsx watch --clear-screen=false --exclude node_modules --exclude dist src/index.ts",
16
+ "dev:mcp": "node ./scripts/mcp-dev-watch.mjs",
17
+ "build": "tsc -p tsconfig.json",
18
+ "start": "node dist/index.js",
19
+ "index": "tsx src/cli/index-codebase.ts",
20
+ "detect-duplicates": "tsx src/cli/detect-duplicates.ts",
21
+ "embedding:dev": "cd embedding-service && python3 -m uvicorn app:app --host 127.0.0.1 --port 8765",
22
+ "docker:up": "docker compose up -d",
23
+ "docker:down": "docker compose down",
24
+ "docker:logs": "docker compose logs -f mysql"
25
+ },
26
+ "dependencies": {
27
+ "@modelcontextprotocol/sdk": "^1.12.3",
28
+ "@types/react": "^19.2.14",
29
+ "dotenv": "^16.4.5",
30
+ "fast-glob": "^3.3.2",
31
+ "mysql2": "^3.11.3",
32
+ "react": "^19.2.4",
33
+ "ts-morph": "^25.0.0",
34
+ "zod": "^3.23.8"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.10.1",
38
+ "tsx": "^4.19.2",
39
+ "typescript": "^5.6.3"
40
+ },
41
+ "publishConfig": {
42
+ "registry": "https://registry.npmjs.org/",
43
+ "access": "public"
44
+ }
45
+ }