Server basics
Start with an McpServer, register the features it exposes, then attach a transport. The server accepts MCP requests such as server/discover, tools/list, and tools/call.
Create a server
Section titled “Create a server”import nimwire
let server = newMcpServer( "weather", "1.0.0", instructions = "Use the weather tool for current conditions.")The name and version are required. instructions is included in discovery so a client can understand the server’s purpose.
The mcpServer template is a shorter form when registration should stay next to construction:
let server = mcpServer("weather", "1.0.0"): discardRegister a raw tool
Section titled “Register a raw tool”Use mcpTool when the handler naturally works with JSON:
import std/[json, strutils]
server.addTool mcpTool("word_count", "Count words in text", %*{ "type": "object", "properties": {"text": {"type": "string"}}, "required": ["text"], "additionalProperties": false}, proc (args: JsonNode, context: McpContext): McpToolResult = textResult($args["text"].getStr.splitWhitespace.len))The second handler parameter is request context. Name it ignoredContext when the handler does not need it. A handler can be synchronous or return Future[McpToolResult].
Tool names are 1 to 128 characters and may contain letters, numbers, _, -, and .. Names must be unique after registration.
Return text or JSON
Section titled “Return text or JSON”Use the result that matches what the client should receive:
textResult("ready")jsonResult(%*{"temperature": 16, "unit": "C"})structuredResult(%*{"temperature": 16, "unit": "C"})textResult creates a text content item. jsonResult and structuredResult include structured content as well as a readable text representation. Set isError = true when a tool completed but its result describes a tool failure.
For typed failures, return McpResult[T]:
proc lookup(code: string): McpResult[string] = if code.len == 0: return mcpResultError[string]("invalid_code", "A code is required") mcpResult("result for " & code)mcpFailure[T](message) is a shorthand for the tool_error code. Set retryable = true when retry middleware or a client may safely try again.
Group tools
Section titled “Group tools”Namespaces make related tools easier to discover and prevent name collisions:
var admin = newMcpToolGroup("admin")admin.addTool mcpTool("reload", "Reload configuration", %*{"type": "object"}, proc (args: JsonNode, context: McpContext): McpToolResult = textResult("ok"))server.addToolGroup(admin)The tool is exposed as admin.reload. You can also use server.addTools("admin", tools).
Discovery and pagination
Section titled “Discovery and pagination”Discovery is sorted by final name, regardless of registration order. Set listPageSize in newMcpServer when a list should be paginated, for example listPageSize = 25. The client follows nextCursor values until it has the complete list.
listTtlMs and listCacheScope add cache hints to list and resource-read responses. listCacheScope must be "public" or "private".
Related: Typed tools, Resources, and the server API reference.