Time: Untimed
Workshop: Non-SDLC agent
Museum Exhibit Studio turns educator-approved facts into visitor-ready exhibit copy:
approved facts -> bounded prompt -> curator session -> structural checks -> human review
You build one growing console application in place, inside start-museum/<language>. Each
step adds one idea and ends with a real run, so the curator comes together in front of you:
| Step | You add | You see |
|---|---|---|
| 1 | A client, a session, one prompt | Museum copy in your terminal |
| 2 | The pre-built streaming printer | Text arriving live |
| 3 | The curator system message | A different voice and shape |
| 4 | The approved-fact tool, prompt, and bounded session runner | Copy that tracks your facts |
| 5 | The pre-built validator | A PASS/FAIL structural report |
| 6 | A scoped Wikipedia research session | Cited background, kept out of the exhibit |
| 7 | An interactive page | exhibit.html in your browser |
| 8 | A celebration and resources | Your next project starts here |
The seven hands-on steps take about 90 minutes. Complete them in order, then celebrate what you built and explore the resources in the final step.
The starter already ships the plumbing you should never have to write: the approved fact sets and
their bounds, the fact-selection menu, a streaming printer, deterministic exhibit validation, the
scoped Wikipedia MCP server with its deny-by-default permission handler, the single-file
exhibit.html write permission, the system messages, the fixed prompt text for the exhibit
structure, the research request, and the page requirements, and the error handling around your
code. You never edit the helper files. You write the SDK code: the session setup, the tool
registration and session configurations, the instructions in the exhibit and page prompts, and one
session runner.
You need an authenticated GitHub Copilot CLI, your language runtime, and a terminal. You work
directly in the minimal project under start-museum/<language>, not the finished app. The completed
project under finished/<language>/museum-exhibit-studio is optional reference material only.
git clone https://github.com/github/copilot-sdk-workshop.git
cd copilot-sdk-workshopConfirm the terminal is at the repository root before you change into a starter:
test "$(git rev-parse --show-toplevel)" = "$PWD"The command must exit successfully without output.
You build the museum application in place, inside the starter directory for your language.
There is no copy step. That means you are editing tracked repository files, so your work shows up in
git status as modified files. That is expected and correct. If you want to start over from a clean
starter, run git checkout -- . from the repository root to discard your edits.
Change into your language's starter directory now and stay there for every command in the museum workshop.
:::language dotnet Change into the .NET starter, then restore, build, and run its local entrypoint:
cd start-museum/dotnet
dotnet restore
dotnet build --no-restore
dotnet run --no-buildPass condition: the build succeeds and the program prints === Museum Exhibit Studio starter ===
followed by Pre-built curator helpers are ready in Helpers/.
You work in start-museum/dotnet for the rest of the workshop, so keep this terminal here. From
this folder, enter code . to open it in VS Code, or open the folder in your favorite editor.
Your helper module is Helpers/Curator*.cs in the MuseumExhibitStudio.Helpers namespace. You
will write every lesson change in Program.cs.
:::
:::language nodejs
Change into the Node.js starter. Its lockfile preserves SDK 1.0.11 and
the compatible @github/copilot 1.0.80 platform package:
cd start-museum/nodejs
npm ci --ignore-scripts --no-audit --fund=false
npm run build
npm startPass condition: the build succeeds and the program prints === Museum Exhibit Studio starter ===
followed by Pre-built curator helpers are ready in src/curator.ts.
You work in start-museum/nodejs for the rest of the workshop, so keep this terminal here. From
this folder, enter code . to open it in VS Code, or open the folder in your favorite editor.
Your helper module is src/curator.ts, and the system messages are in src/system-messages.ts.
You will write every lesson change in src/index.ts.
:::
:::language python Change into the Python starter, create an isolated virtual environment, and install SDK 1.0.11:
cd start-museum/python
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m py_compile *.py
.venv/bin/python main.pyOn Windows, the interpreter lives at .venv/Scripts/python.exe.
Pass condition: the source compiles and the program prints === Museum Exhibit Studio starter ===
followed by Pre-built curator helpers are ready in curator.py.
You work in start-museum/python for the rest of the workshop, so keep this terminal here. From
this folder, enter code . to open it in VS Code, or open the folder in your favorite editor.
Your helper module is curator.py, and the system messages are in system_messages.py. You will
write every lesson change in main.py.
:::
:::language go Change into the Go starter, download the locked SDK 1.0.11 dependency, and build it:
cd start-museum/go
go mod download
go build -mod=readonly ./...
go run .Pass condition: the build succeeds and the program prints === Museum Exhibit Studio starter ===
followed by Pre-built curator helpers are ready in curator.go.
You work in start-museum/go for the rest of the workshop, so keep this terminal here. From
this folder, enter code . to open it in VS Code, or open the folder in your favorite editor.
Your helper module is curator.go, and the system messages are in system_messages.go. Both are
in the same main package. You will write every lesson change in main.go.
:::
:::language rust Change into the Rust starter, fetch locked dependencies, and check it:
cd start-museum/rust
cargo fetch --locked
cargo check --locked
cargo run --lockedPass condition: Cargo leaves Cargo.lock unchanged and the program prints
=== Museum Exhibit Studio starter === followed by
Pre-built curator helpers are ready in src/lib.rs.
You work in start-museum/rust for the rest of the workshop, so keep this terminal here. From
this folder, enter code . to open it in VS Code, or open the folder in your favorite editor.
Your helper module is the museum_exhibit_studio library crate in src/lib.rs, with the system
messages in src/system_messages.rs. You will write every lesson change in src/main.rs.
:::
:::language java
Change into the Maven starter, resolve SDK 1.0.11, compile, and run it with the included
Maven Wrapper (no separate Maven install needed; on Windows, use mvnw.cmd instead of ./mvnw):
cd start-museum/java
./mvnw dependency:go-offline
./mvnw compile
./mvnw exec:javaPass condition: Maven succeeds and the program prints === Museum Exhibit Studio starter ===
followed by Pre-built curator helpers are ready in src/main/java/workshop/.
You work in start-museum/java for the rest of the workshop, so keep this terminal here. From
this folder, enter code . to open it in VS Code, or open the folder in your favorite editor.
Your helper module is src/main/java/workshop/Curator*.java. You will write every lesson change
in src/main/java/workshop/MuseumExhibitStudio.java.
:::
Open the entrypoint named at the end of your setup block above. Every place you write code is a named region between two marker comments:
>>> BEGIN generation-config | Step 4: INSERT | Step 6: REPLACE
<<< END generation-config
The BEGIN line lists every step that touches the region, so the file doubles as a map of the
workshop. Each code block in a lesson is introduced by a line that names its region and one of two
actions:
| Action | The region is | What you do |
|---|---|---|
| INSERT | Empty | Paste the block between the two marker lines. |
| REPLACE | Holding code from an earlier step | Delete everything between the two marker lines, then paste the block. |
A block is always the complete contents of its region, so you never merge code by hand. Leave the marker lines, and the code outside the regions, exactly as they are.
| Control | What it can do |
|---|---|
| System message | Guide role, tone, scope, and output shape |
| Tool allowlist | Decide exactly which tools exist for a session |
| Application code | Own the data behind a tool, and enforce limits, timeout, validation, and cleanup |
| Human review | Decide whether every historical claim is supported |
The educator's approved facts are the only approved source, and the curator reaches them through one application-owned tool. Model memory is not verified museum knowledge, and prompt guidance is not an authorization boundary: only the allowlist and the permission handler decide what the session may actually do.
The SDK behind the curator is documented outside this workshop. These pages are worth having open alongside it.
- GitHub Copilot SDK how-tos: GitHub's own SDK documentation, including the prerequisites this preflight covers.
- Copilot SDK documentation map: the index for setup, authentication, features, and troubleshooting.
- Default setup: the bundled CLI: how the SDK locates and starts the Copilot CLI, and how to point it at a different binary.
- Debugging guide: the first place to look when a run fails before it produces any output.
:::language dotnet
- .NET SDK reference: package installation and a minimal example for the .NET SDK. :::
:::language nodejs
- Node.js SDK reference: package installation and a minimal example for the Node.js SDK. :::
:::language python
- Python SDK reference: package installation and a minimal example for the Python SDK. :::
:::language go
- Go SDK reference: module installation and a minimal example for the Go SDK. :::
:::language rust
- Rust SDK reference: crate installation and a minimal example for the Rust SDK. :::
:::language java
- Java SDK reference: dependency coordinates and a minimal example for the Java SDK. :::
Continue to Your first curator session.