mitchallen

mcp-hello-server

Community mitchallen
Updated

A minimal MCP server: a server_info health check and a multilingual greeting tool

mcp-hello-server

GitHub tag Docker Hub test bdd

A minimal MCP server built with Python andFastMCP — a good starting point for a new server or ademo. It exposes just two tools:

  • server_info — a health/status check.
  • greet — a friendly greeting in one of a handful of languages, defaultingto English. Ask it to "greet in French" and it replies Bonjour!.

Built with Python, uv, FastMCP, andmake. It was scaffolded from the siblingrandom-mcp-server by stripping it down toserver_info and adding the greet demo tool.

Quick start — demo an MCP server in 2 minutes

New to MCP? This is a tiny, safe server for seeing how an MCP client discoversand calls tools. Every tool is a harmless in-memory lookup, so it's a goodsandbox. All you need is Docker and anMCP client — the steps below use Claude Codeand the published Docker Hub image (nothing to build or install).

1. Add the server. Claude Code launches the container per session and talksto it over stdio:

claude mcp add hello -- docker run -i --rm -e MCP_TRANSPORT=stdio mitchallen/mcp-hello-server:latest

2. Confirm it connected:

claude mcp list        # "hello" should report ✔ Connected

3. Ask in plain language — Claude discovers the tools and picks one (the toolit calls is in parentheses):

  • "Is the hello server up? What version is it?" → (server_info)
  • "Greet me in French." → (greetBonjour!)
  • "Say hello in Japanese to Alice." → (greetこんにちは (Konnichiwa), Alice!)
  • "What languages can you greet in?" → (server_info, reads languages)

That round trip — the client listing tools, then calling one with arguments andgetting structured JSON back — is MCP. Peek at the tool schemas the client seeswith make dev (the FastMCP Inspector), or read Tools below.

4. Remove it when you're done:

claude mcp remove hello

Prefer HTTP? Run it as a long-lived server instead:

docker run --rm -p 8000:8000 mitchallen/mcp-hello-server:latest
claude mcp add --transport http hello http://localhost:8000/mcp

See Using a published image or a remote serverfor other clients and the mcp-remote bridge.

Tools

Tool Purpose
server_info() Health/status: app name, version, uptime, supported languages
greet(language?, name?) Greeting in language (default English); optional name

greet

greet takes two optional arguments:

  • language — a language name, an alternate spelling, or an ISO code(case-insensitive). Omit it to default to English. Supported: english,spanish, french, german, italian, portuguese, japanese,hawaiian (e.g. french, Français, or fr all work).
  • name — optional; personalizes the message (Bonjour, Alice!).

It returns { language, greeting, message }:

// greet(language="french")
{ "language": "french", "greeting": "Bonjour", "message": "Bonjour!" }

// greet(language="spanish", name="Alice")
{ "language": "spanish", "greeting": "Hola", "message": "Hola, Alice!" }

// greet()  -> { "language": "english", "greeting": "Hello", "message": "Hello!" }

An unknown language returns an error listing the supported set.

Add a language

Add a row to GREETINGS in src/mcp_hello_server/greetings.py (and, optionally,an alias / ISO code in _ALIASES). server_info reports the supported setautomatically.

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 mcp-hello-server
# or
make run

Streamable HTTP (for networked clients / containers)

make run-http            # PORT defaults to 8000
PORT=9000 make run-http

Inspect the server

make inspect             # print a summary: name, version, tool count
make dev                 # launch the interactive FastMCP Inspector (web UI)

Configuration

All configuration is via environment variables:

Variable Default Purpose
APP_NAME mcp-hello-server Name reported by server_info
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 — local development (from source)

Point a stdio-based client (e.g. Claude Desktop, Claude Code) at the consolescript. Example claude_desktop_config.json entry using uv:

{
  "mcpServers": {
    "hello": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/mcp-hello-server", "mcp-hello-server"]
    }
  }
}

With Claude Code:

claude mcp add hello -- uv run --directory "$PWD" mcp-hello-server

Confirm it's connected with claude mcp list (or /mcp inside a session).

Example prompts (Claude Code)

Once the server is added, just ask in plain language — Claude picks the righttool. The tool it invokes is shown in parentheses.

  • "Is the hello server up? What version is it?" → (server_info)
  • "Greet me." → (greet, defaults to English → "Hello!")
  • "Greet in French." → (greet with language="french" → "Bonjour!")
  • "Say hello in Japanese to Alice." → (greet with language="japanese", name="Alice")
  • "What languages can you greet in?" → (server_info, then read languages)

Using a published image or a remote server

This section is for consumers who are not building from source — you have thepublished Docker image, or someone has deployed the server for you.

Option A — Docker image, client launches it (stdio)

The client starts a fresh container per session and talks to it over stdio. Use-i (keep stdin open) and force the stdio transport, since the image defaults toHTTP. The image is published to two registries, so pick one:

// GitHub Container Registry (GHCR)
{
  "mcpServers": {
    "hello": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT=stdio",
               "ghcr.io/mitchallen/mcp-hello-server:latest"]
    }
  }
}
// Docker Hub
{
  "mcpServers": {
    "hello": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT=stdio",
               "mitchallen/mcp-hello-server:latest"]
    }
  }
}

Claude Code equivalent — again, pick a registry:

# GitHub Container Registry (GHCR)
claude mcp add hello -- docker run -i --rm -e MCP_TRANSPORT=stdio ghcr.io/mitchallen/mcp-hello-server:latest

