Loading...
Loading...
Building MCP (Model Context Protocol) servers for Claude extensibility. Use when creating MCP servers, building custom Claude tools, extending Claude with external integrations, or developing tool packages for Claude Desktop.
npx skill4agent add yonatangross/orchestkit mcp-server-building+-------------+ JSON-RPC +-------------+
| Claude |<----------------->| MCP Server |
| (Host) | stdio/SSE/WS | (Tools) |
+-------------+ +-------------+from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
server = Server("my-tools")
@server.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="greet",
description="Greet a user by name",
inputSchema={
"type": "object",
"properties": {
"name": {"type": "string", "description": "Name to greet"}
},
"required": ["name"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
if name == "greet":
return [TextContent(type="text", text=f"Hello, {arguments['name']}!")]
raise ValueError(f"Unknown tool: {name}")
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const server = new Server(
{ name: "my-tools", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [{
name: "fetch_url",
description: "Fetch content from a URL",
inputSchema: {
type: "object",
properties: { url: { type: "string" } },
required: ["url"],
},
}],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "fetch_url") {
const { url } = request.params.arguments as { url: string };
const response = await fetch(url);
return { content: [{ type: "text", text: await response.text() }] };
}
throw new Error("Unknown tool");
});
await server.connect(new StdioServerTransport());| Decision | Choice | Rationale |
|---|---|---|
| Transport | stdio for CLI, SSE for web | stdio simplest, SSE for browsers |
| Language | TypeScript for production | Better SDK support, type safety |
| Error handling | Return errors as text | Claude can interpret and retry |
asyncio.to_thread()function-callingagent-loopsinput-validation