CHANGELOG
v4.6.3 (2026-10-10)
Bug Fixes
- ci: Allow explicit npm dist-tag for republishes
(
29e8c84)
v4.6.2 (2026-10-10)
Bug Fixes
- ci: Publish in-run so automated tags cannot skip the release
(
a888340)
v4.6.1 (2026-10-10)
Bug Fixes
- ci: Place -v and --noop as global semantic-release flags
(
71b0f88)
[4.6.0] — 2026-10-10
- feat(pi): native gateway registration —
.pi/extensions/mcp-gateway.tsnow callspi.registerMcpServer("gateway", { command: "uvx", args: ["mcp-gway", "serve"] })insidetry/catch(name clash with another extension degrades to a stderr warning, tools keep working)..mcp.jsonis deleted and dropped from thefileswhitelist inpackage.json; a same-named server in a user's projectmcp.jsonstill takes precedence. - feat(pi):
gw_add/gw_removemodel-callable tools wrapping top-levelmcp-gway add/mcp-gway removevia a newrunRoothelper (same never-throws{ ok, text }contract andMAX_OUTPUT_CHARStruncation asrunTools).runAddbuilds the exact CLI argv (--commandfor local,--urlfor remote, repeatable--env/--header,--cwd,--no-enabled,--timeout) and validates before shelling: local withoutcommandor remote withouturlreturns a usage error with zero subprocess spawns. Deliberately no OAuth flags —addfalls back to an interactive OAuth flow that cannot complete headless, so OAuth servers are added from a real terminal. - feat(pi):
uvguard atsession_start— the handler probesuvx --version(5 s timeout) before the inventory call; on missinguvit warns always and notifies (UI only) with the install URL plus reload instruction, then returns early skipping inventory. Toolexecutepaths keep returning today'smcp-gway is not availableerror text. - tests(pi):
tests/pi_extension.test.mjsgrows from 27 to 34 checks —registerMcpServer/unregisterMcpServerstubs onmakePi, native registration args assertion, meta-tool count bumped to 6,gw_addlocal/remote argv (raw name passed through; PascalCase normalization stays server-side in the CLI), both usage-error cases with zero exec calls,gw_removeargv,uvx --versionprobe ordering in the inventory test, and the uv-missing notify test (install URL asserted, no inventory message). VerifiedALL GREEN. - docs(pi):
plugins/pi/INSTALL.mdConfiguration paragraph rewritten (no.mcp.jsonshipped, native registration shape,uvprerequisite with reload path), meta-tools and session-inventory bullets updated, host-map row corrected; stale.mcp.jsoncontract note intests/AGENTS.mdupdated. - chore(omp):
.gitignorenow ignores.omp/plugins/(oh-my-pi local plugin installs).
[4.5.7] — 2026-10-06
- docs(readme): restructure the front door — README.md drops from 389 lines to 75 (badges, tagline, Why/Who, corrected Quick Start, features, documentation index, dev pointer, license) and the depth moves to eight focused guides under
docs/(configuration, cli, code-mode, security, observability, integrations, architecture, development). The three section badges now target files instead of GitHub slugs (0 in-page anchors left) and all 20 local links were verified to resolve. Also removes the duplicate## Quick Startheading and the inventedmcp-gway add --name files --localsyntax — replaced with the real signaturemcp-gway add files --type local --command. - docs(facts): fix stale references while moving sections —
Options for addis 14 options atcli.py:97-136(was "13 flags" atcli.py:45-95; the--retry-on-transport-errorrow was missing from the table),cli.py:50→cli.py:97-102,/healthsample"version":"3.1.0"→4.5.6, test count570→647(verified for this release: 645 passed + 2 skipped), SSRF refmodels.py:115-163→models.py:301-540, both deadMIGRATION.mdlinks →CHANGELOG.md, deaddocs/architecture/adr-009-dynamic-local-commands.mdlink and stalerm ~/.config/mcp-gway/catalog.jsonhint dropped (neither exists), ASCII-artreutilizado→reused.
[4.5.6] — 2026-10-06
- ci(npm): publish to npm via OIDC trusted publishing — the release pipeline now publishes
mcp-gwayto npm alongside PyPI, authenticated by short-lived OIDC instead of a long-lived registry token.id-token: writewas already declared, and both publishes are now secretless (nosecrets.*, noNODE_AUTH_TOKENanywhere in the workflows). Node pinned to24.21.0exactly because npm trusted publishing requires npm >= 11.5.1 and Node 22 only ships npm 10.9.9 — the previousnode-version: "22"could never have published. Addsrepository/homepage/bugsmetadata that npm renders on the package page. The first publish (mcp-gway@4.5.5) was a manual bootstrap, since npm requires a package to exist before a trusted publisher can be configured. - ci(hardening): pin every action and runner to an exact version —
test.ymlwas using floating major tags (checkout@v4,setup-python@v5,setup-uv@v6), now the exact versions already proven inrelease.yml(v4.2.2/v5.6.0/v6.8.0);runs-on: ubuntu-latest→ubuntu-24.04in both workflows, becauselatestis a moving alias rather than a reproducible reference. - ci(pr-only): tests run on
pull_requestonly, thepushtrigger is gone (CI is the PR gate, so the master push run was redundant — verified: 0 Tests runs on the merge commit vs 3 before).release.ymlcannot be PR-triggered because a tag is not a PR, so it gains aVerify tag points at merged codeguard requiring the tagged commit to be an ancestor ofmaster— releases can only come from merged PR code, never a stray branch tag. The guard runs immediately after checkout, before any build or publish step. - docs(workflow): correct the documented release command —
git push --follow-tagsonly pushes ANNOTATED tags and this repo tags lightweight, so it silently failed to pushv4.5.5and no release ran despiteexit 0.
[4.5.5] — 2026-10-06
- chore(packaging): add
fileswhitelist topackage.json— npm was shipping the whole git-tracked tree (2,058,620 B unpacked:.github/workflows/,.omp/,docs/,tests/,AGENTS.md,DESIGN.md,.pre-commit-config.yaml). The whitelist holds the five runtime contracts only:.mcp.json(Pi gateway discovery),plugins/opencode/mcp-gateway.ts(main/exports),.pi/extensions/(pi.extensions),skills/(pi.skills— four cross-referencing SKILL.md files) andrules/mcp-gway.md, which.pi/extensions/mcp-gateway.tsreads at runtime and would otherwise have degraded silently to the embedded fallback card. Evidence:npm pack --dry-run605 KB → 25 KB packed, 2,058,620 → 81,278 B unpacked, 11 files (package.json,README.md,LICENSEare always included by npm regardless).
[4.5.4] — 2026-10-06
- chore(pypi): declare license expression + Python classifiers — PyPI metadata shipped empty (
classifiers: [], nolicense), so the README's dynamic Python and License badges rendered redmissing.license = "MIT"+license-filesnow emitLicense-Expression: MIT/License-File: LICENSEin wheel METADATA (the LICENSE file ships inside the dist), and 3.12/3.13 classifiers match the CI matrix so both badges derive real data. Evidence:uv buildclean (deprecated license classifier dropped — PEP 639 warning gone),uv lock --checkclean, ruff probe confirms shields readslicense_expression.
[4.5.3] — 2026-10-06
- docs(readme): product-focused badge set — CI/Release status, Ruff code style, PyPI downloads, MCP Protocol, Code Mode, Local-First Security, Observability Built-in. Anchor links to corresponding sections. 11 badges total, 2-row visual layout. No code/logic change.
- chore(omp): add .omp/ directory with README badges plan artifact.
[4.5.2] — 2026-10-06
- fix(pi-ext): card injection fallback for omp —
oh-my-pi18.6.1 emitsbefore_agent_startwithoutsystemPromptOptions, so the section write threw and the UI warnedGateway Protocol card not injected. The handler now returns asystemPromptoverride (card appended, deduped by marker) when sections are absent; the Pi section path is unchanged. Regression test intests/pi_extension.test.mjs+ troubleshooting row inplugins/pi/INSTALL.md.
[4.5.1] — 2026-10-06
- docs(scrub): remove retired product names from live surfaces — README, AGENTS, PRODUCT, all four skill files, source docstrings/comments, one served
listToolFilesdescription, and test names reworded. Wording-only: no logic, packaging, plugin, or history change. Zero live mentions remain; scoped sweep + 645 tests + ruff clean. - docs(context): hierarchical
AGENTS.mdvia init-deep — root refresh (178 → 87 lines) with evidence-backed domain table and commands copied frommise.toml; new domain-scoped files forsrc/mcp_gway/core,src/mcp_gway/observability,src/mcp_gway/admin,tests.
[4.5.0] — 2026-10-06
-
feat(pi): gateway over stdio —
.mcp.jsondeclaresgatewayasuvx mcp-gway serve(loopback by construction, no TCP surface, no port, no token). Extension drops programmatic registration; Pi discovers the server declaratively. Extension surface: Gateway Protocol card injection (rules/mcp-gway.mdat runtime, deduped by marker), 4 meta-tools (gw_list,gw_read,gw_docs,gw_execviapi.registerToolshelling out tomcp-gway tools), hiddensession_startserver inventory. 27 checks intests/pi_extension.test.mjsincl..mcp.jsoncontract test. -
feat(pi): Pi packages upgraded to 1.0.4 (
@earendil-works/pi-coding-agent,pi-ai) —ExtensionContexttyping on thebefore_agent_starthandler, no implicit/explicitany. -
fix(antigravity):
mcp_config.jsonmoves to stdio (command: uvx,args: [mcp-gway, serve]);test_mcp_config_loopback_and_no_secretsasserts the stdio shape. -
feat(tracing): stdlib-only distributed tracing completes logs → metrics → traces. New
observability/tracing.py(Tracer+Span, contextvars propagation, W3Ctraceparentin/out, 256-span ring buffer, zero deps).TracingMiddlewarewraps every HTTP request as aserverspan (METHOD /route, status + error capture,traceparentresponse header). Every upstream tool call gets a nestedclientspan (tool server.name,mcp.server/tool/status, retry flag);sandbox.executegets its own span.JSONFormatternow always emitstrace_id+span_idfor log correlation. NewGET /admin/partials/traces?limit=50(loopback-gated) exposes the recent span tail; observability page links it. 7 new tests intest_observability_tracing.py.
[4.3.1] — 2026-10-05
- fix(gateway): silence benign Windows accept noise + harden global error handlers.
install_asyncio_exception_handler()downgrades transient client-abort accept errors (WinError 64/121/995/1236,ConnectionResetError, "Accept failed on a socket") to debug — wired vianew_event_looppatch inserve(uvicorn owns the loop),Gateway.__init__, and lifespan. New_ClientDisconnectMiddlewareanswers mid-request hangups with a quiet 204;Exception/HTTPExceptionhandlers guarantee JSON 500s (secret-safe via_safe_error_data, never HTML tracebacks);LoggingMiddlewarelogs disconnects at debug, real failures with context. 3 new regression tests intest_edgecases_gateway.py.
[4.3.0] — 2026-10-05
- feat(models): native pydantic validation errors with human-friendly messages. Validators raise
PydanticCustomErrorwith a distincttype=per failure and the[reason=...]token preserved inmsg+ structuredctx.reason;format_validation_errorrenders onefield: sentenceline per error. CLIaddremote branch wrapped in try/except (exit 1, no traceback) and admin add/save surfaces share the helper.https-onlynow enforced at config validation; SSRF bypass fixtures moved tohttps://URLs.
[4.2.0] — 2026-10-04
- docs(skills): product-first rewrite of all four skills with per-command variants and live examples.
skills/cli→skills/mcp-gway-cli(viagit mv, history preserved): every command gets its own section —adddocuments all 12 flags with remote/local/OAuth variants,tools execshows three variants (--codeinline,--filescript,refresh && read && execchain).skills/mcp→skills/mcp-gway-mcp: transport picker table, fourservevariants, three agent-wiring variants (OpenCode stdio, Claude HTTP, Pi.mcp.json), 4-step protocol with real Context7/ParallelSearch output, Starlark DO/DON'T cookbook.skills/core→skills/mcp-gway-core: config-files table (servers/*.json|pyi,tokens/), complete six-varMCP_GWAY_*table, three policy gates with allow/deny examples, execution stack, OAuth, observability series, admin-backend route table.skills/mcp-gwaybecomes a routing table (task → skill → coverage). All frontmatter bumped to v4.2.0;plugins/pi/INSTALL.mdnaming aligned;README.mdLICENSE link corrected toLICENSE.
[4.1.0] — 2026-10-04
- feat(admin): toast lifecycle, form reset, actionable errors. Success toasts (green/blue/white) auto-dismiss after ~4s via htmx
load delay:4sself-swap to/admin/partials/empty(no inline script, strict CSP holds); red/orange persist with a close control. Add-server and Code Mode execute forms OOB-swap a fresh copy on success and keep user input on error. Every error keeps its searchable head and appends the next action (test_admin_dashboard.py54 tests).
[4.0.0] — 2026-10-04
- feat(cli)!: BREAKING — full break-glass kill.
mcp-gway local-unrestricted [enable|disable|status]is gone (No such command); the marker engine is deleted fromcore/policy.py(UNRESTRICTED_ENV,MARKER_NAME,UnrestrictedStatus,create/remove/unrestricted_status/is_unrestricted_active,marker_path), and the adminGET/POST/DELETE /admin/partials/policy/unrestrictedroutes plus panel are removed. Local commands are gated by the explicit allow-list only (MCP_GWAY_ALLOW_LOCAL_COMMANDS, unset/blank →npx,bunx,uvx,pipx) — no bypass exists. Deny messages now point at the allow-list instead oflocal-unrestricted enable. - feat(cli):
mcp-gway --version/-vprintsmcp-gway <version>via root-groupclick.version_option(mgwinherits it). - docs(product): outcome-first positioning — README opens with one-endpoint/on-demand-schemas, adds Why/Who sections, drops the unverified 92% token claim, EN-only, diagram at v4.0.0.
pyproject/package.json/plugin.jsonone-liners aligned; skill frontmatter at v4.0.0;PRODUCT.mdgateway-first with the corrected parity list.
[3.2.0] — 2026-10-04
- feat(pi): soporte del harness Pi (tercero tras OpenCode y Antigravity) — el repo queda cargable como Pi package (
package.jsondeclarapi.{extensions,skills}) y.pi/extensions/mcp-gateway.tsinyecta la Gateway Protocol card ensystemPromptOptions.sectionsen cadabefore_agent_start, dedupeado por marker, leyendo el texto derules/mcp-gway.mden runtime (fuente única compartida con Antigravity, sin copias que divergan). El registro MCP es declarativo vía.mcp.jsonen la raíz, autodescubierto por pi-mcp-adapter — no runtimeregisterMcpServer(), que fuerzadirectTools: falsey lanza en nombres duplicados. La extensión es fail-soft: lee un archivo local acotado, no abre socket, no spawnea nada y traga sus propios errores, así no puede abortar un turno. Nueva guíaplugins/pi/INSTALL.md. - fix(manifest):
package.jsonera JSON inválido — el bloquepien el working copy tenía"./.pi/prompts/"como propiedad suelta fuera del arrayprompts, lo que invalidaba el JSON y rompía la carga del paquete. La clavepise añade declarando solo los paths que existen (extensions,skills). - fix(antigravity): el hook
PreInvocationestaba roto y nunca ejecutó —hooks.jsoninvocabash /plugins/antigravity/scripts/reinject.sh, una ruta POSIX absoluta que no existe en Windows ni resuelve al repo. Reescrito comoplugins/antigravity/scripts/reinject.mjs(Node ESM; sin shell, sineval, sin red, sin escrituras, degrada a no-op) e invocado comonode ./plugins/antigravity/scripts/reinject.mjs. El.shse elimina. - chore(antigravity):
plugin.jsonsincronizado a3.1.0conpackage.json(was2.8.0); marker derules/mcp-gway.mdy contratos de hook marcados aMCP-GWAY v3.1.0;INSTALL.mdsin elchmod +xde un script que ya no existe.
[v3.1.0] — 2026-09-23
- feat(admin): complete admin web dashboard (htpy 26.5.1 + htmx 2.0.10 + Tailwind, ambos CDN, estética Spotify de
DESIGN.md) — revierte el "CLI-only, no UI" de v2.0.0 solo para gestión; CLI sigue canónico y/dashboard+catalog permanecen retirados. Nuevo paquetesrc/mcp_gway/admin/(theme/components/icons SVG authored/layout/data/routes + pages de status, overview, servers, tools, observability, policy) spliced enGatewaypara ambos transports: páginas/(índice),/admin(alias),/admin/servers[/{name}],/admin/tools(explorador Code Mode: list/read/docs/execute conasyncio.to_threaden el sandbox),/admin/observability,/admin/policy+ 17 endpoints/admin/partials/*(status cada 5s, grid/CRUD/refresh/auth de servers, config editPUT .../{name}/config, tools read-onlyGET .../{name}/tools, break-glass enable/disable, metrics). Paridad con CLI (add/remove/list/inspect/refresh/local-unrestricted) —update(tools) permanece solo CLI: la web NO muta tools (solo add/refresh); edición de config en web con secretos write-only (blank = conserva valor). Seguridad: admin loopback-only (_gate→ 403 siserve_hostno es loopback), CSRF por proceso (app.state.csrf_token, headerX-CSRF-Tokeno campo_csrf) en toda mutación, CSP único relajado en constanteCSPdegateway.py(script-src jsDelivr+Tailwind, style-srcunsafe-inline,frame-ancestors 'none'; test<=2literales intacto), OAuth nunca inline (task en background con paridadrefresh --auth), headers/OAuth enmascarados en detalle, allow-list de comandos locales aplicada víacheck_local_command+ audit en add/refresh,path_templatecolapsa/admin/*(cardinalidad acotada). Host header fail-closed en_gate(solo{127.0.0.1, localhost, ::1, [::1]}→ evil Host 403 en las 24 rutas admin, anti-DNS-rebinding), execute con timeout real clamp [0.1,30]s default 10 (toast/noticeexec-timeout), merge OAuth per-field (blank conserva, sentinela de máscara = blank). Serve banner añade líneaDashboard → http://host:port/. Evidence:tests/test_admin_dashboard.py(50 tests) + 3 asserts CSP migrados a la constanteCSP. - perf(tests): optimize test suite execution and eliminate SSE disconnect hang (SPEC-TEST-PERF-001). Monkeypatched
MAX_IDLE_SECONDSto 0.05s intest_ac005_sse_disconnect_countedto remove a 300-second ASGI idle wait. Bounded mock thread sleeps in sandbox timeout tests (test_sandbox.py,test_edgecases_sandbox.py) from 10s to 0.8s/0.5s to preventThreadPoolExecutorshutdown lag. Fixed DNS timeout monkeypatch target toSSRF_DNS_TIMEOUTintest_p0_round2_hardening.py. Total test suite execution time reduced from >340s to ~8.9s across all 562 tests (100% pass rate, zero production code changes). - feat(casing): universal casing ingestion, auto-migration on refresh, and canonical PascalCase exposure (SPEC-CASING-001, ADR-013). Upgraded
to_pascal_case_identifierto cleanly parsecamelCase,ALL_CAPSacronyms (GITHUB→Github,WEATHER_SERVICE→WeatherService), delimiters, and numbers. Implemented case-insensitive server lookup acrossremove,inspect,update, andrefresh.mcp-gway refreshautomatically migrates legacy and non-canonical servers to canonical PascalCase files and tokens.
v3.0.0 (2026-09-22)
- feat(transport)!: BREAKING —
/mcproutes are now per-transport with no cross-fallback (SPEC-TRANSPORT-SEPARATION-001, gate OPEN 2026-09-22, 7 reviews). One process no longer serves both transports:serve --transport httpexposes onlyPOST /mcp(GET /mcp→405 Allow: POST;/mcp/messages→ 404, 6 routes) andserve --transport sseonlyGET /mcp+POST /mcp/messages(POST /mcp→405 Allow: GET, 7 routes). Probes (/health,/ready,/live,/metrics) remain on both;app.state.transportexposed;Gateway(transport=...)rejects unknown values. Migration: SSE-only clients must use--transport sse(seeplugins/antigravity/INSTALL.mdtroubleshooting); streamable-HTTP (POST) clients are unaffected. Strict semver:feat!→ major (3.0.0). Evidence:tests/test_transport_separation.py9/9 + suite 570 passed; amends ADR-010 AC-05 inline (AGENTS.md,API_CONTRACTS.md).
v2.5.0 (2026-09-17)
- feat(cli): expose
mgwas a 1:1 shortcut formcp-gway(verified 2026-09-17, samecli.main, SPEC-MGW-001);mcp-gwaystays canonical, both shims ship on install (pyproject.toml:20-21). Evidence:tests/test_cli_alias.py3/3 green + README/AGENTS.md shortcut callouts. - fix(ready): event-loop drift threshold 3s → 35s (30s heartbeat + 5s buffer, SPEC-READY-001) —
/readyreturned 503 false-positive; now 200 when healthy, p99=16ms. Change:src/mcp_gway/observability/health.py:88. - docs(perf): internal-only performance audit tooling (verified 2026-09-17, SPEC-PERF-001, engineering). Benchmark script (
bench_perf.py), runbook (RUNBOOK-perf.md), findings baseline v2.4.0 (PERF-FINDINGS-v2.4.0.md+reports/baseline_20260917_*.json, all 5 SLO hypotheses PASS), architecture NFRs (ARCHITECTURE.md), ADR-011. No user-facing impact, no src/ changes. - docs(release): reconcile v2.4.0 tag collision — remote annotated tag stays the 2026-09-16 automation (
0cdcfe8); local lightweight tag (6601767) deleted locally, never pushed;RELEASE_NOTES.mdrollback corrected (nevertag -d/push-delete a published tag; published recovery isgit revert+ PyPI yank via devops + vasquez). - docs(verify): FEAT-007 verification evidence 2026-09-17 —
tests/test_obsfeat007.py11/11 core ACs green (AC-001/003/004/008/009/013/014/015/016/017/018),ruff check+format --checkclean;--retry-on-transport-errorevidencetest_ac014/015/016green (server_factory.py:101-148,models.py:720,cli.py:107-112).
Residual risks (accepted, owners tracked)
- AC-004 (
discovery_duration_seconds) dead code — no production caller passesmetrics=. Owner: vasquez. - Raw error messages in CLI/CodeMode logs (M-01..M-04) — hygiene, not network-facing. Owner: vasquez.
- Code mode refresh dead code (reliability F-1) — informational overlap, harmless. Owner: vasquez.
v2.4.0 (2026-09-16)
- note: published automation tag (remote annotated
07b3b05…→0cdcfe8, semantic-release 2026-09-16). Post-v2.4.0 delta (09-16/17:mgwfeat,/readyfix, perf docs) rides## Unreleasedabove and ships with the next version — it is NOT part of this v2.4.0 entry. - cleanup: remove legacy env-based log-level inference —
_resolve_log_levelnow reads onlyMCP_GWAY_LOG_LEVEL(--log-leveloverrides; defaultinfo). DroppedMCP_GWAY_ENV,ENV,ENVIRONMENT,APP_ENV,DEBUG,LOG_LEVELfallbacks and the serve bannerenv <hint>echo. Purged inertMCP_GWAY_ALLOW_LOCAL_VIA_DASHBOARDfrom docs (code already removed in v2.0.0; AGENTS.md/README.md updated). - feat(cli): unified
serve --transport [stdio|http|sse](defaultstdio);--registry-diris now a commonserveoption;--host/--portonly apply tohttp|sse(withstdio→Error: --host/--port only apply to --transport http|sse+ exit 2, never warn-and-ignore). - deprecation:
mcp-gway mcpis now a hidden alias (hidden=True):serve --transport stdioequivmcp— mismo loop NDJSON y mismos args a_serve_stdio(), modulo aviso de deprecacion[mcp] deprecated, use serve --transport stdioen stderr (solomcp, sin logica propia). Usecommand: [mcp-gway, serve, --transport, stdio]for OpenCodetype: local. - compat: local-first intact (
127.0.0.1default, non-loopback withoutMCP_GWAY_ALLOW_REMOTE=1→ exit 2 legacy text);http/sseshare the sameGateway.app; stdio keeps stdout pure NDJSON (bannerserr=True). - feat(observability): FEAT-007 hardening — process/build lifecycle metrics (
build_info,process_start_time_seconds,uptime_secondsvia 30s heartbeat,lifetime_secondsset at shutdown + JSONgateway shutdown summary); SSE disconnects counted by reason (gateway_sse_disconnects_total); stdio per-request metrics + JSON access log (transport:"stdio");discovery_duration_seconds{server,status}revived via injected registry; upstream CodeMode telemetry (upstream_tool_calls_total{server,tool,status}withtimeoutclassification,upstream_tool_duration_seconds,upstream_retries_total);code_mode_servers_skipped_total{reason}+ WARN + degraded serve banner when server injection fails; label-cardinality cap (_MAX_LABEL_COMBOS=200, overflow coalesces to_other); slow-request WARN (threshold 1000ms); CLI structured events (WARNING always, INFO gated byMCP_GWAY_LOG_LEVEL). No prod deps added — stdlib + vendored registry only. - feat(cli): opt-in
--retry-on-transport-errorformcp-gway add— retries exactly once only when the transport/connect+initialize phase fails, never aftersession.call_toolstarts (non-idempotency-safe, ADR-012 decision 9). Default off → zero behavior change for existing configs.
v2.2.0 (2026-09-11)
- feat: add
AIdirectory to.gitignoreso local Claude skills are never committed (a559bbc). Version bump only — no runtime changes.
v2.1.2 (2026-09-11)
- fix(policy): harden break-glass marker create/remove/status with explicit CLI (
mcp-gway local-unrestricted enable|disable|status) — marker ops distinguish missing vs failure and fail closed (416ef38).
v2.1.1 (2026-09-11)
- fix(mcp): typed JSON-RPC errors
-32602(invalid params) /-32603(internal) withdatacarrying safe[reason=...]tokens;.pyistub sanitization; parameter validation on tool calls (dd8e52b).
v2.1.0 (2026-09-11)
- feat(mcp): stdio local mode —
mcp-gway mcpserves NDJSON JSON-RPC over stdin/stdout (usable as an OpenCodetype: localserver viacommand: [mcp-gway, mcp]), with hardened client-side transport (filtered_stdio_client) that drops non-JSON noise from child servers (cec3277).
v2.0.1 (2026-09-10)
- fix(policy): expand environment denylist — exact
PATH, PATHEXT, SYSTEMROOT, COMSPEC, LD_PRELOAD, LD_LIBRARY_PATH, PYTHONPATH, PYTHONHOME, NODE_OPTIONS, NODE_PATH, NODE_EXTRA_CA_CERTS, NODE_TLS_REJECT_UNAUTHORIZED+ prefixesDYLD_, NPM_CONFIG_, BUN_, UV_(e9d4d5f). - docs: allow-list wording sync — exact denylist and
bunxopt-in CISO note (pin + owner + regate 90d; runtime stays out) (2b26b3d,218148f). - docs(release): sync ADR-007 to
python-semantic-releasev10 (ce89db7). - tests: drop legacy monkeypatch paths in transport tests (
814c0db).
v2.0.0 (2026-09-10)
-
breaking: removed dashboard (
/dashboard,/api/servers,/static,/alias) and catalog (/api/catalog,/dashboard/catalog, Bifrost fetch,~/.config/mcp-gway/catalog.jsoncache). Gateway serves/mcp,/health,/ready,/live,/metricsonly; management is CLI-only. Droppedhtpydependency (httpxkept). Delete stale cache manually:rm ~/.config/mcp-gway/catalog.json. -
feat-006: Dynamic-no-static local allow-list + 72h break-glass (ADR-009)
- Default-deny: empty
MCP_GWAY_ALLOW_LOCAL_COMMANDSdenies alllocal; CSV basenames,*invalid. - Operative CISO values: default-deny BR-002..BR-016 (single syntax rule, allow-list, 72h TTL, VIA+loopback gate,
which-only spawn,cwd/env gates, audit***), break-glassMCP_GWAY_ALLOW_UNRESTRICTED_LOCAL=1+ marker~/.config/mcp-gway/.local_unrestricted(epoch,0o600, 72h TTL). - Closes PATCH
from_editbypass; re-gates POST/PATCH/refresh/catalog + CLIadd/refresh; DashboardALLOW = VIA=1 AND (unrestricted OR in allow-list) AND serve-host loopback. - Env vars (do not rename):
MCP_GWAY_ALLOW_LOCAL_COMMANDS,MCP_GWAY_ALLOW_UNRESTRICTED_LOCAL,MCP_GWAY_ALLOW_LOCAL_VIA_DASHBOARD.
- Default-deny: empty
Migration
- Endpoints servidos solo
/mcp,/health,/ready,/live,/metrics; gestión CLI-only. - Delete stale cache:
rm ~/.config/mcp-gway/catalog.json. - Vars:
MCP_GWAY_ALLOW_LOCAL_COMMANDS/MCP_GWAY_ALLOW_UNRESTRICTED_LOCAL/MCP_GWAY_ALLOW_LOCAL_VIA_DASHBOARD.
v0.9.1 (2026-08-25)
Bug Fixes
-
dashboard: Filter, type toggle, hover, pill centering, tooltips and spacing (
bca81a6) -
Extract inline script to vendored dashboard.js to fix CSP blocking (filter by name and remote/local toggle now work, re-hydrates on htmx:load) - Fix table row buttons blocked by capture stopPropagation in dialog.js (remove capture listener) - Fix search icon alignment (inset-y-0 flex centering vs translate) - Fix stats cards too close to header (pt-8 gap-8) - Fix healthy pill centering and size (justify-center gap-1 px-2 leading-none) - Fix row hover missing (hover:bg-slate-50 vs purged /80) - Add native tooltips via title on View/Toggle/Delete/Refresh/Reveal/Copy/Close for accessibility
v0.9.0 (2026-08-25)
Chores
- lock: Sync uv.lock to 0.8.0
(
9aaef3f)
Match pyproject.toml and src/mcp_gway/init.py after 0.8.0 semantic release; previous lock at 0.7.1 causing inconsistent build metadata.
Features
- dashboard: Expose dashboard at root path
(
7686d48)
Serve the same SSR dashboard on both root and dashboard via handle_dashboard alias. Keeps local-first gating, CSP and X-Warning behaviour identical so index path fulfils product requirement that root must load the dashboard, not 404. Single handler reuse avoids duplication and preserves bounded-context purity.
v0.8.0 (2026-08-25)
Features
- dashboard: Swiss minimal redesign with micro-interactions for lazy-person UX
(
333180b)
Redesign dashboard under ui-ux-pro-max minimalism-and-swiss-style: header glass + stats grid, row stagger 28ms with reduced-motion, badges with dot/status, filter, progressive disclosure form, drawer and empty state polish. Vendored Tailwind expanded to 14KB covering new utilities while staying local-first and <100KB. 188 tests pass, ruff clean.
v0.7.2 (2026-08-25)
Bug Fixes
- dashboard: Harden dialog resilience and clean architecture
(
70c64df)
Resilience C1: dialog.js now handles htmx:responseError/sendError/ timeout/swapError with handleDialogError -> toast + fallback aside panel inside dialog, reuses server error HTML and htmx.process. Set htmx.config.timeout=7000 so offline/slow doesn't hang.
Resilience I1: hx-indicator #global-spinner on tr and View button, global timeout, indicator wiring.
Readability/Reliability: extract _DIALOG_ID/_DIALOG_TARGET/_CLOSE_ATTRS, _BASE_BADGE/_BADGE_COLORS, split server_drawer 210 lines into _drawer_header/_drawer_metadata/_drawer_actions/_tool_panel, fix nested role dialog -> region inside native dialog, delegate stopPropagation via single document click listener (survives #server-table-body swaps), dedup openDialog/clearDialog helpers, isEmpty robust via childElementCount, documented delays.
Tests: add 7 hardening tests for dialog contract (layout has dialog no drawer, row targets dialog + indicator, drawer returns aside region, dialog.js resilient tokens, detail panel, close clears, no inline onclick) -> 188 passed, ruff clean.
- dashboard: Migrate drawer to native dialog with vendored style
(
129654b)
Drawer inline was rendered at page bottom (screenshot shandcn below footer, truncated) instead of overlay — broke UX and a11y. Replace div#drawer fixed overlay with native using existing Tailwind vendored style (backdrop blur, shadow-xl, border-l).
- views.py: hx-target #drawer -> #server-dialog, remove inline onclick stopPropagation (CSP default-src 'self'), drawer_error/ server_drawer now return aside only, layout hosts + script /static/dialog.js external - static/dialog.js: showModal/close, backdrop click, ESC cancel, htmx:afterSwap/afterSettle open/close, delegated stopPropagation for row buttons without inline handlers - static/tailwind.css: vendor missing utilities for dialog (m-0 p-0 max-w-none w-screen h-screen backdrop:* open:flex etc) <7.6KB, htmx 2.3KB, dialog 2.8KB, no Node
Verified 181/181 pytest, ruff ok, layout contains and no id=drawer, /static/dialog.js served with showModal.
v0.7.1 (2026-08-25)
Chores
- release: Expand semantic-release triggers to automate patch releases
(
abf3beb)
Expand patch_tags from [fix, perf] to include refactor, docs, build, chore, style, test, ci, revert so workflow_run Tests + python-semantic-release triggers automated patch on any conventional commit. Add revert to allowed_tags for completeness. Keeps minor_tags=[feat] and BREAKING CHANGE->major intact to preserve semver; hybrid workflow push v* + workflow_run Tests + concurrency:release prevents duplicate versions. No Node, pure ruff/uv.
Documentation
- dashboard: Sync v0.7.0 GA specs and polish dashboard bottom UI
(
23c6f8b)
Sync AGENTS.md, README.md and SPEC-UI-001 with shipped v0.7.0 GA so docs match code and close the SBTDD verification gate (Registry single source, htpy+htmx bounded context, local-first 127.0.0.1, masking ***).
Polish src/mcp_gway/dashboard/views.py bottom area: sticky table header, action group (View/Toggle/Delete) with hx-* handlers, footer, drawer/header and spacing refinements with transition/shadow polish for visual completeness. No logic change, only presentation.
Verified: ruff check/format pass, 181 pytest pass, dashboard SSR/API intact. Keeps history atomic before push per CEO GO.
v0.7.0 (2026-08-25)
Bug Fixes
-
dashboard: P0 refuter fixes - form double-read, htmx load, payload OOM, hide 405 actions (
1dad496) -
api.handle_create: check Content-Type before consuming body; Content-Length pre-check before read prevents OOM; JSON branch reads body only when application/json else uses form without prior body() to avoid empty form (fixes H-01). Enforce 413 for both branches.
-
htmx.min.js stub: add DOMContentLoaded loader for hx-trigger load so GET /dashboard/servers auto-fetches; support hx-swap outerHTML, keep <20KB, no Node.
-
views.server_row: hide Wave1-unimplemented hx-delete/hx-patch (would 405); Wave1 demo shows only inspect. Keeps js handlers for Wave2.
-
local gating: retain MCP_GWAY_ALLOW_LOCAL_VIA_DASHBOARD default 1 (dashboard allows local unless 0) - documented.
Verified: ruff clean, 171 pytest green, manual form hx POST 201, content-length 413.
-
security: P0 hardening for dashboard and registry (BR-UI-003/004/009, HC-03/05, EC-01..04, AC-09) (
c3216df) -
models: strict regex ^[A-Za-z_][A-Za-z0-9_]{0,63}$ + reserved (con,prn,aux,nul,com1-9,lpt1-9) + reject / \ . .. and < > ; ensures ../../evil, /absolute, a/b, .. etc 400 - registry: _safe_path with regex + resolve().is_relative_to() defense-in-depth, atomic write via .tmp replace, guard all servers_dir usages - oauth: FileTokenStorage validates server_name with same regex and traversal check - dashboard/api: html.escape for all toasts/detail, form vs json content-type handling, payload limit 1M ->413, semaphore(3) for discovery, validate via MCPServerConfig before existence, generic validation_error without secret leak, delegate to Registry only, local via dashboard gated by env - dashboard/views: urllib.parse.quote for detail/delete URLs, htpy auto-escape kept - cli/gateway: serve defaults 127.0.0.1, gate non-loopback behind MCP_GWAY_ALLOW_REMOTE=1 else exit 2, X-Warning header for non-loopback - tests: existing 171 green, manual curl checks for traversal, XSS, form hx, masking ***
Chores
- Add pre-commit hook enforcing ruff check+format locally
(
1eee823)
Prevent future CI failures like run 32782781915 where ruff F401+I001 blocked pipeline and caused Release skip. Add deterministic local gate so git commit fails fast if lint not clean - haces las cosas con excelencia desde el commit 1.
-
.pre-commit-config.yaml pinned to astral-sh/ruff-pre-commit v0.16.4 with ruff --fix and ruff-format plus hygiene hooks (trailing-whitespace, end-of-file-fixer, check-yaml, check-added-large-files) - pyproject.toml dev group adds pre-commit>=4.0.0 - AGENTS.md documents uv run pre-commit install and run --all-files with CI parity ruff commands - Fix trailing whitespace in spec uncovered by new hook - Verified: uv run pre-commit run --all-files, ruff check/format, and pytest 152 passed exit 0
-
Sync uv.lock to 0.6.0 (
2963e8b)
Co-authored-by: Vasquez deuriib@gmail.com
- ci: Bump workflows to latest Node24 (checkout v7, setup-python v7, setup-uv v10)
(
a407e8f)
Opcion B (latest estable) sobre A (minimo). CTO pidio explicitamente B: llevar todo a latest Node24 nativo con security hardening y sin warnings Node20. Preserva logica de jobs, solo bump de tags.
Bumps: - actions/checkout@v5.0.1 -> @v7.0.1 (latest Node24 immutable, publicado 20-jul-2026, ESM, fix SHA-256 repos y fork-PR blocking; action.yml using: node24 verificado) - actions/setup-python@v6.3.0 -> @v7.0.0 (latest Node24 ESM, publicado 20-jul-2026; action.yml using: node24 verificado) - astral-sh/setup-uv@v7.0.0 -> @v10.0.1 immutable via SHA 20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 (latest Node24 immutable desde v8.0.0, publicado 14-ago-2026; action.yml using: node24 verificado; SHA pin es ideal immutable, tag @v10.0.1 tambien immutable)
Trade-offs vs A: - A = higiene minima (primer major Node24: checkout v5, setup-python v6, setup-uv v7) minimo bump, minimo riesgo. - B = latest estable: mas fixes/security hardening (checkout v7 SHA-256 + ESM + allow-unsafe-pr-checkout), setup-python v7 ESM, setup-uv v10 ultimas features/perf. Mayor churn de major pero still Node24 native y elimina deuda futura. Elegido por decision explicita CTO.
Compatibilidad runner: - checkout@v7 y setup-python@v7 (ESM) requieren runner >=v2.327.1. ubuntu-latest actual es v2.330+ -> OK.
Breakings documentados (no mitigados, comportamiento seguro deseado): - setup-uv@v10: enable-cache auto ahora deshabilita cache en workflow_run y release (seguridad #984). Nuestro release.yml es workflow_run -> cache se deshabilitara por defecto. Es el comportamiento seguro deseado, no se hace override. - checkout@v7: nuevo allow-unsafe-pr-checkout=false bloquea checkout de fork PR en workflow_run/pull_request_target. Nuestro release.yml corre sobre workflow_run de Tests en main/master (no fork) -> sin impacto, pero documentado.
No toca semver, no toca uv.lock, no mezcla otros chores. Tags completos pinned para reproducibilidad.
Validacion local: - uv run ruff check src/ tests/ -> All checks passed - uv run ruff format --check src/ tests/ -> 25 files already formatted - uv run pytest -v -> 152 passed - python yaml.safe_load ambos workflows -> YAML valid OK - grep confirma solo v7.0.1/v7.0.0/v10.0.1 (SHA), sin v5.0.1/v6.3.0/v7.0.0 residuales
-
ci: Hybrid release workflow for v0.7.0 GA (
b45dbc0) -
ci: Migrate workflows from Node20 to Node24 native (
a3b78ee)
GitHub deprecated Node20 (EOL Apr 2026, runners default Node24 since 2026-06-16). Workflows test.yml/release.yml used checkout@v4, setup-python@v5 and setup-uv@v4 (all Node20) causing 'Node.js 20 is deprecated' warnings. FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 only masks.
Migrate to minimal native Node24 majors (higiene minima, no logic change): - actions/checkout@v4 -> @v5.0.1 (first Node24; v5.0.1 chosen over v6.1.0/ v7.0.1 which are also Node24 to minimize major bump; v5.1.0 also Node24 but v5.0.1 matches ticket example and is stable patch) - actions/setup-python@v5 (Node20) -> @v6.3.0 (first Node24 major is v6; ticket incorrectly says @v5 is Node24 - corrected: v5=Node20, v6=Node24; v6.3.0 is latest v6 patch for fixes, verified v6.0.0..v6.3.0 and v7.0.0 all Node24; v7 exists but v6 is minimal) - astral-sh/setup-uv@v4 (Node20) -> @v7.0.0 (v5/v6 still Node20, v7 first Node24; verified v4/v5/v6=Node20, v7.0.0/v7.6.0/v10.0.1=Node24; v7.0.0 is minimal Node24, v7.6.0+ also Node24 but minimal chosen)
Verified python-semantic-release@v9 uses: docker and pypa/gh-action-pypi-publish@release/v1 uses: composite (no Node, no change).
Compatibility: Node24 requires runner >=2.327.1, ubuntu-latest cumple. Tags pinned con version completa para reproducibilidad.
Evidencia action.yml using: node24 consultada: - checkout@v5.0.1, v6.0.3, v7.0.0 -> node24 - setup-python@v5 -> node20, @v6.3.0/@v7.0.0 -> node24 - setup-uv@v4/v5/v6 -> node20, @v7.0.0 -> node24 - psr@v9 -> docker, pypi-publish@release/v1 -> composite
Validacion local: uv run ruff check/format OK, pytest 152 passed, YAML syntax OK, grep sin checkout@v4/setup-python@v5/setup-uv@v4, solo Node24.
- release: Bump version 0.6.0 -> 0.7.0 for GA
(
5f96c44)
Documentation
-
Promote OpenCode remote/local as primary, deprecate http/stdio/sse, document pre-commit (
e4a6745) -
README: primary remote/local examples with --header/--oauth/--timeout/--enabled/--env/--cwd, deprecated http/stdio/sse section kept for compat, Commands table updated to remote|local, Options table expanded to 12+ flags including --args/--tools/--oauth-port (deprecated compat noted), refresh/serve signatures clarified, registry description corrected to .pyi signatures + .json config, Development reflects uv sync --all-groups and pre-commit hygiene hooks (6 hooks) - AGENTS.md: CLI primary remote/local with full options pointer, deprecated note, Development with pre-commit, registry pattern updated - Fixes reliability findings F-01/F-02/F-03/F-11/F-12/F-13; --docs-url marked as deprecated not persisted per refuter
Features
- dashboard: Management MCPs dashboard GA
(
e1d52eb)
v0.6.0 (2026-08-25)
Bug Fixes
-
Address final review critical findings (
1341949) -
cli: Correct timeout None guard ordering (
8b4c5e4) -
tests: Remove unused StdioConfig and sort imports (F401, I001) (
426ff62)
Unblocks CI run 32782781915 which failed on ruff check (F401 in conftest.py:9, I001 in test_transport.py:3) causing Release 32782803712 to skip. No functional change — 152 tests pass, ruff check/format clean.
Chores
- Sync uv.lock to 0.5.2
(
e195a1f)
Documentation
- Add OpenCode schema adoption spec and plan
(
98b857f)
Co-Authored-By: Vasquez CTO vasquez@mcp-gateway
Features
-
cli: Integrate transport auto-detection (
6b9d1e6) -
cli: Opencode-style options with backward compat (
69163bd) -
models: Add MCPServerConfig with OpenCode schema (
a1771f0) -
registry: Opencode JSON format with auto-migration (
4489f97) -
transport: Auto-detect streamable-http/sse/http (
50bd03e)
Refactoring
- Update fixtures to MCPServerConfig and fix lint
(
0fb1a32)
v0.5.2 (2026-08-24)
Bug Fixes
- sandbox: Inject print as no-op to prevent Variable not found error
(
7064975)
Starlark sandbox lacked a print builtin, causing cryptic errors when users wrote print() in executeToolCode. Inject _noop as print so scripts with print() run without failing.
v0.5.1 (2026-08-24)
Bug Fixes
- Sanitize hyphenated MCP tool names for Starlark sandbox
(
55ca24d)
MCP servers like context7 expose tools with hyphens (query-docs, resolve-library-id) which break Starlark struct syntax. Add _sanitize_identifier() to convert non-identifier characters to underscores at the Starlark boundary, preserving original names for MCP calls.
v0.5.0 (2026-08-24)
Bug Fixes
- Resolve ruff lint errors (S110, I001)
(
00bb396)
Features
- Wire MCP tool execution into Starlark sandbox via ServerFactory
(
452d258)
Previously, executeToolCode ran code in an empty sandbox with no access to MCP servers. This commit bridges the gap by:
- Adding ServerFactory: creates server structs and call_tool function that wrap async MCP client calls with asyncio.run() for sync access - Extending StarlarkSandbox with set_global() for injecting functions - Wiring CodeMode to inject call_tool + server structs on init - Updating executeToolCode description to document tool access
112 tests passing, 0 regressions.
v0.4.4 (2026-08-24)
Bug Fixes
-
Mock win32 platform in absolute_path_invalid test for CI (Linux) (
1c8faad) -
Use Self type for aenter/aiter (ruff PYI034) (
349986e) -
Windows stdio transport — command resolution, noise filter, env passthrough (
c4c2a69) -
Add stdio_transport.py: resolve_windows_command prefers .exe over .cmd/.bat to bypass cmd.exe banner injection on Windows - Add filtered_stdio_client: wraps MCP SDK stdio_client, drops non-JSON parse failures from read stream with on_noise callback - Fix _FilteredReadStream to implement async context manager protocol (aenter/aexit) required by MCP SDK dispatcher - Fix t.inputSchema -> t.input_schema for MCP SDK v2 compatibility - Wire StdioConfig.envs -> StdioServerParameters.env with --env CLI option - Wire on_noise callback in production (logs warning to stderr) - 22 new tests in test_stdio_transport.py, 3 new tests in test_cli.py, 1 new test in test_registry.py (96/96 pass, ruff clean)
v0.4.3 (2026-08-24)
Bug Fixes
- Refresh continues after individual server errors
(
4a9afe3)
Extract _refresh_server as standalone async function (was defined inside the for loop). Wrap each server refresh in try/except so a failure in one server does not abort the entire refresh cycle.
v0.4.2 (2026-08-24)
Bug Fixes
- Parse stdio command from connection_string in old .pyi fallback
(
1acdeed)
Old-format STDIO .pyi files store the command in # connection_string: instead of # stdio_command:. The fallback parser was checking for stdio_command first and creating no StdioConfig when it was missing, causing validation errors on refresh.
v0.4.1 (2026-08-24)
Bug Fixes
- List command reads connection type from JSON config
(
988bba3)
list_servers() was parsing .pyi comments for connection_type, which no longer exist in the new JSON-based format. Now reads from get_config() which handles both JSON and legacy .pyi comment fallback.
v0.4.0 (2026-08-24)
Features
-
Auto-auth OAuth flow, stdio config persistence, token cleanup (
0c4d448) -
Add force_auth param to _discover_tools for conditional OAuth - Add/remove/refresh commands try without auth first, OAuth only on failure - Persist stdio_command and stdio_args in .pyi registry files - Clean up stored OAuth tokens on server remove - Backward compat for old .pyi files without stdio comments - Add comprehensive tests for all new behaviors
-
Harden gateway with session TTL, sandbox timeout, clean registry, and configurable OAuth (
6d51ebc) -
Session TTL + cleanup: evict idle sessions after 5min, send None sentinel to close SSE streams, return JSON-RPC error for expired sessions - Real sandbox timeout: ThreadPoolExecutor with configurable timeout (default 30s), SandboxTimeoutError for slow injected callbacks - Deduplicate _discover_tools: extract _create_client_transport async context manager, single flight path for all connection types - STREAMABLE_HTTP validation: require connection_string in model_post_init - Configurable OAuth port: --oauth-port option on add/refresh commands - Clean registry: config in JSON files, .pyi contains only tool signatures, backward compatible with old comment-style .pyi files - serverInfo.version now reads version instead of hardcoded 0.1.0 - 22 new tests (71 total), all passing, lint clean
v0.3.0 (2026-08-24)
Features
- Move servers/ to ~/.config/mcp-gway/servers/
(
db62a5a)
v0.2.1 (2026-08-24)
Bug Fixes
- Return docs_url in getToolDocs instead of opening browser
(
7bc1457)
v0.2.0 (2026-08-24)
Features
- Add --docs-url option and open browser in getToolDocs
(
c41f412)
v0.1.4 (2026-08-24)
Bug Fixes
- Update config path to mcp-gway in oauth, gateway, cli
(
9ce40ba)
Documentation
- Update package name to mcp-gway in README and AGENTS
(
6a3e48e)
v0.1.3 (2026-08-24)
Bug Fixes
-
Rename package to mcp-gway for PyPI (
e1e6622) -
Rename Python module to mcp_gway to match PyPI package name (
4c6de5d)
v0.1.2 (2026-08-24)
Bug Fixes
- Build package after semantic release bumps version
(
be80eeb)
Continuous Integration
- Chain release workflow to run after tests pass
(
bfe88bc)
v0.1.1 (2026-08-24)
Bug Fixes
- Update docstring format
(
f421602)
v0.1.0 (2026-08-24)
Chores
Continuous Integration
-
Add semantic release and fix uv installation (
e6db163) -
Replace publish.yml with release.yml for automatic versioning - Add python-semantic-release configuration - Fix uv installation in GitHub Actions using astral-sh/setup-uv - Add branch triggers for main and master
Features
-
Cli commands for MCP gateway management (
f86a9ae) -
Code mode with 4 meta-tools (
12e3f72) -
Http/sse gateway server with JSON-RPC 2.0 (
edaba81) -
Integration test and project documentation (
b55a40b) -
Oauth support, refresh command, SSE transport, and project docs (
bc5d5d0) -
Added OAuth 2.0 support with dynamic client registration (RFC 7591) - Added refresh command for re-authenticating and re-discovering tools - Added POST /mcp endpoint for direct JSON-RPC - Added streamable-http transport type - Added agentmemory, context7, supabase, betterfullstack MCP servers - Professional README with architecture diagram - AGENTS.md for AI assistants - GitHub Actions workflows for testing and PyPI deployment - MIT License
-
Project scaffold with models and tests (
22f4b80) -
Registry for .pyi file CRUD operations (
65d69ee) -
Starlark sandbox and server proxy for code mode (
1e63043)