/**
* 知識庫工具執行器
*/
import type { ToolResponse } from '@mcp-internal/shared'
import { getGitHubClient, type RepoType } from './client.js'
export const knowledgeToolDefinitions = [
{
name: 'knowledge_search',
description: '搜尋產品知識庫',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: '搜尋關鍵字' },
category: { type: 'string', enum: ['tiles', 'flooring', 'bathroom', 'countertops'], description: '產品分類' },
repo: { type: 'string', enum: ['internal', 'alliance', 'all'], description: '搜尋範圍', default: 'all' },
limit: { type: 'number', description: '返回數量限制', default: 20 },
},
required: ['query'],
},
},
{
name: 'knowledge_get_file',
description: '讀取知識庫檔案內容',
inputSchema: {
type: 'object',
properties: {
repo: { type: 'string', enum: ['internal', 'alliance', 'products'], description: '來源 repo' },
path: { type: 'string', description: '檔案路徑' },
},
required: ['repo', 'path'],
},
},
{
name: 'knowledge_list_directory',
description: '列出知識庫目錄內容',
inputSchema: {
type: 'object',
properties: {
repo: { type: 'string', enum: ['internal', 'alliance', 'products'], description: '來源 repo' },
path: { type: 'string', description: '目錄路徑' },
},
required: ['repo'],
},
},
{
name: 'knowledge_get_price',
description: '查詢產品價格(含成本,僅內部可用)',
inputSchema: {
type: 'object',
properties: {
sku: { type: 'string', description: '產品 SKU' },
},
required: ['sku'],
},
},
{
name: 'knowledge_search_spec',
description: '搜尋產品規格',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: '搜尋關鍵字' },
category: { type: 'string', enum: ['tiles', 'flooring', 'bathroom', 'countertops'], description: '產品分類' },
},
required: ['query'],
},
},
]
export async function executeKnowledgeTool(
toolName: string,
args: any
): Promise<ToolResponse> {
const startTime = Date.now()
const allowedRepos: RepoType[] = ['internal', 'alliance']
try {
const client = await getGitHubClient()
let result: any
switch (toolName) {
case 'knowledge_search': {
let repos: RepoType[] = []
if (args.repo === 'all') {
repos = allowedRepos
} else if (args.repo === 'internal') {
repos = ['internal']
} else if (args.repo === 'alliance') {
repos = ['alliance']
} else {
throw new Error(`無權存取 ${args.repo} repo`)
}
result = await client.searchProducts({
query: args.query,
repos,
category: args.category,
})
break
}
case 'knowledge_get_file': {
const repo = args.repo as RepoType
result = await client.getFileContent({ repo, path: args.path })
break
}
case 'knowledge_list_directory': {
const repo = args.repo as RepoType
result = await client.listDirectory({ repo, path: args.path })
break
}
case 'knowledge_get_price': {
result = await client.getProductPrice(args.sku)
if (!result) {
throw new Error(`找不到 SKU: ${args.sku}`)
}
break
}
case 'knowledge_search_spec': {
result = await client.searchCode({
query: args.query,
repos: allowedRepos,
path: args.category ? `specs/${args.category}` : 'specs',
extension: 'md',
limit: 20,
})
break
}
default:
throw new Error(`未知的知識庫工具: ${toolName}`)
}
return {
success: true,
result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] },
metadata: { executionTimeMs: Date.now() - startTime, tool: toolName, timestamp: new Date().toISOString() },
}
} catch (error) {
return {
success: false,
error: { code: 'EXTERNAL_SERVICE_ERROR', message: error instanceof Error ? error.message : String(error) },
metadata: { executionTimeMs: Date.now() - startTime, tool: toolName, timestamp: new Date().toISOString() },
}
}
}