opalserve 3.0.1 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +600 -569
  3. package/assets/logo.svg +51 -51
  4. package/dist/auth/api-keys.d.ts +8 -0
  5. package/dist/auth/api-keys.d.ts.map +1 -1
  6. package/dist/auth/api-keys.js +62 -2
  7. package/dist/auth/api-keys.js.map +1 -1
  8. package/dist/auth/index.d.ts +1 -1
  9. package/dist/auth/index.d.ts.map +1 -1
  10. package/dist/auth/index.js +1 -1
  11. package/dist/auth/index.js.map +1 -1
  12. package/dist/auth/middleware.d.ts.map +1 -1
  13. package/dist/auth/middleware.js +3 -11
  14. package/dist/auth/middleware.js.map +1 -1
  15. package/dist/cli/commands/admin.js +6 -6
  16. package/dist/cli/commands/context.d.ts.map +1 -1
  17. package/dist/cli/commands/context.js +9 -2
  18. package/dist/cli/commands/context.js.map +1 -1
  19. package/dist/cli/index.js +2 -1
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/cli/ui/banner.d.ts.map +1 -1
  22. package/dist/cli/ui/banner.js +15 -14
  23. package/dist/cli/ui/banner.js.map +1 -1
  24. package/dist/config/defaults.d.ts +1 -0
  25. package/dist/config/defaults.d.ts.map +1 -1
  26. package/dist/config/defaults.js +3 -0
  27. package/dist/config/defaults.js.map +1 -1
  28. package/dist/constants.d.ts +1 -1
  29. package/dist/constants.js +1 -1
  30. package/dist/context/index.js +1 -1
  31. package/dist/core/server-manager.d.ts.map +1 -1
  32. package/dist/core/server-manager.js +2 -1
  33. package/dist/core/server-manager.js.map +1 -1
  34. package/dist/dashboard/assets/charts-CKTlvUso.js +68 -0
  35. package/dist/dashboard/assets/icons-DciuKSzL.js +131 -0
  36. package/dist/dashboard/assets/index-BrOv-3xx.css +1 -0
  37. package/dist/dashboard/assets/index-DnqqzxX6.js +33 -0
  38. package/dist/dashboard/assets/react-BJczIp53.js +28 -0
  39. package/dist/dashboard/index.html +17 -14
  40. package/dist/integrations/github.js +3 -3
  41. package/dist/integrations/slack.js +1 -1
  42. package/dist/monitoring/tracker.js +13 -13
  43. package/dist/server/app.d.ts.map +1 -1
  44. package/dist/server/app.js +34 -1
  45. package/dist/server/app.js.map +1 -1
  46. package/dist/server/mcp-gateway.d.ts.map +1 -1
  47. package/dist/server/mcp-gateway.js +2 -1
  48. package/dist/server/mcp-gateway.js.map +1 -1
  49. package/dist/server/routes/_schemas.d.ts +116 -0
  50. package/dist/server/routes/_schemas.d.ts.map +1 -0
  51. package/dist/server/routes/_schemas.js +53 -0
  52. package/dist/server/routes/_schemas.js.map +1 -0
  53. package/dist/server/routes/auth.d.ts.map +1 -1
  54. package/dist/server/routes/auth.js +28 -14
  55. package/dist/server/routes/auth.js.map +1 -1
  56. package/dist/server/routes/context.d.ts.map +1 -1
  57. package/dist/server/routes/context.js +15 -8
  58. package/dist/server/routes/context.js.map +1 -1
  59. package/dist/server/routes/health.d.ts.map +1 -1
  60. package/dist/server/routes/health.js +2 -1
  61. package/dist/server/routes/health.js.map +1 -1
  62. package/dist/server/routes/servers.d.ts.map +1 -1
  63. package/dist/server/routes/servers.js +12 -7
  64. package/dist/server/routes/servers.js.map +1 -1
  65. package/dist/server/routes/stats.d.ts.map +1 -1
  66. package/dist/server/routes/stats.js +32 -11
  67. package/dist/server/routes/stats.js.map +1 -1
  68. package/dist/server/routes/team-servers.d.ts.map +1 -1
  69. package/dist/server/routes/team-servers.js +7 -6
  70. package/dist/server/routes/team-servers.js.map +1 -1
  71. package/dist/server/routes/tools.d.ts.map +1 -1
  72. package/dist/server/routes/tools.js +26 -12
  73. package/dist/server/routes/tools.js.map +1 -1
  74. package/dist/storage/database.d.ts.map +1 -1
  75. package/dist/storage/database.js +132 -129
  76. package/dist/storage/database.js.map +1 -1
  77. package/package.json +10 -8
  78. package/dist/dashboard/assets/index-BNOtcUPs.js +0 -257
  79. package/dist/dashboard/assets/index-Duwp34GW.css +0 -1
