@byteqa/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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +150 -0
- package/package.json +34 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { createRequire } from "module";
|
|
5
|
+
import { acknowledgeInputSchema, acknowledgeRun, approveInputSchema, approveRun, auditInputSchema, getStatus, retroInputSchema, runAudit, runRetro, statusInputSchema, validateArtifacts, validateInputSchema } from "@byteqa/core";
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
const pkg = createRequire(import.meta.url)("../package.json");
|
|
8
|
+
function resolveTargetPath(input) {
|
|
9
|
+
if (typeof input.targetPath === "string" && input.targetPath.length > 0) return input.targetPath;
|
|
10
|
+
const envTarget = process.env.BYTEQA_TARGET;
|
|
11
|
+
if (typeof envTarget === "string" && envTarget.length > 0) return envTarget;
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
function missingTargetError() {
|
|
15
|
+
return {
|
|
16
|
+
content: [{
|
|
17
|
+
type: "text",
|
|
18
|
+
text: "byteqa error: targetPath is required. Provide it as a tool input or set the BYTEQA_TARGET environment variable."
|
|
19
|
+
}],
|
|
20
|
+
isError: true
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function errorResponse(err) {
|
|
24
|
+
return {
|
|
25
|
+
content: [{
|
|
26
|
+
type: "text",
|
|
27
|
+
text: `byteqa error: ${err instanceof Error ? err.message : String(err)}`
|
|
28
|
+
}],
|
|
29
|
+
isError: true
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const server = new McpServer({
|
|
33
|
+
name: "byteqa-local",
|
|
34
|
+
version: pkg.version
|
|
35
|
+
});
|
|
36
|
+
server.tool("byteqa_audit", "Run the full byteQA loop — scan, audit, security, performance, checker review. Writes .qa/ into targetPath. Returns structured result with status, bugs, escalations, writeBoundary, and nextAction.", auditInputSchema.shape, async (input) => {
|
|
37
|
+
const targetPath = resolveTargetPath(input);
|
|
38
|
+
if (!targetPath) return missingTargetError();
|
|
39
|
+
try {
|
|
40
|
+
const result = await runAudit({
|
|
41
|
+
targetPath,
|
|
42
|
+
maxLoops: input.maxLoops
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
content: [{
|
|
46
|
+
type: "text",
|
|
47
|
+
text: `byteqa audit complete.\nStatus: ${result.status}\nNext action: ${result.nextAction}\nBugs: critical=${result.bugCount.critical} high=${result.bugCount.high} medium=${result.bugCount.medium} low=${result.bugCount.low}\nEscalated: ${result.escalatedBugIds.join(", ") || "none"}\nPending actions: ${result.pendingHumanActions.join("; ") || "none"}`
|
|
48
|
+
}],
|
|
49
|
+
structuredContent: result
|
|
50
|
+
};
|
|
51
|
+
} catch (err) {
|
|
52
|
+
return errorResponse(err);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
server.tool("byteqa_status", "Read the current status of the latest byteQA run. Read-only — never writes files. Returns STATUS, bug summary, pending human actions, and unacted prompt lessons.", statusInputSchema.shape, async (input) => {
|
|
56
|
+
const targetPath = resolveTargetPath(input);
|
|
57
|
+
if (!targetPath) return missingTargetError();
|
|
58
|
+
try {
|
|
59
|
+
const result = await getStatus({ targetPath });
|
|
60
|
+
return {
|
|
61
|
+
content: [{
|
|
62
|
+
type: "text",
|
|
63
|
+
text: `byteqa status.\nRun: ${result.runId}\nStatus: ${result.status}\nPending actions: ${result.pendingHumanActions.join("; ") || "none"}`
|
|
64
|
+
}],
|
|
65
|
+
structuredContent: result
|
|
66
|
+
};
|
|
67
|
+
} catch (err) {
|
|
68
|
+
return errorResponse(err);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
server.tool("byteqa_approve", "Approve bugs for dev handoff. Human-facing operation. Writes approval.md and triggers dev-handoff creation when approvedForDev=true.", approveInputSchema.shape, async (input) => {
|
|
72
|
+
const targetPath = resolveTargetPath(input);
|
|
73
|
+
if (!targetPath) return missingTargetError();
|
|
74
|
+
try {
|
|
75
|
+
const result = await approveRun({
|
|
76
|
+
targetPath,
|
|
77
|
+
bugIds: input.bugIds,
|
|
78
|
+
approvedForDev: input.approvedForDev,
|
|
79
|
+
notes: input.notes
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
content: [{
|
|
83
|
+
type: "text",
|
|
84
|
+
text: `byteqa approve complete.\nApproved bug IDs: ${result.approvedBugIds.join(", ") || "none"}\nDev handoff created: ${result.devHandoffCreated}\nNext action: ${result.nextAction}`
|
|
85
|
+
}],
|
|
86
|
+
structuredContent: result
|
|
87
|
+
};
|
|
88
|
+
} catch (err) {
|
|
89
|
+
return errorResponse(err);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
server.tool("byteqa_acknowledge", "Acknowledge pending human actions. Clears PENDING_HUMAN_ACTIONS and stamps HUMAN_ACKNOWLEDGED_AT so the morning digest does not replay cleared items.", acknowledgeInputSchema.shape, async (input) => {
|
|
93
|
+
const targetPath = resolveTargetPath(input);
|
|
94
|
+
if (!targetPath) return missingTargetError();
|
|
95
|
+
try {
|
|
96
|
+
const result = await acknowledgeRun({ targetPath });
|
|
97
|
+
return {
|
|
98
|
+
content: [{
|
|
99
|
+
type: "text",
|
|
100
|
+
text: `byteqa acknowledge complete.\nCleared actions: ${result.clearedActions}\nAcknowledged at: ${result.acknowledgedAt}`
|
|
101
|
+
}],
|
|
102
|
+
structuredContent: result
|
|
103
|
+
};
|
|
104
|
+
} catch (err) {
|
|
105
|
+
return errorResponse(err);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
server.tool("byteqa_validate", "Validate .qa/ artifacts against byteQA schemas. Read-only. Reports malformed or missing required files. Pass artifact to validate a specific file, omit to validate all.", validateInputSchema.shape, async (input) => {
|
|
109
|
+
const targetPath = resolveTargetPath(input);
|
|
110
|
+
if (!targetPath) return missingTargetError();
|
|
111
|
+
try {
|
|
112
|
+
const result = await validateArtifacts({
|
|
113
|
+
targetPath,
|
|
114
|
+
artifact: input.artifact
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
content: [{
|
|
118
|
+
type: "text",
|
|
119
|
+
text: `byteqa validate complete.\nValid: ${result.valid}\nErrors: ${result.errors.length}\nWarnings: ${result.warnings.length}`
|
|
120
|
+
}],
|
|
121
|
+
structuredContent: result
|
|
122
|
+
};
|
|
123
|
+
} catch (err) {
|
|
124
|
+
return errorResponse(err);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
server.tool("byteqa_retro", "Analyse the last N byteQA runs and surface patterns: recurring bug types, gate failure trends, Checker escalation rate, verification pass rate. Read-only.", retroInputSchema.shape, async (input) => {
|
|
128
|
+
const targetPath = resolveTargetPath(input);
|
|
129
|
+
if (!targetPath) return missingTargetError();
|
|
130
|
+
try {
|
|
131
|
+
const result = await runRetro({
|
|
132
|
+
targetPath,
|
|
133
|
+
lastNRuns: input.lastNRuns,
|
|
134
|
+
restoreSkill: input.restoreSkill
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
content: [{
|
|
138
|
+
type: "text",
|
|
139
|
+
text: `byteqa retro complete.\nRuns analysed: ${result.runsAnalyzed}\nVerification pass rate: ${result.verificationPassRate}\nChecker escalation rate: ${result.checkerEscalationRate}`
|
|
140
|
+
}],
|
|
141
|
+
structuredContent: result
|
|
142
|
+
};
|
|
143
|
+
} catch (err) {
|
|
144
|
+
return errorResponse(err);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
const transport = new StdioServerTransport();
|
|
148
|
+
await server.connect(transport);
|
|
149
|
+
//#endregion
|
|
150
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@byteqa/mcp",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "byteQA local MCP stdio server — adapter over @byteqa/core. Binary: byteqa-mcp.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"byteqa-mcp": "./dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"../../README.md"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"module": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsdown",
|
|
27
|
+
"prepublishOnly": "tsdown"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@byteqa/core": "1.0.1",
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
32
|
+
"zod": "^4.4.3"
|
|
33
|
+
}
|
|
34
|
+
}
|