Skip to main content
Glama
gavinarori

MCP Server with Durable History

by gavinarori

MCP server — OAuth, stateless instances, external session state, load balancer

Run it

npm install

# Single instance, no load balancer:
npm run dev              # server on :3000
npm run simulate         # in another terminal: OAuth + traffic simulation
npm run simulate:oauth   # step-by-step OAuth walkthrough

# Full cluster: 3 backends + load balancer on :3000
npm run cluster          # or start pieces individually, see below

To start the cluster manually (useful for watching each backend's logs separately):

PORT=3001 INSTANCE_ID=backend-1 PUBLIC_URL=http://localhost:3000 npm run dev
PORT=3002 INSTANCE_ID=backend-2 PUBLIC_URL=http://localhost:3000 npm run dev
PORT=3003 INSTANCE_ID=backend-3 PUBLIC_URL=http://localhost:3000 npm run dev
npm run lb                # load balancer on :3000, routes to the 3 above

Related MCP server: MCP IDE Bridge

Files

Storage layer (swap these for real infra later — see bottom of this file)

  • src/session-store.ts — "hot" tier, stands in for Redis.

  • src/history-store.ts — "durable" tier, stands in for Postgres, idempotency-key guarded.

MCP server

  • src/mcp-instance.ts — registers the chat tool: resolve session → append turn → reply → update session.

  • src/server.ts — Express + Streamable HTTP transport + OAuth wiring. Distinguishes the MCP protocol session (transport handshake, in-memory Map, dies with the process) from the application conversation session (your data, in the stores above).

OAuth 2.1 (RFC 7591 dynamic registration + PKCE, via the MCP SDK's built-in auth router)

  • src/oauth-provider.ts — in-memory authorization server: clients, codes, tokens. Auto-approves consent (see the big comment at the top — this is the one thing to swap for real login before production).

  • src/oauth-client-helper.ts — shared client-side helper: registerClient() once per app, getAccessToken() once per user/login.

  • src/oauth-simulate.ts — didactic step-by-step walkthrough of the whole OAuth flow, with an unauthenticated call and a bad-token call to prove enforcement.

Load balancer

  • src/load-balancer.ts — health-checked reverse proxy across N backends. Currently IP-sticky, not round-robin — see the file's top comment for exactly why (OAuth tokens + MCP protocol sessions are still per-instance in-memory, so a client's whole lifecycle must land on one backend until that state is externalized too).

Simulation

  • src/simulate-traffic.ts — real MCP client: registers one OAuth client (app-level), then runs one multi-turn conversation (continuity proof) and 25 concurrent new conversations (load proof), each with its own per-user token.

What's simulated vs. real here

Real: MCP protocol handshake, tool registration/invocation, OAuth 2.1 (PKCE, dynamic registration, token issuance/verification/revocation), the reverse proxy, health checks.

Simulated, so you can run this with zero external infra: SessionStore, HistoryStore, and the OAuth provider's clients/codes/tokens are all in-memory Maps. The login screen in oauth-provider.authorize() is also stubbed to auto-approve as a single demo user.

Next steps to production

  1. Redis for session-store.ts (ioredis, same method signatures).

  2. Postgres for history-store.ts (pg/Drizzle/Prisma, same method signatures).

  3. Shared token store for oauth-provider.ts (Redis again works well) — this is what lets the load balancer drop IP-stickiness and go pure round-robin, since any instance can then verify any token.

  4. Real login/consent UI in oauth-provider.authorize(), replacing the auto-approve.

  5. MCP protocol session (the Map in server.ts) still wants either sticky routing by Mcp-Session-Id, or a client that reconnects per-request — this one is inherent to the Streamable HTTP transport, not something storage-swapping fixes.

  6. A real queue in front for burst absorption once traffic exceeds what autoscaling can react to in time.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A stateless MCP server that enables real-time, bidirectional messaging and collaboration between different IDEs and AI agents. It facilitates client-to-client communication, allowing tools like Cursor, VS Code, and Windsurf to coordinate workflows and share information seamlessly.
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that provides persistent memory for AI agents by storing session snapshots, factual memories, and conversation summaries. It enables seamless continuity between interactions by allowing agents to restore previous emotional states and recall relevant past experiences.
  • A
    license
    C
    quality
    C
    maintenance
    An MCP server that provides memory management and gateway capabilities, enabling persistent storage and retrieval of contextual information across sessions.
    48
    566
    26
    MIT

View all related MCP servers

Related MCP Connectors

  • Cloud-hosted MCP server for durable AI memory

  • An MCP memory server. One memory your agents share — across models, devices and apps.

  • An authenticated remote MCP server for user-owned devices and one-shot capability invocation.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gavinarori/MCP-system-design-and-architecture-in-typescript-'

If you have feedback or need assistance with the MCP directory API, please join our Discord server