Skip to main content
Glama
tanvir-ux

typescript-mcp-server-demo

by tanvir-ux
README.md
# typescript-mcp-server-demo

Node.js / TypeScript MCP-style tool server skeleton for startups wiring agent tools. Exposes list_tools + call_tool (JSON-RPC 2.0) over stdio or HTTP JSON. No API keys required — tools are local stubs suitable for demos and integration tests.

## Why this shape

| Concern | Approach in this repo |
|---------|------------------------|
| Discovery | list_tools / tools/list returns name, description, JSON Schema |
| Invocation | call_tool / tools/call with name + arguments |
| Transport | MCP_TRANSPORT=stdio (default) or http |
| Startup fit | HTTP for Postman / gateways; stdio for local agent hosts |
| Safety | Fake CRM only; no secrets committed |

Protocol-light on purpose: integrate a tool plane without locking to one MCP SDK version. Swap handlers for real CRM / billing / support APIs when you harden.

## Tools

| Name | Purpose |
|------|---------|
| echo | Connectivity check — returns message |
| get_time | Current server time (UTC ISO-8601) |
| fake_crm_lookup | In-memory customer lookup by customerId or email |

Demo CRM ids: cust_1001, cust_1002, cust_1003.

## Architecture

```
Client (agent / IDE)
   |
   |- stdio: one JSON-RPC object per line on stdin -> stdout
   |- HTTP: /health /tools /rpc /tools/call
              |
              v
        handleRequest() -> ToolRegistry -> echo | get_time | fake_crm_lookup
```

## Requirements

- Node.js 18+
- package manager compatible with the lockfile-free package.json in this repo

## Setup

Install dependencies, optionally copy the env example file, then build TypeScript to dist/.
Scripts are defined in package.json: build, start, start:http, start:stdio, dev, dev:http, test.

## Run

Set MCP_TRANSPORT to http (port via MCP_PORT, default 3100) or stdio (default).

HTTP routes:

- GET /health — liveness
- GET /tools — list_tools shortcut
- POST /rpc — full JSON-RPC body
- POST /tools/call — body with name and arguments

Example tools/call body:

{"name":"echo","arguments":{"message":"hello"}}

Example JSON-RPC call_tool:

{"jsonrpc":"2.0","id":1,"method":"call_tool","params":{"name":"fake_crm_lookup","arguments":{"customerId":"cust_1001"}}}

## Test

Run the package.json test script. Uses Node built-in test runner (node:test) via tsx.

## Config

| Variable | Default | Notes |
|----------|---------|-------|
| MCP_TRANSPORT | stdio | stdio or http |
| MCP_HOST | 127.0.0.1 | HTTP bind host |
| MCP_PORT | 3100 | HTTP port |
| MCP_SERVER_NAME | typescript-mcp-server-demo | Log / health label |

See .env.example.

## Project layout

```
src/
  index.ts
  server.ts
  types.ts
  tools/ (echo, get-time, fake-crm-lookup, index)
  transports/ (stdio, http)
tests/
  tools.test.ts
  server.test.ts
```

## Integrating into a startup agent stack

1. Discover tools at boot (GET /tools or list_tools) and cache schemas for the LLM tool-calling layer.
2. Call tools from your agent loop with structured arguments; surface content[].text to the model and data to your app layer.
3. Replace fake_crm_lookup with a real CRM client behind the same RegisteredTool interface — keep names/schemas stable for prompts.
4. Lock down HTTP with authn/authz and network policy before production; prefer stdio or private mesh for privileged tools.
5. Graduate to a full MCP SDK transport when you need resources/prompts/sampling; this skeleton stays focused on the tool plane.

## License

MIT — see LICENSE.

---

Author: tanvir-ux