{"id":51490179,"url":"https://github.com/icholy/mcpswap","last_synced_at":"2026-07-07T11:01:07.768Z","repository":{"id":359808403,"uuid":"1240701756","full_name":"icholy/mcpswap","owner":"icholy","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-23T15:44:13.000Z","size":78,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-23T17:06:18.518Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/icholy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-16T13:10:59.000Z","updated_at":"2026-05-23T15:44:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/icholy/mcpswap","commit_stats":null,"previous_names":["icholy/mcproxy"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/icholy/mcpswap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fmcpswap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fmcpswap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fmcpswap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fmcpswap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/icholy","download_url":"https://codeload.github.com/icholy/mcpswap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fmcpswap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35225029,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-07T11:01:06.924Z","updated_at":"2026-07-07T11:01:07.752Z","avatar_url":"https://github.com/icholy.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mcpswap\n\nA single-upstream MCP adapter. It fronts one upstream MCP server\n(stdio, SSE, or streamable-HTTP) and exposes it over an HTTP endpoint,\nforwarding tools, prompts, and resources through unchanged. The active\nupstream session can be hot-swapped at runtime, which lets an embedder\nrotate credentials (e.g. refresh an OAuth token) without dropping\nin-flight requests.\n\n## Usage\n\n```go\nvar up mcpswap.Upstream\n\n// Swap accepts any mcp.Transport. Use the transport's HTTPClient for\n// auth headers, retries, etc.\ntransport := \u0026mcp.StreamableClientTransport{Endpoint: \"https://api.example.com/mcp/\"}\nif err := up.Swap(ctx, transport); err != nil {\n    return err\n}\n\nsrv := mcp.NewServer(\u0026mcp.Implementation{Name: \"mcpswap\", Version: \"0.1.0\"}, \u0026mcp.ServerOptions{\n    HasTools:     true,\n    HasPrompts:   true,\n    HasResources: true,\n})\nsrv.AddReceivingMiddleware(up.Dispatch)\nhttp.ListenAndServe(\":8080\", mcp.NewStreamableHTTPHandler(\n    func(*http.Request) *mcp.Server { return srv }, nil,\n))\n```\n\n`Upstream.Dispatch` is an `mcp` receiving middleware that forwards\nlist/call/get/read requests to the active upstream session; add it to\nyour own `mcp.Server`.\n\n`Upstream.Swap` connects a new session and atomically replaces the\nactive one, closing the previous session in the background. On failure\nthe active session is left untouched, so callers may retry or keep\nserving on the old session. To rotate credentials, build a fresh\ntransport and call `Swap` again — the mechanism is identical across\ntransports. `mcpswap` ships no rotation policy: when and how you\nre-`Swap` is up to you.\n\n## Transports\n\n`Swap` accepts any `mcp.Transport`, so the upstream can be stdio\n(`mcp.CommandTransport`), streamable-HTTP (`mcp.StreamableClientTransport`),\nor SSE (`mcp.SSEClientTransport`). `mcpswap` does not construct\ntransports — build whichever you need and hand it to `Swap`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficholy%2Fmcpswap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficholy%2Fmcpswap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficholy%2Fmcpswap/lists"}