Skip to main content
Glama
kriscendobot

minion.town

by kriscendobot

minion.town πŸ™οΈ

A toy MCP (Model Context Protocol) server with OAuth 2.1 authentication and authorization, built to validate one design: an MCP server that has an excellent local developer experience and a clean path to AWS β€” with the same code running in both places, differing only by configuration.

It's a tiny "minion town": three MCP tools, each gated by an OAuth scope.

Full design rationale: designs/mcp-oauth.md. AWS deploy: infra/README.md.

Quickstart (local, no cloud, no Docker)

cp .env.example .env
npm install
npm run dev          # mock OAuth server (:9000) + MCP server (:3000), hot-reload

In another terminal, run the full OAuth + MCP flow:

npm run client                 # PKCE flow β†’ every tool succeeds
npm run client -- read-only    # omit the write scope β†’ summon_minion is denied
β†’ running OAuth flow (scope: mcp:tools mcp:minions:read mcp:minions:write)
βœ“ got access token (eyJraWQiOiI0NjY5…)
tools: minion_status, list_minions, summon_minion
minion_status: βœ“ πŸ™οΈ  minion.town has 0 minion(s).
summon_minion: βœ“ ✨ Summoned Bob (minion-1) to do "guard the gate".
list_minions:  βœ“ β€’ Bob β€” guard the gate

Run the end-to-end authN/authZ tests (real mock AS + real middleware, nothing about the auth path is stubbed):

npm test

Related MCP server: Keycard Hello MCP Server

The tools and their scopes

Tool

Scope required

Does

minion_status

mcp:tools

count minions in town

list_minions

mcp:minions:read

list the roster

summon_minion

mcp:minions:write

summon a new minion

A token only carrying mcp:tools mcp:minions:read can list but cannot summon β€” authorization is enforced from the token's scopes.

How it works (one paragraph)

The MCP server is an OAuth 2.1 resource server. Unauthenticated requests get 401 + WWW-Authenticate pointing at RFC 9728 Protected Resource Metadata, which advertises the authorization server. The client runs PKCE auth-code with an RFC 8707 resource parameter; the server validates the JWT's signature, issuer, expiry, and audience (so a token for another server is rejected), then maps the token's scopes β†’ which tools it may call. Locally the authorization server is oauth2-mock-server; on AWS it's Amazon Cognito. The server code is identical; only src/config.ts reads different env vars. Built on @modelcontextprotocol/sdk and grounded in the MCP authorization spec (2025-06-18 + Nov 2025 update).

Layout

src/        MCP resource server (config seam, verifier, scope→tool map, tools, HTTP)
dev/        local dev harness: mock OAuth AS + browserless PKCE client
test/       end-to-end authN/authZ tests
infra/      AWS CDK deploy (App Runner + Cognito + Route53/ACM) β€” documented path
designs/    the design document

Security

No secrets are committed. .env is gitignored; AWS secrets are injected by the platform. See designs/mcp-oauth.md Β§ Threat-model notes.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kriscendobot/minion.town'

If you have feedback or need assistance with the MCP directory API, please join our Discord server