WendyOS Docs
AdvancedExamples

MCPExample

A minimal reference implementation of a WendyOS app that exposes device tools over the Model Context Protocol (MCP). Deploy it with wendy run and its tools become instantly availab

MCPExample

A minimal reference implementation of a WendyOS app that exposes device tools over the Model Context Protocol (MCP). Deploy it with wendy run and its tools become instantly available inside wendy mcp serve.

What it does

The example runs a Python MCP server built with FastMCP and served over HTTP by uvicorn. It exposes three tools:

ToolDescription
pingReturns "pong" — useful for checking reachability
device_infoReturns hostname, CPU architecture, OS, and Python version
run_commandRuns an arbitrary shell command and returns exit_code, stdout, and stderr

File layout

MCPExample/
  Dockerfile          # Python 3.11-slim image
  main.py             # FastMCP server definition
  requirements.txt    # mcp[cli] + uvicorn[standard]
  wendy.json          # App config with mcp entitlement

wendy.json

{
  "appId": "com.wendylabs.examples.mcp-example",
  "platform": "linux",
  "version": "1.0.0",
  "language": "python",
  "python": {
    "container": {
      "sourceRoot": "/app"
    }
  },
  "entitlements": [
    { "type": "network", "mode": "host" },
    { "type": "mcp", "port": 3000 }
  ]
}

Two entitlements are required:

  • network (host mode) — lets the agent reach the container's MCP port over loopback (127.0.0.1:3000).
  • mcp — tells the agent that this container runs an MCP server on port 3000. The agent stores the port in the sh.wendy/mcp.port container label and exposes the container's tools through wendy mcp serve.

Authentication

wendy mcp serve uses the auth session stored by wendy auth login. If multiple sessions are stored, MCP tools inherit whichever session is active — either the persisted default (set with wendy auth use) or a session selected via cloud_grpc in the tool call.

Multiple auth sessions: When more than one Wendy Cloud session is stored, pass cloud_grpc in the tool call to select one explicitly, or run wendy auth use in your terminal to set a persistent default that MCP tools will use automatically.

Running the example

cd Examples/MCPExample
wendy run

wendy run:

  1. Builds the Docker image for the target device architecture.
  2. Pushes and starts the container on the device.
  3. Because of the mcp entitlement, the container's port (3000) is registered with the wendy agent.

Once the container is running, start the MCP server:

wendy mcp serve

The ping, device_info, and run_command tools appear prefixed with the app name (e.g. com.wendylabs.examples.mcp-example/ping) in any connected AI assistant.

Environment variables

VariableDefaultDescription
MCP_PORT3000TCP port the MCP server listens on. Must match wendy.json.

Dependencies

mcp[cli]>=1.9.4
uvicorn[standard]>=0.27.0

How the proxy works

When an AI assistant calls a tool on this container, the request flows through:

AI Assistant
    │  MCP (stdio)

wendy mcp serve
    │  StreamMCP gRPC (bidirectional streaming)

wendy-agent (on device)
    │  TCP

container MCP server (127.0.0.1:3000)

The wendy agent's StreamMCP RPC proxies raw bytes between the gRPC stream and the container's TCP port. The agent verifies that:

  • The container has an mcp entitlement (non-zero sh.wendy/mcp.port label).
  • The container is in the RUNNING state before attempting the TCP connection.

See wendy-agent/mcp.md for full API documentation.

On this page