@samanhappy/mcphub 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -1
- package/.env.example +0 -2
- package/.eslintrc.json +0 -25
- package/.github/workflows/build.yml +0 -51
- package/.github/workflows/release.yml +0 -19
- package/.prettierrc +0 -7
- package/Dockerfile +0 -51
- package/assets/amap-edit.png +0 -0
- package/assets/amap-result.png +0 -0
- package/assets/cherry-mcp.png +0 -0
- package/assets/cursor-mcp.png +0 -0
- package/assets/cursor-query.png +0 -0
- package/assets/cursor-tools.png +0 -0
- package/assets/dashboard.png +0 -0
- package/assets/dashboard.zh.png +0 -0
- package/assets/group.png +0 -0
- package/assets/group.zh.png +0 -0
- package/assets/market.zh.png +0 -0
- package/assets/wegroup.jpg +0 -0
- package/assets/wegroup.png +0 -0
- package/assets/wexin.png +0 -0
- package/doc/intro.md +0 -73
- package/doc/intro2.md +0 -232
- package/entrypoint.sh +0 -10
- package/frontend/favicon.ico +0 -0
- package/frontend/index.html +0 -13
- package/frontend/postcss.config.js +0 -6
- package/frontend/src/App.tsx +0 -44
- package/frontend/src/components/AddGroupForm.tsx +0 -132
- package/frontend/src/components/AddServerForm.tsx +0 -90
- package/frontend/src/components/ChangePasswordForm.tsx +0 -158
- package/frontend/src/components/EditGroupForm.tsx +0 -149
- package/frontend/src/components/EditServerForm.tsx +0 -76
- package/frontend/src/components/GroupCard.tsx +0 -143
- package/frontend/src/components/MarketServerCard.tsx +0 -153
- package/frontend/src/components/MarketServerDetail.tsx +0 -297
- package/frontend/src/components/ProtectedRoute.tsx +0 -27
- package/frontend/src/components/ServerCard.tsx +0 -230
- package/frontend/src/components/ServerForm.tsx +0 -276
- package/frontend/src/components/icons/LucideIcons.tsx +0 -14
- package/frontend/src/components/layout/Content.tsx +0 -17
- package/frontend/src/components/layout/Header.tsx +0 -61
- package/frontend/src/components/layout/Sidebar.tsx +0 -98
- package/frontend/src/components/ui/Badge.tsx +0 -33
- package/frontend/src/components/ui/Button.tsx +0 -0
- package/frontend/src/components/ui/DeleteDialog.tsx +0 -48
- package/frontend/src/components/ui/Pagination.tsx +0 -128
- package/frontend/src/components/ui/Toast.tsx +0 -96
- package/frontend/src/components/ui/ToggleGroup.tsx +0 -134
- package/frontend/src/components/ui/ToolCard.tsx +0 -38
- package/frontend/src/contexts/AuthContext.tsx +0 -159
- package/frontend/src/contexts/ToastContext.tsx +0 -60
- package/frontend/src/hooks/useGroupData.ts +0 -232
- package/frontend/src/hooks/useMarketData.ts +0 -410
- package/frontend/src/hooks/useServerData.ts +0 -306
- package/frontend/src/hooks/useSettingsData.ts +0 -131
- package/frontend/src/i18n.ts +0 -42
- package/frontend/src/index.css +0 -20
- package/frontend/src/layouts/MainLayout.tsx +0 -33
- package/frontend/src/locales/en.json +0 -214
- package/frontend/src/locales/zh.json +0 -214
- package/frontend/src/main.tsx +0 -12
- package/frontend/src/pages/Dashboard.tsx +0 -206
- package/frontend/src/pages/GroupsPage.tsx +0 -116
- package/frontend/src/pages/LoginPage.tsx +0 -104
- package/frontend/src/pages/MarketPage.tsx +0 -356
- package/frontend/src/pages/ServersPage.tsx +0 -144
- package/frontend/src/pages/SettingsPage.tsx +0 -149
- package/frontend/src/services/authService.ts +0 -141
- package/frontend/src/types/index.ts +0 -160
- package/frontend/src/utils/cn.ts +0 -10
- package/frontend/tsconfig.json +0 -31
- package/frontend/tsconfig.node.json +0 -10
- package/frontend/vite.config.ts +0 -26
- package/googled76ca578b6543fbc.html +0 -1
- package/jest.config.js +0 -10
- package/mcp_settings.json +0 -45
- package/servers.json +0 -74722
- package/src/config/index.ts +0 -46
- package/src/controllers/authController.ts +0 -179
- package/src/controllers/groupController.ts +0 -341
- package/src/controllers/marketController.ts +0 -154
- package/src/controllers/serverController.ts +0 -303
- package/src/index.ts +0 -18
- package/src/middlewares/auth.ts +0 -28
- package/src/middlewares/index.ts +0 -43
- package/src/models/User.ts +0 -103
- package/src/routes/index.ts +0 -96
- package/src/server.ts +0 -72
- package/src/services/groupService.ts +0 -232
- package/src/services/marketService.ts +0 -116
- package/src/services/mcpService.ts +0 -385
- package/src/services/sseService.ts +0 -119
- package/src/types/index.ts +0 -129
- package/src/utils/migration.ts +0 -52
- package/tsconfig.json +0 -17
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
-
import { IGroup, McpSettings } from '../types/index.js';
|
|
3
|
-
import { loadSettings, saveSettings } from '../config/index.js';
|
|
4
|
-
import { notifyToolChanged } from './mcpService.js';
|
|
5
|
-
|
|
6
|
-
// Get all groups
|
|
7
|
-
export const getAllGroups = (): IGroup[] => {
|
|
8
|
-
const settings = loadSettings();
|
|
9
|
-
return settings.groups || [];
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// Get group by ID or name
|
|
13
|
-
export const getGroupByIdOrName = (key: string): IGroup | undefined => {
|
|
14
|
-
const settings = loadSettings();
|
|
15
|
-
const routingConfig = settings.systemConfig?.routing || {
|
|
16
|
-
enableGlobalRoute: true,
|
|
17
|
-
enableGroupNameRoute: true,
|
|
18
|
-
};
|
|
19
|
-
const groups = getAllGroups();
|
|
20
|
-
return (
|
|
21
|
-
groups.find(
|
|
22
|
-
(group) => group.id === key || (group.name === key && routingConfig.enableGroupNameRoute),
|
|
23
|
-
) || undefined
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// Create a new group
|
|
28
|
-
export const createGroup = (
|
|
29
|
-
name: string,
|
|
30
|
-
description?: string,
|
|
31
|
-
servers: string[] = [],
|
|
32
|
-
): IGroup | null => {
|
|
33
|
-
try {
|
|
34
|
-
const settings = loadSettings();
|
|
35
|
-
const groups = settings.groups || [];
|
|
36
|
-
|
|
37
|
-
// Check if group with same name already exists
|
|
38
|
-
if (groups.some((group) => group.name === name)) {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Filter out non-existent servers
|
|
43
|
-
const validServers = servers.filter((serverName) => settings.mcpServers[serverName]);
|
|
44
|
-
|
|
45
|
-
const newGroup: IGroup = {
|
|
46
|
-
id: uuidv4(),
|
|
47
|
-
name,
|
|
48
|
-
description,
|
|
49
|
-
servers: validServers,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Initialize groups array if it doesn't exist
|
|
53
|
-
if (!settings.groups) {
|
|
54
|
-
settings.groups = [];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
settings.groups.push(newGroup);
|
|
58
|
-
|
|
59
|
-
if (!saveSettings(settings)) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return newGroup;
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.error('Failed to create group:', error);
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Update an existing group
|
|
71
|
-
export const updateGroup = (id: string, data: Partial<IGroup>): IGroup | null => {
|
|
72
|
-
try {
|
|
73
|
-
const settings = loadSettings();
|
|
74
|
-
if (!settings.groups) {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const groupIndex = settings.groups.findIndex((group) => group.id === id);
|
|
79
|
-
if (groupIndex === -1) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Check for name uniqueness if name is being updated
|
|
84
|
-
if (data.name && settings.groups.some((g) => g.name === data.name && g.id !== id)) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// If servers array is provided, validate server existence
|
|
89
|
-
if (data.servers) {
|
|
90
|
-
data.servers = data.servers.filter((serverName) => settings.mcpServers[serverName]);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const updatedGroup = {
|
|
94
|
-
...settings.groups[groupIndex],
|
|
95
|
-
...data,
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
settings.groups[groupIndex] = updatedGroup;
|
|
99
|
-
|
|
100
|
-
if (!saveSettings(settings)) {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
notifyToolChanged();
|
|
105
|
-
return updatedGroup;
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error(`Failed to update group ${id}:`, error);
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// Update servers in a group (batch update)
|
|
113
|
-
export const updateGroupServers = (groupId: string, servers: string[]): IGroup | null => {
|
|
114
|
-
try {
|
|
115
|
-
const settings = loadSettings();
|
|
116
|
-
if (!settings.groups) {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const groupIndex = settings.groups.findIndex((group) => group.id === groupId);
|
|
121
|
-
if (groupIndex === -1) {
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Filter out non-existent servers
|
|
126
|
-
const validServers = servers.filter((serverName) => settings.mcpServers[serverName]);
|
|
127
|
-
|
|
128
|
-
settings.groups[groupIndex].servers = validServers;
|
|
129
|
-
|
|
130
|
-
if (!saveSettings(settings)) {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
notifyToolChanged();
|
|
135
|
-
return settings.groups[groupIndex];
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error(`Failed to update servers for group ${groupId}:`, error);
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// Delete a group
|
|
143
|
-
export const deleteGroup = (id: string): boolean => {
|
|
144
|
-
try {
|
|
145
|
-
const settings = loadSettings();
|
|
146
|
-
if (!settings.groups) {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const initialLength = settings.groups.length;
|
|
151
|
-
settings.groups = settings.groups.filter((group) => group.id !== id);
|
|
152
|
-
|
|
153
|
-
if (settings.groups.length === initialLength) {
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return saveSettings(settings);
|
|
158
|
-
} catch (error) {
|
|
159
|
-
console.error(`Failed to delete group ${id}:`, error);
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// Add server to group
|
|
165
|
-
export const addServerToGroup = (groupId: string, serverName: string): IGroup | null => {
|
|
166
|
-
try {
|
|
167
|
-
const settings = loadSettings();
|
|
168
|
-
if (!settings.groups) {
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Verify server exists
|
|
173
|
-
if (!settings.mcpServers[serverName]) {
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const groupIndex = settings.groups.findIndex((group) => group.id === groupId);
|
|
178
|
-
if (groupIndex === -1) {
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const group = settings.groups[groupIndex];
|
|
183
|
-
|
|
184
|
-
// Add server to group if not already in it
|
|
185
|
-
if (!group.servers.includes(serverName)) {
|
|
186
|
-
group.servers.push(serverName);
|
|
187
|
-
|
|
188
|
-
if (!saveSettings(settings)) {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
notifyToolChanged();
|
|
194
|
-
return group;
|
|
195
|
-
} catch (error) {
|
|
196
|
-
console.error(`Failed to add server ${serverName} to group ${groupId}:`, error);
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
// Remove server from group
|
|
202
|
-
export const removeServerFromGroup = (groupId: string, serverName: string): IGroup | null => {
|
|
203
|
-
try {
|
|
204
|
-
const settings = loadSettings();
|
|
205
|
-
if (!settings.groups) {
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const groupIndex = settings.groups.findIndex((group) => group.id === groupId);
|
|
210
|
-
if (groupIndex === -1) {
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const group = settings.groups[groupIndex];
|
|
215
|
-
group.servers = group.servers.filter((name) => name !== serverName);
|
|
216
|
-
|
|
217
|
-
if (!saveSettings(settings)) {
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return group;
|
|
222
|
-
} catch (error) {
|
|
223
|
-
console.error(`Failed to remove server ${serverName} from group ${groupId}:`, error);
|
|
224
|
-
return null;
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
// Get all servers in a group
|
|
229
|
-
export const getServersInGroup = (groupId: string): string[] => {
|
|
230
|
-
const group = getGroupByIdOrName(groupId);
|
|
231
|
-
return group ? group.servers : [];
|
|
232
|
-
};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { MarketServer } from '../types/index.js';
|
|
4
|
-
|
|
5
|
-
// Get path to the servers.json file
|
|
6
|
-
export const getServersJsonPath = (): string => {
|
|
7
|
-
return path.resolve(process.cwd(), 'servers.json');
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
// Load all market servers from servers.json
|
|
11
|
-
export const getMarketServers = (): Record<string, MarketServer> => {
|
|
12
|
-
try {
|
|
13
|
-
const serversJsonPath = getServersJsonPath();
|
|
14
|
-
const data = fs.readFileSync(serversJsonPath, 'utf8');
|
|
15
|
-
const serversObj = JSON.parse(data) as Record<string, MarketServer>;
|
|
16
|
-
|
|
17
|
-
const sortedEntries = Object.entries(serversObj).sort(([, serverA], [, serverB]) => {
|
|
18
|
-
if (serverA.is_official && !serverB.is_official) return -1;
|
|
19
|
-
if (!serverA.is_official && serverB.is_official) return 1;
|
|
20
|
-
return 0;
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
return Object.fromEntries(sortedEntries);
|
|
24
|
-
} catch (error) {
|
|
25
|
-
console.error('Failed to load servers from servers.json:', error);
|
|
26
|
-
return {};
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Get a specific market server by name
|
|
31
|
-
export const getMarketServerByName = (name: string): MarketServer | null => {
|
|
32
|
-
const servers = getMarketServers();
|
|
33
|
-
return servers[name] || null;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
// Get all categories from market servers
|
|
37
|
-
export const getMarketCategories = (): string[] => {
|
|
38
|
-
const servers = getMarketServers();
|
|
39
|
-
const categories = new Set<string>();
|
|
40
|
-
|
|
41
|
-
Object.values(servers).forEach((server) => {
|
|
42
|
-
server.categories?.forEach((category) => {
|
|
43
|
-
categories.add(category);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
return Array.from(categories).sort();
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// Get all tags from market servers
|
|
51
|
-
export const getMarketTags = (): string[] => {
|
|
52
|
-
const servers = getMarketServers();
|
|
53
|
-
const tags = new Set<string>();
|
|
54
|
-
|
|
55
|
-
Object.values(servers).forEach((server) => {
|
|
56
|
-
server.tags?.forEach((tag) => {
|
|
57
|
-
tags.add(tag);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
return Array.from(tags).sort();
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
// Search market servers by query
|
|
65
|
-
export const searchMarketServers = (query: string): MarketServer[] => {
|
|
66
|
-
const servers = getMarketServers();
|
|
67
|
-
const searchTerms = query
|
|
68
|
-
.toLowerCase()
|
|
69
|
-
.split(' ')
|
|
70
|
-
.filter((term) => term.length > 0);
|
|
71
|
-
|
|
72
|
-
if (searchTerms.length === 0) {
|
|
73
|
-
return Object.values(servers);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return Object.values(servers).filter((server) => {
|
|
77
|
-
// Search in name, display_name, description, categories, and tags
|
|
78
|
-
const searchableText = [
|
|
79
|
-
server.name,
|
|
80
|
-
server.display_name,
|
|
81
|
-
server.description,
|
|
82
|
-
...(server.categories || []),
|
|
83
|
-
...(server.tags || []),
|
|
84
|
-
]
|
|
85
|
-
.join(' ')
|
|
86
|
-
.toLowerCase();
|
|
87
|
-
|
|
88
|
-
return searchTerms.some((term) => searchableText.includes(term));
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
// Filter market servers by category
|
|
93
|
-
export const filterMarketServersByCategory = (category: string): MarketServer[] => {
|
|
94
|
-
const servers = getMarketServers();
|
|
95
|
-
|
|
96
|
-
if (!category) {
|
|
97
|
-
return Object.values(servers);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return Object.values(servers).filter((server) => {
|
|
101
|
-
return server.categories?.includes(category);
|
|
102
|
-
});
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// Filter market servers by tag
|
|
106
|
-
export const filterMarketServersByTag = (tag: string): MarketServer[] => {
|
|
107
|
-
const servers = getMarketServers();
|
|
108
|
-
|
|
109
|
-
if (!tag) {
|
|
110
|
-
return Object.values(servers);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return Object.values(servers).filter((server) => {
|
|
114
|
-
return server.tags?.includes(tag);
|
|
115
|
-
});
|
|
116
|
-
};
|