@samanhappy/mcphub 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/package.json +6 -3
  2. package/.env.example +0 -2
  3. package/.eslintrc.json +0 -25
  4. package/.github/workflows/build.yml +0 -51
  5. package/.github/workflows/release.yml +0 -19
  6. package/.prettierrc +0 -7
  7. package/Dockerfile +0 -51
  8. package/assets/amap-edit.png +0 -0
  9. package/assets/amap-result.png +0 -0
  10. package/assets/cherry-mcp.png +0 -0
  11. package/assets/cursor-mcp.png +0 -0
  12. package/assets/cursor-query.png +0 -0
  13. package/assets/cursor-tools.png +0 -0
  14. package/assets/dashboard.png +0 -0
  15. package/assets/dashboard.zh.png +0 -0
  16. package/assets/group.png +0 -0
  17. package/assets/group.zh.png +0 -0
  18. package/assets/market.zh.png +0 -0
  19. package/assets/wegroup.jpg +0 -0
  20. package/assets/wegroup.png +0 -0
  21. package/assets/wexin.png +0 -0
  22. package/doc/intro.md +0 -73
  23. package/doc/intro2.md +0 -232
  24. package/entrypoint.sh +0 -10
  25. package/frontend/favicon.ico +0 -0
  26. package/frontend/index.html +0 -13
  27. package/frontend/postcss.config.js +0 -6
  28. package/frontend/src/App.tsx +0 -44
  29. package/frontend/src/components/AddGroupForm.tsx +0 -132
  30. package/frontend/src/components/AddServerForm.tsx +0 -90
  31. package/frontend/src/components/ChangePasswordForm.tsx +0 -158
  32. package/frontend/src/components/EditGroupForm.tsx +0 -149
  33. package/frontend/src/components/EditServerForm.tsx +0 -76
  34. package/frontend/src/components/GroupCard.tsx +0 -143
  35. package/frontend/src/components/MarketServerCard.tsx +0 -153
  36. package/frontend/src/components/MarketServerDetail.tsx +0 -297
  37. package/frontend/src/components/ProtectedRoute.tsx +0 -27
  38. package/frontend/src/components/ServerCard.tsx +0 -230
  39. package/frontend/src/components/ServerForm.tsx +0 -276
  40. package/frontend/src/components/icons/LucideIcons.tsx +0 -14
  41. package/frontend/src/components/layout/Content.tsx +0 -17
  42. package/frontend/src/components/layout/Header.tsx +0 -61
  43. package/frontend/src/components/layout/Sidebar.tsx +0 -98
  44. package/frontend/src/components/ui/Badge.tsx +0 -33
  45. package/frontend/src/components/ui/Button.tsx +0 -0
  46. package/frontend/src/components/ui/DeleteDialog.tsx +0 -48
  47. package/frontend/src/components/ui/Pagination.tsx +0 -128
  48. package/frontend/src/components/ui/Toast.tsx +0 -96
  49. package/frontend/src/components/ui/ToggleGroup.tsx +0 -134
  50. package/frontend/src/components/ui/ToolCard.tsx +0 -38
  51. package/frontend/src/contexts/AuthContext.tsx +0 -159
  52. package/frontend/src/contexts/ToastContext.tsx +0 -60
  53. package/frontend/src/hooks/useGroupData.ts +0 -232
  54. package/frontend/src/hooks/useMarketData.ts +0 -410
  55. package/frontend/src/hooks/useServerData.ts +0 -306
  56. package/frontend/src/hooks/useSettingsData.ts +0 -131
  57. package/frontend/src/i18n.ts +0 -42
  58. package/frontend/src/index.css +0 -20
  59. package/frontend/src/layouts/MainLayout.tsx +0 -33
  60. package/frontend/src/locales/en.json +0 -214
  61. package/frontend/src/locales/zh.json +0 -214
  62. package/frontend/src/main.tsx +0 -12
  63. package/frontend/src/pages/Dashboard.tsx +0 -206
  64. package/frontend/src/pages/GroupsPage.tsx +0 -116
  65. package/frontend/src/pages/LoginPage.tsx +0 -104
  66. package/frontend/src/pages/MarketPage.tsx +0 -356
  67. package/frontend/src/pages/ServersPage.tsx +0 -144
  68. package/frontend/src/pages/SettingsPage.tsx +0 -149
  69. package/frontend/src/services/authService.ts +0 -141
  70. package/frontend/src/types/index.ts +0 -160
  71. package/frontend/src/utils/cn.ts +0 -10
  72. package/frontend/tsconfig.json +0 -31
  73. package/frontend/tsconfig.node.json +0 -10
  74. package/frontend/vite.config.ts +0 -26
  75. package/googled76ca578b6543fbc.html +0 -1
  76. package/jest.config.js +0 -10
  77. package/mcp_settings.json +0 -45
  78. package/servers.json +0 -74722
  79. package/src/config/index.ts +0 -46
  80. package/src/controllers/authController.ts +0 -179
  81. package/src/controllers/groupController.ts +0 -341
  82. package/src/controllers/marketController.ts +0 -154
  83. package/src/controllers/serverController.ts +0 -303
  84. package/src/index.ts +0 -18
  85. package/src/middlewares/auth.ts +0 -28
  86. package/src/middlewares/index.ts +0 -43
  87. package/src/models/User.ts +0 -103
  88. package/src/routes/index.ts +0 -96
  89. package/src/server.ts +0 -72
  90. package/src/services/groupService.ts +0 -232
  91. package/src/services/marketService.ts +0 -116
  92. package/src/services/mcpService.ts +0 -385
  93. package/src/services/sseService.ts +0 -119
  94. package/src/types/index.ts +0 -129
  95. package/src/utils/migration.ts +0 -52
  96. package/tsconfig.json +0 -17