package/README.md CHANGED
@@ -1,569 +1,600 @@
1
- <p align="center">
2
- <img src="assets/banner.svg" alt="OpalServe" width="800" />
3
- </p>
4
-
5
- <p align="center">
6
- <strong>The control plane for your team's AI tools</strong>
7
- </p>
8
-
9
- <p align="center">
10
- <a href="https://www.npmjs.com/package/opalserve"><img src="https://img.shields.io/npm/v/opalserve?style=flat-square&color=F97316" alt="npm version" /></a>
11
- <a href="https://www.npmjs.com/package/opalserve"><img src="https://img.shields.io/npm/dm/opalserve?style=flat-square" alt="downloads" /></a>
12
- <a href="https://github.com/adityaidev/opalserve/blob/master/LICENSE"><img src="https://img.shields.io/github/license/adityaidev/opalserve?style=flat-square" alt="license" /></a>
13
- <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen?style=flat-square" alt="node version" /></a>
14
- <a href="https://github.com/adityaidev/opalserve"><img src="https://img.shields.io/github/stars/adityaidev/opalserve?style=flat-square" alt="GitHub stars" /></a>
15
- </p>
16
-
17
- ---
18
-
19
- **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.
20
-
21
- ---
22
-
23
- ## Feature Highlights
24
-
25
- | | Feature | Description |
26
- |---|---|---|
27
- | :books: | **Team MCP Registry** | Admin registers servers once; every developer pulls them with `opalserve sync` |
28
- | :brain: | **Shared Knowledge Base** | Upload architecture docs, coding standards, and API specs -- AI tools query them automatically via MCP |
29
- | :bar_chart: | **Usage Analytics Dashboard** | React SPA showing tool calls, token usage, active users, and error rates in real time |
30
- | :lock: | **Auth & Access Control** | User accounts, JWT tokens, API keys, rate limits, and per-role tool permissions |
31
- | :electric_plug: | **GitHub + Slack Integrations** | Webhooks auto-update context; Slack slash commands for search and notifications |
32
- | :globe_with_meridians: | **MCP Gateway** | OpalServe itself is an MCP server -- connect any AI client to access every tool from one endpoint |
33
- | :art: | **Beautiful CLI** | Interactive setup wizard, gradient banners, color-coded tables, 20+ commands |
34
- | :seedling: | **100% Open Source** | MIT licensed, self-host for free, no vendor lock-in |
35
-
36
- ---
37
-
38
- ## Architecture
39
-
40
- ```
41
- ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
42
- │ GitHub │ │ Slack │ │ Filesystem │ │ PostgreSQL │
43
- │ MCP Server │ │ MCP Server │ │ MCP Server │ │ MCP Server │
44
- └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
45
- │ │ │ │
46
- └────────────────┼────────────────┼────────────────┘
47
- │ MCP Protocol (stdio / SSE)
48
-
49
- ┌──────────┴──────────────────────────────┐
50
- │ OpalServe Team Server │
51
- │ │
52
- │ ┌─────────────┐ ┌──────────────────┐ │
53
- │ │ MCP Server │ │ Shared Knowledge │ │
54
- │ │ Registry │ │ Base (FTS) │ │
55
- │ └─────────────┘ └──────────────────┘ │
56
- │ ┌─────────────┐ ┌──────────────────┐ │
57
- │ │ Usage │ │ Auth / API Keys │ │
58
- │ │ Analytics │ │ Rate Limiting │ │
59
- │ └─────────────┘ └──────────────────┘ │
60
- │ ┌─────────────┐ ┌──────────────────┐ │
61
- │ │ MCP Gateway │ │ React Dashboard │ │
62
- │ │ (stdio/SSE) │ │ (/dashboard) │ │
63
- │ └─────────────┘ └──────────────────┘ │
64
- │ │
65
- │ SQLite DB ── Fastify HTTP API (:3456) │
66
- └──────────────────┬──────────────────────┘
67
-
68
- HTTPS API + MCP Protocol (stdio / SSE)
69
-
70
- ┌──────────────────────┼──────────────────────┐
71
- │ │ │
72
- ┌────────┴─────────┐ ┌────────┴─────────┐ ┌────────┴─────────┐
73
- │ Dev A │ │ Dev B │ │ Dev C │
74
- │ Claude Code │ │ Cursor │ │ Codex / Windsurf │
75
- │ opalserve sync │ │ opalserve sync │ │ opalserve sync │
76
- └──────────────────┘ └──────────────────┘ └──────────────────┘
77
- ```
78
-
79
- ---
80
-
81
- ## Quick Start
82
-
83
- ```bash
84
- # 1. Install globally
85
- npm install -g opalserve
86
-
87
- # 2. Run the interactive setup wizard
88
- opalserve init
89
-
90
- # 3. Start the server
91
- opalserve start
92
-
93
- # 4. Register your first MCP server
94
- opalserve server add --name files --stdio "npx -y @modelcontextprotocol/server-filesystem ."
95
-
96
- # 5. Discover available tools
97
- opalserve tools search "read file"
98
- ```
99
-
100
- > **Tip:** OpalServe runs on port **3456** by default. Visit `http://localhost:3456/dashboard` after starting.
101
-
102
- ---
103
-
104
- ## Team Mode Setup
105
-
106
- Team mode turns OpalServe into a shared server that your entire engineering org connects to.
107
-
108
- ### 1. Initialize the team server
109
-
110
- ```bash
111
- opalserve admin init
112
- ```
113
-
114
- This creates an admin account, generates encryption keys, and prepares the SQLite database.
115
-
116
- ### 2. Configure team mode
117
-
118
- Edit `opalserve.config.json` and set the mode:
119
-
120
- ```json
121
- {
122
- "mode": "team-server",
123
- "port": 3456,
124
- "host": "0.0.0.0"
125
- }
126
- ```
127
-
128
- ### 3. Start the server
129
-
130
- ```bash
131
- opalserve start
132
- ```
133
-
134
- ### 4. Invite team members
135
-
136
- ```bash
137
- opalserve admin invite alice@company.com
138
- opalserve admin invite bob@company.com
139
- ```
140
-
141
- ### 5. Developers connect
142
-
143
- On each developer's machine:
144
-
145
- ```bash
146
- npm install -g opalserve
147
-
148
- # Login to the team server
149
- opalserve login
150
-
151
- # Pull all registered servers to local config
152
- opalserve sync
153
- ```
154
-
155
- ### 6. Manage access
156
-
157
- ```bash
158
- # Set rate limits by role
159
- opalserve admin limits --set developer:calls_per_hour:500
160
-
161
- # Set tool permissions
162
- opalserve admin permissions --set developer:filesystem:*:allow
163
- ```
164
-
165
- ---
166
-
167
- ## Knowledge Base
168
-
169
- The knowledge base lets you upload documents that become searchable context for every AI tool connected through OpalServe.
170
-
171
- ### Adding documents
172
-
173
- ```bash
174
- # Upload architecture docs
175
- opalserve context add ./docs/architecture.md
176
-
177
- # Upload API specifications
178
- opalserve context add ./docs/api-spec.md
179
-
180
- # Upload coding standards
181
- opalserve context add ./docs/coding-standards.md
182
- ```
183
-
184
- ### Searching context
185
-
186
- ```bash
187
- # Search by natural language query
188
- opalserve context search "authentication flow"
189
-
190
- # List all uploaded documents
191
- opalserve context list
192
-
193
- # Remove a document
194
- opalserve context remove <document-id>
195
- ```
196
-
197
- 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.
198
-
199
- ---
200
-
201
- ## Admin Dashboard
202
-
203
- OpalServe ships with a built-in React SPA accessible at `/dashboard` when the server is running.
204
-
205
- The dashboard provides:
206
-
207
- - **Usage overview** -- charts for tool calls, token consumption, and active users over time
208
- - **Server monitoring** -- live status of every registered MCP server with health indicators
209
- - **User management** -- view team members, roles, and activity
210
- - **Tool browser** -- searchable catalog of all discovered tools across servers
211
- - **Knowledge base manager** -- upload, browse, and remove context documents
212
- - **Settings** -- API key management, integration configuration, rate limits
213
-
214
- ```
215
- http://localhost:3456/dashboard
216
- ```
217
-
218
- > The dashboard is available in team-server mode. Authentication is required for all management operations.
219
-
220
- ---
221
-
222
- ## CLI Commands
223
-
224
- | Command | Description |
225
- |---|---|
226
- | `opalserve init` | Interactive setup wizard -- configures mode, port, and first server |
227
- | `opalserve start` | Start the registry server (HTTP API + MCP gateway) |
228
- | `opalserve status` | Show server status, connected servers, and tool counts |
229
- | `opalserve health` | Health check all registered servers |
230
- | `opalserve health --server <name>` | Health check a specific server |
231
- | `opalserve login` | Authenticate with a team server |
232
- | `opalserve logout` | Clear stored credentials |
233
- | `opalserve whoami` | Show current authenticated user info |
234
- | `opalserve sync` | Pull team server configurations to local machine |
235
- | `opalserve server list` | List all registered MCP servers |
236
- | `opalserve server add` | Register a new MCP server (stdio, SSE, or streamable-http) |
237
- | `opalserve server remove <name>` | Remove a registered server |
238
- | `opalserve tools list` | List all discovered tools across servers |
239
- | `opalserve tools search <query>` | Search for tools by natural language query |
240
- | `opalserve context add <file>` | Upload a file to the shared knowledge base |
241
- | `opalserve context list` | List all context documents |
242
- | `opalserve context search <query>` | Search the knowledge base |
243
- | `opalserve context remove <id>` | Remove a context document |
244
- | `opalserve admin init` | Initialize team mode with an admin user |
245
- | `opalserve admin stats` | Show usage statistics for the team |
246
- | `opalserve admin users` | List all team members |
247
- | `opalserve admin invite <email>` | Invite a user to the team |
248
- | `opalserve admin limits` | View and manage rate limits |
249
- | `opalserve admin permissions` | View and manage tool permissions |
250
-
251
- ---
252
-
253
- ## HTTP API
254
-
255
- OpalServe exposes a RESTful API under `/api/v1`. All endpoints return JSON.
256
-
257
- ### Health
258
-
259
- ```bash
260
- curl http://localhost:3456/api/v1/health
261
- ```
262
-
263
- ### Servers
264
-
265
- ```bash
266
- # List all servers
267
- curl http://localhost:3456/api/v1/servers
268
-
269
- # Register a new server
270
- curl -X POST http://localhost:3456/api/v1/servers \
271
- -H "Content-Type: application/json" \
272
- -d '{
273
- "name": "filesystem",
274
- "transport": {
275
- "type": "stdio",
276
- "command": "npx",
277
- "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
278
- }
279
- }'
280
-
281
- # Remove a server
282
- curl -X DELETE http://localhost:3456/api/v1/servers/filesystem
283
-
284
- # Health check a specific server
285
- curl http://localhost:3456/api/v1/servers/filesystem/health
286
- ```
287
-
288
- ### Tools
289
-
290
- ```bash
291
- # List all tools
292
- curl http://localhost:3456/api/v1/tools
293
-
294
- # Search tools
295
- curl "http://localhost:3456/api/v1/tools/search?q=read+file&limit=5"
296
-
297
- # Call a tool
298
- curl -X POST http://localhost:3456/api/v1/tools/filesystem__read_file/call \
299
- -H "Content-Type: application/json" \
300
- -d '{"arguments": {"path": "./README.md"}}'
301
- ```
302
-
303
- ### Authentication (team mode)
304
-
305
- ```bash
306
- # Register
307
- curl -X POST http://localhost:3456/api/v1/auth/register \
308
- -H "Content-Type: application/json" \
309
- -d '{"email": "dev@company.com", "password": "...", "name": "Alice"}'
310
-
311
- # Login
312
- curl -X POST http://localhost:3456/api/v1/auth/login \
313
- -H "Content-Type: application/json" \
314
- -d '{"email": "dev@company.com", "password": "..."}'
315
-
316
- # Get current user
317
- curl http://localhost:3456/api/v1/auth/me \
318
- -H "Authorization: Bearer <token>"
319
-
320
- # Create API key
321
- curl -X POST http://localhost:3456/api/v1/auth/keys \
322
- -H "Authorization: Bearer <token>" \
323
- -H "Content-Type: application/json" \
324
- -d '{"name": "ci-pipeline"}'
325
- ```
326
-
327
- ### Knowledge Base (team mode)
328
-
329
- ```bash
330
- # Upload a document
331
- curl -X POST http://localhost:3456/api/v1/context/documents \
332
- -H "Authorization: Bearer <token>" \
333
- -H "Content-Type: application/json" \
334
- -d '{"title": "Architecture", "content": "...", "type": "markdown"}'
335
-
336
- # Search documents
337
- curl "http://localhost:3456/api/v1/context/search?q=authentication+flow" \
338
- -H "Authorization: Bearer <token>"
339
- ```
340
-
341
- ### Usage Stats (team mode)
342
-
343
- ```bash
344
- # Overview
345
- curl http://localhost:3456/api/v1/stats/overview \
346
- -H "Authorization: Bearer <token>"
347
- ```
348
-
349
- ---
350
-
351
- ## Library Usage
352
-
353
- Use OpalServe programmatically in your Node.js applications:
354
-
355
- ```typescript
356
- import {
357
- OpalServeRegistry,
358
- McpGateway,
359
- KnowledgeBase,
360
- UsageTracker,
361
- } from 'opalserve';
362
-
363
- // Create the registry with server definitions
364
- const registry = await OpalServeRegistry.create({
365
- servers: [
366
- {
367
- name: 'filesystem',
368
- transport: {
369
- type: 'stdio',
370
- command: 'npx',
371
- args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],
372
- },
373
- },
374
- {
375
- name: 'github',
376
- transport: {
377
- type: 'sse',
378
- url: 'https://mcp-github.example.com/sse',
379
- },
380
- },
381
- ],
382
- });
383
-
384
- // Start the registry -- connects to all servers and indexes tools
385
- await registry.start();
386
-
387
- // List all discovered tools
388
- const tools = registry.listTools();
389
- console.log(`Discovered ${tools.length} tools`);
390
-
391
- // Search with natural language
392
- const results = registry.searchTools('read file contents');
393
- for (const result of results) {
394
- console.log(`${result.tool.name} (score: ${result.score})`);
395
- }
396
-
397
- // Graceful shutdown
398
- await registry.stop();
399
- ```
400
-
401
- ---
402
-
403
- ## MCP Gateway
404
-
405
- 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.
406
-
407
- ### Claude Desktop
408
-
409
- Add to your `claude_desktop_config.json`:
410
-
411
- ```json
412
- {
413
- "mcpServers": {
414
- "opalserve": {
415
- "command": "opalserve",
416
- "args": ["start", "--mcp"]
417
- }
418
- }
419
- }
420
- ```
421
-
422
- ### Cursor
423
-
424
- Add to your Cursor MCP settings:
425
-
426
- ```json
427
- {
428
- "mcpServers": {
429
- "opalserve": {
430
- "command": "opalserve",
431
- "args": ["start", "--mcp"]
432
- }
433
- }
434
- }
435
- ```
436
-
437
- Once connected, your AI client gains access to:
438
-
439
- - **`opalserve_search`** -- search across all registered tools by natural language query
440
- - **`opalserve_context_search`** -- search the shared knowledge base
441
- - **All proxied tools** -- every tool from every registered server, available through the single gateway
442
-
443
- ---
444
-
445
- ## Integrations
446
-
447
- ### GitHub
448
-
449
- Set up GitHub webhooks to automatically update context when code changes:
450
-
451
- ```bash
452
- # Add GitHub MCP server
453
- opalserve server add --name github --stdio "npx -y @modelcontextprotocol/server-github"
454
-
455
- # Configure webhook (point your repo's webhook to):
456
- # POST http://your-server:3456/api/v1/webhooks/github
457
- ```
458
-
459
- Environment variables:
460
-
461
- ```
462
- GITHUB_TOKEN=ghp_...
463
- GITHUB_WEBHOOK_SECRET=your-secret
464
- ```
465
-
466
- ### Slack
467
-
468
- Enable Slack integration for search commands and notifications:
469
-
470
- ```bash
471
- # Add Slack MCP server
472
- opalserve server add --name slack --stdio "npx -y @modelcontextprotocol/server-slack"
473
- ```
474
-
475
- Configure your Slack app to send events and commands to:
476
-
477
- ```
478
- Events: POST http://your-server:3456/api/v1/slack/events
479
- Commands: POST http://your-server:3456/api/v1/slack/commands
480
- ```
481
-
482
- Environment variables:
483
-
484
- ```
485
- SLACK_BOT_TOKEN=xoxb-...
486
- SLACK_SIGNING_SECRET=your-secret
487
- ```
488
-
489
- ---
490
-
491
- ## Configuration
492
-
493
- OpalServe is configured via `opalserve.config.json` in your project root or home directory.
494
-
495
- ```json
496
- {
497
- "mode": "local",
498
- "port": 3456,
499
- "host": "127.0.0.1",
500
- "servers": [
501
- {
502
- "name": "filesystem",
503
- "transport": {
504
- "type": "stdio",
505
- "command": "npx",
506
- "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
507
- }
508
- }
509
- ]
510
- }
511
- ```
512
-
513
- | Option | Default | Description |
514
- |---|---|---|
515
- | `mode` | `"local"` | `"local"` for single-user, `"team-server"` for shared |
516
- | `port` | `3456` | HTTP API port |
517
- | `host` | `"127.0.0.1"` | Bind address (`0.0.0.0` for team server) |
518
- | `servers` | `[]` | Array of MCP server configurations |
519
-
520
- Modes: **local** (single developer, no auth) and **team-server** (multi-user with auth, analytics, knowledge base).
521
-
522
- > See the [full configuration reference](https://opalserve.vercel.app/config) for all options.
523
-
524
- ---
525
-
526
- ## Contributing
527
-
528
- Contributions are welcome. To get started:
529
-
530
- ```bash
531
- # Clone the repo
532
- git clone https://github.com/adityaidev/opalserve.git
533
- cd opalserve
534
-
535
- # Install dependencies
536
- pnpm install
537
-
538
- # Start in dev mode (watch + auto-reload)
539
- pnpm dev
540
-
541
- # Type-check
542
- pnpm typecheck
543
-
544
- # Lint
545
- pnpm lint
546
-
547
- # Run tests
548
- pnpm test
549
- ```
550
-
551
- Please open an issue before submitting large PRs. Follow the existing code style -- strict TypeScript, Zod schemas for validation, and `.js` extensions in imports.
552
-
553
- ---
554
-
555
- ## Links
556
-
557
- - **Documentation:** [opalserve.vercel.app](https://opalserve.vercel.app)
558
- - **npm:** [npmjs.com/package/opalserve](https://www.npmjs.com/package/opalserve)
559
- - **GitHub:** [github.com/adityaidev/opalserve](https://github.com/adityaidev/opalserve)
560
- - **Releases:** [github.com/adityaidev/opalserve/releases](https://github.com/adityaidev/opalserve/releases)
561
- - **Issues:** [github.com/adityaidev/opalserve/issues](https://github.com/adityaidev/opalserve/issues)
562
-
563
- ---
564
-
565
- ## License
566
-
567
- MIT -- 100% open source, free to self-host.
568
-
569
- See [LICENSE](./LICENSE) for details.
1
+ <p align="center">
2
+ <img src="assets/banner.svg" alt="OpalServe" width="800" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ <strong>The control plane for your team's AI tools</strong>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/opalserve"><img src="https://img.shields.io/npm/v/opalserve?style=flat-square&color=F97316" alt="npm version" /></a>
11
+ <a href="https://www.npmjs.com/package/opalserve"><img src="https://img.shields.io/npm/dm/opalserve?style=flat-square" alt="downloads" /></a>
12
+ <a href="https://github.com/adityaidev/opalserve/blob/master/LICENSE"><img src="https://img.shields.io/github/license/adityaidev/opalserve?style=flat-square" alt="license" /></a>
13
+ <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen?style=flat-square" alt="node version" /></a>
14
+ <a href="https://github.com/adityaidev/opalserve"><img src="https://img.shields.io/github/stars/adityaidev/opalserve?style=flat-square" alt="GitHub stars" /></a>
15
+ </p>
16
+
17
+ ---
18
+
19
+ **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.
20
+
21
+ ---
22
+
23
+ ## Feature Highlights
24
+
25
+ | | Feature | Status | Description |
26
+ |---|---|---|---|
27
+ | :books: | **Team MCP Registry** | ✅ Stable | Admin registers servers once; every developer pulls them with `opalserve sync` |
28
+ | :brain: | **Shared Knowledge Base** | ⚙️ Keyword search today; semantic graph (Graphiti) lands in v3.3 | Upload docs, search via the `opalserve_search` MCP tool from any connected client |
29
+ | :bar_chart: | **Usage Analytics Dashboard** | 🚧 Dashboard ships; live event ingestion lands in v3.3 | React SPA renders the analytics surface; full event capture is the v3.3 milestone |
30
+ | :lock: | **Auth & Access Control** | ✅ Stable (v3.1.1 hardened) | User accounts (scrypt-hashed), HMAC-secured API keys, per-IP/key rate limits. Per-role tool-permission enforcement targets v3.3 |
31
+ | :electric_plug: | **GitHub + Slack Integrations** | ⚙️ Webhook handlers ship; signature verification lands in v3.2 | Webhooks accept events; Slack slash command returns search results |
32
+ | :globe_with_meridians: | **MCP Gateway** | ✅ Stable (stdio); SSE/HTTP transports targeted for v3.3 | OpalServe is itself an MCP server connect any MCP client over stdio today |
33
+ | :art: | **Beautiful CLI** | ✅ Stable | Interactive setup wizard, gradient banners, color-coded tables, 20+ commands |
34
+ | :seedling: | **100% Open Source** | ✅ Stable | MIT licensed, self-host for free, no vendor lock-in |
35
+
36
+ ---
37
+
38
+ ## Architecture
39
+
40
+ ```
41
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
42
+ │ GitHub │ │ Slack │ │ Filesystem │ │ PostgreSQL │
43
+ │ MCP Server │ │ MCP Server │ │ MCP Server │ │ MCP Server │
44
+ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
45
+ │ │ │ │
46
+ └────────────────┼────────────────┼────────────────┘
47
+ │ MCP Protocol (stdio / SSE)
48
+
49
+ ┌──────────┴──────────────────────────────┐
50
+ │ OpalServe Team Server │
51
+ │ │
52
+ │ ┌─────────────┐ ┌──────────────────┐ │
53
+ │ │ MCP Server │ │ Shared Knowledge │ │
54
+ │ │ Registry │ │ Base (FTS) │ │
55
+ │ └─────────────┘ └──────────────────┘ │
56
+ │ ┌─────────────┐ ┌──────────────────┐ │
57
+ │ │ Usage │ │ Auth / API Keys │ │
58
+ │ │ Analytics │ │ Rate Limiting │ │
59
+ │ └─────────────┘ └──────────────────┘ │
60
+ │ ┌─────────────┐ ┌──────────────────┐ │
61
+ │ │ MCP Gateway │ │ React Dashboard │ │
62
+ │ │ (stdio/SSE) │ │ (/dashboard) │ │
63
+ │ └─────────────┘ └──────────────────┘ │
64
+ │ │
65
+ │ SQLite DB ── Fastify HTTP API (:3456) │
66
+ └──────────────────┬──────────────────────┘
67
+
68
+ HTTPS API + MCP Protocol (stdio / SSE)
69
+
70
+ ┌──────────────────────┼──────────────────────┐
71
+ │ │ │
72
+ ┌────────┴─────────┐ ┌────────┴─────────┐ ┌────────┴─────────┐
73
+ │ Dev A │ │ Dev B │ │ Dev C │
74
+ │ Claude Code │ │ Cursor │ │ Codex / Windsurf │
75
+ │ opalserve sync │ │ opalserve sync │ │ opalserve sync │
76
+ └──────────────────┘ └──────────────────┘ └──────────────────┘
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Quick Start
82
+
83
+ ```bash
84
+ # 1. Install globally
85
+ npm install -g opalserve
86
+
87
+ # 2. Run the interactive setup wizard
88
+ opalserve init
89
+
90
+ # 3. Start the server
91
+ opalserve start
92
+
93
+ # 4. Register your first MCP server
94
+ opalserve server add --name files --stdio "npx -y @modelcontextprotocol/server-filesystem ."
95
+
96
+ # 5. Discover available tools
97
+ opalserve tools search "read file"
98
+ ```
99
+
100
+ > **Tip:** OpalServe runs on port **3456** by default. The dashboard ships inside the npm package and is served from `http://localhost:3456/dashboard` after starting.
101
+
102
+ ## Trust Check
103
+
104
+ OpalServe 3.1.1 the **Trust Patch** — hardens the auth and HTTP surface:
105
+
106
+ - **API keys** now use HMAC-SHA256 with a per-installation server secret (was unsalted SHA-256). Legacy keys are rehashed transparently on first use.
107
+ - **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.
108
+ - **Zod validation** is enforced on every HTTP route. Raw `request.body as { ... }` casts are gone.
109
+ - **Rate limiting** via `@fastify/rate-limit`: 200 req/min global per IP/key; 10 req/min on `/auth/register` and `/auth/login`.
110
+ - **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`.
111
+
112
+ Disclosure policy: see [SECURITY.md](SECURITY.md).
113
+
114
+ ```bash
115
+ opalserve --version
116
+ # 3.1.0
117
+
118
+ opalserve start
119
+ # HTTP API http://127.0.0.1:3456
120
+ # Dashboard http://127.0.0.1:3456/dashboard
121
+ ```
122
+
123
+ For source builds, the same release checks are used locally and in CI:
124
+
125
+ ```bash
126
+ pnpm typecheck
127
+ pnpm lint
128
+ pnpm test
129
+ pnpm build
130
+ pnpm pack --dry-run
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Team Mode Setup
136
+
137
+ Team mode turns OpalServe into a shared server that your entire engineering org connects to.
138
+
139
+ ### 1. Initialize the team server
140
+
141
+ ```bash
142
+ opalserve admin init
143
+ ```
144
+
145
+ This creates an admin account, generates encryption keys, and prepares the SQLite database.
146
+
147
+ ### 2. Configure team mode
148
+
149
+ Edit `opalserve.config.json` and set the mode:
150
+
151
+ ```json
152
+ {
153
+ "mode": "team-server",
154
+ "port": 3456,
155
+ "host": "0.0.0.0"
156
+ }
157
+ ```
158
+
159
+ ### 3. Start the server
160
+
161
+ ```bash
162
+ opalserve start
163
+ ```
164
+
165
+ ### 4. Invite team members
166
+
167
+ ```bash
168
+ opalserve admin invite alice@company.com
169
+ opalserve admin invite bob@company.com
170
+ ```
171
+
172
+ ### 5. Developers connect
173
+
174
+ On each developer's machine:
175
+
176
+ ```bash
177
+ npm install -g opalserve
178
+
179
+ # Login to the team server
180
+ opalserve login
181
+
182
+ # Pull all registered servers to local config
183
+ opalserve sync
184
+ ```
185
+
186
+ ### 6. Manage access
187
+
188
+ ```bash
189
+ # Set rate limits by role
190
+ opalserve admin limits --set developer:calls_per_hour:500
191
+
192
+ # Set tool permissions
193
+ opalserve admin permissions --set developer:filesystem:*:allow
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Knowledge Base
199
+
200
+ The knowledge base lets you upload documents that become searchable context for every AI tool connected through OpalServe.
201
+
202
+ ### Adding documents
203
+
204
+ ```bash
205
+ # Upload architecture docs
206
+ opalserve context add ./docs/architecture.md
207
+
208
+ # Upload API specifications
209
+ opalserve context add ./docs/api-spec.md
210
+
211
+ # Upload coding standards
212
+ opalserve context add ./docs/coding-standards.md
213
+ ```
214
+
215
+ ### Searching context
216
+
217
+ ```bash
218
+ # Search by natural language query
219
+ opalserve context search "authentication flow"
220
+
221
+ # List all uploaded documents
222
+ opalserve context list
223
+
224
+ # Remove a document
225
+ opalserve context remove <document-id>
226
+ ```
227
+
228
+ 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.
229
+
230
+ ---
231
+
232
+ ## Admin Dashboard
233
+
234
+ OpalServe ships with a built-in React SPA accessible at `/dashboard` when the server is running.
235
+
236
+ The dashboard provides:
237
+
238
+ - **Usage overview** -- charts for tool calls, token consumption, and active users over time
239
+ - **Server monitoring** -- live status of every registered MCP server with health indicators
240
+ - **User management** -- view team members, roles, and activity
241
+ - **Tool browser** -- searchable catalog of all discovered tools across servers
242
+ - **Knowledge base manager** -- upload, browse, and remove context documents
243
+ - **Settings** -- API key management, integration configuration, rate limits
244
+
245
+ ```
246
+ http://localhost:3456/dashboard
247
+ ```
248
+
249
+ > The dashboard is available in team-server mode. Authentication is required for all management operations.
250
+
251
+ ---
252
+
253
+ ## CLI Commands
254
+
255
+ | Command | Description |
256
+ |---|---|
257
+ | `opalserve init` | Interactive setup wizard -- configures mode, port, and first server |
258
+ | `opalserve start` | Start the registry server (HTTP API + MCP gateway) |
259
+ | `opalserve status` | Show server status, connected servers, and tool counts |
260
+ | `opalserve health` | Health check all registered servers |
261
+ | `opalserve health --server <name>` | Health check a specific server |
262
+ | `opalserve login` | Authenticate with a team server |
263
+ | `opalserve logout` | Clear stored credentials |
264
+ | `opalserve whoami` | Show current authenticated user info |
265
+ | `opalserve sync` | Pull team server configurations to local machine |
266
+ | `opalserve server list` | List all registered MCP servers |
267
+ | `opalserve server add` | Register a new MCP server (stdio, SSE, or streamable-http) |
268
+ | `opalserve server remove <name>` | Remove a registered server |
269
+ | `opalserve tools list` | List all discovered tools across servers |
270
+ | `opalserve tools search <query>` | Search for tools by natural language query |
271
+ | `opalserve context add <file>` | Upload a file to the shared knowledge base |
272
+ | `opalserve context list` | List all context documents |
273
+ | `opalserve context search <query>` | Search the knowledge base |
274
+ | `opalserve context remove <id>` | Remove a context document |
275
+ | `opalserve admin init` | Initialize team mode with an admin user |
276
+ | `opalserve admin stats` | Show usage statistics for the team |
277
+ | `opalserve admin users` | List all team members |
278
+ | `opalserve admin invite <email>` | Invite a user to the team |
279
+ | `opalserve admin limits` | View and manage rate limits |
280
+ | `opalserve admin permissions` | View and manage tool permissions |
281
+
282
+ ---
283
+
284
+ ## HTTP API
285
+
286
+ OpalServe exposes a RESTful API under `/api/v1`. All endpoints return JSON.
287
+
288
+ ### Health
289
+
290
+ ```bash
291
+ curl http://localhost:3456/api/v1/health
292
+ ```
293
+
294
+ ### Servers
295
+
296
+ ```bash
297
+ # List all servers
298
+ curl http://localhost:3456/api/v1/servers
299
+
300
+ # Register a new server
301
+ curl -X POST http://localhost:3456/api/v1/servers \
302
+ -H "Content-Type: application/json" \
303
+ -d '{
304
+ "name": "filesystem",
305
+ "transport": {
306
+ "type": "stdio",
307
+ "command": "npx",
308
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
309
+ }
310
+ }'
311
+
312
+ # Remove a server
313
+ curl -X DELETE http://localhost:3456/api/v1/servers/filesystem
314
+
315
+ # Health check a specific server
316
+ curl http://localhost:3456/api/v1/servers/filesystem/health
317
+ ```
318
+
319
+ ### Tools
320
+
321
+ ```bash
322
+ # List all tools
323
+ curl http://localhost:3456/api/v1/tools
324
+
325
+ # Search tools
326
+ curl "http://localhost:3456/api/v1/tools/search?q=read+file&limit=5"
327
+
328
+ # Call a tool
329
+ curl -X POST http://localhost:3456/api/v1/tools/filesystem__read_file/call \
330
+ -H "Content-Type: application/json" \
331
+ -d '{"arguments": {"path": "./README.md"}}'
332
+ ```
333
+
334
+ ### Authentication (team mode)
335
+
336
+ ```bash
337
+ # Register
338
+ curl -X POST http://localhost:3456/api/v1/auth/register \
339
+ -H "Content-Type: application/json" \
340
+ -d '{"email": "dev@company.com", "password": "...", "name": "Alice"}'
341
+
342
+ # Login
343
+ curl -X POST http://localhost:3456/api/v1/auth/login \
344
+ -H "Content-Type: application/json" \
345
+ -d '{"email": "dev@company.com", "password": "..."}'
346
+
347
+ # Get current user
348
+ curl http://localhost:3456/api/v1/auth/me \
349
+ -H "Authorization: Bearer <token>"
350
+
351
+ # Create API key
352
+ curl -X POST http://localhost:3456/api/v1/auth/keys \
353
+ -H "Authorization: Bearer <token>" \
354
+ -H "Content-Type: application/json" \
355
+ -d '{"name": "ci-pipeline"}'
356
+ ```
357
+
358
+ ### Knowledge Base (team mode)
359
+
360
+ ```bash
361
+ # Upload a document
362
+ curl -X POST http://localhost:3456/api/v1/context/documents \
363
+ -H "Authorization: Bearer <token>" \
364
+ -H "Content-Type: application/json" \
365
+ -d '{"title": "Architecture", "content": "...", "type": "markdown"}'
366
+
367
+ # Search documents
368
+ curl "http://localhost:3456/api/v1/context/search?q=authentication+flow" \
369
+ -H "Authorization: Bearer <token>"
370
+ ```
371
+
372
+ ### Usage Stats (team mode)
373
+
374
+ ```bash
375
+ # Overview
376
+ curl http://localhost:3456/api/v1/stats/overview \
377
+ -H "Authorization: Bearer <token>"
378
+ ```
379
+
380
+ ---
381
+
382
+ ## Library Usage
383
+
384
+ Use OpalServe programmatically in your Node.js applications:
385
+
386
+ ```typescript
387
+ import {
388
+ OpalServeRegistry,
389
+ McpGateway,
390
+ KnowledgeBase,
391
+ UsageTracker,
392
+ } from 'opalserve';
393
+
394
+ // Create the registry with server definitions
395
+ const registry = await OpalServeRegistry.create({
396
+ servers: [
397
+ {
398
+ name: 'filesystem',
399
+ transport: {
400
+ type: 'stdio',
401
+ command: 'npx',
402
+ args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],
403
+ },
404
+ },
405
+ {
406
+ name: 'github',
407
+ transport: {
408
+ type: 'sse',
409
+ url: 'https://mcp-github.example.com/sse',
410
+ },
411
+ },
412
+ ],
413
+ });
414
+
415
+ // Start the registry -- connects to all servers and indexes tools
416
+ await registry.start();
417
+
418
+ // List all discovered tools
419
+ const tools = registry.listTools();
420
+ console.log(`Discovered ${tools.length} tools`);
421
+
422
+ // Search with natural language
423
+ const results = registry.searchTools('read file contents');
424
+ for (const result of results) {
425
+ console.log(`${result.tool.name} (score: ${result.score})`);
426
+ }
427
+
428
+ // Graceful shutdown
429
+ await registry.stop();
430
+ ```
431
+
432
+ ---
433
+
434
+ ## MCP Gateway
435
+
436
+ 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.
437
+
438
+ ### Claude Desktop
439
+
440
+ Add to your `claude_desktop_config.json`:
441
+
442
+ ```json
443
+ {
444
+ "mcpServers": {
445
+ "opalserve": {
446
+ "command": "opalserve",
447
+ "args": ["start", "--mcp"]
448
+ }
449
+ }
450
+ }
451
+ ```
452
+
453
+ ### Cursor
454
+
455
+ Add to your Cursor MCP settings:
456
+
457
+ ```json
458
+ {
459
+ "mcpServers": {
460
+ "opalserve": {
461
+ "command": "opalserve",
462
+ "args": ["start", "--mcp"]
463
+ }
464
+ }
465
+ }
466
+ ```
467
+
468
+ Once connected, your AI client gains access to:
469
+
470
+ - **`opalserve_search`** -- search across all registered tools by natural language query
471
+ - **`opalserve_context_search`** -- search the shared knowledge base
472
+ - **All proxied tools** -- every tool from every registered server, available through the single gateway
473
+
474
+ ---
475
+
476
+ ## Integrations
477
+
478
+ ### GitHub
479
+
480
+ Set up GitHub webhooks to automatically update context when code changes:
481
+
482
+ ```bash
483
+ # Add GitHub MCP server
484
+ opalserve server add --name github --stdio "npx -y @modelcontextprotocol/server-github"
485
+
486
+ # Configure webhook (point your repo's webhook to):
487
+ # POST http://your-server:3456/api/v1/webhooks/github
488
+ ```
489
+
490
+ Environment variables:
491
+
492
+ ```
493
+ GITHUB_TOKEN=ghp_...
494
+ GITHUB_WEBHOOK_SECRET=your-secret
495
+ ```
496
+
497
+ ### Slack
498
+
499
+ Enable Slack integration for search commands and notifications:
500
+
501
+ ```bash
502
+ # Add Slack MCP server
503
+ opalserve server add --name slack --stdio "npx -y @modelcontextprotocol/server-slack"
504
+ ```
505
+
506
+ Configure your Slack app to send events and commands to:
507
+
508
+ ```
509
+ Events: POST http://your-server:3456/api/v1/slack/events
510
+ Commands: POST http://your-server:3456/api/v1/slack/commands
511
+ ```
512
+
513
+ Environment variables:
514
+
515
+ ```
516
+ SLACK_BOT_TOKEN=xoxb-...
517
+ SLACK_SIGNING_SECRET=your-secret
518
+ ```
519
+
520
+ ---
521
+
522
+ ## Configuration
523
+
524
+ OpalServe is configured via `opalserve.config.json` in your project root or home directory.
525
+
526
+ ```json
527
+ {
528
+ "mode": "local",
529
+ "port": 3456,
530
+ "host": "127.0.0.1",
531
+ "servers": [
532
+ {
533
+ "name": "filesystem",
534
+ "transport": {
535
+ "type": "stdio",
536
+ "command": "npx",
537
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
538
+ }
539
+ }
540
+ ]
541
+ }
542
+ ```
543
+
544
+ | Option | Default | Description |
545
+ |---|---|---|
546
+ | `mode` | `"local"` | `"local"` for single-user, `"team-server"` for shared |
547
+ | `port` | `3456` | HTTP API port |
548
+ | `host` | `"127.0.0.1"` | Bind address (`0.0.0.0` for team server) |
549
+ | `servers` | `[]` | Array of MCP server configurations |
550
+
551
+ Modes: **local** (single developer, no auth) and **team-server** (multi-user with auth, analytics, knowledge base).
552
+
553
+ > See the [full configuration reference](https://opalserve.adityaai.dev/config) for all options.
554
+
555
+ ---
556
+
557
+ ## Contributing
558
+
559
+ Contributions are welcome. To get started:
560
+
561
+ ```bash
562
+ # Clone the repo
563
+ git clone https://github.com/adityaidev/opalserve.git
564
+ cd opalserve
565
+
566
+ # Install dependencies
567
+ pnpm install
568
+
569
+ # Start in dev mode (watch + auto-reload)
570
+ pnpm dev
571
+
572
+ # Type-check
573
+ pnpm typecheck
574
+
575
+ # Lint
576
+ pnpm lint
577
+
578
+ # Run tests
579
+ pnpm test
580
+ ```
581
+
582
+ Please open an issue before submitting large PRs. Follow the existing code style -- strict TypeScript, Zod schemas for validation, and `.js` extensions in imports.
583
+
584
+ ---
585
+
586
+ ## Links
587
+
588
+ - **Documentation:** [opalserve.adityaai.dev](https://opalserve.adityaai.dev)
589
+ - **npm:** [npmjs.com/package/opalserve](https://www.npmjs.com/package/opalserve)
590
+ - **GitHub:** [github.com/adityaidev/opalserve](https://github.com/adityaidev/opalserve)
591
+ - **Releases:** [github.com/adityaidev/opalserve/releases](https://github.com/adityaidev/opalserve/releases)
592
+ - **Issues:** [github.com/adityaidev/opalserve/issues](https://github.com/adityaidev/opalserve/issues)
593
+
594
+ ---
595
+
596
+ ## License
597
+
598
+ MIT -- 100% open source, free to self-host.
599
+
600
+ See [LICENSE](./LICENSE) for details.