Skip to main content
Glama
dayvough
by dayvough
README.md
# OpenCode + MCP: find a café you can work from

Build toward one question:

> Find cafés in BGC with Wi-Fi, power outlets, matcha, and Spanish latte.

The finish line is an actual MCP call that checks every loaded BGC record and returns supported matches with their evidence. **Both drinks are required. Unknown does not mean yes.**

This repo is the companion to the **AWS MCP + OpenCode** talk. The café exercise runs locally; it needs no AWS account, cloud deployment, or café API key. OpenCode uses your own configured model access.

## Get the repo

Install [Git](https://git-scm.com/downloads), [Node.js 22.19 or newer](https://nodejs.org/en/download), and [OpenCode](https://opencode.ai/docs/). OpenCode must already be able to answer a short question with your chosen model before the timed workshop starts.

```sh
git clone https://github.com/dayvough/opencode-mcp.git
cd opencode-mcp
npm ci --ignore-scripts
npm run doctor
```

Already cloned it? Run `git pull --ff-only`, then `npm ci --ignore-scripts`. Commit or stash your own edits first if Git reports a conflict; do not discard your work to follow the workshop.

**Run every command below from the repo root.** You do not need to change folders between steps. The examples use JavaScript modules, so there is no compile step.

## Follow the folders

Each folder contains the instructions and code for that stage. These are working checkpoints: inspect the small piece that changes, run it, then try the suggested edit. You can jump to the next checkpoint if you fall behind.

| Folder | What you do | Command | Time |
|---|---|---|---|
| [00 — Setup](00-setup/) | Clone, install, check your tools | `npm run doctor` | Before the timer |
| [01 — Read the data](01-data/) | See the café records and their unknowns | `npm run step:01` | 0–2 min |
| [02 — Add the filter](02-filter/) | Turn the question into explicit rules | `npm run step:02` | 2–6 min |
| [03 — Create the MCP tool](03-mcp/) | Expose the filter through the SDK | `npm run step:03` | 6–9 min |
| [04 — Inspect the call](04-inspector/) | Discover and call the tool directly | `npm run step:04` | 9–12 min |
| [05 — Connect OpenCode](05-opencode/) | Add the server to your client | `npm run step:05` | 12–15 min |
| [06 — Check the answer](06-check/) | Compare returned IDs with known answers | `npm run step:06` | 15–18 min |
| [07 — Change a record](07-change-record/) | Prove the same call reflects changed data | `npm run step:07` | 18–20 min |

Step 3 waits for a client. **Press Ctrl+C before moving on.** Step 4 launches its own server process, makes real MCP requests, and exits.

## Ask OpenCode

After step 5, restart OpenCode from this directory:

```sh
opencode mcp list
opencode
```

Ask:

> Use the cafes MCP tool find_cafes. Find BGC cafés with Wi-Fi and customer-use power outlets. Require both matcha and Spanish latte. Show the returned café IDs, sources, and source dates. Keep unknowns separate from supported matches.

OpenCode may show the tool with a server prefix, such as `cafes_find_cafes`. Inspect the tool call and its arguments. A confident paragraph without the intended tool call does not pass this exercise.

## What is happening?

```mermaid
flowchart LR
  A[Your question] --> B[OpenCode chooses tool and arguments]
  B -->|MCP tools/call| C[find_cafes]
  C --> D[Read saved café records]
  D --> E[Apply the filter in code]
  E --> F[Return matches and evidence]
  F --> B
```

On connection, the client discovers the tool with `tools/list`. When the model chooses it, the client sends `tools/call`. MCP is the shared interface. The filtering rules come from our code; the quality of the facts comes from the dataset and its sources.

OpenCode can also read files and use other tools without MCP. Keep the model, question, and other access the same when comparing the two setups. Our addition is a named, reusable search with validated inputs and checkable results.

## Two datasets, two purposes

- [The real BGC snapshot](data/bgc.cafes.md) contains source-backed branch records. The default tool reads [data/bgc.json](data/bgc.json) on every call. It is a saved snapshot, not a live scraper or a complete list of every café in BGC.
- [The test fixture](06-check/fixtures/cafes.json) contains seven explicitly fictional cafés. Their known answers let us prove that missing requirements, unknowns, conflicts, and changes are handled properly. The default server never loads these records.

Read [the data notes](data/README.md) before presenting a real café as a match. A delivery menu is not proof of current stock; a customer Wi-Fi report is not a speed test or an official policy.

## For the presenter

- [Teaching notes and the 45-minute talk route](docs/presenter-guide.md)
- [My talk checklist](docs/rehearsal-checklist.md)
- [AWS documentation demo without an AWS account](docs/aws-knowledge-demo.md)
- [One-page participant checklist](docs/participant-checklist.md)
- [Troubleshooting](docs/troubleshooting.md)
- [Technical references](docs/references.md)
- [Verified results and remaining rehearsal check](docs/verification.md)
- [Slides](https://docs.google.com/presentation/d/1naXyiU3_hdUMpO7TUvGuSssPxRyK-Ff9DoW3wdXWQI0/edit)

`npm test` checks the filter, data provenance, actual MCP discovery/calls, invalid inputs, and a record change through the same running server. It does not test a model's natural-language answer. Complete that last check in OpenCode during rehearsal.

Code and original workshop explanations are available under the [MIT license](LICENSE). Linked source material retains its own terms.

## After the workshop

Try the [optional challenges](08-optional/). Compare drink rules, inspect failure cases, add a drink, or build an explanation tool. These are separate from the timed workshop.