Guide to scaffolding, running, debugging, building, and deploying a Python MCP server with KMCP and MCP Inspector exposing cryptocurrency price tools
Hello everyone.
Welcome to this hands-on lab. In this lesson we’ll scaffold a Python-based MCP server using the kmcp CLI. The example MCP server will fetch real-time cryptocurrency prices and expose that functionality as MCP tools that agents can call.High-level flow:
An agent requests a tool (for example, “get Bitcoin price”).
The agent calls the MCP server’s tool endpoints.
The MCP server executes the tool code (fetches live price), processes the response, and returns it.
KMCP helps scaffold the project, run locally with the Inspector, build a container image, and deploy the MCP server to Kubernetes.
KMCP is the CLI for building and managing Model Context Protocol (MCP) servers. Do not confuse it with the KAgent CLI — KAgent CLI focuses on building and interacting with agents, while KMCP focuses on MCP server tooling, scaffolding, local debugging, builds, and deployments.
Downloading https://github.com/kagent-dev/kmcp/releases/download/v0.2.2/kmcp-linux-amd64Preparing to install kmcp into /usr/local/binkmcp installed into /usr/local/bin/kmcp🎉 KMCP installation completed successfully!To verify the installation, please run:kmcp --versioncontrolplane ~ ➜ kmcp --versionkmcp version 0.2.2
To explore kmcp commands:
kmcp --help
Abbreviated sample output:
KMCP is a CLI tool for building and managing Model Context Protocol (MCP) servers.Usage: kmcp [flags]Available Commands: add-tool Add a new MCP tool to your project build Build MCP server as a Docker image deploy Deploy MCP server to Kubernetes init Initialize a new MCP server project install Install the KMCP controller on a Kubernetes cluster run Run MCP server locally secrets Manage project secrets help Help about any command
Below is a quick reference to the key files generated by kmcp init:
File
Purpose
Example / Notes
kmcp.yaml
Main MCP configuration (environments, secrets, metadata)
See example YAML below
pyproject.toml
Python packaging and dependency configuration
Use dependency-groups for dev dependencies
Dockerfile
Image build instructions for containerization
Used by kmcp build
src/
Source code: core server and tools
src/main.py, src/tools/*
Example kmcp.yaml (abbreviated):
name: crypto-price-mcpframework: fastmcp-pythonversion: 0.1.0description: MCP server built with fastmcp-pythonsecrets: local: enabled: false provider: env file: .env.local production: enabled: false provider: kubernetes secretName: crypto-price-mcp-secrets-production namespace: defaultcreated_at: 2025-12-19T07:38:32.303583657Zupdated_at: 2025-12-19T07:38:32.338228897Z
Do not commit sensitive keys or API secrets to version control. Use kmcp secrets with a secrets provider (env files or Kubernetes Secrets) and reference them from kmcp.yaml so your tools can read them securely at runtime.
The generated src/main.py boots the FastMCP server and registers tools. It typically parses CLI arguments for transport and host/port, then starts the server.Representative excerpt:
# src/main.pyimport argparseimport sysfrom pathlib import Path# Add src to Python pathsys.path.insert(0, str(Path(__file__).parent))from core.server import DynamicMCPServer # noqa: E402def main() -> None: """Main entry point for the MCP server.""" parser = argparse.ArgumentParser(description="crypto-price-mcp MCP Server") parser.add_argument("--transport", choices=["stdio", "http"], default="stdio", help="Transport mode: stdio or http") parser.add_argument("--host", default="127.0.0.1", help="Host for HTTP transport") parser.add_argument("--port", type=int, default=8080, help="Port for HTTP transport") args = parser.parse_args() server = DynamicMCPServer(project_dir=Path(__file__).parent) server.run(transport=args.transport, host=args.host, port=args.port)if __name__ == "__main__": main()
Notes:
DynamicMCPServer loads tools from src/tools and exposes them over the chosen transport.
Use --transport http for running as an HTTP service (suitable for Kubernetes), or stdio for Inspector/local development.
Tools live under src/tools. Each tool is a Python function decorated with @mcp.tool() so the MCP server can register it and expose metadata.Example src/tools/echo.py:
# src/tools/echo.py"""Example echo tool for crypto-price-mcp MCP server."""from core.server import mcpfrom core.utils import get_tool_config@mcp.tool()def echo(message: str) -> str: """Echo a message back to the client. Args: message: The message to echo Returns: The echoed message with any configured prefix """ config = get_tool_config("echo") prefix = config.get("prefix", "") return f"{prefix}{message}" if prefix else message
Tool definition tips:
@mcp.tool() registers the function as a callable MCP tool.
Type annotations help schema generation for inputs/outputs.
Docstrings are surfaced in the Inspector UI as descriptions.
Use core.utils.get_tool_config to read tool-specific configuration from kmcp.yaml.
Run the MCP server locally. The kmcp run command installs dependencies and starts the MCP Inspector proxy for local debugging:
kmcp run --project-dir ./crypto-price-mcp
Example output when starting:
warning: The `tool.uv.dev-dependencies` field (used in pyproject.toml) is deprecated; use `dependency-groups.dev` insteadResolved 104 packagesStarting MCP inspector...⚙ Proxy server listening on 127.0.0.1:6277🔑 Session token: 46f50eb8951e5e501c94fffdec7a4dd39a1973a4c05c737e2e32e76aeed590a3Use this token to authenticate requests🔗 Open inspector with token pre-filled:http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=46f50eb8951e5e501c94fffdec7a4dd39a1973a4c05c737e2e32e76aeed590a3🟢 MCP Inspector is up and running at http://127.0.0.1:6274 🚀
MCP Inspector is a Postman-like UI for exploring and invoking tools exposed by an MCP server. It proxies connections to the running server and displays tools, schemas, and responses.Example inspector startup output:
Starting MCP inspector...Proxy server listening on 127.0.0.1:6277Session token: d2e3a6e837cd46fbd3bf344186d490d9fb1e0808e0b9a6554afcd49fb5d8f04aOpen inspector with token pre-filled:http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=d2e3a6e837cd46fbd3bf344186d490d9fb1e0808e0b9a6554afcd49fb5d8f04aMCP Inspector is up and running at http://127.0.0.1:6274 🚀Connection details saved to: /root/mcp-inspector-info.txt
Command: uv (the uv entrypoint used in the generated project)
Arguments: run python /root/crypto-price-mcp/src/main.py
Example inspector connection command shown in the UI:
Command: uvArguments: run python /root/crypto-price-mcp/src/main.py
Provide the Inspector Proxy Address and Session Token (from the start output) and click Connect. When connected you’ll see a green indicator and can list and invoke tools.
The Inspector lists available tools and their input/output schemas. For the scaffolded project you’ll see the echo tool.Inspector tools listing example:
ToolsList ToolsechoEcho a message back to the client.Args: message: The message to echoReturns: The echoed message with any configured prefix
Run the echo tool by providing input and clicking Run. Example response shown by Inspector:
{ "result": "hello how are you today ?"}
Under the hood: the Inspector sends an MCP request to the server; the server validates and dispatches to the registered tool function; the tool runs, and the server returns an MCP-compliant response the Inspector displays.