@certscore/mcp 0.2.4 → 0.2.5
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/README.md +23 -9
- package/dist/certscore-mcp.mjs +85 -38
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +32 -0
- package/package.json +2 -2
- package/server.json +7 -21
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
CertScore MCP exposes a focused Model Context Protocol server for CertScore Pulse workflows.
|
|
4
4
|
|
|
5
|
-
Status: public
|
|
5
|
+
Status: public developer preview. The server is distributed for external macOS MCP clients through Homebrew. Local WC01 development uses `pnpm mcp:certscore`.
|
|
6
6
|
|
|
7
7
|
Public docs:
|
|
8
8
|
|
|
@@ -13,7 +13,8 @@ Public docs:
|
|
|
13
13
|
|
|
14
14
|
## Tools
|
|
15
15
|
|
|
16
|
-
- `
|
|
16
|
+
- `create_scan` - Deprecated compatibility alias of scan_site. Removed in 0.2.0. Use scan_site. Start a CertScore Pulse scan for a public URL and return immediately with status, scan, and polling links.
|
|
17
|
+
- `scan_site` - Start or reuse a CertScore public-web scan for a public URL.
|
|
17
18
|
- `get_scan` - Retrieve the API v2 public-safe scan resource for a stable scan ID.
|
|
18
19
|
- `get_scan_status` - Pass scanId (preferred, API v2). Pass jobId only for a just-created scan that has not yet returned a scanId.
|
|
19
20
|
- `get_report` - Retrieve a summary CertScore Pulse report by stable scan ID. Use get_evidence for the larger bounded evidence packet.
|
|
@@ -25,7 +26,17 @@ Public docs:
|
|
|
25
26
|
- `get_latest_domain_scan` - Retrieve the latest eligible API v2 public-safe scan for a domain.
|
|
26
27
|
- `get_latest_domain_pre_consent_cookies_trackers` - Retrieve the public-safe Cookies & Trackers (Pre-consent) table from the latest eligible scan for a domain.
|
|
27
28
|
|
|
28
|
-
The initial MCP surface intentionally does not include account scan browsing
|
|
29
|
+
The initial MCP surface intentionally does not include account scan browsing or scan comparison tools.
|
|
30
|
+
|
|
31
|
+
## Scan Timing Fields
|
|
32
|
+
|
|
33
|
+
MCP tools backed by API v2 scan resources return scan timing when CertScore has enough timing evidence:
|
|
34
|
+
|
|
35
|
+
- `startedAt`
|
|
36
|
+
- `completedAt`
|
|
37
|
+
- `scanTimeSeconds`
|
|
38
|
+
|
|
39
|
+
This applies to `scan_site` when it returns an API v2 scan resource or job, `get_scan`, and `get_scan_status` when called with a `scanId`. `scanTimeSeconds: null` means timing is unavailable or incomplete and should not be displayed as `0`.
|
|
29
40
|
|
|
30
41
|
## Configuration
|
|
31
42
|
|
|
@@ -60,9 +71,12 @@ Run from this monorepo for local development:
|
|
|
60
71
|
CERTSCORE_API_KEY=... pnpm mcp:certscore
|
|
61
72
|
```
|
|
62
73
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
Generate a scoped preview key after applying DB migrations:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm db:migrate
|
|
78
|
+
pnpm mcp:certscore:generate-key -- --name "CertScore MCP preview"
|
|
79
|
+
```
|
|
66
80
|
|
|
67
81
|
Run the built package directly after local build:
|
|
68
82
|
|
|
@@ -77,11 +91,11 @@ CERTSCORE_BASE_URL=https://certscore.ai
|
|
|
77
91
|
CERTSCORE_REQUEST_TIMEOUT_MS=300000
|
|
78
92
|
```
|
|
79
93
|
|
|
80
|
-
`CERTSCORE_API_KEY` should be a scoped CertScore API token for the workspace or
|
|
94
|
+
`CERTSCORE_API_KEY` should be a scoped CertScore API token for the workspace or preview user. The MCP server passes it to Pulse as a bearer token and does not persist it.
|
|
81
95
|
|
|
82
96
|
## API Key Access
|
|
83
97
|
|
|
84
|
-
MCP clients usually need `scan:read
|
|
98
|
+
MCP clients usually need `scan:read`, `scan:create`, and `mcp` scopes. Request developer-preview access by emailing `support@certscore.ai` with your organization, MCP client, expected workflow, expected request volume, contact email, and requested scopes.
|
|
85
99
|
|
|
86
100
|
## Verify Install
|
|
87
101
|
|
|
@@ -214,7 +228,7 @@ For the full production operator smoke, run from the WC01 repo:
|
|
|
214
228
|
pnpm ops:smoke:mcp-production
|
|
215
229
|
```
|
|
216
230
|
|
|
217
|
-
This verifies the Homebrew-installed `certscore-mcp` command against live `https://certscore.ai`. It creates a short-lived
|
|
231
|
+
This verifies the Homebrew-installed `certscore-mcp` command against live `https://certscore.ai`. It creates a short-lived preview key, stores only the hash in production through the approved ECS/Fargate path, checks required tools, requests a fresh EU-IR scan with `freshness: "refresh"` and `scanFrom: "eu_ie"`, requires non-empty findings and pre-consent cookies/trackers rows, runs `explain_finding`, and revokes the temporary key afterward. It exercises existing public-safe API/MCP projections only.
|
|
218
232
|
|
|
219
233
|
## Troubleshooting
|
|
220
234
|
|
package/dist/certscore-mcp.mjs
CHANGED
|
@@ -17846,7 +17846,7 @@ var pulseErrorSchema = external_exports.object({
|
|
|
17846
17846
|
var apiV2Disclaimer = "CertScore outputs are automated public-web observations for review. They are not legal advice, certification, or a compliance determination.";
|
|
17847
17847
|
var apiV2ScanStatusSchema = external_exports.enum(["queued", "running", "finalizing", "completed", "completed_limited", "failed", "expired", "rate_limited"]);
|
|
17848
17848
|
var apiV2ScanFreshnessSchema = external_exports.enum(["latest", "refresh"]);
|
|
17849
|
-
var apiV2ScanFromSchema = external_exports.enum(["eu_ie"
|
|
17849
|
+
var apiV2ScanFromSchema = external_exports.enum(["eu_ie"]);
|
|
17850
17850
|
var apiV2FindingCriticalitySchema = external_exports.enum(["critical", "high", "medium", "low", "info", "unknown"]);
|
|
17851
17851
|
var apiV2FindingConfidenceSchema = external_exports.enum(["strong", "good", "moderate", "weak", "unknown"]);
|
|
17852
17852
|
var apiV2EvidenceBasisSchema = external_exports.enum(["runtime_observation", "policy_surface_detection", "accessibility_check", "public_report_projection"]);
|
|
@@ -17888,6 +17888,9 @@ var apiV2ScanJobSchema = external_exports.object({
|
|
|
17888
17888
|
status: apiV2ScanStatusSchema,
|
|
17889
17889
|
phase: external_exports.string().optional(),
|
|
17890
17890
|
createdAt: external_exports.string().optional(),
|
|
17891
|
+
startedAt: external_exports.string().nullable().optional(),
|
|
17892
|
+
completedAt: external_exports.string().nullable().optional(),
|
|
17893
|
+
scanTimeSeconds: external_exports.number().nullable().optional(),
|
|
17891
17894
|
lastUpdatedAt: external_exports.string().optional(),
|
|
17892
17895
|
retryAfterSeconds: external_exports.number().int().nullable().optional(),
|
|
17893
17896
|
links: apiV2LinksSchema.optional(),
|
|
@@ -17903,6 +17906,7 @@ var apiV2ScanResourceSchema = external_exports.object({
|
|
|
17903
17906
|
createdAt: external_exports.string().nullable().optional(),
|
|
17904
17907
|
startedAt: external_exports.string().nullable().optional(),
|
|
17905
17908
|
completedAt: external_exports.string().nullable().optional(),
|
|
17909
|
+
scanTimeSeconds: external_exports.number().nullable().optional(),
|
|
17906
17910
|
score: external_exports.number().int().min(0).max(100).nullable().optional(),
|
|
17907
17911
|
riskLevel: external_exports.string().nullable().optional(),
|
|
17908
17912
|
coverage: external_exports.object({
|
|
@@ -18017,7 +18021,7 @@ var mcpPulseDetailSchema = external_exports.enum(["tiny", "quick", "standard", "
|
|
|
18017
18021
|
var mcpGptSafePulseDetailSchema = external_exports.enum(["tiny", "standard", "summary"]);
|
|
18018
18022
|
var mcpPulseFormatSchema = external_exports.enum(["json", "markdown"]);
|
|
18019
18023
|
var mcpPulseFreshnessSchema = external_exports.enum(["latest", "refresh"]);
|
|
18020
|
-
var mcpScanFromSchema = external_exports.enum(["eu_ie"
|
|
18024
|
+
var mcpScanFromSchema = external_exports.enum(["eu_ie"]);
|
|
18021
18025
|
var mcpCreateScanInputSchema = {
|
|
18022
18026
|
url: external_exports.string().min(1).describe("Public URL or domain to scan."),
|
|
18023
18027
|
detail: mcpPulseDetailSchema.optional().describe("Pulse detail level. Defaults to summary."),
|
|
@@ -18065,22 +18069,16 @@ var mcpGetLatestDomainPreConsentCookiesTrackersInputSchema = {
|
|
|
18065
18069
|
scanFrom: mcpScanFromSchema.optional().describe("Optional scan execution context for matching eligible scans."),
|
|
18066
18070
|
maxRows: external_exports.number().int().min(1).max(200).optional().describe("Maximum inventory rows to return. Defaults to 200.")
|
|
18067
18071
|
};
|
|
18068
|
-
|
|
18069
|
-
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
|
|
18073
|
-
|
|
18074
|
-
|
|
18075
|
-
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
return {
|
|
18079
|
-
title,
|
|
18080
|
-
readOnlyHint: true,
|
|
18081
|
-
openWorldHint: true
|
|
18082
|
-
};
|
|
18083
|
-
}
|
|
18072
|
+
var scanCreationAnnotations = {
|
|
18073
|
+
readOnlyHint: false,
|
|
18074
|
+
destructiveHint: false,
|
|
18075
|
+
idempotentHint: false,
|
|
18076
|
+
openWorldHint: true
|
|
18077
|
+
};
|
|
18078
|
+
var readOnlyOpenWorldAnnotations = {
|
|
18079
|
+
readOnlyHint: true,
|
|
18080
|
+
openWorldHint: true
|
|
18081
|
+
};
|
|
18084
18082
|
var mcpToolErrorPayloadSchema = external_exports.object({
|
|
18085
18083
|
error: external_exports.object({
|
|
18086
18084
|
name: external_exports.string(),
|
|
@@ -18108,7 +18106,10 @@ var mcpScanSiteOutputSchema = external_exports.object({
|
|
|
18108
18106
|
jobId: external_exports.string().optional(),
|
|
18109
18107
|
domain: external_exports.string().nullable().optional(),
|
|
18110
18108
|
status: apiV2ScanStatusSchema,
|
|
18111
|
-
scanFrom: apiV2ScanFromSchema.optional()
|
|
18109
|
+
scanFrom: apiV2ScanFromSchema.optional(),
|
|
18110
|
+
startedAt: external_exports.string().nullable().optional(),
|
|
18111
|
+
completedAt: external_exports.string().nullable().optional(),
|
|
18112
|
+
scanTimeSeconds: external_exports.number().nullable().optional()
|
|
18112
18113
|
}).passthrough();
|
|
18113
18114
|
var mcpScanStatusOutputSchema = external_exports.object({
|
|
18114
18115
|
type: external_exports.enum(["certscore_scan_job", "certscore_pulse_status"]).optional(),
|
|
@@ -18117,6 +18118,9 @@ var mcpScanStatusOutputSchema = external_exports.object({
|
|
|
18117
18118
|
scan_id: external_exports.string().nullable().optional(),
|
|
18118
18119
|
domain: external_exports.string().nullable().optional(),
|
|
18119
18120
|
status: external_exports.union([apiV2ScanStatusSchema, pulseStatusSchema.shape.status]).optional(),
|
|
18121
|
+
startedAt: external_exports.string().nullable().optional(),
|
|
18122
|
+
completedAt: external_exports.string().nullable().optional(),
|
|
18123
|
+
scanTimeSeconds: external_exports.number().nullable().optional(),
|
|
18120
18124
|
error: mcpToolErrorPayloadSchema.shape.error.optional()
|
|
18121
18125
|
}).passthrough();
|
|
18122
18126
|
var mcpReportOutputSchema = external_exports.object({
|
|
@@ -18163,45 +18167,53 @@ var mcpPreConsentCookiesTrackersOutputSchema = apiV2PreConsentCookiesTrackersSch
|
|
|
18163
18167
|
})
|
|
18164
18168
|
});
|
|
18165
18169
|
var certScoreMcpToolContracts = [
|
|
18170
|
+
{
|
|
18171
|
+
name: "create_scan",
|
|
18172
|
+
title: "Create CertScore Pulse scan",
|
|
18173
|
+
description: "Deprecated compatibility alias of scan_site. Removed in 0.2.0. Use scan_site. Start a CertScore Pulse scan for a public URL and return immediately with status, scan, and polling links.",
|
|
18174
|
+
inputSchema: mcpCreateScanInputSchema,
|
|
18175
|
+
outputSchema: mcpCreateScanOutputSchema,
|
|
18176
|
+
annotations: scanCreationAnnotations
|
|
18177
|
+
},
|
|
18166
18178
|
{
|
|
18167
18179
|
name: "scan_site",
|
|
18168
18180
|
title: "Scan site",
|
|
18169
|
-
description: "Start or reuse a CertScore public-web scan for a public URL. API
|
|
18181
|
+
description: "Start or reuse a CertScore public-web scan for a public URL. API v2 responses may include startedAt, completedAt, and scanTimeSeconds.",
|
|
18170
18182
|
inputSchema: mcpCreateScanInputSchema,
|
|
18171
18183
|
outputSchema: mcpScanSiteOutputSchema,
|
|
18172
|
-
annotations: scanCreationAnnotations
|
|
18184
|
+
annotations: scanCreationAnnotations
|
|
18173
18185
|
},
|
|
18174
18186
|
{
|
|
18175
18187
|
name: "get_scan",
|
|
18176
18188
|
title: "Get CertScore scan",
|
|
18177
|
-
description: "Retrieve the API v2 public-safe scan resource for a stable scan ID.",
|
|
18189
|
+
description: "Retrieve the API v2 public-safe scan resource for a stable scan ID, including startedAt, completedAt, and scanTimeSeconds when available.",
|
|
18178
18190
|
inputSchema: mcpGetScanInputSchema,
|
|
18179
18191
|
outputSchema: apiV2ScanResourceSchema,
|
|
18180
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18192
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18181
18193
|
},
|
|
18182
18194
|
{
|
|
18183
18195
|
name: "get_scan_status",
|
|
18184
|
-
title: "Get CertScore scan status",
|
|
18185
|
-
description: "Pass scanId (preferred, API v2). Pass jobId only for a just-created scan that has not yet returned a scanId.",
|
|
18196
|
+
title: "Get CertScore Pulse scan status",
|
|
18197
|
+
description: "Pass scanId (preferred, API v2) to retrieve status and scan timing fields. Pass jobId only for a just-created scan that has not yet returned a scanId.",
|
|
18186
18198
|
inputSchema: mcpGetScanStatusInputSchema,
|
|
18187
18199
|
outputSchema: mcpScanStatusOutputSchema,
|
|
18188
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18200
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18189
18201
|
},
|
|
18190
18202
|
{
|
|
18191
18203
|
name: "get_report",
|
|
18192
|
-
title: "Get CertScore report",
|
|
18204
|
+
title: "Get CertScore Pulse report",
|
|
18193
18205
|
description: "Retrieve a summary CertScore Pulse report by stable scan ID. Use get_evidence for the larger bounded evidence packet.",
|
|
18194
18206
|
inputSchema: mcpGetReportInputSchema,
|
|
18195
18207
|
outputSchema: mcpReportOutputSchema,
|
|
18196
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18208
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18197
18209
|
},
|
|
18198
18210
|
{
|
|
18199
18211
|
name: "get_evidence",
|
|
18200
|
-
title: "Get CertScore evidence",
|
|
18212
|
+
title: "Get CertScore Pulse evidence",
|
|
18201
18213
|
description: "Retrieve the bounded structured Evidence JSON packet for a stable scan ID. Excludes raw cookie values, raw bodies, sensitive payloads, full DOM, and unredacted query values.",
|
|
18202
18214
|
inputSchema: mcpGetEvidenceInputSchema,
|
|
18203
18215
|
outputSchema: pulseResponseSchema,
|
|
18204
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18216
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18205
18217
|
},
|
|
18206
18218
|
{
|
|
18207
18219
|
name: "export_findings",
|
|
@@ -18209,7 +18221,7 @@ var certScoreMcpToolContracts = [
|
|
|
18209
18221
|
description: "Return structured findings from a CertScore Pulse report for downstream review or ticketing workflows.",
|
|
18210
18222
|
inputSchema: mcpExportFindingsInputSchema,
|
|
18211
18223
|
outputSchema: mcpFindingsExportOutputSchema,
|
|
18212
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18224
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18213
18225
|
},
|
|
18214
18226
|
{
|
|
18215
18227
|
name: "list_findings",
|
|
@@ -18217,15 +18229,15 @@ var certScoreMcpToolContracts = [
|
|
|
18217
18229
|
description: "List API v2 public-safe findings already projected for a scan.",
|
|
18218
18230
|
inputSchema: mcpListFindingsInputSchema,
|
|
18219
18231
|
outputSchema: mcpFindingListOutputSchema,
|
|
18220
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18232
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18221
18233
|
},
|
|
18222
18234
|
{
|
|
18223
18235
|
name: "get_pre_consent_cookies_trackers",
|
|
18224
|
-
title: "Get pre-consent cookies
|
|
18236
|
+
title: "Get pre-consent cookies and trackers",
|
|
18225
18237
|
description: "Retrieve the public-safe Cookies & Trackers (Pre-consent) report table as compact JSON for a scan.",
|
|
18226
18238
|
inputSchema: mcpGetPreConsentCookiesTrackersInputSchema,
|
|
18227
18239
|
outputSchema: mcpPreConsentCookiesTrackersOutputSchema,
|
|
18228
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18240
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18229
18241
|
},
|
|
18230
18242
|
{
|
|
18231
18243
|
name: "explain_finding",
|
|
@@ -18233,7 +18245,7 @@ var certScoreMcpToolContracts = [
|
|
|
18233
18245
|
description: "Explain a single CertScore finding with public evidence, caveats, and reviewer next steps.",
|
|
18234
18246
|
inputSchema: mcpExplainFindingInputSchema,
|
|
18235
18247
|
outputSchema: apiV2FindingDetailSchema,
|
|
18236
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18248
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18237
18249
|
},
|
|
18238
18250
|
{
|
|
18239
18251
|
name: "get_latest_domain_scan",
|
|
@@ -18241,15 +18253,15 @@ var certScoreMcpToolContracts = [
|
|
|
18241
18253
|
description: "Retrieve the latest eligible API v2 public-safe scan for a domain.",
|
|
18242
18254
|
inputSchema: mcpGetLatestDomainScanInputSchema,
|
|
18243
18255
|
outputSchema: apiV2DomainLatestScanSchema,
|
|
18244
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18256
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18245
18257
|
},
|
|
18246
18258
|
{
|
|
18247
18259
|
name: "get_latest_domain_pre_consent_cookies_trackers",
|
|
18248
|
-
title: "Get latest pre-consent cookies
|
|
18260
|
+
title: "Get latest domain pre-consent cookies and trackers",
|
|
18249
18261
|
description: "Retrieve the public-safe Cookies & Trackers (Pre-consent) table from the latest eligible scan for a domain.",
|
|
18250
18262
|
inputSchema: mcpGetLatestDomainPreConsentCookiesTrackersInputSchema,
|
|
18251
18263
|
outputSchema: mcpPreConsentCookiesTrackersOutputSchema,
|
|
18252
|
-
annotations: readOnlyOpenWorldAnnotations
|
|
18264
|
+
annotations: readOnlyOpenWorldAnnotations
|
|
18253
18265
|
}
|
|
18254
18266
|
];
|
|
18255
18267
|
|
|
@@ -22702,6 +22714,7 @@ function explainFinding(report, findingId) {
|
|
|
22702
22714
|
}
|
|
22703
22715
|
|
|
22704
22716
|
// src/server.ts
|
|
22717
|
+
var createScanDeprecationWarningPrinted = false;
|
|
22705
22718
|
function toolContract(name) {
|
|
22706
22719
|
const contract = certScoreMcpToolContracts.find((candidate) => candidate.name === name);
|
|
22707
22720
|
if (!contract) {
|
|
@@ -22726,6 +22739,40 @@ function createCertScoreMcpServer(options = {}) {
|
|
|
22726
22739
|
version: CERTSCORE_MCP_VERSION
|
|
22727
22740
|
});
|
|
22728
22741
|
const registerTool = server.registerTool.bind(server);
|
|
22742
|
+
async function createPulseScanTool(input) {
|
|
22743
|
+
const result = await client.submitScan(input.url, {
|
|
22744
|
+
detail: normalizeDetail2(input.detail),
|
|
22745
|
+
format: normalizeFormat2(input.format),
|
|
22746
|
+
freshness: input.freshness ?? "latest",
|
|
22747
|
+
scanFrom: input.scanFrom
|
|
22748
|
+
});
|
|
22749
|
+
return {
|
|
22750
|
+
type: "certscore_mcp_scan_created",
|
|
22751
|
+
status: result.status,
|
|
22752
|
+
jobId: result.jobId ?? null,
|
|
22753
|
+
scanId: result.scanId ?? result.scan_id ?? null,
|
|
22754
|
+
completed: result.completed ?? false,
|
|
22755
|
+
statusUrl: result.statusUrl ?? result.nextCheckUrl ?? null,
|
|
22756
|
+
resultUrl: result.resultUrl ?? null,
|
|
22757
|
+
reportUrl: result.reportUrl ?? null,
|
|
22758
|
+
pulse: result.pulse ?? null
|
|
22759
|
+
};
|
|
22760
|
+
}
|
|
22761
|
+
registerTool(
|
|
22762
|
+
"create_scan",
|
|
22763
|
+
toolContract("create_scan"),
|
|
22764
|
+
async (input) => {
|
|
22765
|
+
try {
|
|
22766
|
+
if (!createScanDeprecationWarningPrinted) {
|
|
22767
|
+
createScanDeprecationWarningPrinted = true;
|
|
22768
|
+
console.error("[certscore-mcp] create_scan is deprecated and will be removed in 0.2.0. Use scan_site.");
|
|
22769
|
+
}
|
|
22770
|
+
return toToolResult(await createPulseScanTool(input));
|
|
22771
|
+
} catch (error2) {
|
|
22772
|
+
return toToolError(error2);
|
|
22773
|
+
}
|
|
22774
|
+
}
|
|
22775
|
+
);
|
|
22729
22776
|
registerTool(
|
|
22730
22777
|
"scan_site",
|
|
22731
22778
|
toolContract("scan_site"),
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAqCD,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,mBAAwB,aAsNzE"}
|
package/dist/server.js
CHANGED
|
@@ -3,6 +3,7 @@ import { certScoreMcpToolContracts } from "@certscore/api-contracts";
|
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { CERTSCORE_MCP_VERSION } from "./version.js";
|
|
5
5
|
import { boundEvidencePacket, exportFindings, limitPreConsentRows, normalizeDetail, normalizeFormat, paginateFindingList, scanIdFromStatus, toToolError, toToolResult } from "./tools.js";
|
|
6
|
+
let createScanDeprecationWarningPrinted = false;
|
|
6
7
|
function toolContract(name) {
|
|
7
8
|
const contract = certScoreMcpToolContracts.find((candidate) => candidate.name === name);
|
|
8
9
|
if (!contract) {
|
|
@@ -27,6 +28,37 @@ export function createCertScoreMcpServer(options = {}) {
|
|
|
27
28
|
version: CERTSCORE_MCP_VERSION
|
|
28
29
|
});
|
|
29
30
|
const registerTool = server.registerTool.bind(server);
|
|
31
|
+
async function createPulseScanTool(input) {
|
|
32
|
+
const result = await client.submitScan(input.url, {
|
|
33
|
+
detail: normalizeDetail(input.detail),
|
|
34
|
+
format: normalizeFormat(input.format),
|
|
35
|
+
freshness: input.freshness ?? "latest",
|
|
36
|
+
scanFrom: input.scanFrom
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
type: "certscore_mcp_scan_created",
|
|
40
|
+
status: result.status,
|
|
41
|
+
jobId: result.jobId ?? null,
|
|
42
|
+
scanId: result.scanId ?? result.scan_id ?? null,
|
|
43
|
+
completed: result.completed ?? false,
|
|
44
|
+
statusUrl: result.statusUrl ?? result.nextCheckUrl ?? null,
|
|
45
|
+
resultUrl: result.resultUrl ?? null,
|
|
46
|
+
reportUrl: result.reportUrl ?? null,
|
|
47
|
+
pulse: result.pulse ?? null
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
registerTool("create_scan", toolContract("create_scan"), async (input) => {
|
|
51
|
+
try {
|
|
52
|
+
if (!createScanDeprecationWarningPrinted) {
|
|
53
|
+
createScanDeprecationWarningPrinted = true;
|
|
54
|
+
console.error("[certscore-mcp] create_scan is deprecated and will be removed in 0.2.0. Use scan_site.");
|
|
55
|
+
}
|
|
56
|
+
return toToolResult(await createPulseScanTool(input));
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return toToolError(error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
30
62
|
registerTool("scan_site", toolContract("scan_site"), async (input) => {
|
|
31
63
|
try {
|
|
32
64
|
return toToolResult(await client.scans.create(input.url, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@certscore/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"mcpName": "ai.certscore/mcp",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "MCP server for CertScore public website risk-signal workflows.",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@certscore/api-contracts": "0.1.0",
|
|
63
|
-
"@certscore/sdk": "0.
|
|
63
|
+
"@certscore/sdk": "0.2.3"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --platform=node --format=esm --target=node20 --banner:js='#!/usr/bin/env node' --outfile=dist/certscore-mcp.mjs",
|
package/server.json
CHANGED
|
@@ -1,37 +1,23 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
|
|
3
3
|
"name": "ai.certscore/mcp",
|
|
4
|
-
"
|
|
5
|
-
"
|
|
4
|
+
"description": "MCP server for CertScore public website risk-signal workflows.",
|
|
5
|
+
"status": "active",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "https://github.com/ergoveritas1-alt/certscore.ai",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "0.2.
|
|
10
|
+
"version": "0.2.5",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
|
+
"registryBaseUrl": "https://registry.npmjs.org",
|
|
14
15
|
"identifier": "@certscore/mcp",
|
|
15
|
-
"version": "0.2.
|
|
16
|
+
"version": "0.2.5",
|
|
16
17
|
"transport": {
|
|
17
18
|
"type": "stdio"
|
|
18
19
|
},
|
|
19
|
-
"
|
|
20
|
-
{
|
|
21
|
-
"name": "CERTSCORE_API_KEY",
|
|
22
|
-
"description": "CertScore API key with scan:read, scan:create, and mcp scopes.",
|
|
23
|
-
"isRequired": true,
|
|
24
|
-
"format": "string",
|
|
25
|
-
"isSecret": true
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"name": "CERTSCORE_BASE_URL",
|
|
29
|
-
"description": "Optional CertScore API base URL. Defaults to https://certscore.ai.",
|
|
30
|
-
"isRequired": false,
|
|
31
|
-
"format": "string",
|
|
32
|
-
"isSecret": false
|
|
33
|
-
}
|
|
34
|
-
]
|
|
20
|
+
"runtimeHint": "node"
|
|
35
21
|
}
|
|
36
22
|
]
|
|
37
23
|
}
|