# Docker Hub
claude mcp add hello -- docker run -i --rm -e MCP_TRANSPORT=stdio mitchallen/mcp-hello-server:latest

(Pin a version like :0.1.0 in place of :latest for a reproducible setup. Add--scope user to register the server for every project on your machine.)

Option B — Long-running container over HTTP (local)

Start the container once (it serves HTTP by default) from either registry, thenpoint an HTTP-capable client at it:

# GitHub Container Registry (GHCR)
docker run -d --rm -p 8000:8000 --name mcp-hello ghcr.io/mitchallen/mcp-hello-server:latest

# Docker Hub
docker run -d --rm -p 8000:8000 --name mcp-hello mitchallen/mcp-hello-server:latest

Claude Code (native HTTP transport):

claude mcp add --transport http hello http://localhost:8000/mcp

For clients that only speak stdio, bridge to the HTTP endpoint withmcp-remote:

{
  "mcpServers": {
    "hello": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:8000/mcp"]
    }
  }
}

Option C — Remote deployment (HTTP)

If the server is hosted elsewhere, use its public URL — everything else matchesOption B:

claude mcp add --transport http hello https://mcp-hello.example.com/mcp

Notes for remote use:

  • Prefer HTTPS so traffic is encrypted in transit.
  • This server ships no authentication. If you expose it beyond localhost, putit behind a reverse proxy, gateway, or network policy — or addFastMCP auth.
  • The endpoint path is /mcp (no trailing slash). Requesting /mcp/ works toobut returns a 307 redirect to /mcp.

Docker

Published multi-platform (linux/amd64, linux/arm64) images are availablefrom two registries:

  • GitHub Container Registry: ghcr.io/mitchallen/mcp-hello-server
  • Docker Hub: mitchallen/mcp-hello-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 and run

docker pull ghcr.io/mitchallen/mcp-hello-server:latest
docker run --rm -p 8000:8000 --name mcp-hello ghcr.io/mitchallen/mcp-hello-server:latest

Then connect an HTTP MCP client to http://localhost:8000/mcp.

Test a published release with make

Convenience targets pull and run the published image in your local Dockerenvironment — handy for smoke-testing a release without a local build:

make docker-test               # up + smoke + down in one shot (exits non-zero on failure)

make docker-up                 # pull + run ghcr.io/mitchallen latest, detached
make docker-smoke              # MCP `initialize` handshake — passes if the server responds
make docker-down               # stop it

make docker-up TAG=0.1.0                         # pin a version
make docker-up REGISTRY=docker.io/mitchallen     # pull from Docker Hub instead
make docker-up HTTP_PORT=9000                    # publish on a different host port

Build locally

make docker-build        # docker build -t mcp-hello-server .
make docker-run          # serves http on localhost:8000

CI / Publish

Three kinds of GitHub Actions workflows live in .github/workflows/:

  • test — runs on every push/PR to main: the unit suite(pytest --ignore=tests/test_bdd.py).
  • bdd — runs the pytest-bdd scenarios (pytest tests/test_bdd.py) inits own workflow so it passes/badges independently of the unit suite.
  • publish / publish-dockerhub — triggered by pushing a v* tag.Build a multi-platform image and push it to GHCR and Docker Hub, then runmake docker-test against the just-published image as a post-publish smokecheck. The Docker Hub job needs DOCKERHUB_USERNAME / DOCKERHUB_TOKENrepository secrets and a pre-created mitchallen/mcp-hello-server repo.

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.

Development

  • Source: src/mcp_hello_server/
    • greetings.py — greeting data + language resolution (greet)
    • server.py — FastMCP tools + entry point (main)
  • Tests: tests/, run with make test (uv run pytest), driven through anin-memory FastMCP client. Layers:
    • test_greetings.py — plain pytest unit tests for the resolver/builder.
    • test_server.py — the tools through the in-memory client.
    • test_bdd.py + tests/features/*.feature — a pytest-bdd layer.
  • make build produces a wheel/sdist via uv build.
  • Dependencies: uv.lock is committed and the Docker build installs from itwith --frozen. Whenever you change dependencies in pyproject.toml, runmake lock (or uv lock) to refresh the lockfile and commit it.

License

MIT © Mitch Allen

MCP Server · Populars

MCP Server · New

    adelinamart

    RoBrain

    Shared memory across your team and your AI agents — with judgment about what's worth keeping.

    Community adelinamart
    Lyellr88

    MARM: Local-First Persistent Multi-Agent Memory Layer for MCP Clients v2.20.0

    Self-hosted, local-first MCP memory server for AI agents. Sub-20ms recall at 10k memories, hybrid semantic + exact-syntax search (RAG), code & concept knowledge graphs (158 languages). All local in SQLite: no cloud, no vector DB, no API keys. Works with Claude Code, Codex, Cursor, Gemini & any MCP client.

    Community Lyellr88
    Bumblebiber

    hmem — Humanlike Memory for AI Agents

    Persistent memory and agent lifecycle for Claude Code — because sessions shouldn't start from zero.

    Community Bumblebiber
    firish

    Claude Code for Visual Studio

    Bring Claude Code to Visual Studio 2026: A native diff with accept/reject, a live debugger Claude can drive autonomously, Roslyn code navigation, and Test Explorer integration. The IDE half of Claude Code's integration protocol. Community-built, unofficial.

    Community firish
    uiNerd16

    @aicanvas/mcp

    Open-source React and Tailwind component marketplace. Install via the shadcn CLI or your AI editor over MCP, with reproduction prompts for Claude Code, Lovable, and V0.

    Community uiNerd16