opalserve 0.1.2 → 2.0.0
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.
- package/README.md +112 -116
- package/assets/logo.svg +54 -0
- package/dist/cli/commands/health.d.ts +4 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +36 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +81 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/server.d.ts +10 -0
- package/dist/cli/commands/server.d.ts.map +1 -0
- package/dist/cli/commands/server.js +108 -0
- package/dist/cli/commands/server.js.map +1 -0
- package/dist/cli/commands/start.d.ts +6 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +63 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +21 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/tools.d.ts +8 -0
- package/dist/cli/commands/tools.d.ts.map +1 -0
- package/dist/cli/commands/tools.js +28 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +82 -30
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ui/banner.d.ts +8 -0
- package/dist/cli/ui/banner.d.ts.map +1 -0
- package/dist/cli/ui/banner.js +54 -0
- package/dist/cli/ui/banner.js.map +1 -0
- package/dist/cli/ui/prompts.d.ts +11 -0
- package/dist/cli/ui/prompts.d.ts.map +1 -0
- package/dist/cli/ui/prompts.js +74 -0
- package/dist/cli/ui/prompts.js.map +1 -0
- package/dist/cli/ui/table.d.ts +5 -0
- package/dist/cli/ui/table.d.ts.map +1 -0
- package/dist/cli/ui/table.js +103 -0
- package/dist/cli/ui/table.js.map +1 -0
- package/dist/config/defaults.d.ts +5 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +18 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/loader.d.ts +4 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +57 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +2 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +2 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/discovery.d.ts +17 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +31 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/proxy.d.ts +14 -0
- package/dist/core/proxy.d.ts.map +1 -0
- package/dist/core/proxy.js +36 -0
- package/dist/core/proxy.js.map +1 -0
- package/dist/core/registry.d.ts +28 -31
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +90 -234
- package/dist/core/registry.js.map +1 -1
- package/dist/core/server-manager.d.ts +18 -0
- package/dist/core/server-manager.d.ts.map +1 -0
- package/dist/core/server-manager.js +120 -0
- package/dist/core/server-manager.js.map +1 -0
- package/dist/index.d.ts +11 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -9
- package/dist/index.js.map +1 -1
- package/dist/server/app.d.ts +8 -0
- package/dist/server/app.d.ts.map +1 -0
- package/dist/server/app.js +35 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/mcp-gateway.d.ts +12 -0
- package/dist/server/mcp-gateway.d.ts.map +1 -0
- package/dist/server/mcp-gateway.js +91 -0
- package/dist/server/mcp-gateway.js.map +1 -0
- package/dist/server/routes/health.d.ts +4 -0
- package/dist/server/routes/health.d.ts.map +1 -0
- package/dist/server/routes/health.js +22 -0
- package/dist/server/routes/health.js.map +1 -0
- package/dist/server/routes/servers.d.ts +4 -0
- package/dist/server/routes/servers.d.ts.map +1 -0
- package/dist/server/routes/servers.js +47 -0
- package/dist/server/routes/servers.js.map +1 -0
- package/dist/server/routes/tools.d.ts +4 -0
- package/dist/server/routes/tools.d.ts.map +1 -0
- package/dist/server/routes/tools.js +44 -0
- package/dist/server/routes/tools.js.map +1 -0
- package/dist/storage/database.d.ts +41 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +195 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/repositories/server-repo.d.ts +2 -0
- package/dist/storage/repositories/server-repo.d.ts.map +1 -0
- package/dist/storage/repositories/server-repo.js +3 -0
- package/dist/storage/repositories/server-repo.js.map +1 -0
- package/dist/storage/repositories/tool-repo.d.ts +2 -0
- package/dist/storage/repositories/tool-repo.d.ts.map +1 -0
- package/dist/storage/repositories/tool-repo.js +3 -0
- package/dist/storage/repositories/tool-repo.js.map +1 -0
- package/dist/types/index.d.ts +384 -591
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +44 -69
- package/dist/types/index.js.map +1 -1
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +23 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +65 -56
- package/.env.example +0 -19
- package/config/servers.example.yaml +0 -67
- package/config/servers.yaml +0 -2
- package/dist/cli/discover.d.ts +0 -3
- package/dist/cli/discover.d.ts.map +0 -1
- package/dist/cli/discover.js +0 -160
- package/dist/cli/discover.js.map +0 -1
- package/dist/connectors/base.d.ts +0 -49
- package/dist/connectors/base.d.ts.map +0 -1
- package/dist/connectors/base.js +0 -45
- package/dist/connectors/base.js.map +0 -1
- package/dist/connectors/custom.d.ts +0 -19
- package/dist/connectors/custom.d.ts.map +0 -1
- package/dist/connectors/custom.js +0 -129
- package/dist/connectors/custom.js.map +0 -1
- package/dist/connectors/github.d.ts +0 -18
- package/dist/connectors/github.d.ts.map +0 -1
- package/dist/connectors/github.js +0 -188
- package/dist/connectors/github.js.map +0 -1
- package/dist/connectors/google-drive.d.ts +0 -18
- package/dist/connectors/google-drive.d.ts.map +0 -1
- package/dist/connectors/google-drive.js +0 -209
- package/dist/connectors/google-drive.js.map +0 -1
- package/dist/connectors/index.d.ts +0 -11
- package/dist/connectors/index.d.ts.map +0 -1
- package/dist/connectors/index.js +0 -76
- package/dist/connectors/index.js.map +0 -1
- package/dist/connectors/postgres.d.ts +0 -18
- package/dist/connectors/postgres.d.ts.map +0 -1
- package/dist/connectors/postgres.js +0 -140
- package/dist/connectors/postgres.js.map +0 -1
- package/dist/connectors/slack.d.ts +0 -18
- package/dist/connectors/slack.d.ts.map +0 -1
- package/dist/connectors/slack.js +0 -181
- package/dist/connectors/slack.js.map +0 -1
- package/dist/core/auth.d.ts +0 -26
- package/dist/core/auth.d.ts.map +0 -1
- package/dist/core/auth.js +0 -81
- package/dist/core/auth.js.map +0 -1
- package/dist/core/tokenizer.d.ts +0 -16
- package/dist/core/tokenizer.d.ts.map +0 -1
- package/dist/core/tokenizer.js +0 -29
- package/dist/core/tokenizer.js.map +0 -1
- package/dist/governance/audit.d.ts +0 -27
- package/dist/governance/audit.d.ts.map +0 -1
- package/dist/governance/audit.js +0 -149
- package/dist/governance/audit.js.map +0 -1
- package/dist/governance/index.d.ts +0 -5
- package/dist/governance/index.d.ts.map +0 -1
- package/dist/governance/index.js +0 -5
- package/dist/governance/index.js.map +0 -1
- package/dist/governance/policy.d.ts +0 -20
- package/dist/governance/policy.d.ts.map +0 -1
- package/dist/governance/policy.js +0 -162
- package/dist/governance/policy.js.map +0 -1
- package/dist/governance/rate-limiter.d.ts +0 -20
- package/dist/governance/rate-limiter.d.ts.map +0 -1
- package/dist/governance/rate-limiter.js +0 -73
- package/dist/governance/rate-limiter.js.map +0 -1
- package/dist/governance/types.d.ts +0 -246
- package/dist/governance/types.d.ts.map +0 -1
- package/dist/governance/types.js +0 -72
- package/dist/governance/types.js.map +0 -1
- package/dist/identity/access-control.d.ts +0 -15
- package/dist/identity/access-control.d.ts.map +0 -1
- package/dist/identity/access-control.js +0 -81
- package/dist/identity/access-control.js.map +0 -1
- package/dist/identity/index.d.ts +0 -4
- package/dist/identity/index.d.ts.map +0 -1
- package/dist/identity/index.js +0 -4
- package/dist/identity/index.js.map +0 -1
- package/dist/identity/manager.d.ts +0 -29
- package/dist/identity/manager.d.ts.map +0 -1
- package/dist/identity/manager.js +0 -167
- package/dist/identity/manager.js.map +0 -1
- package/dist/identity/types.d.ts +0 -237
- package/dist/identity/types.d.ts.map +0 -1
- package/dist/identity/types.js +0 -80
- package/dist/identity/types.js.map +0 -1
- package/dist/registry/server.d.ts +0 -14
- package/dist/registry/server.d.ts.map +0 -1
- package/dist/registry/server.js +0 -177
- package/dist/registry/server.js.map +0 -1
- package/dist/utils/config.d.ts +0 -29
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js +0 -47
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -44
- package/dist/utils/index.js.map +0 -1
- package/dist/workflow/engine.d.ts +0 -18
- package/dist/workflow/engine.d.ts.map +0 -1
- package/dist/workflow/engine.js +0 -155
- package/dist/workflow/engine.js.map +0 -1
- package/dist/workflow/index.d.ts +0 -4
- package/dist/workflow/index.d.ts.map +0 -1
- package/dist/workflow/index.js +0 -4
- package/dist/workflow/index.js.map +0 -1
- package/dist/workflow/templates.d.ts +0 -4
- package/dist/workflow/templates.d.ts.map +0 -1
- package/dist/workflow/templates.js +0 -218
- package/dist/workflow/templates.js.map +0 -1
- package/dist/workflow/types.d.ts +0 -255
- package/dist/workflow/types.d.ts.map +0 -1
- package/dist/workflow/types.js +0 -48
- package/dist/workflow/types.js.map +0 -1
- package/eslint.config.js +0 -25
package/README.md
CHANGED
|
@@ -1,33 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/banner.svg" alt="OpalServe" width="800" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
>
|
|
5
|
+
<p align="center">
|
|
6
|
+
<strong>Local MCP Tool Registry & Discovery Hub</strong>
|
|
7
|
+
</p>
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
+
</p>
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
OpalServe solves the **"N×M" integration problem** in AI agent tooling. Before MCP, developers had to build custom connectors for every combination of AI model and tool. OpalServe provides a centralized registry with intelligent, context-sized tool discovery.
|
|
13
|
-
|
|
14
|
-
### Key Features
|
|
15
|
-
|
|
16
|
-
- **Intelligent Discovery**: Context-sized responses with relevance scoring
|
|
17
|
-
- **5 Pre-built Connectors**: GitHub, Slack, PostgreSQL, Google Drive, Custom
|
|
18
|
-
- **40+ MCP Tools**: Ready-to-use tools with full JSON Schema documentation
|
|
19
|
-
- **Visual Workflow Builder**: Build multi-step agentic workflows with templates
|
|
20
|
-
- **Enterprise Security**: JWT authentication, RBAC, audit logging
|
|
21
|
-
- **Governance**: Policy engine, rate limiting, compliance tracking
|
|
16
|
+
---
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
**OpalServe** aggregates, discovers, and proxies tools across multiple MCP (Model Context Protocol) servers from a single hub.
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
- **Real MCP Protocol** — Connects to any MCP server via stdio, SSE, or Streamable HTTP
|
|
21
|
+
- **Full-Text Search** — SQLite FTS5-powered tool discovery across all servers
|
|
22
|
+
- **Beautiful CLI** — Interactive setup, gradient banners, color-coded tables
|
|
23
|
+
- **HTTP API** — Fastify REST API for managing servers and tools
|
|
24
|
+
- **Persistent** — SQLite database survives restarts
|
|
25
|
+
- **MCP Gateway** — Acts as an MCP server itself for LLM clients
|
|
31
26
|
|
|
32
27
|
## Quick Start
|
|
33
28
|
|
|
@@ -35,113 +30,114 @@ OpalServe solves the **"N×M" integration problem** in AI agent tooling. Before
|
|
|
35
30
|
# Install globally
|
|
36
31
|
npm install -g opalserve
|
|
37
32
|
|
|
38
|
-
#
|
|
39
|
-
|
|
33
|
+
# Interactive setup
|
|
34
|
+
opalserve init
|
|
35
|
+
|
|
36
|
+
# Start the registry
|
|
37
|
+
opalserve start
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Add MCP Servers
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Filesystem access
|
|
44
|
+
opalserve server add --name files --stdio "npx -y @modelcontextprotocol/server-filesystem ."
|
|
40
45
|
|
|
41
|
-
#
|
|
42
|
-
opalserve
|
|
46
|
+
# GitHub
|
|
47
|
+
opalserve server add --name github --stdio "npx -y @modelcontextprotocol/server-github" --env GITHUB_TOKEN=ghp_xxx
|
|
43
48
|
|
|
44
|
-
#
|
|
45
|
-
opalserve-
|
|
49
|
+
# Any MCP server
|
|
50
|
+
opalserve server add --name my-server --url https://mcp.example.com/sse
|
|
46
51
|
```
|
|
47
52
|
|
|
48
|
-
##
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
### PostgreSQL (6 tools)
|
|
61
|
-
- Execute query, Get schema, List tables
|
|
62
|
-
- Get table info, List databases, Health check
|
|
63
|
-
|
|
64
|
-
### Google Drive (10 tools)
|
|
65
|
-
- List files, Get file, Create folder, Upload file
|
|
66
|
-
- Share file, List permissions, Search files
|
|
67
|
-
- Delete file, Download file, Get file metadata
|
|
68
|
-
|
|
69
|
-
### Custom (5 tools)
|
|
70
|
-
- HTTP request, Webhook trigger, Transform data
|
|
71
|
-
- Aggregate data, Route request
|
|
72
|
-
|
|
73
|
-
## API Endpoints
|
|
74
|
-
|
|
75
|
-
| Method | Endpoint | Description |
|
|
76
|
-
|--------|----------|-------------|
|
|
77
|
-
| GET | `/api/v1/health` | Health check |
|
|
78
|
-
| GET | `/api/v1/discover?query=<text>` | Discover tools by query |
|
|
79
|
-
| GET | `/api/v1/tools` | List all registered tools |
|
|
80
|
-
| GET | `/api/v1/tools/:id` | Get specific tool details |
|
|
81
|
-
| GET | `/api/v1/servers` | List MCP servers |
|
|
82
|
-
| POST | `/api/v1/servers/register` | Register new MCP server |
|
|
83
|
-
| POST | `/api/v1/auth/token` | Generate JWT token |
|
|
84
|
-
|
|
85
|
-
## Configuration
|
|
86
|
-
|
|
87
|
-
```env
|
|
88
|
-
PORT=3000
|
|
89
|
-
HOST=localhost
|
|
90
|
-
JWT_SECRET=your-secret-key
|
|
91
|
-
GITHUB_TOKEN=ghp_xxx
|
|
92
|
-
SLACK_BOT_TOKEN=xoxb-xxx
|
|
93
|
-
POSTGRES_URL=postgresql://user:pass@host:5432/db
|
|
94
|
-
GOOGLE_SERVICE_ACCOUNT=./config/google-service-account.json
|
|
95
|
-
ENABLE_AUTH=false
|
|
53
|
+
## Discover Tools
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# List all tools
|
|
57
|
+
opalserve tools list
|
|
58
|
+
|
|
59
|
+
# Full-text search
|
|
60
|
+
opalserve tools search "create issue"
|
|
61
|
+
|
|
62
|
+
# Check server health
|
|
63
|
+
opalserve health
|
|
96
64
|
```
|
|
97
65
|
|
|
98
|
-
##
|
|
66
|
+
## Use as MCP Gateway
|
|
99
67
|
|
|
68
|
+
Point your MCP client (Claude Desktop, Cursor, etc.) at OpalServe to access all tools from one connection:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"opalserve": {
|
|
74
|
+
"command": "npx",
|
|
75
|
+
"args": ["-y", "opalserve", "start", "--mcp"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
100
79
|
```
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
80
|
+
|
|
81
|
+
## Library Usage
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { OpalServeRegistry } from 'opalserve';
|
|
85
|
+
|
|
86
|
+
const registry = await OpalServeRegistry.create({
|
|
87
|
+
servers: [{
|
|
88
|
+
name: 'my-files',
|
|
89
|
+
transport: { type: 'stdio', command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', '.'] },
|
|
90
|
+
}],
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
await registry.start();
|
|
94
|
+
|
|
95
|
+
const tools = registry.listTools();
|
|
96
|
+
const results = registry.searchTools('read file');
|
|
97
|
+
const result = await registry.callTool('my-files:read_file', { path: './README.md' });
|
|
98
|
+
|
|
99
|
+
await registry.stop();
|
|
120
100
|
```
|
|
121
101
|
|
|
122
|
-
##
|
|
102
|
+
## HTTP API
|
|
123
103
|
|
|
124
|
-
|
|
125
|
-
- **RBAC**: Fine-grained permission-based access control
|
|
126
|
-
- **Confused Deputy Prevention**: Blocks malicious prompt injection
|
|
127
|
-
- **Native HTTP**: Uses Node.js `fetch` (no external dependencies)
|
|
128
|
-
- **Audit Logging**: Track all tool invocations and access
|
|
104
|
+
Start the server with `opalserve start`, then:
|
|
129
105
|
|
|
130
|
-
|
|
106
|
+
```bash
|
|
107
|
+
# Health check
|
|
108
|
+
curl http://localhost:3456/api/v1/health
|
|
131
109
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
3. **Workflow Automation**: Build multi-step workflows with visual builder
|
|
135
|
-
4. **Governance**: Monitor and control tool usage across organizations
|
|
110
|
+
# List tools
|
|
111
|
+
curl http://localhost:3456/api/v1/tools
|
|
136
112
|
|
|
137
|
-
|
|
113
|
+
# Search tools
|
|
114
|
+
curl "http://localhost:3456/api/v1/tools/search?q=read+file"
|
|
138
115
|
|
|
139
|
-
|
|
116
|
+
# Call a tool
|
|
117
|
+
curl -X POST http://localhost:3456/api/v1/tools/files%3Aread_file/call \
|
|
118
|
+
-H "Content-Type: application/json" \
|
|
119
|
+
-d '{"path": "./README.md"}'
|
|
120
|
+
```
|
|
140
121
|
|
|
141
|
-
##
|
|
122
|
+
## Architecture
|
|
142
123
|
|
|
143
|
-
|
|
124
|
+
```
|
|
125
|
+
[Claude/Cursor] <--MCP--> [OpalServe Gateway] <--MCP--> [Server A]
|
|
126
|
+
| <--MCP--> [Server B]
|
|
127
|
+
[HTTP API] <--MCP--> [Server C]
|
|
128
|
+
[SQLite DB]
|
|
129
|
+
```
|
|
144
130
|
|
|
145
|
-
|
|
131
|
+
OpalServe is simultaneously:
|
|
132
|
+
- An **MCP Client** to each backend server
|
|
133
|
+
- An **MCP Server** exposing aggregated tools
|
|
134
|
+
- An **HTTP API** for management
|
|
135
|
+
- A **CLI** for humans
|
|
136
|
+
|
|
137
|
+
## Documentation
|
|
138
|
+
|
|
139
|
+
Full documentation at [adityaidev.github.io/opalserve](https://adityaidev.github.io/opalserve)
|
|
140
|
+
|
|
141
|
+
## License
|
|
146
142
|
|
|
147
|
-
|
|
143
|
+
MIT
|
package/assets/logo.svg
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="none">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="opal-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#F59E0B"/>
|
|
5
|
+
<stop offset="35%" stop-color="#F97316"/>
|
|
6
|
+
<stop offset="65%" stop-color="#EF4444"/>
|
|
7
|
+
<stop offset="100%" stop-color="#8B5CF6"/>
|
|
8
|
+
</linearGradient>
|
|
9
|
+
<linearGradient id="opal-shine" x1="20%" y1="0%" x2="80%" y2="100%">
|
|
10
|
+
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="0.4"/>
|
|
11
|
+
<stop offset="50%" stop-color="#FFFFFF" stop-opacity="0.1"/>
|
|
12
|
+
<stop offset="100%" stop-color="#FFFFFF" stop-opacity="0"/>
|
|
13
|
+
</linearGradient>
|
|
14
|
+
<linearGradient id="facet-light" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
15
|
+
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="0.25"/>
|
|
16
|
+
<stop offset="100%" stop-color="#FFFFFF" stop-opacity="0.05"/>
|
|
17
|
+
</linearGradient>
|
|
18
|
+
</defs>
|
|
19
|
+
|
|
20
|
+
<!-- Outer gem shape — hexagonal prism -->
|
|
21
|
+
<polygon
|
|
22
|
+
points="256,32 432,128 432,320 256,480 80,320 80,128"
|
|
23
|
+
fill="url(#opal-gradient)"
|
|
24
|
+
/>
|
|
25
|
+
|
|
26
|
+
<!-- Top facet highlight -->
|
|
27
|
+
<polygon
|
|
28
|
+
points="256,32 432,128 256,192 80,128"
|
|
29
|
+
fill="url(#opal-shine)"
|
|
30
|
+
/>
|
|
31
|
+
|
|
32
|
+
<!-- Left facet -->
|
|
33
|
+
<polygon
|
|
34
|
+
points="80,128 256,192 256,380 80,320"
|
|
35
|
+
fill="url(#facet-light)"
|
|
36
|
+
opacity="0.3"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<!-- Inner refraction lines -->
|
|
40
|
+
<line x1="256" y1="192" x2="256" y2="380" stroke="#FFFFFF" stroke-opacity="0.15" stroke-width="2"/>
|
|
41
|
+
<line x1="256" y1="192" x2="160" y2="260" stroke="#FFFFFF" stroke-opacity="0.12" stroke-width="1.5"/>
|
|
42
|
+
<line x1="256" y1="192" x2="352" y2="260" stroke="#FFFFFF" stroke-opacity="0.12" stroke-width="1.5"/>
|
|
43
|
+
<line x1="256" y1="192" x2="180" y2="340" stroke="#FFFFFF" stroke-opacity="0.08" stroke-width="1"/>
|
|
44
|
+
<line x1="256" y1="192" x2="332" y2="340" stroke="#FFFFFF" stroke-opacity="0.08" stroke-width="1"/>
|
|
45
|
+
|
|
46
|
+
<!-- Center sparkle -->
|
|
47
|
+
<circle cx="256" cy="220" r="6" fill="#FFFFFF" opacity="0.6"/>
|
|
48
|
+
<circle cx="256" cy="220" r="12" fill="#FFFFFF" opacity="0.15"/>
|
|
49
|
+
|
|
50
|
+
<!-- Small accent sparkles -->
|
|
51
|
+
<circle cx="200" cy="260" r="3" fill="#FFFFFF" opacity="0.3"/>
|
|
52
|
+
<circle cx="310" cy="280" r="2.5" fill="#FFFFFF" opacity="0.25"/>
|
|
53
|
+
<circle cx="240" cy="320" r="2" fill="#FFFFFF" opacity="0.2"/>
|
|
54
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/health.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC/E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { OpalServeRegistry } from '../../core/registry.js';
|
|
4
|
+
import { showMiniBanner, showSuccess, showError } from '../ui/banner.js';
|
|
5
|
+
export async function healthCommand(options) {
|
|
6
|
+
showMiniBanner();
|
|
7
|
+
const spinner = ora('Running health checks...').start();
|
|
8
|
+
const registry = await OpalServeRegistry.create();
|
|
9
|
+
// Reconnect servers to get fresh status
|
|
10
|
+
const servers = registry.config.servers.filter(s => s.enabled);
|
|
11
|
+
if (options.server) {
|
|
12
|
+
const filtered = servers.filter(s => s.name === options.server);
|
|
13
|
+
if (filtered.length === 0) {
|
|
14
|
+
spinner.fail(`Server "${options.server}" not found`);
|
|
15
|
+
registry.getDatabase().close();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const results = await registry.healthCheck(options.server);
|
|
20
|
+
spinner.stop();
|
|
21
|
+
console.log(` ${chalk.bold('Health Check Results')}\n`);
|
|
22
|
+
for (const result of results) {
|
|
23
|
+
if (result.healthy) {
|
|
24
|
+
showSuccess(`${chalk.white(result.serverName)} — ${chalk.green('healthy')} (${result.toolCount} tools)`);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
showError(`${chalk.white(result.serverName)} — ${chalk.red('unhealthy')}${result.error ? ` (${result.error})` : ''}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (results.length === 0) {
|
|
31
|
+
console.log(chalk.gray(' No servers registered.'));
|
|
32
|
+
}
|
|
33
|
+
console.log('');
|
|
34
|
+
registry.getDatabase().close();
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/cli/commands/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA4B;IAC9D,cAAc,EAAE,CAAC;IAEjB,MAAM,OAAO,GAAG,GAAG,CAAC,0BAA0B,CAAC,CAAC,KAAK,EAAE,CAAC;IAExD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE,CAAC;IAElD,wCAAwC;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAChE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,aAAa,CAAC,CAAC;YACrD,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAEzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,WAAW,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,SAAS,SAAS,CAAC,CAAC;QAC3G,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxH,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyDjD"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { select } from '@inquirer/prompts';
|
|
5
|
+
import { showBox, showSuccess, showInfo } from '../ui/banner.js';
|
|
6
|
+
import { promptServerName, promptTransportType, promptStdioCommand, promptUrl, promptEnvVars, promptConfirm, promptPort } from '../ui/prompts.js';
|
|
7
|
+
export async function initCommand() {
|
|
8
|
+
showBox(`Welcome to ${chalk.bold('OpalServe')} Setup\n\n` +
|
|
9
|
+
'This wizard will help you configure OpalServe\n' +
|
|
10
|
+
'as your local MCP tool registry.', 'Setup');
|
|
11
|
+
// Step 1: Config location
|
|
12
|
+
const configLocation = await select({
|
|
13
|
+
message: 'Where should OpalServe store its configuration?',
|
|
14
|
+
choices: [
|
|
15
|
+
{ value: 'local', name: 'Current directory (./opalserve.config.json)' },
|
|
16
|
+
{ value: 'home', name: 'Home directory (~/.opalserve/config.json)' },
|
|
17
|
+
],
|
|
18
|
+
});
|
|
19
|
+
// Step 2: Port
|
|
20
|
+
const port = await promptPort();
|
|
21
|
+
// Step 3: Add servers
|
|
22
|
+
const servers = [];
|
|
23
|
+
let addServer = await promptConfirm('Would you like to register an MCP server now?');
|
|
24
|
+
while (addServer) {
|
|
25
|
+
const server = await promptServerConfig();
|
|
26
|
+
servers.push(server);
|
|
27
|
+
showSuccess(`Server "${server.name}" configured`);
|
|
28
|
+
addServer = await promptConfirm('Add another server?', false);
|
|
29
|
+
}
|
|
30
|
+
// Step 4: Write config
|
|
31
|
+
const config = {
|
|
32
|
+
servers,
|
|
33
|
+
gateway: { port, host: '127.0.0.1' },
|
|
34
|
+
storage: { path: '' },
|
|
35
|
+
logging: { level: 'info' },
|
|
36
|
+
};
|
|
37
|
+
const configPath = configLocation === 'local'
|
|
38
|
+
? resolve(process.cwd(), 'opalserve.config.json')
|
|
39
|
+
: resolve(process.env.HOME || process.env.USERPROFILE || '.', '.opalserve', 'config.json');
|
|
40
|
+
// Ensure directory exists
|
|
41
|
+
const { mkdirSync } = await import('node:fs');
|
|
42
|
+
const { dirname } = await import('node:path');
|
|
43
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
44
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
45
|
+
showSuccess(`Configuration saved to ${chalk.cyan(configPath)}`);
|
|
46
|
+
console.log('');
|
|
47
|
+
showInfo('Next steps:');
|
|
48
|
+
console.log(` ${chalk.cyan('opalserve start')} Start the registry`);
|
|
49
|
+
console.log(` ${chalk.cyan('opalserve server add')} Add more servers`);
|
|
50
|
+
console.log(` ${chalk.cyan('opalserve tools')} Browse available tools`);
|
|
51
|
+
console.log('');
|
|
52
|
+
}
|
|
53
|
+
async function promptServerConfig() {
|
|
54
|
+
const name = await promptServerName();
|
|
55
|
+
const transportType = await promptTransportType();
|
|
56
|
+
if (transportType === 'stdio') {
|
|
57
|
+
const { command, args } = await promptStdioCommand();
|
|
58
|
+
const env = await promptEnvVars();
|
|
59
|
+
return {
|
|
60
|
+
name,
|
|
61
|
+
transport: {
|
|
62
|
+
type: 'stdio',
|
|
63
|
+
command,
|
|
64
|
+
args,
|
|
65
|
+
...(Object.keys(env).length > 0 ? { env } : {}),
|
|
66
|
+
},
|
|
67
|
+
enabled: true,
|
|
68
|
+
tags: [],
|
|
69
|
+
autoConnect: true,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const url = await promptUrl();
|
|
73
|
+
return {
|
|
74
|
+
name,
|
|
75
|
+
transport: { type: transportType, url },
|
|
76
|
+
enabled: true,
|
|
77
|
+
tags: [],
|
|
78
|
+
autoConnect: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function serverListCommand(): Promise<void>;
|
|
2
|
+
export declare function serverAddCommand(options: {
|
|
3
|
+
name?: string;
|
|
4
|
+
stdio?: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
transport?: string;
|
|
7
|
+
env?: string[];
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function serverRemoveCommand(name: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/server.ts"],"names":[],"mappings":"AAQA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAWvD;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4EhB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBrE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { OpalServeRegistry } from '../../core/registry.js';
|
|
4
|
+
import { McpServerConfigSchema } from '../../types/index.js';
|
|
5
|
+
import { showMiniBanner, showSuccess, showError } from '../ui/banner.js';
|
|
6
|
+
import { renderServerTable } from '../ui/table.js';
|
|
7
|
+
import { promptServerName, promptTransportType, promptStdioCommand, promptUrl, promptEnvVars, promptConfirm } from '../ui/prompts.js';
|
|
8
|
+
export async function serverListCommand() {
|
|
9
|
+
showMiniBanner();
|
|
10
|
+
const registry = await OpalServeRegistry.create();
|
|
11
|
+
const servers = registry.listServers();
|
|
12
|
+
console.log(` ${chalk.bold('Registered Servers')} ${chalk.dim(`(${servers.length})`)}\n`);
|
|
13
|
+
console.log(renderServerTable(servers));
|
|
14
|
+
console.log('');
|
|
15
|
+
registry.getDatabase().close();
|
|
16
|
+
}
|
|
17
|
+
export async function serverAddCommand(options) {
|
|
18
|
+
showMiniBanner();
|
|
19
|
+
let config;
|
|
20
|
+
if (options.name && (options.stdio || options.url)) {
|
|
21
|
+
// Non-interactive mode
|
|
22
|
+
if (options.stdio) {
|
|
23
|
+
const parts = options.stdio.split(/\s+/);
|
|
24
|
+
const envObj = {};
|
|
25
|
+
if (options.env) {
|
|
26
|
+
for (const e of options.env) {
|
|
27
|
+
const [key, ...valueParts] = e.split('=');
|
|
28
|
+
envObj[key] = valueParts.join('=');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
config = McpServerConfigSchema.parse({
|
|
32
|
+
name: options.name,
|
|
33
|
+
transport: {
|
|
34
|
+
type: 'stdio',
|
|
35
|
+
command: parts[0],
|
|
36
|
+
args: parts.slice(1),
|
|
37
|
+
...(Object.keys(envObj).length > 0 ? { env: envObj } : {}),
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
config = McpServerConfigSchema.parse({
|
|
43
|
+
name: options.name,
|
|
44
|
+
transport: {
|
|
45
|
+
type: options.transport || 'sse',
|
|
46
|
+
url: options.url,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Interactive mode
|
|
53
|
+
const name = options.name || await promptServerName();
|
|
54
|
+
const transportType = await promptTransportType();
|
|
55
|
+
if (transportType === 'stdio') {
|
|
56
|
+
const { command, args } = await promptStdioCommand();
|
|
57
|
+
const env = await promptEnvVars();
|
|
58
|
+
config = McpServerConfigSchema.parse({
|
|
59
|
+
name,
|
|
60
|
+
transport: {
|
|
61
|
+
type: 'stdio',
|
|
62
|
+
command,
|
|
63
|
+
args,
|
|
64
|
+
...(Object.keys(env).length > 0 ? { env } : {}),
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const url = await promptUrl();
|
|
70
|
+
config = McpServerConfigSchema.parse({
|
|
71
|
+
name,
|
|
72
|
+
transport: { type: transportType, url },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const spinner = ora(`Connecting to ${config.name}...`).start();
|
|
77
|
+
try {
|
|
78
|
+
const registry = await OpalServeRegistry.create();
|
|
79
|
+
await registry.addServer(config);
|
|
80
|
+
const server = registry.listServers().find(s => s.name === config.name);
|
|
81
|
+
spinner.succeed(`Connected to ${chalk.white(config.name)}`);
|
|
82
|
+
showSuccess(`${server?.toolCount || 0} tools discovered`);
|
|
83
|
+
registry.getDatabase().close();
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
spinner.fail(`Failed to connect to ${config.name}`);
|
|
87
|
+
showError(error instanceof Error ? error.message : String(error));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export async function serverRemoveCommand(name) {
|
|
92
|
+
showMiniBanner();
|
|
93
|
+
const confirmed = await promptConfirm(`Remove server "${name}"?`);
|
|
94
|
+
if (!confirmed) {
|
|
95
|
+
console.log(chalk.dim(' Cancelled'));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const registry = await OpalServeRegistry.create();
|
|
99
|
+
try {
|
|
100
|
+
await registry.removeServer(name);
|
|
101
|
+
showSuccess(`Server "${name}" removed`);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
showError(error instanceof Error ? error.message : String(error));
|
|
105
|
+
}
|
|
106
|
+
registry.getDatabase().close();
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/cli/commands/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAMA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgE5G"}
|