vigile_check_server
Check MCP server trust scores and security findings in the Vigile registry to evaluate third-party tool safety.
Instructions
Look up the trust score and security findings for an MCP server in the Vigile registry. Returns trust score (0-100), trust level, findings summary, and a link to the full report.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | MCP server name or npm package name (e.g., '@anthropic/mcp-server-filesystem') |
Implementation Reference
- src/tools/check-server.ts:7-81 (handler)The checkServer function is the core handler for vigile_check_server. It fetches MCP server trust data from the Vigile API, handles 404 not-found cases with helpful guidance, and formats the response with trust score, trust level, security findings, and metadata.
export async function checkServer( baseUrl: string, apiKey: string, name: string ): Promise<string> { const { ok, status, data } = await fetchVigile( baseUrl, apiKey, `/api/v1/registry/${encodeURIComponent(name)}` ); if (!ok) { if (status === 404) { return [ `## MCP Server: ${name}`, "", "**Not found in the Vigile registry.**", "", "This server hasn't been scanned yet. You can:", `- Submit it for scanning at https://vigile.dev`, `- Run \`npx vigile-scan ${name}\` to scan it locally`, "", "β οΈ An unscanned server should be treated with caution.", ].join("\n"); } return `Error looking up "${name}": ${data?.detail || `HTTP ${status}`}`; } const emoji = trustLevelEmoji(data.trust_level); const lines = [ `## ${emoji} ${data.name}`, "", `**Trust Score:** ${formatScore(data.trust_score)}`, `**Trust Level:** ${data.trust_level}`, `**Source:** ${data.source}`, ]; if (data.description) { lines.push(`**Description:** ${data.description}`); } if (data.maintainer) { lines.push(`**Maintainer:** ${data.maintainer}`); } if (data.downloads_weekly) { lines.push(`**Weekly Downloads:** ${data.downloads_weekly.toLocaleString()}`); } if (data.stars) { lines.push(`**GitHub Stars:** ${data.stars.toLocaleString()}`); } if (data.last_scanned) { lines.push(`**Last Scanned:** ${new Date(data.last_scanned).toLocaleDateString()}`); } // Findings summary if (data.latest_findings && data.latest_findings.length > 0) { lines.push("", "### Security Findings"); for (const f of data.latest_findings.slice(0, 5)) { const severity = f.severity === "critical" ? "π΄" : f.severity === "high" ? "π " : "π‘"; lines.push(`- ${severity} **[${f.severity.toUpperCase()}]** ${f.title}`); if (f.recommendation) { lines.push(` β ${f.recommendation}`); } } if (data.latest_findings.length > 5) { lines.push(` ... and ${data.latest_findings.length - 5} more findings`); } } lines.push( "", `π [Full report on Vigile](https://vigile.dev/server/${encodeURIComponent(data.name)})` ); return lines.join("\n"); } - src/index.ts:65-77 (registration)Registers the vigile_check_server tool with the MCP server using server.tool(). Defines the tool name, description, Zod input schema (name parameter), and the async handler that calls checkServer().
// ββ Tool: vigile_check_server ββ server.tool( "vigile_check_server", "Look up the trust score and security findings for an MCP server in the Vigile registry. Returns trust score (0-100), trust level, findings summary, and a link to the full report.", { name: z.string().min(1).max(200).describe("MCP server name or npm package name (e.g., '@anthropic/mcp-server-filesystem')"), }, async ({ name }) => { const result = await checkServer(API_BASE, API_KEY, name); return { content: [{ type: "text" as const, text: result }] }; } ); - src/index.ts:71-71 (schema)Zod schema definition for the vigile_check_server input: a 'name' string (1-200 chars) representing the MCP server name or npm package name to look up.
name: z.string().min(1).max(200).describe("MCP server name or npm package name (e.g., '@anthropic/mcp-server-filesystem')"), - src/tools/api.ts:5-65 (helper)API client helper utilities used by checkServer: fetchVigile() for HTTP requests to the Vigile API, trustLevelEmoji() for mapping trust levels to emoji indicators, and formatScore() for formatting trust scores.
export async function fetchVigile( baseUrl: string, apiKey: string, path: string, options?: { method?: string; body?: string } ): Promise<{ ok: boolean; status: number; data: any }> { const headers: Record<string, string> = { "Content-Type": "application/json", "User-Agent": "vigile-mcp/0.1.7", }; if (apiKey) { headers["Authorization"] = `Bearer ${apiKey}`; } try { const res = await fetch(`${baseUrl}${path}`, { method: options?.method || "GET", headers, body: options?.body, }); const data = await res.json().catch(() => null); return { ok: res.ok, status: res.status, data }; } catch (error: any) { // Sanitize error message β don't leak internal details like // hostnames, ports, file paths, or stack traces const rawMsg = error?.message || "Unknown error"; const safeMsg = rawMsg.includes("ECONNREFUSED") || rawMsg.includes("ENOTFOUND") ? "API server unreachable" : rawMsg.includes("ETIMEDOUT") || rawMsg.includes("timeout") ? "Request timed out" : rawMsg.includes("ECONNRESET") ? "Connection reset" : "Connection failed"; return { ok: false, status: 0, data: { detail: safeMsg }, }; } } export function trustLevelEmoji(level: string): string { switch (level) { case "trusted": return "π’"; case "caution": return "π‘"; case "risky": return "π "; case "dangerous": return "π΄"; default: return "βͺ"; } } export function formatScore(score: number): string { return `${Math.round(score)}/100`; }