AI & MCP
An MCP server in Node: official SDK or a hand-written dispatcher
A Node MCP server handles the handshake, the tool list and the calls. The official SDK removes the transport code; a read-only catalogue does without it.
Key points
- The SDK provides the server, the stdio and Streamable HTTP transports, argument validation and the error shape.
- Authentication, rate limits and the text of descriptions stay with whoever writes the server.
- EneUI uses a hand-written dispatcher: 9 tools, 8 dependencies in package.json and no MCP SDK.
A Node MCP server must handle the handshake, the tool list and the calls over a transport. The official SDK removes the transport code, but a read-only catalogue works with a hand-written dispatcher.
What the SDK does for you
The @modelcontextprotocol/sdk package provides the server, the stdio and Streamable HTTP transports, tool registration, input-schema validation and error serialisation. You write the function and the content it returns.
What stays yours either way
- Authentication: read the token, resolve it to an account, answer 401 with
WWW-Authenticate. - Rate limits: count calls per token or per IP and return 429 with
Retry-After. - Content: descriptions, schemas and data come from your catalogue, not from the SDK.
The wire is simpler than the SDK
curl -s https://ui.eneawork.it/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize"}'
The response carries protocolVersion, capabilities, serverInfo and the agent instructions. Answer those fields and four methods and you already have a server Cursor and Claude Code can use.
| Method | With the SDK | EneUI, by hand |
|---|---|---|
| initialize | handled | handled |
| tools/list | from the registered list | from the TOOLS array |
| tools/call | automatic validation | dispatch with try/catch |
| resources/read | from the registered map | check with a regular expression |
| prompts/get | handled | -32601 |
| sampling/createMessage | handled | -32601 |
Why a catalogue stays without the SDK
There are 9 tools and they read an in-memory index: a dispatcher shows exactly what it answers, with no dependency to keep updated. The price is manual argument validation.
The install command the tools return is already complete: npx shadcn@latest add "https://ui.eneawork.it/api/registry/<library>/<name>.json?token=YOUR_TOKEN". The server copies no files: it hands the command to the agent.
The EneUI catalogue
Actions and pricing blocks come back as records, not generated code; one example is the 21st-shadcn data table, MIT licence and 114 stars declared upstream, read on 1 November 2026.
The limitation
A hand-written dispatcher validates no schema: a wrong argument throws inside the function and the answer becomes Tool failed: … with isError, not a -32602. EneUI accepts that trade because the tools are few and the types are simple.
Where to continue
Methods and transport are in how to build an MCP server; the name and schema of a tool are in designing an MCP tool; the big picture is in what MCP is. The comparison with REST APIs is in MCP vs REST.
Frequently asked questions
Do I need the SDK to write an MCP server?
No. The SDK removes transport and validation code, but the protocol is JSON-RPC over a transport: a manual dispatcher is enough for a few tools.
Which transport should I use in Node?
stdio if the client starts the process on the same machine; Streamable HTTP if the server is remote and shared by several clients.
Does the SDK handle authentication?
No. Tokens, the OAuth session and the WWW-Authenticate header stay with the server, which must resolve them before running the tool.
How many dependencies does the EneUI server have?
Eight in package.json, none of them an MCP SDK. The server uses Express for the JSON body and an array of tools for everything else.
What answer does a wrong argument produce?
In the EneUI server, content with isError and the text “Tool failed”, not a JSON-RPC error: validation is manual and the catch is broad.