opalserve
v3.4.0
Published
The control plane for your team's AI tools — share MCP servers, knowledge bases, and usage analytics across your engineering team
Maintainers
Readme
OpalServe is an open-source platform that gives engineering teams a single place to register, discover, and govern the MCP (Model Context Protocol) servers their AI coding tools depend on. Instead of every developer manually configuring Claude Desktop, Cursor, Codex, or Windsurf with scattered server definitions, OpalServe provides a centralized registry with shared knowledge bases, usage analytics, role-based access control, and a built-in MCP gateway -- so your team's AI tools stay consistent, observable, and secure.
Feature Highlights
| | Feature | Status | Description |
|---|---|---|---|
| :books: | Team MCP Registry | ✅ Stable | Admin registers servers once; every developer pulls them with opalserve sync |
| :brain: | Team Brain (Graphiti) | 🆕 v3.4 preview | Run opalserve enable graph to spawn a Graphiti sidecar — temporal knowledge graph that every linked editor inherits via graph_search |
| :bar_chart: | Usage Analytics Dashboard | ✅ Stable (v3.3.0) | Every tool call (HTTP + MCP gateway) is captured in usage_events. Dashboard renders real numbers; /api/v1/me/activity for personal audit; opalserve admin audit --since 7d for team feed |
| :twisted_rightwards_arrows: | Drift Detection | 🆕 v3.4 | opalserve drift compares local registry to team config; flags match/drift/missing/local-only servers. REST endpoint + Dashboard tab |
| :lock: | Auth & Access Control | ✅ Stable (v3.1.1 hardened) | User accounts (scrypt-hashed), HMAC-secured API keys, per-IP/key rate limits |
| :electric_plug: | Editor adapters | ✅ Stable (v3.2) | opalserve link auto-configures Claude Desktop, Cursor, Cline with one command |
| :globe_with_meridians: | MCP Gateway | ✅ Stable (stdio); SSE/HTTP transports targeted for v3.5 | OpalServe is itself an MCP server — connect any MCP client over stdio today |
| :art: | Beautiful CLI | ✅ Stable | Interactive setup wizard, gradient banners, color-coded tables, 25+ commands |
| :seedling: | 100% Open Source | ✅ Stable | MIT licensed, self-host for free, no vendor lock-in |
Architecture
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ GitHub │ │ Slack │ │ Filesystem │ │ PostgreSQL │
│ MCP Server │ │ MCP Server │ │ MCP Server │ │ MCP Server │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │ │
└────────────────┼────────────────┼────────────────┘
│ MCP Protocol (stdio / SSE)
│
┌──────────┴──────────────────────────────┐
│ OpalServe Team Server │
│ │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ MCP Server │ │ Shared Knowledge │ │
│ │ Registry │ │ Base (FTS) │ │
│ └─────────────┘ └──────────────────┘ │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ Usage │ │ Auth / API Keys │ │
│ │ Analytics │ │ Rate Limiting │ │
│ └─────────────┘ └──────────────────┘ │
│ ┌─────────────┐ ┌──────────────────┐ │
│ │ MCP Gateway │ │ React Dashboard │ │
│ │ (stdio/SSE) │ │ (/dashboard) │ │
│ └─────────────┘ └──────────────────┘ │
│ │
│ SQLite DB ── Fastify HTTP API (:3456) │
└──────────────────┬──────────────────────┘
│
HTTPS API + MCP Protocol (stdio / SSE)
│
┌──────────────────────┼──────────────────────┐
│ │ │
┌────────┴─────────┐ ┌────────┴─────────┐ ┌────────┴─────────┐
│ Dev A │ │ Dev B │ │ Dev C │
│ Claude Code │ │ Cursor │ │ Codex / Windsurf │
│ opalserve sync │ │ opalserve sync │ │ opalserve sync │
└──────────────────┘ └──────────────────┘ └──────────────────┘Quick Start
# 1. Install globally
npm install -g opalserve
# 2. Run the interactive setup wizard
opalserve init
# 3. Start the server
opalserve start
# 4. Register your first MCP server
opalserve server add --name files --stdio "npx -y @modelcontextprotocol/server-filesystem ."
# 5. Discover available tools
opalserve tools search "read file"
# 6. Wire OpalServe into your AI editor
opalserve link claude # or: cursor, cline
# (restart the editor; OpalServe shows up as the "opalserve" MCP server)Tip: OpalServe runs on port 3456 by default. The dashboard ships inside the npm package, opens automatically on
start, and is served fromhttp://localhost:3456/dashboard.
Wire-Up — One Command
opalserve link <editor> writes the OpalServe MCP gateway into your editor's config so its AI assistant gets every tool you've registered. Supports Claude Desktop, Cursor, and Cline (VS Code).
opalserve link cursor # link a single editor
opalserve link --all # link every detected editor
opalserve link --status # see what's linked, no changes
opalserve unlink cursor # remove later
opalserve doctor # diagnose port, gateway, links, secretsUnder the hood the editor spawns npx -y opalserve mcp as its MCP stdio process. Override with OPALSERVE_LINK_COMMAND env var if you want it to invoke a specific binary path instead.
Releases
3.3.0 — Team Intelligence (current): every tool call (HTTP and MCP gateway) now writes a usage_events row with user/team attribution, latency, success/error — so the analytics dashboard shows real data for the first time. New endpoints: GET /api/v1/me/activity (every user can see exactly what's logged about them — privacy-first), GET /api/v1/audit (admins see the full team feed; members see their own scoped). New CLI: opalserve admin audit --since 7d for a readable activity table.
3.2.1 — Coherence polish: smart opalserve add <thing> (URL → server, file → context doc, email → invite). Bare opalserve is context-aware. Init wizard detects installed AI editors.
3.2.0 — Coherence: opalserve link <editor> wires OpalServe into Claude Desktop / Cursor / Cline with one command, plus opalserve doctor for self-serve diagnostics, the opalserve mcp stdio entry-point, and auto-open of the dashboard on start.
3.1.1 — Trust Patch: hardens the auth and HTTP surface.
- API keys now use HMAC-SHA256 with a per-installation server secret (was unsalted SHA-256). Legacy keys are rehashed transparently on first use.
- Auth bypass (env-var fallback that silently disabled auth in non-team mode) removed. The registry's mode is now the single source of truth.
- Zod validation is enforced on every HTTP route. Raw
request.body as { ... }casts are gone. - Rate limiting via
@fastify/rate-limit: 200 req/min global per IP/key; 10 req/min on/auth/registerand/auth/login. - Helmet wired into Fastify (not just the Vercel docs layer); CORS narrowed from wildcard ports to a strict regex with optional allowlist via
OPALSERVE_CORS_ORIGINS.
Disclosure policy: see SECURITY.md.
opalserve --version
# 3.3.0
opalserve start
# HTTP API http://127.0.0.1:3456
# Dashboard http://127.0.0.1:3456/dashboard (opens in browser automatically)For source builds, the same release checks are used locally and in CI:
pnpm typecheck
pnpm lint
pnpm test
pnpm build
pnpm pack --dry-runTeam Mode Setup
Team mode turns OpalServe into a shared server that your entire engineering org connects to.
1. Initialize the team server
opalserve admin initThis creates an admin account, generates encryption keys, and prepares the SQLite database.
2. Configure team mode
Edit opalserve.config.json and set the mode:
{
"mode": "team-server",
"port": 3456,
"host": "0.0.0.0"
}3. Start the server
opalserve start4. Invite team members
opalserve admin invite [email protected]
opalserve admin invite [email protected]5. Developers connect
On each developer's machine:
npm install -g opalserve
# Login to the team server
opalserve login
# Pull all registered servers to local config
opalserve sync6. Manage access
# Set rate limits by role
opalserve admin limits --set developer:calls_per_hour:500
# Set tool permissions
opalserve admin permissions --set developer:filesystem:*:allowKnowledge Base
The knowledge base lets you upload documents that become searchable context for every AI tool connected through OpalServe.
Adding documents
# Upload architecture docs
opalserve context add ./docs/architecture.md
# Upload API specifications
opalserve context add ./docs/api-spec.md
# Upload coding standards
opalserve context add ./docs/coding-standards.mdSearching context
# Search by natural language query
opalserve context search "authentication flow"
# List all uploaded documents
opalserve context list
# Remove a document
opalserve context remove <document-id>When connected via the MCP gateway, AI tools like Claude Desktop can automatically search the knowledge base to ground their responses in your team's actual documentation.
Admin Dashboard
OpalServe ships with a built-in React SPA accessible at /dashboard when the server is running.
The dashboard provides:
- Usage overview -- charts for tool calls, token consumption, and active users over time
- Server monitoring -- live status of every registered MCP server with health indicators
- User management -- view team members, roles, and activity
- Tool browser -- searchable catalog of all discovered tools across servers
- Knowledge base manager -- upload, browse, and remove context documents
- Settings -- API key management, integration configuration, rate limits
http://localhost:3456/dashboardThe dashboard is available in team-server mode. Authentication is required for all management operations.
CLI Commands
| Command | Description |
|---|---|
| opalserve (no args) | Context-aware welcome: status if running, hints if not, first-run guide if fresh |
| opalserve add <thing> | Smart-add — URL → MCP server, file → context doc, email → invite |
| opalserve init | Interactive setup wizard -- configures mode, port, first server, links editors |
| opalserve start | Start the registry server (HTTP API + MCP gateway); opens dashboard in browser |
| opalserve start --no-browser | Start without auto-opening the dashboard |
| opalserve status | Show server status, connected servers, and tool counts |
| opalserve doctor | Self-diagnose port, gateway, registered servers, editor links, secrets |
| opalserve link <editor> | Wire OpalServe into Claude Desktop, Cursor, or Cline |
| opalserve link --all | Link every detected AI editor in one shot |
| opalserve link --status | Show editor link status (no changes) |
| opalserve unlink <editor> | Remove OpalServe from an editor's MCP config |
| opalserve mcp | Run as a stdio MCP server (used internally by linked editors) |
| opalserve health | Health check all registered servers |
| opalserve health --server <name> | Health check a specific server |
| opalserve admin audit | Show recent tool-call audit events (default: last 7d) |
| opalserve admin audit --since 24h | Custom time window (h/d/w/m) |
| opalserve login | Authenticate with a team server |
| opalserve logout | Clear stored credentials |
| opalserve whoami | Show current authenticated user info |
| opalserve sync | Pull team server configurations to local machine |
| opalserve server list | List all registered MCP servers |
| opalserve server add | Register a new MCP server (stdio, SSE, or streamable-http) |
| opalserve server remove <name> | Remove a registered server |
| opalserve tools list | List all discovered tools across servers |
| opalserve tools search <query> | Search for tools by natural language query |
| opalserve context add <file> | Upload a file to the shared knowledge base |
| opalserve context list | List all context documents |
| opalserve context search <query> | Search the knowledge base |
| opalserve context remove <id> | Remove a context document |
| opalserve admin init | Initialize team mode with an admin user |
| opalserve admin stats | Show usage statistics for the team |
| opalserve admin users | List all team members |
| opalserve admin invite <email> | Invite a user to the team |
| opalserve admin limits | View and manage rate limits |
| opalserve admin permissions | View and manage tool permissions |
HTTP API
OpalServe exposes a RESTful API under /api/v1. All endpoints return JSON.
Health
curl http://localhost:3456/api/v1/healthServers
# List all servers
curl http://localhost:3456/api/v1/servers
# Register a new server
curl -X POST http://localhost:3456/api/v1/servers \
-H "Content-Type: application/json" \
-d '{
"name": "filesystem",
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}'
# Remove a server
curl -X DELETE http://localhost:3456/api/v1/servers/filesystem
# Health check a specific server
curl http://localhost:3456/api/v1/servers/filesystem/healthTools
# List all tools
curl http://localhost:3456/api/v1/tools
# Search tools
curl "http://localhost:3456/api/v1/tools/search?q=read+file&limit=5"
# Call a tool
curl -X POST http://localhost:3456/api/v1/tools/filesystem__read_file/call \
-H "Content-Type: application/json" \
-d '{"arguments": {"path": "./README.md"}}'Authentication (team mode)
# Register
curl -X POST http://localhost:3456/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "...", "name": "Alice"}'
# Login
curl -X POST http://localhost:3456/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "password": "..."}'
# Get current user
curl http://localhost:3456/api/v1/auth/me \
-H "Authorization: Bearer <token>"
# Create API key
curl -X POST http://localhost:3456/api/v1/auth/keys \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name": "ci-pipeline"}'Knowledge Base (team mode)
# Upload a document
curl -X POST http://localhost:3456/api/v1/context/documents \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"title": "Architecture", "content": "...", "type": "markdown"}'
# Search documents
curl "http://localhost:3456/api/v1/context/search?q=authentication+flow" \
-H "Authorization: Bearer <token>"Usage Stats (team mode)
# Overview
curl http://localhost:3456/api/v1/stats/overview \
-H "Authorization: Bearer <token>"Library Usage
Use OpalServe programmatically in your Node.js applications:
import {
OpalServeRegistry,
McpGateway,
KnowledgeBase,
UsageTracker,
} from 'opalserve';
// Create the registry with server definitions
const registry = await OpalServeRegistry.create({
servers: [
{
name: 'filesystem',
transport: {
type: 'stdio',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],
},
},
{
name: 'github',
transport: {
type: 'sse',
url: 'https://mcp-github.example.com/sse',
},
},
],
});
// Start the registry -- connects to all servers and indexes tools
await registry.start();
// List all discovered tools
const tools = registry.listTools();
console.log(`Discovered ${tools.length} tools`);
// Search with natural language
const results = registry.searchTools('read file contents');
for (const result of results) {
console.log(`${result.tool.name} (score: ${result.score})`);
}
// Graceful shutdown
await registry.stop();MCP Gateway
OpalServe can act as an MCP server itself, exposing every registered tool through a single endpoint. This lets you point Claude Desktop, Cursor, or any MCP-compatible client at OpalServe instead of configuring each server individually.
Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"opalserve": {
"command": "opalserve",
"args": ["start", "--mcp"]
}
}
}Cursor
Add to your Cursor MCP settings:
{
"mcpServers": {
"opalserve": {
"command": "opalserve",
"args": ["start", "--mcp"]
}
}
}Once connected, your AI client gains access to:
opalserve_search-- search across all registered tools by natural language queryopalserve_context_search-- search the shared knowledge base- All proxied tools -- every tool from every registered server, available through the single gateway
Integrations
GitHub
Set up GitHub webhooks to automatically update context when code changes:
# Add GitHub MCP server
opalserve server add --name github --stdio "npx -y @modelcontextprotocol/server-github"
# Configure webhook (point your repo's webhook to):
# POST http://your-server:3456/api/v1/webhooks/githubEnvironment variables:
GITHUB_TOKEN=ghp_...
GITHUB_WEBHOOK_SECRET=your-secretSlack
Enable Slack integration for search commands and notifications:
# Add Slack MCP server
opalserve server add --name slack --stdio "npx -y @modelcontextprotocol/server-slack"Configure your Slack app to send events and commands to:
Events: POST http://your-server:3456/api/v1/slack/events
Commands: POST http://your-server:3456/api/v1/slack/commandsEnvironment variables:
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=your-secretConfiguration
OpalServe is configured via opalserve.config.json in your project root or home directory.
{
"mode": "local",
"port": 3456,
"host": "127.0.0.1",
"servers": [
{
"name": "filesystem",
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
]
}| Option | Default | Description |
|---|---|---|
| mode | "local" | "local" for single-user, "team-server" for shared |
| port | 3456 | HTTP API port |
| host | "127.0.0.1" | Bind address (0.0.0.0 for team server) |
| servers | [] | Array of MCP server configurations |
Modes: local (single developer, no auth) and team-server (multi-user with auth, analytics, knowledge base).
See the full configuration reference for all options.
Contributing
Contributions are welcome. To get started:
# Clone the repo
git clone https://github.com/adityaidev/opalserve.git
cd opalserve
# Install dependencies
pnpm install
# Start in dev mode (watch + auto-reload)
pnpm dev
# Type-check
pnpm typecheck
# Lint
pnpm lint
# Run tests
pnpm testPlease open an issue before submitting large PRs. Follow the existing code style -- strict TypeScript, Zod schemas for validation, and .js extensions in imports.
Links
- Documentation: opalserve.adityaai.dev
- npm: npmjs.com/package/opalserve
- GitHub: github.com/adityaidev/opalserve
- Releases: github.com/adityaidev/opalserve/releases
- Issues: github.com/adityaidev/opalserve/issues
License
MIT -- 100% open source, free to self-host.
See LICENSE for details.
