typescript sdk
v0.1.2Verify every MCP server your agents connect to.
Zero-dependency TypeScript SDK with two trust signals (security + runtime), capability flag detection, a CLI, and a GitHub Action for supply-chain safety.
npm install @strata-ai/sdkquick start
Verify in 8 lines.
Pass any GitHub URL, npm package name, or hosted MCP endpoint. The SDK auto-detects the input shape.
import { Strata } from '@strata-ai/sdk'
const strata = new Strata({ apiKey: process.env.STRATA_API_KEY })
const result = await strata.verify(
'https://github.com/microsoft/playwright-mcp'
)
console.log(result.risk_level) // 'low'
console.log(result.capability_flags) // ['fs_write', 'net_egress']
console.log(result.security_score) // 85
console.log(result.runtime_score) // 72trust signals
Two scores, one judgment.
Every server in the directory carries two independent trust signals. Together they power the risk_level classification.
security_score · 0–100
Repo health
Derived from GitHub signals: stars, commit recency, release discipline, license, and archived/fork status. Scores below 20 are immediately flagged critical.
runtime_score · 0–100
Behavioral trust
Derived from live tool-call probes against the server’s hosted endpoint: response latency, tool count, capability flag detection, and injection scan.
Capability flags are extracted from runtime probes. They describe what a server can actually do — not what its README claims.
shell_exec · highhighRuns arbitrary shell commands on the host machinedynamic_eval · highhighEvaluates dynamic code at runtime (eval, exec, etc.)fs_write · mediummediumWrites to the local filesystem outside sandboxed pathsarbitrary_sql · mediummediumExecutes raw SQL queries against a databasenet_egress · lowlowMakes outbound network requests to external servicessecret_read · lowlowReads environment variables, credentials, or secret storesprocess_spawn · lowlowSpawns child processesauthentication
Key or anonymous.
With an API key, every authenticated route is available. Without one, the anonymous tier (10 req/hour per IP) covers verify and findMCP. Get a free key →
// No API key — anonymous tier (10 req/hour per IP).
const strata = Strata.public()
await strata.verify('@modelcontextprotocol/server-filesystem')api reference
Methods.
verify(input)
(input: string | VerifyInput) => Promise<VerifyResult>
Single-server lookup. Smart-detects GitHub URLs, npm packages, and hosted endpoints. Returns { found: false, risk_level: 'unknown' } for unknown servers — never throws for not-found.
verifyAll(inputs)
(inputs: Array<string | VerifyInput>) => Promise<VerifyResult[]>
Batch lookup. Order preserved. Uses single bulk POST when N > 5. Counts as ceil(N/10) calls against your monthly quota.
const results = await strata.verifyAll([
'@modelcontextprotocol/server-filesystem',
'https://github.com/microsoft/playwright-mcp',
{ endpoint: 'https://example.com/mcp' },
])
for (const r of results) {
console.log(`${r.name}: ${r.risk_level}`)
}findMCP(query, options?)
(query: string, options?: FindMCPOptions) => Promise<McpServer[]>
Semantic search across Strata's directory. Quarantined and archived servers are excluded automatically.
const servers = await strata.findMCP('browser automation', {
excludeCapabilities: ['shell_exec', 'dynamic_eval'],
minSecurityScore: 50,
minRuntimeScore: 40,
requireHosted: false,
limit: 5,
})ecosystem(slug)
(slug: string) => Promise<EcosystemBrief>
Composite intelligence brief — best practices, news, integrations — in one round trip. Requires authentication.
const brief = await strata.ecosystem('claude')
console.log(brief.best_practices) // 5 most recent best practices
console.log(brief.news) // 10 most recent items
console.log(brief.integrations) // 10 top integrationsrisk model
Five levels, conservative by default.
Strata maps every server to one of five levels. trusted: true is set only at low.
cli
strata verify · strata scan
The package ships a strata binary. verify checks one server. scan walks an MCP client config and verifies every entry — defaults to your Claude Desktop config path.
# via npx — use @strata-ai/sdk (the bare "strata" name is taken on npm)
$ npx @strata-ai/sdk verify @modelcontextprotocol/server-filesystem
✓ @modelcontextprotocol/server-filesystem
Risk: 🟢 low (security 85, runtime 72)
Flags: fs_write, net_egress
→ https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem
$ npx @strata-ai/sdk verify github.com/owner/sketchy-mcp
✗ owner/sketchy-mcp
Risk: 🔴 critical (security 12, runtime 8)
Flags: shell_exec, dynamic_eval
Reasons: exposes shell_exec; security_score 12 below 20
# or: npm install -g @strata-ai/sdk → strata verify …$ npx @strata-ai/sdk scan
Strata MCP Security Scan
~/Library/Application Support/Claude/claude_desktop_config.json
✓ @modelcontextprotocol/server-filesystem 🟢 low security 85, runtime 72 [fs_write]
! @scope/risky-mcp 🟠 high security 60, runtime 30 [shell_exec]
? local-script unverifiable — local node script
✓ 1 passed ! 1 warnings ✗ 0 critical ? 1 unverifiableExit codes: 0 ok, 1 if any server breaches --fail-on, 2 internal error. Pass --json for parseable output.
github action
Gate every PR.
Drop this into .github/workflows/. The action finds every MCP server reference in the repo (Claude Desktop / Cursor / Cline configs, mcp.json, package.json with an mcp field), verifies each one, and posts an idempotent PR comment with the trust report.
name: MCP Security
on: [pull_request, push]
permissions:
contents: read
pull-requests: write
jobs:
strata:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: PThrower/strata-mcp-check@v1
with:
strata_api_key: ${{ secrets.STRATA_API_KEY }}
fail_on: criticalfail_on: critical | high | medium. Re-runs UPDATE the same comment instead of stacking. Full action README →
error handling
Typed errors for every failure mode.
Every failure has its own class. StrataRateLimitError exposes the parsed reset time so you can decide your retry policy precisely.
import {
Strata,
StrataAuthError,
StrataRateLimitError,
StrataValidationError,
StrataNetworkError,
} from '@strata-ai/sdk'
try {
await strata.verify(url)
} catch (err) {
if (err instanceof StrataRateLimitError) {
console.log('Reset at', err.resetAt)
console.log('Remaining', err.remaining)
}
}