Skip to main content
Glama

teamhub-mcp-server

A remote MCP (Model Context Protocol) server that lets multiple people's Claude Code sessions collaborate — see each other's live status, share and search project notes, hand off tasks, and share small durable facts — with per-project, owner-approved access control.

One person hosts it. Everyone else connects to it as a normal remote MCP server with a personal bearer token.

How it works

 Person A's Claude Code  --.
                            +--> teamhub-mcp-server (one Node process, one SQLite file)
 Person B's Claude Code  --'
  • Presence is global — everyone can see who's online and what they're doing.

  • Everything else (notes, tasks, memory) lives inside a project, which is permissioned. A project's owner has full access; everyone else needs an approved join request at one of two levels:

    • read_only — can view notes, tasks, and memory

    • collaborate — can also post notes, create/claim tasks, and write memory

Nothing is shared by default. Every cross-person data flow is an explicit tool call.

Related MCP server: Claude Orchestrator MCP

Prerequisites

  • Node.js >= 20 (tested on 20 and 24)

  • npm

  • A host machine with persistent disk (VPS, Fly.io, Render, Railway — not classic serverless like Lambda/Vercel functions)

Quick start

1. Clone and install

git clone https://github.com/murali2212/-teamhub-mcp-server.git
cd -teamhub-mcp-server
npm install

2. Build

npm run build

This compiles TypeScript from src/ into dist/.

3. Add users

Each person who will connect needs a bearer token. Generate one per person:

node scripts/add-user.mjs alice
node scripts/add-user.mjs bob

Each command:

  • Generates a random token

  • Stores only its SHA-256 hash in users.json (never the raw token)

  • Prints the raw token once — send it to that person privately

  • Prints the exact claude mcp add command they need to run

If a username already exists, the script refuses and tells you to remove the entry manually first (to rotate a token).

4. Start the server

npm start

The server listens on port 3000 by default. Override with the PORT environment variable:

PORT=8080 npm start

5. Each person connects (on their own machine)

Each person runs the command printed by add-user.mjs, which looks like:

claude mcp add --transport http teamhub https://<your-server-url>/mcp \
  --scope user \
  --header "Authorization: Bearer <their-token>"

--scope user makes it available across every project they open in Claude Code. They verify it works with /mcp inside any session.

Environment variables

Variable

Default

Description

PORT

3000

HTTP listen port

TEAMHUB_DB_PATH

<project-root>/teamhub.db

SQLite database file location

TEAMHUB_USERS_PATH

<project-root>/users.json

Users/tokens file location

Deployment

