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 →
language support
Works from any language.
The @strata-ai/sdknpm package targets Node.js, Bun, Cloudflare Workers, and browsers. Strata doesn't have a native Python package yet — a PyPI package is on the roadmap. In the meantime, the REST API works with any HTTP client.
npm install @strata-ai/sdkNative SDK — full TypeScript typesnpm install @strata-ai/sdkZero-dependency, edge-compatiblepip install requestsREST API via requests (PyPI package coming soon)net/http (stdlib)REST API, no extra deps neededgem install faradayREST API via faradayx-api-key: sk_... header (see MCP client docs)Claude Code, Cursor, Windsurf, ClinePThrower/strata-mcp-check@v1GitHub Action — gate PRs on MCP riskpython
Python via requests.
The REST API works directly from Python with the requests library — no extra packages needed. A native PyPI package is on the roadmap.
pip install requestsBasic server verification
import requests
response = requests.get(
"https://usestrata.dev/api/v1/mcp/verify",
params={"url": "github.com/owner/repo"},
headers={"X-API-Key": "YOUR_KEY"}
)
data = response.json()
print(f"Risk: {data['risk_level']} | Score: {data['security_score']}")Scan multiple servers
import requests
servers = [
"github.com/modelcontextprotocol/server-filesystem",
"github.com/owner/unknown-server"
]
for server in servers:
r = requests.get(
"https://usestrata.dev/api/v1/mcp/verify",
params={"url": server},
headers={"X-API-Key": "YOUR_KEY"}
)
data = r.json()
if data["risk_level"] in ["high", "critical"]:
print(f"WARNING: {server} — {data['risk_level']}")x402 payment verification
import requests
r = requests.get(
"https://usestrata.dev/api/v1/x402/verify",
params={"url": "https://api.example.com/premium"},
headers={"X-API-Key": "YOUR_KEY"}
)
data = r.json()
if data["trusted"]:
print(f"Safe to pay — score: {data['security_score']}")
else:
print(f"BLOCKED — flags: {data['flags']}")Get threat feed
import requests
from datetime import datetime, timedelta, timezone
since = (datetime.now(timezone.utc) - timedelta(days=7)).isoformat()
r = requests.get(
"https://usestrata.dev/api/v1/threats",
params={"since": since, "severity": "critical"},
headers={"X-API-Key": "YOUR_KEY"}
)
for event in r.json()["events"]:
print(f"{event['severity'].upper()}: {event['detail']}")Record data lineage
import requests
r = requests.post(
"https://usestrata.dev/api/v1/lineage",
json={
"source_server": "https://source-mcp.example.com",
"dest_server": "https://dest-mcp.example.com",
"session_id": "my-agent-run-001",
"data_tags": ["internal"]
},
headers={"X-API-Key": "YOUR_KEY"}
)
print(r.json()["risk_level"])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)
}
}