@@ -1,159 +0,0 @@
1
- import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
2
- import { AuthState, IUser } from '../types';
3
- import * as authService from '../services/authService';
4
-
5
- // Initial auth state
6
- const initialState: AuthState = {
7
- token: null,
8
- isAuthenticated: false,
9
- loading: true,
10
- user: null,
11
- error: null,
12
- };
13
-
14
- // Create auth context
15
- const AuthContext = createContext<{
16
- auth: AuthState;
17
- login: (username: string, password: string) => Promise<boolean>;
18
- register: (username: string, password: string, isAdmin?: boolean) => Promise<boolean>;
19
- logout: () => void;
20
- }>({
21
- auth: initialState,
22
- login: async () => false,
23
- register: async () => false,
24
- logout: () => {},
25
- });
26
-
27
- // Auth provider component
28
- export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
29
- const [auth, setAuth] = useState<AuthState>(initialState);
30
-
31
- // Load user if token exists
32
- useEffect(() => {
33
- const loadUser = async () => {
34
- const token = authService.getToken();
35
-
36
- if (!token) {
37
- setAuth({
38
- ...initialState,
39
- loading: false,
40
- });
41
- return;
42
- }
43
-
44
- try {
45
- const response = await authService.getCurrentUser();
46
-
47
- if (response.success && response.user) {
48
- setAuth({
49
- token,
50
- isAuthenticated: true,
51
- loading: false,
52
- user: response.user,
53
- error: null,
54
- });
55
- } else {
56
- authService.removeToken();
57
- setAuth({
58
- ...initialState,
59
- loading: false,
60
- });
61
- }
62
- } catch (error) {
63
- authService.removeToken();
64
- setAuth({
65
- ...initialState,
66
- loading: false,
67
- });
68
- }
69
- };
70
-
71
- loadUser();
72
- }, []);
73
-
74
- // Login function
75
- const login = async (username: string, password: string): Promise<boolean> => {
76
- try {
77
- const response = await authService.login({ username, password });
78
-
79
- if (response.success && response.token && response.user) {
80
- setAuth({
81
- token: response.token,
82
- isAuthenticated: true,
83
- loading: false,
84
- user: response.user,
85
- error: null,
86
- });
87
- return true;
88
- } else {
89
- setAuth({
90
- ...initialState,
91
- loading: false,
92
- error: response.message || 'Authentication failed',
93
- });
94
- return false;
95
- }
96
- } catch (error) {
97
- setAuth({
98
- ...initialState,
99
- loading: false,
100
- error: 'Authentication failed',
101
- });
102
- return false;
103
- }
104
- };
105
-
106
- // Register function
107
- const register = async (
108
- username: string,
109
- password: string,
110
- isAdmin = false
111
- ): Promise<boolean> => {
112
- try {
113
- const response = await authService.register({ username, password, isAdmin });
114
-
115
- if (response.success && response.token && response.user) {
116
- setAuth({
117
- token: response.token,
118
- isAuthenticated: true,
119
- loading: false,
120
- user: response.user,
121
- error: null,
122
- });
123
- return true;
124
- } else {
125
- setAuth({
126
- ...initialState,
127
- loading: false,
128
- error: response.message || 'Registration failed',
129
- });
130
- return false;
131
- }
132
- } catch (error) {
133
- setAuth({
134
- ...initialState,
135
- loading: false,
136
- error: 'Registration failed',
137
- });
138
- return false;
139
- }
140
- };
141
-
142
- // Logout function
143
- const logout = (): void => {
144
- authService.logout();
145
- setAuth({
146
- ...initialState,
147
- loading: false,
148
- });
149
- };
150
-
151
- return (
152
- <AuthContext.Provider value={{ auth, login, register, logout }}>
153
- {children}
154
- </AuthContext.Provider>
155
- );
156
- };
157
-
158
- // Custom hook to use auth context
159
- export const useAuth = () => useContext(AuthContext);
@@ -1,60 +0,0 @@
1
- import React, { createContext, useContext, useState, ReactNode } from 'react';
2
- import Toast, { ToastType } from '@/components/ui/Toast';
3
-
4
- interface ToastContextProps {
5
- showToast: (message: string, type?: ToastType, duration?: number) => void;
6
- }
7
-
8
- const ToastContext = createContext<ToastContextProps | undefined>(undefined);
9
-
10
- export const useToast = () => {
11
- const context = useContext(ToastContext);
12
- if (!context) {
13
- throw new Error('useToast must be used within a ToastProvider');
14
- }
15
- return context;
16
- };
17
-
18
- interface ToastProviderProps {
19
- children: ReactNode;
20
- }
21
-
22
- export const ToastProvider: React.FC<ToastProviderProps> = ({ children }) => {
23
- const [toast, setToast] = useState<{
24
- message: string;
25
- type: ToastType;
26
- visible: boolean;
27
- duration: number;
28
- }>({
29
- message: '',
30
- type: 'info',
31
- visible: false,
32
- duration: 3000,
33
- });
34
-
35
- const showToast = (message: string, type: ToastType = 'info', duration: number = 3000) => {
36
- setToast({
37
- message,
38
- type,
39
- visible: true,
40
- duration,
41
- });
42
- };
43
-
44
- const hideToast = () => {
45
- setToast((prev) => ({ ...prev, visible: false }));
46
- };
47
-
48
- return (
49
- <ToastContext.Provider value={{ showToast }}>
50
- {children}
51
- <Toast
52
- message={toast.message}
53
- type={toast.type}
54
- duration={toast.duration}
55
- onClose={hideToast}
56
- visible={toast.visible}
57
- />
58
- </ToastContext.Provider>
59
- );
60
- };
@@ -1,232 +0,0 @@
1
- import { useState, useEffect, useCallback } from 'react';
2
- import { useTranslation } from 'react-i18next';
3
- import { Group, ApiResponse } from '@/types';
4
-
5
- export const useGroupData = () => {
6
- const { t } = useTranslation();
7
- const [groups, setGroups] = useState<Group[]>([]);
8
- const [loading, setLoading] = useState(true);
9
- const [error, setError] = useState<string | null>(null);
10
- const [refreshKey, setRefreshKey] = useState(0);
11
-
12
- const fetchGroups = useCallback(async () => {
13
- try {
14
- setLoading(true);
15
- const token = localStorage.getItem('mcphub_token');
16
- const response = await fetch('/api/groups', {
17
- headers: {
18
- 'x-auth-token': token || ''
19
- }
20
- });
21
-
22
- if (!response.ok) {
23
- throw new Error(`Status: ${response.status}`);
24
- }
25
-
26
- const data: ApiResponse<Group[]> = await response.json();
27
-
28
- if (data && data.success && Array.isArray(data.data)) {
29
- setGroups(data.data);
30
- } else {
31
- console.error('Invalid group data format:', data);
32
- setGroups([]);
33
- }
34
-
35
- setError(null);
36
- } catch (err) {
37
- console.error('Error fetching groups:', err);
38
- setError(err instanceof Error ? err.message : 'Failed to fetch groups');
39
- setGroups([]);
40
- } finally {
41
- setLoading(false);
42
- }
43
- }, []);
44
-
45
- // Trigger a refresh of the groups data
46
- const triggerRefresh = useCallback(() => {
47
- setRefreshKey(prev => prev + 1);
48
- }, []);
49
-
50
- // Create a new group with server associations
51
- const createGroup = async (name: string, description?: string, servers: string[] = []) => {
52
- try {
53
- const token = localStorage.getItem('mcphub_token');
54
- const response = await fetch('/api/groups', {
55
- method: 'POST',
56
- headers: {
57
- 'Content-Type': 'application/json',
58
- 'x-auth-token': token || ''
59
- },
60
- body: JSON.stringify({ name, description, servers }),
61
- });
62
-
63
- const result: ApiResponse<Group> = await response.json();
64
-
65
- if (!response.ok) {
66
- setError(result.message || t('groups.createError'));
67
- return null;
68
- }
69
-
70
- triggerRefresh();
71
- return result.data || null;
72
- } catch (err) {
73
- setError(err instanceof Error ? err.message : 'Failed to create group');
74
- return null;
75
- }
76
- };
77
-
78
- // Update an existing group with server associations
79
- const updateGroup = async (id: string, data: { name?: string; description?: string; servers?: string[] }) => {
80
- try {
81
- const token = localStorage.getItem('mcphub_token');
82
- const response = await fetch(`/api/groups/${id}`, {
83
- method: 'PUT',
84
- headers: {
85
- 'Content-Type': 'application/json',
86
- 'x-auth-token': token || ''
87
- },
88
- body: JSON.stringify(data),
89
- });
90
-
91
- const result: ApiResponse<Group> = await response.json();
92
-
93
- if (!response.ok) {
94
- setError(result.message || t('groups.updateError'));
95
- return null;
96
- }
97
-
98
- triggerRefresh();
99
- return result.data || null;
100
- } catch (err) {
101
- setError(err instanceof Error ? err.message : 'Failed to update group');
102
- return null;
103
- }
104
- };
105
-
106
- // Update servers in a group (for batch updates)
107
- const updateGroupServers = async (groupId: string, servers: string[]) => {
108
- try {
109
- const token = localStorage.getItem('mcphub_token');
110
- const response = await fetch(`/api/groups/${groupId}/servers/batch`, {
111
- method: 'PUT',
112
- headers: {
113
- 'Content-Type': 'application/json',
114
- 'x-auth-token': token || ''
115
- },
116
- body: JSON.stringify({ servers }),
117
- });
118
-
119
- const result: ApiResponse<Group> = await response.json();
120
-
121
- if (!response.ok) {
122
- setError(result.message || t('groups.updateError'));
123
- return null;
124
- }
125
-
126
- triggerRefresh();
127
- return result.data || null;
128
- } catch (err) {
129
- setError(err instanceof Error ? err.message : 'Failed to update group servers');
130
- return null;
131
- }
132
- };
133
-
134
- // Delete a group
135
- const deleteGroup = async (id: string) => {
136
- try {
137
- const token = localStorage.getItem('mcphub_token');
138
- const response = await fetch(`/api/groups/${id}`, {
139
- method: 'DELETE',
140
- headers: {
141
- 'x-auth-token': token || ''
142
- }
143
- });
144
-
145
- const result = await response.json();
146
-
147
- if (!response.ok) {
148
- setError(result.message || t('groups.deleteError'));
149
- return false;
150
- }
151
-
152
- triggerRefresh();
153
- return true;
154
- } catch (err) {
155
- setError(err instanceof Error ? err.message : 'Failed to delete group');
156
- return false;
157
- }
158
- };
159
-
160
- // Add server to a group
161
- const addServerToGroup = async (groupId: string, serverName: string) => {
162
- try {
163
- const token = localStorage.getItem('mcphub_token');
164
- const response = await fetch(`/api/groups/${groupId}/servers`, {
165
- method: 'POST',
166
- headers: {
167
- 'Content-Type': 'application/json',
168
- 'x-auth-token': token || ''
169
- },
170
- body: JSON.stringify({ serverName }),
171
- });
172
-
173
- const result: ApiResponse<Group> = await response.json();
174
-
175
- if (!response.ok) {
176
- setError(result.message || t('groups.serverAddError'));
177
- return null;
178
- }
179
-
180
- triggerRefresh();
181
- return result.data || null;
182
- } catch (err) {
183
- setError(err instanceof Error ? err.message : 'Failed to add server to group');
184
- return null;
185
- }
186
- };
187
-
188
- // Remove server from group
189
- const removeServerFromGroup = async (groupId: string, serverName: string) => {
190
- try {
191
- const token = localStorage.getItem('mcphub_token');
192
- const response = await fetch(`/api/groups/${groupId}/servers/${serverName}`, {
193
- method: 'DELETE',
194
- headers: {
195
- 'x-auth-token': token || ''
196
- }
197
- });
198
-
199
- const result: ApiResponse<Group> = await response.json();
200
-
201
- if (!response.ok) {
202
- setError(result.message || t('groups.serverRemoveError'));
203
- return null;
204
- }
205
-
206
- triggerRefresh();
207
- return result.data || null;
208
- } catch (err) {
209
- setError(err instanceof Error ? err.message : 'Failed to remove server from group');
210
- return null;
211
- }
212
- };
213
-
214
- // Fetch groups when the component mounts or refreshKey changes
215
- useEffect(() => {
216
- fetchGroups();
217
- }, [fetchGroups, refreshKey]);
218
-
219
- return {
220
- groups,
221
- loading,
222
- error,
223
- setError,
224
- triggerRefresh,
225
- createGroup,
226
- updateGroup,
227
- updateGroupServers,
228
- deleteGroup,
229
- addServerToGroup,
230
- removeServerFromGroup
231
- };
232
- };