foro-demo-mcp
by abboskhonov
README.md
# foro-demo-mcp
A tiny **demo MCP server in TypeScript** with no build step — five tools, streamable HTTP, made to deploy on [foro.sh](https://foro.sh) in about a minute.
## Tools
| Tool | What it does |
| --- | --- |
| `hello` | Greet someone — proves the round trip works |
| `roll_dice` | Roll `count` dice with `sides` faces |
| `remember` | Store a value under a key (in-memory) |
| `recall` | Read a value back — state persists between calls |
| `whoami` | Show the caller's verified identity (`X-Foro-*` headers) |
| `get_my_orders` | Pattern A demo: call your backend as the verified user |
| `server_info` | Runtime info: port, node version, uptime (never secrets) |
## Auth: two sides
```
[User + AI client] ──① inbound: who calls?──▶ foro gate ──▶ your tool code ──② outbound──▶ your backend
token or OAuth JWT injects X-Foro-* reads identity service key + X-User-Id
```
- **① Inbound (foro handles it):** Settings → Server access → `token` (one shared
bearer token, no per-user identity) or `oauth` (each user signs in; the gate
verifies their JWT and injects `X-Foro-Subject` / `X-Foro-Org` / `X-Foro-Scopes`,
stripping anything the client tried to spoof). `whoami` shows what arrives.
- **② Outbound (you write it):** set `BACKEND_URL` (plain) and `BACKEND_API_KEY`
(secret) in foro → Secrets, redeploy. `get_my_orders` then calls your backend
with the service key **plus** `X-User-Id` from the gate, so your backend knows
*which* user the call is on behalf of (Pattern A).
Never ask users to paste their backend API key as a tool argument — it would end
up in LLM context and transcripts. Identity arrives as a gate-verified header.
## Run locally
```sh
npm install
npm start # → http://0.0.0.0:8000/mcp (PORT env var overrides)
```
No `tsc`, no bundler: Node ≥ 22.18 runs the TypeScript directly via native type stripping.
## Deploy on foro.sh
1. Sign in at [foro.sh](https://foro.sh) with GitHub
2. **New project → I have a repo** → pick this repo, branch `main`
3. Click **Deploy** — foro reads `package.json` (`main`, `engines`), installs with npm, health-checks, and goes live
4. Copy your `https://<slug>.foro.sh` URL and project bearer token from the Overview tab
foro injects `PORT`, which this server reads automatically. State in `remember`/`recall` lives in the container's memory until it restarts.
## Connect an agent
**Claude Desktop / Claude Code** (Settings → Developers → Edit Config):
```json
{
"mcpServers": {
"foro-demo": {
"type": "http",
"url": "https://<slug>.foro.sh/mcp",
"headers": { "Authorization": "Bearer <your-foro-token>" }
}
}
}
```
**OpenCode** (`opencode.json`):
```json
{
"mcp": {
"servers": {
"foro-demo": {
"type": "remote",
"url": "https://<slug>.foro.sh/mcp",
"oauth": false,
"headers": { "Authorization": "Bearer {env:FORO_DEMO_TOKEN}" }
}
}
}
}
```
Any client that speaks MCP over streamable HTTP works — Cursor, VS Code, Windsurf, Codex.
## Notes
- Stateless HTTP mode: a fresh server + transport per request, no session tracking
- The bearer-token check is performed by foro's gate in front of this server
- `server_info` deliberately reports only non-sensitive values
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues