103 lines
4.0 KiB
JavaScript
103 lines
4.0 KiB
JavaScript
const { spawn } = require("child_process");
|
|
|
|
const config = "C:\\project\\FT546WMS-SHANDOW\\.cursorrules-mcp.json";
|
|
const database = "FT546-wms";
|
|
|
|
function createClient() {
|
|
const child = spawn("powershell.exe", [
|
|
"-NoProfile", "-ExecutionPolicy", "Bypass", "-File",
|
|
"C:\\project\\sqlserver-mcp-server\\start.ps1",
|
|
"-ConfigPath", config
|
|
], { stdio: ["pipe", "pipe", "pipe"] });
|
|
let buffer = "";
|
|
let nextId = 1;
|
|
const pending = new Map();
|
|
child.stdout.on("data", (chunk) => {
|
|
buffer += chunk.toString();
|
|
const lines = buffer.split(/\r?\n/);
|
|
buffer = lines.pop();
|
|
for (const line of lines) {
|
|
if (!line.trim()) continue;
|
|
try {
|
|
const message = JSON.parse(line);
|
|
const resolve = pending.get(message.id);
|
|
if (resolve) {
|
|
pending.delete(message.id);
|
|
resolve(message);
|
|
}
|
|
} catch {
|
|
// Ignore non-protocol output.
|
|
}
|
|
}
|
|
});
|
|
function call(method, params) {
|
|
return new Promise((resolve, reject) => {
|
|
const id = nextId++;
|
|
pending.set(id, (message) => message.error
|
|
? reject(new Error(message.error.message || "MCP error"))
|
|
: resolve(message.result));
|
|
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
|
|
});
|
|
}
|
|
return { child, call };
|
|
}
|
|
|
|
function parseResult(result) {
|
|
const item = (result.content || []).find((entry) => entry.type === "text");
|
|
if (!item) throw new Error("MCP returned no result text");
|
|
try {
|
|
return JSON.parse(item.text);
|
|
} catch {
|
|
throw new Error(item.text.replace(/password\s*[:=]\s*[^\s,}]+/gi, "password=[redacted]").replace(/\r?\n/g, " "));
|
|
}
|
|
}
|
|
|
|
function quote(value) {
|
|
return String(value ?? "").replaceAll("'", "''");
|
|
}
|
|
|
|
async function main() {
|
|
const client = createClient();
|
|
try {
|
|
await client.call("initialize", {
|
|
protocolVersion: "2025-06-18",
|
|
capabilities: {},
|
|
clientInfo: { name: "ft546-stockout-detail-check", version: "1.0" }
|
|
});
|
|
client.child.stdin.write(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }) + "\n");
|
|
|
|
async function read(query) {
|
|
return parseResult(await client.call("tools/call", {
|
|
name: "sqlserver_read_data",
|
|
arguments: { databaseName: database, query, response_format: "json" }
|
|
}));
|
|
}
|
|
|
|
const detail = await read("SELECT stockout_detail_id, warehouse_id, spare4 AS project_no, product_id FROM dbo.out_stockout_detail WHERE stockout_detail_id = 'CKD202608180003-1'");
|
|
const row = detail.rows?.[0];
|
|
const projectNo = row?.project_no == null ? null : String(row.project_no).trim();
|
|
const productNo = row?.product_id == null ? null : String(row.product_id).trim();
|
|
const projectLiteral = projectNo == null || projectNo === "" ? "NULL" : `'${quote(projectNo)}'`;
|
|
const productConditionLegacy = productNo == null || productNo === "" ? "1 = 1" : `product_id = '${quote(productNo)}'`;
|
|
const productConditionShadow = productNo == null || productNo === "" ? "1 = 1" : `product_no = '${quote(productNo)}'`;
|
|
|
|
const legacy = await read(`SELECT stock_id, warehouse_id, cargo_space_id, tray_code, spare4 AS project_no, product_id, quantity, out_quantity, stock_status, product_status FROM dbo.bas_stock WHERE spare4 = ${projectLiteral} AND ${productConditionLegacy}`);
|
|
const shadow = await read(`SELECT stock_id, space_id, tray_code, project_no, product_no, quantity, out_quantity FROM alg.v_inventory_item WHERE project_no = ${projectLiteral} AND ${productConditionShadow}`);
|
|
const sync = await read("SELECT MAX(synchronized_at) AS latest_shadow_inventory_sync FROM alg.inventory_item_snapshot WHERE warehouse_id = '01'");
|
|
|
|
console.log(JSON.stringify({
|
|
detail: detail.rows || [],
|
|
legacy_stock: legacy.rows || [],
|
|
shadow_inventory: shadow.rows || [],
|
|
latest_sync: sync.rows || []
|
|
}, null, 2));
|
|
} finally {
|
|
client.child.kill();
|
|
}
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error("READONLY_QUERY_FAILED " + error.message);
|
|
process.exitCode = 1;
|
|
});
|