Requirements

  • Persistent local disk — SQLite needs a real filesystem. Do NOT deploy to classic serverless (Vercel functions, Netlify functions, AWS Lambda) where the filesystem is ephemeral.

  • HTTPS in production — the bearer token travels in a header on every request. Use a reverse proxy (Caddy, nginx + Let's Encrypt) or a tunnel (Cloudflare Tunnel, ngrok) for HTTPS.

  • One long-running process — this is not a request-at-a-time function; it's a persistent Node.js server.

Docker

A multi-stage Dockerfile is included:

docker build -t teamhub-mcp-server .
docker run -d \
  -p 3000:3000 \
  -v /path/to/data:/app/data \
  -e TEAMHUB_DB_PATH=/app/data/teamhub.db \
  -e TEAMHUB_USERS_PATH=/app/data/users.json \
  teamhub-mcp-server

Mount a volume for /app/data so the database and users file survive container restarts.

VPS (systemd)

# Build on the server
cd /opt/teamhub-mcp-server
npm install && npm run build

# Create a systemd service
sudo tee /etc/systemd/system/teamhub.service > /dev/null <<EOF
[Unit]
Description=TeamHub MCP Server
After=network.target

[Service]
Type=simple
User=teamhub
WorkingDirectory=/opt/teamhub-mcp-server
ExecStart=/usr/bin/node dist/index.js
Restart=always
Environment=PORT=3000

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable teamhub
sudo systemctl start teamhub

Put Caddy or nginx in front for automatic HTTPS.

Fly.io

fly launch --no-deploy
fly volumes create teamhub_data --size 1
# Edit fly.toml to mount the volume and set env vars
fly deploy

Railway / Render

Point at this repo, set the build command to npm install && npm run build, start command to npm start, and add a persistent disk mounted where TEAMHUB_DB_PATH and TEAMHUB_USERS_PATH point.

All 18 tools

Presence (global, no project needed)

Tool

What it does

teamhub_set_status

Update your live status so teammates can see what you're doing

teamhub_list_presence

See everyone's current status

Projects (access control)

Tool

What it does

teamhub_create_project

Create a new isolated project (you become the owner)

teamhub_request_to_join

Ask a project's owner for access (files a pending request — grants nothing)

teamhub_list_join_requests

List pending requests for projects you own

teamhub_respond_to_join_request

Approve or decline a join request (owner only)

teamhub_revoke_access

Revoke a member's access immediately (owner only)

teamhub_list_my_projects

List projects you own, are a member of, or have pending requests for

teamhub_project_audit_log

View the access-change audit trail (owner only)

Notes (project-scoped)

Tool

Access needed

What it does

teamhub_post_note

collaborate

Post a note to the project timeline

teamhub_get_notes

read_only

Read recent notes, newest first

teamhub_search_notes

read_only

Search notes by keyword (case-insensitive)

Tasks (project-scoped)

Tool

Access needed

What it does

teamhub_create_task

collaborate

Create a task, optionally assign to a teammate

teamhub_list_tasks

read_only

List tasks, optionally filtered by status/assignee

teamhub_claim_task

collaborate

Claim an open task for yourself

teamhub_update_task

collaborate

Update task status (open/claimed/done) with optional result

Memory (project-scoped key-value)

Tool

Access needed

What it does

teamhub_remember

collaborate

Store a key-value fact (upserts)

teamhub_recall

read_only

Look up a key, or list all keys

Security

  • Tokens hashed at restusers.json stores SHA-256 hashes, never raw tokens. A leaked file doesn't give working credentials.

  • Per-project access control — connecting to the server exposes nothing. Access must be explicitly requested and approved per project.

  • Audit trail — every access-affecting event is logged and queryable by the project owner.

  • Rate limiting — basic in-memory rate limiter (120 requests per 60-second window per token) guards against runaway loops.

  • No internal error leaks — unhandled exceptions return a generic 500, never stack traces.

  • Prompt injection mitigation — tool descriptions instruct the calling model to treat shared content as reference data, never as instructions.

Why not OAuth?

Static bearer tokens are a deliberate choice for the scale this targets (2-15 trusted friends/teammates). OAuth 2.1 with dynamic client registration is real infrastructure — disproportionate to "a handful of people I personally invite." If this ever needs self-service signup or untrusted users, that's the point to add OAuth.

Architecture decisions

  • Stateless HTTP transport — a fresh MCP server instance per request, no session IDs. Makes the server trivially restartable and safe behind a load balancer. Trade-off: no server-initiated push notifications (pull-based only).

  • SQLite (WAL mode) — zero-ops, single file, right-sized for small teams. Not meant to scale past ~15 people.

  • AsyncLocalStorage for caller identity — tool handlers get the caller's username via getCaller() without threading it through every function.

  • Per-request users.json reload — adding a new teammate doesn't require a server restart.

Project structure

teamhub-mcp-server/
  src/
    index.ts          # Express app, /mcp endpoint, /health, error handling
    auth.ts           # Bearer token auth middleware, rate limiting
    context.ts        # AsyncLocalStorage for per-request caller identity
    db.ts             # SQLite setup, schema, logAudit helper
    access.ts         # requireProjectAccess helper, AccessError class
    tools/
      presence.ts     # teamhub_set_status, teamhub_list_presence
      projects.ts     # Project CRUD, join requests, revoke, audit log
      notes.ts        # Post, get, search notes
      tasks.ts        # Create, list, claim, update tasks
      memory.ts       # Remember and recall key-value facts
  scripts/
    add-user.mjs      # CLI to generate tokens and add users
  Dockerfile          # Multi-stage Docker build
  package.json
  tsconfig.json

License

MIT

Related MCP Connectors

Related MCP Servers