@samanhappy/mcphub 0.12.17 → 1.0.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.
- package/README.fr.md +7 -5
- package/README.md +24 -4
- package/README.zh.md +25 -4
- package/bin/cli.js +64 -50
- package/dist/cli/call-arguments.js +81 -0
- package/dist/cli/call-arguments.js.map +1 -0
- package/dist/cli/commands/call.js +75 -0
- package/dist/cli/commands/call.js.map +1 -0
- package/dist/cli/commands/config.js +132 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/discover.js +127 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/export.js +20 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/groups.js +107 -0
- package/dist/cli/commands/groups.js.map +1 -0
- package/dist/cli/commands/install.js +173 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/keys.js +91 -0
- package/dist/cli/commands/keys.js.map +1 -0
- package/dist/cli/commands/login.js +70 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/servers.js +142 -0
- package/dist/cli/commands/servers.js.map +1 -0
- package/dist/cli/commands/tools.js +162 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/context.js +44 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/errors.js +19 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/help.js +157 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/http.js +93 -0
- package/dist/cli/http.js.map +1 -0
- package/dist/cli/main.js +81 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.js +47 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parse-args.js +103 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/profile.js +109 -0
- package/dist/cli/profile.js.map +1 -0
- package/dist/cli/prompts.js +56 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/controllers/oauthServerController.js +37 -1
- package/dist/controllers/oauthServerController.js.map +1 -1
- package/dist/dao/ServerDaoDbImpl.js +3 -0
- package/dist/dao/ServerDaoDbImpl.js.map +1 -1
- package/dist/db/connection.js +48 -4
- package/dist/db/connection.js.map +1 -1
- package/dist/db/entities/Server.js +4 -0
- package/dist/db/entities/Server.js.map +1 -1
- package/dist/db/entities/VectorEmbedding.js +2 -5
- package/dist/db/entities/VectorEmbedding.js.map +1 -1
- package/dist/db/repositories/VectorEmbeddingRepository.js +100 -34
- package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
- package/dist/services/dataService.js +10 -1
- package/dist/services/dataService.js.map +1 -1
- package/dist/services/mcpService.js +47 -10
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/sseService.js +5 -3
- package/dist/services/sseService.js.map +1 -1
- package/dist/services/vectorSearchService.js +16 -3
- package/dist/services/vectorSearchService.js.map +1 -1
- package/dist/utils/migration.js +1 -0
- package/dist/utils/migration.js.map +1 -1
- package/dist/utils/serverConfigPersistence.js +5 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/frontend/dist/assets/ActivityPage-DwzGiMh_.js +2 -0
- package/frontend/dist/assets/ActivityPage-DwzGiMh_.js.map +1 -0
- package/frontend/dist/assets/ConfirmDialog-CxlizGia.js +2 -0
- package/frontend/dist/assets/ConfirmDialog-CxlizGia.js.map +1 -0
- package/frontend/dist/assets/Dashboard-BUCJcvk-.js +2 -0
- package/frontend/dist/assets/Dashboard-BUCJcvk-.js.map +1 -0
- package/frontend/dist/assets/DeleteDialog-DRbWonMu.js +2 -0
- package/frontend/dist/assets/DeleteDialog-DRbWonMu.js.map +1 -0
- package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js +2 -0
- package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js.map +1 -0
- package/frontend/dist/assets/GroupsPage-DfLlww4U.js +33 -0
- package/frontend/dist/assets/GroupsPage-DfLlww4U.js.map +1 -0
- package/frontend/dist/assets/LoginPage-DCjqYw_8.js +2 -0
- package/frontend/dist/assets/LoginPage-DCjqYw_8.js.map +1 -0
- package/frontend/dist/assets/LogsPage-CTa8kuDf.js +2 -0
- package/frontend/dist/assets/LogsPage-CTa8kuDf.js.map +1 -0
- package/frontend/dist/assets/MarketPage-C2Rh4WJB.js +3 -0
- package/frontend/dist/assets/MarketPage-C2Rh4WJB.js.map +1 -0
- package/frontend/dist/assets/{Pagination-y-gVO8ms.js → Pagination-BFi-X7qY.js} +2 -2
- package/frontend/dist/assets/{Pagination-y-gVO8ms.js.map → Pagination-BFi-X7qY.js.map} +1 -1
- package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js +2 -0
- package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js.map +1 -0
- package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js +2 -0
- package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js.map +1 -0
- package/frontend/dist/assets/ServersPage-hgCbCglG.js +37 -0
- package/frontend/dist/assets/ServersPage-hgCbCglG.js.map +1 -0
- package/frontend/dist/assets/SettingsPage-BzNX8mXv.js +12 -0
- package/frontend/dist/assets/SettingsPage-BzNX8mXv.js.map +1 -0
- package/frontend/dist/assets/StatusDot-CQzailBQ.js +2 -0
- package/frontend/dist/assets/StatusDot-CQzailBQ.js.map +1 -0
- package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js → ToggleGroup-CNBBvo3C.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js.map → ToggleGroup-CNBBvo3C.js.map} +1 -1
- package/frontend/dist/assets/UsersPage-C33b7LCM.js +2 -0
- package/frontend/dist/assets/UsersPage-C33b7LCM.js.map +1 -0
- package/frontend/dist/assets/{framework-vendor-_OBebcuv.js → framework-vendor-BUhDPOUZ.js} +2 -2
- package/frontend/dist/assets/{framework-vendor-_OBebcuv.js.map → framework-vendor-BUhDPOUZ.js.map} +1 -1
- package/frontend/dist/assets/{i18n-vendor-MQ921plD.js → i18n-vendor-Kbr87Ofu.js} +2 -2
- package/frontend/dist/assets/{i18n-vendor-MQ921plD.js.map → i18n-vendor-Kbr87Ofu.js.map} +1 -1
- package/frontend/dist/assets/icons-vendor-CKgJB3SC.js +292 -0
- package/frontend/dist/assets/icons-vendor-CKgJB3SC.js.map +1 -0
- package/frontend/dist/assets/index-BGiKkKzj.js +3 -0
- package/frontend/dist/assets/index-BGiKkKzj.js.map +1 -0
- package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
- package/frontend/dist/assets/{resourceService-BfCTSBsr.js → resourceService-C6umWRgq.js} +2 -2
- package/frontend/dist/assets/{resourceService-BfCTSBsr.js.map → resourceService-C6umWRgq.js.map} +1 -1
- package/frontend/dist/assets/useServerData-P5In98R4.js +2 -0
- package/frontend/dist/assets/{useServerData-QZqQTYcv.js.map → useServerData-P5In98R4.js.map} +1 -1
- package/frontend/dist/assets/useSettingsData-Cz7vKGLE.js +2 -0
- package/frontend/dist/assets/{useSettingsData-D3VROqS7.js.map → useSettingsData-Cz7vKGLE.js.map} +1 -1
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js +16 -0
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
- package/frontend/dist/index.html +5 -5
- package/package.json +2 -1
- package/frontend/dist/assets/ActivityPage-ClgKeihP.js +0 -2
- package/frontend/dist/assets/ActivityPage-ClgKeihP.js.map +0 -1
- package/frontend/dist/assets/Badge-Ck2fhRdl.js +0 -2
- package/frontend/dist/assets/Badge-Ck2fhRdl.js.map +0 -1
- package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js +0 -2
- package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js.map +0 -1
- package/frontend/dist/assets/Dashboard-BIXrLobn.js +0 -2
- package/frontend/dist/assets/Dashboard-BIXrLobn.js.map +0 -1
- package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js +0 -2
- package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js.map +0 -1
- package/frontend/dist/assets/GroupsPage-BjrvyHwu.js +0 -33
- package/frontend/dist/assets/GroupsPage-BjrvyHwu.js.map +0 -1
- package/frontend/dist/assets/LoginPage-BBHt_TfF.js +0 -2
- package/frontend/dist/assets/LoginPage-BBHt_TfF.js.map +0 -1
- package/frontend/dist/assets/LogsPage-D8Znq5NB.js +0 -2
- package/frontend/dist/assets/LogsPage-D8Znq5NB.js.map +0 -1
- package/frontend/dist/assets/MarketPage-haRuzjCw.js +0 -3
- package/frontend/dist/assets/MarketPage-haRuzjCw.js.map +0 -1
- package/frontend/dist/assets/PromptsPage-ByHWPyGe.js +0 -2
- package/frontend/dist/assets/PromptsPage-ByHWPyGe.js.map +0 -1
- package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js +0 -2
- package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js.map +0 -1
- package/frontend/dist/assets/ServersPage-CtS1I4yS.js +0 -37
- package/frontend/dist/assets/ServersPage-CtS1I4yS.js.map +0 -1
- package/frontend/dist/assets/SettingsPage-DxVigf7p.js +0 -12
- package/frontend/dist/assets/SettingsPage-DxVigf7p.js.map +0 -1
- package/frontend/dist/assets/UsersPage-Bipw33cS.js +0 -2
- package/frontend/dist/assets/UsersPage-Bipw33cS.js.map +0 -1
- package/frontend/dist/assets/icons-vendor-B67NtVuR.js +0 -172
- package/frontend/dist/assets/icons-vendor-B67NtVuR.js.map +0 -1
- package/frontend/dist/assets/index-CmnA4an8.js +0 -5
- package/frontend/dist/assets/index-CmnA4an8.js.map +0 -1
- package/frontend/dist/assets/index-DfFHVARX.css +0 -1
- package/frontend/dist/assets/useGroupData-DLhbP6zd.js +0 -2
- package/frontend/dist/assets/useGroupData-DLhbP6zd.js.map +0 -1
- package/frontend/dist/assets/useServerData-QZqQTYcv.js +0 -2
- package/frontend/dist/assets/useSettingsData-D3VROqS7.js +0 -2
- package/frontend/dist/assets/variableDetection-C3Xi21av.js +0 -16
- package/frontend/dist/assets/variableDetection-C3Xi21av.js.map +0 -1
package/README.fr.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
MCPHub facilite la gestion et la mise à l'échelle de plusieurs serveurs MCP (Model Context Protocol) en les organisant en points de terminaison HTTP streamables (SSE) flexibles, prenant en charge l'accès à tous les serveurs, à des serveurs individuels ou à des groupes de serveurs logiques.
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|
|
|
9
9
|
## 🌐 Démo en direct et Documentation
|
|
10
10
|
|
|
@@ -15,6 +15,7 @@ MCPHub facilite la gestion et la mise à l'échelle de plusieurs serveurs MCP (M
|
|
|
15
15
|
|
|
16
16
|
- **Gestion centralisée** - Surveillez et contrôlez tous les serveurs MCP depuis un tableau de bord unifié
|
|
17
17
|
- **Routage flexible** - Accédez à tous les serveurs, groupes spécifiques ou serveurs individuels via HTTP/SSE
|
|
18
|
+
- **Visibilité granulaire par groupe** - Contrôlez indépendamment la visibilité des Tools, Prompts et Resources de chaque serveur dans un groupe
|
|
18
19
|
- **Routage intelligent** - Découverte d'outils propulsée par IA utilisant la recherche sémantique vectorielle ([En savoir plus](https://docs.mcphub.app/features/smart-routing))
|
|
19
20
|
- **Configuration à chaud** - Ajoutez, supprimez ou mettez à jour les serveurs sans temps d'arrêt
|
|
20
21
|
- **Support OAuth 2.0** - Modes client et serveur pour une authentification sécurisée ([En savoir plus](https://docs.mcphub.app/features/oauth))
|
|
@@ -51,8 +52,8 @@ Créez un fichier `mcp_settings.json` :
|
|
|
51
52
|
# Exécutez avec une configuration personnalisée (recommandé)
|
|
52
53
|
docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
|
|
53
54
|
|
|
54
|
-
# Ou exécutez avec les paramètres par défaut
|
|
55
|
-
docker run -p 3000:3000 samanhappy/mcphub
|
|
55
|
+
# Ou exécutez avec les paramètres par défaut (montez ./data pour préserver l'état entre redémarrages)
|
|
56
|
+
docker run -p 3000:3000 -v ./data:/app/data samanhappy/mcphub
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
### Accéder au tableau de bord
|
|
@@ -110,9 +111,10 @@ pnpm dev
|
|
|
110
111
|
|
|
111
112
|
## 🔍 Stack technique
|
|
112
113
|
|
|
113
|
-
- **Backend** : Node.js, Express, TypeScript
|
|
114
|
+
- **Backend** : Node.js, Express, TypeScript (ESM)
|
|
114
115
|
- **Frontend** : React, Vite, Tailwind CSS
|
|
115
|
-
- **
|
|
116
|
+
- **Stockage** : `mcp_settings.json` (par défaut) ; PostgreSQL via TypeORM avec pgvector pour le Smart Routing
|
|
117
|
+
- **Authentification** : JWT + bcrypt pour les comptes locaux ; bearer keys ; serveur OAuth 2.0 intégré (`@node-oauth/oauth2-server`) ; Better Auth optionnel pour GitHub/Google
|
|
116
118
|
- **Protocole** : Model Context Protocol SDK
|
|
117
119
|
|
|
118
120
|
## 👥 Contribuer
|
package/README.md
CHANGED
|
@@ -52,8 +52,8 @@ Create a `mcp_settings.json` file:
|
|
|
52
52
|
# Run with custom config (recommended)
|
|
53
53
|
docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
|
|
54
54
|
|
|
55
|
-
# Or run with default settings
|
|
56
|
-
docker run -p 3000:3000 samanhappy/mcphub
|
|
55
|
+
# Or run with default settings (also mount ./data so credentials and state survive restarts)
|
|
56
|
+
docker run -p 3000:3000 -v ./data:/app/data samanhappy/mcphub
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
### Access Dashboard
|
|
@@ -85,6 +85,24 @@ http://localhost:3000/mcp/$smart/{group} # Smart routing within group
|
|
|
85
85
|
|
|
86
86
|
📖 See [API Reference](https://docs.mcphub.app/api-reference) for detailed endpoint documentation.
|
|
87
87
|
|
|
88
|
+
### Manage From the Terminal
|
|
89
|
+
|
|
90
|
+
The same `mcphub` binary doubles as a CLI for the running hub — no extra install needed.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
mcphub login --url http://localhost:3000 --username admin
|
|
94
|
+
mcphub servers list
|
|
95
|
+
mcphub servers add fetch --type stdio --command uvx --arg mcp-server-fetch
|
|
96
|
+
mcphub tools list # discover what tools are available
|
|
97
|
+
mcphub tools get fetch_url # see required params + sample command
|
|
98
|
+
mcphub call fetch_url url=https://example.com --json
|
|
99
|
+
mcphub keys create --name ci --access-type all
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
It also speaks the public marketplace API (`mcphub discover`, `mcphub install ...`) so server lookup and one-command install work against any hub with discovery enabled.
|
|
103
|
+
|
|
104
|
+
📖 See [CLI Guide](https://docs.mcphub.app/features/cli) for every subcommand, profiles, and CI usage.
|
|
105
|
+
|
|
88
106
|
## 📚 Documentation
|
|
89
107
|
|
|
90
108
|
| Topic | Description |
|
|
@@ -94,6 +112,7 @@ http://localhost:3000/mcp/$smart/{group} # Smart routing within group
|
|
|
94
112
|
| [Database Mode](https://docs.mcphub.app/configuration/database-configuration) | PostgreSQL setup for production |
|
|
95
113
|
| [OAuth](https://docs.mcphub.app/features/oauth) | OAuth 2.0 client and server setup |
|
|
96
114
|
| [Smart Routing](https://docs.mcphub.app/features/smart-routing) | AI-powered tool discovery |
|
|
115
|
+
| [CLI Guide](https://docs.mcphub.app/features/cli) | Manage and call the hub from a terminal |
|
|
97
116
|
| [Docker Setup](https://docs.mcphub.app/configuration/docker-setup) | Docker deployment guide |
|
|
98
117
|
|
|
99
118
|
## 🧑💻 Local Development
|
|
@@ -111,9 +130,10 @@ pnpm dev
|
|
|
111
130
|
|
|
112
131
|
## 🔍 Tech Stack
|
|
113
132
|
|
|
114
|
-
- **Backend**: Node.js, Express, TypeScript
|
|
133
|
+
- **Backend**: Node.js, Express, TypeScript (ESM)
|
|
115
134
|
- **Frontend**: React, Vite, Tailwind CSS
|
|
116
|
-
- **
|
|
135
|
+
- **Storage**: file-based `mcp_settings.json` by default; PostgreSQL via TypeORM with pgvector for Smart Routing
|
|
136
|
+
- **Auth**: JWT + bcrypt for local accounts; bearer keys; built-in OAuth 2.0 server (`@node-oauth/oauth2-server`); optional Better Auth for GitHub/Google login
|
|
117
137
|
- **Protocol**: Model Context Protocol SDK
|
|
118
138
|
|
|
119
139
|
## 👥 Contributing
|
package/README.zh.md
CHANGED
|
@@ -15,6 +15,7 @@ MCPHub 通过将多个 MCP(Model Context Protocol)服务器组织为灵活
|
|
|
15
15
|
|
|
16
16
|
- **集中式管理** - 在统一控制台中监控和管理所有 MCP 服务器
|
|
17
17
|
- **灵活路由** - 通过 HTTP/SSE 访问所有服务器、特定分组或单个服务器
|
|
18
|
+
- **细粒度分组可见性** - 在分组中可独立控制每个服务器的 Tool、Prompt 与 Resource 是否对外暴露
|
|
18
19
|
- **智能路由** - 基于向量语义搜索的 AI 工具发现 ([了解更多](https://docs.mcphub.app/zh/features/smart-routing))
|
|
19
20
|
- **热插拔配置** - 无需停机即可添加、移除或更新服务器
|
|
20
21
|
- **OAuth 2.0 支持** - 客户端和服务端模式,实现安全认证 ([了解更多](https://docs.mcphub.app/zh/features/oauth))
|
|
@@ -51,8 +52,8 @@ MCPHub 通过将多个 MCP(Model Context Protocol)服务器组织为灵活
|
|
|
51
52
|
# 挂载自定义配置运行(推荐)
|
|
52
53
|
docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
|
|
53
54
|
|
|
54
|
-
#
|
|
55
|
-
docker run -p 3000:3000 samanhappy/mcphub
|
|
55
|
+
# 或使用默认配置运行(仍建议挂载 ./data,避免容器删除后数据丢失)
|
|
56
|
+
docker run -p 3000:3000 -v ./data:/app/data samanhappy/mcphub
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
### 访问控制台
|
|
@@ -84,6 +85,24 @@ http://localhost:3000/mcp/$smart/{group} # 智能路由(特定分组)
|
|
|
84
85
|
|
|
85
86
|
📖 查看 [API 参考](https://docs.mcphub.app/zh/api-reference)了解详细的端点文档。
|
|
86
87
|
|
|
88
|
+
### 终端管理
|
|
89
|
+
|
|
90
|
+
`mcphub` 同一个二进制兼任 CLI,无需额外安装。
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
mcphub login --url http://localhost:3000 --username admin
|
|
94
|
+
mcphub servers list
|
|
95
|
+
mcphub servers add fetch --type stdio --command uvx --arg mcp-server-fetch
|
|
96
|
+
mcphub tools list # 看有哪些 tool 可调
|
|
97
|
+
mcphub tools get fetch_url # 看必填参数和样例命令
|
|
98
|
+
mcphub call fetch_url url=https://example.com --json
|
|
99
|
+
mcphub keys create --name ci --access-type all
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
CLI 同样对接公共市场接口(`mcphub discover`、`mcphub install ...`),可对任意开启了 discovery 的 hub 做检索与一键安装。
|
|
103
|
+
|
|
104
|
+
📖 查看 [CLI 指南](https://docs.mcphub.app/zh/features/cli)了解全部子命令、profile 管理与 CI 用法。
|
|
105
|
+
|
|
87
106
|
## 📚 文档
|
|
88
107
|
|
|
89
108
|
| 主题 | 描述 |
|
|
@@ -93,6 +112,7 @@ http://localhost:3000/mcp/$smart/{group} # 智能路由(特定分组)
|
|
|
93
112
|
| [数据库模式](https://docs.mcphub.app/zh/configuration/database-configuration) | PostgreSQL 生产环境配置 |
|
|
94
113
|
| [OAuth](https://docs.mcphub.app/zh/features/oauth) | OAuth 2.0 客户端和服务端配置 |
|
|
95
114
|
| [智能路由](https://docs.mcphub.app/zh/features/smart-routing) | AI 驱动的工具发现 |
|
|
115
|
+
| [CLI 指南](https://docs.mcphub.app/zh/features/cli) | 终端管理与工具调用 |
|
|
96
116
|
| [Docker 部署](https://docs.mcphub.app/zh/configuration/docker-setup) | Docker 部署指南 |
|
|
97
117
|
|
|
98
118
|
## 🧑💻 本地开发
|
|
@@ -110,9 +130,10 @@ pnpm dev
|
|
|
110
130
|
|
|
111
131
|
## 🔍 技术栈
|
|
112
132
|
|
|
113
|
-
- **后端**:Node.js、Express、TypeScript
|
|
133
|
+
- **后端**:Node.js、Express、TypeScript(ESM)
|
|
114
134
|
- **前端**:React、Vite、Tailwind CSS
|
|
115
|
-
-
|
|
135
|
+
- **存储**:默认基于文件的 `mcp_settings.json`;可选 PostgreSQL(TypeORM + pgvector,用于智能路由)
|
|
136
|
+
- **认证**:本地账号使用 JWT + bcrypt;支持 Bearer Key、内置 OAuth 2.0 服务端(`@node-oauth/oauth2-server`),以及可选的 Better Auth(GitHub/Google 一键登录)
|
|
116
137
|
- **协议**:Model Context Protocol SDK
|
|
117
138
|
|
|
118
139
|
## 👥 贡献指南
|
package/bin/cli.js
CHANGED
|
@@ -4,44 +4,51 @@ import path from 'path';
|
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
|
|
7
|
-
// Enable debug logging if needed
|
|
8
|
-
// process.env.DEBUG = 'true';
|
|
9
|
-
|
|
10
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
8
|
const __dirname = path.dirname(__filename);
|
|
12
9
|
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
// Subcommands routed to the CLI dispatcher in dist/cli/main.js. Anything else
|
|
11
|
+
// (including no args) falls through to the legacy server bootstrap so
|
|
12
|
+
// `npx @samanhappy/mcphub` keeps working exactly as before.
|
|
13
|
+
const CLI_COMMANDS = new Set([
|
|
14
|
+
'login',
|
|
15
|
+
'logout',
|
|
16
|
+
'config',
|
|
17
|
+
'servers',
|
|
18
|
+
'groups',
|
|
19
|
+
'keys',
|
|
20
|
+
'tools',
|
|
21
|
+
'call',
|
|
22
|
+
'export',
|
|
23
|
+
'discover',
|
|
24
|
+
'install',
|
|
25
|
+
'help',
|
|
26
|
+
'--help',
|
|
27
|
+
'-h',
|
|
28
|
+
'--version',
|
|
29
|
+
'-v',
|
|
30
|
+
]);
|
|
16
31
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// - dist/
|
|
20
|
-
// - bin/
|
|
21
|
-
// - frontend/dist/
|
|
32
|
+
const argv = process.argv.slice(2);
|
|
33
|
+
const isCliCommand = argv.length > 0 && CLI_COMMANDS.has(argv[0]);
|
|
22
34
|
|
|
23
|
-
// Get the package root - this is where package.json is located
|
|
24
35
|
function findPackageRoot() {
|
|
25
36
|
const isDebug = process.env.DEBUG === 'true';
|
|
26
|
-
|
|
27
|
-
// Possible locations for package.json
|
|
37
|
+
|
|
28
38
|
const possibleRoots = [
|
|
29
|
-
// Standard npm package location
|
|
30
39
|
path.resolve(__dirname, '..'),
|
|
31
|
-
|
|
32
|
-
path.resolve(__dirname, '..', '..', '..')
|
|
40
|
+
path.resolve(__dirname, '..', '..', '..'),
|
|
33
41
|
];
|
|
34
|
-
|
|
35
|
-
// Special handling for npx
|
|
42
|
+
|
|
36
43
|
if (process.argv[1] && process.argv[1].includes('_npx')) {
|
|
37
44
|
const npxDir = path.dirname(process.argv[1]);
|
|
38
45
|
possibleRoots.unshift(path.resolve(npxDir, '..'));
|
|
39
46
|
}
|
|
40
|
-
|
|
47
|
+
|
|
41
48
|
if (isDebug) {
|
|
42
49
|
console.log('DEBUG: Checking for package.json in:', possibleRoots);
|
|
43
50
|
}
|
|
44
|
-
|
|
51
|
+
|
|
45
52
|
for (const root of possibleRoots) {
|
|
46
53
|
const packageJsonPath = path.join(root, 'package.json');
|
|
47
54
|
if (fs.existsSync(packageJsonPath)) {
|
|
@@ -58,41 +65,48 @@ function findPackageRoot() {
|
|
|
58
65
|
}
|
|
59
66
|
}
|
|
60
67
|
}
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
|
|
69
|
+
if (!isCliCommand) {
|
|
70
|
+
console.log('⚠️ Could not find package.json, using default path');
|
|
71
|
+
}
|
|
63
72
|
return path.resolve(__dirname, '..');
|
|
64
73
|
}
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
console.
|
|
75
|
+
const projectRoot = findPackageRoot();
|
|
76
|
+
|
|
77
|
+
if (isCliCommand) {
|
|
78
|
+
// CLI subcommand path — keep stdout clean for --json / pipes.
|
|
79
|
+
const cliEntryPath = path.join(projectRoot, 'dist', 'cli', 'main.js');
|
|
80
|
+
if (!fs.existsSync(cliEntryPath)) {
|
|
81
|
+
console.error('❌ CLI build missing: ' + cliEntryPath);
|
|
82
|
+
console.error('Run "pnpm backend:build" (or "pnpm build") and retry.');
|
|
83
|
+
process.exit(1);
|
|
73
84
|
}
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
const cliEntryUrl = pathToFileURL(cliEntryPath).href;
|
|
86
|
+
const mod = await import(cliEntryUrl);
|
|
87
|
+
await mod.runCli(argv);
|
|
88
|
+
} else {
|
|
89
|
+
// Legacy: server bootstrap. Existing console.log banner preserved here so it
|
|
90
|
+
// never leaks into CLI subcommand output.
|
|
91
|
+
console.log('📋 MCPHub CLI');
|
|
92
|
+
console.log(`📁 CLI script location: ${__dirname}`);
|
|
93
|
+
console.log(`📦 Using package root: ${projectRoot}`);
|
|
94
|
+
|
|
95
|
+
const frontendDistPath = path.join(projectRoot, 'frontend', 'dist');
|
|
96
|
+
if (
|
|
97
|
+
fs.existsSync(frontendDistPath) &&
|
|
98
|
+
fs.existsSync(path.join(frontendDistPath, 'index.html'))
|
|
99
|
+
) {
|
|
76
100
|
console.log('✅ Frontend distribution found');
|
|
77
|
-
return true;
|
|
78
101
|
} else {
|
|
79
102
|
console.log('⚠️ Frontend distribution not found at', frontendDistPath);
|
|
80
|
-
return false;
|
|
81
103
|
}
|
|
82
|
-
}
|
|
83
104
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const entryPath = path.join(projectRoot, 'dist', 'index.js');
|
|
93
|
-
// Convert to file:// URL for cross-platform ESM compatibility (required on Windows)
|
|
94
|
-
const entryUrl = pathToFileURL(entryPath).href;
|
|
95
|
-
import(entryUrl).catch(err => {
|
|
96
|
-
console.error('Failed to start MCPHub:', err);
|
|
97
|
-
process.exit(1);
|
|
98
|
-
});
|
|
105
|
+
console.log('🚀 Starting MCPHub server...');
|
|
106
|
+
const entryPath = path.join(projectRoot, 'dist', 'index.js');
|
|
107
|
+
const entryUrl = pathToFileURL(entryPath).href;
|
|
108
|
+
import(entryUrl).catch((err) => {
|
|
109
|
+
console.error('Failed to start MCPHub:', err);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { CliUsageError } from './errors.js';
|
|
3
|
+
export function parseCallArguments(argv, options = {}) {
|
|
4
|
+
const args = {};
|
|
5
|
+
const extra = [];
|
|
6
|
+
const reader = options.fs ?? fs;
|
|
7
|
+
for (const token of argv) {
|
|
8
|
+
const eq = token.indexOf('=');
|
|
9
|
+
if (eq <= 0) {
|
|
10
|
+
extra.push(token);
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
const key = token.slice(0, eq);
|
|
14
|
+
const raw = token.slice(eq + 1);
|
|
15
|
+
if (options.noCoerce) {
|
|
16
|
+
args[key] = raw;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
args[key] = coerce(raw, reader);
|
|
20
|
+
}
|
|
21
|
+
return { args, extra };
|
|
22
|
+
}
|
|
23
|
+
function coerce(raw, reader) {
|
|
24
|
+
if (raw === 'null')
|
|
25
|
+
return null;
|
|
26
|
+
if (raw === 'true')
|
|
27
|
+
return true;
|
|
28
|
+
if (raw === 'false')
|
|
29
|
+
return false;
|
|
30
|
+
if (raw.startsWith('@')) {
|
|
31
|
+
const path = raw.slice(1);
|
|
32
|
+
if (!path)
|
|
33
|
+
throw new CliUsageError('@ prefix requires a file path');
|
|
34
|
+
let content;
|
|
35
|
+
try {
|
|
36
|
+
content = reader.readFileSync(path, 'utf8');
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
throw new CliUsageError(`Failed to read file ${path}: ${e.message}`);
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(content);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
throw new CliUsageError(`Failed to parse JSON from ${path}: ${e.message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (raw.length > 1 &&
|
|
49
|
+
((raw.startsWith('{') && raw.endsWith('}')) || (raw.startsWith('[') && raw.endsWith(']')))) {
|
|
50
|
+
try {
|
|
51
|
+
return JSON.parse(raw);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// fall through and keep as string — a value that happens to start with
|
|
55
|
+
// a brace but isn't valid JSON is more likely meant literally.
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (raw.startsWith('"') && raw.endsWith('"') && raw.length >= 2) {
|
|
59
|
+
// Explicit JSON string form — preserve the inner text without coercion.
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(raw);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return raw.slice(1, -1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (isNumeric(raw)) {
|
|
68
|
+
return Number(raw);
|
|
69
|
+
}
|
|
70
|
+
return raw;
|
|
71
|
+
}
|
|
72
|
+
function isNumeric(s) {
|
|
73
|
+
if (s === '' || s === '-' || s === '.')
|
|
74
|
+
return false;
|
|
75
|
+
// Preserve identifier-like strings such as zip codes and phone numbers:
|
|
76
|
+
// a leading zero on a multi-digit integer keeps the value as a string.
|
|
77
|
+
if (/^-?0\d/.test(s))
|
|
78
|
+
return false;
|
|
79
|
+
return /^-?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?$/.test(s);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=call-arguments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-arguments.js","sourceRoot":"","sources":["../../src/cli/call-arguments.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { CliUsageError } from '../errors.js';
|
|
2
|
+
import { buildClient, resolveTarget } from '../context.js';
|
|
3
|
+
import { extractFlags } from '../parse-args.js';
|
|
4
|
+
import { parseCallArguments } from '../call-arguments.js';
|
|
5
|
+
import { printJson, printLine } from '../output.js';
|
|
6
|
+
export async function run(args, globals, deps = {}) {
|
|
7
|
+
const { positional, flags } = extractFlags(args, {
|
|
8
|
+
valued: ['--group', '--server', '--params-json'],
|
|
9
|
+
boolean: ['--smart', '--no-coerce'],
|
|
10
|
+
});
|
|
11
|
+
const tool = positional.shift();
|
|
12
|
+
if (!tool) {
|
|
13
|
+
throw new CliUsageError('Usage: mcphub call <tool> [key=value ...] [--group <g>|--server <s>|--smart] [--params-json <json>]');
|
|
14
|
+
}
|
|
15
|
+
let params;
|
|
16
|
+
if (flags['--params-json']) {
|
|
17
|
+
try {
|
|
18
|
+
params = JSON.parse(flags['--params-json']);
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
throw new CliUsageError(`--params-json is not valid JSON: ${e.message}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const parsed = parseCallArguments(positional, { noCoerce: flags['--no-coerce'] === true });
|
|
26
|
+
params = parsed.args;
|
|
27
|
+
}
|
|
28
|
+
// Routing precedence: --smart > --server > --group > default ($smart).
|
|
29
|
+
// /mcp/:slug? accepts a group name, a server name, or $smart, so --server
|
|
30
|
+
// and --group are different names for the same wire surface. --server is
|
|
31
|
+
// the natural pair for `mcphub tools list`/`tools get` output.
|
|
32
|
+
const group = flags['--smart'] === true
|
|
33
|
+
? '$smart'
|
|
34
|
+
: flags['--server'] ??
|
|
35
|
+
flags['--group'] ??
|
|
36
|
+
'$smart';
|
|
37
|
+
const client = deps.client ?? buildClient(resolveTarget(globals));
|
|
38
|
+
const body = {
|
|
39
|
+
jsonrpc: '2.0',
|
|
40
|
+
id: 1,
|
|
41
|
+
method: 'tools/call',
|
|
42
|
+
params: { name: tool, arguments: params },
|
|
43
|
+
};
|
|
44
|
+
const response = await client.mcpCall(group, body);
|
|
45
|
+
if (globals.json) {
|
|
46
|
+
printJson(response);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (response.error) {
|
|
50
|
+
throw new CliUsageError(`MCP error ${response.error.code}: ${response.error.message}`);
|
|
51
|
+
}
|
|
52
|
+
printToolResult(response.result);
|
|
53
|
+
}
|
|
54
|
+
function printToolResult(result) {
|
|
55
|
+
if (!result) {
|
|
56
|
+
printLine('(no result)');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (result.isError) {
|
|
60
|
+
printLine('(tool reported an error)');
|
|
61
|
+
}
|
|
62
|
+
if (!Array.isArray(result.content)) {
|
|
63
|
+
printLine(JSON.stringify(result, null, 2));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
for (const piece of result.content) {
|
|
67
|
+
if (piece.type === 'text' && typeof piece.text === 'string') {
|
|
68
|
+
printLine(piece.text);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
printLine(JSON.stringify(piece, null, 2));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../../src/cli/commands/call.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { CliUsageError } from '../errors.js';
|
|
2
|
+
import { extractFlags } from '../parse-args.js';
|
|
3
|
+
import { deleteProfile, loadCredentials, saveCredentials, setCurrentProfile, setProfile, } from '../profile.js';
|
|
4
|
+
import { bold, dim, green, maskToken, printJson, printLine, printTable } from '../output.js';
|
|
5
|
+
export async function run(args, globals, deps = {}) {
|
|
6
|
+
const sub = args.shift();
|
|
7
|
+
switch (sub) {
|
|
8
|
+
case undefined:
|
|
9
|
+
case 'show':
|
|
10
|
+
return showActive(globals, deps);
|
|
11
|
+
case 'list':
|
|
12
|
+
return list(globals, deps);
|
|
13
|
+
case 'use':
|
|
14
|
+
return use(args, deps);
|
|
15
|
+
case 'set-url':
|
|
16
|
+
return setUrl(args, globals, deps);
|
|
17
|
+
case 'set-token':
|
|
18
|
+
return setToken(args, globals, deps);
|
|
19
|
+
case 'remove':
|
|
20
|
+
return remove(args, deps);
|
|
21
|
+
default:
|
|
22
|
+
throw new CliUsageError(`Unknown config subcommand: ${sub}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function showActive(globals, deps) {
|
|
26
|
+
const creds = (deps.loadCreds ?? loadCredentials)();
|
|
27
|
+
const name = globals.profile || creds.current;
|
|
28
|
+
if (!name || !creds.profiles[name]) {
|
|
29
|
+
printLine(dim('No active profile. Run `mcphub login` to create one.'));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const profile = creds.profiles[name];
|
|
33
|
+
if (globals.json) {
|
|
34
|
+
printJson({
|
|
35
|
+
name,
|
|
36
|
+
url: profile.url,
|
|
37
|
+
tokenKind: profile.tokenKind ?? 'jwt',
|
|
38
|
+
tokenMasked: maskToken(profile.token),
|
|
39
|
+
username: profile.username ?? null,
|
|
40
|
+
savedAt: profile.savedAt ?? null,
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
printLine(`${bold('profile')} ${name}`);
|
|
45
|
+
printLine(`${bold('url')} ${profile.url}`);
|
|
46
|
+
printLine(`${bold('tokenKind')} ${profile.tokenKind ?? 'jwt'}`);
|
|
47
|
+
printLine(`${bold('token')} ${maskToken(profile.token)}`);
|
|
48
|
+
if (profile.username)
|
|
49
|
+
printLine(`${bold('username')} ${profile.username}`);
|
|
50
|
+
if (profile.savedAt)
|
|
51
|
+
printLine(`${bold('savedAt')} ${profile.savedAt}`);
|
|
52
|
+
}
|
|
53
|
+
function list(globals, deps) {
|
|
54
|
+
const creds = (deps.loadCreds ?? loadCredentials)();
|
|
55
|
+
const rows = Object.entries(creds.profiles).map(([name, p]) => ({
|
|
56
|
+
name,
|
|
57
|
+
current: name === creds.current ? '*' : '',
|
|
58
|
+
url: p.url,
|
|
59
|
+
tokenKind: p.tokenKind ?? 'jwt',
|
|
60
|
+
token: maskToken(p.token),
|
|
61
|
+
username: p.username ?? '',
|
|
62
|
+
}));
|
|
63
|
+
if (globals.json) {
|
|
64
|
+
printJson({ current: creds.current, profiles: rows });
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
printTable(rows, ['name', 'current', 'url', 'tokenKind', 'token', 'username']);
|
|
68
|
+
}
|
|
69
|
+
function use(args, deps) {
|
|
70
|
+
const name = args[0];
|
|
71
|
+
if (!name)
|
|
72
|
+
throw new CliUsageError('Usage: mcphub config use <name>');
|
|
73
|
+
const load = deps.loadCreds ?? loadCredentials;
|
|
74
|
+
const save = deps.saveCreds ?? saveCredentials;
|
|
75
|
+
const next = setCurrentProfile(load(), name);
|
|
76
|
+
save(next);
|
|
77
|
+
printLine(green(`Active profile set to "${name}".`));
|
|
78
|
+
}
|
|
79
|
+
function setUrl(args, globals, deps) {
|
|
80
|
+
const url = args[0];
|
|
81
|
+
if (!url)
|
|
82
|
+
throw new CliUsageError('Usage: mcphub config set-url <url>');
|
|
83
|
+
const load = deps.loadCreds ?? loadCredentials;
|
|
84
|
+
const save = deps.saveCreds ?? saveCredentials;
|
|
85
|
+
const creds = load();
|
|
86
|
+
const target = globals.profile || creds.current || 'default';
|
|
87
|
+
const existing = creds.profiles[target];
|
|
88
|
+
const next = setProfile(creds, target, {
|
|
89
|
+
url,
|
|
90
|
+
tokenKind: existing?.tokenKind,
|
|
91
|
+
token: existing?.token,
|
|
92
|
+
username: existing?.username,
|
|
93
|
+
});
|
|
94
|
+
save(next);
|
|
95
|
+
printLine(green(`Set url for profile "${target}" to ${url}.`));
|
|
96
|
+
}
|
|
97
|
+
function setToken(args, globals, deps) {
|
|
98
|
+
const { positional, flags } = extractFlags(args, { boolean: ['--bearer'] });
|
|
99
|
+
const token = positional[0];
|
|
100
|
+
if (!token)
|
|
101
|
+
throw new CliUsageError('Usage: mcphub config set-token <token> [--bearer]');
|
|
102
|
+
const load = deps.loadCreds ?? loadCredentials;
|
|
103
|
+
const save = deps.saveCreds ?? saveCredentials;
|
|
104
|
+
const creds = load();
|
|
105
|
+
const target = globals.profile || creds.current;
|
|
106
|
+
if (!target || !creds.profiles[target]) {
|
|
107
|
+
throw new CliUsageError('No profile to update. Run `mcphub login` first or pass --profile.');
|
|
108
|
+
}
|
|
109
|
+
const existing = creds.profiles[target];
|
|
110
|
+
const next = setProfile(creds, target, {
|
|
111
|
+
url: existing.url,
|
|
112
|
+
tokenKind: flags['--bearer'] ? 'bearer' : 'jwt',
|
|
113
|
+
token,
|
|
114
|
+
username: existing.username,
|
|
115
|
+
});
|
|
116
|
+
save(next);
|
|
117
|
+
printLine(green(`Set token for profile "${target}" (${flags['--bearer'] ? 'bearer' : 'jwt'}).`));
|
|
118
|
+
}
|
|
119
|
+
function remove(args, deps) {
|
|
120
|
+
const name = args[0];
|
|
121
|
+
if (!name)
|
|
122
|
+
throw new CliUsageError('Usage: mcphub config remove <name>');
|
|
123
|
+
const load = deps.loadCreds ?? loadCredentials;
|
|
124
|
+
const save = deps.saveCreds ?? saveCredentials;
|
|
125
|
+
const creds = load();
|
|
126
|
+
if (!creds.profiles[name]) {
|
|
127
|
+
throw new CliUsageError(`Profile not found: ${name}`);
|
|
128
|
+
}
|
|
129
|
+
save(deleteProfile(creds, name));
|
|
130
|
+
printLine(green(`Removed profile "${name}".`));
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/commands/config.ts"],"names":[],"mappings":"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"}
|