Compare commits

..

260 Commits

Author SHA1 Message Date
samanhappy
29cb6d3f84 Merge branch 'main' into copilot/upgrade-glob-to-10-5-0 2025-12-05 17:41:25 +08:00
Copilot
71667dab2c Fix validator security vulnerability CVE in isLength() (#484)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-12-05 17:40:29 +08:00
copilot-swe-agent[bot]
723ddb4fb0 Upgrade glob to version 10.5.0 via pnpm override
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-12-05 09:38:22 +00:00
Copilot
1921a0363b [WIP] Update auth0/node-jws to version 3.2.3 or 4.0.1 (#482)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-12-05 17:38:03 +08:00
copilot-swe-agent[bot]
d276823726 Initial plan 2025-12-05 09:32:36 +00:00
Copilot
f9fe2e444b Add build-essential to Dockerfile for Python native extension compilation (#478)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-12-04 22:48:07 +08:00
samanhappy
8d420a927b fix: streamline tool filtering logic and add group-based filtering (#476)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-04 15:10:49 +08:00
dependabot[bot]
cb77593fd7 chore(deps-dev): bump next from 15.5.2 to 15.5.7 (#475)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-04 08:41:39 +08:00
dependabot[bot]
dbcebecf40 chore(deps): bump @modelcontextprotocol/sdk from 1.20.2 to 1.24.0 (#473)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 19:10:51 +08:00
cheestard
54e877cbd8 feat: add reload button. (#471) 2025-12-03 18:55:48 +08:00
samanhappy
61b748151f chore(deps): bump react-dom to 19.2.0 (#474) 2025-12-03 11:37:50 +08:00
dependabot[bot]
4f05815210 chore(deps-dev): bump @swc/core from 1.13.5 to 1.15.3 (#468)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 11:27:33 +08:00
dependabot[bot]
691d91f207 chore(deps-dev): bump @tailwindcss/vite from 4.1.12 to 4.1.17 (#469)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 11:27:14 +08:00
dependabot[bot]
3d58042ce5 chore(deps): bump bcryptjs from 3.0.2 to 3.0.3 (#470)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 11:26:35 +08:00
dependabot[bot]
81486b09df chore(deps): bump express from 4.21.2 to 4.22.0 (#472)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 11:26:08 +08:00
dependabot[bot]
a41707c228 chore(deps-dev): bump react and @types/react (#467)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 11:18:26 +08:00
dependabot[bot]
7391e57f35 chore(deps-dev): bump @tailwindcss/postcss from 4.1.14 to 4.1.17 (#466)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-03 11:18:01 +08:00
samanhappy
9d8f5ba370 Enhance MCP settings export with error handling and null value removal (#465) 2025-12-01 16:28:45 +08:00
samanhappy
764959eaca Implement OAuth client and token management with settings updates (#464) 2025-12-01 16:02:55 +08:00
samanhappy
b5dff990e5 refactor: Remove outdated OpenAPI test scripts and add comprehensive integration tests (#459) 2025-11-30 17:33:15 +08:00
samanhappy
19f11a0927 Remove outdated documentation files (#458) 2025-11-30 17:29:37 +08:00
samanhappy
884870c9de refactor: Simplify database configuration instructions and update API endpoint references (#457) 2025-11-30 17:20:01 +08:00
samanhappy
7b8d9a7e5a Refactor documentation for clarity and dual data source support (#456) 2025-11-30 16:43:50 +08:00
samanhappy
8770b9ccfe feat: Enhance Keep-Alive configuration handling (#455) 2025-11-30 09:59:48 +08:00
Copilot
063b081297 Add PostgreSQL-backed data storage support (#444)
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-11-29 17:45:25 +08:00
samanhappy
73ae33e777 refactor: Remove deprecated systemConfig section from mcp_settings.json (#452) 2025-11-27 21:34:07 +08:00
Copilot
dac0d376e8 Fix inverted validation for enableSessionRebuild system config (#451)
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-11-27 21:01:13 +08:00
samanhappy
803e35b14c refactor: Simplify DataService implementation and remove unused DataServicex (#448) 2025-11-23 22:57:44 +08:00
samanhappy
a736398cd5 feat: Update permissions and settings structure for improved configuration management (#447) 2025-11-23 20:43:24 +08:00
samanhappy
6de3221974 feat: Enhance user forms and user management UI (#437) 2025-11-23 13:50:55 +08:00
samanhappy
ac0b60ed4b feat: Implement keepalive functionality for SSE and StreamableHTTP connections (#442) 2025-11-22 12:07:21 +08:00
samanhappy
a57218d076 fix: Remove test routing and oauthClients configurations from settings (#441) 2025-11-22 11:27:00 +08:00
samanhappy
8c985b7de1 fix: Include mcpServers, oauthClients, and oauthTokens in merged settings for non-admin users (#440) 2025-11-21 17:16:48 +08:00
samanhappy
01bb011736 fix: Use base URL from settings for dynamic client registration and metadata endpoints (#438) 2025-11-21 16:20:54 +08:00
Copilot
449e6ea4fd Add OAuth 2.0 authorization server to enable ChatGPT Web integration (#413)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-11-21 13:25:02 +08:00
cheestard
1869f283ba fix: Bad Request: No valid session ID provided (#405) (#427) 2025-11-19 18:17:37 +08:00
Copilot
07adeab036 feat: Add copy button for tool names in server tool list (#435)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-11-19 11:41:11 +08:00
dependabot[bot]
5d7d8fdd1a chore(deps): bump js-yaml from 3.14.1 to 3.14.2 (#436)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 11:38:24 +08:00
Copilot
fb847797c0 Add missing API documentation for tool execution and management endpoints (#430)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-11-12 22:18:56 +08:00
Alptekin Gülcan
8df2b4704a Fix: Handle ToolName in CallToolRequest to Resolve Server Discovery Issues (#429)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 09:13:50 +08:00
samanhappy
602b5cb80e fix: update GitHub repository links to point to the new repository (#423) 2025-11-03 17:04:49 +08:00
samanhappy
e63f045819 refactor: remove outdated references to MCP protocol and cloud deployment in documentation (#422) 2025-11-03 17:02:10 +08:00
Chengwei Guo
a4e4791b60 fix the deployment on kubernetes (#417) 2025-11-03 14:16:12 +08:00
samanhappy
01370ea959 Revert "Feat: Enhance package cache for stdio servers (#400)" (#418) 2025-11-03 13:35:24 +08:00
samanhappy
f5d66c1bb7 fix versions for react and react-dom (#414) 2025-11-02 23:02:25 +08:00
dependabot[bot]
9e59dd9fb0 chore(deps-dev): bump react and @types/react (#407)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 22:48:13 +08:00
dependabot[bot]
250487f042 chore(deps-dev): bump lucide-react from 0.486.0 to 0.552.0 (#408)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 22:45:01 +08:00
dependabot[bot]
da91708420 chore(deps): bump i18next from 25.5.0 to 25.6.0 (#409)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 22:44:42 +08:00
dependabot[bot]
576bba1f9e chore(deps): bump openai from 4.104.0 to 6.7.0 (#410)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 22:44:21 +08:00
dependabot[bot]
f4b83929a6 chore(deps): bump axios from 1.12.2 to 1.13.1 (#406)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 22:43:57 +08:00
Alptekin Gülcan
3825f389cd Feat: Add Turkish localization (tr) (#411) 2025-11-02 22:43:18 +08:00
samanhappy
44e0309fd4 Feat: Enhance package cache for stdio servers (#400) 2025-10-31 21:56:43 +08:00
Copilot
7e570a900a Fix: Convert form parameters to schema-defined types before MCP tool calls (#397)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-29 18:41:23 +08:00
Copilot
6268a02c0e Fix URL routing for MCP servers with slashes in names (#396)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-29 18:37:24 +08:00
samanhappy
695d663939 Fix display for null server author (#398) 2025-10-29 14:44:09 +08:00
samanhappy
d595e5d874 Fix support for nested smart group segments in MCP routing (#394) 2025-10-28 17:51:58 +08:00
Copilot
ff797b4ab9 Add group-scoped smart routing via $smart/{group} pattern (#388)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-26 20:51:55 +08:00
samanhappy
9105507722 Refactor: Clean up code formatting and improve readability across multiple files (#387) 2025-10-26 19:27:30 +08:00
Copilot
f79028ed64 Expand environment variables throughout mcp_settings.json configuration (#384)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-26 19:25:53 +08:00
Copilot
5ca5e2ad47 Add password security: default credential warning and strength validation (#386)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-26 19:22:51 +08:00
Copilot
2f7726b008 Add JSON import for MCP servers (#385)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-10-26 19:13:06 +08:00
Copilot
26b26a5fb1 Add OAuth support for upstream MCP servers (#381)
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-10-26 16:09:34 +08:00
Copilot
7dbd6c386e Fix: Environment variable expansion in headers for HTTP-based MCP transports (#380)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-23 19:18:50 +08:00
Copilot
c1fee91142 Fix Dependabot alert #18: Remove outdated package-lock.json causing axios vulnerability false positive (#379)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-22 15:16:24 +08:00
samanhappy
1130f6833e fix: use reconnect mechanism for sse tool calling error (#378) 2025-10-22 12:05:21 +08:00
dependabot[bot]
c3f1de8f5b chore(deps-dev): bump vite from 6.3.6 to 6.4.1 (#376)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-22 12:04:16 +08:00
samanhappy
86367a4875 feat: integrate offcial mcp server registry (#374) 2025-10-19 21:15:25 +08:00
samanhappy
bd4c546bba fix settings data export & parsing error (#373) 2025-10-16 13:08:28 +08:00
Copilot
3e9e5cc3c9 feat: Auto-start Docker daemon when installed in container (#370)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-10-13 22:38:13 +08:00
samanhappy
16a92096b3 feat: Enhance package root detection and version retrieval using ESM-compatible methods (#371) 2025-10-13 22:36:29 +08:00
Copilot
4d736c543d feat: Add MCP settings export and copy functionality (#367)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-10-13 19:39:01 +08:00
samanhappy
f53c4a0e3b fix: assign server name from key in getMarketServers function (#369) 2025-10-13 18:19:21 +08:00
Copilot
d4bdb099d0 Add Docker CLI support to Docker image with INSTALL_EXT build argument (#366)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-10-12 16:51:02 +08:00
samanhappy
435227cbd4 fix: improve error handling and directory creation for settings path (#364) 2025-10-12 15:30:40 +08:00
Copilot
6a59becd8d Fix Windows startup error: Convert paths to file:// URLs for ESM dynamic imports (#363)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-10-12 11:31:44 +08:00
samanhappy
91698a50e3 fix: use specified environment setting path when available (#359) 2025-10-11 23:44:23 +08:00
samanhappy
a5d5045832 fix: add groups handling in mergeSettings method (#362) 2025-10-11 23:29:59 +08:00
samanhappy
198ea85225 feat: implement user management features with add, edit, and delete functionality 2025-10-02 15:11:08 +08:00
dependabot[bot]
6b39916909 chore(deps): bump typeorm from 0.3.26 to 0.3.27 (#356)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-02 14:47:55 +08:00
dependabot[bot]
9e8db370ff chore(deps-dev): bump @tailwindcss/postcss from 4.1.12 to 4.1.13 (#358)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-02 14:47:09 +08:00
dependabot[bot]
5d8bc44a73 chore(deps-dev): bump @types/node from 22.17.2 to 24.6.1 (#357)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-02 14:44:13 +08:00
dependabot[bot]
021901dbda chore(deps-dev): bump jest and @types/jest (#354)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-02 14:40:42 +08:00
WuWen
f6934a32dc feat: add configurable name separator for tools and prompts (#353) 2025-10-02 14:40:01 +08:00
samanhappy
7685b9bca8 feat: enhance visual hierarchy on LoginPage by increasing slogan size and spacing (#347) 2025-09-20 17:23:54 +08:00
samanhappy
c2dd91606f chore(deps): update @modelcontextprotocol/sdk to 1.18.1 and axios to 1.12.2 (#346) 2025-09-20 17:16:04 +08:00
samanhappy
66b6053f7f feat: add passthrough headers support for OpenAPI client and MCP protocol (#345) 2025-09-20 17:12:20 +08:00
dependabot[bot]
ba50a78879 chore(deps): bump axios from 1.11.0 to 1.12.0 (#342)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-14 16:14:13 +08:00
comeback01
a856404963 docs: add French translation for README (#339)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-09-12 17:56:00 +08:00
comeback01
9a65532a50 feat: add french localization (#337)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-09-12 14:27:05 +08:00
dependabot[bot]
c5aa97de50 chore(deps-dev): bump vite from 6.3.5 to 6.3.6 (#334)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-10 12:42:00 +08:00
dependabot[bot]
271c9fe2c3 chore(deps-dev): bump i18next from 24.2.3 to 25.4.2 (#329)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-05 08:51:54 +08:00
dependabot[bot]
d59961c4d4 chore(deps-dev): bump next from 15.5.0 to 15.5.2 (#328)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-05 08:51:23 +08:00
dependabot[bot]
d0ec80303a chore(deps-dev): bump jest-mock-extended from 4.0.0-beta1 to 4.0.0 (#330)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 22:49:30 +08:00
dependabot[bot]
69e92b5aa8 chore(deps): bump @apidevtools/swagger-parser from 11.0.1 to 12.0.0 (#331)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 22:48:29 +08:00
dependabot[bot]
5acae64b29 chore(deps-dev): bump @typescript-eslint/eslint-plugin from 6.21.0 to 7.0.0 (#327)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 22:47:30 +08:00
samanhappy
a5fc4a429d fix: ensure settings cache is cleared after saving and clearing cache (#326) 2025-09-01 10:15:50 +08:00
Junsen Huang
ce15330016 fix(server-context): fix server edite error (#325) 2025-08-30 17:37:30 +08:00
samanhappy
621bc36560 feat: Add OpenAPI-compatible tool execution endpoints for named APIs (#316) 2025-08-30 16:00:15 +08:00
Junsen Huang
c398223824 feat: refactor server data management to use global context (#319) 2025-08-28 22:15:16 +08:00
Copilot
5dd3e7978e Generate comprehensive GitHub Copilot instructions for MCPHub development (#314)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-08-27 21:58:06 +08:00
samanhappy
f577351f04 fix: set current working directory for StdioClientTransport to homedir (#311) 2025-08-27 19:23:00 +08:00
Copilot
62de87b1a4 Add granular OpenAPI endpoints for server-level and group-level tool access (#309)
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-08-27 17:25:32 +08:00
samanhappy
bbd6c891c9 feat(dao): Implement comprehensive DAO layer (#308)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-08-27 15:21:30 +08:00
Copilot
f9019545c3 Fix integer parameter conversion in OpenAPI endpoints (#306)
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-08-27 11:04:25 +08:00
samanhappy
d778536388 fix: update tool call API endpoint structure and enhance error handling (#300) 2025-08-26 18:49:34 +08:00
Copilot
976e90679d Add OpenAPI specification generation for OpenWebUI integration (#295)
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-08-26 14:54:19 +08:00
samanhappy
f6ee9beed3 refactor: remove MCPRouter referer and title input sections from SettingsPage (#294) 2025-08-25 15:51:02 +08:00
samanhappy
69a800fa7a fix: update MCPRouter referer URL to new domain (#293) 2025-08-25 13:25:37 +08:00
Copilot
83cbd16821 Fix Dependabot security alert #11 - resolve sha.js and brace-expansion vulnerabilities (#292)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-08-25 12:26:04 +08:00
samanhappy
9300814994 Add .git to .dockerignore to prevent Git files from being included in Docker builds (#290) 2025-08-24 15:37:38 +08:00
Rilomilo
9952927a13 remove redundant code (#288) 2025-08-24 11:40:33 +08:00
samanhappy
4547ae526a fix: adjust spacing and heading size in LoginPage for improved layout (#286)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-08-20 22:14:41 +08:00
Copilot
80b83bb029 Fix missing i18n translation for api.errors.invalid_credentials (#285)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
2025-08-20 21:06:03 +08:00
Copilot
fa2de88fea Center login form and simplify layout with main slogan only (#283)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
Co-authored-by: samanhappy <samanhappy@gmail.com>
2025-08-20 14:37:10 +08:00
samanhappy
6020611f57 Add prompt management functionality to MCP server (#281) 2025-08-20 14:23:55 +08:00
samanhappy
81c3091a5c fix: filter out empty values in tool arguments for improved functionality (#280)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-20 14:21:51 +08:00
samanhappy
6a8f246dff fix: adjust layout for LoginPage to improve responsiveness and styling (#278) 2025-08-14 16:28:47 +08:00
samanhappy
2bef1fb0bd fix: update @modelcontextprotocol/sdk dependency to version 1.17.2 (#277) 2025-08-14 15:17:19 +08:00
samanhappy
bdb5b37cf5 Add API documentation (#275) 2025-08-14 14:12:15 +08:00
samanhappy
cbb3b15ba2 fix: standardize naming to MCPHub across documentation and UI (#271)
Co-authored-by: samanhappy@qq.com <my6051199>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-13 21:54:41 +08:00
samanhappy
77b423fbcc Refactor JWT secret management and enhance documentation (#270) 2025-08-11 19:09:33 +08:00
samanhappy
604fe4f71d fix: remove registration endpoint from authentication bypass in middleware (#267) 2025-08-11 14:18:28 +08:00
samanhappy
907bca8aac Refactor cloud and market pages for improved functionality and UI consistency (#265) 2025-08-10 17:39:34 +08:00
samanhappy
8c58200dcc feat: add health check endpoint to monitor MCP server status (#264) 2025-08-10 16:46:22 +08:00
samanhappy
0b4dc453a5 fix: reinitialize mcp server connection on update (#263) 2025-08-10 16:20:36 +08:00
samanhappy
35012f99fc refine docs 2025-08-10 12:52:54 +08:00
samanhappy
22ad4f83f6 fix: handle undefined and null values for number inputs in DynamicForm (#261)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-10 12:52:20 +08:00
samanhappy
26720d9e49 feat: introduce cloud server market (#260) 2025-08-09 21:14:26 +08:00
samanhappy
a9aa4a9a08 feat: Update registerService to handle environment-specific service overrides (#257) 2025-08-05 14:48:48 +08:00
samanhappy
48bcf9f5f0 feat: Add cleanInputSchema function to remove $schema field from inputSchema (#255) 2025-08-05 13:45:52 +08:00
samanhappy
f63f06d879 feat: Enhance authentication flow by integrating permissions retrieval and updating related services (#256) 2025-08-05 13:45:31 +08:00
samanhappy
63b356b8d7 Add Chinese localization support and i18n middleware (#253) 2025-08-03 11:53:04 +08:00
samanhappy
a6cea2ad3f feat: Enhance group management with server tool configuration (#250) 2025-07-29 17:31:05 +08:00
samanhappy
5bb2715094 refactor: simplify LanguageSwitch component by removing unnecessary language count checks and enhancing dropdown behavior (#249) 2025-07-27 20:44:50 +08:00
samanhappy
9b40f7e101 feat: enhance LanguageSwitch component with language toggle functionality and improve dropdown behavior; update UserProfileMenu styles (#248) 2025-07-26 22:58:01 +08:00
samanhappy
df872823c1 Implement language and theme switchers in Header (#247) 2025-07-26 21:46:14 +08:00
samanhappy
9304653c34 feat: enhance GroupCard with copy options for ID, URL, and JSON; update translations (#246)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-25 14:30:52 +08:00
dependabot[bot]
b5685b7010 chore(deps): bump axios from 1.10.0 to 1.11.0 (#245)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-24 10:39:17 +08:00
samanhappy
89c37b2f02 Enhance operation name generation in OpenAPIClient (#244) 2025-07-23 19:02:43 +08:00
Oven
c316cb896e fix: create when dxt upload path does not exist (#243) 2025-07-23 13:47:11 +08:00
samanhappy
bc3c8facfa feat: add replaceEnvVarsInArray function and integrate it into server transport configuration (#241)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-07-22 23:24:04 +08:00
dependabot[bot]
69afb865c0 chore(deps): bump brace-expansion from 1.1.11 to 1.1.12 (#231)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-22 23:07:20 +08:00
dependabot[bot]
ba30d88840 chore(deps): bump multer from 2.0.1 to 2.0.2 (#229)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-22 23:06:24 +08:00
samanhappy
6d0d622bd8 feat: add permissions for contents and packages in build workflow (#238) 2025-07-22 10:05:16 +08:00
samanhappy
ab50c7e9eb feat: add conditional check for repository in build and npm publish workflows (#236)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-07-22 08:56:50 +08:00
samanhappy
e507bea2e3 Refactor service registration and revert lazy loading implementation (#234) 2025-07-20 22:30:09 +08:00
samanhappy
0f00ad7200 feat: implement lazy loading for data service and enhance service registration (#233) 2025-07-20 21:37:43 +08:00
samanhappy
b0b0c93337 feat: enable immediate loading of service overrides during registration (#232) 2025-07-20 20:35:00 +08:00
samanhappy
20fd355b87 feat: enhance JSON serialization safety & add dxt upload limit (#230) 2025-07-20 19:18:10 +08:00
dependabot[bot]
4388084704 chore(deps): bump typeorm from 0.3.24 to 0.3.25 (#210)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-07 09:54:52 +08:00
dependabot[bot]
fe2535461d chore(deps-dev): bump @types/react-dom from 19.1.5 to 19.1.6 (#211)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-07 09:39:52 +08:00
dependabot[bot]
985598e529 chore(deps): bump pg from 8.16.0 to 8.16.3 (#212)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-05 15:24:37 +08:00
dependabot[bot]
b2b6d0588b chore(deps-dev): bump tailwindcss from 4.1.8 to 4.1.11 (#213)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-03 14:11:24 +08:00
dependabot[bot]
64628ee3ed chore(deps-dev): bump tsx from 4.19.4 to 4.20.3 (#214)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-02 18:04:25 +08:00
samanhappy
66d4142039 feat: add variable detection and confirmation dialogs in server forms (#205) 2025-06-29 22:23:42 +08:00
samanhappy
cf72295f99 Refactor UI components across multiple pages for improved styling and consistency (#204) 2025-06-29 22:01:00 +08:00
samanhappy
89f85c73ff fix: resolve race conditions in initializeClientsFromSettings (#201) 2025-06-28 22:11:14 +08:00
samanhappy
adabf1d92b feat:support DXT file server installation (#200) 2025-06-27 14:45:24 +08:00
samanhappy
c3a6dfadb4 feat: Add dynamic header input fields for server configuration in ServerForm (#193) 2025-06-20 14:52:22 +08:00
samanhappy
d119be0f82 feat: Implement bearer token validation in auth middleware (#186) 2025-06-19 12:11:35 +08:00
samanhappy
1e308ec4c5 feat: add Jest testing framework and CI/CD configuration (#187)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-06-18 14:02:52 +08:00
samanhappy
1bd4fd6d9c feat: Add OpenAPI support with comprehensive configuration options and client integration (#184)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-16 17:50:51 +08:00
Imgodmaoyouknow
4b3bb26301 fix: 修复从市场安装服务器时,选择SSE和Streamable HTTP不生效的问题 (#180) 2025-06-13 22:50:36 +08:00
samanhappy
40af398f68 chore: update @modelcontextprotocol/sdk to version 1.12.1 (#176) 2025-06-10 16:50:28 +08:00
samanhappy
4726f00a22 feat: add request options configuration to server form (#171) 2025-06-10 13:51:01 +08:00
samanhappy
77f64b7b98 feat: enhance DynamicForm to support array and object (#173)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-06-10 13:50:14 +08:00
samanhappy
d9cbc5381a feat: implement keep-alive functionality for SSE connections (#166)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-06-07 20:41:51 +08:00
samanhappy
56c6447469 feat: implement settings cache with load, save, clear, and status functions (#167) 2025-06-07 20:36:52 +08:00
samanhappy
f8149c4b0b fix: update SSE transport path to use basePath from config (#165)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-06-07 20:35:20 +08:00
purefkh
e259f30539 fix: save user config when install mcp server from market (#168) 2025-06-07 20:34:51 +08:00
samanhappy
3a421bc476 fix: update tool name formatting from '/' to '-' in ToolCard and mcpService (#164)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-05 15:34:49 +08:00
samanhappy
503b60edb7 feat: add tool management features including toggle and description updates (#163)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-06-04 16:03:45 +08:00
dependabot[bot]
4039a85ee1 chore(deps-dev): bump concurrently from 8.2.2 to 9.1.2 (#156)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-02 19:49:58 +08:00
dependabot[bot]
3a83b83a9e chore(deps-dev): bump @vitejs/plugin-react from 4.4.1 to 4.5.0 (#160)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-02 19:47:04 +08:00
samanhappy
c1621805de fix: expand environment variables in database and OpenAI configuration (#162) 2025-06-02 19:46:39 +08:00
samanhappy
ecf79eaef3 fix: update error response status for missing transport in SSE service (#161) 2025-06-02 10:56:23 +08:00
samanhappy
e2cb5fa467 fix: update favicon path from "/favicon.svg" to "/favicon.ico" in documentation (#155) 2025-06-01 08:27:05 +08:00
samanhappy
7193ca4cdc fix: update "Get Started" button link to point to the correct documentation URL (#154) 2025-06-01 00:23:18 +08:00
samanhappy
9675cd8533 generate documents using mintlify (#153) 2025-06-01 00:17:09 +08:00
samanhappy
65c95aaa0b feat: Implement tool management features including tool execution and result handling (#152) 2025-05-31 22:00:05 +08:00
samanhappy
d2bbadea83 Add HTTP headers support and batch update for routing configuration (#151) 2025-05-31 18:36:41 +08:00
samanhappy
394945bbc5 fix: enhance environment variable handling in replaceEnvVars and expandEnvVars functions (#149)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-05-31 08:41:20 +08:00
samanhappy
bfc184afc6 fix: enhance database initialization by adding required PostgreSQL extensions and improving error handling (#144)
Co-authored-by: samanhappy@qq.com <my6051199>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-30 23:03:42 +08:00
Oven
1acacfab88 配置MCP Server时,env中填写的${xxx}值可以从环境变量中读取 (#135) 2025-05-30 23:02:34 +08:00
terrydash
63c55875b5 add env var for setting file (#147)
Co-authored-by: Xu, Guoxu | Terry | CNTD <guoxu.xu@rakuten.com>
2025-05-30 23:01:52 +08:00
samanhappy
80c6aae116 Add comprehensive documentation for MCPHub including deployment, configuration, and smart routing features (#142) 2025-05-29 15:44:39 +08:00
samanhappy
e2c5cc8ed1 fix: refine sessionId handling in handleMcpPostRequest for initialization requests (#138)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-05-28 23:25:21 +08:00
samanhappy
b0a65cc6d0 fix: streamline sessionId handling in handleMcpPostRequest (#137)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-05-28 22:15:14 +08:00
samanhappy
e019c9e8b3 fix: simplify server status labels in English and Chinese locales (#128) 2025-05-28 18:20:43 +08:00
samanhappy
39b69bf550 fix: improve sessionId validation and error handling in handleSseMessage (#134) 2025-05-28 14:30:35 +08:00
samanhappy
a1047321d1 feat: introduce runtime path (#132) 2025-05-27 18:34:23 +08:00
samanhappy
268ce5cce6 feat: Refactor API URL handling and add base path support (#131) 2025-05-27 16:11:35 +08:00
samanhappy
37bb3414c8 feat: add VITE_BASE_PATH environment variable and update routing in App component (#130) 2025-05-27 13:08:41 +08:00
samanhappy
c3e1fa1eee Update asset paths to use relative URLs (#129) 2025-05-27 11:55:50 +08:00
samanhappy
edfbdb7123 fix: update README and README.zh.md for clarity and consistency (#124) 2025-05-25 21:32:46 +08:00
samanhappy
9e5c2b5525 feat: introduce auto routing (#122) 2025-05-25 21:09:47 +08:00
samanhappy
27b7e766af fix: downgrade express and @types/express to compatible versions (#119) 2025-05-22 15:14:05 +08:00
dependabot[bot]
9c55f63bb1 chore(deps-dev): bump @types/node from 20.17.28 to 22.15.21 (#114)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 14:57:56 +08:00
dependabot[bot]
b1674cc630 chore(deps): bump express and @types/express (#113)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 14:56:06 +08:00
dependabot[bot]
3570232ccc chore(deps-dev): bump tailwind-merge from 3.1.0 to 3.3.0 (#112)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 14:54:29 +08:00
dependabot[bot]
f50bb08816 chore(deps-dev): bump @tailwindcss/postcss from 4.1.3 to 4.1.7 (#115)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 14:54:03 +08:00
dependabot[bot]
721674e7eb chore(deps-dev): bump @radix-ui/react-slot from 1.1.2 to 1.2.3 (#116)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 14:53:50 +08:00
samanhappy
1337eeed84 Update dependabot.yml (#111) 2025-05-21 09:39:56 +08:00
samanhappy
b14be9955b Create dependabot.yml (#110) 2025-05-21 09:37:39 +08:00
samanhappy
da45d49a5e feat: Bump Vite to v6 and update esbuild (#109)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-05-21 09:34:24 +08:00
samanhappy
f46e2c22fc feat: implement dynamic package versioning and refactor MCP server initialization (#104) 2025-05-18 20:07:01 +08:00
samanhappy
ae3fe1c6f1 add mintlify doc (#106) 2025-05-17 22:42:46 +08:00
samanhappy
76a27a454e docs: add Star History section to README files (#105) 2025-05-17 20:34:02 +08:00
samanhappy
b15b71f407 fix: enhance stdio log (#103) 2025-05-17 19:40:34 +08:00
samanhappy
298d96d593 feat: enhance MCP server retrieval and logging for transport closure (#101) 2025-05-16 16:47:21 +08:00
samanhappy
d44886b81b docs: update README to enhance clarity and add new features overview (#102) 2025-05-16 13:28:46 +08:00
Lawrence Sinclair
bbe44fc540 Add MseeP.ai badge (#95) 2025-05-14 17:14:48 +08:00
samanhappy
c60b98e3d6 feat: add icons and link to Header (#94) 2025-05-14 13:54:29 +08:00
samanhappy
a447fe5b41 feat: display current version in Header and remove version display from UserProfileMenu (#93) 2025-05-14 10:19:43 +08:00
samanhappy
94d51fa03a refactor: update issue templates for consistency and clarity (#91) 2025-05-13 22:01:23 +08:00
samanhappy
b88a7240c6 Update issue templates (#90) 2025-05-13 19:57:00 +08:00
samanhappy
3c875590ce refactor: remove Node.js setup and version update steps from release workflow (#84) 2025-05-13 14:37:09 +08:00
samanhappy
26fa61fcfc feat: implement version checking and update notifications in AboutDialog and UserProfileMenu (#83) 2025-05-13 14:18:49 +08:00
samanhappy
d689541fc4 refactor: remove dependency on wait-for-npm job in build workflow (#82) 2025-05-13 13:07:21 +08:00
samanhappy
30895c4b9a refactor: remove wait-for-npm job from build workflow (#81) 2025-05-13 13:05:26 +08:00
samanhappy
37c3fd9e06 feat: add bearer authentication support for MCP requests (#79) 2025-05-13 13:02:41 +08:00
samanhappy
59454ca250 feat: add wait-for-npm job and update version from tag in build workflow (#80) 2025-05-13 13:01:54 +08:00
samanhappy
63efa0038c feat: add npmRegistry support to installation configuration (#77)
Co-authored-by: samanhappy@qq.com <my6051199>
2025-05-13 09:21:07 +08:00
samanhappy
040782da8d feat: support streamable http upstream server (#75)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-12 22:12:48 +08:00
samanhappy
f1a5f692cc feat: create MCP server for different session (#74) 2025-05-12 15:11:37 +08:00
samanhappy
5d798cfe6a feat: enhance release workflow to automatically update package.json version (#70) 2025-05-11 14:43:48 +08:00
samanhappy
0490d98c9e feat: add sponsorship section to README.md (#72) 2025-05-11 14:41:00 +08:00
samanhappy
7af3c8a2ba feat: add installation configuration support with pythonIndexUrl in settings (#67) 2025-05-10 21:33:35 +08:00
samanhappy
7c43ca359e feat: add acknowledgment section to README.zh.md (#68)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-10 21:33:22 +08:00
samanhappy
2bb6302cbc feat: enhance user experience with version info (#69)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-10 21:33:05 +08:00
samanhappy
3a3f6c984c Create FUNDING.yml (#65) 2025-05-10 11:05:07 +08:00
samanhappy
e8bc053788 fix: update react-router-dom to version 7.6.0 in package.json and pnpm-lock.yaml (#63) 2025-05-09 22:06:51 +08:00
samanhappy
bb674236c7 feat: update Node.js and pnpm versions in CI workflow; add packageManager field in package.json (#62) 2025-05-09 21:34:25 +08:00
samanhappy
0f5dfbe419 feat: support server-specified endpoint (#58) 2025-05-09 21:25:44 +08:00
samanhappy
74d1ca6a87 fix: remove unnecessary dependency from fetchMarketServers to improve performance (#56) 2025-05-09 21:24:27 +08:00
dependabot[bot]
eab421c753 chore(deps-dev): bump vite from 5.4.18 to 5.4.19 (#51)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 20:58:54 +08:00
samanhappy
886ca44681 Implement code changes to enhance functionality and improve performance (#52) 2025-05-05 20:54:11 +08:00
samanhappy
3d4baeef1a feat: update dependencies in pnpm-lock.yaml for improved functionality and security (#50) 2025-05-05 19:44:25 +08:00
samanhappy
4379513a35 feat: add GitHub Actions workflow for publishing to NPM (#49) 2025-05-05 19:39:09 +08:00
samanhappy
9a06bae225 fix: improve error handling in CallToolRequest by providing detailed error messages (#48) 2025-05-05 19:09:02 +08:00
samanhappy
e5aaae466f feat: add log management features including log viewing, filtering, and streaming (#45) 2025-05-02 21:41:16 +08:00
samanhappy
9b1338a356 feat: add support for HTTP_PROXY and HTTPS_PROXY environment variables in Dockerfile and entrypoint script (#42) 2025-05-02 12:40:44 +08:00
samanhappy
10d4616601 Implement theme switching and enhance dark mode support (#43) 2025-05-02 12:40:11 +08:00
samanhappy
9ca242a0e4 docs: update README and README.zh to clarify Streamable HTTP endpoint support (#41) 2025-05-01 17:42:46 +08:00
samanhappy
0a6259decf feat: enhance configuration file handling and dynamic frontend path resolution (#40)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-30 22:38:21 +08:00
samanhappy
7887a3a5f9 docs: update README to reflect changes in HTTP endpoint support and deprecate SSE endpoint (#38) 2025-04-28 14:49:40 +08:00
samanhappy
7f33615161 feat: support Streamable HTTP transport for downstream (#32) 2025-04-27 13:55:25 +08:00
samanhappy
c9ec3b77ce fix: sort market servers by official status (#36) 2025-04-26 21:17:05 +08:00
samanhappy
142c3f628a Update group chat invitation details (#34) 2025-04-25 10:00:56 +08:00
samanhappy
bbb99b6f17 fix: enhance MCP server tool registration and client initialization logic (#31) 2025-04-23 16:27:21 +08:00
samanhappy
c1eabb5607 fix: improve client connection handling and tool listing in mcpService (#30) 2025-04-23 15:46:06 +08:00
samanhappy
afd1ee7a50 Enhance routing and settings functionality (#29) 2025-04-21 17:51:21 +08:00
samanhappy
6bf22025e1 docs: Refine introduction and usage details in intro2.md for clarity … (#27) 2025-04-21 14:03:20 +08:00
samanhappy
2c00f1d606 docs: Add comprehensive introduction and usage guide for MCPHub, deta… (#26) 2025-04-20 17:49:40 +08:00
samanhappy
3d49c652ad introduce market 2025-04-20 13:58:52 +08:00
samanhappy
c4008f617d fix: add catch-all route to serve frontend index.html in AppServer in… (#24) 2025-04-18 22:44:12 +08:00
samanhappy
6a5039a90e fix: consolidate build jobs and improve Docker image tagging logic (#23) 2025-04-18 20:50:00 +08:00
samanhappy
39222bdcd8 fix: update build workflow to improve cache configuration and image n… (#22) 2025-04-18 20:01:13 +08:00
samanhappy
436318b24c fix: refactor build workflow to separate base and full variants with … (#21) 2025-04-18 19:50:22 +08:00
samanhappy
3e5a64d533 fix: improve Docker tags configuration for edge and semver variants i… (#20) 2025-04-18 19:31:01 +08:00
402 changed files with 146433 additions and 4627 deletions

16
.coveragerc Normal file
View File

@@ -0,0 +1,16 @@
# Test coverage configuration
# This file tells Jest what to include/exclude from coverage reports
# Coverage patterns
- "src/**/*.{ts,tsx}"
# Exclusions
- "!src/**/*.d.ts"
- "!src/index.ts"
- "!src/**/__tests__/**"
- "!src/**/*.test.{ts,tsx}"
- "!src/**/*.spec.{ts,tsx}"
- "!**/node_modules/**"
- "!coverage/**"
- "!dist/**"
- "!build/**"

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
.git

View File

@@ -1,2 +1,8 @@
PORT=3000
NODE_ENV=development
# Database Configuration (Optional - for database-backed configuration)
# Simply set DB_URL to enable database mode (auto-detected)
# DB_URL=postgresql://mcphub:password@localhost:5432/mcphub
# Or explicitly control with USE_DB (overrides auto-detection)
# USE_DB=true

View File

@@ -20,6 +20,6 @@
}
],
"@typescript-eslint/no-explicit-any": "off",
"no-undef": "off",
"no-undef": "off"
}
}

124
.github/DOCKER_CLI_TEST.md vendored Normal file
View File

@@ -0,0 +1,124 @@
# Docker Engine Installation Test Procedure
This document describes how to test the Docker Engine installation feature added with the `INSTALL_EXT=true` build argument.
## Test 1: Build with INSTALL_EXT=false (default)
```bash
# Build without extended features
docker build -t mcphub:base .
# Run the container
docker run --rm mcphub:base docker --version
```
**Expected Result**: `docker: not found` error (Docker is NOT installed)
## Test 2: Build with INSTALL_EXT=true
```bash
# Build with extended features
docker build --build-arg INSTALL_EXT=true -t mcphub:extended .
# Test Docker CLI is available
docker run --rm mcphub:extended docker --version
```
**Expected Result**: Docker version output (e.g., `Docker version 27.x.x, build xxxxx`)
## Test 3: Docker-in-Docker with Auto-start Daemon
```bash
# Build with extended features
docker build --build-arg INSTALL_EXT=true -t mcphub:extended .
# Run with privileged mode (allows Docker daemon to start)
docker run -d \
--name mcphub-test \
--privileged \
-p 3000:3000 \
mcphub:extended
# Wait a few seconds for daemon to start
sleep 5
# Test Docker commands from inside the container
docker exec mcphub-test docker ps
docker exec mcphub-test docker images
docker exec mcphub-test docker info
# Cleanup
docker stop mcphub-test
docker rm mcphub-test
```
**Expected Result**:
- Docker daemon should auto-start inside the container
- Docker commands should work without mounting the host's Docker socket
- `docker info` should show the container's own Docker daemon
## Test 4: Docker-in-Docker with Host Socket (Alternative)
```bash
# Build with extended features
docker build --build-arg INSTALL_EXT=true -t mcphub:extended .
# Run with Docker socket mounted (uses host's daemon)
docker run -d \
--name mcphub-test \
-p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
mcphub:extended
# Test Docker commands from inside the container
docker exec mcphub-test docker ps
docker exec mcphub-test docker images
# Cleanup
docker stop mcphub-test
docker rm mcphub-test
```
**Expected Result**:
- Docker daemon should NOT auto-start (socket already exists from host)
- Docker commands should work and show the host's containers and images
## Test 5: Verify Image Size
```bash
# Build both versions
docker build -t mcphub:base .
docker build --build-arg INSTALL_EXT=true -t mcphub:extended .
# Compare image sizes
docker images mcphub:*
```
**Expected Result**:
- The `extended` image should be larger than the `base` image
- The size difference should be reasonable (Docker Engine adds ~100-150MB)
## Test 6: Architecture Support
```bash
# On AMD64/x86_64
docker build --build-arg INSTALL_EXT=true --platform linux/amd64 -t mcphub:extended-amd64 .
# On ARM64
docker build --build-arg INSTALL_EXT=true --platform linux/arm64 -t mcphub:extended-arm64 .
```
**Expected Result**:
- Both builds should succeed
- AMD64 includes Chrome/Playwright + Docker Engine
- ARM64 includes Docker Engine only (Chrome installation is skipped)
## Notes
- The Docker Engine installation follows the official Docker documentation
- Includes full Docker daemon (`dockerd`), CLI (`docker`), and containerd
- The daemon auto-starts when running in privileged mode
- The installation uses the Debian Bookworm repository
- All temporary files are cleaned up to minimize image size
- The feature is opt-in via the `INSTALL_EXT` build argument
- `iptables` is installed as it's required for Docker networking

15
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: samanhappy
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -0,0 +1,29 @@
---
name: Bug Report / Bug 报告
about: Create a report to help us improve / 报告问题以帮助改进
title: ''
labels: bug
assignees: ''
---
**Bug Description / 问题描述**
What happened? / 发生了什么?
**Steps to Reproduce / 复现步骤**
1.
2.
3.
**Expected Behavior / 预期行为**
What should happen? / 应该发生什么?
**Environment / 运行环境**
- Running on / 运行方式: [docker/npx/local / docker/npx/本地]
- Version / 版本: [e.g. 1.0.0]
**Screenshots / 截图**
If relevant, add screenshots / 如果有帮助的话,请添加截图
**Additional Info / 补充信息**
Any other details? / 还有其他信息吗?

View File

@@ -0,0 +1,20 @@
---
name: Feature request / 功能请求
about: Suggest an idea for this project / 为项目提出新想法
title: ''
labels: enhancement
assignees: ''
---
**Current Problem / 当前问题**
What problem are you trying to solve? / 您想要解决什么问题?
**Proposed Solution / 建议方案**
How would you like this to work? / 您期望的解决方案是什么?
**Alternatives / 替代方案**
Have you considered any alternatives? / 您是否考虑过其他解决方案?
**Additional Context / 补充说明**
Any screenshots, mockups, or relevant information? / 有任何截图、设计图或相关信息吗?

272
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,272 @@
# MCPHub Coding Instructions
**ALWAYS follow these instructions first and only fallback to additional search and context gathering if the information here is incomplete or found to be in error.**
## Project Overview
MCPHub is a TypeScript/Node.js MCP (Model Context Protocol) server management hub that provides unified access through HTTP endpoints. It serves as a centralized dashboard for managing multiple MCP servers with real-time monitoring, authentication, and flexible routing.
**Core Components:**
- **Backend**: Express.js + TypeScript + ESM (`src/server.ts`)
- **Frontend**: React/Vite + Tailwind CSS (`frontend/`)
- **MCP Integration**: Connects multiple MCP servers (`src/services/mcpService.ts`)
- **Authentication**: JWT-based with bcrypt password hashing
- **Configuration**: JSON-based MCP server definitions (`mcp_settings.json`)
- **Documentation**: API docs and usage instructions(`docs/`)
## Working Effectively
### Bootstrap and Setup (CRITICAL - Follow Exact Steps)
```bash
# Install pnpm if not available
npm install -g pnpm
# Install dependencies - takes ~30 seconds
pnpm install
# Setup environment (optional)
cp .env.example .env
# Build and test to verify setup
pnpm lint # ~3 seconds - NEVER CANCEL
pnpm backend:build # ~5 seconds - NEVER CANCEL
pnpm test:ci # ~16 seconds - NEVER CANCEL. Set timeout to 60+ seconds
pnpm frontend:build # ~5 seconds - NEVER CANCEL
pnpm build # ~10 seconds total - NEVER CANCEL. Set timeout to 60+ seconds
```
**CRITICAL TIMING**: These commands are fast but NEVER CANCEL them. Always wait for completion.
### Development Environment
```bash
# Start both backend and frontend (recommended for most development)
pnpm dev # Backend on :3001, Frontend on :5173
# OR start separately (required on Windows, optional on Linux/macOS)
# Terminal 1: Backend only
pnpm backend:dev # Runs on port 3000 (or PORT env var)
# Terminal 2: Frontend only
pnpm frontend:dev # Runs on port 5173, proxies API to backend
```
**NEVER CANCEL**: Development servers may take 10-15 seconds to fully initialize all MCP servers.
### Build Commands (Production)
```bash
# Full production build - takes ~10 seconds total
pnpm build # NEVER CANCEL - Set timeout to 60+ seconds
# Individual builds
pnpm backend:build # TypeScript compilation - ~5 seconds
pnpm frontend:build # Vite build - ~5 seconds
# Start production server
pnpm start # Requires dist/ and frontend/dist/ to exist
```
### Testing and Validation
```bash
# Run all tests - takes ~16 seconds with 73 tests
pnpm test:ci # NEVER CANCEL - Set timeout to 60+ seconds
# Development testing
pnpm test # Interactive mode
pnpm test:watch # Watch mode for development
pnpm test:coverage # With coverage report
# Code quality
pnpm lint # ESLint - ~3 seconds
pnpm format # Prettier formatting - ~3 seconds
```
**CRITICAL**: All tests MUST pass before committing. Do not modify tests to make them pass unless specifically required for your changes.
## Manual Validation Requirements
**ALWAYS perform these validation steps after making changes:**
### 1. Basic Application Functionality
```bash
# Start the application
pnpm dev
# Verify backend responds (in another terminal)
curl http://localhost:3000/api/health
# Expected: Should return health status
# Verify frontend serves
curl -I http://localhost:3000/
# Expected: HTTP 200 OK with HTML content
```
### 2. MCP Server Integration Test
```bash
# Check MCP servers are loading (look for log messages)
# Expected log output should include:
# - "Successfully connected client for server: [name]"
# - "Successfully listed [N] tools for server: [name]"
# - Some servers may fail due to missing API keys (normal in dev)
```
### 3. Build Verification
```bash
# Verify production build works
pnpm build
node scripts/verify-dist.js
# Expected: "✅ Verification passed! Frontend and backend dist files are present."
```
**NEVER skip these validation steps**. If any fail, debug and fix before proceeding.
## Project Structure and Key Files
### Critical Backend Files
- `src/index.ts` - Application entry point
- `src/server.ts` - Express server setup and middleware
- `src/services/mcpService.ts` - **Core MCP server management logic**
- `src/config/index.ts` - Configuration management
- `src/routes/` - HTTP route definitions
- `src/controllers/` - HTTP request handlers
- `src/dao/` - Data access layer (supports JSON file & PostgreSQL)
- `src/db/` - TypeORM entities & repositories (for PostgreSQL mode)
- `src/types/index.ts` - TypeScript type definitions
### DAO Layer (Dual Data Source)
MCPHub supports **JSON file** (default) and **PostgreSQL** storage:
- Set `USE_DB=true` + `DB_URL=postgresql://...` to use database
- When modifying data structures, update: `src/types/`, `src/dao/`, `src/db/entities/`, `src/db/repositories/`, `src/utils/migration.ts`
- See `AGENTS.md` for detailed DAO modification checklist
### Critical Frontend Files
- `frontend/src/` - React application source
- `frontend/src/pages/` - Page components (development entry point)
- `frontend/src/components/` - Reusable UI components
- `frontend/src/utils/fetchInterceptor.js` - Backend API interaction
### Configuration Files
- `mcp_settings.json` - **MCP server definitions and user accounts**
- `package.json` - Dependencies and scripts
- `tsconfig.json` - TypeScript configuration
- `jest.config.cjs` - Test configuration
- `.eslintrc.json` - Linting rules
### Docker and Deployment
- `Dockerfile` - Multi-stage build with Python base + Node.js
- `entrypoint.sh` - Docker startup script
- `bin/cli.js` - NPM package CLI entry point
## Development Process and Conventions
### Code Style Requirements
- **ESM modules**: Always use `.js` extensions in imports, not `.ts`
- **English only**: All code comments must be written in English
- **TypeScript strict**: Follow strict type checking rules
- **Import style**: `import { something } from './file.js'` (note .js extension)
### Key Configuration Notes
- **MCP servers**: Defined in `mcp_settings.json` with command/args
- **Endpoints**: `/mcp/{group|server}` and `/mcp/$smart` for routing
- **i18n**: Frontend uses react-i18next with files in `locales/` folder
- **Authentication**: JWT tokens with bcrypt password hashing
- **Default credentials**: admin/admin123 (configured in mcp_settings.json)
### Development Entry Points
- **Add MCP server**: Modify `mcp_settings.json` and restart
- **New API endpoint**: Add route in `src/routes/`, controller in `src/controllers/`
- **Frontend feature**: Start from `frontend/src/pages/` or `frontend/src/components/`
- **Add tests**: Follow patterns in `tests/` directory
### Common Development Tasks
#### Adding a new MCP server:
1. Add server definition to `mcp_settings.json`
2. Restart backend to load new server
3. Check logs for successful connection
4. Test via dashboard or API endpoints
#### API development:
1. Define route in `src/routes/`
2. Implement controller in `src/controllers/`
3. Add types in `src/types/index.ts` if needed
4. Write tests in `tests/controllers/`
#### Frontend development:
1. Create/modify components in `frontend/src/components/`
2. Add pages in `frontend/src/pages/`
3. Update routing if needed
4. Test in development mode with `pnpm frontend:dev`
#### Documentation:
1. Update or add docs in `docs/` folder
2. Ensure README.md reflects any major changes
## Validation and CI Requirements
### Before Committing - ALWAYS Run:
```bash
pnpm lint # Must pass - ~3 seconds
pnpm backend:build # Must compile - ~5 seconds
pnpm test:ci # All tests must pass - ~16 seconds
pnpm build # Full build must work - ~10 seconds
```
**CRITICAL**: CI will fail if any of these commands fail. Fix issues locally first.
### CI Pipeline (.github/workflows/ci.yml)
- Runs on Node.js 20.x
- Tests: linting, type checking, unit tests with coverage
- **NEVER CANCEL**: CI builds may take 2-3 minutes total
## Troubleshooting
### Common Issues
- **"uvx command not found"**: Some MCP servers require `uvx` (Python package manager) - this is expected in development
- **Port already in use**: Change PORT environment variable or kill existing processes
- **Frontend not loading**: Ensure frontend was built with `pnpm frontend:build`
- **MCP server connection failed**: Check server command/args in `mcp_settings.json`
### Build Failures
- **TypeScript errors**: Run `pnpm backend:build` to see compilation errors
- **Test failures**: Run `pnpm test:verbose` for detailed test output
- **Lint errors**: Run `pnpm lint` and fix reported issues
### Development Issues
- **Backend not starting**: Check for port conflicts, verify `mcp_settings.json` syntax
- **Frontend proxy errors**: Ensure backend is running before starting frontend
- **Hot reload not working**: Restart development server
## Performance Notes
- **Install time**: pnpm install takes ~30 seconds
- **Build time**: Full build takes ~10 seconds
- **Test time**: Complete test suite takes ~16 seconds
- **Startup time**: Backend initialization takes 10-15 seconds (MCP server connections)
**Remember**: NEVER CANCEL any build or test commands. Always wait for completion even if they seem slow.

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"

View File

@@ -8,6 +8,9 @@ on:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
variant: ${{ startsWith(github.ref, 'refs/tags/') && fromJSON('["base", "full"]') || fromJSON('["base"]') }}
@@ -16,27 +19,50 @@ jobs:
with:
fetch-depth: 0
- name: Update version from tag
if: startsWith(github.ref, 'refs/tags/')
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "Updating package.json version to $VERSION"
jq ".version = \"$VERSION\"" package.json > package.json.tmp
mv package.json.tmp package.json
echo "Updated version in package.json:"
grep -m 1 "version" package.json
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
if: endsWith(github.repository, 'mcphub')
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
if: endsWith(github.repository, 'mcphubx')
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: samanhappy/mcphub
images: |
${{ endsWith(github.repository, 'mcphub') && github.repository || '' }}
${{ endsWith(github.repository, 'mcphubx') && format('ghcr.io/{0}', github.repository) || '' }}
tags: |
type=raw,value=edge${{ matrix.variant == 'full' && '-full' || '' }},enable=${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
type=semver,pattern={{version}}${{ matrix.variant == 'full' && '-full' || '' }},enable=${{ startsWith(github.ref, 'refs/tags/') }}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') && matrix.variant == 'base' }}
type=raw,value=latest-full,enable=${{ startsWith(github.ref, 'refs/tags/') && matrix.variant == 'full' }}
type=raw,value=latest${{ matrix.variant == 'full' && '-full' || '' }},enable=${{ startsWith(github.ref, 'refs/tags/') }}
flavor: |
latest=false
- name: Build and Push Docker Image
if: endsWith(github.repository, 'mcphub') || endsWith(github.repository, 'mcphubx')
uses: docker/build-push-action@v5
with:
context: .

112
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,112 @@
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run linter
run: pnpm lint
- name: Run type checking
run: pnpm backend:build
- name: Run tests
run: pnpm test:ci
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
# build:
# runs-on: ubuntu-latest
# needs: test
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Setup Node.js
# uses: actions/setup-node@v4
# with:
# node-version: '20.x'
# - name: Enable Corepack
# run: corepack enable
# - name: Install dependencies
# run: pnpm install --frozen-lockfile
# - name: Build application
# run: pnpm build
# - name: Verify build artifacts
# run: node scripts/verify-dist.js
# integration-test:
# runs-on: ubuntu-latest
# needs: test
# services:
# postgres:
# image: postgres:15
# env:
# POSTGRES_PASSWORD: postgres
# POSTGRES_DB: mcphub_test
# options: >-
# --health-cmd pg_isready
# --health-interval 10s
# --health-timeout 5s
# --health-retries 5
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Setup Node.js
# uses: actions/setup-node@v4
# with:
# node-version: '20.x'
# - name: Enable Corepack
# run: corepack enable
# - name: Install dependencies
# run: pnpm install --frozen-lockfile
# - name: Build application
# run: pnpm build
# - name: Run integration tests
# run: |
# export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/mcphub_test"
# node test-integration.ts
# env:
# NODE_ENV: test

59
.github/workflows/npm-publish.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: Publish to NPM
on:
push:
tags: ['v*.*.*']
jobs:
publish-npm:
runs-on: ubuntu-latest
if: endsWith(github.repository, 'mcphub')
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 10
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Update version from tag
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "Updating package.json version to $VERSION"
jq ".version = \"$VERSION\"" package.json > package.json.tmp
mv package.json.tmp package.json
echo "Updated version in package.json:"
grep -m 1 "version" package.json
- name: Build package
run: pnpm build
- name: Publish to NPM
run: pnpm publish --no-git-checks --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -13,6 +13,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Release
uses: softprops/action-gh-release@v2
with:

4
.gitignore vendored
View File

@@ -2,6 +2,7 @@
/node_modules
/.pnp
.pnp.js
package-lock.json
# production
dist
@@ -24,3 +25,6 @@ yarn-error.log*
.vscode/
*.log
coverage/
data/
temp-test-config/

View File

@@ -4,4 +4,4 @@
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
}
}

78
AGENTS.md Normal file
View File

@@ -0,0 +1,78 @@
# Repository Guidelines
These notes align current contributors around the code layout, daily commands, and collaboration habits that keep `@samanhappy/mcphub` moving quickly.
## Project Structure & Module Organization
- Backend services live in `src`, grouped by responsibility (`controllers/`, `services/`, `dao/`, `routes/`, `utils/`), with `server.ts` orchestrating HTTP bootstrap.
- `frontend/src` contains the Vite + React dashboard; `frontend/public` hosts static assets and translations sit in `locales/`.
- Jest-aware test code is split between colocated specs (`src/**/*.{test,spec}.ts`) and higher-level suites in `tests/`; use `tests/utils/` helpers when exercising the CLI or SSE flows.
- Build artifacts and bundles are generated into `dist/`, `frontend/dist/`, and `coverage/`; never edit these manually.
## Build, Test, and Development Commands
- `pnpm dev` runs backend (`tsx watch src/index.ts`) and frontend (`vite`) together for local iteration.
- `pnpm backend:dev`, `pnpm frontend:dev`, and `pnpm frontend:preview` target each surface independently; prefer them when debugging one stack.
- `pnpm build` executes `pnpm backend:build` (TypeScript to `dist/`) and `pnpm frontend:build`; run before release or publishing.
- `pnpm test`, `pnpm test:watch`, and `pnpm test:coverage` drive Jest; `pnpm lint` and `pnpm format` enforce style via ESLint and Prettier.
## Coding Style & Naming Conventions
- TypeScript everywhere; default to 2-space indentation and single quotes, letting Prettier settle formatting. ESLint configuration assumes ES modules.
- Name services and data access layers with suffixes (`UserService`, `AuthDao`), React components and files in `PascalCase`, and utility modules in `camelCase`.
- Keep DTOs and shared types in `src/types` to avoid duplication; re-export through index files only when it clarifies imports.
## Testing Guidelines
- Use Jest with the `ts-jest` ESM preset; place shared setup in `tests/setup.ts` and mock helpers under `tests/utils/`.
- Mirror production directory names when adding new suites and end filenames with `.test.ts` or `.spec.ts` for automatic discovery.
- Aim to maintain or raise coverage when touching critical flows (auth, OAuth, SSE); add integration tests under `tests/integration/` when touching cross-service logic.
## Commit & Pull Request Guidelines
- Follow the existing Conventional Commit pattern (`feat:`, `fix:`, `chore:`, etc.) with imperative, present-tense summaries and optional multi-line context.
- Each PR should describe the behavior change, list testing performed, and link issues; include before/after screenshots or GIFs for frontend tweaks.
- Re-run `pnpm build` and `pnpm test` before requesting review, and ensure generated artifacts stay out of the diff.
## DAO Layer & Dual Data Source
MCPHub supports **JSON file** (default) and **PostgreSQL** storage. Set `USE_DB=true` + `DB_URL` to switch.
### Key Files
- `src/types/index.ts` - Core interfaces (`IUser`, `IGroup`, `ServerConfig`, etc.)
- `src/dao/*Dao.ts` - DAO interface + JSON implementation
- `src/dao/*DaoDbImpl.ts` - Database implementation
- `src/db/entities/*.ts` - TypeORM entities
- `src/db/repositories/*.ts` - TypeORM repository wrappers
- `src/utils/migration.ts` - JSON-to-database migration
### Modifying Data Structures (CRITICAL)
When adding/changing fields, update **ALL** these files:
| Step | File | Action |
| ---- | -------------------------- | ---------------------------- |
| 1 | `src/types/index.ts` | Add field to interface |
| 2 | `src/dao/*Dao.ts` | Update JSON impl if needed |
| 3 | `src/db/entities/*.ts` | Add TypeORM `@Column` |
| 4 | `src/dao/*DaoDbImpl.ts` | Map field in create/update |
| 5 | `src/db/repositories/*.ts` | Update if needed |
| 6 | `src/utils/migration.ts` | Include in migration |
| 7 | `mcp_settings.json` | Update example if applicable |
### Data Type Mapping
| Model | DAO | DB Entity | JSON Path |
| -------------- | ----------------- | -------------- | ------------------------ |
| `IUser` | `UserDao` | `User` | `settings.users[]` |
| `ServerConfig` | `ServerDao` | `Server` | `settings.mcpServers{}` |
| `IGroup` | `GroupDao` | `Group` | `settings.groups[]` |
| `SystemConfig` | `SystemConfigDao` | `SystemConfig` | `settings.systemConfig` |
| `UserConfig` | `UserConfigDao` | `UserConfig` | `settings.userConfigs{}` |
### Common Pitfalls
- Forgetting migration script → fields won't migrate to DB
- Optional fields need `nullable: true` in entity
- Complex objects need `simple-json` column type

View File

@@ -2,33 +2,39 @@ FROM python:3.13-slim-bookworm AS base
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
RUN apt-get update && apt-get install -y curl gnupg \
RUN apt-get update && apt-get install -y curl gnupg git build-essential \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
RUN npm install -g pnpm
ARG REQUEST_TIMEOUT=60000
ENV REQUEST_TIMEOUT=$REQUEST_TIMEOUT
ENV PNPM_HOME=/usr/local/share/pnpm
ENV PATH=$PNPM_HOME:$PATH
RUN mkdir -p $PNPM_HOME && \
pnpm add -g @amap/amap-maps-mcp-server @playwright/mcp@latest tavily-mcp@latest @modelcontextprotocol/server-github @modelcontextprotocol/server-slack
pnpm add -g @amap/amap-maps-mcp-server @playwright/mcp@latest tavily-mcp@latest @modelcontextprotocol/server-github @modelcontextprotocol/server-slack
ARG INSTALL_EXT=false
RUN if [ "$INSTALL_EXT" = "true" ]; then \
ARCH=$(uname -m); \
if [ "$ARCH" = "x86_64" ]; then \
npx -y playwright install --with-deps chrome; \
else \
echo "Skipping Chrome installation on non-amd64 architecture: $ARCH"; \
fi; \
fi
ARCH=$(uname -m); \
if [ "$ARCH" = "x86_64" ]; then \
npx -y playwright install --with-deps chrome; \
else \
echo "Skipping Chrome installation on non-amd64 architecture: $ARCH"; \
fi; \
# Install Docker Engine (includes CLI and daemon) \
apt-get update && \
apt-get install -y ca-certificates curl iptables && \
install -m 0755 -d /etc/apt/keyrings && \
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc && \
chmod a+r /etc/apt/keyrings/docker.asc && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && \
apt-get update && \
apt-get install -y docker-ce docker-ce-cli containerd.io && \
apt-get clean && rm -rf /var/lib/apt/lists/*; \
fi
RUN uv tool install mcp-server-fetch
ENV UV_PYTHON_INSTALL_MIRROR="http://mirrors.aliyun.com/pypi/simple/"
WORKDIR /app
@@ -37,6 +43,9 @@ RUN pnpm install
COPY . .
# Download the latest servers.json from mcpm.sh and replace the existing file
RUN curl -s -f --connect-timeout 10 https://mcpm.sh/api/servers.json -o servers.json || echo "Failed to download servers.json, using bundled version"
RUN pnpm frontend:build && pnpm build
COPY entrypoint.sh /usr/local/bin/entrypoint.sh

126
QWEN.md Normal file
View File

@@ -0,0 +1,126 @@
# MCPHub Project Overview
## Project Summary
MCPHub is a centralized hub server for managing multiple Model Context Protocol (MCP) servers. It allows organizing these servers into flexible Streamable HTTP (SSE) endpoints, supporting access to all servers, individual servers, or logical server groups. It provides a web dashboard for monitoring and managing servers, along with features like authentication, group-based access control, and Smart Routing using vector semantic search.
## Technology Stack
### Backend
- **Language:** TypeScript (Node.js)
- **Framework:** Express
- **Key Libraries:**
- `@modelcontextprotocol/sdk`: Core library for MCP interactions.
- `typeorm`: ORM for database interactions.
- `pg` & `pgvector`: PostgreSQL database and vector support.
- `jsonwebtoken` & `bcryptjs`: Authentication (JWT) and password hashing.
- `openai`: For embedding generation in Smart Routing.
- Various utility and validation libraries (e.g., `dotenv`, `express-validator`, `uuid`).
### Frontend
- **Framework:** React (via Vite)
- **Language:** TypeScript
- **UI Library:** Tailwind CSS
- **Routing:** `react-router-dom`
- **Internationalization:** `i18next`
- **Component Structure:** Modular components and pages within `frontend/src`.
### Infrastructure
- **Build Tool:** `pnpm` (package manager and script runner).
- **Containerization:** Docker (`Dockerfile` provided).
- **Process Management:** Not explicitly defined in core files, but likely managed by Docker or host system.
## Key Features
- **MCP Server Management:** Configure, start, stop, and monitor multiple upstream MCP servers via `stdio`, `SSE`, or `Streamable HTTP` protocols.
- **Centralized Dashboard:** Web UI for server status, group management, user administration, and logs.
- **Flexible Endpoints:**
- Global MCP/SSE endpoint (`/mcp`, `/sse`) for all enabled servers.
- Group-based endpoints (`/mcp/{group}`, `/sse/{group}`).
- Server-specific endpoints (`/mcp/{server}`, `/sse/{server}`).
- Smart Routing endpoint (`/mcp/$smart`, `/sse/$smart`) using vector search.
- **Authentication & Authorization:** JWT-based user authentication with role-based access control (admin/user).
- **Group Management:** Logical grouping of servers for targeted access and permission control.
- **Smart Routing (Experimental):** Uses pgvector and OpenAI embeddings to semantically search and find relevant tools across all connected servers.
- **Configuration:** Managed via `mcp_settings.json`.
- **Logging:** Server logs are captured and viewable via the dashboard.
- **Marketplace Integration:** Access to a marketplace of MCP servers (`servers.json`).
## Project Structure
```
C:\code\mcphub\
├───src\ # Backend source code (TypeScript)
├───frontend\ # Frontend source code (React/TypeScript)
│ ├───src\
│ ├───components\ # Reusable UI components
│ ├───pages\ # Top-level page components
│ ├───contexts\ # React contexts (Auth, Theme, Toast)
│ ├───layouts\ # Page layouts
│ ├───utils\ # Frontend utilities
│ └───...
├───dist\ # Compiled backend output
├───frontend\dist\ # Compiled frontend output
├───tests\ # Backend tests
├───docs\ # Documentation
├───scripts\ # Utility scripts
├───bin\ # CLI entry points
├───assets\ # Static assets (e.g., images for README)
├───.github\ # GitHub workflows
├───.vscode\ # VS Code settings
├───mcp_settings.json # Main configuration file for MCP servers and users
├───servers.json # Marketplace server definitions
├───package.json # Node.js project definition, dependencies, and scripts
├───pnpm-lock.yaml # Dependency lock file
├───tsconfig.json # TypeScript compiler configuration (Backend)
├───README.md # Project documentation
├───Dockerfile # Docker image definition
└───...
```
## Building and Running
### Prerequisites
- Node.js (>=18.0.0 or >=20.0.0)
- pnpm
- Python 3.13 (for some upstream servers and uvx)
- Docker (optional, for containerized deployment)
- PostgreSQL with pgvector (optional, for Smart Routing)
### Local Development
1. Clone the repository.
2. Install dependencies: `pnpm install`.
3. Start development servers: `pnpm dev`.
- This runs `pnpm backend:dev` (Node.js with `tsx watch`) and `pnpm frontend:dev` (Vite dev server) concurrently.
- Access the dashboard at `http://localhost:5173` (Vite default) or the configured port/path.
### Production Build
1. Install dependencies: `pnpm install`.
2. Build the project: `pnpm build`.
- This runs `pnpm backend:build` (TypeScript compilation to `dist/`) and `pnpm frontend:build` (Vite build to `frontend/dist/`).
3. Start the production server: `pnpm start`.
- This runs `node dist/index.js`.
### Docker Deployment
- Pull the image: `docker pull samanhappy/mcphub`.
- Run with default settings: `docker run -p 3000:3000 samanhappy/mcphub`.
- Run with custom config: `docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub`.
- Access the dashboard at `http://localhost:3000`.
## Configuration
The main configuration file is `mcp_settings.json`. It defines:
- `mcpServers`: A map of server configurations (command, args, env, URL, etc.).
- `users`: A list of user accounts (username, hashed password, admin status).
- `groups`: A map of server groups.
- `systemConfig`: System-wide settings (e.g., proxy, registry, installation options).
## Development Conventions
- **Language:** TypeScript for both backend and frontend.
- **Backend Style:** Modular structure with clear separation of concerns (controllers, services, models, middlewares, routes, config, utils).
- **Frontend Style:** Component-based React architecture with contexts for state management.
- **Database:** TypeORM with PostgreSQL is used, leveraging decorators for entity definition.
- **Testing:** Uses `jest` for backend testing.
- **Linting/Formatting:** Uses `eslint` and `prettier`.
- **Scripts:** Defined in `package.json` under the `scripts` section for common tasks (dev, build, start, test, lint, format).

119
README.fr.md Normal file
View File

@@ -0,0 +1,119 @@
# MCPHub : Le Hub Unifié pour les Serveurs MCP
[English](README.md) | Français | [中文版](README.zh.md)
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.
![Aperçu du tableau de bord](assets/dashboard.zh.png)
## 🌐 Démo en direct et Documentation
- **Documentation** : [docs.mcphubx.com](https://docs.mcphubx.com/)
- **Environnement de démo** : [demo.mcphubx.com](https://demo.mcphubx.com/)
## 🚀 Fonctionnalités
- **Gestion centralisée** - Surveillez et contrôlez tous les serveurs MCP depuis un tableau de bord unifié
- **Routage flexible** - Accédez à tous les serveurs, groupes spécifiques ou serveurs individuels via HTTP/SSE
- **Routage intelligent** - Découverte d'outils propulsée par IA utilisant la recherche sémantique vectorielle ([En savoir plus](https://docs.mcphubx.com/features/smart-routing))
- **Configuration à chaud** - Ajoutez, supprimez ou mettez à jour les serveurs sans temps d'arrêt
- **Support OAuth 2.0** - Modes client et serveur pour une authentification sécurisée ([En savoir plus](https://docs.mcphubx.com/features/oauth))
- **Mode Base de données** - Stockez la configuration dans PostgreSQL pour les environnements de production ([En savoir plus](https://docs.mcphubx.com/configuration/database-configuration))
- **Prêt pour Docker** - Déployez instantanément avec la configuration conteneurisée
## 🔧 Démarrage rapide
### Configuration
Créez un fichier `mcp_settings.json` :
```json
{
"mcpServers": {
"time": {
"command": "npx",
"args": ["-y", "time-mcp"]
},
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
}
}
}
```
📖 Consultez le [Guide de configuration](https://docs.mcphubx.com/configuration/mcp-settings) pour les options complètes incluant OAuth, les variables d'environnement, et plus.
### Déploiement avec Docker
```bash
# Exécutez avec une configuration personnalisée (recommandé)
docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
# Ou exécutez avec les paramètres par défaut
docker run -p 3000:3000 samanhappy/mcphub
```
### Accéder au tableau de bord
Ouvrez `http://localhost:3000` et connectez-vous avec les identifiants par défaut : `admin` / `admin123`
### Connecter les clients IA
Connectez les clients IA (Claude Desktop, Cursor, etc.) via :
```
http://localhost:3000/mcp # Tous les serveurs
http://localhost:3000/mcp/{group} # Groupe spécifique
http://localhost:3000/mcp/{server} # Serveur spécifique
http://localhost:3000/mcp/$smart # Routage intelligent
```
📖 Consultez la [Référence API](https://docs.mcphubx.com/api-reference) pour la documentation détaillée des points de terminaison.
## 📚 Documentation
| Sujet | Description |
| ------------------------------------------------------------------------------------- | ------------------------------------------- |
| [Démarrage rapide](https://docs.mcphubx.com/quickstart) | Commencez en 5 minutes |
| [Configuration](https://docs.mcphubx.com/configuration/mcp-settings) | Options de configuration du serveur MCP |
| [Mode Base de données](https://docs.mcphubx.com/configuration/database-configuration) | Configuration PostgreSQL pour la production |
| [OAuth](https://docs.mcphubx.com/features/oauth) | Configuration client et serveur OAuth 2.0 |
| [Routage intelligent](https://docs.mcphubx.com/features/smart-routing) | Découverte d'outils propulsée par IA |
| [Configuration Docker](https://docs.mcphubx.com/configuration/docker-setup) | Guide de déploiement Docker |
## 🧑‍💻 Développement local
```bash
git clone https://github.com/samanhappy/mcphub.git
cd mcphub
pnpm install
pnpm dev
```
> Pour les utilisateurs Windows, démarrez le backend et le frontend séparément : `pnpm backend:dev`, `pnpm frontend:dev`
📖 Consultez le [Guide de développement](https://docs.mcphubx.com/development) pour les instructions de configuration détaillées.
## 🔍 Stack technique
- **Backend** : Node.js, Express, TypeScript
- **Frontend** : React, Vite, Tailwind CSS
- **Authentification** : JWT & bcrypt
- **Protocole** : Model Context Protocol SDK
## 👥 Contribuer
Les contributions sont les bienvenues ! Rejoignez notre [communauté Discord](https://discord.gg/qMKNsn5Q) pour des discussions et du support.
## ❤️ Sponsor
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/samanhappy)
## 🌟 Historique des étoiles
[![Historique des étoiles](https://api.star-history.com/svg?repos=samanhappy/mcphub&type=Date)](https://www.star-history.com/#samanhappy/mcphub&Date)
## 📄 Licence
Sous licence [Apache 2.0 License](LICENSE).

128
README.md
View File

@@ -1,113 +1,86 @@
# MCPHub: Your Ultimate MCP Server Hub
# MCPHub: The Unified Hub for Model Context Protocol (MCP) Servers
English | [中文版](README.zh.md)
English | [Français](README.fr.md) | [中文版](README.zh.md)
MCPHub is a unified management platform that aggregates multiple MCP (Model Context Protocol) servers into separate SSE endpoints for different scenarios by group. It streamlines your AI tool integrations through an intuitive interface and robust protocol handling.
MCPHub makes it easy to manage and scale multiple MCP (Model Context Protocol) servers by organizing them into flexible Streamable HTTP (SSE) endpoints—supporting access to all servers, individual servers, or logical server groups.
![Dashboard Preview](assets/dashboard.png)
## 🌐 Live Demo & Docs
- **Documentation**: [docs.mcphubx.com](https://docs.mcphubx.com/)
- **Demo Environment**: [demo.mcphubx.com](https://demo.mcphubx.com/)
## 🚀 Features
- **Out-of-the-Box MCP Server Support**: Seamlessly integrate popular servers like `amap-maps`, `playwright`, `fetch`, `slack`, and more.
- **Centralized Dashboard**: Monitor real-time status and performance metrics from one sleek web UI.
- **Flexible Protocol Handling**: Full compatibility with both stdio and SSE MCP protocols.
- **Hot-Swappable Configuration**: Add, remove, or update MCP servers on the fly — no downtime required.
- **Group-Based Access Control**: Organize servers into customizable groups for streamlined permissions management.
- **Secure Authentication**: Built-in user management with role-based access powered by JWT and bcrypt.
- **Docker-Ready**: Deploy instantly with our containerized setup.
- **Centralized Management** - Monitor and control all MCP servers from a unified dashboard
- **Flexible Routing** - Access all servers, specific groups, or individual servers via HTTP/SSE
- **Smart Routing** - AI-powered tool discovery using vector semantic search ([Learn more](https://docs.mcphubx.com/features/smart-routing))
- **Hot-Swappable Config** - Add, remove, or update servers without downtime
- **OAuth 2.0 Support** - Both client and server modes for secure authentication ([Learn more](https://docs.mcphubx.com/features/oauth))
- **Database Mode** - Store configuration in PostgreSQL for production environments ([Learn more](https://docs.mcphubx.com/configuration/database-configuration))
- **Docker-Ready** - Deploy instantly with containerized setup
## 🔧 Quick Start
### Optional Configuration
### Configuration
Create a `mcp_settings.json` file to customize your server settings:
Create a `mcp_settings.json` file:
```json
{
"mcpServers": {
"amap-maps": {
"time": {
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "your-api-key"
}
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
"args": ["-y", "time-mcp"]
},
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
},
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "your-bot-token",
"SLACK_TEAM_ID": "your-team-id"
}
}
},
"users": [
{
"username": "admin",
"password": "$2b$10$Vt7krIvjNgyN67LXqly0uOcTpN0LI55cYRbcKC71pUDAP0nJ7RPa.",
"isAdmin": true
}
]
}
}
```
> **Note**: Default credentials are `admin` / `admin123`. Passwords are securely hashed with bcrypt. Generate a new hash with:
>
> ```bash
> npx bcryptjs your-password
> ```
📖 See [Configuration Guide](https://docs.mcphubx.com/configuration/mcp-settings) for full options including OAuth, environment variables, and more.
### Docker Deployment
**Recommended**: Mount your custom config:
```bash
docker run -p 3000:3000 -v $(pwd)/mcp_settings.json:/app/mcp_settings.json samanhappy/mcphub
```
# Run with custom config (recommended)
docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
or run with default settings:
```bash
# Or run with default settings
docker run -p 3000:3000 samanhappy/mcphub
```
### Access the Dashboard
### Access Dashboard
Open `http://localhost:3000` and log in with your credentials.
> **Note**: Default credentials are `admin` / `admin123`.
Open `http://localhost:3000` and log in with default credentials: `admin` / `admin123`
**Dashboard Overview**:
- Live status of all MCP servers
- Enable/disable or reconfigure servers
- Group management for organizing servers
- User administration for access control
### Connect AI Clients
### SSE Endpoint
Connect AI clients (Claude Desktop, Cursor, etc.) via:
Connect AI clients (e.g., Claude Desktop, Cursor, Cherry Studio) via:
```
http://localhost:3000/sse
http://localhost:3000/mcp # All servers
http://localhost:3000/mcp/{group} # Specific group
http://localhost:3000/mcp/{server} # Specific server
http://localhost:3000/mcp/$smart # Smart routing
```
**Group-Specific Endpoints (Recommended)**:
📖 See [API Reference](https://docs.mcphubx.com/api-reference) for detailed endpoint documentation.
![Group Management](assets/group.png)
## 📚 Documentation
For targeted access to specific server groups, use the group-based SSE endpoint:
```
http://localhost:3000/sse/{groupId}
```
Where `{groupId}` is the ID of the group you created in the dashboard. This allows you to:
- Connect to a specific subset of MCP servers organized by use case
- Isolate different AI tools to access only relevant servers
- Implement more granular access control for different environments or teams
| Topic | Description |
| ------------------------------------------------------------------------------ | --------------------------------- |
| [Quick Start](https://docs.mcphubx.com/quickstart) | Get started in 5 minutes |
| [Configuration](https://docs.mcphubx.com/configuration/mcp-settings) | MCP server configuration options |
| [Database Mode](https://docs.mcphubx.com/configuration/database-configuration) | PostgreSQL setup for production |
| [OAuth](https://docs.mcphubx.com/features/oauth) | OAuth 2.0 client and server setup |
| [Smart Routing](https://docs.mcphubx.com/features/smart-routing) | AI-powered tool discovery |
| [Docker Setup](https://docs.mcphubx.com/configuration/docker-setup) | Docker deployment guide |
## 🧑‍💻 Local Development
@@ -118,7 +91,9 @@ pnpm install
pnpm dev
```
This starts both frontend and backend in development mode with hot-reloading.
> For Windows users, start backend and frontend separately: `pnpm backend:dev`, `pnpm frontend:dev`
📖 See [Development Guide](https://docs.mcphubx.com/development) for detailed setup instructions.
## 🔍 Tech Stack
@@ -129,12 +104,15 @@ This starts both frontend and backend in development mode with hot-reloading.
## 👥 Contributing
Contributions are welcome!
Contributions welcome! See our [Discord community](https://discord.gg/qMKNsn5Q) for discussions and support.
- New features & optimizations
- Documentation improvements
- Bug reports & fixes
- Translations & suggestions
## ❤️ Sponsor
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/samanhappy)
## 🌟 Star History
[![Star History Chart](https://api.star-history.com/svg?repos=samanhappy/mcphub&type=Date)](https://www.star-history.com/#samanhappy/mcphub&Date)
## 📄 License

View File

@@ -1,113 +1,86 @@
# MCPHub一站式 MCP 服务器聚合平台
[English Version](README.md) | 中文版
[English](README.md) | [Français](README.fr.md) | 中文版
MCPHub 是一个统一的 MCPModel Context Protocol,模型上下文协议)服务器聚合平台,可以根据场景将多个服务器聚合到不同的 SSE 端点。它通过直观的界面和强大的协议处理能力,简化了您的 AI 工具集成流程
MCPHub 通过将多个 MCPModel Context Protocol)服务器组织为灵活的流式 HTTPSSE端点,简化了管理与扩展工作。系统支持按需访问全部服务器、单个服务器或按场景分组的服务器集合
![控制面板预览](assets/dashboard.zh.png)
## 🌐 在线文档与演示
- **文档地址**: [docs.mcphubx.com](https://docs.mcphubx.com/)
- **演示环境**: [demo.mcphubx.com](https://demo.mcphubx.com/)
## 🚀 功能亮点
- **开箱即用的 MCP 服务器支持**:无缝集成 `amap-maps``playwright``fetch``slack` 等常见服务器。
- **集中式管理控制台**:在一个简洁的 Web UI 中实时监控所有服务器的状态和性能指标。
- **灵活的协议兼容**:完全支持 stdio 和 SSE 两种 MCP 协议。
- **热插拔配置**:在运行时动态添加、移除或更新服务器配置,无需停机。
- **基于分组的访问控制**:自定义分组并管理服务器访问权限。
- **安全认证机制**:内置用户管理,基于 JWT 和 bcrypt实现角色权限控制。
- **Docker 就绪**:提供容器化镜像,快速部署。
- **集中式管理** - 在统一控制台中监控和管理所有 MCP 服务器
- **灵活路由** - 通过 HTTP/SSE 访问所有服务器、特定分组或单个服务器
- **智能路由** - 基于向量语义搜索的 AI 工具发现 ([了解更多](https://docs.mcphubx.com/zh/features/smart-routing))
- **热插拔配置** - 无需停机即可添加、移除或更新服务器
- **OAuth 2.0 支持** - 客户端和服务端模式,实现安全认证 ([了解更多](https://docs.mcphubx.com/zh/features/oauth))
- **数据库模式** - 将配置存储在 PostgreSQL 中,适用于生产环境 ([了解更多](https://docs.mcphubx.com/zh/configuration/database-configuration))
- **Docker 就绪** - 容器化部署,开箱即用
## 🔧 快速开始
### 可选配置
### 配置
通过创建 `mcp_settings.json` 自定义服务器设置
创建 `mcp_settings.json` 文件
```json
{
"mcpServers": {
"amap-maps": {
"time": {
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "your-api-key"
}
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
"args": ["-y", "time-mcp"]
},
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
},
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "your-bot-token",
"SLACK_TEAM_ID": "your-team-id"
}
}
},
"users": [
{
"username": "admin",
"password": "$2b$10$Vt7krIvjNgyN67LXqly0uOcTpN0LI55cYRbcKC71pUDAP0nJ7RPa.",
"isAdmin": true
}
]
}
}
```
> **提示**:默认用户名/密码为 `admin` / `admin123`。密码已通过 bcrypt 安全哈希。生成新密码哈希:
>
> ```bash
> npx bcryptjs your-password
> ```
📖 查看[配置指南](https://docs.mcphubx.com/zh/configuration/mcp-settings)了解完整选项,包括 OAuth、环境变量等。
### Docker 部署
**推荐**:挂载自定义配置:
```bash
docker run -p 3000:3000 -v $(pwd)/mcp_settings.json:/app/mcp_settings.json samanhappy/mcphub
```
# 挂载自定义配置运行(推荐)
docker run -p 3000:3000 -v ./mcp_settings.json:/app/mcp_settings.json -v ./data:/app/data samanhappy/mcphub
或使用默认配置运行
```bash
# 或使用默认配置运行
docker run -p 3000:3000 samanhappy/mcphub
```
### 访问控制台
打开 `http://localhost:3000`,使用您的账号登录
> **提示**:默认用户名/密码为 `admin` / `admin123`。
打开 `http://localhost:3000`,使用默认账号登录`admin` / `admin123`
**控制台功能**
- 实时监控所有 MCP 服务器状态
- 启用/禁用或重新配置服务器
- 分组管理,组织服务器访问
- 用户管理,设定权限
### 连接 AI 客户端
### SSE 端点集成
通过以下地址连接 AI 客户端Claude Desktop、Cursor 等):
通过以下地址连接 AI 客户端(如 Claude Desktop、Cursor、Cherry Studio 等):
```
http://localhost:3000/sse
http://localhost:3000/mcp # 所有服务器
http://localhost:3000/mcp/{group} # 特定分组
http://localhost:3000/mcp/{server} # 特定服务器
http://localhost:3000/mcp/$smart # 智能路由
```
**基于分组的 SSE 端点(推荐)**
📖 查看 [API 参考](https://docs.mcphubx.com/zh/api-reference)了解详细的端点文档。
![分组](assets/group.zh.png)
## 📚 文档
要针对特定服务器分组进行访问,请使用基于分组的 SSE 端点:
```
http://localhost:3000/sse/{groupId}
```
其中 `{groupId}` 是您在控制面板中创建的分组 ID。这样做可以
- 连接到按用例组织的特定 MCP 服务器子集
- 隔离不同的 AI 工具,使其只能访问相关服务器
- 为不同环境或团队实现更精细的访问控制
| 主题 | 描述 |
| ------------------------------------------------------------------------------ | ---------------------------- |
| [快速开始](https://docs.mcphubx.com/zh/quickstart) | 5 分钟快速上手 |
| [配置指南](https://docs.mcphubx.com/zh/configuration/mcp-settings) | MCP 服务器配置选项 |
| [数据库模式](https://docs.mcphubx.com/zh/configuration/database-configuration) | PostgreSQL 生产环境配置 |
| [OAuth](https://docs.mcphubx.com/zh/features/oauth) | OAuth 2.0 客户端和服务端配置 |
| [智能路由](https://docs.mcphubx.com/zh/features/smart-routing) | AI 驱动的工具发现 |
| [Docker 部署](https://docs.mcphubx.com/zh/configuration/docker-setup) | Docker 部署指南 |
## 🧑‍💻 本地开发
@@ -118,7 +91,9 @@ pnpm install
pnpm dev
```
此命令将在开发模式下启动前后端,并启用热重载。
> Windows 用户需分别启动后端和前端:`pnpm backend:dev``pnpm frontend:dev`
📖 查看[开发指南](https://docs.mcphubx.com/zh/development)了解详细设置说明。
## 🔍 技术栈
@@ -129,16 +104,21 @@ pnpm dev
## 👥 贡献指南
期待您的贡献!
欢迎加入企微交流共建群,由于群人数限制,有兴趣的同学可以扫码添加管理员为好友后拉入群聊。
- 新功能与优化
- 文档完善
- Bug 报告与修复
- 翻译与建议
<img src="assets/wexin.png" width="350">
欢迎加入企微交流共建群
如果觉得项目有帮助,不妨请我喝杯咖啡 ☕️
<img src="assets/wegroup.png" width="500">
<img src="assets/reward.png" width="350">
## 致谢
感谢以下朋友的赞赏小白、唐秀川、琛、孔、黄祥取、兰军飞、无名之辈、Kyle以及其他匿名支持者。
## 🌟 Star 历史趋势
[![Star History Chart](https://api.star-history.com/svg?repos=samanhappy/mcphub&type=Date)](https://www.star-history.com/#samanhappy/mcphub&Date)
## 📄 许可证

BIN
articals/assets/sr-conf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
articals/assets/sr-dc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
articals/assets/sr-time.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
articals/assets/sr-web.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -48,11 +48,11 @@ MCPHub 已内置多个常用 MCP 服务如高德地图、GitHub、Slack、Fet
![配置高德地图](../assets/amap-edit.png)
点击保存后MCP Hub 将自动重启高德地图的 MCP 服务,使新配置生效。
点击保存后MCPHub 将自动重启高德地图的 MCP 服务,使新配置生效。
### 配置 MCP Hub SSE
### 配置 MCPHub SSE
MCP Hub 提供了单一聚合的 MCP Server SSE 端点:`http://localhost:3000/sse`,可在任意支持 MCP 的客户端中配置使用。这里我们选择开源的 Cherry Studio 进行演示。
MCPHub 提供了单一聚合的 MCP Server SSE 端点:`http://localhost:3000/sse`,可在任意支持 MCP 的客户端中配置使用。这里我们选择开源的 Cherry Studio 进行演示。
![配置 Cherry Studio](../assets/cherry-mcp.png)

232
articals/intro2.md Normal file
View File

@@ -0,0 +1,232 @@
# 本地部署、一键安装、分组路由MCPHub 重塑 MCP 服务器体验
## 概述
现代 AI 应用场景中将大模型LLM与各种数据源和工具无缝对接往往需要手动编写大量胶水代码并且无法快速复用。MCPModel Context Protocol协议由 Anthropic 在 2024 年开源旨在提供类似“USBC”接口般的标准化通信方式简化 AI 助手与内容仓库、业务系统等的集成流程。然而MCP 服务器部署常常需要大量环境依赖、手动配置及持续运行开发者常因安装和配置耗费大量时间和精力。MCPHub 作为一款开源的一站式聚合平台,通过直观的 Web UI、Docker 镜像和热插拔配置,实现本地或容器里的“一键安装”与“分组路由”,大幅降低 MCP 服务器的使用门槛和运维成本​。
## MCPHub 是什么
### MCP 协议简介
Model Context ProtocolMCP是一种开放标准类似“USBC”接口为 AI 助手与内容仓库、业务系统和第三方服务之间提供统一通信协议。它支持 stdio 与 SSE最新协议中被 Streamable HTTP 取代两种通信方式既能满足实时流式数据交换也可用于批量任务。2024 年由 Anthropic 团队开源发布后MCP 已在各类 AI 客户端(如 Claude Desktop中得到应用成功实现与 GitHub、Slack、网页自动化工具等的无缝对接。
### MCPHub 项目概览
MCPHub 是一个统一的 MCP 服务器聚合平台,内置 MCP 服务器市场实现一键安装。前端基于 React、Vite 和 Tailwind CSS 构建,后端兼容任意使用 npx 或 uvx 命令启动的 MCP 服务器。它通过一个集中式 Dashboard 实时展示各服务器的运行状态,并支持在运行时热插拔增删改服务器配置,无需停机维护。支持分组式访问控制,可以通过独立的 SSE 端点访问不同的 MCP 服务器组合,管理员可灵活定义不同团队或环境的权限策略。官方提供 Docker 镜像,仅需一条命令即可快速启动本地或云端服务。
![MCPHub 控制面板](../assets/dashboard.zh.png)
## 为什么要使用 MCPHub
### 1. 复杂的环境依赖与配置
- MCP 服务器常依赖 Node.js、Python 等多种运行时,需手动维护大量命令、参数和环境变量。
- MCPHub 内置 MCP 服务器市场,包含众多常用 MCP 服务器,支持一键安装和自动配置,简化了环境搭建过程。
- 通过 Docker 部署MCPHub 可在任何支持 Docker 的平台上运行,避免了环境不一致的问题。
![MCPHub 市场](../assets/market.zh.png)
### 2. 持续运行的服务压力
- MCP 要求长连接服务常驻内存,重启或升级时需要人工干预,缺乏弹性。
- 借助 Docker 容器化部署MCPHub 可快速重建环境,享受容器带来的弹性与隔离优势。
### 3. 路由与分组管理缺乏统一视图
- 传统方式下,很难可视化地将不同 MCP 服务按场景分类,容易造成 token 浪费和工具选择精度下降。
- MCPHub 支持动态创建分组(如“地图检索”、“网页自动化”、“聊天”等),为每个分组生成独立的 SSE 端点,实现各类用例的隔离与优化。
![MCPHub 分组](../assets/group.zh.png)
## 如何使用 MCPHub
### 快速部署
```bash
docker run -p 3000:3000 samanhappy/mcphub
```
一条命令就可以在本地快速启动 MCPHub默认监听 3000 端口。
MCPHub 使用`mcp_settings.json`保存所有服务器、分组和用户的配置。你可以创建一个 `mcp_settings.json` 文件,并将其挂载到 Docker 容器中,以便在重启时保留配置。
```json
{
"mcpServers": {
"amap": {
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "your-api-key"
}
},
"time-mcp": {
"command": "npx",
"args": [
"-y",
"time-mcp"
]
},
"sequential-thinking": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sequential-thinking"
]
}
}
}
```
然后挂载配置文件启动:
```bash
docker run -p 3000:3000 -v $(pwd)/mcp_settings.json:/app/mcp_settings.json samanhappy/mcphub
```
> 注意首次运行时MCPHub 会自动下载并安装所需的依赖包,可能需要一些时间。
### 访问控制台
启动后访问 `http://localhost:3000` 即可进入控制台。
> 默认登录用户名和密码为 `admin`/`admin123`,登录后可以修改密码以确保安全。
控制台提供了服务器管理、分组管理和市场管理等功能,你可以在这里查看所有已安装的 MCP 服务器、创建新的分组、添加或删除服务器等。
### 分组路由 & SSE 端点
#### 全局 SSE 端点
```
http://localhost:3000/sse
```
通过全局 SSE 端点可以访问所有已启用的 MCP 服务器。
#### 基于分组的 SSE 端点
除了全局 SSE 端点MCPHub 还支持基于分组的 SSE 端点。你可以为每个分组创建独立的 SSE 端点,以便更好地管理和路由请求。
分组的 SSE 端点格式如下:
```
http://localhost:3000/sse/{groupId}
```
其中 `{groupId}` 是分组的唯一标识符,可以从控制台获取。比如我在上面的截图中创建了一个名为 `map` 的分组,选择了 `amap``sequential-thinking` 两个服务器,那么可以通过以下 URL 访问这个分组的 SSE 端点:
```
http://localhost:3000/sse/a800bef7-c4c1-4460-9557-5f4404cdd0bd
```
#### 使用分组路由
创建了路由分组后,我们就可以在任意支持 MCP 的客户端中使用这个分组的 SSE 端点了。比如在 `Cursor` 中,我们可以在配置文件中指定分组的 SSE 端点:
```json
{
"mcpServers": {
"mcphub": {
"url": "http://localhost:3000/sse/a800bef7-c4c1-4460-9557-5f4404cdd0bd"
}
}
}
```
配置完成后,可以从 `Cursor` 中看到所有可用的 MCP 服务器工具列表。
![Cursor 中的 MCP 配置](../assets/cursor-mcp.png)
然后,我们可以测试一下,比如输入:深度思考一下,帮我制定一个五一假期从南京出发的自驾行出游计划,要求避开拥堵路线,结合天气情况,并且可以体验到不同的自然风光。
![Cursor 中的测试输入](../assets/cursor-query.png)
接着可以看到,`Cursor` 在运行过程中调用了多个工具。
![Cursor 中的工具调用](../assets/cursor-tools.png)
最终生成结果如下:
```markdown
基于对路线和天气的全面分析,我为你制定了一个四天的五一自驾游行程方案:
### 第一天4月29日南京→黄山
- 出发时间建议早上8点出发
- 行驶路线G42沪蓉高速 → S11巢黄高速
- 行驶时间约4.5小时282公里
- 住宿地点:黄山风景区附近
- 特别提醒:
* 路线多隧道,注意安全
* 天气较好,适合出行
* 建议提前订好黄山景区附近酒店
### 第二天4月30日黄山→婺源
- 游览时间:上午游览黄山景区
- 下午出发前往婺源
- 行驶路线G3京台高速 → G56杭瑞高速
- 行驶时间约2.5小时139公里
- 住宿地点:婺源县城或特色古村落
- 特别提醒:
* 注意天气可能有阵雨
* 建议游览篁岭、李坑等著名古村落
### 第三天5月1日婺源→景德镇
- 上午游览婺源景点
- 中午后出发前往景德镇
- 行驶路线G56杭瑞高速
- 行驶时间约1.5小时77公里
- 住宿地点:景德镇市区
- 特别提醒:
* 可能遇到阵雨天气
* 建议参观陶瓷博物馆和古窑址
### 第四天5月2日景德镇→南京
- 建议上午游览景德镇景点
- 中午后出发返回南京
- 行驶路线G35济广高速 → G4211宁芜高速
- 行驶时间约5小时429公里
- 特别提醒:
* 路程较长,建议做好休息安排
* 注意途中加油站分布
* 建议错峰返程,避免拥堵
### 整体建议:
1. 避堵建议:
- 选择错峰出行时间
- 提前查看实时路况
- 准备备选绕行路线
2. 安全建议:
- 全程多雨,注意雨天行车安全
- 保持车距,谨慎驾驶
- 途经隧道较多,注意灯光使用
3. 行程准备:
- 提前预订住宿
- 准备雨具和应急用品
- 建议下载离线地图
- 检查车况,特别是雨刮和轮胎
4. 景点安排:
- 黄山:建议游览迎客松、光明顶等
- 婺源:篁岭、李坑、江岭等
- 景德镇:陶瓷博物馆、古窑民俗博览区
这条路线可以让你体验到:
- 黄山的壮丽山景
- 婺源的田园风光
- 景德镇的人文历史
既避开了主要拥堵路段,又能欣赏到不同的自然风光。
```
可以看到,`Cursor` 通过调用 `amap``sequential-thinking` 两个服务器,成功生成了一个五一假期的自驾游行程方案,并且避开了拥堵路线,结合了天气情况。但是细心的同学可能发现,计划中的开始时间是 4 月 29 日,而今年的五一假期是 5 月 1 日开始的,产生偏差的原因是 `sequential-thinking` 使用了错误的假期时间。如何解决这个问题呢?我们可以尝试在分组中添加支持搜索的 MCP 服务器,这样就可以在查询时自动纠正错误的假期时间了,具体就不在这里展开了。
## 结语
MCPHub 将本地部署、一键安装、分组路由和可视化管理融为一体,以简洁而强大的设计,彻底解决了 MCP 服务器的部署、配置与运维难题。无论是追求快速验证的开发者,还是需要稳定可靠 AI 工具链的企业用户,都能通过 MCPHub 专注于核心业务与创新,而无需被底层细节所困扰。
尽管目前各家平台都在陆续推出各类 MCP 云服务但在数据隐私、合规性和定制化需求日益增长的背景下MCPHub 仍然是一个值得关注的本地部署解决方案​。
MCPHub 只是我一时兴起开发的小项目,没想到竟收获了这么多关注,非常感谢大家的支持!目前 MCPHub 还有不少地方需要优化和完善我也专门建了个交流群方便大家交流反馈。如果你也对这个项目感兴趣欢迎一起参与建设项目地址为https://github.com/samanhappy/mcphub。
![企业微信交流群](../assets/wegroup.jpg)

177
articals/smart-routing.md Normal file
View File

@@ -0,0 +1,177 @@
# 无限工具智能路由MCPHub 引领 AI 工具使用新范式
## 概述
在现代 AI 应用中,随着 MCP 服务器数量的快速增长和工具种类的不断丰富,如何从数百个可用工具中快速定位最适合当前任务的工具,成为开发者和 AI 助手面临的一项重要挑战。
传统做法要么将所有工具暴露给 AI 助手处理,导致 token 消耗巨大、响应延迟严重;要么依赖开发者手动分组配置,灵活性和智能性不足。
MCPHub 推出的智能路由功能,基于向量语义搜索技术,实现了自然语言驱动的工具发现与精准推荐。它让 AI 助手能够像人类专家一样,根据任务描述自动选择最优工具组合,大幅提升了系统效率和用户体验。
## 什么是智能路由
### 技术原理
智能路由是 MCPHub 的核心功能之一。它将每个 MCP 工具的名称和描述嵌入为高维语义向量。当用户发起自然语言任务请求时,系统会将该请求也转换为向量,通过计算相似度,快速返回最相关的工具列表。
这一过程摒弃了传统的关键词匹配,具备更强的语义理解能力,能够处理自然语言的模糊性和多样性。
### 核心组件
- **向量嵌入引擎**:支持如 `text-embedding-3-small``bge-m3` 等主流模型,将文本描述转为语义向量。
- **PostgreSQL + pgvector**:使用开源向量数据库方案,支持高效的向量索引和搜索。
- **两步工作流分离**
- `search_tools`:负责语义工具发现
- `call_tool`:执行实际工具调用逻辑
## 为什么需要智能路由
### 1. 减少认知负荷
- 当工具数量超过 100 个AI 模型难以处理所有工具上下文。
- 智能路由通过语义压缩,将候选工具缩小至 510 个,提高决策效率。
### 2. 显著降低 token 消耗
- 传统做法传入全量工具描述,可能消耗上千 token。
- 使用智能路由,通常可将 token 使用降低 7090%。
### 3. 提升调用准确率
- 理解任务语义:如“图片增强”→选择图像处理工具,而不是依赖命名关键词。
- 上下文感知:考虑输入/输出格式和工具组合能力,匹配更合理的执行链路。
## 智能路由配置指南
### 1. 启动支持 `pgvector` 的 PostgreSQL 数据库
```bash
docker run --name mcphub-postgres \
-e POSTGRES_DB=mcphub \
-e POSTGRES_USER=mcphub \
-e POSTGRES_PASSWORD=your_password \
-p 5432:5432 \
-d pgvector/pgvector:pg17
```
如已部署 PostgreSQL可直接创建数据库并启用 `pgvector` 扩展:
```sql
CREATE DATABASE mcphub;
CREATE EXTENSION vector;
```
### 2. 获取 embedding 模型的 API Key
前往 OpenAI 或其他提供商获取嵌入模型的 API Key。国内用户推荐使用硅基流动 `bge-m3` 免费模型,没有注册过的用户可以使用我的邀请链接:[https://cloud.siliconflow.cn/i/TQhVYBvA](https://cloud.siliconflow.cn/i/TQhVYBvA)。
### 3. 控制台配置
![配置](./assets/sr-conf.png)
在 MCPHub 控制台中,进入「智能路由」配置页面,填写以下信息:
- **数据库 URL**`postgresql://mcphub:your_password@localhost:5432/mcphub`
- **OpenAI API Key** :填写你获取的嵌入模型 API Key
- **OpenAI 基础 URL**`https://api.siliconflow.cn/v1`
- **嵌入模型**:推荐使用 `BAAI/bge-m3`
开启「启用智能路由」后系统会自动:
- 对所有工具生成向量嵌入
- 构建向量索引
- 自动监听新增工具,更新索引
## 工具定义
### search_tools - 工具搜索
```ts
{
"name": "search_tools",
"arguments": {
"query": "help me resize and convert images",
"limit": 10
}
}
```
### call_tool - 工具执行
```ts
{
"name": "call_tool",
"arguments": {
"toolName": "image_resizer",
"arguments": {
"input_path": "/path/to/image.png",
"width": 800,
"height": 600
}
}
}
```
## 演示
下面我将通过几个示例来展示如何使用智能路由。
首先,我们需要在 mcphub 添加几个不同类型的 MCP 服务器:`amap``time-map``fetch`
![添加服务器](./assets/sr-servers.png)
然后我们需要选择一个支持 MCP 的客户端,这里选择国产的 DeepChat聊天模型选择 `Qwen3-14B`
接着,在 DeepChat 中添加 mcphub 的智能路由端点:
![添加智能路由](./assets/sr-dc.png)
添加成功后,就可以在工具中看到 `search_tools``call_tool` 两个工具了:
![工具列表](./assets/sr-tools.png)
### 示例 1地图导航
输入:从北京如何导航到上海。
结果:
![地图导航](./assets/sr-map-result.png)
可以看到DeepChat 先调用了 `search_tools` 工具:
![搜索工具](./assets/sr-map-search.png)
然后再调用 `call_tool` 查询具体的导航信息:
![调用工具](./assets/sr-map-call.png)
### 示例 2查询时间
输入:使用工具查询美国现在的时间是几点
结果:
![查询时间](./assets/sr-time.png)
需要说明的是,由于不同的模型对工具调用的支持程度不同,可能会出现一些差异。比如在这个例子中,为了提高准确性,我在输入中明确提到了“使用工具”。
### 示例 3查看网页
输入:打开 baidu.com 看看有什么
结果:
![查看网页](./assets/sr-web.png)
可以看到DeepChat 成功调用了工具,不过由于百度的 robots.txt 限制,无法获取到具体内容。
## 结语
借助 MCPHub 的智能路由功能AI 助手能够更高效地处理复杂任务,显著减少不必要的 token 消耗,同时提升工具调用的准确性与灵活性。作为面向未来的 AI 工具发现与调用基础设施,智能路由不仅使 AI 更聪明地选择和组合工具,还为多 Agent 协同提供了清晰、可控且可扩展的底层能力支撑。
> MCPHub 只是我一时兴起开发的小项目,没想到收获了这么多关注,非常感谢大家的支持!目前 MCPHub 还有不少地方需要优化和完善,我也专门建了个交流群,感兴趣的可以添加下面的微信。
![微信](../assets/wexin.png)
> 同时,欢迎大家一起参与建设!项目地址为:[https://github.com/samanhappy/mcphub](https://github.com/samanhappy/mcphub)。

BIN
assets/cursor-mcp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
assets/cursor-query.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/cursor-tools.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

BIN
assets/market.zh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
assets/reward.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
assets/smart-routing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
assets/smart-routing.zh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
assets/wegroup.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
assets/wexin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

98
bin/cli.js Executable file
View File

@@ -0,0 +1,98 @@
#!/usr/bin/env node
import path from 'path';
import { fileURLToPath, pathToFileURL } from 'url';
import fs from 'fs';
// Enable debug logging if needed
// process.env.DEBUG = 'true';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Start with more debug information
console.log('📋 MCPHub CLI');
console.log(`📁 CLI script location: ${__dirname}`);
// The npm package directory structure when installed is:
// node_modules/@samanhappy/mcphub/
// - dist/
// - bin/
// - frontend/dist/
// Get the package root - this is where package.json is located
function findPackageRoot() {
const isDebug = process.env.DEBUG === 'true';
// Possible locations for package.json
const possibleRoots = [
// Standard npm package location
path.resolve(__dirname, '..'),
// When installed via npx
path.resolve(__dirname, '..', '..', '..')
];
// Special handling for npx
if (process.argv[1] && process.argv[1].includes('_npx')) {
const npxDir = path.dirname(process.argv[1]);
possibleRoots.unshift(path.resolve(npxDir, '..'));
}
if (isDebug) {
console.log('DEBUG: Checking for package.json in:', possibleRoots);
}
for (const root of possibleRoots) {
const packageJsonPath = path.join(root, 'package.json');
if (fs.existsSync(packageJsonPath)) {
try {
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
if (pkg.name === 'mcphub' || pkg.name === '@samanhappy/mcphub') {
if (isDebug) {
console.log(`DEBUG: Found package.json at ${packageJsonPath}`);
}
return root;
}
} catch (e) {
// Continue to the next potential root
}
}
}
console.log('⚠️ Could not find package.json, using default path');
return path.resolve(__dirname, '..');
}
// Locate and check the frontend distribution
function checkFrontend(packageRoot) {
const isDebug = process.env.DEBUG === 'true';
const frontendDistPath = path.join(packageRoot, 'frontend', 'dist');
if (isDebug) {
console.log(`DEBUG: Checking frontend at: ${frontendDistPath}`);
}
if (fs.existsSync(frontendDistPath) && fs.existsSync(path.join(frontendDistPath, 'index.html'))) {
console.log('✅ Frontend distribution found');
return true;
} else {
console.log('⚠️ Frontend distribution not found at', frontendDistPath);
return false;
}
}
const projectRoot = findPackageRoot();
console.log(`📦 Using package root: ${projectRoot}`);
// Check if frontend exists
checkFrontend(projectRoot);
// Start the server
console.log('🚀 Starting MCPHub server...');
const entryPath = path.join(projectRoot, 'dist', 'index.js');
// Convert to file:// URL for cross-platform ESM compatibility (required on Windows)
const entryUrl = pathToFileURL(entryPath).href;
import(entryUrl).catch(err => {
console.error('Failed to start MCPHub:', err);
process.exit(1);
});

60
docker-compose.db.yml Normal file
View File

@@ -0,0 +1,60 @@
version: "3.8"
services:
# PostgreSQL database for MCPHub configuration
postgres:
image: postgres:16-alpine
container_name: mcphub-postgres
environment:
POSTGRES_DB: mcphub
POSTGRES_USER: mcphub
POSTGRES_PASSWORD: ${DB_PASSWORD:-mcphub_password}
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "${DB_PORT:-5432}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mcphub"]
interval: 10s
timeout: 5s
retries: 5
networks:
- mcphub-network
# MCPHub application
mcphub:
image: samanhappy/mcphub:latest
container_name: mcphub
environment:
# Database connection (setting DB_URL automatically enables database mode)
DB_URL: "postgresql://mcphub:${DB_PASSWORD:-mcphub_password}@postgres:5432/mcphub"
# Optional: Explicitly control database mode (overrides auto-detection)
# USE_DB: "true"
# Application settings
PORT: 3000
NODE_ENV: production
# Optional: Custom npm registry
# NPM_REGISTRY: https://registry.npmjs.org/
# Optional: Proxy settings
# HTTP_PROXY: http://proxy:8080
# HTTPS_PROXY: http://proxy:8080
ports:
- "${MCPHUB_PORT:-3000}:3000"
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
networks:
- mcphub-network
volumes:
pgdata:
driver: local
networks:
mcphub-network:
driver: bridge

32
docs/README.md Normal file
View File

@@ -0,0 +1,32 @@
# Mintlify Starter Kit
Click on `Use this template` to copy the Mintlify starter kit. The starter kit contains examples including
- Guide pages
- Navigation
- Customizations
- API Reference pages
- Use of popular components
### Development
Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command
```
npm i -g mintlify
```
Run the following command at the root of your documentation (where docs.json is)
```
mintlify dev
```
### Publishing Changes
Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
#### Troubleshooting
- Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies.
- Page loads as a 404 - Make sure you are running in a folder with `docs.json`

147
docs/api-reference/auth.mdx Normal file
View File

@@ -0,0 +1,147 @@
---
title: "Authentication"
description: "Manage users and authentication."
---
import { Card, Cards } from 'mintlify';
<Card
title="POST /api/auth/login"
href="#login"
>
Log in to get a JWT token.
</Card>
<Card
title="POST /api/auth/register"
href="#register"
>
Register a new user.
</Card>
<Card
title="GET /api/auth/user"
href="#get-current-user"
>
Get the currently authenticated user.
</Card>
<Card
title="POST /api/auth/change-password"
href="#change-password"
>
Change the password for the current user.
</Card>
---
### Login
Authenticates a user and returns a JWT token along with user details.
- **Endpoint**: `/api/auth/login`
- **Method**: `POST`
- **Body**:
- `username` (string, required): The user's username.
- `password` (string, required): The user's password.
- **Request Example**:
```json
{
"username": "admin",
"password": "admin123"
}
```
- **Success Response**:
```json
{
"success": true,
"message": "Login successful",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"username": "admin",
"isAdmin": true,
"permissions": { ... }
}
}
```
---
### Register
Registers a new user and returns a JWT token.
- **Endpoint**: `/api/auth/register`
- **Method**: `POST`
- **Body**:
- `username` (string, required): The desired username.
- `password` (string, required): The desired password (must be at least 6 characters).
- `isAdmin` (boolean, optional): Whether the user should have admin privileges.
- **Request Example**:
```json
{
"username": "newuser",
"password": "password123",
"isAdmin": false
}
```
- **Success Response**:
```json
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"username": "newuser",
"isAdmin": false,
"permissions": { ... }
}
}
```
---
### Get Current User
Retrieves the profile of the currently authenticated user.
- **Endpoint**: `/api/auth/user`
- **Method**: `GET`
- **Authentication**: Bearer Token required.
- **Success Response**:
```json
{
"success": true,
"user": {
"username": "admin",
"isAdmin": true,
"permissions": { ... }
}
}
```
---
### Change Password
Allows the authenticated user to change their password.
- **Endpoint**: `/api/auth/change-password`
- **Method**: `POST`
- **Authentication**: Bearer Token required.
- **Body**:
- `currentPassword` (string, required): The user's current password.
- `newPassword` (string, required): The desired new password (must be at least 6 characters).
- **Request Example**:
```json
{
"currentPassword": "oldpassword",
"newPassword": "newpassword123"
}
```
- **Success Response**:
```json
{
"success": true,
"message": "Password updated successfully"
}
```

View File

@@ -0,0 +1,111 @@
---
title: "Config"
description: "Manage and retrieve system-wide configurations."
---
import { Card, Cards } from 'mintlify';
<Card title="PUT /api/system-config" href="#update-system-config">Update the main system configuration.</Card>
<Card title="GET /api/settings" href="#get-all-settings">Get all system settings, including servers and groups.</Card>
<Card title="GET /config" href="#get-runtime-config">Get public runtime configuration for the frontend.</Card>
<Card title="GET /public-config" href="#get-public-config">Get public configuration to check for auth skip.</Card>
---
### Update System Config
Updates various parts of the system configuration. You only need to provide the keys for the sections you want to update.
- **Endpoint**: `/api/system-config`
- **Method**: `PUT`
- **Body**: A JSON object containing one or more of the following top-level keys: `routing`, `install`, `smartRouting`, `mcpRouter`.
#### Routing Configuration (`routing`)
- `enableGlobalRoute` (boolean): Enable or disable the global `/api/mcp` route.
- `enableGroupNameRoute` (boolean): Enable or disable group-based routing (e.g., `/api/mcp/group/:groupName`).
- `enableBearerAuth` (boolean): Enable bearer token authentication for MCP routes.
- `bearerAuthKey` (string): The secret key to use for bearer authentication.
- `skipAuth` (boolean): If true, skips all authentication, making the instance public.
#### Install Configuration (`install`)
- `pythonIndexUrl` (string): The base URL of the Python Package Index (PyPI) to use for installations.
- `npmRegistry` (string): The URL of the npm registry to use for installations.
- `baseUrl` (string): The public base URL of this MCPHub instance.
#### Smart Routing Configuration (`smartRouting`)
- `enabled` (boolean): Enable or disable the Smart Routing feature.
- `dbUrl` (string): The database connection URL for storing embeddings.
- `openaiApiBaseUrl` (string): The base URL for the OpenAI-compatible API for generating embeddings.
- `openaiApiKey` (string): The API key for the embeddings service.
- `openaiApiEmbeddingModel` (string): The name of the embedding model to use.
#### MCP Router Configuration (`mcpRouter`)
- `apiKey` (string): The API key for the MCP Router service.
- `referer` (string): The referer header to use for MCP Router requests.
- `title` (string): The title to display for this instance on MCP Router.
- `baseUrl` (string): The base URL for the MCP Router API.
- **Request Example**:
```json
{
"routing": {
"skipAuth": true
},
"smartRouting": {
"enabled": true,
"dbUrl": "postgresql://user:pass@host:port/db"
}
}
```
---
### Get All Settings
Retrieves the entire settings object for the instance, including all server configurations, groups, and system settings. This is a comprehensive dump of the `mcp_settings.json` file.
- **Endpoint**: `/api/settings`
- **Method**: `GET`
---
### Get Runtime Config
Retrieves the essential runtime configuration required for the frontend application. This endpoint does not require authentication.
- **Endpoint**: `/config`
- **Method**: `GET`
- **Success Response**:
```json
{
"success": true,
"data": {
"basePath": "",
"version": "1.0.0",
"name": "MCPHub"
}
}
```
---
### Get Public Config
Retrieves public configuration, primarily to check if authentication is skipped. This allows the frontend to adjust its behavior accordingly before a user has logged in. This endpoint does not require authentication.
- **Endpoint**: `/public-config`
- **Method**: `GET`
- **Success Response**:
```json
{
"success": true,
"data": {
"skipAuth": false,
"permissions": {}
}
}
```

View File

@@ -0,0 +1,212 @@
---
title: "Groups"
description: "Manage server groups to organize and route requests."
---
import { Card, Cards } from 'mintlify';
<Card title="GET /api/groups" href="#get-all-groups">Get a list of all groups.</Card>
<Card title="POST /api/groups" href="#create-a-new-group">Create a new group.</Card>
<Card title="GET /api/groups/:id" href="#get-a-group">Get details of a specific group.</Card>
<Card title="PUT /api/groups/:id" href="#update-a-group">Update an existing group.</Card>
<Card title="DELETE /api/groups/:id" href="#delete-a-group">Delete a group.</Card>
<Card title="POST /api/groups/:id/servers" href="#add-server-to-group">Add a server to a group.</Card>
<Card title="DELETE /api/groups/:id/servers/:serverName" href="#remove-server-from-group">Remove a server from a group.</Card>
<Card title="PUT /api/groups/:id/servers/batch" href="#batch-update-group-servers">Batch update servers in a group.</Card>
<Card title="GET /api/groups/:id/server-configs" href="#get-group-server-configs">Get detailed server configurations in a group.</Card>
<Card title="PUT /api/groups/:id/server-configs/:serverName/tools" href="#update-group-server-tools">Update tool selection for a server in a group.</Card>
---
### Get All Groups
Retrieves a list of all server groups.
- **Endpoint**: `/api/groups`
- **Method**: `GET`
- **Success Response**:
```json
{
"success": true,
"data": [
{
"id": "group-1",
"name": "My Group",
"description": "A collection of servers.",
"servers": ["server1", "server2"],
"owner": "admin"
}
]
}
```
---
### Create a New Group
Creates a new server group.
- **Endpoint**: `/api/groups`
- **Method**: `POST`
- **Body**:
- `name` (string, required): The name of the group.
- `description` (string, optional): A description for the group.
- `servers` (array of strings, optional): A list of server names to include in the group.
- **Request Example**:
```json
{
"name": "My New Group",
"description": "A description for the new group",
"servers": ["server1", "server2"]
}
```
---
### Get a Group
Retrieves details for a specific group by its ID or name.
- **Endpoint**: `/api/groups/:id`
- **Method**: `GET`
- **Parameters**:
- `:id` (string, required): The ID or name of the group.
---
### Update a Group
Updates an existing group's name, description, or server list.
- **Endpoint**: `/api/groups/:id`
- **Method**: `PUT`
- **Parameters**:
- `:id` (string, required): The ID or name of the group to update.
- **Body**:
- `name` (string, optional): The new name for the group.
- `description` (string, optional): The new description for the group.
- `servers` (array, optional): The new list of servers for the group. See [Batch Update Group Servers](#batch-update-group-servers) for format.
- **Request Example**:
```json
{
"name": "Updated Group Name",
"description": "Updated description"
}
```
---
### Delete a Group
Deletes a group by its ID or name.
- **Endpoint**: `/api/groups/:id`
- **Method**: `DELETE`
- **Parameters**:
- `:id` (string, required): The ID or name of the group to delete.
---
### Add Server to Group
Adds a single server to a group.
- **Endpoint**: `/api/groups/:id/servers`
- **Method**: `POST`
- **Parameters**:
- `:id` (string, required): The ID or name of the group.
- **Body**:
- `serverName` (string, required): The name of the server to add.
- **Request Example**:
```json
{
"serverName": "my-server"
}
```
---
### Remove Server from Group
Removes a single server from a group.
- **Endpoint**: `/api/groups/:id/servers/:serverName`
- **Method**: `DELETE`
- **Parameters**:
- `:id` (string, required): The ID or name of the group.
- `:serverName` (string, required): The name of the server to remove.
---
### Batch Update Group Servers
Replaces all servers in a group with a new list. The list can be simple strings or detailed configuration objects.
- **Endpoint**: `/api/groups/:id/servers/batch`
- **Method**: `PUT`
- **Parameters**:
- `:id` (string, required): The ID or name of the group.
- **Body**:
- `servers` (array, required): An array of server names (strings) or server configuration objects.
- **Request Example (Simple)**:
```json
{
"servers": ["server1", "server2"]
}
```
- **Request Example (Detailed)**:
```json
{
"servers": [
{ "name": "server1", "tools": "all" },
{ "name": "server2", "tools": ["toolA", "toolB"] }
]
}
```
---
### Get Group Server Configs
Retrieves the detailed configuration for all servers within a group, including which tools are enabled.
- **Endpoint**: `/api/groups/:id/server-configs`
- **Method**: `GET`
- **Parameters**:
- `:id` (string, required): The ID or name of the group.
- **Success Response**:
```json
{
"success": true,
"data": [
{
"name": "server1",
"tools": "all"
},
{
"name": "server2",
"tools": ["toolA", "toolB"]
}
]
}
```
---
### Update Group Server Tools
Updates the tool selection for a specific server within a group.
- **Endpoint**: `/api/groups/:id/server-configs/:serverName/tools`
- **Method**: `PUT`
- **Parameters**:
- `:id` (string, required): The ID or name of the group.
- `:serverName` (string, required): The name of the server to update.
- **Body**:
- `tools` (string or array of strings, required): Either the string `"all"` to enable all tools, or an array of tool names to enable specifically.
- **Request Example**:
```json
{
"tools": ["toolA", "toolC"]
}
```

View File

@@ -0,0 +1,13 @@
---
title: "Introduction"
description: "Welcome to the MCPHub API documentation."
---
The MCPHub API provides a comprehensive set of endpoints to manage your MCP servers, groups, users, and more. The API is divided into two main categories:
- **MCP Endpoints**: These are the primary endpoints for interacting with your MCP servers. They provide a unified interface for sending requests to your servers and receiving responses in real-time.
- **Management API**: These endpoints are used for managing the MCPHub instance itself. This includes managing servers, groups, users, and system settings.
All API endpoints are available under the `/api` path. For example, the endpoint to get all servers is `/api/servers`.
Authentication is required for most Management API endpoints. See the [Authentication](/api-reference/auth) section for more details.

View File

@@ -0,0 +1,81 @@
---
title: "Logs"
description: "Access and manage server logs."
---
import { Card, Cards } from 'mintlify';
<Card
title="GET /api/logs"
href="#get-all-logs"
>
Get all logs.
</Card>
<Card
title="DELETE /api/logs"
href="#clear-logs"
>
Clear all logs.
</Card>
<Card
title="GET /api/logs/stream"
href="#stream-logs"
>
Stream logs in real-time.
</Card>
---
### Get All Logs
Retrieves all stored logs.
- **Endpoint**: `/api/logs`
- **Method**: `GET`
- **Success Response**:
```json
{
"success": true,
"data": [
{
"timestamp": "2023-10-27T10:00:00.000Z",
"level": "info",
"message": "Server started successfully.",
"service": "system"
}
]
}
```
---
### Clear Logs
Deletes all stored logs.
- **Endpoint**: `/api/logs`
- **Method**: `DELETE`
- **Success Response**:
```json
{
"success": true,
"message": "Logs cleared successfully"
}
```
---
### Stream Logs
Streams logs in real-time using Server-Sent Events (SSE). The connection will remain open, and new log entries will be sent as they occur.
- **Endpoint**: `/api/logs/stream`
- **Method**: `GET`
- **Response Format**: The stream sends events with a `data` field containing a JSON object. The first event has `type: 'initial'` and contains all historical logs. Subsequent events have `type: 'log'` and contain a single new log entry.
- **Example Event**:
```
data: {"type":"log","log":{"timestamp":"2023-10-27T10:00:05.000Z","level":"debug","message":"Processing request for /api/some-endpoint","service":"mcp-server"}}
```

View File

@@ -0,0 +1,33 @@
---
title: "MCP HTTP Endpoints"
description: "Connect to your MCP servers using the unified HTTP endpoint."
---
MCPHub provides a unified streamable HTTP interface for all your MCP servers. This allows you to send requests to any configured MCP server and receive responses in real-time.
### Unified Endpoint
This endpoint provides access to all enabled MCP servers.
- **Endpoint**: `http://localhost:3000/mcp`
- **Method**: `POST`
### Group-Specific Endpoint
For targeted access to specific server groups, use the group-based HTTP endpoint.
- **Endpoint**: `http://localhost:3000/mcp/{group}`
- **Method**: `POST`
- **Parameters**:
- `{group}`: The ID or name of the group.
### Server-Specific Endpoint
For direct access to individual servers, use the server-specific HTTP endpoint.
- **Endpoint**: `http://localhost:3000/mcp/{server}`
- **Method**: `POST`
- **Parameters**:
- `{server}`: The name of the server.
> **Note**: If a server name and group name are the same, the group will take precedence.

View File

@@ -0,0 +1,25 @@
---
title: "MCP SSE Endpoints (Deprecated)"
description: "Connect to your MCP servers using the SSE endpoint."
---
The SSE endpoint is deprecated and will be removed in a future version. Please use the [MCP HTTP Endpoints](/api-reference/mcp-http) instead.
### Unified Endpoint
- **Endpoint**: `http://localhost:3000/sse`
- **Method**: `GET`
### Group-Specific Endpoint
- **Endpoint**: `http://localhost:3000/sse/{group}`
- **Method**: `GET`
- **Parameters**:
- `{group}`: The ID or name of the group.
### Server-Specific Endpoint
- **Endpoint**: `http://localhost:3000/sse/{server}`
- **Method**: `GET`
- **Parameters**:
- `{server}`: The name of the server.

View File

@@ -0,0 +1,217 @@
{
"openapi": "3.1.0",
"info": {
"title": "OpenAPI Plant Store",
"description": "A sample API that uses a plant store as an example to demonstrate features in the OpenAPI specification",
"license": {
"name": "MIT"
},
"version": "1.0.0"
},
"servers": [
{
"url": "http://sandbox.mintlify.com"
}
],
"security": [
{
"bearerAuth": []
}
],
"paths": {
"/plants": {
"get": {
"description": "Returns all plants from the system that the user has access to",
"parameters": [
{
"name": "limit",
"in": "query",
"description": "The maximum number of results to return",
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "Plant response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Plant"
}
}
}
}
},
"400": {
"description": "Unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"description": "Creates a new plant in the store",
"requestBody": {
"description": "Plant to add to the store",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewPlant"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "plant response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Plant"
}
}
}
},
"400": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/plants/{id}": {
"delete": {
"description": "Deletes a single plant based on the ID supplied",
"parameters": [
{
"name": "id",
"in": "path",
"description": "ID of plant to delete",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"204": {
"description": "Plant deleted",
"content": {}
},
"400": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
}
},
"webhooks": {
"/plant/webhook": {
"post": {
"description": "Information about a new plant added to the store",
"requestBody": {
"description": "Plant added to the store",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewPlant"
}
}
}
},
"responses": {
"200": {
"description": "Return a 200 status to indicate that the data was received successfully"
}
}
}
}
},
"components": {
"schemas": {
"Plant": {
"required": [
"name"
],
"type": "object",
"properties": {
"name": {
"description": "The name of the plant",
"type": "string"
},
"tag": {
"description": "Tag to specify the type",
"type": "string"
}
}
},
"NewPlant": {
"allOf": [
{
"$ref": "#/components/schemas/Plant"
},
{
"required": [
"id"
],
"type": "object",
"properties": {
"id": {
"description": "Identification number of the plant",
"type": "integer",
"format": "int64"
}
}
}
]
},
"Error": {
"required": [
"error",
"message"
],
"type": "object",
"properties": {
"error": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
}
}
}
},
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer"
}
}
}
}

View File

@@ -0,0 +1,276 @@
---
title: "OpenAPI Integration"
description: "Generate OpenAPI specifications from MCP tools for seamless integration with OpenWebUI and other systems"
---
# OpenAPI Generation for OpenWebUI Integration
MCPHub now supports generating OpenAPI 3.0.3 specifications from MCP tools, enabling seamless integration with OpenWebUI and other OpenAPI-compatible systems without requiring MCPO as an intermediary proxy.
## Features
- ✅ **Automatic OpenAPI Generation**: Converts MCP tools to OpenAPI 3.0.3 specification
- ✅ **OpenWebUI Compatible**: Direct integration without MCPO proxy
- ✅ **Real-time Tool Discovery**: Dynamically includes tools from connected MCP servers
- ✅ **Dual Parameter Support**: Supports both GET (query params) and POST (JSON body) for tool execution
- ✅ **No Authentication Required**: OpenAPI endpoints are public for easy integration
- ✅ **Comprehensive Metadata**: Full OpenAPI specification with proper schemas and documentation
## API Endpoints
### OpenAPI Specification
<CodeGroup>
```bash GET /api/openapi.json
curl "http://localhost:3000/api/openapi.json"
```
```bash With Parameters
curl "http://localhost:3000/api/openapi.json?title=My MCP API&version=2.0.0"
```
</CodeGroup>
Generates and returns the complete OpenAPI 3.0.3 specification for all connected MCP tools.
**Query Parameters:**
<ParamField query="title" type="string" optional>
Custom API title
</ParamField>
<ParamField query="description" type="string" optional>
Custom API description
</ParamField>
<ParamField query="version" type="string" optional>
Custom API version
</ParamField>
<ParamField query="serverUrl" type="string" optional>
Custom server URL
</ParamField>
<ParamField query="includeDisabled" type="boolean" optional default="false">
Include disabled tools
</ParamField>
<ParamField query="servers" type="string" optional>
Comma-separated list of server names to include
</ParamField>
### Group/Server-Specific OpenAPI Specification
<CodeGroup>
```bash GET /api/:name/openapi.json
curl "http://localhost:3000/api/mygroup/openapi.json"
```
```bash With Parameters
curl "http://localhost:3000/api/myserver/openapi.json?title=My Server API&version=1.0.0"
```
</CodeGroup>
Generates and returns the OpenAPI 3.0.3 specification for a specific group or server. If a group with the given name exists, it returns the specification for all servers in that group. Otherwise, it treats the name as a server name and returns the specification for that server only.
**Path Parameters:**
<ParamField path="name" type="string" required>
Group ID/name or server name
</ParamField>
**Query Parameters:**
Same as the main OpenAPI specification endpoint (title, description, version, serverUrl, includeDisabled).
### Available Servers
<CodeGroup>
```bash GET /api/openapi/servers
curl "http://localhost:3000/api/openapi/servers"
```
</CodeGroup>
Returns a list of connected MCP server names.
<ResponseExample>
```json Example Response
{
"success": true,
"data": ["amap", "playwright", "slack"]
}
```
</ResponseExample>
### Tool Statistics
<CodeGroup>
```bash GET /api/openapi/stats
curl "http://localhost:3000/api/openapi/stats"
```
</CodeGroup>
Returns statistics about available tools and servers.
<ResponseExample>
```json Example Response
{
"success": true,
"data": {
"totalServers": 3,
"totalTools": 41,
"serverBreakdown": [
{"name": "amap", "toolCount": 12, "status": "connected"},
{"name": "playwright", "toolCount": 21, "status": "connected"},
{"name": "slack", "toolCount": 8, "status": "connected"}
]
}
}
```
</ResponseExample>
### Tool Execution
<CodeGroup>
```bash GET /api/tools/{serverName}/{toolName}
curl "http://localhost:3000/api/tools/amap/amap-maps_weather?city=Beijing"
```
```bash POST /api/tools/{serverName}/{toolName}
curl -X POST "http://localhost:3000/api/tools/playwright/playwright-browser_navigate" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
```
</CodeGroup>
Execute MCP tools via OpenAPI-compatible endpoints.
**Path Parameters:**
<ParamField path="serverName" type="string" required>
The name of the MCP server
</ParamField>
<ParamField path="toolName" type="string" required>
The name of the tool to execute
</ParamField>
## OpenWebUI Integration
To integrate MCPHub with OpenWebUI:
<Steps>
<Step title="Start MCPHub">
Ensure MCPHub is running with your MCP servers configured
</Step>
<Step title="Get OpenAPI Specification">
```bash
curl http://localhost:3000/api/openapi.json > mcphub-api.json
```
</Step>
<Step title="Add to OpenWebUI">
Import the OpenAPI specification file or point to the URL directly in OpenWebUI
</Step>
</Steps>
### Configuration Example
In OpenWebUI, you can add MCPHub as an OpenAPI tool by using:
<CardGroup cols={2}>
<Card title="OpenAPI URL" icon="link">
`http://localhost:3000/api/openapi.json`
</Card>
<Card title="Base URL" icon="server">
`http://localhost:3000/api`
</Card>
</CardGroup>
## Generated OpenAPI Structure
The generated OpenAPI specification includes:
### Tool Conversion Logic
- **Simple tools** (≤10 primitive parameters) → GET endpoints with query parameters
- **Complex tools** (objects, arrays, or >10 parameters) → POST endpoints with JSON request body
- **All tools** include comprehensive response schemas and error handling
### Example Generated Operation
```yaml
/tools/amap/amap-maps_weather:
get:
summary: "根据城市名称或者标准adcode查询指定城市的天气"
operationId: "amap_amap-maps_weather"
tags: ["amap"]
parameters:
- name: city
in: query
required: true
description: "城市名称或者adcode"
schema:
type: string
responses:
'200':
description: "Successful tool execution"
content:
application/json:
schema:
$ref: '#/components/schemas/ToolResponse'
```
### Security
- Bearer authentication is defined but not enforced for tool execution endpoints
- Enables flexible integration with various OpenAPI-compatible systems
## Benefits over MCPO
<CardGroup cols={2}>
<Card title="Direct Integration" icon="plug">
No need for intermediate proxy
</Card>
<Card title="Real-time Updates" icon="refresh">
OpenAPI spec updates automatically as MCP servers connect/disconnect
</Card>
<Card title="Better Performance" icon="bolt">
Direct tool execution without proxy overhead
</Card>
<Card title="Simplified Architecture" icon="layer-group">
One less component to manage
</Card>
</CardGroup>
## Troubleshooting
<AccordionGroup>
<Accordion title="OpenAPI spec shows no tools">
Ensure MCP servers are connected. Check `/api/openapi/stats` for server status.
</Accordion>
<Accordion title="Tool execution fails">
Verify the tool name and parameters match the OpenAPI specification. Check server logs for details.
</Accordion>
<Accordion title="OpenWebUI can't connect">
Ensure MCPHub is accessible from OpenWebUI and the OpenAPI URL is correct.
</Accordion>
<Accordion title="Missing tools in specification">
Check if tools are enabled in your MCP server configuration. Use `includeDisabled=true` to see all tools.
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,142 @@
---
title: "Prompts"
description: "Manage and execute MCP prompts."
---
import { Card, Cards } from 'mintlify';
<Card
title="POST /api/mcp/:serverName/prompts/:promptName"
href="#get-a-prompt"
>
Execute a prompt on an MCP server.
</Card>
<Card
title="POST /api/servers/:serverName/prompts/:promptName/toggle"
href="#toggle-a-prompt"
>
Enable or disable a prompt.
</Card>
<Card
title="PUT /api/servers/:serverName/prompts/:promptName/description"
href="#update-prompt-description"
>
Update the description of a prompt.
</Card>
---
### Get a Prompt
Execute a prompt on an MCP server and get the result.
- **Endpoint**: `/api/mcp/:serverName/prompts/:promptName`
- **Method**: `POST`
- **Authentication**: Required
- **Parameters**:
- `:serverName` (string, required): The name of the MCP server.
- `:promptName` (string, required): The name of the prompt.
- **Body**:
```json
{
"arguments": {
"arg1": "value1",
"arg2": "value2"
}
}
```
- `arguments` (object, optional): Arguments to pass to the prompt.
- **Response**:
```json
{
"success": true,
"data": {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Prompt content"
}
}
]
}
}
```
**Example Request:**
```bash
curl -X POST "http://localhost:3000/api/mcp/myserver/prompts/code-review" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"arguments": {
"language": "typescript",
"code": "const x = 1;"
}
}'
```
---
### Toggle a Prompt
Enable or disable a specific prompt on a server.
- **Endpoint**: `/api/servers/:serverName/prompts/:promptName/toggle`
- **Method**: `POST`
- **Authentication**: Required
- **Parameters**:
- `:serverName` (string, required): The name of the server.
- `:promptName` (string, required): The name of the prompt.
- **Body**:
```json
{
"enabled": true
}
```
- `enabled` (boolean, required): `true` to enable the prompt, `false` to disable it.
**Example Request:**
```bash
curl -X POST "http://localhost:3000/api/servers/myserver/prompts/code-review/toggle" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"enabled": false}'
```
---
### Update Prompt Description
Update the description of a specific prompt.
- **Endpoint**: `/api/servers/:serverName/prompts/:promptName/description`
- **Method**: `PUT`
- **Authentication**: Required
- **Parameters**:
- `:serverName` (string, required): The name of the server.
- `:promptName` (string, required): The name of the prompt.
- **Body**:
```json
{
"description": "New prompt description"
}
```
- `description` (string, required): The new description for the prompt.
**Example Request:**
```bash
curl -X PUT "http://localhost:3000/api/servers/myserver/prompts/code-review/description" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"description": "Review code for best practices and potential issues"}'
```
**Note**: Prompts are templates that can be used to generate standardized requests to MCP servers. They are defined by the MCP server and can have arguments that are filled in when the prompt is executed.

View File

@@ -0,0 +1,265 @@
---
title: "Servers"
description: "Manage your MCP servers."
---
import { Card, Cards } from 'mintlify';
<Card
title="GET /api/servers"
href="#get-all-servers"
>
Get a list of all MCP servers.
</Card>
<Card
title="POST /api/servers"
href="#create-a-new-server"
>
Create a new MCP server.
</Card>
<Card
title="PUT /api/servers/:name"
href="#update-a-server"
>
Update an existing MCP server.
</Card>
<Card
title="DELETE /api/servers/:name"
href="#delete-a-server"
>
Delete an MCP server.
</Card>
<Card
title="POST /api/servers/:name/toggle"
href="#toggle-a-server"
>
Toggle the enabled state of a server.
</Card>
<Card
title="POST /api/servers/:serverName/tools/:toolName/toggle"
href="#toggle-a-tool"
>
Toggle the enabled state of a tool.
</Card>
<Card
title="PUT /api/servers/:serverName/tools/:toolName/description"
href="#update-tool-description"
>
Update the description of a tool.
</Card>
<Card
title="PUT /api/system-config"
href="#update-system-config"
>
Update system configuration settings.
</Card>
<Card
title="GET /api/settings"
href="#get-settings"
>
Get all server settings and configurations.
</Card>
---
### Get All Servers
Retrieves a list of all configured MCP servers, including their status and available tools.
- **Endpoint**: `/api/servers`
- **Method**: `GET`
- **Response**:
```json
{
"success": true,
"data": [
{
"name": "example-server",
"status": "connected",
"tools": [
{
"name": "tool1",
"description": "Description of tool 1"
}
],
"config": {
"type": "stdio",
"command": "node",
"args": ["server.js"]
}
}
]
}
```
---
### Create a New Server
Adds a new MCP server to the configuration.
- **Endpoint**: `/api/servers`
- **Method**: `POST`
- **Body**:
```json
{
"name": "my-new-server",
"config": {
"type": "stdio",
"command": "python",
"args": ["-u", "my_script.py"],
"owner": "admin"
}
}
```
- `name` (string, required): The unique name for the server.
- `config` (object, required): The server configuration object.
- `type` (string): `stdio`, `sse`, `streamable-http`, or `openapi`.
- `command` (string): Command to execute for `stdio` type.
- `args` (array of strings): Arguments for the command.
- `url` (string): URL for `sse`, `streamable-http`, or `openapi` types.
- `openapi` (object): OpenAPI configuration.
- `url` (string): URL to the OpenAPI schema.
- `schema` (object): The OpenAPI schema object itself.
- `headers` (object): Headers to send with requests for `sse`, `streamable-http`, and `openapi` types.
- `keepAliveInterval` (number): Keep-alive interval in milliseconds for `sse` type. Defaults to 60000.
- `owner` (string): The owner of the server. Defaults to the current user or 'admin'.
---
### Update a Server
Updates the configuration of an existing MCP server.
- **Endpoint**: `/api/servers/:name`
- **Method**: `PUT`
- **Parameters**:
- `:name` (string, required): The name of the server to update.
- **Body**:
```json
{
"config": {
"type": "stdio",
"command": "node",
"args": ["new_server.js"]
}
}
```
- `config` (object, required): The updated server configuration object. See "Create a New Server" for details.
---
### Delete a Server
Removes an MCP server from the configuration.
- **Endpoint**: `/api/servers/:name`
- **Method**: `DELETE`
- **Parameters**:
- `:name` (string, required): The name of the server to delete.
---
### Toggle a Server
Enables or disables an MCP server.
- **Endpoint**: `/api/servers/:name/toggle`
- **Method**: `POST`
- **Parameters**:
- `:name` (string, required): The name of the server to toggle.
- **Body**:
```json
{
"enabled": true
}
```
- `enabled` (boolean, required): `true` to enable the server, `false` to disable it.
---
### Toggle a Tool
Enables or disables a specific tool on a server.
- **Endpoint**: `/api/servers/:serverName/tools/:toolName/toggle`
- **Method**: `POST`
- **Parameters**:
- `:serverName` (string, required): The name of the server.
- `:toolName` (string, required): The name of the tool.
- **Body**:
```json
{
"enabled": true
}
```
- `enabled` (boolean, required): `true` to enable the tool, `false` to disable it.
---
### Update Tool Description
Updates the description of a specific tool.
- **Endpoint**: `/api/servers/:serverName/tools/:toolName/description`
- **Method**: `PUT`
- **Parameters**:
- `:serverName` (string, required): The name of the server.
- `:toolName` (string, required): The name of the tool.
- **Body**:
```json
{
"description": "New tool description"
}
```
- `description` (string, required): The new description for the tool.
---
### Update System Config
Updates the system-wide configuration settings.
- **Endpoint**: `/api/system-config`
- **Method**: `PUT`
- **Body**:
```json
{
"openaiApiKey": "sk-...",
"openaiBaseUrl": "https://api.openai.com/v1",
"modelName": "gpt-4",
"temperature": 0.7,
"maxTokens": 2048
}
```
- All fields are optional. Only provided fields will be updated.
---
### Get Settings
Retrieves all server settings and configurations.
- **Endpoint**: `/api/settings`
- **Method**: `GET`
- **Response**:
```json
{
"success": true,
"data": {
"servers": [...],
"groups": [...],
"systemConfig": {...}
}
}
```
**Note**: For detailed prompt management, see the [Prompts API](/api-reference/prompts) documentation.

View File

@@ -0,0 +1,29 @@
---
title: "Smart Routing"
description: "Intelligent tool discovery using vector semantic search."
---
Smart Routing is MCPHub's intelligent tool discovery system that uses vector semantic search to automatically find the most relevant tools for any given task.
### HTTP Endpoint
- **Endpoint**: `http://localhost:3000/mcp/$smart`
- **Method**: `POST`
### SSE Endpoint (Deprecated)
- **Endpoint**: `http://localhost:3000/sse/$smart`
- **Method**: `GET`
### How it Works
1. **Tool Indexing**: All MCP tools are automatically converted to vector embeddings and stored in PostgreSQL with pgvector.
2. **Semantic Search**: User queries are converted to vectors and matched against tool embeddings using cosine similarity.
3. **Intelligent Filtering**: Dynamic thresholds ensure relevant results without noise.
4. **Precise Execution**: Found tools can be directly executed with proper parameter validation.
### Setup Requirements
- PostgreSQL with pgvector extension
- OpenAI API key (or compatible embedding service)
- Enable Smart Routing in MCPHub settings

View File

@@ -0,0 +1,113 @@
---
title: "System"
description: "System and utility endpoints."
---
import { Card, Cards } from 'mintlify';
<Card
title="GET /health"
href="#health-check"
>
Check the health status of the MCPHub server.
</Card>
<Card
title="GET /oauth/callback"
href="#oauth-callback"
>
OAuth callback endpoint for authentication flows.
</Card>
<Card
title="POST /api/dxt/upload"
href="#upload-dxt-file"
>
Upload a DXT configuration file.
</Card>
<Card
title="GET /api/mcp-settings/export"
href="#export-mcp-settings"
>
Export MCP settings as JSON.
</Card>
---
### Health Check
Check the health status of the MCPHub server.
- **Endpoint**: `/health`
- **Method**: `GET`
- **Authentication**: Not required
- **Response**:
```json
{
"status": "ok",
"timestamp": "2024-11-12T01:30:00.000Z",
"uptime": 12345
}
```
**Example Request:**
```bash
curl "http://localhost:3000/health"
```
---
### OAuth Callback
OAuth callback endpoint for handling OAuth authentication flows. This endpoint is automatically called by OAuth providers after user authorization.
- **Endpoint**: `/oauth/callback`
- **Method**: `GET`
- **Authentication**: Not required (public callback URL)
- **Query Parameters**: Varies by OAuth provider (typically includes `code`, `state`, etc.)
**Note**: This endpoint is used internally by MCPHub's OAuth integration and should not be called directly by clients.
---
### Upload DXT File
Upload a DXT (Desktop Extension) configuration file to import server configurations.
- **Endpoint**: `/api/dxt/upload`
- **Method**: `POST`
- **Authentication**: Required
- **Content-Type**: `multipart/form-data`
- **Body**:
- `file` (file, required): The DXT configuration file to upload.
**Example Request:**
```bash
curl -X POST "http://localhost:3000/api/dxt/upload" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@config.dxt"
```
---
### Export MCP Settings
Export the current MCP settings configuration as a JSON file.
- **Endpoint**: `/api/mcp-settings/export`
- **Method**: `GET`
- **Authentication**: Required
- **Response**: Returns the `mcp_settings.json` configuration file.
**Example Request:**
```bash
curl "http://localhost:3000/api/mcp-settings/export" \
-H "Authorization: Bearer YOUR_TOKEN" \
-o mcp_settings.json
```
**Note**: This endpoint allows you to download a backup of your MCP settings, which can be used to restore or migrate your configuration.

View File

@@ -0,0 +1,86 @@
---
title: "Tools"
description: "Execute MCP tools programmatically."
---
import { Card, Cards } from 'mintlify';
<Card
title="POST /api/tools/call/:server"
href="#call-a-tool"
>
Call a specific tool on an MCP server.
</Card>
---
### Call a Tool
Execute a specific tool on an MCP server with given arguments.
- **Endpoint**: `/api/tools/call/:server`
- **Method**: `POST`
- **Parameters**:
- `:server` (string, required): The name of the MCP server.
- **Body**:
```json
{
"toolName": "tool-name",
"arguments": {
"param1": "value1",
"param2": "value2"
}
}
```
- `toolName` (string, required): The name of the tool to execute.
- `arguments` (object, optional): The arguments to pass to the tool. Defaults to an empty object.
- **Response**:
```json
{
"success": true,
"data": {
"content": [
{
"type": "text",
"text": "Tool execution result"
}
],
"toolName": "tool-name",
"arguments": {
"param1": "value1",
"param2": "value2"
}
}
}
```
**Example Request:**
```bash
curl -X POST "http://localhost:3000/api/tools/call/amap" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"toolName": "amap-maps_weather",
"arguments": {
"city": "Beijing"
}
}'
```
**Notes:**
- The tool arguments are automatically converted to the proper types based on the tool's input schema.
- Use the `x-session-id` header to maintain session state across multiple tool calls if needed.
- This endpoint requires authentication.
---
### Alternative: OpenAPI Tool Execution
For OpenAPI-compatible tool execution without authentication, see the [OpenAPI Integration](/api-reference/openapi#tool-execution) documentation. The OpenAPI endpoints provide:
- **GET** `/api/tools/:serverName/:toolName` - For simple tools with query parameters
- **POST** `/api/tools/:serverName/:toolName` - For complex tools with JSON body
These endpoints are designed for integration with OpenWebUI and other OpenAPI-compatible systems.

View File

@@ -0,0 +1,195 @@
---
title: "Users"
description: "Manage users in MCPHub."
---
import { Card, Cards } from 'mintlify';
<Card
title="GET /api/users"
href="#get-all-users"
>
Get a list of all users.
</Card>
<Card
title="GET /api/users/:username"
href="#get-a-user"
>
Get details of a specific user.
</Card>
<Card
title="POST /api/users"
href="#create-a-user"
>
Create a new user.
</Card>
<Card
title="PUT /api/users/:username"
href="#update-a-user"
>
Update an existing user.
</Card>
<Card
title="DELETE /api/users/:username"
href="#delete-a-user"
>
Delete a user.
</Card>
<Card
title="GET /api/users-stats"
href="#get-user-statistics"
>
Get statistics about users and their server access.
</Card>
---
### Get All Users
Retrieves a list of all users in the system.
- **Endpoint**: `/api/users`
- **Method**: `GET`
- **Authentication**: Required (Admin only)
- **Response**:
```json
{
"success": true,
"data": [
{
"username": "admin",
"role": "admin",
"servers": ["server1", "server2"],
"groups": ["group1"]
},
{
"username": "user1",
"role": "user",
"servers": ["server1"],
"groups": []
}
]
}
```
---
### Get a User
Retrieves details of a specific user.
- **Endpoint**: `/api/users/:username`
- **Method**: `GET`
- **Authentication**: Required (Admin only)
- **Parameters**:
- `:username` (string, required): The username of the user.
- **Response**:
```json
{
"success": true,
"data": {
"username": "user1",
"role": "user",
"servers": ["server1", "server2"],
"groups": ["group1"]
}
}
```
---
### Create a User
Creates a new user in the system.
- **Endpoint**: `/api/users`
- **Method**: `POST`
- **Authentication**: Required (Admin only)
- **Body**:
```json
{
"username": "newuser",
"password": "securepassword",
"role": "user",
"servers": ["server1"],
"groups": ["group1"]
}
```
- `username` (string, required): The username for the new user.
- `password` (string, required): The password for the new user. Must be at least 6 characters.
- `role` (string, optional): The role of the user. Either `"admin"` or `"user"`. Defaults to `"user"`.
- `servers` (array of strings, optional): List of server names the user has access to.
- `groups` (array of strings, optional): List of group IDs the user belongs to.
---
### Update a User
Updates an existing user's information.
- **Endpoint**: `/api/users/:username`
- **Method**: `PUT`
- **Authentication**: Required (Admin only)
- **Parameters**:
- `:username` (string, required): The username of the user to update.
- **Body**:
```json
{
"password": "newpassword",
"role": "admin",
"servers": ["server1", "server2", "server3"],
"groups": ["group1", "group2"]
}
```
- `password` (string, optional): New password for the user.
- `role` (string, optional): New role for the user.
- `servers` (array of strings, optional): Updated list of accessible servers.
- `groups` (array of strings, optional): Updated list of groups.
---
### Delete a User
Removes a user from the system.
- **Endpoint**: `/api/users/:username`
- **Method**: `DELETE`
- **Authentication**: Required (Admin only)
- **Parameters**:
- `:username` (string, required): The username of the user to delete.
---
### Get User Statistics
Retrieves statistics about users and their access to servers and groups.
- **Endpoint**: `/api/users-stats`
- **Method**: `GET`
- **Authentication**: Required (Admin only)
- **Response**:
```json
{
"success": true,
"data": {
"totalUsers": 5,
"adminUsers": 1,
"regularUsers": 4,
"usersPerServer": {
"server1": 3,
"server2": 2
},
"usersPerGroup": {
"group1": 2,
"group2": 1
}
}
}
```
**Note**: All user management endpoints require admin authentication.

View File

@@ -0,0 +1,304 @@
---
title: 'Database Configuration'
description: 'Configuring MCPHub to use a PostgreSQL database as an alternative to the mcp_settings.json file.'
---
# Database Configuration for MCPHub
## Overview
MCPHub supports storing configuration data in a PostgreSQL database as an alternative to the `mcp_settings.json` file. Database mode provides enhanced persistence and scalability for production environments and enterprise deployments.
## Why Use Database Configuration?
**Core Benefits:**
- ✅ **Better Persistence** - Configuration stored in a professional database with transaction support and data integrity
- ✅ **High Availability** - Leverage database replication and failover capabilities
- ✅ **Enterprise Ready** - Meets enterprise data management and compliance requirements
- ✅ **Backup & Recovery** - Use mature database backup tools and strategies
## Environment Variables
### Required for Database Mode
```bash
# Database connection URL (PostgreSQL)
# Simply setting DB_URL will automatically enable database mode
DB_URL=postgresql://user:password@localhost:5432/mcphub
# Or explicitly control with USE_DB (overrides auto-detection)
# USE_DB=true
```
<Note>
**Simplified Configuration**: You only need to set `DB_URL` to enable database mode. MCPHub will automatically detect and enable database mode when `DB_URL` is present. Use `USE_DB=false` to explicitly disable database mode even when `DB_URL` is set.
</Note>
## Setup Instructions
### 1. Using Docker
#### Option A: Using External Database
If you already have a PostgreSQL database:
```bash
docker run -d \
-p 3000:3000 \
-v ./mcp_settings.json:/app/mcp_settings.json \
-e DB_URL="postgresql://user:password@your-db-host:5432/mcphub" \
samanhappy/mcphub
```
#### Option B: Using PostgreSQL as a separate service
Create a `docker-compose.yml`:
```yaml
version: '3.8'
services:
postgres:
image: postgres:16
environment:
POSTGRES_DB: mcphub
POSTGRES_USER: mcphub
POSTGRES_PASSWORD: your_secure_password
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
mcphub:
image: samanhappy/mcphub:latest
environment:
USE_DB: "true"
DB_URL: "postgresql://mcphub:your_secure_password@postgres:5432/mcphub"
PORT: 3000
ports:
- "3000:3000"
depends_on:
- postgres
volumes:
pgdata:
```
Run with:
```bash
docker-compose up -d
```
### 2. Manual Setup
#### Step 1: Setup PostgreSQL Database
```bash
# Install PostgreSQL (if not already installed)
sudo apt-get install postgresql postgresql-contrib
# Create database and user
sudo -u postgres psql <<EOF
CREATE DATABASE mcphub;
CREATE USER mcphub WITH ENCRYPTED PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE mcphub TO mcphub;
EOF
```
#### Step 2: Install MCPHub
```bash
npm install -g @samanhappy/mcphub
```
#### Step 3: Set Environment Variables
Create a `.env` file:
```bash
# Simply set DB_URL to enable database mode (USE_DB is auto-detected)
DB_URL=postgresql://mcphub:your_password@localhost:5432/mcphub
PORT=3000
```
#### Step 4: Run Migration (Optional)
If you have an existing `mcp_settings.json` file, migrate it:
```bash
# Run migration script
npx tsx src/scripts/migrate-to-database.ts
```
Or let MCPHub auto-migrate on first startup.
#### Step 5: Start MCPHub
```bash
mcphub
```
## Migration from File-Based to Database
MCPHub provides automatic migration on first startup when database mode is enabled. However, you can also run the migration manually.
### Automatic Migration
When you start MCPHub with `USE_DB=true` for the first time:
1. MCPHub connects to the database
2. Checks if any users exist in the database
3. If no users found, automatically migrates from `mcp_settings.json`
4. Creates all tables and imports all data
### Manual Migration
Run the migration script:
```bash
# Using npx
npx tsx src/scripts/migrate-to-database.ts
# Or using Node
node dist/scripts/migrate-to-database.js
```
The migration will:
- ✅ Create database tables if they don't exist
- ✅ Import all users with hashed passwords
- ✅ Import all MCP server configurations
- ✅ Import all groups
- ✅ Import system configuration
- ✅ Import user-specific configurations
- ✅ Skip existing records (safe to run multiple times)
## Configuration After Migration
Once running in database mode, all configuration changes are stored in the database:
- User management via `/api/users`
- Server management via `/api/servers`
- Group management via `/api/groups`
- System settings via `/api/system/config`
The web dashboard works exactly the same way, but now stores changes in the database instead of the file.
## Database Schema
MCPHub creates the following tables:
- **users** - User accounts and authentication
- **servers** - MCP server configurations
- **groups** - Server groups
- **system_config** - System-wide settings
- **user_configs** - User-specific settings
- **vector_embeddings** - Vector search data (for smart routing)
## Backup and Restore
### Backup
```bash
# PostgreSQL backup
pg_dump -U mcphub mcphub > mcphub_backup.sql
# Or using Docker
docker exec postgres pg_dump -U mcphub mcphub > mcphub_backup.sql
```
### Restore
```bash
# PostgreSQL restore
psql -U mcphub mcphub < mcphub_backup.sql
# Or using Docker
docker exec -i postgres psql -U mcphub mcphub < mcphub_backup.sql
```
## Switching Back to File-Based Config
If you need to switch back to file-based configuration:
1. Set `USE_DB=false` or remove `DB_URL` and `USE_DB` environment variables
2. Restart MCPHub
3. MCPHub will use `mcp_settings.json` again
Note: Changes made in database mode won't be reflected in the file unless you manually export them.
## Troubleshooting
### Connection Refused
```
Error: connect ECONNREFUSED 127.0.0.1:5432
```
**Solution:** Check that PostgreSQL is running and accessible:
```bash
# Check PostgreSQL status
sudo systemctl status postgresql
# Or for Docker
docker ps | grep postgres
```
### Authentication Failed
```
Error: password authentication failed for user "mcphub"
```
**Solution:** Verify database credentials in `DB_URL` environment variable.
### Migration Failed
```
❌ Migration failed: ...
```
**Solution:**
1. Check that `mcp_settings.json` exists and is valid JSON
2. Verify database connection
3. Check logs for specific error messages
4. Ensure database user has CREATE TABLE permissions
### Tables Already Exist
Database tables are automatically created if they don't exist. If you get errors about existing tables, check:
1. Whether a previous migration partially completed
2. Manual table creation conflicts
3. Run with `synchronize: false` in database config if needed
## Environment Variables Reference
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `DB_URL` | Yes* | - | Full PostgreSQL connection URL. Setting this automatically enables database mode |
| `USE_DB` | No | auto | Explicitly enable/disable database mode. If not set, auto-detected based on `DB_URL` presence |
| `MCPHUB_SETTING_PATH` | No | - | Path to mcp_settings.json (for migration) |
*Required for database mode. Simply setting `DB_URL` enables database mode automatically
## Security Considerations
1. **Database Credentials:** Store database credentials securely, use environment variables or secrets management
2. **Network Access:** Restrict database access to MCPHub instances only
3. **Encryption:** Use SSL/TLS for database connections in production:
```bash
DB_URL=postgresql://user:password@host:5432/mcphub?sslmode=require
```
4. **Backup:** Regularly backup your database
5. **Access Control:** Use strong database passwords and limit user permissions
## Performance
Database mode offers better performance for:
- Multiple concurrent users
- Frequent configuration changes
- Large number of servers/groups
File mode may be faster for:
- Single user setups
- Read-heavy workloads with infrequent changes
- Development/testing environments

View File

@@ -0,0 +1,583 @@
---
title: 'Docker Setup'
description: 'Deploy MCPHub using Docker and Docker Compose'
---
# Docker Setup
This guide covers deploying MCPHub using Docker, including development and production configurations.
## Quick Start with Docker
### Using Pre-built Image
```bash
# Pull the latest image
docker pull mcphub/mcphub:latest
# Run with default configuration
docker run -d \
--name mcphub \
-p 3000:3000 \
-v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
mcphub/mcphub:latest
```
### Building from Source
```bash
# Clone the repository
git clone https://github.com/your-username/mcphub.git
cd mcphub
# Build the Docker image
docker build -t mcphub:local .
# Run the container
docker run -d \
--name mcphub \
-p 3000:3000 \
-v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
mcphub:local
```
### Building with Extended Features
The Docker image supports an `INSTALL_EXT` build argument to include additional tools:
```bash
# Build with extended features (includes Docker Engine, Chrome/Playwright)
docker build --build-arg INSTALL_EXT=true -t mcphub:extended .
# Option 1: Run with automatic Docker-in-Docker (requires privileged mode)
docker run -d \
--name mcphub \
--privileged \
-p 3000:3000 \
-v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
mcphub:extended
# Option 2: Run with Docker socket mounted (use host's Docker daemon)
docker run -d \
--name mcphub \
-p 3000:3000 \
-v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
-v /var/run/docker.sock:/var/run/docker.sock \
mcphub:extended
# Verify Docker is available
docker exec mcphub docker --version
docker exec mcphub docker ps
```
<Note>
**What's included with INSTALL_EXT=true:**
- **Docker Engine**: Full Docker daemon with CLI for container management. The daemon auto-starts when the container runs in privileged mode.
- **Chrome/Playwright** (amd64 only): For browser automation tasks
The extended image is larger but provides additional capabilities for advanced use cases.
</Note>
<Warning>
**Docker-in-Docker Security Considerations:**
- **Privileged mode** (`--privileged`): Required for the Docker daemon to start inside the container. This gives the container elevated permissions on the host.
- **Docker socket mounting** (`/var/run/docker.sock`): Gives the container access to the host's Docker daemon. Both approaches should only be used in trusted environments.
- For production, consider using Docker socket mounting instead of privileged mode for better security.
</Warning>
## Docker Compose Setup
### Basic Configuration
Create a `docker-compose.yml` file:
```yaml
version: '3.8'
services:
mcphub:
image: mcphub/mcphub:latest
# For local development, use:
# build: .
container_name: mcphub
ports:
- '3000:3000'
environment:
- NODE_ENV=production
- PORT=3000
- JWT_SECRET=${JWT_SECRET:-your-jwt-secret}
- DATABASE_URL=postgresql://mcphub:password@postgres:5432/mcphub
volumes:
- ./mcp_settings.json:/app/mcp_settings.json:ro
- ./servers.json:/app/servers.json:ro
- mcphub_data:/app/data
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
networks:
- mcphub-network
postgres:
image: postgres:15-alpine
container_name: mcphub-postgres
environment:
- POSTGRES_DB=mcphub
- POSTGRES_USER=mcphub
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
ports:
- '5432:5432'
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U mcphub -d mcphub']
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- mcphub-network
volumes:
postgres_data:
mcphub_data:
networks:
mcphub-network:
driver: bridge
```
### Production Configuration with Nginx
```yaml
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: mcphub-nginx
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- nginx_logs:/var/log/nginx
depends_on:
- mcphub
restart: unless-stopped
networks:
- mcphub-network
mcphub:
image: mcphub/mcphub:latest
container_name: mcphub-app
expose:
- '3000'
environment:
- NODE_ENV=production
- PORT=3000
- JWT_SECRET=${JWT_SECRET}
- JWT_EXPIRES_IN=${JWT_EXPIRES_IN:-24h}
- DATABASE_URL=postgresql://mcphub:${POSTGRES_PASSWORD}@postgres:5432/mcphub
- OPENAI_API_KEY=${OPENAI_API_KEY}
- REDIS_URL=redis://redis:6379
volumes:
- ./mcp_settings.json:/app/mcp_settings.json:ro
- ./servers.json:/app/servers.json:ro
- mcphub_data:/app/data
- mcphub_logs:/app/logs
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
networks:
- mcphub-network
healthcheck:
test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:3000/health']
interval: 30s
timeout: 10s
retries: 3
postgres:
image: postgres:15-alpine
container_name: mcphub-postgres
environment:
- POSTGRES_DB=mcphub
- POSTGRES_USER=mcphub
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backups:/backups
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U mcphub -d mcphub']
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- mcphub-network
redis:
image: redis:7-alpine
container_name: mcphub-redis
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- mcphub-network
volumes:
postgres_data:
redis_data:
mcphub_data:
mcphub_logs:
nginx_logs:
networks:
mcphub-network:
driver: bridge
```
### Environment Variables
Create a `.env` file for Docker Compose:
```env
# Application
NODE_ENV=production
JWT_SECRET=your-super-secret-jwt-key-change-this
JWT_EXPIRES_IN=24h
# Database
POSTGRES_PASSWORD=your-secure-database-password
# Redis
REDIS_PASSWORD=your-secure-redis-password
# External APIs
OPENAI_API_KEY=your-openai-api-key
# Optional: Custom port
# PORT=3000
```
## Development Setup
### Development Docker Compose
Create `docker-compose.dev.yml`:
```yaml
version: '3.8'
services:
mcphub-dev:
build:
context: .
dockerfile: Dockerfile.dev
container_name: mcphub-dev
ports:
- '3000:3000'
- '5173:5173' # Frontend dev server
- '9229:9229' # Debug port
environment:
- NODE_ENV=development
- PORT=3000
- DATABASE_URL=postgresql://mcphub:password@postgres:5432/mcphub
volumes:
- .:/app
- /app/node_modules
- /app/frontend/node_modules
depends_on:
- postgres
command: pnpm dev
networks:
- mcphub-dev
postgres:
image: postgres:15-alpine
container_name: mcphub-postgres-dev
environment:
- POSTGRES_DB=mcphub
- POSTGRES_USER=mcphub
- POSTGRES_PASSWORD=password
ports:
- '5432:5432'
volumes:
- postgres_dev_data:/var/lib/postgresql/data
networks:
- mcphub-dev
volumes:
postgres_dev_data:
networks:
mcphub-dev:
driver: bridge
```
### Development Dockerfile
Create `Dockerfile.dev`:
```dockerfile
FROM node:20-alpine
# Install pnpm
RUN npm install -g pnpm
# Set working directory
WORKDIR /app
# Copy package files
COPY package.json pnpm-lock.yaml ./
COPY frontend/package.json ./frontend/
# Install dependencies
RUN pnpm install
# Copy source code
COPY . .
# Expose ports
EXPOSE 3000 5173 9229
# Start development server
CMD ["pnpm", "dev"]
```
## Running the Application
### Development Mode
```bash
# Start development environment
docker-compose -f docker-compose.dev.yml up -d
# View logs
docker-compose -f docker-compose.dev.yml logs -f mcphub-dev
# Stop development environment
docker-compose -f docker-compose.dev.yml down
```
### Production Mode
```bash
# Start production environment
docker-compose up -d
# View logs
docker-compose logs -f mcphub
# Stop production environment
docker-compose down
```
## Configuration Management
### MCP Settings Volume Mount
Create your `mcp_settings.json`:
```json
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
},
"amap": {
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "your-api-key"
}
}
}
}
```
### Secrets Management
For production, use Docker secrets:
```yaml
version: '3.8'
services:
mcphub:
image: mcphub/mcphub:latest
environment:
- JWT_SECRET_FILE=/run/secrets/jwt_secret
- DATABASE_PASSWORD_FILE=/run/secrets/db_password
secrets:
- jwt_secret
- db_password
secrets:
jwt_secret:
file: ./secrets/jwt_secret.txt
db_password:
file: ./secrets/db_password.txt
```
## Data Persistence
### Database Backups
Add backup service to your `docker-compose.yml`:
```yaml
services:
backup:
image: postgres:15-alpine
container_name: mcphub-backup
environment:
- PGPASSWORD=${POSTGRES_PASSWORD}
volumes:
- ./backups:/backups
- ./scripts/backup.sh:/backup.sh:ro
command: /bin/sh -c "chmod +x /backup.sh && /backup.sh"
depends_on:
- postgres
profiles:
- backup
networks:
- mcphub-network
```
Create `scripts/backup.sh`:
```bash
#!/bin/sh
BACKUP_FILE="/backups/mcphub_$(date +%Y%m%d_%H%M%S).sql"
pg_dump -h postgres -U mcphub -d mcphub > "$BACKUP_FILE"
echo "Backup created: $BACKUP_FILE"
# Keep only last 7 days of backups
find /backups -name "mcphub_*.sql" -mtime +7 -delete
```
Run backup:
```bash
docker-compose --profile backup run --rm backup
```
## Monitoring and Health Checks
### Health Check Endpoint
Add to your application:
```javascript
// In your Express app
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage(),
version: process.env.npm_package_version,
});
});
```
### Docker Health Checks
```yaml
services:
mcphub:
# ... other config
healthcheck:
test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:3000/health']
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
```
### Monitoring with Watchtower
Add automatic updates:
```yaml
services:
watchtower:
image: containrrr/watchtower
container_name: mcphub-watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_POLL_INTERVAL=3600
- WATCHTOWER_INCLUDE_STOPPED=true
restart: unless-stopped
```
## Troubleshooting
### Common Issues
**Container fails to start**: Check logs with `docker-compose logs mcphub`
**Database connection errors**: Ensure PostgreSQL is healthy and accessible
**Port conflicts**: Check if ports 3000/5432 are already in use
**Volume mount issues**: Verify file paths and permissions
### Debug Commands
```bash
# Check container status
docker-compose ps
# View logs
docker-compose logs -f [service_name]
# Execute commands in container
docker-compose exec mcphub sh
# Check database connection
docker-compose exec postgres psql -U mcphub -d mcphub
# Restart specific service
docker-compose restart mcphub
# Rebuild and restart
docker-compose up --build -d
```
### Performance Optimization
```yaml
services:
mcphub:
# ... other config
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
```
This Docker setup provides a complete containerized environment for MCPHub with development and production configurations.

View File

@@ -0,0 +1,104 @@
---
title: 'Environment Variables'
description: 'Configure MCPHub using environment variables'
---
# Environment Variables
MCPHub uses environment variables for configuration. This guide covers all available variables and their usage.
## Core Application Settings
### Server Configuration
| Variable | Default | Description |
| --- | --- | --- |
| `PORT` | `3000` | Port number for the HTTP server |
| `INIT_TIMEOUT` | `300000` | Initial timeout for the application |
| `BASE_PATH` | `''` | The base path of the application |
| `READONLY` | `false` | Set to `true` to enable readonly mode |
| `MCPHUB_SETTING_PATH` | | Path to the MCPHub settings |
| `NODE_ENV` | `development` | Application environment (`development`, `production`, `test`) |
```env
PORT=3000
INIT_TIMEOUT=300000
BASE_PATH=/api
READONLY=true
MCPHUB_SETTING_PATH=/path/to/settings
NODE_ENV=production
```
## Authentication & Security
### JWT Configuration
| Variable | Default | Description |
| --- | --- | --- |
| `JWT_SECRET` | - | Secret key for JWT token signing (required) |
```env
JWT_SECRET=your-super-secret-key-change-this-in-production
```
## Configuration Examples
### Development Environment
```env
# .env.development
NODE_ENV=development
PORT=3000
# Auth
JWT_SECRET=dev-secret-key
```
### Production Environment
```env
# .env.production
NODE_ENV=production
PORT=3000
# Security
JWT_SECRET=your-super-secure-production-secret
```
### Docker Environment
```env
# .env.docker
NODE_ENV=production
PORT=3000
# Security
JWT_SECRET_FILE=/run/secrets/jwt_secret
```
## Environment Variable Loading
MCPHub loads environment variables in the following order:
1. System environment variables
2. `.env.local` (ignored by git)
3. `.env.{NODE_ENV}` (e.g., `.env.production`)
4. `.env`
### Using dotenv-expand
MCPHub supports variable expansion:
```env
BASE_URL=https://api.example.com
API_ENDPOINT=${BASE_URL}/v1
```
## Security Best Practices
1. **Never commit secrets** to version control
2. **Use strong, unique secrets** for production
3. **Rotate secrets regularly**
4. **Use environment-specific files**
5. **Validate all environment variables** at startup
6. **Use Docker secrets** for container deployments

View File

@@ -0,0 +1,519 @@
---
title: 'MCP Settings Configuration'
description: 'Configure MCP servers and their settings for MCPHub'
---
# MCP Settings Configuration
This guide explains how to configure MCP servers in MCPHub using the `mcp_settings.json` file and related configurations.
## Configuration Files Overview
MCPHub uses several configuration files:
- **`mcp_settings.json`**: Main MCP server configurations
- **`servers.json`**: Server metadata and grouping
- **`.env`**: Environment variables and secrets
## Basic MCP Settings Structure
### mcp_settings.json
```json
{
"mcpServers": {
"server-name": {
"command": "command-to-run",
"args": ["arg1", "arg2"],
"env": {
"ENV_VAR": "value"
}
}
}
}
```
### Example Configuration
```json
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"],
"env": {
"USER_AGENT": "MCPHub/1.0"
}
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
},
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}",
"SLACK_TEAM_ID": "${SLACK_TEAM_ID}"
}
}
}
}
```
## Server Configuration Options
### Required Fields
| Field | Type | Description |
| --------- | ------ | -------------------------- |
| `command` | string | Executable command or path |
| `args` | array | Command-line arguments |
### Optional Fields
| Field | Type | Default | Description |
| -------------- | ------- | --------------- | --------------------------- |
| `env` | object | `{}` | Environment variables |
## Common MCP Server Examples
### Web and API Servers
#### Fetch Server
```json
{
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"],
"env": {
"USER_AGENT": "MCPHub/1.0",
"MAX_REDIRECTS": "10"
}
}
}
```
#### Web Scraping with Playwright
```json
{
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"],
"timeout": 60000,
"env": {
"PLAYWRIGHT_BROWSERS_PATH": "/tmp/browsers"
}
}
}
```
### File and System Servers
#### Filesystem Server
```json
{
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
"env": {
"ALLOWED_OPERATIONS": "read,write,list"
}
}
}
```
#### SQLite Server
```json
{
"sqlite": {
"command": "uvx",
"args": ["mcp-server-sqlite", "--db-path", "/path/to/database.db"],
"env": {
"SQLITE_READONLY": "false"
}
}
}
```
### Communication Servers
#### Slack Server
```json
{
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}",
"SLACK_TEAM_ID": "${SLACK_TEAM_ID}",
"SLACK_APP_TOKEN": "${SLACK_APP_TOKEN}"
}
}
}
```
#### Email Server
```json
{
"email": {
"command": "python",
"args": ["-m", "mcp_server_email"],
"env": {
"SMTP_HOST": "smtp.gmail.com",
"SMTP_PORT": "587",
"EMAIL_USER": "${EMAIL_USER}",
"EMAIL_PASSWORD": "${EMAIL_PASSWORD}"
}
}
}
```
### Development and API Servers
#### GitHub Server
```json
{
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
}
}
```
#### Google Drive Server
```json
{
"gdrive": {
"command": "npx",
"args": ["-y", "@google/mcp-server-gdrive"],
"env": {
"GOOGLE_CLIENT_ID": "${GOOGLE_CLIENT_ID}",
"GOOGLE_CLIENT_SECRET": "${GOOGLE_CLIENT_SECRET}",
"GOOGLE_REFRESH_TOKEN": "${GOOGLE_REFRESH_TOKEN}"
}
}
}
```
### Map and Location Services
#### Amap (高德地图) Server
```json
{
"amap": {
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "${AMAP_API_KEY}",
"AMAP_LANGUAGE": "zh-cn"
}
}
}
```
#### OpenStreetMap Server
```json
{
"osm": {
"command": "python",
"args": ["-m", "mcp_server_osm"],
"env": {
"OSM_USER_AGENT": "MCPHub/1.0"
}
}
}
```
## Advanced Configuration
### Environment Variable Substitution
MCPHub supports environment variable substitution using `${VAR_NAME}` syntax:
```json
{
"mcpServers": {
"api-server": {
"command": "python",
"args": ["-m", "api_server"],
"env": {
"API_KEY": "${API_KEY}",
"API_URL": "${API_BASE_URL}/v1"
}
}
}
}
```
{/* ### Custom Server Scripts
#### Local Python Server
```json
{
"custom-python": {
"command": "python",
"args": ["./servers/custom_server.py"],
"cwd": "/app/custom-servers",
"env": {
"PYTHONPATH": "/app/custom-servers",
"CONFIG_FILE": "./config.json"
}
}
}
```
#### Local Node.js Server
```json
{
"custom-node": {
"command": "node",
"args": ["./servers/custom-server.js"],
"cwd": "/app/custom-servers",
"env": {
"NODE_ENV": "production"
}
}
}
```
## Server Metadata Configuration
### servers.json
Complement `mcp_settings.json` with server metadata:
```json
{
"servers": {
"fetch": {
"name": "Fetch Server",
"description": "HTTP client for web requests",
"category": "web",
"tags": ["http", "api", "web"],
"version": "1.0.0",
"author": "MCPHub Team",
"documentation": "https://docs.mcphub.com/servers/fetch",
"enabled": true
},
"playwright": {
"name": "Playwright Browser",
"description": "Web automation and scraping",
"category": "automation",
"tags": ["browser", "scraping", "automation"],
"version": "2.0.0",
"enabled": true
}
},
"groups": {
"web-tools": {
"name": "Web Tools",
"description": "Tools for web interaction",
"servers": ["fetch", "playwright"],
"access": "public"
},
"admin-tools": {
"name": "Admin Tools",
"description": "Administrative utilities",
"servers": ["filesystem", "database"],
"access": "admin"
}
}
}
``` */}
## Group Management
### Group Configuration
```json
{
"groups": {
"production": {
"name": "Production Tools",
"description": "Stable production servers",
"servers": ["fetch", "slack", "github"]
},
"experimental": {
"name": "Experimental Features",
"description": "Beta and experimental servers",
"servers": ["experimental-ai", "beta-search"]
}
}
}
```
{/* ### Access Control
| Access Level | Description |
| --------------- | -------------------------- |
| `public` | No authentication required |
| `authenticated` | Valid JWT token required |
| `admin` | Admin role required |
| `custom` | Custom permission logic |
## Dynamic Configuration
### Hot Reloading
MCPHub supports hot reloading of configurations:
```bash
# Reload configurations without restart
curl -X POST http://localhost:3000/api/admin/reload-config \
-H "Authorization: Bearer your-admin-token"
``` */}
{/* ### Configuration Validation
MCPHub validates configurations on startup and reload:
```json
{
"validation": {
"strict": true,
"allowUnknownServers": false,
"requireDocumentation": true
}
}
``` */}
## Best Practices
### Security
1. **Use environment variables** for sensitive data:
```json
{
"env": {
"API_KEY": "${API_KEY}",
"DATABASE_PASSWORD": "${DB_PASSWORD}"
}
}
```
{/* 2. **Limit server permissions**:
```json
{
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/restricted/path"],
"env": {
"READONLY": "true"
}
}
}
``` */}
{/* ### Performance
1. **Set appropriate timeouts**:
```json
{
"timeout": 30000,
"maxRestarts": 3,
"restartDelay": 5000
}
```
2. **Resource limits**:
```json
{
"env": {
"NODE_OPTIONS": "--max-old-space-size=512",
"MEMORY_LIMIT": "512MB"
}
}
``` */}
{/* ### Monitoring
1. **Enable health checks**:
```json
{
"healthCheck": {
"enabled": true,
"interval": 30000,
"timeout": 5000
}
}
```
2. **Logging configuration**:
```json
{
"env": {
"LOG_LEVEL": "info",
"LOG_FORMAT": "json"
}
}
``` */}
{/* ## Troubleshooting
### Common Issues
**Server won't start**: Check command and arguments
```bash
# Test command manually
uvx mcp-server-fetch
``` */}
{/* **Environment variables not found**: Verify `.env` file
```bash
# Check environment
printenv | grep API_KEY
```
**Permission errors**: Check file permissions and paths
```bash
# Verify executable permissions
ls -la /path/to/server
``` */}
{/* ### Debug Configuration
Enable debug mode for detailed logging:
```json
{
"debug": {
"enabled": true,
"logLevel": "debug",
"includeEnv": false,
"logStartup": true
}
}
``` */}
{/*
### Validation Errors
Common validation errors and solutions:
1. **Missing required fields**: Add `command` and `args`
2. **Invalid timeout**: Use number, not string
3. **Environment variable not found**: Check `.env` file
4. **Command not found**: Verify installation and PATH */}
This comprehensive guide covers all aspects of configuring MCP servers in MCPHub for various use cases and environments.

View File

@@ -0,0 +1,373 @@
---
title: 'Nginx Configuration'
description: 'Configure Nginx as a reverse proxy for MCPHub'
---
# Nginx Configuration
This guide explains how to configure Nginx as a reverse proxy for MCPHub, including SSL termination, load balancing, and caching strategies.
## Basic Reverse Proxy Setup
### Configuration File
Create or update your Nginx configuration file (`/etc/nginx/sites-available/mcphub`):
```nginx
server {
listen 80;
server_name your-domain.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL Configuration
ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Security Headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# Main application
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 86400;
}
# API endpoints with longer timeout for MCP operations
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300;
proxy_connect_timeout 60;
proxy_send_timeout 60;
}
# Static assets caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://127.0.0.1:3000;
proxy_cache_valid 200 1d;
proxy_cache_valid 404 1m;
add_header Cache-Control "public, immutable";
expires 1y;
}
}
```
### Enable the Configuration
```bash
# Create symbolic link to enable the site
sudo ln -s /etc/nginx/sites-available/mcphub /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
```
## Load Balancing Configuration
For high-availability setups with multiple MCPHub instances:
```nginx
upstream mcphub_backend {
least_conn;
server 127.0.0.1:3000 weight=1 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3001 weight=1 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3002 weight=1 max_fails=3 fail_timeout=30s;
# Health check (Nginx Plus feature)
# health_check interval=5s fails=3 passes=2;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL and other configurations...
location / {
proxy_pass http://mcphub_backend;
# Other proxy settings...
}
}
```
## Caching Configuration
### Browser Caching
```nginx
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_pass http://127.0.0.1:3000;
expires 1y;
add_header Cache-Control "public, immutable";
}
# Cache API responses (be careful with dynamic content)
location /api/public/ {
proxy_pass http://127.0.0.1:3000;
proxy_cache mcphub_cache;
proxy_cache_valid 200 5m;
proxy_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
}
```
### Nginx Proxy Cache
Add to the `http` block in `nginx.conf`:
```nginx
http {
# Proxy cache configuration
proxy_cache_path /var/cache/nginx/mcphub
levels=1:2
keys_zone=mcphub_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
# Other configurations...
}
```
## WebSocket Support
For real-time features and SSE (Server-Sent Events):
```nginx
location /api/stream {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Disable buffering for real-time responses
proxy_buffering off;
proxy_cache off;
# Timeouts for long-lived connections
proxy_read_timeout 24h;
proxy_send_timeout 24h;
}
```
## Security Configuration
### Rate Limiting
```nginx
http {
# Define rate limiting zones
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
server {
# Apply rate limiting to API endpoints
location /api/ {
limit_req zone=api burst=20 nodelay;
# Other configurations...
}
# Strict rate limiting for login endpoints
location /api/auth/login {
limit_req zone=login burst=5;
# Other configurations...
}
}
}
```
### IP Whitelisting
```nginx
# Allow specific IPs for admin endpoints
location /api/admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://127.0.0.1:3000;
# Other proxy settings...
}
```
## Monitoring and Logging
### Access Logs
```nginx
http {
# Custom log format
log_format mcphub_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
server {
# Enable access logging
access_log /var/log/nginx/mcphub_access.log mcphub_format;
error_log /var/log/nginx/mcphub_error.log;
# Other configurations...
}
}
```
### Status Page
```nginx
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
```
## Docker Integration
When running MCPHub in Docker, update the proxy configuration:
```nginx
upstream mcphub_docker {
server mcphub:3000; # Docker service name
}
server {
location / {
proxy_pass http://mcphub_docker;
# Other proxy settings...
}
}
```
## Complete Example Configuration
Here's a production-ready example using the provided `nginx.conf.example`:
```bash
# Copy the example configuration
cp nginx.conf.example /etc/nginx/sites-available/mcphub
# Update the configuration with your domain and paths
sudo nano /etc/nginx/sites-available/mcphub
# Enable the site
sudo ln -s /etc/nginx/sites-available/mcphub /etc/nginx/sites-enabled/
# Test and reload
sudo nginx -t && sudo systemctl reload nginx
```
## Troubleshooting
### Common Issues
**502 Bad Gateway**: Check if MCPHub is running and accessible
**504 Gateway Timeout**: Increase `proxy_read_timeout` for long-running operations
**WebSocket connection failures**: Ensure proper `Upgrade` and `Connection` headers
**Cache issues**: Clear proxy cache or disable for development
### Debug Commands
```bash
# Test Nginx configuration
sudo nginx -t
# Check Nginx status
sudo systemctl status nginx
# View error logs
sudo tail -f /var/log/nginx/error.log
# Check if MCPHub is responding
curl -I http://localhost:3000
```
## Performance Optimization
### Worker Processes
```nginx
# In nginx.conf
worker_processes auto;
worker_connections 1024;
```
### Buffer Sizes
```nginx
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
```
### Keep-Alive
```nginx
upstream mcphub_backend {
server 127.0.0.1:3000;
keepalive 32;
}
location / {
proxy_pass http://mcphub_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
```
This configuration provides a solid foundation for running MCPHub behind Nginx with proper security, performance, and reliability features.

107
docs/development.mdx Normal file
View File

@@ -0,0 +1,107 @@
---
title: 'Development'
description: 'Preview changes locally to update your docs'
---
<Info>
**Prerequisite**: Please install Node.js (version 19 or higher) before proceeding. <br />
Please upgrade to ```docs.json``` before proceeding and delete the legacy ```mint.json``` file.
</Info>
Follow these steps to install and run Mintlify on your operating system:
**Step 1**: Install Mintlify:
<CodeGroup>
```bash npm
npm i -g mintlify
```
```bash yarn
yarn global add mintlify
```
</CodeGroup>
**Step 2**: Navigate to the docs directory (where the `docs.json` file is located) and execute the following command:
```bash
mintlify dev
```
A local preview of your documentation will be available at `http://localhost:3000`.
### Custom Ports
By default, Mintlify uses port 3000. You can customize the port Mintlify runs on by using the `--port` flag. To run Mintlify on port 3333, for instance, use this command:
```bash
mintlify dev --port 3333
```
If you attempt to run Mintlify on a port that's already in use, it will use the next available port:
```md
Port 3000 is already in use. Trying 3001 instead.
```
## Mintlify Versions
Please note that each CLI release is associated with a specific version of Mintlify. If your local website doesn't align with the production version, please update the CLI:
<CodeGroup>
```bash npm
npm i -g mintlify@latest
```
```bash yarn
yarn global upgrade mintlify
```
</CodeGroup>
## Validating Links
The CLI can assist with validating reference links made in your documentation. To identify any broken links, use the following command:
```bash
mintlify broken-links
```
## Deployment
<Tip>
Unlimited editors available under the [Pro
Plan](https://mintlify.com/pricing) and above.
</Tip>
If the deployment is successful, you should see the following:
<Frame>
<img src="/images/checks-passed.png" style={{ borderRadius: '0.5rem' }} />
</Frame>
## Code Formatting
We suggest using extensions on your IDE to recognize and format MDX. If you're a VSCode user, consider the [MDX VSCode extension](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx) for syntax highlighting, and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) for code formatting.
## Troubleshooting
<AccordionGroup>
<Accordion title='Error: Could not load the "sharp" module using the darwin-arm64 runtime'>
This may be due to an outdated version of node. Try the following:
1. Remove the currently-installed version of mintlify: `npm remove -g mintlify`
2. Upgrade to Node v19 or higher.
3. Reinstall mintlify: `npm install -g mintlify`
</Accordion>
<Accordion title="Issue: Encountering an unknown error">
Solution: Go to the root of your device and delete the \~/.mintlify folder. Afterwards, run `mintlify dev` again.
</Accordion>
</AccordionGroup>
Curious about what changed in the CLI version? [Check out the CLI changelog.](https://www.npmjs.com/package/mintlify?activeTab=versions)

View File

@@ -0,0 +1,724 @@
---
title: 'Architecture Overview'
description: "Understand MCPHub's system architecture and design principles"
---
## System Overview
MCPHub is designed as a scalable, modular platform for managing Model Context Protocol (MCP) servers. The architecture follows modern web application patterns with clear separation of concerns, microservices-ready design, and extensibility in mind.
## High-Level Architecture
```mermaid
graph TB
subgraph "Client Layer"
WEB[Web Dashboard]
API[External APIs]
CLI[CLI Tools]
end
subgraph "Application Layer"
LB[Load Balancer/Nginx]
APP[MCPHub Server]
WS[WebSocket Server]
end
subgraph "Service Layer"
MCP[MCP Service]
AUTH[Auth Service]
ROUTE[Smart Routing]
MON[Monitoring Service]
end
subgraph "Data Layer"
PG[(PostgreSQL)]
REDIS[(Redis)]
VECTOR[(Vector Store)]
end
subgraph "MCP Servers"
GITHUB[GitHub MCP]
FS[Filesystem MCP]
DB[Database MCP]
CUSTOM[Custom MCP]
end
WEB --> LB
API --> LB
CLI --> LB
LB --> APP
APP --> WS
APP --> MCP
APP --> AUTH
APP --> ROUTE
APP --> MON
MCP --> GITHUB
MCP --> FS
MCP --> DB
MCP --> CUSTOM
AUTH --> PG
AUTH --> REDIS
ROUTE --> VECTOR
MON --> PG
MON --> REDIS
```
## Core Components
### 1. Application Server
The main Node.js/Express application that handles all HTTP requests and coordinates between services.
```typescript
// src/server.ts - Main application entry point
class MCPHubServer {
private app: Express;
private httpServer: Server;
private wsServer: WebSocketServer;
async start(): Promise<void> {
await this.initializeDatabase();
await this.initializeServices();
await this.setupRoutes();
await this.startServer();
}
}
```
**Key Responsibilities:**
- HTTP request handling
- WebSocket connections for real-time features
- Service coordination
- Middleware chain management
- Error handling and logging
### 2. MCP Service Layer
Manages the lifecycle and communication with MCP servers.
```typescript
// src/services/mcpService.ts
class MCPService {
private servers: Map<string, MCPServerInstance> = new Map();
private processManager: ProcessManager;
async startServer(config: MCPServerConfig): Promise<void> {
const instance = await this.processManager.spawn(config);
this.servers.set(config.name, instance);
await this.waitForHealthy(instance);
}
async executeRequest(serverName: string, request: MCPRequest): Promise<MCPResponse> {
const server = this.servers.get(serverName);
return await server.sendRequest(request);
}
}
```
**Key Features:**
- Process lifecycle management
- Health monitoring
- Request routing
- Error recovery
- Resource management
### 3. Smart Routing Engine
Provides AI-powered tool discovery and routing using vector embeddings.
```typescript
// src/services/smartRouting.ts
class SmartRoutingService {
private vectorStore: VectorStore;
private embeddingService: EmbeddingService;
async findRelevantTools(query: string): Promise<ToolMatch[]> {
const queryEmbedding = await this.embeddingService.embed(query);
const matches = await this.vectorStore.similaritySearch(queryEmbedding);
return this.rankResults(matches, query);
}
async indexTool(tool: ToolDefinition): Promise<void> {
const embedding = await this.embeddingService.embed(tool.description);
await this.vectorStore.upsert(tool.id, embedding, tool);
}
}
```
**Components:**
- Vector embedding generation
- Similarity search
- Result ranking and filtering
- Tool metadata management
### 4. Authentication & Authorization
Handles user authentication, session management, and access control.
```typescript
// src/services/authService.ts
class AuthService {
async authenticate(credentials: Credentials): Promise<User> {
const user = await this.validateCredentials(credentials);
const token = await this.generateJWT(user);
await this.createSession(user, token);
return user;
}
async authorize(user: User, resource: string, action: string): Promise<boolean> {
const permissions = await this.getUserPermissions(user);
return this.checkPermission(permissions, resource, action);
}
}
```
**Features:**
- JWT-based authentication
- Role-based access control (RBAC)
- Session management
- API key authentication
- Group-based permissions
### 5. Monitoring & Logging
Provides comprehensive monitoring, metrics collection, and logging.
```typescript
// src/services/monitoringService.ts
class MonitoringService {
private metricsCollector: MetricsCollector;
private alertManager: AlertManager;
async collectMetrics(): Promise<void> {
const systemMetrics = await this.getSystemMetrics();
const serverMetrics = await this.getMCPServerMetrics();
await this.metricsCollector.record(systemMetrics, serverMetrics);
await this.checkAlerts(systemMetrics, serverMetrics);
}
}
```
**Capabilities:**
- Real-time metrics collection
- Performance monitoring
- Error tracking
- Alert management
- Audit logging
## Data Architecture
### Database Schema
```sql
-- Core entities
CREATE TABLE users (
id UUID PRIMARY KEY,
username VARCHAR UNIQUE NOT NULL,
email VARCHAR UNIQUE NOT NULL,
password_hash VARCHAR NOT NULL,
role VARCHAR NOT NULL DEFAULT 'user',
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE servers (
id UUID PRIMARY KEY,
name VARCHAR UNIQUE NOT NULL,
command VARCHAR NOT NULL,
args JSONB NOT NULL DEFAULT '[]',
env JSONB DEFAULT '{}',
group_name VARCHAR,
status VARCHAR DEFAULT 'stopped',
config JSONB DEFAULT '{}',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE groups (
id UUID PRIMARY KEY,
name VARCHAR UNIQUE NOT NULL,
description TEXT,
config JSONB DEFAULT '{}',
created_at TIMESTAMP DEFAULT NOW()
);
-- Vector search for smart routing
CREATE TABLE tool_embeddings (
id UUID PRIMARY KEY,
server_name VARCHAR NOT NULL,
tool_name VARCHAR NOT NULL,
description TEXT,
embedding vector(1536),
metadata JSONB DEFAULT '{}',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Monitoring and logging
CREATE TABLE request_logs (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
server_name VARCHAR NOT NULL,
tool_name VARCHAR,
request_data JSONB,
response_data JSONB,
status VARCHAR NOT NULL,
duration_ms INTEGER,
created_at TIMESTAMP DEFAULT NOW()
);
```
### Caching Strategy
```typescript
// src/services/cacheService.ts
class CacheService {
// Multi-layer caching strategy
private memoryCache: Map<string, CacheEntry> = new Map();
private redisCache: Redis;
async get<T>(key: string): Promise<T | null> {
// L1: Memory cache
const memoryEntry = this.memoryCache.get(key);
if (memoryEntry && !this.isExpired(memoryEntry)) {
return memoryEntry.value;
}
// L2: Redis cache
const redisValue = await this.redisCache.get(key);
if (redisValue) {
const value = JSON.parse(redisValue);
this.memoryCache.set(key, { value, expiry: Date.now() + 60000 });
return value;
}
return null;
}
}
```
**Cache Layers:**
- **L1 (Memory)**: Fast access for frequently used data
- **L2 (Redis)**: Shared cache across instances
- **L3 (Database)**: Persistent storage with query optimization
## Communication Patterns
### Request Flow
```mermaid
sequenceDiagram
participant Client
participant API
participant Auth
participant Router
participant MCP
participant Server
Client->>API: HTTP Request
API->>Auth: Validate Token
Auth-->>API: User Context
API->>Router: Route Request
Router->>Router: Find Target Server
Router->>MCP: Execute Request
MCP->>Server: MCP Protocol
Server-->>MCP: MCP Response
MCP-->>Router: Formatted Response
Router-->>API: Response Data
API-->>Client: HTTP Response
```
### WebSocket Communication
```typescript
// src/services/websocketService.ts
class WebSocketService {
private connections: Map<string, WebSocket> = new Map();
handleConnection(ws: WebSocket, userId: string): void {
this.connections.set(userId, ws);
ws.on('message', async (data) => {
const message = JSON.parse(data.toString());
await this.handleMessage(userId, message);
});
ws.on('close', () => {
this.connections.delete(userId);
});
}
broadcast(event: string, data: any): void {
this.connections.forEach((ws) => {
ws.send(JSON.stringify({ event, data }));
});
}
}
```
### Event-Driven Architecture
```typescript
// src/events/eventBus.ts
class EventBus {
private listeners: Map<string, EventListener[]> = new Map();
emit(event: string, data: any): void {
const handlers = this.listeners.get(event) || [];
handlers.forEach((handler) => handler(data));
}
on(event: string, handler: EventListener): void {
const handlers = this.listeners.get(event) || [];
handlers.push(handler);
this.listeners.set(event, handlers);
}
}
// Usage
eventBus.on('server.started', (data) => {
logger.info(`Server ${data.name} started`);
monitoringService.updateServerStatus(data.name, 'running');
});
```
## Security Architecture
### Authentication Flow
```mermaid
graph LR
A[Client] --> B[Login Request]
B --> C[Validate Credentials]
C --> D[Generate JWT]
D --> E[Create Session]
E --> F[Return Token]
F --> G[Store in Cookie/Header]
G --> H[Subsequent Requests]
H --> I[Validate Token]
I --> J[Check Permissions]
J --> K[Allow/Deny Access]
```
### Authorization Model
```typescript
// Role-Based Access Control (RBAC)
interface Permission {
resource: string; // e.g., 'servers', 'groups', 'users'
action: string; // e.g., 'create', 'read', 'update', 'delete'
scope?: string; // e.g., 'own', 'group', 'all'
}
interface Role {
name: string;
permissions: Permission[];
}
const roles: Role[] = [
{
name: 'admin',
permissions: [{ resource: '*', action: '*', scope: 'all' }],
},
{
name: 'manager',
permissions: [
{ resource: 'servers', action: '*', scope: 'group' },
{ resource: 'groups', action: 'read', scope: 'all' },
],
},
{
name: 'user',
permissions: [
{ resource: 'servers', action: 'read', scope: 'group' },
{ resource: 'tools', action: 'execute', scope: 'group' },
],
},
];
```
## Scalability Considerations
### Horizontal Scaling
```yaml
# Kubernetes deployment for scaling
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcphub
spec:
replicas: 3
selector:
matchLabels:
app: mcphub
template:
spec:
containers:
- name: mcphub
image: mcphub:latest
resources:
requests:
memory: '256Mi'
cpu: '200m'
limits:
memory: '512Mi'
cpu: '500m'
```
### Load Balancing Strategy
```typescript
// src/services/loadBalancer.ts
class LoadBalancer {
private servers: ServerInstance[] = [];
private algorithm: 'round-robin' | 'least-connections' | 'weighted';
selectServer(): ServerInstance {
switch (this.algorithm) {
case 'round-robin':
return this.roundRobin();
case 'least-connections':
return this.leastConnections();
case 'weighted':
return this.weighted();
}
}
}
```
### Database Scaling
```typescript
// Database connection management
class DatabaseManager {
private readPool: Pool; // Read replicas
private writePool: Pool; // Primary database
async query(sql: string, params: any[]): Promise<any> {
if (this.isReadOperation(sql)) {
return this.readPool.query(sql, params);
} else {
return this.writePool.query(sql, params);
}
}
}
```
## Performance Optimization
### Query Optimization
```sql
-- Optimized queries with proper indexing
CREATE INDEX CONCURRENTLY idx_servers_status_group
ON servers(status, group_name)
WHERE status IN ('running', 'starting');
CREATE INDEX CONCURRENTLY idx_tool_embeddings_similarity
ON tool_embeddings USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
CREATE INDEX CONCURRENTLY idx_request_logs_performance
ON request_logs(created_at, status, duration_ms)
WHERE created_at > NOW() - INTERVAL '30 days';
```
### Caching Strategy
```typescript
// Multi-level caching
class CacheManager {
// Cache server configurations
@Cache({ ttl: 300, key: 'server-config' })
async getServerConfig(name: string): Promise<ServerConfig> {
return this.database.getServerConfig(name);
}
// Cache tool metadata for smart routing
@Cache({ ttl: 3600, key: 'tool-metadata' })
async getToolMetadata(): Promise<ToolMetadata[]> {
return this.database.getToolMetadata();
}
// Cache user permissions
@Cache({ ttl: 600, key: 'user-permissions' })
async getUserPermissions(userId: string): Promise<Permission[]> {
return this.authService.getUserPermissions(userId);
}
}
```
## Monitoring & Observability
### Metrics Collection
```typescript
// src/services/metricsService.ts
class MetricsService {
private prometheus: PrometheusRegistry;
constructor() {
this.initializeMetrics();
}
private initializeMetrics(): void {
// Request metrics
this.requestCount = new Counter({
name: 'mcphub_requests_total',
help: 'Total number of requests',
labelNames: ['method', 'route', 'status'],
});
// Server metrics
this.serverStatus = new Gauge({
name: 'mcphub_server_status',
help: 'Status of MCP servers',
labelNames: ['server_name', 'status'],
});
// Performance metrics
this.responseTime = new Histogram({
name: 'mcphub_response_time_seconds',
help: 'Response time in seconds',
labelNames: ['route'],
});
}
}
```
### Distributed Tracing
```typescript
// OpenTelemetry integration
import { trace } from '@opentelemetry/api';
class MCPService {
async executeRequest(serverName: string, request: MCPRequest): Promise<MCPResponse> {
const span = trace.getActiveSpan();
span?.setAttributes({
'mcp.server': serverName,
'mcp.tool': request.tool,
'mcp.request_id': request.id,
});
try {
const response = await this.sendRequest(serverName, request);
span?.setStatus({ code: SpanStatusCode.OK });
return response;
} catch (error) {
span?.setStatus({
code: SpanStatusCode.ERROR,
message: error.message,
});
throw error;
}
}
}
```
## Extension Points
### Plugin Architecture
```typescript
// Plugin interface
interface MCPHubPlugin {
name: string;
version: string;
init(context: PluginContext): Promise<void>;
destroy(): Promise<void>;
}
// Plugin manager
class PluginManager {
private plugins: Map<string, MCPHubPlugin> = new Map();
async loadPlugin(plugin: MCPHubPlugin): Promise<void> {
await plugin.init(this.createContext());
this.plugins.set(plugin.name, plugin);
}
private createContext(): PluginContext {
return {
eventBus: this.eventBus,
logger: this.logger,
database: this.database,
// ... other services
};
}
}
```
### Custom Middleware
```typescript
// Custom middleware registration
class MiddlewareManager {
register(middleware: Middleware): void {
this.app.use(middleware);
}
registerRoute(path: string, middleware: Middleware): void {
this.app.use(path, middleware);
}
}
// Example custom middleware
const customAuthMiddleware: Middleware = (req, res, next) => {
// Custom authentication logic
next();
};
```
## Deployment Architecture
### Container Strategy
```dockerfile
# Multi-stage build for optimized images
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine AS runtime
RUN addgroup -g 1001 -S nodejs
RUN adduser -S mcphub -u 1001
WORKDIR /app
COPY --from=builder --chown=mcphub:nodejs /app .
USER mcphub
EXPOSE 3000
CMD ["node", "dist/server.js"]
```
### Infrastructure as Code
```terraform
# Terraform configuration for AWS deployment
resource "aws_ecs_cluster" "mcphub" {
name = "mcphub-cluster"
}
resource "aws_ecs_service" "mcphub" {
name = "mcphub"
cluster = aws_ecs_cluster.mcphub.id
task_definition = aws_ecs_task_definition.mcphub.arn
desired_count = 3
load_balancer {
target_group_arn = aws_lb_target_group.mcphub.arn
container_name = "mcphub"
container_port = 3000
}
}
```
This architecture provides a solid foundation for building a scalable, maintainable, and extensible MCP server management platform while following modern software development best practices.

View File

@@ -0,0 +1,597 @@
---
title: 'Contributing to MCPHub'
description: 'Learn how to contribute to the MCPHub project'
---
## Welcome Contributors! 🎉
Thank you for your interest in contributing to MCPHub! This guide will help you get started with contributing to the project, whether you're fixing bugs, adding features, improving documentation, or helping with testing.
## Quick Start
1. **Fork the repository** on GitHub
2. **Clone your fork** locally
3. **Create a branch** for your changes
4. **Make your changes** following our guidelines
5. **Test your changes** thoroughly
6. **Submit a pull request**
## Ways to Contribute
### 🐛 Bug Reports
Help us improve MCPHub by reporting bugs:
- **Search existing issues** first to avoid duplicates
- **Use the bug report template** when creating issues
- **Provide detailed information** including steps to reproduce
- **Include system information** (OS, Node.js version, etc.)
```markdown
## Bug Report Template
**Description**
A clear description of what the bug is.
**Steps to Reproduce**
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected Behavior**
What you expected to happen.
**Actual Behavior**
What actually happened.
**Environment**
- OS: [e.g. macOS 12.0]
- Node.js: [e.g. 18.17.0]
- MCPHub Version: [e.g. 1.2.3]
- Browser: [e.g. Chrome 91.0]
**Additional Context**
Any other context about the problem.
```
### ✨ Feature Requests
We welcome feature suggestions:
- **Check existing feature requests** to avoid duplicates
- **Use the feature request template**
- **Explain the use case** and why it would be valuable
- **Consider implementation complexity**
### 🔧 Code Contributions
Ready to write some code? Here's how:
#### Setting Up Development Environment
```bash
# 1. Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/mcphub.git
cd mcphub
# 2. Add upstream remote
git remote add upstream https://github.com/samanhappy/mcphub.git
# 3. Install dependencies
pnpm install
# 4. Set up environment
cp .env.example .env.development
# 5. Start development environment
docker-compose -f docker-compose.dev.yml up -d
pnpm run migrate
pnpm run seed
# 6. Start development server
pnpm run dev
```
#### Branch Naming Convention
Use descriptive branch names with prefixes:
```bash
# Features
git checkout -b feature/smart-routing-improvements
git checkout -b feature/user-authentication
# Bug fixes
git checkout -b fix/server-startup-error
git checkout -b fix/memory-leak-in-cache
# Documentation
git checkout -b docs/api-reference-update
git checkout -b docs/deployment-guide
# Refactoring
git checkout -b refactor/auth-service-cleanup
git checkout -b refactor/database-queries
```
### 📚 Documentation
Help improve our documentation:
- **Fix typos and grammar**
- **Improve existing guides**
- **Add missing documentation**
- **Create tutorials and examples**
- **Translate documentation**
## Development Guidelines
### Code Style
We use ESLint and Prettier to maintain code quality:
```bash
# Check code style
pnpm run lint
# Fix automatically fixable issues
pnpm run lint:fix
# Format code
pnpm run format
# Type check
pnpm run type-check
```
#### TypeScript Best Practices
```typescript
// ✅ Good: Use proper types
interface MCPServerConfig {
name: string;
command: string;
args: string[];
env?: Record<string, string>;
}
// ✅ Good: Use async/await
async function startServer(config: MCPServerConfig): Promise<void> {
try {
await mcpService.start(config);
} catch (error) {
logger.error('Failed to start server', { error, config });
throw error;
}
}
// ❌ Bad: Using any type
function processData(data: any): any {
return data.something();
}
// ❌ Bad: Not handling errors
async function riskyOperation(): Promise<void> {
await dangerousFunction(); // Could throw
}
```
#### React/Frontend Guidelines
```tsx
// ✅ Good: Functional components with proper typing
interface ServerCardProps {
server: MCPServer;
onStart: (serverId: string) => void;
onStop: (serverId: string) => void;
}
const ServerCard: React.FC<ServerCardProps> = ({ server, onStart, onStop }) => {
const handleStart = useCallback(() => {
onStart(server.id);
}, [server.id, onStart]);
return (
<Card data-testid={`server-card-${server.id}`}>
<CardHeader>
<CardTitle>{server.name}</CardTitle>
<Badge variant={server.status === 'running' ? 'success' : 'secondary'}>
{server.status}
</Badge>
</CardHeader>
<CardContent>
<p>{server.description}</p>
</CardContent>
<CardActions>
{server.status === 'stopped' ? (
<Button onClick={handleStart}>Start</Button>
) : (
<Button onClick={() => onStop(server.id)}>Stop</Button>
)}
</CardActions>
</Card>
);
};
```
### Testing Requirements
All contributions must include appropriate tests:
#### Unit Tests
```typescript
// src/services/__tests__/mcpService.test.ts
import { MCPService } from '../mcpService';
import { mockLogger, mockDatabase } from '../../__mocks__';
describe('MCPService', () => {
let service: MCPService;
beforeEach(() => {
service = new MCPService(mockLogger, mockDatabase);
});
describe('startServer', () => {
it('should start a server successfully', async () => {
const config = {
name: 'test-server',
command: 'node',
args: ['server.js'],
};
await service.startServer(config);
expect(service.getServerStatus('test-server')).toBe('running');
});
it('should handle server startup failures', async () => {
const invalidConfig = {
name: 'invalid-server',
command: 'invalid-command',
args: [],
};
await expect(service.startServer(invalidConfig)).rejects.toThrow(
'Failed to start server: Command not found',
);
});
});
});
```
#### Integration Tests
```typescript
// src/__tests__/integration/server-api.test.ts
import request from 'supertest';
import { app } from '../../app';
import { setupTestDatabase, teardownTestDatabase } from '../helpers/database';
describe('Server API Integration', () => {
beforeAll(async () => {
await setupTestDatabase();
});
afterAll(async () => {
await teardownTestDatabase();
});
describe('POST /api/servers', () => {
it('should create a new server', async () => {
const serverData = {
name: 'test-server',
command: 'node',
args: ['server.js'],
group: 'development',
};
const response = await request(app).post('/api/servers').send(serverData).expect(201);
expect(response.body).toMatchObject({
name: 'test-server',
status: 'stopped',
group: 'development',
});
});
});
});
```
#### End-to-End Tests
```typescript
// tests/e2e/server-management.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Server Management', () => {
test('should create and manage MCP servers', async ({ page }) => {
await page.goto('/dashboard');
// Create new server
await page.click('[data-testid="add-server-button"]');
await page.fill('[data-testid="server-name-input"]', 'test-server');
await page.fill('[data-testid="server-command-input"]', 'node server.js');
await page.click('[data-testid="save-server-button"]');
// Verify server appears in list
await expect(page.locator('[data-testid="server-list"]')).toContainText('test-server');
// Start the server
await page.click('[data-testid="start-server-test-server"]');
// Verify server is running
await expect(page.locator('[data-testid="server-status-test-server"]')).toContainText(
'running',
);
});
});
```
### Commit Guidelines
We follow [Conventional Commits](https://www.conventionalcommits.org/):
```bash
# Format: <type>[optional scope]: <description>
# Features
git commit -m "feat(auth): add JWT token refresh functionality"
git commit -m "feat(ui): implement server status dashboard"
# Bug fixes
git commit -m "fix(api): resolve memory leak in server manager"
git commit -m "fix(db): handle connection timeout gracefully"
# Documentation
git commit -m "docs(api): add examples for server endpoints"
git commit -m "docs(readme): update installation instructions"
# Refactoring
git commit -m "refactor(services): extract auth logic into separate module"
# Tests
git commit -m "test(api): add integration tests for server management"
# Chores
git commit -m "chore(deps): update dependencies to latest versions"
```
#### Commit Types
- **feat**: New feature
- **fix**: Bug fix
- **docs**: Documentation changes
- **style**: Code style changes (formatting, etc.)
- **refactor**: Code refactoring
- **test**: Adding or updating tests
- **chore**: Maintenance tasks
- **perf**: Performance improvements
- **ci**: CI/CD changes
### Pull Request Process
#### Before Submitting
```bash
# 1. Sync with upstream
git fetch upstream
git checkout main
git merge upstream/main
# 2. Rebase your feature branch
git checkout feature/your-feature
git rebase main
# 3. Run all checks
pnpm run lint
pnpm run type-check
pnpm run test
pnpm run build
# 4. Update documentation if needed
# 5. Add/update tests for your changes
```
#### Pull Request Template
```markdown
## Description
Brief description of the changes and motivation.
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] E2E tests pass (if applicable)
- [ ] Manual testing completed
## Documentation
- [ ] Code is self-documenting
- [ ] API documentation updated
- [ ] User documentation updated
- [ ] README updated (if needed)
## Checklist
- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
## Screenshots (if applicable)
Add screenshots to help explain your changes.
## Additional Notes
Any additional information that reviewers should know.
```
### Code Review Process
#### For Contributors
- **Be patient**: Reviews take time, and reviewers may have questions
- **Be responsive**: Address feedback promptly and clearly
- **Be open**: Accept constructive criticism and suggestions
- **Ask questions**: If feedback is unclear, ask for clarification
#### For Reviewers
- **Be constructive**: Provide helpful suggestions, not just criticism
- **Be specific**: Point out exact issues and suggest solutions
- **Be timely**: Review PRs within a reasonable timeframe
- **Be encouraging**: Recognize good work and improvements
## Community Guidelines
### Code of Conduct
We are committed to providing a welcoming and inspiring community for all:
- **Be respectful**: Treat everyone with respect and kindness
- **Be inclusive**: Welcome people of all backgrounds and skill levels
- **Be collaborative**: Work together towards common goals
- **Be patient**: Help others learn and grow
- **Be professional**: Maintain professional communication
### Communication Channels
- **GitHub Issues**: Bug reports and feature requests
- **GitHub Discussions**: General questions and community chat
- **Discord**: Real-time community chat (link in README)
- **Email**: Security issues and private matters
## Getting Help
### Documentation
- [Getting Started Guide](./getting-started.mdx)
- [Architecture Overview](./architecture.mdx)
- [API Reference](../api-reference/introduction.mdx)
- [Configuration Guide](../configuration/mcp-settings.mdx)
### Common Issues
**Build Failures**
```bash
# Clear and reinstall dependencies
rm -rf node_modules pnpm-lock.yaml
pnpm install
# Clear build cache
rm -rf dist/
pnpm run build
```
**Test Failures**
```bash
# Run tests with verbose output
pnpm run test -- --verbose
# Run specific test file
pnpm test src/services/mcpService.test.ts
# Debug tests
pnpm run test:debug
```
**Database Issues**
```bash
# Reset database
pnpm run db:reset
# Run migrations
pnpm run migrate
# Seed development data
pnpm run seed
```
### Getting Support
If you need help:
1. **Check the documentation** first
2. **Search existing issues** on GitHub
3. **Ask in GitHub Discussions** for general questions
4. **Create an issue** if you found a bug
5. **Join our Discord** for real-time help
## Recognition
Contributors will be recognized in several ways:
- **Contributors file**: All contributors are listed in CONTRIBUTORS.md
- **Release notes**: Significant contributions are mentioned in release notes
- **GitHub badges**: Active contributors receive special recognition
- **Community showcase**: Outstanding contributions are featured in our blog
## Advanced Topics
### Maintainer Guidelines
For project maintainers:
#### Release Process
```bash
# 1. Create release branch
git checkout -b release/v1.2.0
# 2. Update version
npm version 1.2.0 --no-git-tag-version
# 3. Update changelog
# Edit CHANGELOG.md
# 4. Commit changes
git add .
git commit -m "chore(release): prepare v1.2.0"
# 5. Create PR for review
# 6. After merge, tag release
git tag v1.2.0
git push origin v1.2.0
```
#### Security Handling
For security issues:
1. **Do not** create public issues
2. **Email** security@mcphub.dev
3. **Wait** for response before disclosure
4. **Coordinate** with maintainers on fixes
### Architectural Decisions
When making significant changes:
1. **Create an RFC** (Request for Comments) issue
2. **Discuss** with the community
3. **Get approval** from maintainers
4. **Document** decisions in ADR (Architecture Decision Records)
## Thank You! 🙏
Thank you for taking the time to contribute to MCPHub! Every contribution, no matter how small, helps make the project better for everyone. We look forward to collaborating with you!

View File

@@ -0,0 +1,244 @@
---
title: 'Getting Started with Development'
description: 'Learn how to set up your development environment for MCPHub'
---
# Getting Started with Development
This guide will help you set up your development environment for contributing to MCPHub.
## Prerequisites
Before you begin, ensure you have the following installed:
- **Node.js** (version 18 or higher)
- **pnpm** (recommended package manager)
- **Git**
- **Docker** (optional, for containerized development)
## Setting Up the Development Environment
### 1. Clone the Repository
```bash
git clone https://github.com/your-username/mcphub.git
cd mcphub
```
### 2. Install Dependencies
```bash
pnpm install
```
### 3. Environment Configuration
Create a `.env` file in the root directory:
```bash
cp .env.example .env
```
Configure the following environment variables:
```env
# Server Configuration
PORT=3000
NODE_ENV=development
# Database Configuration
DATABASE_URL=postgresql://username:password@localhost:5432/mcphub
# JWT Configuration
JWT_SECRET=your-secret-key
JWT_EXPIRES_IN=24h
# OpenAI Configuration (for smart routing)
OPENAI_API_KEY=your-openai-api-key
```
### 4. Database Setup
If using PostgreSQL, create a database:
```bash
createdb mcphub
```
### 5. MCP Server Configuration
Create or modify `mcp_settings.json`:
```json
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
}
}
}
```
## Development Workflow
### Running the Development Server
Start both backend and frontend in development mode:
```bash
pnpm dev
```
This will start:
- Backend server on `http://localhost:3000`
- Frontend development server on `http://localhost:5173`
### Running Backend Only
```bash
pnpm backend:dev
```
### Running Frontend Only
```bash
pnpm frontend:dev
```
### Building the Project
Build both backend and frontend:
```bash
pnpm build
```
## Project Structure
```
mcphub/
├── src/ # Backend source code
│ ├── controllers/ # Express controllers
│ ├── routes/ # API routes
│ ├── services/ # Business logic
│ ├── models/ # Database models
│ └── utils/ # Utility functions
├── frontend/ # Frontend React application
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── services/ # API services
│ │ └── utils/ # Frontend utilities
├── docs/ # Documentation
├── bin/ # CLI scripts
└── scripts/ # Build and utility scripts
```
## Development Tools
### Linting and Formatting
```bash
# Run ESLint
pnpm lint
# Format code with Prettier
pnpm format
```
### Testing
```bash
# Run tests
pnpm test
# Run tests in watch mode
pnpm test --watch
```
### Debugging
To debug the backend with Node.js inspector:
```bash
pnpm backend:debug
```
Then attach your debugger to `http://localhost:9229`.
## Making Changes
### Backend Development
1. **Controllers**: Handle HTTP requests and responses
2. **Services**: Implement business logic
3. **Models**: Define database schemas
4. **Routes**: Define API endpoints
### Frontend Development
1. **Components**: Reusable React components
2. **Pages**: Route-specific components
3. **Services**: API communication
4. **Hooks**: Custom React hooks
### Adding New MCP Servers
1. Update `mcp_settings.json` with the new server configuration
2. Test the server integration
3. Update documentation if needed
## Common Development Tasks
### Adding a New API Endpoint
1. Create a controller in `src/controllers/`
2. Define the route in `src/routes/`
3. Add any necessary middleware
4. Write tests for the new endpoint
### Adding a New Frontend Feature
1. Create components in `frontend/src/components/`
2. Add routes if needed
3. Implement API integration
4. Style with Tailwind CSS
### Database Migrations
When modifying database schemas:
1. Update models in `src/models/`
2. Create migration scripts if using TypeORM
3. Test migrations locally
## Troubleshooting
### Common Issues
**Port conflicts**: Ensure ports 3000 and 5173 are available
**Database connection**: Verify PostgreSQL is running and credentials are correct
**MCP server startup**: Check server configurations in `mcp_settings.json`
**Permission issues**: Ensure MCP servers have necessary permissions
### Getting Help
- Check the [Contributing Guide](/development/contributing)
- Review [Architecture Documentation](/development/architecture)
- Open an issue on GitHub for bugs
- Join our community discussions
## Next Steps
- Read the [Architecture Overview](/development/architecture)
- Learn about [Contributing Guidelines](/development/contributing)
- Explore [Configuration Options](/configuration/environment-variables)

174
docs/docs.json Normal file
View File

@@ -0,0 +1,174 @@
{
"$schema": "https://mintlify.com/docs.json",
"theme": "mint",
"name": "MCPHub Documentation",
"description": "The Unified Hub for Model Context Protocol (MCP) Servers",
"colors": {
"primary": "#16A34A",
"light": "#07C983",
"dark": "#15803D"
},
"favicon": "/favicon.ico",
"navigation": {
"tabs": [
{
"tab": "English",
"groups": [
{
"group": "Get Started",
"pages": [
"index",
"quickstart",
"installation"
]
},
{
"group": "Core Features",
"pages": [
"features/server-management",
"features/group-management",
"features/smart-routing",
"features/oauth"
]
},
{
"group": "Configuration",
"pages": [
"configuration/mcp-settings",
"configuration/environment-variables",
"configuration/docker-setup",
"configuration/nginx",
"configuration/database-configuration"
]
}
]
},
{
"tab": "中文",
"groups": [
{
"group": "开始使用",
"pages": [
"zh/index",
"zh/quickstart",
"zh/installation"
]
},
{
"group": "核心功能",
"pages": [
"zh/features/server-management",
"zh/features/group-management",
"zh/features/smart-routing",
"zh/features/oauth"
]
},
{
"group": "配置指南",
"pages": [
"zh/configuration/mcp-settings",
"zh/configuration/environment-variables",
"zh/configuration/docker-setup",
"zh/configuration/nginx",
"zh/configuration/database-configuration"
]
}
]
},
{
"tab": "API",
"groups": [
{
"group": "MCP Endpoints",
"pages": [
"api-reference/introduction",
"api-reference/mcp-http",
"api-reference/mcp-sse",
"api-reference/smart-routing"
]
},
{
"group": "OpenAPI Endpoints",
"pages": [
"api-reference/openapi"
]
},
{
"group": "Management Endpoints",
"pages": [
"api-reference/servers",
"api-reference/groups",
"api-reference/users",
"api-reference/tools",
"api-reference/prompts",
"api-reference/auth",
"api-reference/logs",
"api-reference/config",
"api-reference/system"
]
}
]
},
{
"tab": "接口",
"groups": [
{
"group": "MCP 端点",
"pages": [
"zh/api-reference/introduction",
"zh/api-reference/mcp-http",
"zh/api-reference/mcp-sse",
"zh/api-reference/smart-routing"
]
},
{
"group": "OpenAPI 端点",
"pages": [
"zh/api-reference/openapi"
]
},
{
"group": "管理端点",
"pages": [
"zh/api-reference/servers",
"zh/api-reference/groups",
"zh/api-reference/users",
"zh/api-reference/tools",
"zh/api-reference/prompts",
"zh/api-reference/auth",
"zh/api-reference/logs",
"zh/api-reference/config",
"zh/api-reference/system"
]
}
]
}
],
"global": {
"anchors": []
}
},
"logo": {
"light": "/logo/light.svg",
"dark": "/logo/dark.svg"
},
"navbar": {
"links": [
{
"label": "Demo",
"href": "https://demo.mcphubx.com"
}
],
"primary": {
"type": "button",
"label": "Get Started",
"href": "https://docs.mcphubx.com/quickstart"
}
},
"footer": {
"socials": {
"github": "https://github.com/samanhappy/mcphub",
"discord": "https://discord.gg/qMKNsn5Q"
}
}
}

37
docs/essentials/code.mdx Normal file
View File

@@ -0,0 +1,37 @@
---
title: 'Code Blocks'
description: 'Display inline code and code blocks'
icon: 'code'
---
## Basic
### Inline Code
To denote a `word` or `phrase` as code, enclose it in backticks (`).
```
To denote a `word` or `phrase` as code, enclose it in backticks (`).
```
### Code Block
Use [fenced code blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) by enclosing code in three backticks and follow the leading ticks with the programming language of your snippet to get syntax highlighting. Optionally, you can also write the name of your code after the programming language.
```java HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
````md
```java HelloWorld.java
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
````

View File

@@ -0,0 +1,59 @@
---
title: 'Images and Embeds'
description: 'Add image, video, and other HTML elements'
icon: 'image'
---
<img
style={{ borderRadius: '0.5rem' }}
src="https://mintlify-assets.b-cdn.net/bigbend.jpg"
/>
## Image
### Using Markdown
The [markdown syntax](https://www.markdownguide.org/basic-syntax/#images) lets you add images using the following code
```md
![title](/path/image.jpg)
```
Note that the image file size must be less than 5MB. Otherwise, we recommend hosting on a service like [Cloudinary](https://cloudinary.com/) or [S3](https://aws.amazon.com/s3/). You can then use that URL and embed.
### Using Embeds
To get more customizability with images, you can also use [embeds](/writing-content/embed) to add images
```html
<img height="200" src="/path/image.jpg" />
```
## Embeds and HTML elements
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/4KzFe50RQkQ"
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
style={{ width: '100%', borderRadius: '0.5rem' }}
></iframe>
<br />
<Tip>
Mintlify supports [HTML tags in Markdown](https://www.markdownguide.org/basic-syntax/#html). This is helpful if you prefer HTML tags to Markdown syntax, and lets you create documentation with infinite flexibility.
</Tip>
### iFrames
Loads another HTML page within the document. Most commonly used for embedding videos.
```html
<iframe src="https://www.youtube.com/embed/4KzFe50RQkQ"> </iframe>
```

View File

@@ -0,0 +1,88 @@
---
title: 'Markdown Syntax'
description: 'Text, title, and styling in standard markdown'
icon: 'text-size'
---
## Titles
Best used for section headers.
```md
## Titles
```
### Subtitles
Best use to subsection headers.
```md
### Subtitles
```
<Tip>
Each **title** and **subtitle** creates an anchor and also shows up on the table of contents on the right.
</Tip>
## Text Formatting
We support most markdown formatting. Simply add `**`, `_`, or `~` around text to format it.
| Style | How to write it | Result |
| ------------- | ----------------- | --------------- |
| Bold | `**bold**` | **bold** |
| Italic | `_italic_` | _italic_ |
| Strikethrough | `~strikethrough~` | ~strikethrough~ |
You can combine these. For example, write `**_bold and italic_**` to get **_bold and italic_** text.
You need to use HTML to write superscript and subscript text. That is, add `<sup>` or `<sub>` around your text.
| Text Size | How to write it | Result |
| ----------- | ------------------------ | ---------------------- |
| Superscript | `<sup>superscript</sup>` | <sup>superscript</sup> |
| Subscript | `<sub>subscript</sub>` | <sub>subscript</sub> |
## Linking to Pages
You can add a link by wrapping text in `[]()`. You would write `[link to google](https://google.com)` to [link to google](https://google.com).
Links to pages in your docs need to be root-relative. Basically, you should include the entire folder path. For example, `[link to text](/writing-content/text)` links to the page "Text" in our components section.
Relative links like `[link to text](../text)` will open slower because we cannot optimize them as easily.
## Blockquotes
### Singleline
To create a blockquote, add a `>` in front of a paragraph.
> Dorothy followed her through many of the beautiful rooms in her castle.
```md
> Dorothy followed her through many of the beautiful rooms in her castle.
```
### Multiline
> Dorothy followed her through many of the beautiful rooms in her castle.
>
> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
```md
> Dorothy followed her through many of the beautiful rooms in her castle.
>
> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
```
### LaTeX
Mintlify supports [LaTeX](https://www.latex-project.org) through the Latex component.
<Latex>8 x (vk x H1 - H2) = (0,1)</Latex>
```md
<Latex>8 x (vk x H1 - H2) = (0,1)</Latex>
```

View File

@@ -0,0 +1,87 @@
---
title: 'Navigation'
description: 'The navigation field in docs.json defines the pages that go in the navigation menu'
icon: 'map'
---
The navigation menu is the list of links on every website.
You will likely update `docs.json` every time you add a new page. Pages do not show up automatically.
## Navigation syntax
Our navigation syntax is recursive which means you can make nested navigation groups. You don't need to include `.mdx` in page names.
<CodeGroup>
```json Regular Navigation
"navigation": {
"tabs": [
{
"tab": "Docs",
"groups": [
{
"group": "Getting Started",
"pages": ["quickstart"]
}
]
}
]
}
```
```json Nested Navigation
"navigation": {
"tabs": [
{
"tab": "Docs",
"groups": [
{
"group": "Getting Started",
"pages": [
"quickstart",
{
"group": "Nested Reference Pages",
"pages": ["nested-reference-page"]
}
]
}
]
}
]
}
```
</CodeGroup>
## Folders
Simply put your MDX files in folders and update the paths in `docs.json`.
For example, to have a page at `https://yoursite.com/your-folder/your-page` you would make a folder called `your-folder` containing an MDX file called `your-page.mdx`.
<Warning>
You cannot use `api` for the name of a folder unless you nest it inside another folder. Mintlify uses Next.js which reserves the top-level `api` folder for internal server calls. A folder name such as `api-reference` would be accepted.
</Warning>
```json Navigation With Folder
"navigation": {
"tabs": [
{
"tab": "Docs",
"groups": [
{
"group": "Group Name",
"pages": ["your-folder/your-page"]
}
]
}
]
}
```
## Hidden Pages
MDX files not included in `docs.json` will not show up in the sidebar but are accessible through the search bar and by linking directly to them.

View File

@@ -0,0 +1,110 @@
---
title: Reusable Snippets
description: Reusable, custom snippets to keep content in sync
icon: 'recycle'
---
import SnippetIntro from '/snippets/snippet-intro.mdx';
<SnippetIntro />
## Creating a custom snippet
**Pre-condition**: You must create your snippet file in the `snippets` directory.
<Note>
Any page in the `snippets` directory will be treated as a snippet and will not
be rendered into a standalone page. If you want to create a standalone page
from the snippet, import the snippet into another file and call it as a
component.
</Note>
### Default export
1. Add content to your snippet file that you want to re-use across multiple
locations. Optionally, you can add variables that can be filled in via props
when you import the snippet.
```mdx snippets/my-snippet.mdx
Hello world! This is my content I want to reuse across pages. My keyword of the
day is {word}.
```
<Warning>
The content that you want to reuse must be inside the `snippets` directory in
order for the import to work.
</Warning>
2. Import the snippet into your destination file.
```mdx destination-file.mdx
---
title: My title
description: My Description
---
import MySnippet from '/snippets/path/to/my-snippet.mdx';
## Header
Lorem impsum dolor sit amet.
<MySnippet word="bananas" />
```
### Reusable variables
1. Export a variable from your snippet file:
```mdx snippets/path/to/custom-variables.mdx
export const myName = 'my name';
export const myObject = { fruit: 'strawberries' };
```
2. Import the snippet from your destination file and use the variable:
```mdx destination-file.mdx
---
title: My title
description: My Description
---
import { myName, myObject } from '/snippets/path/to/custom-variables.mdx';
Hello, my name is {myName} and I like {myObject.fruit}.
```
### Reusable components
1. Inside your snippet file, create a component that takes in props by exporting
your component in the form of an arrow function.
```mdx snippets/custom-component.mdx
export const MyComponent = ({ title }) => (
<div>
<h1>{title}</h1>
<p>... snippet content ...</p>
</div>
);
```
<Warning>
MDX does not compile inside the body of an arrow function. Stick to HTML
syntax when you can or use a default export if you need to use MDX.
</Warning>
2. Import the snippet into your destination file and pass in the props
```mdx destination-file.mdx
---
title: My title
description: My Description
---
import { MyComponent } from '/snippets/custom-component.mdx';
Lorem ipsum dolor sit amet.
<MyComponent title={'Custom title'} />
```

View File

@@ -0,0 +1,318 @@
---
title: 'Global Settings'
description: 'Mintlify gives you complete control over the look and feel of your documentation using the docs.json file'
icon: 'gear'
---
Every Mintlify site needs a `docs.json` file with the core configuration settings. Learn more about the [properties](#properties) below.
## Properties
<ResponseField name="name" type="string" required>
Name of your project. Used for the global title.
Example: `mintlify`
</ResponseField>
<ResponseField name="navigation" type="Navigation[]" required>
An array of groups with all the pages within that group
<Expandable title="Navigation">
<ResponseField name="group" type="string">
The name of the group.
Example: `Settings`
</ResponseField>
<ResponseField name="pages" type="string[]">
The relative paths to the markdown files that will serve as pages.
Example: `["customization", "page"]`
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="logo" type="string or object">
Path to logo image or object with path to "light" and "dark" mode logo images
<Expandable title="Logo">
<ResponseField name="light" type="string">
Path to the logo in light mode
</ResponseField>
<ResponseField name="dark" type="string">
Path to the logo in dark mode
</ResponseField>
<ResponseField name="href" type="string" default="/">
Where clicking on the logo links you to
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="favicon" type="string">
Path to the favicon image
</ResponseField>
<ResponseField name="colors" type="Colors">
Hex color codes for your global theme
<Expandable title="Colors">
<ResponseField name="primary" type="string" required>
The primary color. Used for most often for highlighted content, section
headers, accents, in light mode
</ResponseField>
<ResponseField name="light" type="string">
The primary color for dark mode. Used for most often for highlighted
content, section headers, accents, in dark mode
</ResponseField>
<ResponseField name="dark" type="string">
The primary color for important buttons
</ResponseField>
<ResponseField name="background" type="object">
The color of the background in both light and dark mode
<Expandable title="Object">
<ResponseField name="light" type="string" required>
The hex color code of the background in light mode
</ResponseField>
<ResponseField name="dark" type="string" required>
The hex color code of the background in dark mode
</ResponseField>
</Expandable>
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="topbarLinks" type="TopbarLink[]">
Array of `name`s and `url`s of links you want to include in the topbar
<Expandable title="TopbarLink">
<ResponseField name="name" type="string">
The name of the button.
Example: `Contact us`
</ResponseField>
<ResponseField name="url" type="string">
The url once you click on the button. Example: `https://mintlify.com/docs`
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="topbarCtaButton" type="Call to Action">
<Expandable title="Topbar Call to Action">
<ResponseField name="type" type={'"link" or "github"'} default="link">
Link shows a button. GitHub shows the repo information at the url provided including the number of GitHub stars.
</ResponseField>
<ResponseField name="url" type="string">
If `link`: What the button links to.
If `github`: Link to the repository to load GitHub information from.
</ResponseField>
<ResponseField name="name" type="string">
Text inside the button. Only required if `type` is a `link`.
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="versions" type="string[]">
Array of version names. Only use this if you want to show different versions
of docs with a dropdown in the navigation bar.
</ResponseField>
<ResponseField name="anchors" type="Anchor[]">
An array of the anchors, includes the `icon`, `color`, and `url`.
<Expandable title="Anchor">
<ResponseField name="icon" type="string">
The [Font Awesome](https://fontawesome.com/search?q=heart) icon used to feature the anchor.
Example: `comments`
</ResponseField>
<ResponseField name="name" type="string">
The name of the anchor label.
Example: `Community`
</ResponseField>
<ResponseField name="url" type="string">
The start of the URL that marks what pages go in the anchor. Generally, this is the name of the folder you put your pages in.
</ResponseField>
<ResponseField name="color" type="string">
The hex color of the anchor icon background. Can also be a gradient if you pass an object with the properties `from` and `to` that are each a hex color.
</ResponseField>
<ResponseField name="version" type="string">
Used if you want to hide an anchor until the correct docs version is selected.
</ResponseField>
<ResponseField name="isDefaultHidden" type="boolean" default="false">
Pass `true` if you want to hide the anchor until you directly link someone to docs inside it.
</ResponseField>
<ResponseField name="iconType" default="duotone" type="string">
One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin"
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="topAnchor" type="Object">
Override the default configurations for the top-most anchor.
<Expandable title="Object">
<ResponseField name="name" default="Documentation" type="string">
The name of the top-most anchor
</ResponseField>
<ResponseField name="icon" default="book-open" type="string">
Font Awesome icon.
</ResponseField>
<ResponseField name="iconType" default="duotone" type="string">
One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin"
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="tabs" type="Tabs[]">
An array of navigational tabs.
<Expandable title="Tabs">
<ResponseField name="name" type="string">
The name of the tab label.
</ResponseField>
<ResponseField name="url" type="string">
The start of the URL that marks what pages go in the tab. Generally, this
is the name of the folder you put your pages in.
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="api" type="API">
Configuration for API settings. Learn more about API pages at [API Components](/api-playground/demo).
<Expandable title="API">
<ResponseField name="baseUrl" type="string">
The base url for all API endpoints. If `baseUrl` is an array, it will enable for multiple base url
options that the user can toggle.
</ResponseField>
<ResponseField name="auth" type="Auth">
<Expandable title="Auth">
<ResponseField name="method" type='"bearer" | "basic" | "key"'>
The authentication strategy used for all API endpoints.
</ResponseField>
<ResponseField name="name" type="string">
The name of the authentication parameter used in the API playground.
If method is `basic`, the format should be `[usernameName]:[passwordName]`
</ResponseField>
<ResponseField name="inputPrefix" type="string">
The default value that's designed to be a prefix for the authentication input field.
E.g. If an `inputPrefix` of `AuthKey` would inherit the default input result of the authentication field as `AuthKey`.
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="playground" type="Playground">
Configurations for the API playground
<Expandable title="Playground">
<ResponseField name="mode" default="show" type='"show" | "simple" | "hide"'>
Whether the playground is showing, hidden, or only displaying the endpoint with no added user interactivity `simple`
Learn more at the [playground guides](/api-playground/demo)
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="maintainOrder" type="boolean">
Enabling this flag ensures that key ordering in OpenAPI pages matches the key ordering defined in the OpenAPI file.
<Warning>This behavior will soon be enabled by default, at which point this field will be deprecated.</Warning>
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="openapi" type="string | string[]">
A string or an array of strings of URL(s) or relative path(s) pointing to your
OpenAPI file.
Examples:
<CodeGroup>
```json Absolute
"openapi": "https://example.com/openapi.json"
```
```json Relative
"openapi": "/openapi.json"
```
```json Multiple
"openapi": ["https://example.com/openapi1.json", "/openapi2.json", "/openapi3.json"]
```
</CodeGroup>
</ResponseField>
<ResponseField name="footerSocials" type="FooterSocials">
An object of social media accounts where the key:property pair represents the social media platform and the account url.
Example:
```json
{
"x": "https://x.com/mintlify",
"website": "https://mintlify.com"
}
```
<Expandable title="FooterSocials">
<ResponseField name="[key]" type="string">
One of the following values `website`, `facebook`, `x`, `discord`, `slack`, `github`, `linkedin`, `instagram`, `hacker-news`
Example: `x`
</ResponseField>
<ResponseField name="property" type="string">
The URL to the social platform.
Example: `https://x.com/mintlify`
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="feedback" type="Feedback">
Configurations to enable feedback buttons
<Expandable title="Feedback">
<ResponseField name="suggestEdit" type="boolean" default="false">
Enables a button to allow users to suggest edits via pull requests
</ResponseField>
<ResponseField name="raiseIssue" type="boolean" default="false">
Enables a button to allow users to raise an issue about the documentation
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="modeToggle" type="ModeToggle">
Customize the dark mode toggle.
<Expandable title="ModeToggle">
<ResponseField name="default" type={'"light" or "dark"'}>
Set if you always want to show light or dark mode for new users. When not
set, we default to the same mode as the user's operating system.
</ResponseField>
<ResponseField name="isHidden" type="boolean" default="false">
Set to true to hide the dark/light mode toggle. You can combine `isHidden` with `default` to force your docs to only use light or dark mode. For example:
<CodeGroup>
```json Only Dark Mode
"modeToggle": {
"default": "dark",
"isHidden": true
}
```
```json Only Light Mode
"modeToggle": {
"default": "light",
"isHidden": true
}
```
</CodeGroup>
</ResponseField>
</Expandable>
</ResponseField>
<ResponseField name="backgroundImage" type="string">
A background image to be displayed behind every page. See example with
[Infisical](https://infisical.com/docs) and [FRPC](https://frpc.io).
</ResponseField>

BIN
docs/favicon.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

19
docs/favicon.svg Normal file
View File

@@ -0,0 +1,19 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.06145 23.1079C5.26816 22.3769 -3.39077 20.6274 1.4173 5.06384C9.6344 6.09939 16.9728 14.0644 9.06145 23.1079Z" fill="url(#paint0_linear_17557_2021)"/>
<path d="M8.91928 23.0939C5.27642 21.2223 0.78371 4.20891 17.0071 0C20.7569 7.19341 19.6212 16.5452 8.91928 23.0939Z" fill="url(#paint1_linear_17557_2021)"/>
<path d="M8.91388 23.0788C8.73534 19.8817 10.1585 9.08525 23.5699 13.1107C23.1812 20.1229 18.984 26.4182 8.91388 23.0788Z" fill="url(#paint2_linear_17557_2021)"/>
<defs>
<linearGradient id="paint0_linear_17557_2021" x1="3.77557" y1="5.91571" x2="5.23185" y2="21.5589" gradientUnits="userSpaceOnUse">
<stop stop-color="#18E299"/>
<stop offset="1" stop-color="#15803D"/>
</linearGradient>
<linearGradient id="paint1_linear_17557_2021" x1="12.1711" y1="-0.718425" x2="10.1897" y2="22.9832" gradientUnits="userSpaceOnUse">
<stop stop-color="#16A34A"/>
<stop offset="1" stop-color="#4ADE80"/>
</linearGradient>
<linearGradient id="paint2_linear_17557_2021" x1="23.1327" y1="15.353" x2="9.33841" y2="18.5196" gradientUnits="userSpaceOnUse">
<stop stop-color="#4ADE80"/>
<stop offset="1" stop-color="#0D9373"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,338 @@
---
title: 'Authentication & Security'
description: 'Configure authentication and security settings for MCPHub'
---
## Overview
MCPHub provides flexible authentication mechanisms to secure your MCP server management platform. The system supports multiple authentication methods and role-based access control.
## Authentication Methods
### Environment-based Authentication
Configure basic authentication using environment variables:
```bash
# Basic auth credentials
AUTH_USERNAME=admin
AUTH_PASSWORD=your-secure-password
# JWT settings
JWT_SECRET=your-jwt-secret-key
JWT_EXPIRES_IN=24h
```
### Database Authentication
For production deployments, enable database-backed user management:
```json
{
"auth": {
"provider": "database",
"database": {
"url": "postgresql://user:pass@localhost:5432/mcphub",
"userTable": "users"
}
}
}
```
## User Management
### Creating Users
Create users via the admin interface or API:
```bash
# Via API
curl -X POST http://localhost:3000/api/auth/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-d '{
"username": "newuser",
"email": "user@example.com",
"password": "securepassword",
"role": "user"
}'
```
### User Roles
MCPHub supports role-based access control:
- **Admin**: Full system access, user management, server configuration
- **Manager**: Server management, group management, monitoring
- **User**: Basic server access within assigned groups
- **Viewer**: Read-only access to assigned resources
## Group-based Access Control
### Assigning Users to Groups
```bash
# Add user to group
curl -X POST http://localhost:3000/api/groups/{groupId}/users \
-H "Authorization: Bearer $TOKEN" \
-d '{"userId": "user123"}'
```
### Group Permissions
Configure group-level permissions:
```json
{
"groupId": "dev-team",
"permissions": {
"servers": ["read", "write", "execute"],
"tools": ["read", "execute"],
"logs": ["read"],
"config": ["read"]
}
}
```
## API Authentication
### JWT Token Authentication
```javascript
// Login to get token
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: 'your-username',
password: 'your-password',
}),
});
const { token } = await response.json();
// Use token for authenticated requests
const serversResponse = await fetch('/api/servers', {
headers: { Authorization: `Bearer ${token}` },
});
```
### API Key Authentication
For service-to-service communication:
```bash
# Generate API key
curl -X POST http://localhost:3000/api/auth/api-keys \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-d '{
"name": "my-service",
"permissions": ["servers:read", "tools:execute"]
}'
# Use API key
curl -H "X-API-Key: your-api-key" \
http://localhost:3000/api/servers
```
## Security Configuration
### HTTPS Setup
Configure HTTPS for production:
```yaml
# docker-compose.yml
services:
mcphub:
environment:
- HTTPS_ENABLED=true
- SSL_CERT_PATH=/certs/cert.pem
- SSL_KEY_PATH=/certs/key.pem
volumes:
- ./certs:/certs:ro
```
### CORS Configuration
Configure CORS for web applications:
```json
{
"cors": {
"origin": ["https://your-frontend.com"],
"credentials": true,
"methods": ["GET", "POST", "PUT", "DELETE"]
}
}
```
### Rate Limiting
Protect against abuse with rate limiting:
```json
{
"rateLimit": {
"windowMs": 900000,
"max": 100,
"message": "Too many requests from this IP"
}
}
```
## Session Management
### Session Configuration
```json
{
"session": {
"secret": "your-session-secret",
"cookie": {
"secure": true,
"httpOnly": true,
"maxAge": 86400000
},
"store": "redis",
"redis": {
"host": "localhost",
"port": 6379
}
}
}
```
### Logout and Session Cleanup
```javascript
// Logout endpoint
app.post('/api/auth/logout', (req, res) => {
req.session.destroy();
res.json({ message: 'Logged out successfully' });
});
```
## Security Best Practices
### Password Security
- Use strong password requirements
- Implement password hashing with bcrypt
- Support password reset functionality
- Enable two-factor authentication (2FA)
### Token Security
- Use secure JWT secrets
- Implement token rotation
- Set appropriate expiration times
- Store tokens securely in httpOnly cookies
### Network Security
- Use HTTPS in production
- Implement proper CORS policies
- Enable request validation
- Use security headers (helmet.js)
### Monitoring Security Events
```javascript
// Log security events
const auditLog = {
event: 'login_attempt',
user: username,
ip: req.ip,
userAgent: req.headers['user-agent'],
success: true,
timestamp: new Date(),
};
```
## Troubleshooting
### Common Authentication Issues
**Invalid Credentials**
```bash
# Check user exists and password is correct
curl -X POST http://localhost:3000/api/auth/verify \
-d '{"username": "user", "password": "pass"}'
```
**Token Expiration**
```javascript
// Handle token refresh
if (response.status === 401) {
const newToken = await refreshToken();
// Retry request with new token
}
```
**Permission Denied**
```bash
# Check user permissions
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/auth/permissions
```
### Debug Authentication
Enable authentication debugging:
```bash
DEBUG=mcphub:auth npm start
```
## Integration Examples
### Frontend Integration
```javascript
// React authentication hook
const useAuth = () => {
const [user, setUser] = useState(null);
const login = async (credentials) => {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials),
});
if (response.ok) {
const userData = await response.json();
setUser(userData.user);
return true;
}
return false;
};
return { user, login };
};
```
### Middleware Integration
```javascript
// Express middleware
const authMiddleware = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
};
```

View File

@@ -0,0 +1,578 @@
---
title: 'Group Management'
description: 'Organize servers into logical groups for streamlined access control'
---
## Overview
Group Management in MCPHub allows you to organize your MCP servers into logical collections based on functionality, use case, or access requirements. This enables fine-grained control over which tools are available to different AI clients and users.
## Core Concepts
### What are Groups?
Groups are named collections of MCP servers that can be accessed through dedicated endpoints. Instead of connecting to all servers at once, AI clients can connect to specific groups to access only relevant tools.
### Benefits of Groups
- **Focused Tool Access**: AI clients see only relevant tools for their use case
- **Better Performance**: Reduced tool discovery overhead
- **Enhanced Security**: Limit access to sensitive tools
- **Improved Organization**: Logical separation of functionality
- **Simplified Management**: Easier to manage related servers together
## Creating Groups
### Via Dashboard
1. **Navigate to Groups Section**: Click "Groups" in the main navigation
2. **Click "Create Group"**: Start the group creation process
3. **Fill Group Details**:
- **Name**: Unique identifier for the group
4. **Add Servers**: Select servers to include in the group
### Via API
Create groups programmatically:
```bash
curl -X POST http://localhost:3000/api/groups \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"name": "web-automation",
"servers": ["playwright", "fetch"]
}'
```
{/* ### Via Configuration File
Define groups in your `mcp_settings.json`:
```json
{
"mcpServers": {
"fetch": { "command": "uvx", "args": ["mcp-server-fetch"] },
"playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] },
"slack": { "command": "npx", "args": ["@modelcontextprotocol/server-slack"] }
},
"groups": {
"web-tools": {
"name": "web",
"servers": ["fetch", "playwright"],
},
"communication": {
"name": "communication",
"servers": ["slack"],
}
}
}
``` */}
## Group Types and Use Cases
<AccordionGroup>
<Accordion title="Web Automation Group">
**Purpose**: Browser automation and web scraping
**Servers**:
- `playwright`: Browser automation
- `fetch`: HTTP requests and web scraping
- `selenium`: Alternative browser automation
**Use Cases**:
- Automated testing
- Data collection
- Web monitoring
- Content analysis
**Endpoint**: `http://localhost:3000/mcp/web-automation`
</Accordion>
<Accordion title="Data Processing Group">
**Purpose**: Data manipulation and analysis
**Servers**:
- `sqlite`: Database operations
- `filesystem`: File operations
- `spreadsheet`: Excel/CSV processing
**Use Cases**:
- Data analysis
- Report generation
- File processing
- Database queries
**Endpoint**: `http://localhost:3000/mcp/data-processing`
</Accordion>
<Accordion title="Communication Group">
**Purpose**: Messaging and collaboration
**Servers**:
- `slack`: Slack integration
- `discord`: Discord bot
- `email`: Email sending
- `sms`: SMS notifications
**Use Cases**:
- Team notifications
- Customer communication
- Alert systems
- Social media management
**Endpoint**: `http://localhost:3000/mcp/communication`
</Accordion>
<Accordion title="Development Group">
**Purpose**: Software development tools
**Servers**:
- `github`: GitHub operations
- `gitlab`: GitLab integration
- `docker`: Container management
- `kubernetes`: K8s operations
**Use Cases**:
- Code deployment
- Repository management
- CI/CD operations
- Infrastructure management
**Endpoint**: `http://localhost:3000/mcp/development`
</Accordion>
<Accordion title="AI/ML Group">
**Purpose**: Machine learning and AI tools
**Servers**:
- `openai`: OpenAI API integration
- `huggingface`: Hugging Face models
- `vector-db`: Vector database operations
**Use Cases**:
- Model inference
- Data embeddings
- Natural language processing
- Computer vision
**Endpoint**: `http://localhost:3000/mcp/ai-ml`
</Accordion>
</AccordionGroup>
{/* ## Group Access Control
### Access Levels
<Tabs>
<Tab title="Public">
**Public Groups**:
- Accessible to all authenticated users
- No additional permissions required
- Visible in group listings
- Default access level
```json
{
"name": "public-tools",
"accessLevel": "public",
"servers": ["fetch", "calculator"]
}
```
</Tab>
<Tab title="Private">
**Private Groups**:
- Only visible to group members
- Requires explicit user assignment
- Hidden from public listings
- Admin-controlled membership
```json
{
"name": "internal-tools",
"accessLevel": "private",
"members": ["user1", "user2"],
"servers": ["internal-api", "database"]
}
```
</Tab>
<Tab title="Restricted">
**Restricted Groups**:
- Role-based access control
- Requires specific permissions
- Audit logging enabled
- Time-limited access
```json
{
"name": "admin-tools",
"accessLevel": "restricted",
"requiredRoles": ["admin", "operator"],
"servers": ["system-control", "user-management"]
}
```
</Tab>
</Tabs>
### User Management
Assign users to groups:
```bash
# Add user to group
curl -X POST http://localhost:3000/api/groups/web-tools/members \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"userId": "user123"}'
# Remove user from group
curl -X DELETE http://localhost:3000/api/groups/web-tools/members/user123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# List group members
curl http://localhost:3000/api/groups/web-tools/members \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
``` */}
## Group Endpoints
### Accessing Groups
Each group gets its own MCP endpoint:
<Tabs>
<Tab title="HTTP MCP">
```
http://localhost:3000/mcp/{group-name}
```
Examples:
- `http://localhost:3000/mcp/web-tools`
- `http://localhost:3000/mcp/data-processing`
- `http://localhost:3000/mcp/communication`
</Tab>
<Tab title="SSE (Legacy)">
```
http://localhost:3000/sse/{group-name}
```
Examples:
- `http://localhost:3000/sse/web-tools`
- `http://localhost:3000/sse/data-processing`
- `http://localhost:3000/sse/communication`
</Tab>
</Tabs>
### Group Tool Discovery
When connecting to a group endpoint, AI clients will only see tools from servers within that group:
```bash
# List tools in web-tools group
curl -X POST http://localhost:3000/mcp/web-tools \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
```
Response will only include tools from `fetch` and `playwright` servers.
## Dynamic Group Management
### Adding Servers to Groups
<Tabs>
<Tab title="Dashboard">
1. Navigate to the group in the dashboard
2. Click "Manage Servers"
3. Select additional servers to add
4. Click "Save Changes"
</Tab>
<Tab title="API">
```bash
curl -X POST http://localhost:3000/api/groups/web-tools/servers \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"serverId": "new-server"}'
```
</Tab>
</Tabs>
### Removing Servers from Groups
<Tabs>
<Tab title="Dashboard">
1. Navigate to the group in the dashboard
2. Click "Manage Servers"
3. Unselect servers to remove
4. Click "Save Changes"
</Tab>
<Tab title="API">
```bash
curl -X DELETE http://localhost:3000/api/groups/web-tools/servers/server-name \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
</Tab>
</Tabs>
{/* ### Batch Server Updates
Update multiple servers at once:
```bash
curl -X PUT http://localhost:3000/api/groups/web-tools/servers \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"servers": ["fetch", "playwright", "selenium"]
}'
``` */}
{/* ## Group Monitoring
### Group Status
Monitor group health and activity:
```bash
# Get group status
curl http://localhost:3000/api/groups/web-tools/status \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
Response includes:
- Number of active servers
- Tool count
- Active connections
- Recent activity
### Group Analytics
Track group usage:
```bash
# Get group analytics
curl http://localhost:3000/api/groups/web-tools/analytics \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
Metrics include:
- Request count by tool
- Response times
- Error rates
- User activity */}
{/* ## Advanced Group Features
### Nested Groups
Create hierarchical group structures:
```json
{
"groups": {
"development": {
"displayName": "Development Tools",
"subGroups": ["frontend-dev", "backend-dev", "devops"]
},
"frontend-dev": {
"displayName": "Frontend Development",
"servers": ["playwright", "webpack-server"],
"parent": "development"
},
"backend-dev": {
"displayName": "Backend Development",
"servers": ["database", "api-server"],
"parent": "development"
}
}
}
```
### Group Templates
Use templates for quick group creation:
```json
{
"groupTemplates": {
"web-project": {
"description": "Standard web project toolset",
"servers": ["fetch", "playwright", "filesystem"],
"accessLevel": "public"
},
"data-science": {
"description": "Data science and ML tools",
"servers": ["python-tools", "jupyter", "vector-db"],
"accessLevel": "private"
}
}
}
```
Apply template:
```bash
curl -X POST http://localhost:3000/api/groups/from-template \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"name": "my-web-project",
"template": "web-project",
"displayName": "My Web Project Tools"
}'
```
### Group Policies
Define policies for group behavior:
```json
{
"groupPolicies": {
"web-tools": {
"maxConcurrentConnections": 10,
"requestTimeout": 30000,
"rateLimiting": {
"requestsPerMinute": 100,
"burstLimit": 20
},
"allowedOrigins": ["localhost", "myapp.com"]
}
}
}
``` */}
## Best Practices
### Group Organization
<Tip>
**Organize by Use Case**: Group servers based on what users want to accomplish, not just technical
similarity.
</Tip>
<Tip>
**Keep Groups Focused**: Avoid creating groups with too many diverse tools. Smaller, focused
groups are more useful.
</Tip>
<Tip>
**Use Descriptive Names**: Choose names that clearly indicate the group's purpose and contents.
</Tip>
{/* ### Security Considerations
<Warning>
**Principle of Least Privilege**: Only give users access to groups they actually need.
</Warning>
<Warning>
**Sensitive Tool Isolation**: Keep sensitive tools in restricted groups with proper access
controls.
</Warning>
<Warning>
**Regular Access Reviews**: Periodically review group memberships and remove unnecessary access.
</Warning> */}
### Performance Optimization
<Info>
**Balance Group Size**: Very large groups may have slower tool discovery. Consider splitting into
smaller groups.
</Info>
<Info>
**Monitor Usage**: Use analytics to identify which groups are heavily used and optimize
accordingly.
</Info>
## Troubleshooting
<AccordionGroup>
<Accordion title="Group Not Accessible">
**Check:**
- User has proper permissions
- Group exists and is active
- Servers in group are running
- Network connectivity
**Solutions:**
1. Verify user group membership
2. Check group configuration
3. Test individual server connections
4. Review access logs
</Accordion>
<Accordion title="Tools Missing from Group">
**Possible causes:**
- Server not properly added to group
- Server is not running
- Tool discovery failed
- Caching issues
**Debug steps:**
1. Verify server is in group configuration
2. Check server status
3. Force refresh tool discovery
4. Clear group cache
</Accordion>
<Accordion title="Group Performance Issues">
**Common issues:**
- Too many servers in group
- Slow server responses
- Network latency
- Resource constraints
**Optimizations:**
1. Split large groups
2. Monitor server performance
3. Implement request caching
4. Use connection pooling
</Accordion>
</AccordionGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="Smart Routing" icon="route" href="/features/smart-routing">
AI-powered tool discovery across groups
</Card>
<Card title="Authentication" icon="shield" href="/features/authentication">
User management and access control
</Card>
<Card title="API Reference" icon="code" href="/api-reference/groups">
Complete group management API
</Card>
<Card title="Configuration" icon="cog" href="/configuration/mcp-settings">
Advanced group configuration options
</Card>
</CardGroup>

View File

@@ -0,0 +1,526 @@
---
title: 'Monitoring & Logging'
description: 'Monitor your MCP servers and analyze system logs with MCPHub'
---
## Overview
MCPHub provides comprehensive monitoring and logging capabilities to help you track server performance, debug issues, and maintain system health.
## Real-time Monitoring
### Server Status Dashboard
The MCPHub dashboard provides real-time monitoring of all registered MCP servers:
- **Server Health**: Online/offline status with automatic health checks
- **Response Times**: Average, min, max response times per server
- **Request Volume**: Requests per second/minute/hour
- **Error Rates**: Success/failure ratios and error trends
- **Resource Usage**: Memory and CPU utilization (when available)
### Health Check Configuration
Configure health checks for your MCP servers:
```json
{
"healthCheck": {
"enabled": true,
"interval": 30000,
"timeout": 5000,
"retries": 3,
"endpoints": {
"ping": "/health",
"tools": "/tools/list"
}
}
}
```
### Monitoring API
Get monitoring data programmatically:
```bash
# Get server health status
curl http://localhost:3000/api/monitoring/health
# Get performance metrics
curl http://localhost:3000/api/monitoring/metrics?server=my-server&range=1h
# Get system overview
curl http://localhost:3000/api/monitoring/overview
```
## Logging System
### Log Levels
MCPHub supports standard log levels:
- **ERROR**: Critical errors requiring immediate attention
- **WARN**: Warning conditions that should be monitored
- **INFO**: General operational messages
- **DEBUG**: Detailed debugging information
- **TRACE**: Very detailed trace information
### Log Configuration
Configure logging in your environment:
```bash
# Set log level
LOG_LEVEL=info
# Enable structured logging
LOG_FORMAT=json
# Log file location
LOG_FILE=/var/log/mcphub/app.log
# Enable request logging
ENABLE_REQUEST_LOGS=true
```
### Structured Logging
MCPHub uses structured logging for better analysis:
```json
{
"timestamp": "2024-01-20T10:30:00Z",
"level": "info",
"message": "MCP server request completed",
"server": "github-mcp",
"tool": "search_repositories",
"duration": 245,
"status": "success",
"requestId": "req_123456",
"userId": "user_789"
}
```
## Log Management
### Log Storage Options
#### File-based Logging
```yaml
# docker-compose.yml
services:
mcphub:
volumes:
- ./logs:/app/logs
environment:
- LOG_FILE=/app/logs/mcphub.log
- LOG_ROTATION=daily
- LOG_MAX_SIZE=100MB
- LOG_MAX_FILES=7
```
#### Database Logging
```json
{
"logging": {
"database": {
"enabled": true,
"table": "logs",
"retention": "30d",
"indexes": ["timestamp", "level", "server"]
}
}
}
```
#### External Log Services
```bash
# Syslog integration
SYSLOG_ENABLED=true
SYSLOG_HOST=localhost
SYSLOG_PORT=514
SYSLOG_FACILITY=local0
# ELK Stack integration
ELASTICSEARCH_URL=http://localhost:9200
ELASTICSEARCH_INDEX=mcphub-logs
```
### Log Rotation
Automatic log rotation configuration:
```json
{
"logRotation": {
"enabled": true,
"maxSize": "100MB",
"maxFiles": 10,
"compress": true,
"interval": "daily"
}
}
```
## Metrics Collection
### System Metrics
MCPHub collects various system metrics:
```javascript
// Example metrics collected
{
"timestamp": "2024-01-20T10:30:00Z",
"metrics": {
"requests": {
"total": 1547,
"success": 1523,
"errors": 24,
"rate": 12.5
},
"servers": {
"online": 8,
"offline": 2,
"total": 10
},
"performance": {
"avgResponseTime": 156,
"p95ResponseTime": 324,
"p99ResponseTime": 567
},
"system": {
"memoryUsage": "245MB",
"cpuUsage": "15%",
"uptime": "72h 35m"
}
}
}
```
### Custom Metrics
Add custom metrics for your use case:
```javascript
// Custom metric example
const customMetric = {
name: 'tool_usage',
type: 'counter',
tags: {
server: 'github-mcp',
tool: 'search_repositories',
result: 'success',
},
value: 1,
};
// Send to metrics endpoint
await fetch('/api/monitoring/metrics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(customMetric),
});
```
## Alerting
### Alert Configuration
Set up alerts for critical conditions:
```json
{
"alerts": {
"serverDown": {
"condition": "server.status == 'offline'",
"duration": "5m",
"severity": "critical",
"channels": ["email", "slack"]
},
"highErrorRate": {
"condition": "errors.rate > 0.1",
"duration": "2m",
"severity": "warning",
"channels": ["slack"]
},
"slowResponse": {
"condition": "response.p95 > 1000",
"duration": "5m",
"severity": "warning",
"channels": ["email"]
}
}
}
```
### Notification Channels
#### Email Notifications
```bash
# Email configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=alerts@yourcompany.com
SMTP_PASS=your-app-password
ALERT_EMAIL_TO=admin@yourcompany.com
```
#### Slack Integration
```bash
# Slack webhook
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
SLACK_CHANNEL=#mcphub-alerts
```
#### Webhook Notifications
```json
{
"webhooks": [
{
"url": "https://your-service.com/webhooks/mcphub",
"events": ["server.down", "error.rate.high"],
"headers": {
"Authorization": "Bearer your-token"
}
}
]
}
```
## Log Analysis
### Query Logs
Use the logs API to query and analyze logs:
```bash
# Get recent errors
curl "http://localhost:3000/api/logs?level=error&since=1h"
# Search logs by server
curl "http://localhost:3000/api/logs?server=github-mcp&limit=100"
# Get logs for specific request
curl "http://localhost:3000/api/logs?requestId=req_123456"
# Filter by time range
curl "http://localhost:3000/api/logs?from=2024-01-20T00:00:00Z&to=2024-01-20T23:59:59Z"
```
### Log Aggregation
Aggregate logs for insights:
```bash
# Error summary by server
curl "http://localhost:3000/api/logs/aggregate?groupBy=server&level=error&since=24h"
# Request volume over time
curl "http://localhost:3000/api/logs/aggregate?groupBy=hour&type=request&since=7d"
```
## Performance Monitoring
### Response Time Tracking
Monitor MCP server response times:
```javascript
// Response time metrics
{
"server": "github-mcp",
"tool": "search_repositories",
"metrics": {
"calls": 156,
"avgTime": 234,
"minTime": 89,
"maxTime": 1205,
"p50": 201,
"p95": 567,
"p99": 892
}
}
```
### Error Rate Monitoring
Track error rates and patterns:
```bash
# Get error rates by server
curl "http://localhost:3000/api/monitoring/errors?groupBy=server&since=1h"
# Get error details
curl "http://localhost:3000/api/monitoring/errors?server=github-mcp&details=true"
```
## Integration with External Tools
### Prometheus Integration
Export metrics to Prometheus:
```yaml
# prometheus.yml
scrape_configs:
- job_name: 'mcphub'
static_configs:
- targets: ['localhost:3000']
metrics_path: '/api/monitoring/prometheus'
scrape_interval: 30s
```
### Grafana Dashboards
Import MCPHub Grafana dashboard:
```json
{
"dashboard": {
"title": "MCPHub Monitoring",
"panels": [
{
"title": "Server Status",
"type": "stat",
"targets": [
{
"expr": "mcphub_servers_online",
"legendFormat": "Online"
}
]
},
{
"title": "Request Rate",
"type": "graph",
"targets": [
{
"expr": "rate(mcphub_requests_total[5m])",
"legendFormat": "Requests/sec"
}
]
}
]
}
}
```
### ELK Stack Integration
Configure Logstash for log processing:
```ruby
# logstash.conf
input {
beats {
port => 5044
}
}
filter {
if [fields][service] == "mcphub" {
json {
source => "message"
}
date {
match => [ "timestamp", "ISO8601" ]
}
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "mcphub-logs-%{+YYYY.MM.dd}"
}
}
```
## Troubleshooting
### Common Monitoring Issues
**Missing Metrics**
```bash
# Check metrics endpoint
curl http://localhost:3000/api/monitoring/health
# Verify configuration
grep -r "monitoring" /path/to/config/
```
**Log File Issues**
```bash
# Check log file permissions
ls -la /var/log/mcphub/
# Verify disk space
df -h /var/log/
# Check log rotation
logrotate -d /etc/logrotate.d/mcphub
```
**Performance Issues**
```bash
# Monitor system resources
top -p $(pgrep -f mcphub)
# Check database connections
curl http://localhost:3000/api/monitoring/database
# Analyze slow queries
curl http://localhost:3000/api/monitoring/slow-queries
```
### Debug Mode
Enable debug logging for troubleshooting:
```bash
# Enable debug mode
DEBUG=mcphub:* npm start
# Or set environment variable
export DEBUG=mcphub:monitoring,mcphub:logging
```
## Best Practices
### Log Management
- Use structured logging with consistent formats
- Implement proper log levels and filtering
- Set up log rotation and retention policies
- Monitor log file sizes and disk usage
### Monitoring Setup
- Configure appropriate health check intervals
- Set up alerts for critical conditions
- Monitor both system and application metrics
- Use dashboards for visual monitoring
### Performance Optimization
- Index log database tables appropriately
- Use log sampling for high-volume scenarios
- Implement proper caching for metrics
- Regular cleanup of old logs and metrics
### Security Considerations
- Sanitize sensitive data in logs
- Secure access to monitoring endpoints
- Use authentication for external integrations
- Encrypt log transmission when using external services

141
docs/features/oauth.mdx Normal file
View File

@@ -0,0 +1,141 @@
# OAuth Support
## At a Glance
- Covers end-to-end OAuth 2.0 Authorization Code with PKCE for upstream MCP servers.
- Supports automatic discovery from `WWW-Authenticate` responses and RFC 8414 metadata.
- Implements dynamic client registration (RFC 7591) and resource indicators (RFC 8707).
- Persists client credentials and tokens to `mcp_settings.json` for reconnects.
## When MCPHub Switches to OAuth
1. MCPHub calls an MCP server that requires authorization and receives `401 Unauthorized`.
2. The response exposes a `WWW-Authenticate` header pointing to protected resource metadata (`authorization_server` or `as_uri`).
3. MCPHub discovers the authorization server metadata, registers (if needed), and opens the browser so the user can authorize once.
4. After the callback is handled, MCPHub reconnects with fresh tokens and resumes requests transparently.
> MCPHub logs each stage (discovery, registration, authorization URL, token exchange) in the server detail view and the backend logs.
## Quick Start by Server Type
### Servers with Dynamic Registration Support
Some servers expose complete OAuth metadata and allow dynamic client registration. For example, Vercel and Linear MCP servers only need their SSE endpoint configured:
```json
{
"mcpServers": {
"vercel": {
"type": "sse",
"url": "https://mcp.vercel.com"
},
"linear": {
"type": "sse",
"url": "https://mcp.linear.app/mcp"
}
}
}
```
- MCPHub discovers the authorization server, registers the client, and handles PKCE automatically.
- Tokens are stored in `mcp_settings.json`; no additional dashboard configuration is needed.
### Servers Requiring Manual Client Provisioning
Other providers do not support dynamic registration. GitHubs MCP endpoint (`https://api.githubcopilot.com/mcp/`) is one example. To connect:
1. Create an OAuth App in the providers console (for GitHub, go to **Settings → Developer settings → OAuth Apps**).
2. Set the callback/redirect URL to `http://localhost:3000/oauth/callback` (or your deployed dashboard domain).
3. Copy the issued client ID and client secret.
4. Supply the credentials through the MCPHub dashboard or by editing `mcp_settings.json` as shown below.
```json
{
"mcpServers": {
"github": {
"type": "sse",
"url": "https://api.githubcopilot.com/mcp/",
"oauth": {
"clientId": "${GITHUB_OAUTH_APP_ID}",
"clientSecret": "${GITHUB_OAUTH_APP_SECRET}",
"scopes": ["replace-with-provider-scope"],
"resource": "https://api.githubcopilot.com"
}
}
}
}
```
- MCPHub skips dynamic registration and uses the credentials you provide to complete the OAuth exchange.
- Update the dashboard or configuration file whenever you rotate secrets.
- Replace `scopes` with the exact scope strings required by the provider.
## Configuration Options
You can rely on auto-detection for most servers or declare OAuth settings explicitly in `mcp_settings.json`. Only populate the fields you need.
### Basic Auto Detection (Minimal Config)
```json
{
"mcpServers": {
"secured-sse": {
"type": "sse",
"url": "https://mcp.example.com/sse",
"oauth": {
"scopes": ["mcp.tools", "mcp.prompts"],
"resource": "https://mcp.example.com"
}
}
}
}
```
- MCPHub will discover the authorization server from challenge headers and walk the user through authorization automatically.
- Tokens (including refresh tokens) are stored on disk and reused on restart.
### Static Client Credentials (Bring Your Own Client)
```json
{
"oauth": {
"clientId": "mcphub-client",
"clientSecret": "replace-me-if-required",
"authorizationEndpoint": "https://auth.example.com/oauth/authorize",
"tokenEndpoint": "https://auth.example.com/oauth/token",
"redirectUri": "http://localhost:3000/oauth/callback"
}
}
```
- Use this when the authorization server requires manual client provisioning.
- `redirectUri` defaults to `http://localhost:3000/oauth/callback`; override it when running behind a custom domain.
### Dynamic Client Registration (RFC 7591)
```json
{
"oauth": {
"dynamicRegistration": {
"enabled": true,
"issuer": "https://auth.example.com",
"metadata": {
"client_name": "MCPHub",
"redirect_uris": [
"http://localhost:3000/oauth/callback",
"https://mcphub.example.com/oauth/callback"
],
"scope": "mcp.tools mcp.prompts",
"grant_types": ["authorization_code", "refresh_token"]
},
"initialAccessToken": "optional-token-if-required"
},
"scopes": ["mcp.tools", "mcp.prompts"],
"resource": "https://mcp.example.com"
}
}
```
- MCPHub discovers endpoints via `issuer`, registers itself, and persists the issued `client_id`/`client_secret`.
- Provide `initialAccessToken` only when the registration endpoint is protected.
## Authorization Flow
1. **Initialization** On startup MCPHub processes every server entry, discovers metadata, and registers the client if `dynamicRegistration.enabled` is true.
2. **User Authorization** Initiating a connection launches the system browser to the servers authorize page with PKCE parameters.
3. **Callback Handling** The built-in route (`/oauth/callback`) verifies the `state`, completes the token exchange, and saves the tokens via the MCP SDK.
4. **Token Lifecycle** Access and refresh tokens are cached in memory, refreshed automatically, and written back to `mcp_settings.json`.
## Tips & Troubleshooting
- Confirm that the redirect URI used during authorization exactly matches one of the `redirect_uris` registered with the authorization server.
- When running behind HTTPS, expose the callback URL publicly or configure a reverse proxy at `/oauth/callback`.
- If discovery fails, supply `authorizationEndpoint` and `tokenEndpoint` explicitly to bypass metadata lookup.
- Remove stale tokens from `mcp_settings.json` if an authorization server revokes access—MCPHub will prompt for a fresh login on the next request.

View File

@@ -0,0 +1,509 @@
---
title: 'Server Management'
description: 'Centrally manage multiple MCP servers with hot-swappable configuration'
---
## Overview
MCPHub's server management system allows you to centrally configure, monitor, and control multiple MCP (Model Context Protocol) servers from a single dashboard. All changes are applied in real-time without requiring server restarts.
## Adding MCP Servers
### Via Dashboard
1. **Access the Dashboard**: Navigate to `http://localhost:3000` and log in
2. **Click "Add Server"**: Located in the servers section
3. **Fill Server Details**:
- **Name**: Unique identifier for the server
- **Command**: Executable command (e.g., `npx`, `uvx`, `python`)
- **Arguments**: Array of command arguments
- **Environment Variables**: Key-value pairs for environment setup
- **Working Directory**: Optional working directory for the command
### Via Configuration File
Edit your `mcp_settings.json` file:
```json
{
"mcpServers": {
"server-name": {
"command": "command-to-run",
"args": ["arg1", "arg2"],
"env": {
"API_KEY": "your-api-key",
"CONFIG_VALUE": "some-value"
},
"cwd": "/optional/working/directory"
}
}
}
```
### Via API
Use the REST API to add servers programmatically:
```bash
curl -X POST http://localhost:3000/api/servers \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"name": "fetch-server",
"command": "uvx",
"args": ["mcp-server-fetch"],
"env": {}
}'
```
## Popular MCP Server Examples
<AccordionGroup>
<Accordion title="Web Fetch Server">
Provides web scraping and HTTP request capabilities:
```json
{
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
}
}
```
**Available Tools:**
- `fetch`: Make HTTP requests
- `fetch_html`: Scrape web pages
- `fetch_json`: Get JSON data from APIs
</Accordion>
<Accordion title="Playwright Browser Automation">
Browser automation for web interactions:
```json
{
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
}
}
```
**Available Tools:**
- `playwright_navigate`: Navigate to web pages
- `playwright_screenshot`: Take screenshots
- `playwright_click`: Click elements
- `playwright_fill`: Fill forms
</Accordion>
<Accordion title="File System Operations">
File and directory management:
```json
{
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"]
}
}
```
**Available Tools:**
- `read_file`: Read file contents
- `write_file`: Write to files
- `create_directory`: Create directories
- `list_directory`: List directory contents
</Accordion>
<Accordion title="SQLite Database">
Database operations:
```json
{
"sqlite": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sqlite", "/path/to/database.db"]
}
}
```
**Available Tools:**
- `execute_query`: Execute SQL queries
- `describe_tables`: Get table schemas
- `create_table`: Create new tables
</Accordion>
<Accordion title="Slack Integration">
Slack workspace integration:
```json
{
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "xoxb-your-bot-token",
"SLACK_TEAM_ID": "T1234567890"
}
}
}
```
**Available Tools:**
- `send_slack_message`: Send messages to channels
- `list_slack_channels`: List available channels
- `get_slack_thread`: Get thread messages
</Accordion>
<Accordion title="GitHub Integration">
GitHub repository operations:
```json
{
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token"
}
}
}
```
**Available Tools:**
- `create_or_update_file`: Create/update repository files
- `search_repositories`: Search GitHub repositories
- `create_issue`: Create issues
- `create_pull_request`: Create pull requests
</Accordion>
<Accordion title="Google Drive">
Google Drive file operations:
```json
{
"gdrive": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-gdrive"],
"env": {
"GDRIVE_CLIENT_ID": "your-client-id",
"GDRIVE_CLIENT_SECRET": "your-client-secret",
"GDRIVE_REDIRECT_URI": "your-redirect-uri"
}
}
}
```
**Available Tools:**
- `gdrive_search`: Search files and folders
- `gdrive_read`: Read file contents
- `gdrive_create`: Create new files
</Accordion>
<Accordion title="Amap Maps (China)">
Chinese mapping and location services:
```json
{
"amap": {
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "your-api-key"
}
}
}
```
**Available Tools:**
- `search_location`: Search for locations
- `get_directions`: Get route directions
- `reverse_geocode`: Convert coordinates to addresses
</Accordion>
</AccordionGroup>
## Server Lifecycle Management
### Starting Servers
Servers are automatically started when:
- MCPHub boots up
- A server is added via the dashboard or API
- A server configuration is updated
- A stopped server is manually restarted
### Stopping Servers
You can stop servers:
- **Via Dashboard**: Toggle the server status switch
- **Via API**: Send a POST request to `/api/servers/{name}/toggle`
- **Automatically**: Servers stop if they crash or encounter errors
### Restarting Servers
Servers are automatically restarted:
- When configuration changes are made
- After environment variable updates
- When manually triggered via dashboard or API
## Server Status Monitoring
### Status Indicators
Each server displays a status indicator:
- 🟢 **Running**: Server is active and responding
- 🟡 **Starting**: Server is initializing
- 🔴 **Stopped**: Server is not running
- ⚠️ **Error**: Server encountered an error
### Real-time Logs
View server logs in real-time:
1. **Dashboard Logs**: Click on a server to view its logs
2. **API Logs**: Access logs via `/api/logs` endpoint
3. **Streaming Logs**: Subscribe to log streams via WebSocket
### Health Checks
MCPHub automatically performs health checks:
- **Initialization Check**: Verifies server starts successfully
- **Tool Discovery**: Confirms available tools are detected
- **Response Check**: Tests server responsiveness
- **Resource Monitoring**: Tracks CPU and memory usage
## Configuration Management
### Environment Variables
Servers can use environment variables for configuration:
```json
{
"server-name": {
"command": "python",
"args": ["server.py"],
"env": {
"API_KEY": "${YOUR_API_KEY}",
"DEBUG": "true",
"MAX_CONNECTIONS": "10"
}
}
}
```
**Environment Variable Expansion:**
- `${VAR_NAME}`: Expands to environment variable value
- `${VAR_NAME:-default}`: Uses default if variable not set
- `${VAR_NAME:+value}`: Uses value if variable is set
{/* ### Working Directory
Set the working directory for server execution:
```json
{
"server-name": {
"command": "./local-script.sh",
"args": [],
"cwd": "/path/to/server/directory"
}
}
``` */}
### Command Variations
Different ways to specify server commands:
<Tabs>
<Tab title="npm/npx">
```json
{
"npm-server": {
"command": "npx",
"args": ["-y", "package-name", "--option", "value"]
}
}
```
</Tab>
<Tab title="Python/uvx">
```json
{
"python-server": {
"command": "uvx",
"args": ["package-name", "--config", "config.json"]
}
}
```
</Tab>
{/* <Tab title="Direct Python">
```json
{
"direct-python": {
"command": "python",
"args": ["-m", "module_name", "--arg", "value"]
}
}
```
</Tab>
<Tab title="Local Script">
```json
{
"local-script": {
"command": "./server.sh",
"args": ["--port", "8080"],
"cwd": "/path/to/script"
}
}
```
</Tab> */}
</Tabs>
## Advanced Features
### Hot Reloading
MCPHub supports hot reloading of server configurations:
{/* 1. **Config File Changes**: Automatically detects changes to `mcp_settings.json` */}
1. **Dashboard Updates**: Immediately applies changes made through the web interface
2. **API Updates**: Real-time updates via REST API calls
3. **Zero Downtime**: Graceful server restarts without affecting other servers
{/* ### Resource Limits
Control server resource usage:
```json
{
"resource-limited-server": {
"command": "memory-intensive-server",
"args": [],
"limits": {
"memory": "512MB",
"cpu": "50%",
"timeout": "30s"
}
}
}
``` */}
{/* ### Dependency Management
Handle server dependencies:
<AccordionGroup>
<Accordion title="Auto-installation">
MCPHub can automatically install missing packages:
```json
{
"auto-install-server": {
"command": "npx",
"args": ["-y", "package-that-might-not-exist"],
"autoInstall": true
}
}
```
</Accordion>
<Accordion title="Pre-installation Scripts">
Run setup scripts before starting servers:
```json
{
"setup-server": {
"preStart": ["npm install", "pip install -r requirements.txt"],
"command": "python",
"args": ["server.py"]
}
}
```
</Accordion>
</AccordionGroup> */}
## Troubleshooting
<AccordionGroup>
<Accordion title="Server Won't Start">
**Check the following:**
- Command is available in PATH
- All required environment variables are set
- Working directory exists and is accessible
- Network ports are not blocked
- Dependencies are installed
**Debug steps:**
1. Check server logs in the dashboard
2. Test command manually in terminal
3. Verify environment variable expansion
4. Check file permissions
</Accordion>
<Accordion title="Server Keeps Crashing">
**Common causes:**
- Invalid configuration parameters
- Missing API keys or credentials
- Resource limits exceeded
- Dependency conflicts
**Solutions:**
1. Review server logs for error messages
2. Test with minimal configuration
3. Verify all credentials and API keys
4. Check system resource availability
</Accordion>
<Accordion title="Tools Not Appearing">
**Possible issues:**
- Server not fully initialized
- Tool discovery timeout
- Communication protocol mismatch
- Server reporting errors
**Debug steps:**
1. Wait for server initialization to complete
2. Check server logs for tool registration messages
3. Test direct communication with server
4. Verify MCP protocol compatibility
</Accordion>
</AccordionGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="Group Management" icon="users" href="/features/group-management">
Organize servers into logical groups
</Card>
<Card title="Smart Routing" icon="route" href="/features/smart-routing">
Set up AI-powered tool discovery
</Card>
<Card title="API Reference" icon="code" href="/api-reference/servers">
Server management API documentation
</Card>
<Card title="Configuration Guide" icon="cog" href="/configuration/mcp-settings">
Detailed configuration options
</Card>
</CardGroup>

View File

@@ -0,0 +1,795 @@
---
title: 'Smart Routing'
description: 'AI-powered tool discovery using vector semantic search'
---
## Overview
Smart Routing is MCPHub's intelligent tool discovery system that uses vector semantic search to automatically find the most relevant tools for any given task. Instead of manually specifying which tools to use, AI clients can describe what they want to accomplish, and Smart Routing will identify and provide access to the most appropriate tools.
## How Smart Routing Works
### 1. Tool Indexing
When servers start up, Smart Routing automatically:
- Discovers all available tools from MCP servers
- Extracts tool metadata (names, descriptions, parameters)
- Converts tool information to vector embeddings
- Stores embeddings in PostgreSQL with pgvector
### 2. Semantic Search
When a query is made:
- User queries are converted to vector embeddings
- Similarity search finds matching tools using cosine similarity
- Dynamic thresholds filter out irrelevant results
- Results are ranked by relevance score
### 3. Intelligent Filtering
Smart Routing applies several filters:
- **Relevance Threshold**: Only returns tools above similarity threshold
- **Context Awareness**: Considers conversation context
- **Tool Availability**: Ensures tools are currently accessible
- **Permission Filtering**: Respects user access permissions
### 4. Tool Execution
Found tools can be directly executed:
- Parameter validation ensures correct tool usage
- Error handling provides helpful feedback
- Response formatting maintains consistency
- Logging tracks tool usage for analytics
## Prerequisites
Smart Routing requires additional setup compared to basic MCPHub usage:
### Required Components
1. **PostgreSQL with pgvector**: Vector database for embeddings storage
2. **Embedding Service**: OpenAI API or compatible service
3. **Environment Configuration**: Proper configuration variables
{/* ### Quick Setup
<Tabs>
<Tab title="Docker Compose">
Use this `docker-compose.yml` for complete setup:
```yaml
version: '3.8'
services:
mcphub:
image: samanhappy/mcphub:latest
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://mcphub:password@postgres:5432/mcphub
- OPENAI_API_KEY=your_openai_api_key
- ENABLE_SMART_ROUTING=true
depends_on:
- postgres
volumes:
- ./mcp_settings.json:/app/mcp_settings.json
postgres:
image: pgvector/pgvector:pg16
environment:
- POSTGRES_DB=mcphub
- POSTGRES_USER=mcphub
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
postgres_data:
```
Start with:
```bash
docker-compose up -d
```
</Tab>
<Tab title="Manual Setup">
1. **Install PostgreSQL with pgvector**:
```bash
# Using Docker
docker run -d \
--name mcphub-postgres \
-e POSTGRES_DB=mcphub \
-e POSTGRES_USER=mcphub \
-e POSTGRES_PASSWORD=your_password \
-p 5432:5432 \
pgvector/pgvector:pg16
```
2. **Set Environment Variables**:
```bash
export DATABASE_URL="postgresql://mcphub:your_password@localhost:5432/mcphub"
export OPENAI_API_KEY="your_openai_api_key"
export ENABLE_SMART_ROUTING="true"
```
3. **Start MCPHub**:
```bash
mcphub
```
</Tab>
<Tab title="Kubernetes">
Deploy with these Kubernetes manifests:
```yaml
# postgres-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: pgvector/pgvector:pg16
env:
- name: POSTGRES_DB
value: mcphub
- name: POSTGRES_USER
value: mcphub
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
ports:
- containerPort: 5432
---
# mcphub-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcphub
spec:
selector:
matchLabels:
app: mcphub
template:
metadata:
labels:
app: mcphub
spec:
containers:
- name: mcphub
image: samanhappy/mcphub:latest
env:
- name: DATABASE_URL
value: "postgresql://mcphub:password@postgres:5432/mcphub"
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-secret
key: api-key
- name: ENABLE_SMART_ROUTING
value: "true"
ports:
- containerPort: 3000
```
</Tab>
</Tabs>
## Configuration
### Environment Variables
Configure Smart Routing with these environment variables:
```bash
# Required
DATABASE_URL=postgresql://user:password@host:5432/database
OPENAI_API_KEY=your_openai_api_key
# Optional
ENABLE_SMART_ROUTING=true
EMBEDDING_MODEL=text-embedding-3-small
SIMILARITY_THRESHOLD=0.7
MAX_TOOLS_RETURNED=10
EMBEDDING_BATCH_SIZE=100
```
### Configuration Options
<AccordionGroup>
<Accordion title="Database Configuration">
```bash
# Full PostgreSQL connection string
DATABASE_URL=postgresql://username:password@host:port/database?schema=public
# SSL configuration for cloud databases
DATABASE_URL=postgresql://user:pass@host:5432/db?sslmode=require
# Connection pool settings
DATABASE_POOL_SIZE=20
DATABASE_TIMEOUT=30000
```
</Accordion>
<Accordion title="Embedding Service">
```bash
# OpenAI (default)
OPENAI_API_KEY=sk-your-api-key
EMBEDDING_MODEL=text-embedding-3-small
# Azure OpenAI
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
AZURE_OPENAI_API_KEY=your-api-key
AZURE_OPENAI_DEPLOYMENT=your-embedding-deployment
# Custom embedding service
EMBEDDING_SERVICE_URL=https://your-embedding-service.com
EMBEDDING_SERVICE_API_KEY=your-api-key
```
</Accordion>
<Accordion title="Search Parameters">
```bash
# Similarity threshold (0.0 to 1.0)
SIMILARITY_THRESHOLD=0.7
# Maximum tools to return
MAX_TOOLS_RETURNED=10
# Minimum query length for smart routing
MIN_QUERY_LENGTH=5
# Cache TTL for embeddings (seconds)
EMBEDDING_CACHE_TTL=3600
```
</Accordion>
</AccordionGroup> */}
## Using Smart Routing
### Smart Routing Endpoint
Access Smart Routing through the special `$smart` endpoint:
<Tabs>
<Tab title="HTTP MCP">
```
# Search across all servers
http://localhost:3000/mcp/$smart
# Search within a specific group
http://localhost:3000/mcp/$smart/{group}
```
</Tab>
<Tab title="SSE (Legacy)">
```
# Search across all servers
http://localhost:3000/sse/$smart
# Search within a specific group
http://localhost:3000/sse/$smart/{group}
```
</Tab>
</Tabs>
### Group-Scoped Smart Routing
Smart Routing now supports group-scoped searches, allowing you to limit tool discovery to servers within a specific group:
<AccordionGroup>
<Accordion title="Using Group-Scoped Smart Routing">
Connect your AI client to a group-specific Smart Routing endpoint:
```
http://localhost:3000/mcp/$smart/production
```
This endpoint will only search for tools within servers that belong to the "production" group.
**Benefits:**
- **Focused Results**: Only tools from relevant servers are returned
- **Better Performance**: Reduced search space for faster queries
- **Environment Isolation**: Keep development, staging, and production tools separate
- **Access Control**: Limit tool discovery based on user permissions
</Accordion>
<Accordion title="Example: Environment-Based Groups">
Create groups for different environments:
```bash
# Development environment
http://localhost:3000/mcp/$smart/development
# Staging environment
http://localhost:3000/mcp/$smart/staging
# Production environment
http://localhost:3000/mcp/$smart/production
```
Each endpoint will only return tools from servers in that specific environment group.
</Accordion>
<Accordion title="Example: Team-Based Groups">
Organize tools by team or department:
```bash
# Backend team tools
http://localhost:3000/mcp/$smart/backend-team
# Frontend team tools
http://localhost:3000/mcp/$smart/frontend-team
# DevOps team tools
http://localhost:3000/mcp/$smart/devops-team
```
This enables teams to have focused access to their relevant toolsets.
</Accordion>
<Accordion title="How It Works">
When using `$smart/{group}`:
1. The system identifies the specified group
2. Retrieves all servers belonging to that group
3. Filters the tool search to only those servers
4. Returns results scoped to the group's servers
If the group doesn't exist or has no servers, the search will return no results.
</Accordion>
</AccordionGroup>
{/* ### Basic Usage
Connect your AI client to the Smart Routing endpoint and make natural language requests:
```bash
# Example: Find tools for web scraping
curl -X POST http://localhost:3000/mcp/$smart \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/search",
"params": {
"query": "scrape website content and extract text"
}
}'
```
Response:
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "fetch_html",
"server": "fetch",
"description": "Fetch and parse HTML content from a URL",
"relevanceScore": 0.92,
"parameters": { ... }
},
{
"name": "playwright_navigate",
"server": "playwright",
"description": "Navigate to a web page and extract content",
"relevanceScore": 0.87,
"parameters": { ... }
}
]
}
}
``` */}
{/* ### Advanced Queries
Smart Routing supports various query types:
<AccordionGroup>
<Accordion title="Task-Based Queries">
```bash
# What you want to accomplish
curl -X POST http://localhost:3000/mcp/$smart \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/search",
"params": {
"query": "send a message to a slack channel"
}
}'
```
</Accordion>
<Accordion title="Domain-Specific Queries">
```bash
# Specific domain or technology
curl -X POST http://localhost:3000/mcp/$smart \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/search",
"params": {
"query": "database operations SQL queries"
}
}'
```
</Accordion>
<Accordion title="Action-Oriented Queries">
```bash
# Specific actions
curl -X POST http://localhost:3000/mcp/$smart \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/search",
"params": {
"query": "create file upload to github repository"
}
}'
```
</Accordion>
<Accordion title="Context-Aware Queries">
```bash
# Include context for better results
curl -X POST http://localhost:3000/mcp/$smart \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/search",
"params": {
"query": "automated testing web application",
"context": {
"project": "e-commerce website",
"technologies": ["React", "Node.js"],
"environment": "staging"
}
}
}'
```
</Accordion>
</AccordionGroup> */}
{/* ### Tool Execution
Once Smart Routing finds relevant tools, you can execute them directly:
```bash
# Execute a found tool
curl -X POST http://localhost:3000/mcp/$smart \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "fetch_html",
"arguments": {
"url": "https://example.com"
}
}
}'
``` */}
{/* ## Performance Optimization
### Embedding Cache
Smart Routing caches embeddings to improve performance:
```bash
# Configure cache settings
EMBEDDING_CACHE_TTL=3600 # Cache for 1 hour
EMBEDDING_CACHE_SIZE=10000 # Cache up to 10k embeddings
EMBEDDING_CACHE_CLEANUP=300 # Cleanup every 5 minutes
```
### Batch Processing
Tools are indexed in batches for efficiency:
```bash
# Batch size for embedding generation
EMBEDDING_BATCH_SIZE=100
# Concurrent embedding requests
EMBEDDING_CONCURRENCY=5
# Index update frequency
INDEX_UPDATE_INTERVAL=3600 # Re-index every hour
```
### Database Optimization
Optimize PostgreSQL for vector operations:
```sql
-- Create indexes for better performance
CREATE INDEX ON tool_embeddings USING hnsw (embedding vector_cosine_ops);
-- Adjust PostgreSQL settings
ALTER SYSTEM SET shared_preload_libraries = 'vector';
ALTER SYSTEM SET max_connections = 200;
ALTER SYSTEM SET shared_buffers = '256MB';
ALTER SYSTEM SET effective_cache_size = '1GB';
```
## Monitoring and Analytics
### Smart Routing Metrics
Monitor Smart Routing performance:
```bash
# Get Smart Routing statistics
curl http://localhost:3000/api/smart-routing/stats \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
Response includes:
- Query count and frequency
- Average response time
- Embedding cache hit rate
- Most popular tools
- Query patterns
### Tool Usage Analytics
Track which tools are found and used:
```bash
# Get tool usage analytics
curl http://localhost:3000/api/smart-routing/analytics \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
Metrics include:
- Tool discovery rates
- Execution success rates
- User satisfaction scores
- Query-to-execution conversion
### Performance Monitoring
Monitor system performance:
```bash
# Database performance
curl http://localhost:3000/api/smart-routing/db-stats \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Embedding service status
curl http://localhost:3000/api/smart-routing/embedding-stats \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
## Advanced Features
### Custom Embeddings
Use custom embedding models:
```bash
# Hugging Face models
EMBEDDING_SERVICE=huggingface
HUGGINGFACE_MODEL=sentence-transformers/all-MiniLM-L6-v2
HUGGINGFACE_API_KEY=your_api_key
# Local embedding service
EMBEDDING_SERVICE=local
EMBEDDING_SERVICE_URL=http://localhost:8080/embeddings
```
### Query Enhancement
Enhance queries for better results:
```json
{
"queryEnhancement": {
"enabled": true,
"expandAcronyms": true,
"addSynonyms": true,
"contextualExpansion": true
}
}
```
### Result Filtering
Filter results based on criteria:
```json
{
"resultFiltering": {
"minRelevanceScore": 0.7,
"maxResults": 10,
"preferredServers": ["fetch", "playwright"],
"excludeServers": ["deprecated-server"]
}
}
```
### Feedback Learning
Improve results based on user feedback:
```bash
# Provide feedback on search results
curl -X POST http://localhost:3000/api/smart-routing/feedback \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"queryId": "search-123",
"toolName": "fetch_html",
"rating": 5,
"successful": true,
"comments": "Perfect tool for the task"
}'
``` */}
## Troubleshooting
<AccordionGroup>
<Accordion title="Database Connection Issues">
**Symptoms:**
- Smart Routing not available
- Database connection errors
- Embedding storage failures
**Solutions:**
1. Verify PostgreSQL is running
2. Check DATABASE_URL format
3. Ensure pgvector extension is installed
4. Test connection manually:
```bash
psql $DATABASE_URL -c "SELECT 1;"
```
</Accordion>
<Accordion title="Embedding Service Problems">
**Symptoms:**
- Tool indexing failures
- Query processing errors
- API rate limit errors
**Solutions:**
1. Verify API key validity
2. Check network connectivity
3. Monitor rate limits
4. Test embedding service:
```bash
curl -X POST https://api.openai.com/v1/embeddings \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input": "test", "model": "text-embedding-3-small"}'
```
</Accordion>
<Accordion title="Poor Search Results">
**Symptoms:**
- Irrelevant tools returned
- Low relevance scores
- Missing expected tools
**Solutions:**
1. Adjust similarity threshold
2. Re-index tools with better descriptions
3. Use more specific queries
4. Check tool metadata quality
```bash
# Re-index all tools
curl -X POST http://localhost:3000/api/smart-routing/reindex \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
</Accordion>
<Accordion title="Performance Issues">
**Symptoms:**
- Slow query responses
- High database load
- Memory usage spikes
**Solutions:**
1. Optimize database configuration
2. Increase cache sizes
3. Reduce batch sizes
4. Monitor system resources
```bash
# Check system performance
curl http://localhost:3000/api/smart-routing/performance \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
```
</Accordion>
</AccordionGroup>
## Best Practices
### Query Writing
<Tip>
**Be Descriptive**: Use specific, descriptive language in queries for better tool matching.
</Tip>
<Tip>
**Include Context**: Provide relevant context about your task or domain for more accurate results.
</Tip>
<Tip>**Use Natural Language**: Write queries as you would describe the task to a human.</Tip>
### Tool Descriptions
<Warning>
**Quality Metadata**: Ensure MCP servers provide high-quality tool descriptions and metadata.
</Warning>
<Warning>**Regular Updates**: Keep tool descriptions current as functionality evolves.</Warning>
<Warning>
**Consistent Naming**: Use consistent naming conventions across tools and servers.
</Warning>
### System Maintenance
<Info>**Regular Re-indexing**: Periodically re-index tools to ensure embedding quality.</Info>
<Info>**Monitor Performance**: Track query patterns and optimize based on usage.</Info>
<Info>
**Update Models**: Consider updating to newer embedding models as they become available.
</Info>
## Next Steps
<CardGroup cols={2}>
<Card title="Authentication" icon="shield" href="/features/authentication">
User management and access control
</Card>
<Card title="Monitoring" icon="chart-line" href="/features/monitoring">
System monitoring and analytics
</Card>
<Card title="API Reference" icon="code" href="/api-reference/smart-routing">
Complete Smart Routing API documentation
</Card>
<Card title="Configuration" icon="cog" href="/configuration/environment-variables">
Advanced configuration options
</Card>
</CardGroup>

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

BIN
docs/images/hero-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
docs/images/hero-light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

95
docs/index.mdx Normal file
View File

@@ -0,0 +1,95 @@
---
title: MCPHub
description: 'The Unified Hub for Model Context Protocol (MCP) Servers'
---
{/* <img className="block dark:hidden" src="/images/hero-light.png" alt="Hero Light" />
<img className="hidden dark:block" src="/images/hero-dark.png" alt="Hero Dark" /> */}
# Welcome to MCPHub
MCPHub makes it easy to manage and scale multiple MCP (Model Context Protocol) servers by organizing them into flexible Streamable HTTP (SSE) endpoints—supporting access to all servers, individual servers, or logical server groups.
## Key Features
<CardGroup cols={2}>
<Card title="Unified Management" icon="server" href="/features/server-management">
Centrally manage multiple MCP servers with hot-swappable configuration
</Card>
<Card title="Group Management" icon="users" href="/features/group-management">
Organize servers into logical groups for streamlined access control
</Card>
<Card title="Smart Routing" icon="route" href="/features/smart-routing">
AI-powered tool discovery using vector semantic search
</Card>
<Card title="Real-time Monitoring" icon="chart-line" href="/features/monitoring">
Monitor server status and performance from a unified dashboard
</Card>
</CardGroup>
## Quick Start
Get MCPHub running in minutes with Docker:
```bash
docker run -p 3000:3000 samanhappy/mcphub
```
Or with custom configuration:
```bash
docker run -p 3000:3000 -v $(pwd)/mcp_settings.json:/app/mcp_settings.json samanhappy/mcphub
```
Access the dashboard at `http://localhost:3000` with default credentials:
- Username: `admin`
- Password: `admin123`
## Core Concepts
### MCP Endpoints
MCPHub provides multiple ways to access your MCP servers:
- **Unified Access**: `http://localhost:3000/mcp` - Access all servers
- **Group Access**: `http://localhost:3000/mcp/{group}` - Access specific groups
- **Server Access**: `http://localhost:3000/mcp/{server}` - Access individual servers
- **Smart Routing**: `http://localhost:3000/mcp/$smart` - AI-powered tool discovery
### Protocol Support
- **HTTP MCP**: Modern streamable HTTP interface (recommended)
- **SSE**: Server-Sent Events for legacy compatibility
- **stdio**: Native MCP protocol for server communication
## Getting Started
<CardGroup cols={2}>
<Card title="Quick Start Guide" icon="rocket" href="/quickstart">
Get MCPHub running in 5 minutes
</Card>
<Card title="Installation Guide" icon="download" href="/installation">
Detailed installation instructions for all platforms
</Card>
<Card title="Configuration" icon="cog" href="/configuration/mcp-settings">
Learn how to configure your MCP servers
</Card>
<Card title="API Reference" icon="code" href="/api-reference/introduction">
Complete API documentation
</Card>
</CardGroup>
## Community & Support
<CardGroup cols={3}>
<Card title="GitHub" icon="github" href="https://github.com/samanhappy/mcphub">
Source code and issue tracking
</Card>
<Card title="Discord" icon="discord" href="https://discord.gg/qMKNsn5Q">
Join our community discussions
</Card>
<Card title="Sponsor" icon="heart" href="https://ko-fi.com/samanhappy">
Support the project development
</Card>
</CardGroup>

595
docs/installation.mdx Normal file
View File

@@ -0,0 +1,595 @@
---
title: 'Installation Guide'
description: 'Detailed installation instructions for all platforms'
---
## Prerequisites
Before installing MCPHub, ensure you have the following prerequisites:
- **Node.js** 18+ (for local development)
- **Docker** (recommended for production)
- **pnpm** (for local development)
Optional for Smart Routing:
- **PostgreSQL** with pgvector extension
- **OpenAI API Key** or compatible embedding service
## Installation Methods
<Tabs>
<Tab title="Docker (Recommended)">
### Docker Installation
Docker is the recommended way to deploy MCPHub in production.
#### 1. Basic Installation
```bash
# Pull the latest image
docker pull samanhappy/mcphub:latest
# Run with default settings
docker run -d \
--name mcphub \
-p 3000:3000 \
samanhappy/mcphub:latest
```
#### 2. With Custom Configuration
```bash
# Create your configuration file
cat > mcp_settings.json << 'EOF'
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
}
}
}
EOF
# Run with mounted config
docker run -d \
--name mcphub \
-p 3000:3000 \
-v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
samanhappy/mcphub:latest
```
#### 3. With Environment Variables
```bash
docker run -d \
--name mcphub \
-p 3000:3000 \
-e PORT=3000 \
-e BASE_PATH="" \
samanhappy/mcphub:latest
```
#### 4. Docker Compose
Create a `docker-compose.yml` file:
```yaml
version: '3.8'
services:
mcphub:
image: samanhappy/mcphub:latest
ports:
- "3000:3000"
volumes:
- ./mcp_settings.json:/app/mcp_settings.json
environment:
- PORT=3000
- BASE_PATH=""
- REQUEST_TIMEOUT=60000
restart: unless-stopped
# Optional: PostgreSQL for Smart Routing
postgres:
image: pgvector/pgvector:pg16
environment:
POSTGRES_DB: mcphub
POSTGRES_USER: mcphub
POSTGRES_PASSWORD: mcphub_password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
postgres_data:
```
Run with:
```bash
docker-compose up -d
```
</Tab>
<Tab title="npm Package">
### npm Package Installation
Install MCPHub as a global npm package:
#### 1. Global Installation
```bash
# Install globally
npm install -g @samanhappy/mcphub
# Or with yarn
yarn global add @samanhappy/mcphub
# Or with pnpm
pnpm add -g @samanhappy/mcphub
```
#### 2. Running MCPHub
```bash
# Run with default settings
mcphub
# Run with custom port
PORT=8080 mcphub
```
{/* #### 3. Local Installation
You can also install MCPHub locally in a project:
```bash
# Create a new directory
mkdir my-mcphub
cd my-mcphub
# Initialize package.json
npm init -y
# Install MCPHub locally
npm install @samanhappy/mcphub
# Create a start script
echo '#!/bin/bash\nnpx mcphub' > start.sh
chmod +x start.sh
# Run MCPHub
./start.sh
``` */}
</Tab>
<Tab title="Local Development">
### Local Development Setup
For development, customization, or contribution:
#### 1. Clone Repository
```bash
# Clone the repository
git clone https://github.com/samanhappy/mcphub.git
cd mcphub
```
#### 2. Install Dependencies
```bash
# Install dependencies with pnpm (recommended)
pnpm install
# Or with npm
npm install
# Or with yarn
yarn install
```
#### 3. Development Mode
```bash
# Start both backend and frontend in development mode
pnpm dev
# This will start:
# - Backend on http://localhost:3001
# - Frontend on http://localhost:5173
# - Frontend proxies API calls to backend
```
#### 4. Build for Production
```bash
# Build both backend and frontend
pnpm build
# Start production server
pnpm start
```
#### 5. Development Scripts
```bash
# Backend only (for API development)
pnpm backend:dev
# Frontend only (when backend is running separately)
pnpm frontend:dev
# Run tests
pnpm test
# Lint code
pnpm lint
# Format code
pnpm format
```
<Note>
On Windows, you may need to run backend and frontend separately:
```bash
# Terminal 1: Backend
pnpm backend:dev
# Terminal 2: Frontend
pnpm frontend:dev
```
</Note>
</Tab>
<Tab title="Kubernetes">
### Kubernetes Deployment
Deploy MCPHub on Kubernetes with these manifests:
#### 1. ConfigMap for Settings
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mcphub-config
data:
mcp_settings.json: |
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"]
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
}
}
}
```
#### 2. Deployment
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcphub
spec:
replicas: 1
selector:
matchLabels:
app: mcphub
template:
metadata:
labels:
app: mcphub
spec:
initContainers:
- name: prepare-config
image: busybox:1.28
command:
[
"sh",
"-c",
"cp /config-ro/mcp_settings.json /etc/mcphub/mcp_settings.json",
]
volumeMounts:
- name: config
mountPath: /config-ro
readOnly: true
- name: app-storage
mountPath: /etc/mcphub
containers:
- name: mcphub
image: samanhappy/mcphub:latest
ports:
- containerPort: 3000
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
env:
- name: PORT
value: "3000"
- name: MCPHUB_SETTING_PATH
value: /etc/mcphub/mcp_settings.json
volumeMounts:
- name: app-storage
mountPath: /etc/mcphub
volumes:
- name: config
configMap:
name: mcphub-config
- name: app-storage
emptyDir: {}
```
#### 3. Service
```yaml
apiVersion: v1
kind: Service
metadata:
name: mcphub-service
spec:
selector:
app: mcphub
ports:
- port: 80
targetPort: 3000
type: ClusterIP
```
#### 4. Ingress (Optional)
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mcphub-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-buffering: "off"
spec:
rules:
- host: mcphub.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: mcphub-service
port:
number: 80
```
Deploy with:
```bash
kubectl apply -f mcphub-configmap.yaml
kubectl apply -f mcphub-deployment.yaml
kubectl apply -f mcphub-service.yaml
kubectl apply -f mcphub-ingress.yaml
```
</Tab>
</Tabs>
## Smart Routing Setup (Optional)
Smart Routing provides AI-powered tool discovery using vector semantic search.
### Prerequisites
1. **PostgreSQL with pgvector**
2. **OpenAI API Key** (or compatible embedding service)
### Database Setup
<Tabs>
<Tab title="Docker PostgreSQL">
```bash
# Run PostgreSQL with pgvector
docker run -d \
--name mcphub-postgres \
-e POSTGRES_DB=mcphub \
-e POSTGRES_USER=mcphub \
-e POSTGRES_PASSWORD=your_password \
-p 5432:5432 \
pgvector/pgvector:pg16
```
</Tab>
<Tab title="Existing PostgreSQL">
If you have an existing PostgreSQL instance:
```sql
-- Connect to your PostgreSQL instance
-- Create database
CREATE DATABASE mcphub;
-- Connect to the mcphub database
\c mcphub;
-- Enable pgvector extension
CREATE EXTENSION IF NOT EXISTS vector;
```
</Tab>
<Tab title="Cloud PostgreSQL">
For cloud providers (AWS RDS, Google Cloud SQL, etc.):
1. Enable the pgvector extension in your cloud provider's console
2. Create a database named `mcphub`
3. Note down the connection details
</Tab>
</Tabs>
{/* ### Environment Configuration
Set the following environment variables:
```bash
# Database connection
DATABASE_URL=postgresql://mcphub:your_password@localhost:5432/mcphub
# OpenAI API for embeddings
OPENAI_API_KEY=your_openai_api_key
# Optional: Custom embedding model
EMBEDDING_MODEL=text-embedding-3-small
# Optional: Enable smart routing
ENABLE_SMART_ROUTING=true
``` */}
## Verification
After installation, verify MCPHub is working:
{/* ### 1. Health Check
```bash
curl http://localhost:3000/api/health
```
Expected response:
```json
{
"status": "ok",
"version": "x.x.x",
"uptime": 123
}
``` */}
### Dashboard Access
Open your browser and navigate to:
```
http://localhost:3000
```
{/* ### 3. API Test
```bash
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
``` */}
## Troubleshooting
<AccordionGroup>
<Accordion title="Docker Issues">
**Port already in use:**
```bash
# Check what's using port 3000
lsof -i :3000
# Use a different port
docker run -p 8080:3000 samanhappy/mcphub
```
**Container won't start:**
```bash
# Check container logs
docker logs mcphub
# Run interactively for debugging
docker run -it --rm samanhappy/mcphub /bin/bash
```
</Accordion>
<Accordion title="npm Installation Issues">
**Permission errors:**
```bash
# Use npx instead of global install
npx @samanhappy/mcphub
# Or fix npm permissions
npm config set prefix ~/.npm-global
export PATH=~/.npm-global/bin:$PATH
```
**Node version issues:**
```bash
# Check Node version
node --version
# Install Node 18+ using nvm
nvm install 18
nvm use 18
```
</Accordion>
<Accordion title="Network Issues">
**Can't access dashboard:**
- Check if MCPHub is running: `ps aux | grep mcphub`
- Verify port binding: `netstat -tlnp | grep 3000`
- Check firewall settings
- Try accessing via `127.0.0.1:3000` instead of `localhost:3000`
**AI clients can't connect:**
- Ensure the endpoint URL is correct
- Check if MCPHub is behind a proxy
- Verify network policies in Kubernetes/Docker environments
</Accordion>
<Accordion title="Smart Routing Issues">
**Database connection failed:**
```bash
# Test database connection
psql $DATABASE_URL -c "SELECT 1;"
# Check if pgvector is installed
psql $DATABASE_URL -c "CREATE EXTENSION IF NOT EXISTS vector;"
```
**Embedding service errors:**
- Verify OpenAI API key is valid
- Check internet connectivity
- Monitor rate limits
</Accordion>
</AccordionGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="Configuration" icon="cog" href="/configuration/mcp-settings">
Configure your MCP servers and settings
</Card>
<Card title="Quick Start" icon="rocket" href="/quickstart">
Get up and running in 5 minutes
</Card>
<Card title="Server Management" icon="server" href="/features/server-management">
Learn how to manage your MCP servers
</Card>
<Card title="API Reference" icon="code" href="/api-reference/introduction">
Explore the complete API documentation
</Card>
</CardGroup>

27
docs/logo/dark.svg Normal file
View File

@@ -0,0 +1,27 @@
<svg width="320" height="80" viewBox="0 0 320 80" xmlns="http://www.w3.org/2000/svg">
<!-- Background with subtle gradient -->
<defs>
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#1e3a8a;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#3b82f6;stop-opacity:0.05" />
</linearGradient>
<linearGradient id="textGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#1e40af" />
<stop offset="50%" style="stop-color:#3b82f6" />
<stop offset="100%" style="stop-color:#1e40af" />
</linearGradient>
<linearGradient id="hubGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#059669" />
<stop offset="100%" style="stop-color:#10b981" />
</linearGradient>
</defs>
<!-- Background (transparent) -->
<!-- Text: MCPHub as one word -->
<text x="5" y="46" font-family="Arial, sans-serif" font-size="64" font-weight="bold" dominant-baseline="middle" text-anchor="start">
<tspan fill="url(#textGradient)">MCP</tspan><tspan fill="url(#hubGradient)">Hub</tspan>
</text>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

27
docs/logo/light.svg Normal file
View File

@@ -0,0 +1,27 @@
<svg width="320" height="80" viewBox="0 0 320 80" xmlns="http://www.w3.org/2000/svg">
<!-- Background with subtle gradient -->
<defs>
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#1e3a8a;stop-opacity:0.1" />
<stop offset="100%" style="stop-color:#3b82f6;stop-opacity:0.05" />
</linearGradient>
<linearGradient id="textGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#1e40af" />
<stop offset="50%" style="stop-color:#3b82f6" />
<stop offset="100%" style="stop-color:#1e40af" />
</linearGradient>
<linearGradient id="hubGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#059669" />
<stop offset="100%" style="stop-color:#10b981" />
</linearGradient>
</defs>
<!-- Background (transparent) -->
<!-- Text: MCPHub as one word -->
<text x="5" y="46" font-family="Arial, sans-serif" font-size="64" font-weight="bold" dominant-baseline="middle" text-anchor="start">
<tspan fill="url(#textGradient)">MCP</tspan><tspan fill="url(#hubGradient)">Hub</tspan>
</text>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

226
docs/quickstart.mdx Normal file
View File

@@ -0,0 +1,226 @@
---
title: 'Quick Start Guide'
description: 'Get MCPHub running in 5 minutes'
---
## Installation
<Tabs>
<Tab title="Docker (Recommended)">
The fastest way to get started with MCPHub is using Docker:
```bash
# Run with default configuration
docker run -p 3000:3000 samanhappy/mcphub
```
Or mount your custom configuration:
```bash
# Run with custom MCP settings
docker run -p 3000:3000 \
-v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
samanhappy/mcphub
```
</Tab>
<Tab title="Local Development">
For development or customization:
```bash
# Clone the repository
git clone https://github.com/samanhappy/mcphub.git
cd mcphub
# Install dependencies
pnpm install
# Start development servers
pnpm dev
```
This starts both backend (port 3001) and frontend (port 5173) in development mode.
</Tab>
<Tab title="npm Package">
Install MCPHub as a global package:
```bash
# Install globally
npm install -g @samanhappy/mcphub
# Run MCPHub
mcphub
```
</Tab>
</Tabs>
## Initial Setup
### 1. Access the Dashboard
Open your browser and navigate to:
```
http://localhost:3000
```
### 2. Login
Use the default credentials:
- **Username**: `admin`
- **Password**: `admin123`
<Warning>Change these default credentials immediately after first login for security.</Warning>
### 3. Configure Your First MCP Server
1. Click **"Add Server"** in the dashboard
2. Enter server details:
- **Name**: A unique identifier (e.g., `fetch`)
- **Command**: The executable command (`uvx`)
- **Args**: Command arguments (`["mcp-server-fetch"]`)
- **Environment**: Any required environment variables
Example configuration for a fetch server:
```json
{
"name": "fetch",
"command": "uvx",
"args": ["mcp-server-fetch"],
"env": {}
}
```
## Basic Usage
### Connecting AI Clients
Once your servers are configured, connect your AI clients using MCPHub endpoints:
<Tabs>
<Tab title="All Servers">
Access all configured MCP servers: ``` http://localhost:3000/mcp ```
</Tab>
<Tab title="Specific Group">
Access servers in a specific group: ``` http://localhost:3000/mcp/{groupName} ```
</Tab>
<Tab title="Individual Server">
Access a single server: ``` http://localhost:3000/mcp/{serverName} ```
</Tab>
<Tab title="Smart Routing">
Use AI-powered tool discovery: ``` http://localhost:3000/mcp/$smart ```
<Info>Smart routing requires PostgreSQL with pgvector and an OpenAI API key.</Info>
</Tab>
</Tabs>
### Example: Adding Popular MCP Servers
Here are some popular MCP servers you can add:
<AccordionGroup>
<Accordion title="Web Fetch Server">
```json
{
"name": "fetch",
"command": "uvx",
"args": ["mcp-server-fetch"]
}
```
</Accordion>
<Accordion title="Playwright Browser Automation">
```json
{
"name": "playwright",
"command": "npx",
"args": ["@playwright/mcp@latest", "--headless"]
}
```
</Accordion>
<Accordion title="Amap Maps (with API key)">
```json
{
"name": "amap",
"command": "npx",
"args": ["-y", "@amap/amap-maps-mcp-server"],
"env": {
"AMAP_MAPS_API_KEY": "your-api-key-here"
}
}
```
</Accordion>
<Accordion title="Slack Integration">
```json
{
"name": "slack",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": {
"SLACK_BOT_TOKEN": "your-bot-token",
"SLACK_TEAM_ID": "your-team-id"
}
}
```
</Accordion>
</AccordionGroup>
{/* ## Verification
Test your setup by making a simple request:
```bash
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'
```
You should receive a list of available tools from your configured MCP servers. */}
## Next Steps
<CardGroup cols={2}>
<Card title="Server Management" icon="server" href="/features/server-management">
Learn advanced server configuration and management
</Card>
<Card title="Group Management" icon="users" href="/features/group-management">
Organize servers into logical groups
</Card>
<Card title="Smart Routing" icon="route" href="/features/smart-routing">
Set up AI-powered tool discovery
</Card>
<Card title="API Reference" icon="code" href="/api-reference/introduction">
Explore the complete API documentation
</Card>
</CardGroup>
## Troubleshooting
<AccordionGroup>
<Accordion title="Server won't start">
- Check if the MCP server command is accessible in your PATH - Verify environment variables are
correctly set - Check MCPHub logs for detailed error messages
</Accordion>
<Accordion title="Can't connect from AI client">
- Ensure MCPHub is running on the correct port - Check firewall settings - Verify the endpoint
URL format
</Accordion>
<Accordion title="Authentication issues">
- Verify credentials are correct - Check if JWT token is valid - Try clearing browser cache and
cookies
</Accordion>
</AccordionGroup>
Need more help? Join our [Discord community](https://discord.gg/qMKNsn5Q) for support!

View File

@@ -0,0 +1,4 @@
One of the core principles of software development is DRY (Don't Repeat
Yourself). This is a principle that apply to documentation as
well. If you find yourself repeating the same content in multiple places, you
should consider creating a custom snippet to keep your content in sync.

View File

@@ -0,0 +1,147 @@
---
title: "身份验证"
description: "管理用户和身份验证。"
---
import { Card, Cards } from 'mintlify';
<Card
title="POST /api/auth/login"
href="#login"
>
登录以获取 JWT 令牌。
</Card>
<Card
title="POST /api/auth/register"
href="#register"
>
注册一个新用户。
</Card>
<Card
title="GET /api/auth/user"
href="#get-current-user"
>
获取当前已验证的用户。
</Card>
<Card
title="POST /api/auth/change-password"
href="#change-password"
>
更改当前用户的密码。
</Card>
---
### 登录
验证用户身份并返回 JWT 令牌及用户详细信息。
- **端点**: `/api/auth/login`
- **方法**: `POST`
- **正文**:
- `username` (string, 必填): 用户名。
- `password` (string, 必填): 用户密码。
- **请求示例**:
```json
{
"username": "admin",
"password": "admin123"
}
```
- **成功响应**:
```json
{
"success": true,
"message": "登录成功",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"username": "admin",
"isAdmin": true,
"permissions": { ... }
}
}
```
---
### 注册
注册一个新用户并返回 JWT 令牌。
- **端点**: `/api/auth/register`
- **方法**: `POST`
- **正文**:
- `username` (string, 必填): 新的用户名。
- `password` (string, 必填): 新的用户密码 (至少6个字符)。
- `isAdmin` (boolean, 可选): 用户是否应有管理员权限。
- **请求示例**:
```json
{
"username": "newuser",
"password": "password123",
"isAdmin": false
}
```
- **成功响应**:
```json
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"username": "newuser",
"isAdmin": false,
"permissions": { ... }
}
}
```
---
### 获取当前用户
检索当前通过身份验证的用户的个人资料。
- **端点**: `/api/auth/user`
- **方法**: `GET`
- **身份验证**: 需要承载令牌 (Bearer Token)。
- **成功响应**:
```json
{
"success": true,
"user": {
"username": "admin",
"isAdmin": true,
"permissions": { ... }
}
}
```
---
### 更改密码
允许通过身份验证的用户更改其密码。
- **端点**: `/api/auth/change-password`
- **方法**: `POST`
- **身份验证**: 需要承载令牌 (Bearer Token)。
- **正文**:
- `currentPassword` (string, 必填): 用户的当前密码。
- `newPassword` (string, 必填): 新的密码 (至少6个字符)。
- **请求示例**:
```json
{
"currentPassword": "oldpassword",
"newPassword": "newpassword123"
}
```
- **成功响应**:
```json
{
"success": true,
"message": "密码更新成功"
}
```

View File

@@ -0,0 +1,111 @@
---
title: "配置"
description: "管理和检索系统级配置。"
---
import { Card, Cards } from 'mintlify';
<Card title="PUT /api/system-config" href="#update-system-config">更新主系统配置。</Card>
<Card title="GET /api/settings" href="#get-all-settings">获取所有系统设置,包括服务器和群组。</Card>
<Card title="GET /config" href="#get-runtime-config">获取前端的公共运行时配置。</Card>
<Card title="GET /public-config" href="#get-public-config">获取公共配置以检查是否跳过身份验证。</Card>
---
### 更新系统配置
更新系统配置的各个部分。您只需提供要更新部分的键。
- **端点**: `/api/system-config`
- **方法**: `PUT`
- **正文**: 一个 JSON 对象,包含以下一个或多个顶级键:`routing`、`install`、`smartRouting`、`mcpRouter`。
#### 路由配置 (`routing`)
- `enableGlobalRoute` (boolean): 启用或禁用全局 `/api/mcp` 路由。
- `enableGroupNameRoute` (boolean): 启用或禁用基于群组的路由 (例如 `/api/mcp/group/:groupName`)。
- `enableBearerAuth` (boolean): 为 MCP 路由启用承载令牌身份验证。
- `bearerAuthKey` (string): 用于承载身份验证的密钥。
- `skipAuth` (boolean): 如果为 true则跳过所有身份验证使实例公开。
#### 安装配置 (`install`)
- `pythonIndexUrl` (string): 用于安装的 Python 包索引 (PyPI) 的基础 URL。
- `npmRegistry` (string): 用于安装的 npm 注册表 URL。
- `baseUrl` (string): 此 MCPHub 实例的公共基础 URL。
#### 智能路由配置 (`smartRouting`)
- `enabled` (boolean): 启用或禁用智能路由功能。
- `dbUrl` (string): 用于存储嵌入的数据库连接 URL。
- `openaiApiBaseUrl` (string): 用于生成嵌入的 OpenAI 兼容 API 的基础 URL。
- `openaiApiKey` (string): 嵌入服务的 API 密钥。
- `openaiApiEmbeddingModel` (string): 要使用的嵌入模型的名称。
#### MCP 路由器配置 (`mcpRouter`)
- `apiKey` (string): MCP 路由器服务的 API 密钥。
- `referer` (string): 用于 MCP 路由器请求的 referer 头。
- `title` (string): 在 MCP 路由器上显示的此实例的标题。
- `baseUrl` (string): MCP 路由器 API 的基础 URL。
- **请求示例**:
```json
{
"routing": {
"skipAuth": true
},
"smartRouting": {
"enabled": true,
"dbUrl": "postgresql://user:pass@host:port/db"
}
}
```
---
### 获取所有设置
检索实例的整个设置对象,包括所有服务器配置、群组和系统设置。这是 `mcp_settings.json` 文件的完整转储。
- **端点**: `/api/settings`
- **方法**: `GET`
---
### 获取运行时配置
检索前端应用程序所需的基本运行时配置。此端点不需要身份验证。
- **端点**: `/config`
- **方法**: `GET`
- **成功响应**:
```json
{
"success": true,
"data": {
"basePath": "",
"version": "1.0.0",
"name": "MCPHub"
}
}
```
---
### 获取公共配置
检索公共配置,主要用于检查是否跳过身份验证。这允许前端在用户登录前相应地调整其行为。此端点不需要身份验证。
- **端点**: `/public-config`
- **方法**: `GET`
- **成功响应**:
```json
{
"success": true,
"data": {
"skipAuth": false,
"permissions": {}
}
}
```

Some files were not shown because too many files have changed in this diff Show More