
Company News
AWS Security Hub Adds Socket for Supply Chain Security
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.
@shipeasy/mcp
Advanced tools
Feature flags, A/B experiments, kill switches, dynamic config & i18n — Shipeasy MCP server.
@shipeasy/mcp — unified Model Context Protocol serverReplaces packages/mcp-server/. One MCP server, one npm package, covers both subsystems:
- Experimentation — gates, configs, experiments, metrics, events (from experiment-platform/10-mcp-server.md).
- String manager / i18n — label profiles, keys, drafts, translations, publish, codemods (from string-manager-platform/plan.md § MCP server).
AI assistants (Claude Code, Cursor, Copilot, Windsurf, Claude Desktop, Continue) talk to one server and get the full platform.
📖 Docs: docs.shipeasy.ai/get-started/mcp — setup guide · full tool reference (auto-generated from the tool catalog).
packages/mcp/ (this doc).packages/mcp-server/ — will be deleted once this ships. The npm package rename (@shipeasy/mcp-server → @shipeasy/mcp) is a breaking change; the old name publishes one final version that re-exports the new package as a deprecation shim.shipeasy-mcp (unchanged — the old binary name is preserved so existing .claude/settings.json entries keep working).Two steps: (1) register the server with your AI assistant, (2) authenticate once with shipeasy-mcp install. Step 2 is required before any mutating tool will work — it runs a browser-based PKCE device flow against /auth/device/* and writes the token to ~/.config/shipeasy/config.json (shared with @shipeasy/cli).
npx (recommended for AI assistant configs)
// ~/.claude/settings.json | .cursor/mcp.json | .windsurf/mcp.json | .mcp.json (project-local)
{
"mcpServers": {
"shipeasy": {
"command": "npx",
"args": ["-y", "@shipeasy/mcp@latest"]
}
}
}
Global install
npm i -g @shipeasy/mcp
# or
pnpm add -g @shipeasy/mcp
{ "mcpServers": { "shipeasy": { "command": "shipeasy-mcp" } } }
Through the CLI (if @shipeasy/cli is already installed)
shipeasy mcp install # auto-writes ~/.claude/settings.json + .cursor/mcp.json
shipeasy mcp start # run stdio server (same binary, different entry)
env)The server is configured through environment variables, so every setting flows
straight from your mcp.json / settings.json env block:
{
"mcpServers": {
"shipeasy": {
"command": "npx",
"args": ["-y", "@shipeasy/mcp@latest"],
"env": {
"SHIPEASY_MCP_LIST_GUARD": "on",
"SHIPEASY_MCP_LIST_GUARD_WINDOW_MINUTES": "10"
}
}
}
}
| Variable | Default | Effect |
|---|---|---|
XDG_CONFIG_HOME | — | Overrides the token/config file location. |
SHIPEASY_MCP_LIST_GUARD | on | List-before-create guard. When on, every *_create that has a *_list sibling refuses to run unless it carries a fresh listToken that the sibling *_list just returned — a forcing-function so the assistant checks for an existing resource before creating a duplicate. Set off to disable. |
SHIPEASY_MCP_LIST_GUARD_WINDOW_MINUTES | 10 | How long a minted listToken stays valid (effective validity is 1×–2× this, since the previous window is also accepted). A token also dies with the server process, so it can never be replayed across sessions. |
Run this once per machine:
shipeasy-mcp install
What happens:
POST {api_base}/auth/device/start to open a session; the worker returns a state.{app_base}/cli-auth?state=…&code_challenge=…&source=mcp. Sign in with your existing Shipeasy account (GitHub, Google, or magic link — same as the dashboard).POST {api_base}/auth/device/complete with project_id + PKCE verifier.GET {api_base}/auth/device/poll?state=… (header X-Code-Verifier) every ~2 s until it receives { token, project_id }.~/.config/shipeasy/config.json with chmod 600. The directory is created chmod 700.Flags:
| Flag | Effect |
|---|---|
--force | Overwrite an existing session instead of aborting. |
--no-browser | Print the auth URL; useful on remote / headless machines (paste it into a local browser). |
Other subcommands:
shipeasy-mcp whoami # prints { project_id, user_email, config_path }
shipeasy-mcp logout # deletes ~/.config/shipeasy/config.json
shipeasy-mcp --help # usage
shipeasy-mcp --version
The MCP stdio transport runs inside the AI assistant — it can't block for a browser round-trip, spawn new windows, or receive a browser-delivered callback. Browser-based auth has to run in a terminal the user owns. Once the token is written, every MCP server instance on the machine (Claude Code, Cursor, Windsurf, MCP Inspector, etc.) reads the same ~/.config/shipeasy/config.json — one install, many clients.
The in-process auth_login MCP tool therefore always returns a pointer back to the CLI command rather than trying to launch a browser itself.
npx -y @shipeasy/mcp
# or pipe it through MCP Inspector:
npx @modelcontextprotocol/inspector npx -y @shipeasy/mcp
Transport: stdio (JSON-RPC 2.0 framed by Content-Length headers per MCP spec). Capabilities advertised on initialize:
{
"tools": { "listChanged": true },
"prompts": { "listChanged": false },
"resources": { "subscribe": true, "listChanged": true },
"logging": {}
}
notifications/message.Every mutating tool requires a Shipeasy session. Credentials live in ~/.config/shipeasy/config.json and are shared between @shipeasy/mcp and @shipeasy/cli — whichever tool the user authenticates in first, both pick up the same session.
shipeasy-mcp install (terminal) completes the PKCE device flow and writes the config file (see Step 2 — authenticate above).auth_check tool reads the file on every call — no cached state in the server process.auth_login invoked over MCP always returns an actionable error asking the human to run shipeasy-mcp install in a terminal (stdio can't open a browser safely).auth_logout removes the file; the CLI equivalent works too.~/.config/shipeasy/config.json (mode 0600, parent dir 0700)
{
"project_id": "proj_…",
"cli_token": "sdk_admin_…", ← scoped to admin Route Handlers; 90-day rotation
"api_base_url": "https://api.shipeasy.ai",
"app_base_url": "https://shipeasy.ai",
"user_email": "you@example.com",
"created_at": "2026-04-16T…Z"
}
Tool-level auth policy:
| Category | Requires session | Notes |
|---|---|---|
auth_* | — / triggers it | |
list_*, get_* | Yes | Read-only GETs against apps/ui admin Route Handlers. |
create_*, update_*, delete_*, publish_* | Yes | Mutations — the CLI enforces checkLimit server-side. |
Filesystem / AST tools live in the
shipeasyCLI, not this server. Project detection and the i18n source scanners / codemods / loader-install / file-based push / local-Anthropic translation were removed from MCP — the server only makes admin-API calls now (plus the auth +.shipeasybind primitives). The authoritative, generated tool reference isdocs/mcp-reference.md; the catalog below is design-era narrative and has drifted.
Tools are namespaced by subsystem: exp_* (experimentation), i18n_* (string manager), unprefixed (shared: auth, resource listing, SDK snippets). Project detection has moved to the shipeasy CLI.
auth_check// input
{}
// output
{ "authenticated": true, "project_id": "…", "base_url": "…", "user_email": "…" }
auth_loginSpawns shipeasy login, which opens the browser and blocks until the device-auth flow completes. Uses spawn (not execSync) so the MCP event loop stays responsive. The AI assistant should surface a "waiting for browser…" message — the CLI session polls for up to 5 minutes.
// input
{}
// output — same shape as auth_check after success
auth_logoutDeletes ~/.config/shipeasy/config.json. No network call.
list_resourcesUnified listing across both subsystems.
// input
{
"kind": "gates|configs|experiments|events|metrics|universes|attributes|profiles|keys|drafts|sdk_keys|all",
"limit": 50,
"search": "checkout" // optional name filter
}
Hits the matching apps/ui admin Route Handler (e.g. /api/admin/gates, /api/admin/i18n/profiles) and returns a normalized list:
{
"kind": "experiments",
"items": [
{ "id": "…", "name": "checkout_button_color", "universe": "checkout", "status": "running", "allocation": 10 },
...
],
"next_cursor": null
}
get_resourceFetches a single resource by { kind, name_or_id }. Same routing as list_resources.
get_sdk_snippetReturns ready-to-paste code for the detected language + framework, for either subsystem.
// input
{
"domain": "experiment | i18n",
"language": "typescript | python | ruby | go | java | php | swift | kotlin",
"framework": "nextjs | react | remix | vue | svelte | angular | nuxt | django | rails | laravel | spring | swiftui | compose | ... | null",
"type": "gate | experiment | config | label_load | label_render | loader_script | provider_setup",
"name": "new_checkout",
"params": { "color": "string" },
"success_event": "purchase_completed",
"success_value": true
}
Output:
{
"install": "pnpm add shipeasy",
"env_vars": ["SHIPEASY_SERVER_KEY", "NEXT_PUBLIC_SHIPEASY_CLIENT_KEY"],
"init": "…code block…",
"usage": "…code block…",
"tracking": "…code block (only for experiments)…",
"validate_command": "pnpm tsc --noEmit",
"docs_url": "https://docs.shipeasy.ai/sdk/typescript/next"
}
Templates are loaded from the installed SDK package (shipeasy/templates/<language>.js), not from this MCP bundle — so they track the customer's SDK version. Falls back to bundled templates if the SDK has no templates/ export or isn't installed yet. See packages/language_sdks/README.md for the source-of-truth template files per language.
list_prompts / get_promptStandard MCP — see Prompts section below. These are built into @modelcontextprotocol/sdk.
exp_*)All mutations shell out to @shipeasy/cli via execFile (never exec with shell interpolation) with validated, slugified arguments. Names are auto-slugged before validation (SAFE_NAME_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/) and a warning is logged if auto-slugging changed the input.
| Tool | What it does | Shells to |
|---|---|---|
exp_create_gate | Create a feature gate with targeting rules and rollout percentage | shipeasy gates create |
exp_update_gate | Update rules, rollout, killswitch | shipeasy gates update |
exp_delete_gate | shipeasy gates delete | |
exp_create_config | Create a static config (sitevar) | shipeasy configs create |
exp_update_config_value | Update the live value | shipeasy configs set |
exp_create_universe | Create a universe with holdout % | shipeasy universes create |
exp_create_experiment | Create experiment draft with groups, params, targeting gate | shipeasy experiments create |
exp_start_experiment | Transition draft → running | shipeasy experiments start |
exp_stop_experiment | Transition running → stopped, promote winning group | shipeasy experiments stop |
exp_add_metric | Attach a metric as goal/guardrail | shipeasy experiments metric add |
exp_create_event | Register an event schema | shipeasy events create |
exp_create_metric | Create a metric from an event | shipeasy metrics create |
exp_experiment_status | Current results + ship/hold/wait verdict | GET /api/admin/experiments/:name/results |
exp_cleanup_winner | AST-drop losing branches after shipping | Local codemod via jscodeshift/ast-grep |
Representative input — exp_create_experiment:
{
"name": "checkout_button_color",
"description": "Test green vs. gray on new checkout",
"universe": "checkout",
"allocation": 10,
"groups": [
{ "name": "control", "weight": 5000, "params": { "color": "gray" } },
{ "name": "test", "weight": 5000, "params": { "color": "green" } }
],
"params_schema": { "color": "string" },
"targeting_gate": "new_checkout",
"success_event": "purchase_completed",
"success_aggregation": "count_users"
}
Output:
{
"experiment": {
"name": "checkout_button_color",
"id": "exp_…",
"status": "draft",
"universe": "checkout"
},
"metric": { "name": "checkout_button_color_purchase_completed", "status": "created" },
"snippet": {
/* same shape as get_sdk_snippet */
},
"docs_url": "https://docs.shipeasy.ai/experiments/create"
}
i18n_*)The i18n admin API surface is projected from the spec (tag chain i18n ▸ Profiles | Keys | Drafts + x-cli verb), exactly like every other resource. The exact, authoritative list is the generated docs/mcp-reference.md; the current tools are:
| Tool | What it does | Endpoint |
|---|---|---|
i18n_profiles_list | List locale profiles | GET /api/admin/i18n/profiles |
i18n_profiles_create | Create a locale profile (e.g. fr:prod) | POST /api/admin/i18n/profiles |
i18n_profiles_publish | Publish a profile live (profile-wide KV rebuild + CDN purge) | POST /api/admin/i18n/profiles/{profileId}/publish |
i18n_keys_list | List keys for a profile (filter by prefix / free-text) | GET /api/admin/i18n/keys |
i18n_keys_push | Push new keys (insert-only — existing keys are skipped) | POST /api/admin/i18n/keys |
i18n_keys_update | Overwrite one existing key's value (by key id) | PUT /api/admin/i18n/keys/{id} |
i18n_keys_set | Set one key by profile name (omit → default) and publish it live | POST /api/admin/i18n/set |
i18n_drafts_list | List staged machine-translation drafts | GET /api/admin/i18n/drafts |
The filesystem / AST i18n tooling — source scanning, codemods, loader install, key validation, site discovery, local-Anthropic draft translation, and file-based bulk push — is not part of the MCP surface; it lives in the shipeasy CLI (the fs-having consumer). It never hit the admin API, so it carries no spec op.
MCP prompts expose named, parameterized playbooks the AI can get_prompt() to load as context. Mirrors the skills bundle in experiment-platform/11-skills.md and string-manager-platform/plan.md § Skills.
| Prompt name | Purpose |
|---|---|
setup_experimentation | Install the SDK, add env keys, wire a provider, verify with a sample gate |
create_experiment | Propose → create → inject code → start → monitor |
analyze_experiment | Pull results, compute lift + significance, emit ship/hold/wait verdict |
cleanup_winner | Remove losing branches + dead gate code after shipping |
rotate_sdk_keys | Revoke + re-issue client/server keys and update env vars |
(The i18n playbooks setup_i18n / translate_site / i18n_health were removed — they orchestrated the fs/AST tools that now live in the shipeasy CLI.)
Each prompt's body is a short markdown playbook embedded in the server bundle. The assistant fetches it once per conversation with get_prompt({ name }) and follows the steps.
Read-only project context streamed to the assistant via MCP's resources/read. The server advertises resource templates (URI patterns) so the assistant can pull context on demand without the user needing to paste files.
| URI template | Returns |
|---|---|
shipeasy://project | Cached detect_project() output + auth_check() output. |
shipeasy://experiments/{name} | Experiment config + latest stats JSON. |
shipeasy://gates/{name} | Gate config + rollout state. |
shipeasy://configs/{name} | Config value + history. |
shipeasy://i18n/profiles/{profile} | Profile metadata + published strings + coverage %. |
shipeasy://i18n/drafts/{draft_id} | Draft metadata + per-key diff vs. source profile. |
shipeasy://plans/current | Plan tier + current-month usage + remaining quota. |
shipeasy://docs/{slug} | Pre-rendered markdown page from docs.shipeasy.ai — AI-consumable. |
resources/subscribe is supported on shipeasy://experiments/{name} — the server pushes notifications/resources/updated when cron finishes a new analysis run (detected via long-poll on /api/admin/experiments/:name/results?since=ts).
packages/mcp/
package.json ← name: "@shipeasy/mcp", bin: "shipeasy-mcp"
tsconfig.json
tsup.config.ts ← esm output, single bundle
bin/
mcp.js ← shebang → runs dist/index.js
src/
index.ts ← Server setup, capability advertise, tool routing
rpc/
list-tools.ts
call-tool.ts
list-prompts.ts
get-prompt.ts
list-resources.ts
read-resource.ts
subscribe-resource.ts
tools/
schema.ts ← TOOLS array — MCP tool definitions
shared/
detect.ts ← detect_project (with realpath sandbox)
auth.ts ← auth_check, auth_login, auth_logout
list-resource.ts ← list_resources, get_resource
snippets.ts ← get_sdk_snippet + template loader
exp/
gates.ts
configs.ts
universes.ts
experiments.ts
events.ts
metrics.ts
status.ts
cleanup.ts
i18n/
scan.ts ← i18n_scan_code (ast-grep driver)
discover.ts ← i18n_discover_site
profiles.ts
keys.ts
drafts.ts
translate.ts ← i18n_translate_draft (Anthropic shell-out)
publish.ts
usage.ts
codemods/
nextjs.ts
react.ts
vue.ts
svelte.ts
angular.ts
rails.ts
django.ts
index.ts ← dispatcher for i18n_codemod_preview/apply
validate.ts
loader.ts ← i18n_install_loader
prompts/
schema.ts ← PROMPTS array
setup_experimentation.md
create_experiment.md
analyze_experiment.md
cleanup_winner.md
setup_i18n.md
translate_site.md
i18n_health.md
rotate_sdk_keys.md
resources/
schema.ts ← RESOURCE_TEMPLATES
project.ts
experiments.ts
gates.ts
configs.ts
i18n.ts
plans.ts
docs.ts
util/
cli.ts ← execFile wrapper with shared error decoding
http.ts ← fetch wrapper w/ cli_token header
slug.ts ← autoSlug + SAFE_NAME_RE
safe-read.ts ← realpath-sandboxed fs reads
progress.ts ← notifications/progress helper
logger.ts ← notifications/message helper (respects client log level)
compat.ts ← semver compatibility check per language
templates/ ← fallback snippets when SDK has no templates/ export
typescript.ts
python.ts
ruby.ts
go.ts
java.ts
php.ts
swift.ts
kotlin.ts
test/
rpc/*.test.ts ← each request handler covered
tools/exp/*.test.ts
tools/i18n/*.test.ts
tools/shared/detect.test.ts ← realpath sandbox edge cases
fixtures/
projects/
nextjs-with-sdk/
django-clean/
rails-with-i18n/
astro-plain/
{
"name": "@shipeasy/mcp",
"version": "1.0.0",
"description": "Model Context Protocol server for the Shipeasy platform (experimentation + i18n)",
"keywords": [
"mcp",
"model-context-protocol",
"shipeasy",
"feature-flags",
"experimentation",
"i18n",
"ai"
],
"type": "module",
"bin": { "shipeasy-mcp": "./bin/mcp.js" },
"files": ["bin/", "dist/", "src/prompts/*.md"],
"engines": { "node": ">=20" },
"scripts": {
"build": "tsup src/index.ts --format esm --dts --clean",
"type-check": "tsc --noEmit",
"test": "vitest",
"prepublishOnly": "pnpm build"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"@shipeasy/sdk": "workspace:*",
"semver": "^7.6.0",
"zod": "^3.23.0",
"conf": "^13.0.0",
"@ast-grep/napi": "^0.22.0"
},
"devDependencies": {
"@types/node": "^20.19.0",
"@types/semver": "^7.5.0",
"tsup": "^8.3.0",
"typescript": "^5.7.0",
"vitest": "^2.0.0"
}
}
Why @ast-grep/napi? A single, fast, multi-language AST engine used by every codemod (JS/TS/Vue/Svelte/Python/Ruby) instead of per-framework parsers. Keeps the install footprint small — one native dep, prebuilt binaries for common platforms.
Every tool returns one of three shapes:
// Success
{ content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }
// Known validation / domain error (isError: true)
{ content: [{ type: "text", text: "Error: gate 'new_checkout' already exists" }], isError: true }
// Protocol error — JSON-RPC level
{ error: { code: -32602, message: "Invalid params: 'name' required" } }
Rules:
isError: true tool result with a redacted message; a structured notifications/message log is emitted at error level for the operator.exec + string interpolation. All subprocess calls go through util/cli.ts which uses execFile with an argument array and a 60 s default timeout.util/safe-read.ts — path traversal attempts throw a specific error that's shown to the user, not silently followed.notifications/message. The assistant honours the client-set log level (debug, info, warning, error) advertised at initialize time.i18n_translate_draft, i18n_codemod_apply on large repos, i18n_push_keys) emit notifications/progress with { progressToken, progress, total, message } so the assistant can render a spinner/bar.{ tool, duration_ms, result_status, error_code } locally to ~/.cache/shipeasy/mcp.log (rolling 10 MB, 3 files). No payloads. No secrets.Each SDK language declares a compatible template range; the MCP server bundles the template authority and resolves at call time.
const COMPATIBLE_VERSIONS: Record<Lang, string> = {
typescript: ">=1.0.0 <3.0.0",
python: ">=1.0.0",
ruby: ">=1.0.0",
go: ">=1.0.0",
java: ">=1.0.0",
php: ">=1.0.0",
swift: ">=1.0.0",
kotlin: ">=1.0.0",
};
detect_project sets template_warning when the installed SDK is outside the range. get_sdk_snippet first tries to import templates from the customer's installed shipeasy/templates/<lang>.js and falls back to this MCP server's bundled templates only if the SDK is not present (e.g. during fresh project setup).
fetch + mocked execFile. Target ≥90% coverage on src/tools/**.test/fixtures/projects/ contains minimal Next.js / Django / Rails / Astro projects. detect_project runs against each one and asserts the returned shape.npx @modelcontextprotocol/inspector npx -y ./dist/index.js and exercises list_tools, list_prompts, list_resources, and one success/one error tool call per domain.create_experiment → get_sdk_snippet → experiment_status loop writes to D1 and KV correctly. Required per CLAUDE.md.tsc --noEmit, Python → py_compile, etc.) in a tiny scratch project. Regressions in template strings fail CI instantly.Independent of the CLI and the SDK:
initialize advertises serverInfo.version. The assistant may show a nudge when a newer version is available on npm. @shipeasy/cli re-exports @shipeasy/mcp at the matching major so shipeasy mcp start never runs a mismatched server.
This server is listed in the official MCP Registry as ai.shipeasy/mcp, which is what most MCP directories (Smithery, Glama, PulseMCP, mcp.so, the VS Code / Cursor galleries) ingest from. The registry hosts only metadata — the actual artifact is the @shipeasy/mcp npm package.
Single source of truth: package.json. Its mcpName is the registry server name and the npm name/version/description/repository feed the rest. server.json is generated — never hand-edit it:
pnpm --filter @shipeasy/mcp registry:gen # package.json → server.json
This is automated. .github/workflows/publish.yml publishes to npm on a GitHub Release, then a publish-registry job lists the new version on the MCP Registry (it waits for npm to expose the version, regenerates server.json, and authenticates via DNS using the MCP_PRIVATE_KEY repo secret — the Ed25519 key behind the shipeasy.ai TXT proof). GitHub-OIDC auth is not usable here: it only grants io.github.* namespaces, not our ai.shipeasy domain namespace. So the day-to-day flow is just: bump version, regen server.json, commit, tag a release — CI does the rest.
The manual flow below is the fallback (first-time setup, or republishing out of band).
The registry verifies ownership by checking that the published npm package's package.json carries mcpName: "ai.shipeasy/mcp". So the order matters — ship npm first, then the registry:
mcpName). Bump version, tag a release on shipeasy-ai/mcp, let CI publish via OIDC. Manual npm publish is forbidden (see ## Non-negotiables).ai.shipeasy namespace (DNS-based, one-time TXT record on shipeasy.ai):
openssl genpkey -algorithm Ed25519 -out key.pem
PUBLIC_KEY="$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)"
# add TXT on shipeasy.ai: v=MCPv1; k=ed25519; p=$PUBLIC_KEY
PRIVATE_KEY="$(openssl pkey -in key.pem -noout -text | grep -A3 'priv:' | tail -n +2 | tr -d ' :\n')"
mcp-publisher login dns --domain shipeasy.ai --private-key "$PRIVATE_KEY"
pnpm --filter @shipeasy/mcp registry:gen
cd packages/mcp && mcp-publisher publish
Install mcp-publisher with brew install mcp-publisher (or the release binary). Verify after: curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=ai.shipeasy/mcp".
/api/admin/experiments/* and /api/admin/i18n/*. Two servers would each prompt for login.detect_project needs to report both experimentation and i18n status; splitting doubles the filesystem walks for every conversation.translate_site wants to read experiment config (does the site have an en variant gated by a new_language_picker flag?) — a single server can get_resource from both domains without a cross-server handshake..claude/settings.json, not two.i18n_install_loader call can consult the same detected stack exp_create_experiment just used.tools/schema.ts, Zod validator at call-time, unit test, and an entry in this README's catalog table.prompts/schema.ts + a markdown file under prompts/*.md + a one-line description for list_prompts.create_*, update_*, delete_*, publish_*) requires an authenticated session and re-validates limits by letting the apps/ui handler call checkLimit() — the MCP server never hand-rolls plan enforcement.execFile + argument arrays.util/safe-read.ts.index.ts and converted to notifications/message errors — the process never exits on a per-request failure.shipeasy/templates/) and validated in CI with tsc --noEmit / py_compile / equivalent.FAQs
Feature flags, A/B experiments, kill switches, dynamic config & i18n — Shipeasy MCP server.
We found that @shipeasy/mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.

Research
/Security News
Popular npm packages keyv and cacheable compromised.

Security News
A misconfiguration gave three Anthropic models internet access, and one, believing it was in a simulation, shipped a credential-stealing package to PyPI.