random-mcp-server
An MCP server that returns random JSONthings — people, words, values, coordinates, and an always-empty list. It is aPython / FastMCP adaptation of the Node/Expressrandom-server REST API: each REST route family becomes anMCP tool.
Built with Python, uv, FastMCP, andmake.
How the REST API maps to MCP
The REST server seeds a fixed pool of records when it starts and serves them at/v1/<kind>, /v1/<kind>/count, and /v1/<kind>/:id. This server does thesame, exposing the pool through a small set of tools parameterized by kind(people, words, values, coords, empty):
| REST route | MCP tool |
|---|---|
GET / |
server_info() |
GET /v1/<kind> |
list_records(kind, count?) |
GET /v1/<kind>/count |
count_records(kind) |
GET /v1/<kind>/:id |
get_record(kind, id) (1-based) |
| (restart to reseed) | regenerate(seed?) |
Records are seeded at start-up, so a given id is stable until you callregenerate. Pass a fixed seed (tool arg or RANDOM_SEED) for reproducibledata.
Differences from random-server
- No
x-api-keyauth. The REST server's optionalAPI_KEYguard on/v1routes is not ported — MCP transports handle authentication differently(add FastMCP auth if anetworked deployment needs it). TheAPP_NAME, seeding, and per-kind countbehavior are preserved. - No Swagger UI. The
/api-docsexplorer has no MCP equivalent; toolschemas are discoverable through the MCP protocol itself (e.g.make dev).
Example records
// get_record(kind="people", id=1)
{ "type": "people", "prefix": "Mr.", "first": "Augustus", "last": "Gomez",
"age": 42, "birthday": "7/8/1959", "gender": "male", "zip": "74948-0928",
"ssnFour": "0791", "phone": "(509) 504-8066", "email": "[email protected]" }
// get_record(kind="words", id=1) -> { "type": "words", "value": "cezuwdi" }
// get_record(kind="values", id=1) -> { "type": "values", "name": "dafe", "value": -415365907192.2176 }
// get_record(kind="coords", id=1) -> { "type": "coords", "latitude": 88.43647, "longitude": -93.31203 }
Quick start
Requires uv.
make install # create .venv and sync deps
make test # run the test suite
make run # run the server over stdio
make help lists every target.
Running the server
stdio (default — for MCP clients that launch the server)
uv run random-mcp-server
# or
make run
Streamable HTTP (for networked clients / containers)
make run-http # PORT defaults to 8000
PORT=9000 make run-http
Interactive Inspector
make dev # launches the FastMCP Inspector
Configuration
All configuration is via environment variables:
| Variable | Default | Purpose |
|---|---|---|
APP_NAME |
random-mcp-server |
Name reported by server_info |
RANDOM_COUNT |
25 |
Records generated per kind at start-up |
RANDOM_SEED |
(random) | Fixed seed for reproducible pools |
MCP_TRANSPORT |
stdio |
stdio, http, or sse |
HOST |
127.0.0.1 |
Bind address for http/sse |
PORT |
8000 |
Bind port for http/sse |
Using with an MCP client
Point a stdio-based client (e.g. Claude Desktop, Claude Code) at the consolescript. Example claude_desktop_config.json entry using uv:
{
"mcpServers": {
"random": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/random-mcp-server", "random-mcp-server"]
}
}
}
With Claude Code:
claude mcp add random -- uv run --directory "$PWD" random-mcp-server
Docker
Published multi-platform (linux/amd64, linux/arm64) images are availablefrom two registries:
- GitHub Container Registry:
ghcr.io/mitchallen/random-mcp-server - Docker Hub:
mitchallen/random-mcp-server
The image runs the server over streamable HTTP by default (MCP_TRANSPORT=http,HOST=0.0.0.0, PORT=8000) so it's reachable on a published port.
Pull the image
docker pull ghcr.io/mitchallen/random-mcp-server:latest
# or from Docker Hub
docker pull mitchallen/random-mcp-server:latest
Both registries also publish version tags (e.g. :0.1.0); prefer a pinnedversion over :latest for reproducible deployments.
Run the container
docker run --rm -p 8000:8000 --name random-mcp ghcr.io/mitchallen/random-mcp-server:latest
Then connect an HTTP MCP client to http://localhost:8000/mcp/.
Configure at runtime
Pass any of the configuration variables with -e:
docker run --rm -p 9000:9000 \
-e PORT=9000 \
-e APP_NAME=my-random \
-e RANDOM_COUNT=50 \
-e RANDOM_SEED=42 \
ghcr.io/mitchallen/random-mcp-server:latest
To run over stdio inside the container instead (e.g. when another processattaches to it), override the transport:
docker run --rm -i -e MCP_TRANSPORT=stdio ghcr.io/mitchallen/random-mcp-server:latest
Build locally
make docker-build # docker build -t random-mcp-server .
make docker-run # serves http on localhost:8000
CI / Publish
Two GitHub Actions workflows live in .github/workflows/:
test— runs on every push/PR tomain:uv sync --frozenthenuv run pytest.publish— triggered by pushing av*tag. Builds a multi-platform(linux/amd64,linux/arm64) image and pushes it to the GitHub ContainerRegistry asghcr.io/mitchallen/random-mcp-serverwith both the version andlatesttags. It uses the built-inGITHUB_TOKEN, so no extra secrets areneeded.publish-dockerhub— also triggered by av*tag. Pushes the samemulti-platform image to Docker Hub asmitchallen/random-mcp-serverand syncsthis README to the Docker Hub repo description. Requires two repositorysecrets and a pre-created Docker Hub repository (see below).
Docker Hub setup
The publish-dockerhub workflow needs:
A Docker Hub repository named
mitchallen/random-mcp-server.Two repository secrets — set them with the GitHub CLI:
gh secret set DOCKERHUB_USERNAME --repo mitchallen/random-mcp-server gh secret set DOCKERHUB_TOKEN --repo mitchallen/random-mcp-server # a Docker Hub access token
Until both secrets exist, the publish-dockerhub job will fail on tag pusheswhile the GHCR publish job continues to work on its own.
To cut a release, use the release target — it bumps version inpyproject.toml (and uv.lock), commits, tags, and pushes, which triggers bothpublish workflows:
make release # patch bump (default)
make release BUMP=minor # or minor / major
The target refuses to run unless the working tree is clean and you're on main.It's equivalent to bumping the version, then git tag vX.Y.Z && git push origin main vX.Y.Z by hand.
Development
- Source:
src/random_mcp_server/generators.py— deterministic, seedable record builders (RandomFactory)server.py— FastMCP tools + entry point (main)
- Tests:
tests/(pytest, driven through an in-memory FastMCP client) make buildproduces a wheel/sdist viauv build.- Dependencies:
uv.lockis committed and the Docker build installs from itwith--frozen. Whenever you change dependencies inpyproject.toml, runmake lock(oruv lock) to refresh the lockfile and commit it.
License
MIT © Mitch Allen