Mcp.StdioServer
Examples below assume
mcp-serveris imported asMcp.
Owns an MCP SDK Server bound to a StdioServerTransport over the
controller's stdin/stdout. Designed for desktop clients (Claude Desktop,
Cursor, …) that spawn the server as a child process.
Lifecycle
init()— resolves every bundle ref intools:/resources:/prompts:, validates entries (within-bundle and cross-bundle uniqueness), builds one SDK Server and registers each entry as a handler.run()— connects the SDK Server to aStdioServerTransport, mints a synthetic session UUID (sorequest.session.idis always defined for CEL inputs), and acquires a kernel hold viactx.acquireHold()so the process stays up.teardown()— closes the transport (releasing the hold viatransport.onclose) and closes the SDK Server.
stdin EOF (the parent closing the pipe) triggers transport.onclose, which
releases the hold and lets the kernel exit cleanly.
Schema
kind: Mcp.StdioServer
metadata: { name: <ServerName> }
serverInfo:
name: <advertised-server-name>
version: <semver>
instructions: | # optional — primer for the client's LLM
Free-form text surfaced on `initialize`.
tools: [<Mcp.Tools bundle names>]
resources: [<Mcp.Resources bundle names>] # v2 runtime
prompts: [<Mcp.Prompts bundle names>] # v2 runtime
In v1, resources: and prompts: arrays are accepted in the schema but
must be empty — runtime dispatch lands in v2.
instructions
Optional free-form string carried on the SDK Server's instructions option.
Compatible MCP clients (Claude Desktop, etc.) surface it to the LLM as system
context. Use it to teach the model what your server is, what its tools mean,
and how to use them — onboarding without requiring the LLM to call a separate
"help" tool first.
Minimal example
kind: Telo.Application
metadata: { name: my-stdio-mcp }
imports:
Mcp: std/mcp-server@0.7.0
JS: std/javascript@0.5.0
targets: [ !ref Server ]
---
kind: Mcp.StdioServer
metadata: { name: Server }
serverInfo: { name: my-stdio-mcp, version: 1.0.0 }
tools: [ WeatherTools ]
---
kind: Mcp.Tools
metadata: { name: WeatherTools }
entries:
- name: get_weather
description: Get current weather for a city.
argumentsSchema:
type: object
properties: { city: { type: string } }
required: [ city ]
handler: { kind: JS.Script, name: GetWeatherImpl }
inputs: { city: "${{ request.arguments.city }}" }
result:
content:
- { type: text, text: "${{ result.summary }}" }
Differences from Mcp.HttpEndpoint
| Aspect | Mcp.StdioServer | Mcp.HttpEndpoint |
|---|---|---|
| Capability | Telo.Service (owns transport + run) | Telo.Mount (mounts on Http.Server) |
| Lifecycle | Process lives until stdin EOF | Sessions live until Http.Server closes |
| Sessions | One implicit, synthetic UUID | Per-client, header-routed |
| SDK Server cardinality | One per process | One per session |