{"id":51505764,"url":"https://github.com/github/copilot-sdk-server-sample","last_synced_at":"2026-07-08T00:02:14.028Z","repository":{"id":369693470,"uuid":"1199465885","full_name":"github/copilot-sdk-server-sample","owner":"github","description":"Sample of a multiuser system using GitHub Copilot SDK","archived":false,"fork":false,"pushed_at":"2026-07-06T13:23:13.000Z","size":828,"stargazers_count":15,"open_issues_count":2,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-06T14:10:54.143Z","etag":null,"topics":["copilot","copilot-cli","copilot-sdk"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/github.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE.md","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-02T11:28:36.000Z","updated_at":"2026-07-06T13:08:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/github/copilot-sdk-server-sample","commit_stats":null,"previous_names":["github/copilot-sdk-server-sample"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/github/copilot-sdk-server-sample","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fcopilot-sdk-server-sample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fcopilot-sdk-server-sample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fcopilot-sdk-server-sample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fcopilot-sdk-server-sample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/github","download_url":"https://codeload.github.com/github/copilot-sdk-server-sample/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2Fcopilot-sdk-server-sample/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35246561,"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":["copilot","copilot-cli","copilot-sdk"],"created_at":"2026-07-08T00:02:13.297Z","updated_at":"2026-07-08T00:02:14.013Z","avatar_url":"https://github.com/github.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitHub Copilot SDK — Session Server Sample\n\nA sample app demonstrating one possible way to build a multi-user, server-hosted agent chat experience. This is built using [GitHub Copilot SDK](https://github.com/github/copilot-sdk), so it can complete challenging real-world tasks using the same proven harness that powers Copilot CLI.\n\nIn this sample, each user gets an isolated session with its own virtual filesystem and virtual bash runtime, all managed server-side.\n\n![Screenshot](docs/screenshot.png)\n\nThe agent can manage its own files, write and execute Python code, and use `curl` to access only pre-approved web resources.\n\n⚠️ This is a sample to demonstrate a possible app architecture. It's not an app you could deploy as-is, since it lacks important security features such as auth, and the filesystem isolation is limited. See [limitations](#limitations) for more details.\n\n## Running the sample\n\nYou need a GitHub token (a fine-grained PAT with no special permissions, or the output of `gh auth token`). This token is used by Copilot SDK to perform AI inferencing using a model approved for your account.\n\n```bash\n# On Bash (macOS/Linux)\nGITHUB_TOKEN=\u003cyour-token\u003e docker compose build --no-cache\nGITHUB_TOKEN=\u003cyour-token\u003e docker compose up\n\n# On PowerShell (Windows)\n$env:GITHUB_TOKEN=\"\u003cyour-token\u003e\"\ndocker compose build --no-cache\ndocker compose up\n```\n\nWhen it's running, open [http://localhost:3001](http://localhost:3001).\n\n### In-memory mode\n\nBy default, each session's virtual filesystem (VFS) is backed by disk. You can see and edit all the virtual filesystems inside `app/sessions`.\n\nTo use a purely in-memory virtual filesystem instead, set an environment variable `USE_IN_MEMORY_VFS` to `true` and re-run `docker compose up`.\n\nIn realistic server deployments it would be better to use disk rather than in-memory storage, because disk space is more cheaply available. But if you're building a client-side application that creates large numbers of short-lived agent sessions, it might work well to use an in-memory VFS.\n\n## Architecture\n\n```mermaid\ngraph LR\n    Users((Users)) --\u003e LB[Load Balancer]\n    LB --\u003e App1[App Server 1]\n    LB --\u003e App2[App Server 2]\n    App1 --\u003e|rsync| FS[(rsync-filestore)]\n    App2 --\u003e|rsync| FS\n```\n\n### Per-session isolation\n\nWhen a user connects, the app server creates an isolated session with:\n\n- A **Copilot SDK session** (`CopilotSession`) that maintains conversation state, tool handlers, and event streaming.\n  - We limit it to using tools that are intended to be safe in multi-user environments because they don't read/write files.\n  - The session's only tool that can operate on disk is `bash`, but this is swapped out for a virtual version (see below).\n- A **virtual filesystem** (in-memory or disk-backed) scoped to that session. The Copilot agent reads and writes files within this filesystem only. It cannot see the server's disk or the state of other sessions.\n- A **virtual bash runtime** ([just-bash](https://github.com/aspect-build/just-bash)) attached to the virtual filesystem, exposed to the agent as a tool. Network access is restricted to a small allowlist.\n\nMultiple browser tabs can observe the same session simultaneously — the server maintains a single `CopilotSession` per session ID and fans out events to all connected WebSockets. To see this, copy and paste your session URL into a second browser window or tab.\n\n### Scaling across multiple app servers\n\nThe architecture supports running multiple app server instances behind a load balancer:\n\n- **Session files are synced to a shared filestore.** After each agent turn completes, the app server pushes the session's directory to the `rsync-filestore` container using rsync. This is incremental and efficient.\n- **Sessions can be resumed on any server.** When a user reconnects (possibly to a different app server), the server restores the session files from the filestore before resuming the Copilot session.\n- **App servers clean up local storage.** Once all WebSocket connections for a session close, the app server deletes the local copy. This keeps each server's disk usage bounded.\n\nThe `rsync-filestore` container is a minimal Alpine image running an rsync daemon. It serves as the persistent, shared store that survives app server restarts and enables session mobility across servers.\n\n**This is just one possible example of how to balance performance and resilience to server recycling.** Other strategies are also possible, because the storage virtualization APIs in Copilot SDK allow you to store things anywhere you like. For example you could directly stream session events to an event store rather than letting them be written to disk in the first place. But for this example, simply synchronizing and restoring the session's entire VFS is a simple and comprehensive solution.\n\n## Code structure\n\n * `app`: the application server. You could run many instances and load balance over them.\n   * `api`: server-side code that defines and manages agent sessions\n     * `chatSocket.ts`: starts a WebSocket listener. As clients connect/disconnect, starts and stops `CopilotSession` instances and synchronizes storage to `rsync-filestore`\n     * `storage/`: simple VFS implementations\n     * `bash.ts`: swaps out Copilot SDK's built-in shell tool with one backed by [just-bash](https://github.com/vercel-labs/just-bash). This is simply an example - you could instead map it into a per-session container, any other isolated shell. Various other open source projects provide isolated shells.\n   * `web-ui`: an Express+React application providing the user interface\n     * `hooks/useChat.ts`: opens the websocket connection to `api/chat` and uses a reducer pattern to convert the event stream into a UI\n     * everything else: generic chat UI (a lot of code but nothing interesting)\n * `rsync-filestore`: a minimal `rsync` server that provides persistent storage shared by all application servers\n\n## Limitations\n\n\u003e **⚠️ GitHub Copilot SDK is under active development and patterns for multi-user deployment are still evolving.**\n\nThis example illustrates many useful ideas, but isn't something you can deploy as-is, because:\n\n- **No authentication.** The sample has no user authentication or session authorization. Anyone with access to the server can create or resume sessions.\n- **Not production-hardened.** Error handling, rate limiting, and resource quotas are minimal. This is a reference implementation to illustrate the architecture, not a production-ready service.\n\n## License\n\nThis project is licensed under the terms of the MIT open source license. Please refer to the [LICENSE](./LICENSE) file for the full terms.\n\n## Support\n\nThis project is a sample/reference implementation. Please use [GitHub Issues](https://github.com/github/copilot-sdk/issues) to report bugs or request features in Copilot SDK itself.\n\n## Contributing\n\nWe're not looking for contributions into this sample, since we aim to keep it simple and minimal. However we are very happy to consider contributions to [Copilot SDK](https://github.com/github/copilot-sdk).\n\nThis project adheres to a [Code of Conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Fcopilot-sdk-server-sample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgithub%2Fcopilot-sdk-server-sample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Fcopilot-sdk-server-sample/lists"}