Skip to main content
Glama
brian-mwirigi

@mcp-apps/streamable-ui-kit

README.md
# @mcp-apps/streamable-ui-kit

A Node host for [MCP](https://modelcontextprotocol.io) Streamable HTTP, protocol `2025-11-25`. MIT licensed. Extracted from [Claimbite](https://github.com/brian-mwirigi/claimbite) so other projects can run the same host without the bill-auditing app.

It wraps `@modelcontextprotocol/sdk` 1.32.1 `WebStandardStreamableHTTPServerTransport` and fixes two gaps that showed up when that transport was mounted on Node `http`:

- A pre-read request body was forwarded into the web-standard transport, and Node then wrote raw SSE bytes where a chunk-size header belonged.
- A `202` or `204` with no `Content-Length` was framed as chunked, and `fetch().text()` never returned.

`writeWebResponse` drops `transfer-encoding` from the SDK response and sets `Content-Length: 0` on `202` and `204`.

## Run the example

Node 22 or newer.

```bash
npm install
npm start
```

That listens on `http://127.0.0.1:<port>/mcp` and registers one tool, `ping`. Origins other than localhost are rejected. `GET /.well-known/oauth-protected-resource` returns RFC 9728 metadata with `authorization_servers: []`.

```bash
npm test
```

## Use it

```ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { startStreamableMcpServer } from "@mcp-apps/streamable-ui-kit";

const running = await startStreamableMcpServer({
  createServer: (client) => {
    const server = new McpServer({ name: "example", version: "0.0.1" });
    if (!client.elicitation) {
      // The client did not advertise elicitation. Refuse side effects in your tools.
    }
    return server;
  },
});
```

`client.elicitation` is true when the `initialize` body includes `capabilities.elicitation`. This package reports that flag. It does not refuse a tool call by itself.

`parseSseEvents` and `parseSseJson` live in `@mcp-apps/streamable-ui-kit/sse` and import nothing. A browser client can use them to read `notifications/progress` and a mid-stream `elicitation/create` before the POST body closes.

The package depends on `@modelcontextprotocol/sdk` and `@cfworker/json-schema`. It is not published to npm. Install from this repository.