mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
mcp
This commit is contained in:
@@ -44,5 +44,11 @@
|
|||||||
"Bash(for comp in GitHubBuildStatus LazyD3BarChart StorageSettings LoadingFallback NavigationItem PageHeaderContent SaveIndicator SeedDataManager TreeCard)",
|
"Bash(for comp in GitHubBuildStatus LazyD3BarChart StorageSettings LoadingFallback NavigationItem PageHeaderContent SaveIndicator SeedDataManager TreeCard)",
|
||||||
"Bash(do grep -r \"from ''@/components/molecules/$comp''\" src/ --files-with-matches)"
|
"Bash(do grep -r \"from ''@/components/molecules/$comp''\" src/ --files-with-matches)"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"mcpServers": {
|
||||||
|
"codeql": {
|
||||||
|
"command": "node",
|
||||||
|
"args": ["scripts/mcp/codeql-mcp.js"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
259
scripts/mcp/codeql-mcp.js
Normal file
259
scripts/mcp/codeql-mcp.js
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const { spawn } = require('node:child_process')
|
||||||
|
|
||||||
|
function send(message) {
|
||||||
|
process.stdout.write(`${JSON.stringify(message)}\n`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function respond(id, result) {
|
||||||
|
send({ jsonrpc: '2.0', id, result })
|
||||||
|
}
|
||||||
|
|
||||||
|
function respondError(id, code, message) {
|
||||||
|
send({ jsonrpc: '2.0', id, error: { code, message } })
|
||||||
|
}
|
||||||
|
|
||||||
|
function toolList() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'codeql_analyze',
|
||||||
|
description: 'Run CodeQL database analyze with a query pack.',
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
dbPath: { type: 'string' },
|
||||||
|
queryPack: { type: 'string' },
|
||||||
|
output: { type: 'string' },
|
||||||
|
format: { type: 'string', default: 'sarifv2.1.0' },
|
||||||
|
rerun: { type: 'boolean', default: false },
|
||||||
|
extraArgs: { type: 'array', items: { type: 'string' } },
|
||||||
|
},
|
||||||
|
required: ['dbPath', 'queryPack'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'codeql_database_create',
|
||||||
|
description: 'Create a CodeQL database.',
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
dbPath: { type: 'string' },
|
||||||
|
language: { type: 'string', default: 'javascript' },
|
||||||
|
sourceRoot: { type: 'string', default: '.' },
|
||||||
|
buildMode: { type: 'string', default: 'none' },
|
||||||
|
extraArgs: { type: 'array', items: { type: 'string' } },
|
||||||
|
},
|
||||||
|
required: ['dbPath'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'codeql_pack_install',
|
||||||
|
description: 'Install dependencies for a local CodeQL pack.',
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
packDir: { type: 'string' },
|
||||||
|
extraArgs: { type: 'array', items: { type: 'string' } },
|
||||||
|
},
|
||||||
|
required: ['packDir'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'codeql_pack_download',
|
||||||
|
description: 'Download a CodeQL pack by name.',
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
pack: { type: 'string' },
|
||||||
|
extraArgs: { type: 'array', items: { type: 'string' } },
|
||||||
|
},
|
||||||
|
required: ['pack'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'codeql_resolve_packs',
|
||||||
|
description: 'List available CodeQL packs.',
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
extraArgs: { type: 'array', items: { type: 'string' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'codeql_resolve_languages',
|
||||||
|
description: 'List available CodeQL languages.',
|
||||||
|
inputSchema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
extraArgs: { type: 'array', items: { type: 'string' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCodeql(args, options = {}) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const proc = spawn('codeql', args, { stdio: ['ignore', 'pipe', 'pipe'], ...options })
|
||||||
|
let stdout = ''
|
||||||
|
let stderr = ''
|
||||||
|
|
||||||
|
proc.stdout.on('data', (chunk) => {
|
||||||
|
stdout += chunk.toString()
|
||||||
|
})
|
||||||
|
proc.stderr.on('data', (chunk) => {
|
||||||
|
stderr += chunk.toString()
|
||||||
|
})
|
||||||
|
|
||||||
|
proc.on('error', (err) => reject(err))
|
||||||
|
proc.on('close', (code) => {
|
||||||
|
resolve({ code, stdout, stderr, args })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCodeqlAnalyze(input) {
|
||||||
|
const {
|
||||||
|
dbPath,
|
||||||
|
queryPack,
|
||||||
|
output,
|
||||||
|
format = 'sarifv2.1.0',
|
||||||
|
rerun = false,
|
||||||
|
extraArgs = [],
|
||||||
|
} = input || {}
|
||||||
|
|
||||||
|
if (!dbPath || !queryPack) {
|
||||||
|
return Promise.reject(new Error('dbPath and queryPack are required'))
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = ['database', 'analyze', dbPath, queryPack, `--format=${format}`]
|
||||||
|
if (output) args.push(`--output=${output}`)
|
||||||
|
if (rerun) args.push('--rerun')
|
||||||
|
if (Array.isArray(extraArgs)) args.push(...extraArgs)
|
||||||
|
|
||||||
|
return runCodeql(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCodeqlDatabaseCreate(input) {
|
||||||
|
const {
|
||||||
|
dbPath,
|
||||||
|
language = 'javascript',
|
||||||
|
sourceRoot = '.',
|
||||||
|
buildMode = 'none',
|
||||||
|
extraArgs = [],
|
||||||
|
} = input || {}
|
||||||
|
|
||||||
|
if (!dbPath) {
|
||||||
|
return Promise.reject(new Error('dbPath is required'))
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = [
|
||||||
|
'database',
|
||||||
|
'create',
|
||||||
|
dbPath,
|
||||||
|
`--language=${language}`,
|
||||||
|
`--source-root=${sourceRoot}`,
|
||||||
|
`--build-mode`,
|
||||||
|
buildMode,
|
||||||
|
]
|
||||||
|
if (Array.isArray(extraArgs)) args.push(...extraArgs)
|
||||||
|
return runCodeql(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCodeqlPackInstall(input) {
|
||||||
|
const { packDir, extraArgs = [] } = input || {}
|
||||||
|
if (!packDir) return Promise.reject(new Error('packDir is required'))
|
||||||
|
const args = ['pack', 'install']
|
||||||
|
if (Array.isArray(extraArgs)) args.push(...extraArgs)
|
||||||
|
return runCodeql(args, { cwd: packDir })
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCodeqlPackDownload(input) {
|
||||||
|
const { pack, extraArgs = [] } = input || {}
|
||||||
|
if (!pack) return Promise.reject(new Error('pack is required'))
|
||||||
|
const args = ['pack', 'download', pack]
|
||||||
|
if (Array.isArray(extraArgs)) args.push(...extraArgs)
|
||||||
|
return runCodeql(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCodeqlResolvePacks(input) {
|
||||||
|
const { extraArgs = [] } = input || {}
|
||||||
|
const args = ['resolve', 'packs']
|
||||||
|
if (Array.isArray(extraArgs)) args.push(...extraArgs)
|
||||||
|
return runCodeql(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCodeqlResolveLanguages(input) {
|
||||||
|
const { extraArgs = [] } = input || {}
|
||||||
|
const args = ['resolve', 'languages']
|
||||||
|
if (Array.isArray(extraArgs)) args.push(...extraArgs)
|
||||||
|
return runCodeql(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleRequest(message) {
|
||||||
|
const { id, method, params } = message
|
||||||
|
|
||||||
|
if (method === 'initialize') {
|
||||||
|
return respond(id, {
|
||||||
|
capabilities: { tools: { list: true, call: true } },
|
||||||
|
serverInfo: { name: 'codeql-mcp', version: '0.1.0' },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method === 'tools/list') {
|
||||||
|
return respond(id, { tools: toolList() })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method === 'tools/call') {
|
||||||
|
const { name, arguments: args } = params || {}
|
||||||
|
try {
|
||||||
|
let result
|
||||||
|
if (name === 'codeql_analyze') {
|
||||||
|
result = await runCodeqlAnalyze(args)
|
||||||
|
} else if (name === 'codeql_database_create') {
|
||||||
|
result = await runCodeqlDatabaseCreate(args)
|
||||||
|
} else if (name === 'codeql_pack_install') {
|
||||||
|
result = await runCodeqlPackInstall(args)
|
||||||
|
} else if (name === 'codeql_pack_download') {
|
||||||
|
result = await runCodeqlPackDownload(args)
|
||||||
|
} else if (name === 'codeql_resolve_packs') {
|
||||||
|
result = await runCodeqlResolvePacks(args)
|
||||||
|
} else if (name === 'codeql_resolve_languages') {
|
||||||
|
result = await runCodeqlResolveLanguages(args)
|
||||||
|
} else {
|
||||||
|
return respondError(id, -32601, `Unknown tool: ${name}`)
|
||||||
|
}
|
||||||
|
return respond(id, {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: `exit: ${result.code}\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
return respondError(id, -32603, err.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return respondError(id, -32601, `Unknown method: ${method}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let buffer = ''
|
||||||
|
process.stdin.setEncoding('utf8')
|
||||||
|
process.stdin.on('data', (chunk) => {
|
||||||
|
buffer += chunk
|
||||||
|
let idx
|
||||||
|
while ((idx = buffer.indexOf('\n')) >= 0) {
|
||||||
|
const line = buffer.slice(0, idx).trim()
|
||||||
|
buffer = buffer.slice(idx + 1)
|
||||||
|
if (!line) continue
|
||||||
|
try {
|
||||||
|
const message = JSON.parse(line)
|
||||||
|
handleRequest(message)
|
||||||
|
} catch (err) {
|
||||||
|
respondError(null, -32700, 'Invalid JSON')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user