SkillTriage
Scan MCP servers and agent skills from a program or an AI agent. No API key. Static analysis only: nothing is installed or run. Submitted text is scanned in a temporary directory and deleted; only a hash, the verdict and content-free findings are stored.
Limits
Per IP address, shared by the API and the MCP endpoint: 60 requests per minute, 30 paste scans per hour and 10 package scans per hour. A result served from cache costs only the request. Bodies are capped at 1 MB. Package analyses run one at a time; when 5 are waiting, the API answers 503 with Retry-After: 30. Past a limit the answer is 429 with Retry-After in seconds.
Browsers. /api/v1/verdict and /openapi.json answer web pages on any site (CORS: Access-Control-Allow-Origin: *, with an OPTIONS preflight; no cookies or credentials are involved). The two scan routes and /mcp do not: a request with an Origin header that is not this service's gets 403. Calls from a server or a script send no Origin and are answered.
Endpoints
| Endpoint | Body | Returns |
|---|---|---|
POST /api/v1/scan | { "text", "filename"? } | verdict, content-free findings, pinning advice for a config file, permalink |
POST /api/v1/scan-package | { "ref" }: npm:<name>[@ver], pypi:<name>[==ver], github:<owner>/<repo>/<path>[@ref] | verdict, findings, MCP pre-install checks (npm, PyPI), permalink; reused for 24 hours |
POST /api/v1/verdict | { "ecosystem": "npm"|"pypi", "name", "version"? } | the published catalogue verdict, or found:false (not a clean result) |
GET /api/reputation-feed.json | every published MCP verdict, to match on your side without naming a server | |
GET /scan/:id.json · /package/:id.json | a scan's Evidence Pack; POST /api/verify recomputes its digest | |
POST /mcp | JSON-RPC 2.0 | the MCP endpoint (below) |
Examples
curl -s https://skilltriage.moorai.dev/api/v1/scan-package \
-H 'Content-Type: application/json' \
-d '{"ref":"npm:@modelcontextprotocol/server-filesystem"}'
curl -s https://skilltriage.moorai.dev/api/v1/scan \
-H 'Content-Type: application/json' \
-d '{"filename":".mcp.json","text":"{\"mcpServers\":{\"files\":{\"command\":\"npx\",\"args\":[\"-y\",\"@modelcontextprotocol/server-filesystem\",\".\"]}}}"}'
curl -s https://skilltriage.moorai.dev/api/v1/scan \
-H 'Content-Type: application/json' \
--data-binary @<(jq -Rs '{filename:"SKILL.md", text:.}' SKILL.md)
curl -s https://skilltriage.moorai.dev/api/v1/verdict \
-H 'Content-Type: application/json' \
-d '{"ecosystem":"pypi","name":"mcp-server-fetch"}'
MCP endpoint
https://skilltriage.moorai.dev/mcp is a remote MCP server (Streamable HTTP, no sign-in) with four tools: scan_package, scan_mcp_config, scan_skill and lookup_verdict. It answers protocol version 2026-07-28 and the earlier 2025-11-25, 2025-06-18 and 2025-03-26. It is stateless: no sessions, JSON responses, no GET stream. Remove secrets from env and headers before you ask it to check a config: they are not needed.
Claude Code
claude mcp add --transport http skilltriage https://skilltriage.moorai.dev/mcp
Claude Desktop and claude.ai: Customize › Connectors › Add › Add custom connector, enter https://skilltriage.moorai.dev/mcp, and choose no sign-in.
Cursor (.cursor/mcp.json in a project, or ~/.cursor/mcp.json)
{
"mcpServers": {
"skilltriage": {
"url": "https://skilltriage.moorai.dev/mcp"
}
}
}
Any client, by hand:
curl -s https://skilltriage.moorai.dev/mcp -H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"lookup_verdict","arguments":{"ecosystem":"npm","name":"@modelcontextprotocol/server-everything"}}}'