@qulib/mcp 0.11.0 → 0.13.0
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.map +1 -1
- package/dist/index.js +63 -1
- package/package.json +2 -2
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAuqBA,wBAAsB,eAAe,CAAC,KAAK,EAAE;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAsBzD"}
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
15
15
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
16
16
|
const requirePkg = createRequire(import.meta.url);
|
|
17
17
|
const pkg = requirePkg('../package.json');
|
|
18
|
-
import { analyzeApp, detectAuth, exploreAuth, scanRepo, computeAutomationMaturity, scaffoldTests, discoverApiSurfaceWithRepo, computeApiCoverage, computeReleaseConfidence, buildConfidenceInputFromQulib, analyzeRunDiff, loadGapAnalysisFile, detectPromptLeakage, scoreBugReport, scoreDecisions, } from '@qulib/core';
|
|
18
|
+
import { analyzeApp, detectAuth, exploreAuth, scanRepo, computeAutomationMaturity, scaffoldTests, discoverApiSurfaceWithRepo, computeApiCoverage, computeReleaseConfidence, buildConfidenceInputFromQulib, analyzeRunDiff, loadGapAnalysisFile, detectPromptLeakage, scoreBugReport, scoreDecisions, validateSpecConformance, } from '@qulib/core';
|
|
19
19
|
import { RecipeIdSchema } from '@qulib/core';
|
|
20
20
|
import { z } from 'zod';
|
|
21
21
|
import { buildAnalyzeAppMcpPayload } from './analyze-app-mcp-payload.js';
|
|
@@ -678,6 +678,68 @@ mcpServer.registerTool('qulib_score_decisions', {
|
|
|
678
678
|
// No non-prefixed `score_decisions` alias: this is a brand-new tool with no
|
|
679
679
|
// prior integrations to keep compatible, and an unprefixed name is ambiguous
|
|
680
680
|
// and widens the attack surface. The canonical name is qulib_score_decisions.
|
|
681
|
+
// ---------------------------------------------------------------------------
|
|
682
|
+
// qulib_validate_spec — spec-grounded conformance check
|
|
683
|
+
// ---------------------------------------------------------------------------
|
|
684
|
+
const SpecRequirementMcpSchema = z.object({
|
|
685
|
+
id: z.string().min(1).describe('Stable requirement id, e.g. "req-1"'),
|
|
686
|
+
text: z.string().min(1).max(2000).describe('The requirement text (untrusted; max 2000 chars)'),
|
|
687
|
+
});
|
|
688
|
+
const ValidateSpecInputSchema = z.object({
|
|
689
|
+
requirements: z
|
|
690
|
+
.array(SpecRequirementMcpSchema)
|
|
691
|
+
.min(1)
|
|
692
|
+
.max(100)
|
|
693
|
+
.describe('List of requirements to grade (1–100). Each has an id and text.'),
|
|
694
|
+
observed: z.object({
|
|
695
|
+
url: z.string().optional().describe('URL of the app that was observed (informational)'),
|
|
696
|
+
summary: z
|
|
697
|
+
.string()
|
|
698
|
+
.min(1)
|
|
699
|
+
.max(20000)
|
|
700
|
+
.describe('Observed app behavior summary — output from analyze_app, manual description, or any text evidence of what the app does. Untrusted; max 20000 chars.'),
|
|
701
|
+
}),
|
|
702
|
+
enableLlmJudge: z
|
|
703
|
+
.boolean()
|
|
704
|
+
.optional()
|
|
705
|
+
.describe('When true and ANTHROPIC_API_KEY is set, grade each requirement with the pinned LLM judge. ' +
|
|
706
|
+
'Default false: all requirements return conforms=unknown and verdict=insufficient-evidence ' +
|
|
707
|
+
'(honesty — never fabricates without the judge).'),
|
|
708
|
+
});
|
|
709
|
+
const VALIDATE_SPEC_DESCRIPTION = 'Grade whether a deployed app\'s OBSERVED behavior conforms to a SUPPLIED spec (PRD / requirements). ' +
|
|
710
|
+
'Not "does it crash" — "does it match intent." ' +
|
|
711
|
+
'For each requirement, returns conforms (yes/no/unknown), confidence (0–1), rationale, and scoringPath. ' +
|
|
712
|
+
'Aggregates into a verdict (conforms / partial / violates / insufficient-evidence) and conformanceRate. ' +
|
|
713
|
+
'Without ANTHROPIC_API_KEY or enableLlmJudge=true, all requirements return unknown (honest: no fabricated verdicts). ' +
|
|
714
|
+
'Requirement text and observed summary are UNTRUSTED — prompt-injection hardened. Read-only; no network egress beyond the pinned judge.';
|
|
715
|
+
mcpServer.registerTool('qulib_validate_spec', {
|
|
716
|
+
description: VALIDATE_SPEC_DESCRIPTION,
|
|
717
|
+
inputSchema: ValidateSpecInputSchema,
|
|
718
|
+
}, async (input) => {
|
|
719
|
+
try {
|
|
720
|
+
log.info(`qulib_validate_spec requirements=${input.requirements.length} enableLlmJudge=${input.enableLlmJudge ?? false}`);
|
|
721
|
+
const result = await validateSpecConformance(input);
|
|
722
|
+
log.info(`qulib_validate_spec done verdict=${result.verdict} conformanceRate=${result.conformanceRate} unmet=${result.unmet.length}`);
|
|
723
|
+
return {
|
|
724
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
catch (err) {
|
|
728
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
729
|
+
// Classify input validation errors — never leak a stack trace.
|
|
730
|
+
if (msg.includes('String must contain') ||
|
|
731
|
+
msg.includes('Array must contain') ||
|
|
732
|
+
msg.includes('Expected') ||
|
|
733
|
+
msg.includes('Invalid input') ||
|
|
734
|
+
msg.includes('Required')) {
|
|
735
|
+
return toolError('QULIB_INPUT_INVALID', msg, undefined);
|
|
736
|
+
}
|
|
737
|
+
// Log the stack to stderr for server-side diagnosis, but never return it
|
|
738
|
+
// in the client-visible detail (it discloses server filesystem paths).
|
|
739
|
+
log.error(`qulib_validate_spec failed: ${err instanceof Error ? err.stack : msg}`);
|
|
740
|
+
return toolError('QULIB_VALIDATE_SPEC_FAILED', msg, undefined);
|
|
741
|
+
}
|
|
742
|
+
});
|
|
681
743
|
async function startMcpServer() {
|
|
682
744
|
const transport = new StdioServerTransport();
|
|
683
745
|
await mcpServer.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qulib/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "MCP server for Qulib — AI-callable release confidence. Seven tools: fused verdict, live-app scan, automation maturity, API coverage, test scaffold, and auth tools.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Tapesh Nagarwal",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
37
|
-
"@qulib/core": "0.
|
|
37
|
+
"@qulib/core": "0.13.0",
|
|
38
38
|
"zod": "^3.23.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|