@mcp-shark/mcp-shark 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/LICENSE +85 -0
  2. package/README.md +724 -0
  3. package/bin/mcp-shark.js +93 -0
  4. package/mcp-server/.editorconfig +15 -0
  5. package/mcp-server/.prettierignore +11 -0
  6. package/mcp-server/.prettierrc +12 -0
  7. package/mcp-server/README.md +280 -0
  8. package/mcp-server/commitlint.config.cjs +42 -0
  9. package/mcp-server/eslint.config.js +131 -0
  10. package/mcp-server/lib/auditor/audit.js +228 -0
  11. package/mcp-server/lib/common/error.js +15 -0
  12. package/mcp-server/lib/server/external/all.js +32 -0
  13. package/mcp-server/lib/server/external/config.js +59 -0
  14. package/mcp-server/lib/server/external/kv.js +102 -0
  15. package/mcp-server/lib/server/external/single/client.js +35 -0
  16. package/mcp-server/lib/server/external/single/request.js +49 -0
  17. package/mcp-server/lib/server/external/single/run.js +75 -0
  18. package/mcp-server/lib/server/external/single/transport.js +57 -0
  19. package/mcp-server/lib/server/internal/handlers/common.js +20 -0
  20. package/mcp-server/lib/server/internal/handlers/error.js +7 -0
  21. package/mcp-server/lib/server/internal/handlers/prompts-get.js +22 -0
  22. package/mcp-server/lib/server/internal/handlers/prompts-list.js +12 -0
  23. package/mcp-server/lib/server/internal/handlers/resources-list.js +12 -0
  24. package/mcp-server/lib/server/internal/handlers/resources-read.js +19 -0
  25. package/mcp-server/lib/server/internal/handlers/tools-call.js +37 -0
  26. package/mcp-server/lib/server/internal/handlers/tools-list.js +14 -0
  27. package/mcp-server/lib/server/internal/run.js +49 -0
  28. package/mcp-server/lib/server/internal/server.js +63 -0
  29. package/mcp-server/lib/server/internal/session.js +39 -0
  30. package/mcp-server/mcp-shark.js +72 -0
  31. package/mcp-server/package-lock.json +4784 -0
  32. package/mcp-server/package.json +30 -0
  33. package/package.json +103 -0
  34. package/ui/README.md +212 -0
  35. package/ui/index.html +16 -0
  36. package/ui/package-lock.json +3574 -0
  37. package/ui/package.json +12 -0
  38. package/ui/paths.js +282 -0
  39. package/ui/public/og-image.png +0 -0
  40. package/ui/server/routes/backups.js +251 -0
  41. package/ui/server/routes/composite.js +244 -0
  42. package/ui/server/routes/config.js +175 -0
  43. package/ui/server/routes/conversations.js +25 -0
  44. package/ui/server/routes/help.js +43 -0
  45. package/ui/server/routes/logs.js +32 -0
  46. package/ui/server/routes/playground.js +152 -0
  47. package/ui/server/routes/requests.js +235 -0
  48. package/ui/server/routes/sessions.js +27 -0
  49. package/ui/server/routes/smartscan/discover.js +117 -0
  50. package/ui/server/routes/smartscan/scans/clearCache.js +22 -0
  51. package/ui/server/routes/smartscan/scans/createBatchScans.js +123 -0
  52. package/ui/server/routes/smartscan/scans/createScan.js +42 -0
  53. package/ui/server/routes/smartscan/scans/getCachedResults.js +51 -0
  54. package/ui/server/routes/smartscan/scans/getScan.js +41 -0
  55. package/ui/server/routes/smartscan/scans/listScans.js +24 -0
  56. package/ui/server/routes/smartscan/scans.js +13 -0
  57. package/ui/server/routes/smartscan/token.js +56 -0
  58. package/ui/server/routes/smartscan/transport.js +53 -0
  59. package/ui/server/routes/smartscan.js +24 -0
  60. package/ui/server/routes/statistics.js +83 -0
  61. package/ui/server/utils/config-update.js +212 -0
  62. package/ui/server/utils/config.js +98 -0
  63. package/ui/server/utils/paths.js +23 -0
  64. package/ui/server/utils/port.js +28 -0
  65. package/ui/server/utils/process.js +80 -0
  66. package/ui/server/utils/scan-cache/all-results.js +180 -0
  67. package/ui/server/utils/scan-cache/directory.js +35 -0
  68. package/ui/server/utils/scan-cache/file-operations.js +104 -0
  69. package/ui/server/utils/scan-cache/hash.js +47 -0
  70. package/ui/server/utils/scan-cache/server-operations.js +80 -0
  71. package/ui/server/utils/scan-cache.js +12 -0
  72. package/ui/server/utils/serialization.js +13 -0
  73. package/ui/server/utils/smartscan-token.js +42 -0
  74. package/ui/server.js +199 -0
  75. package/ui/src/App.jsx +153 -0
  76. package/ui/src/CompositeLogs.jsx +164 -0
  77. package/ui/src/CompositeSetup.jsx +285 -0
  78. package/ui/src/HelpGuide/HelpGuideContent.jsx +118 -0
  79. package/ui/src/HelpGuide/HelpGuideFooter.jsx +58 -0
  80. package/ui/src/HelpGuide/HelpGuideHeader.jsx +56 -0
  81. package/ui/src/HelpGuide.jsx +65 -0
  82. package/ui/src/IntroTour.jsx +140 -0
  83. package/ui/src/LogDetail.jsx +122 -0
  84. package/ui/src/LogTable.jsx +242 -0
  85. package/ui/src/PacketDetail.jsx +190 -0
  86. package/ui/src/PacketFilters.jsx +222 -0
  87. package/ui/src/PacketList.jsx +183 -0
  88. package/ui/src/SmartScan.jsx +178 -0
  89. package/ui/src/TabNavigation.jsx +143 -0
  90. package/ui/src/components/App/HelpButton.jsx +64 -0
  91. package/ui/src/components/App/TrafficTab.jsx +69 -0
  92. package/ui/src/components/App/useAppState.js +163 -0
  93. package/ui/src/components/BackupList.jsx +192 -0
  94. package/ui/src/components/CollapsibleSection.jsx +82 -0
  95. package/ui/src/components/ConfigFileSection.jsx +84 -0
  96. package/ui/src/components/ConfigViewerModal.jsx +141 -0
  97. package/ui/src/components/ConfirmationModal.jsx +129 -0
  98. package/ui/src/components/DetailsTab/BodySection.jsx +27 -0
  99. package/ui/src/components/DetailsTab/CollapsibleRequestResponse.jsx +70 -0
  100. package/ui/src/components/DetailsTab/HeadersSection.jsx +25 -0
  101. package/ui/src/components/DetailsTab/InfoSection.jsx +28 -0
  102. package/ui/src/components/DetailsTab/NetworkInfoSection.jsx +63 -0
  103. package/ui/src/components/DetailsTab/ProtocolInfoSection.jsx +75 -0
  104. package/ui/src/components/DetailsTab/RequestDetailsSection.jsx +46 -0
  105. package/ui/src/components/DetailsTab/ResponseDetailsSection.jsx +66 -0
  106. package/ui/src/components/DetailsTab.jsx +31 -0
  107. package/ui/src/components/DetectedPathsList.jsx +171 -0
  108. package/ui/src/components/FileInput.jsx +144 -0
  109. package/ui/src/components/GroupHeader.jsx +76 -0
  110. package/ui/src/components/GroupedByMcpView.jsx +103 -0
  111. package/ui/src/components/GroupedByServerView.jsx +134 -0
  112. package/ui/src/components/GroupedBySessionView.jsx +127 -0
  113. package/ui/src/components/GroupedViews.jsx +2 -0
  114. package/ui/src/components/HexTab.jsx +188 -0
  115. package/ui/src/components/LogsDisplay.jsx +93 -0
  116. package/ui/src/components/LogsToolbar.jsx +193 -0
  117. package/ui/src/components/McpPlayground/LoadingModal.jsx +113 -0
  118. package/ui/src/components/McpPlayground/PromptsSection/PromptCallPanel.jsx +125 -0
  119. package/ui/src/components/McpPlayground/PromptsSection/PromptItem.jsx +48 -0
  120. package/ui/src/components/McpPlayground/PromptsSection/PromptsList.jsx +45 -0
  121. package/ui/src/components/McpPlayground/PromptsSection.jsx +106 -0
  122. package/ui/src/components/McpPlayground/ResourcesSection/ResourceCallPanel.jsx +89 -0
  123. package/ui/src/components/McpPlayground/ResourcesSection/ResourceItem.jsx +59 -0
  124. package/ui/src/components/McpPlayground/ResourcesSection/ResourcesList.jsx +45 -0
  125. package/ui/src/components/McpPlayground/ResourcesSection.jsx +91 -0
  126. package/ui/src/components/McpPlayground/ToolsSection/ToolCallPanel.jsx +125 -0
  127. package/ui/src/components/McpPlayground/ToolsSection/ToolItem.jsx +48 -0
  128. package/ui/src/components/McpPlayground/ToolsSection/ToolsList.jsx +45 -0
  129. package/ui/src/components/McpPlayground/ToolsSection.jsx +107 -0
  130. package/ui/src/components/McpPlayground/common/EmptyState.jsx +17 -0
  131. package/ui/src/components/McpPlayground/common/ErrorState.jsx +17 -0
  132. package/ui/src/components/McpPlayground/common/LoadingState.jsx +17 -0
  133. package/ui/src/components/McpPlayground/useMcpPlayground.js +280 -0
  134. package/ui/src/components/McpPlayground.jsx +171 -0
  135. package/ui/src/components/MessageDisplay.jsx +28 -0
  136. package/ui/src/components/PacketDetailHeader.jsx +88 -0
  137. package/ui/src/components/PacketFilters/ExportControls.jsx +126 -0
  138. package/ui/src/components/PacketFilters/FilterInput.jsx +59 -0
  139. package/ui/src/components/RawTab.jsx +142 -0
  140. package/ui/src/components/RequestRow/OrphanedResponseRow.jsx +155 -0
  141. package/ui/src/components/RequestRow/RequestRowMain.jsx +240 -0
  142. package/ui/src/components/RequestRow/ResponseRow.jsx +158 -0
  143. package/ui/src/components/RequestRow.jsx +70 -0
  144. package/ui/src/components/ServerControl.jsx +133 -0
  145. package/ui/src/components/ServiceSelector.jsx +209 -0
  146. package/ui/src/components/SetupHeader.jsx +30 -0
  147. package/ui/src/components/SharkLogo.jsx +21 -0
  148. package/ui/src/components/SmartScan/AnalysisResult.jsx +64 -0
  149. package/ui/src/components/SmartScan/BatchResultsDisplay/BatchResultItem.jsx +215 -0
  150. package/ui/src/components/SmartScan/BatchResultsDisplay/BatchResultsHeader.jsx +94 -0
  151. package/ui/src/components/SmartScan/BatchResultsDisplay.jsx +26 -0
  152. package/ui/src/components/SmartScan/DebugInfoSection.jsx +53 -0
  153. package/ui/src/components/SmartScan/EmptyState.jsx +57 -0
  154. package/ui/src/components/SmartScan/ErrorDisplay.jsx +48 -0
  155. package/ui/src/components/SmartScan/ExpandableSection.jsx +93 -0
  156. package/ui/src/components/SmartScan/FindingsTable.jsx +257 -0
  157. package/ui/src/components/SmartScan/ListViewContent.jsx +75 -0
  158. package/ui/src/components/SmartScan/NotablePatternsSection.jsx +75 -0
  159. package/ui/src/components/SmartScan/OverallSummarySection.jsx +72 -0
  160. package/ui/src/components/SmartScan/RawDataSection.jsx +52 -0
  161. package/ui/src/components/SmartScan/RecommendationsSection.jsx +78 -0
  162. package/ui/src/components/SmartScan/ScanDetailHeader.jsx +92 -0
  163. package/ui/src/components/SmartScan/ScanDetailView.jsx +141 -0
  164. package/ui/src/components/SmartScan/ScanListView/ScanListHeader.jsx +49 -0
  165. package/ui/src/components/SmartScan/ScanListView/ScanListItem.jsx +201 -0
  166. package/ui/src/components/SmartScan/ScanListView.jsx +73 -0
  167. package/ui/src/components/SmartScan/ScanOverviewSection.jsx +123 -0
  168. package/ui/src/components/SmartScan/ScanResultsDisplay.jsx +35 -0
  169. package/ui/src/components/SmartScan/ScanViewContent.jsx +68 -0
  170. package/ui/src/components/SmartScan/ScanningProgress.jsx +47 -0
  171. package/ui/src/components/SmartScan/ServerInfoSection.jsx +43 -0
  172. package/ui/src/components/SmartScan/ServerSelectionRow.jsx +207 -0
  173. package/ui/src/components/SmartScan/SingleResultDisplay.jsx +269 -0
  174. package/ui/src/components/SmartScan/SmartScanControls.jsx +290 -0
  175. package/ui/src/components/SmartScan/SmartScanHeader.jsx +77 -0
  176. package/ui/src/components/SmartScan/ViewModeTabs.jsx +57 -0
  177. package/ui/src/components/SmartScan/hooks/useCacheManagement.js +34 -0
  178. package/ui/src/components/SmartScan/hooks/useMcpDiscovery.js +121 -0
  179. package/ui/src/components/SmartScan/hooks/useScanList.js +193 -0
  180. package/ui/src/components/SmartScan/hooks/useScanOperations.js +87 -0
  181. package/ui/src/components/SmartScan/hooks/useServerStatus.js +26 -0
  182. package/ui/src/components/SmartScan/hooks/useTokenManagement.js +53 -0
  183. package/ui/src/components/SmartScan/scanDataUtils.js +98 -0
  184. package/ui/src/components/SmartScan/useSmartScan.js +72 -0
  185. package/ui/src/components/SmartScan/utils.js +19 -0
  186. package/ui/src/components/SmartScanIcons.jsx +58 -0
  187. package/ui/src/components/TabNavigation/DesktopTabs.jsx +111 -0
  188. package/ui/src/components/TabNavigation/MobileDropdown.jsx +140 -0
  189. package/ui/src/components/TabNavigation.jsx +97 -0
  190. package/ui/src/components/TabNavigationIcons.jsx +40 -0
  191. package/ui/src/components/TableHeader.jsx +164 -0
  192. package/ui/src/components/TourOverlay.jsx +117 -0
  193. package/ui/src/components/TourTooltip/TourTooltipButtons.jsx +117 -0
  194. package/ui/src/components/TourTooltip/TourTooltipHeader.jsx +70 -0
  195. package/ui/src/components/TourTooltip/TourTooltipIcons.jsx +45 -0
  196. package/ui/src/components/TourTooltip/useTooltipPosition.js +108 -0
  197. package/ui/src/components/TourTooltip.jsx +83 -0
  198. package/ui/src/components/ViewModeTabs.jsx +91 -0
  199. package/ui/src/components/WhatThisDoesSection.jsx +61 -0
  200. package/ui/src/config/tourSteps.jsx +141 -0
  201. package/ui/src/hooks/useAnimation.js +92 -0
  202. package/ui/src/hooks/useConfigManagement.js +124 -0
  203. package/ui/src/hooks/useServiceExtraction.js +51 -0
  204. package/ui/src/index.css +42 -0
  205. package/ui/src/main.jsx +10 -0
  206. package/ui/src/theme.js +65 -0
  207. package/ui/src/utils/animations.js +170 -0
  208. package/ui/src/utils/groupingUtils.js +93 -0
  209. package/ui/src/utils/hexUtils.js +24 -0
  210. package/ui/src/utils/mcpGroupingUtils.js +262 -0
  211. package/ui/src/utils/requestUtils.js +297 -0
  212. package/ui/vite.config.js +18 -0
@@ -0,0 +1,285 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { colors } from './theme';
3
+ import SetupHeader from './components/SetupHeader';
4
+ import ConfigFileSection from './components/ConfigFileSection';
5
+ import WhatThisDoesSection from './components/WhatThisDoesSection';
6
+ import ServerControl from './components/ServerControl';
7
+ import MessageDisplay from './components/MessageDisplay';
8
+ import BackupList from './components/BackupList';
9
+ import ConfigViewerModal from './components/ConfigViewerModal';
10
+ import { useServiceExtraction } from './hooks/useServiceExtraction';
11
+ import { useConfigManagement } from './hooks/useConfigManagement';
12
+
13
+ function CompositeSetup() {
14
+ const [fileContent, setFileContent] = useState('');
15
+ const [filePath, setFilePath] = useState('');
16
+ const [updatePath, setUpdatePath] = useState('');
17
+ const [status, setStatus] = useState({ running: false, pid: null });
18
+ const [loading, setLoading] = useState(false);
19
+ const [message, setMessage] = useState(null);
20
+ const [error, setError] = useState(null);
21
+
22
+ const { services, selectedServices, setSelectedServices } = useServiceExtraction(
23
+ fileContent,
24
+ filePath
25
+ );
26
+
27
+ const {
28
+ detectedPaths,
29
+ detecting,
30
+ detectConfigPaths,
31
+ backups,
32
+ loadingBackups,
33
+ loadBackups,
34
+ viewingConfig,
35
+ configContent,
36
+ loadingConfig,
37
+ handleViewConfig,
38
+ setViewingConfig,
39
+ setConfigContent,
40
+ viewingBackup,
41
+ backupContent,
42
+ loadingBackup,
43
+ handleViewBackup,
44
+ handleDeleteBackup,
45
+ setViewingBackup,
46
+ setBackupContent,
47
+ } = useConfigManagement();
48
+
49
+ useEffect(() => {
50
+ fetchStatus();
51
+ const interval = setInterval(fetchStatus, 2000);
52
+ return () => clearInterval(interval);
53
+ }, []);
54
+
55
+ const handleRestore = async (backupPath, originalPath) => {
56
+ if (
57
+ !confirm(
58
+ 'Are you sure you want to restore this backup? This will overwrite the current config file.'
59
+ )
60
+ ) {
61
+ return;
62
+ }
63
+
64
+ try {
65
+ const res = await fetch('/api/config/restore', {
66
+ method: 'POST',
67
+ headers: { 'Content-Type': 'application/json' },
68
+ body: JSON.stringify({ backupPath, originalPath }),
69
+ });
70
+
71
+ const data = await res.json();
72
+ if (res.ok) {
73
+ setMessage(data.message || 'Config restored successfully');
74
+ setError(null);
75
+ loadBackups();
76
+ detectConfigPaths();
77
+ } else {
78
+ setError(data.error || 'Failed to restore backup');
79
+ setMessage(null);
80
+ }
81
+ } catch (err) {
82
+ setError(err.message || 'Failed to restore backup');
83
+ setMessage(null);
84
+ }
85
+ };
86
+
87
+ const handleDelete = async (backupPath) => {
88
+ const success = await handleDeleteBackup(backupPath);
89
+ if (success) {
90
+ setMessage('Backup deleted successfully');
91
+ setError(null);
92
+ } else {
93
+ setError('Failed to delete backup');
94
+ setMessage(null);
95
+ }
96
+ };
97
+
98
+ const fetchStatus = async () => {
99
+ try {
100
+ const res = await fetch('/api/composite/status');
101
+ const data = await res.json();
102
+ setStatus(data);
103
+ } catch (err) {
104
+ console.error('Failed to fetch status:', err);
105
+ }
106
+ };
107
+
108
+ const handleFileSelect = (e) => {
109
+ const file = e.target.files[0];
110
+ if (file) {
111
+ const reader = new FileReader();
112
+ reader.onload = (event) => {
113
+ setFileContent(event.target.result);
114
+ };
115
+ reader.readAsText(file);
116
+ }
117
+ };
118
+
119
+ const handlePathInput = (e) => {
120
+ const value = e.target.value;
121
+ setFilePath(value);
122
+ if (value) {
123
+ setFileContent('');
124
+ }
125
+ };
126
+
127
+ const handleUpdatePathInput = (e) => {
128
+ setUpdatePath(e.target.value);
129
+ };
130
+
131
+ const handleSetup = async () => {
132
+ setLoading(true);
133
+ setError(null);
134
+ setMessage(null);
135
+
136
+ try {
137
+ const payload = fileContent ? { fileContent, filePath: updatePath || null } : { filePath };
138
+
139
+ if (selectedServices.size > 0) {
140
+ payload.selectedServices = Array.from(selectedServices);
141
+ }
142
+
143
+ const res = await fetch('/api/composite/setup', {
144
+ method: 'POST',
145
+ headers: { 'Content-Type': 'application/json' },
146
+ body: JSON.stringify(payload),
147
+ });
148
+
149
+ const data = await res.json();
150
+
151
+ if (res.ok) {
152
+ const msg = data.message || 'MCP Shark server started successfully';
153
+ setMessage(data.backupPath ? `${msg} (Backup saved to ${data.backupPath})` : msg);
154
+ setFileContent('');
155
+ setFilePath('');
156
+ setUpdatePath('');
157
+ setSelectedServices(new Set());
158
+ setTimeout(fetchStatus, 1000);
159
+ } else {
160
+ setError(data.error || 'Failed to setup MCP Shark server');
161
+ }
162
+ } catch (err) {
163
+ setError(err.message || 'Failed to setup MCP Shark server');
164
+ } finally {
165
+ setLoading(false);
166
+ }
167
+ };
168
+
169
+ const handleStop = async () => {
170
+ setLoading(true);
171
+ setError(null);
172
+ setMessage(null);
173
+
174
+ try {
175
+ const res = await fetch('/api/composite/stop', {
176
+ method: 'POST',
177
+ });
178
+
179
+ const data = await res.json();
180
+
181
+ if (res.ok) {
182
+ const msg = data.message || 'MCP Shark server stopped';
183
+ setMessage(
184
+ data.message && data.message.includes('restored')
185
+ ? 'MCP Shark server stopped and original config file restored'
186
+ : msg
187
+ );
188
+ setTimeout(fetchStatus, 1000);
189
+ } else {
190
+ setError(data.error || 'Failed to stop MCP Shark server');
191
+ }
192
+ } catch (err) {
193
+ setError(err.message || 'Failed to stop MCP Shark server');
194
+ } finally {
195
+ setLoading(false);
196
+ }
197
+ };
198
+
199
+ const canStart =
200
+ (fileContent || filePath) && (services.length === 0 || selectedServices.size > 0);
201
+
202
+ return (
203
+ <div
204
+ style={{
205
+ position: 'relative',
206
+ width: '100%',
207
+ height: '100%',
208
+ background: colors.bgPrimary,
209
+ overflow: 'auto',
210
+ }}
211
+ >
212
+ <div
213
+ style={{
214
+ width: '100%',
215
+ maxWidth: '1200px',
216
+ margin: '0 auto',
217
+ padding: '32px',
218
+ minHeight: '100%',
219
+ boxSizing: 'border-box',
220
+ }}
221
+ >
222
+ <SetupHeader />
223
+
224
+ <ConfigFileSection
225
+ detectedPaths={detectedPaths}
226
+ detecting={detecting}
227
+ onDetect={detectConfigPaths}
228
+ onPathSelect={(path) => {
229
+ setFilePath(path);
230
+ setFileContent('');
231
+ setUpdatePath(path);
232
+ }}
233
+ onViewConfig={handleViewConfig}
234
+ filePath={filePath}
235
+ fileContent={fileContent}
236
+ updatePath={updatePath}
237
+ onFileSelect={handleFileSelect}
238
+ onPathChange={handlePathInput}
239
+ onUpdatePathChange={handleUpdatePathInput}
240
+ services={services}
241
+ selectedServices={selectedServices}
242
+ onSelectionChange={setSelectedServices}
243
+ />
244
+
245
+ <ServerControl
246
+ status={status}
247
+ loading={loading}
248
+ onStart={handleSetup}
249
+ onStop={handleStop}
250
+ canStart={canStart}
251
+ />
252
+
253
+ <MessageDisplay message={message} error={error} />
254
+
255
+ <BackupList
256
+ backups={backups}
257
+ loadingBackups={loadingBackups}
258
+ onRefresh={loadBackups}
259
+ onRestore={handleRestore}
260
+ onView={handleViewBackup}
261
+ onDelete={handleDelete}
262
+ />
263
+
264
+ <WhatThisDoesSection filePath={filePath} updatePath={updatePath} />
265
+ </div>
266
+
267
+ <ConfigViewerModal
268
+ viewingConfig={viewingConfig}
269
+ configContent={configContent}
270
+ loadingConfig={loadingConfig}
271
+ viewingBackup={viewingBackup}
272
+ backupContent={backupContent}
273
+ loadingBackup={loadingBackup}
274
+ onClose={() => {
275
+ setViewingConfig(null);
276
+ setConfigContent(null);
277
+ setViewingBackup(null);
278
+ setBackupContent(null);
279
+ }}
280
+ />
281
+ </div>
282
+ );
283
+ }
284
+
285
+ export default CompositeSetup;
@@ -0,0 +1,118 @@
1
+ import { colors, fonts } from '../theme';
2
+
3
+ export default function HelpGuideContent() {
4
+ return (
5
+ <div
6
+ style={{
7
+ color: colors.textPrimary,
8
+ lineHeight: '1.6',
9
+ fontSize: '14px',
10
+ fontFamily: fonts.body,
11
+ }}
12
+ >
13
+ <section style={{ marginBottom: '24px' }}>
14
+ <h3
15
+ style={{
16
+ color: colors.accentBlue,
17
+ marginTop: 0,
18
+ marginBottom: '12px',
19
+ fontSize: '16px',
20
+ fontFamily: fonts.body,
21
+ }}
22
+ >
23
+ What is MCP Shark?
24
+ </h3>
25
+ <p style={{ margin: 0, color: colors.textSecondary }}>
26
+ MCP Shark is a powerful tool for monitoring, debugging, and analyzing Model Context
27
+ Protocol (MCP) traffic. It captures all communication between MCP clients and servers,
28
+ allowing you to inspect requests, responses, and understand the flow of data.
29
+ </p>
30
+ </section>
31
+
32
+ <section style={{ marginBottom: '24px' }}>
33
+ <h3
34
+ style={{
35
+ color: colors.accentBlue,
36
+ marginTop: 0,
37
+ marginBottom: '12px',
38
+ fontSize: '16px',
39
+ fontFamily: fonts.body,
40
+ }}
41
+ >
42
+ Getting Started
43
+ </h3>
44
+ <ol style={{ margin: 0, paddingLeft: '20px', color: colors.textSecondary }}>
45
+ <li style={{ marginBottom: '8px' }}>
46
+ Go to the <strong>Setup</strong> tab to configure your MCP servers
47
+ </li>
48
+ <li style={{ marginBottom: '8px' }}>
49
+ Start the MCP Shark server to begin capturing traffic
50
+ </li>
51
+ <li style={{ marginBottom: '8px' }}>
52
+ Use your MCP client (Cursor, Claude Desktop, etc.) as normal
53
+ </li>
54
+ <li style={{ marginBottom: '8px' }}>
55
+ View captured traffic in the <strong>Traffic Capture</strong> tab
56
+ </li>
57
+ </ol>
58
+ </section>
59
+
60
+ <section style={{ marginBottom: '24px' }}>
61
+ <h3
62
+ style={{
63
+ color: colors.accentBlue,
64
+ marginTop: 0,
65
+ marginBottom: '12px',
66
+ fontSize: '16px',
67
+ fontFamily: fonts.body,
68
+ }}
69
+ >
70
+ Traffic Capture Features
71
+ </h3>
72
+ <ul style={{ margin: 0, paddingLeft: '20px', color: colors.textSecondary }}>
73
+ <li style={{ marginBottom: '8px' }}>
74
+ <strong>General List:</strong> View all requests in a flat chronological list
75
+ </li>
76
+ <li style={{ marginBottom: '8px' }}>
77
+ <strong>MCP Protocol View:</strong> Organize traffic by MCP protocol categories
78
+ </li>
79
+ <li style={{ marginBottom: '8px' }}>
80
+ <strong>Filters:</strong> Use the search bar and filters to find specific requests,
81
+ sessions, or servers
82
+ </li>
83
+ <li style={{ marginBottom: '8px' }}>
84
+ <strong>Details:</strong> Click any request to view full headers, body, and metadata
85
+ </li>
86
+ </ul>
87
+ </section>
88
+
89
+ <section style={{ marginBottom: '24px' }}>
90
+ <h3
91
+ style={{
92
+ color: colors.accentBlue,
93
+ marginTop: 0,
94
+ marginBottom: '12px',
95
+ fontSize: '16px',
96
+ fontFamily: fonts.body,
97
+ }}
98
+ >
99
+ Tips
100
+ </h3>
101
+ <ul style={{ margin: 0, paddingLeft: '20px', color: colors.textSecondary }}>
102
+ <li style={{ marginBottom: '8px' }}>
103
+ Use the search bar to find requests by method, URL, JSON-RPC method, or any text content
104
+ </li>
105
+ <li style={{ marginBottom: '8px' }}>
106
+ Filter by session ID to track a specific conversation
107
+ </li>
108
+ <li style={{ marginBottom: '8px' }}>
109
+ Filter by server name to see all traffic for a specific MCP server
110
+ </li>
111
+ <li style={{ marginBottom: '8px' }}>
112
+ Click on request/response rows to see detailed packet information
113
+ </li>
114
+ </ul>
115
+ </section>
116
+ </div>
117
+ );
118
+ }
@@ -0,0 +1,58 @@
1
+ import { colors, fonts } from '../theme';
2
+
3
+ export default function HelpGuideFooter({ dontShowAgain, setDontShowAgain, onClose }) {
4
+ return (
5
+ <div
6
+ style={{
7
+ marginTop: '24px',
8
+ paddingTop: '20px',
9
+ borderTop: `1px solid ${colors.borderLight}`,
10
+ display: 'flex',
11
+ alignItems: 'center',
12
+ justifyContent: 'space-between',
13
+ }}
14
+ >
15
+ <label
16
+ style={{
17
+ display: 'flex',
18
+ alignItems: 'center',
19
+ gap: '8px',
20
+ color: colors.textTertiary,
21
+ cursor: 'pointer',
22
+ fontSize: '13px',
23
+ fontFamily: fonts.body,
24
+ }}
25
+ >
26
+ <input
27
+ type="checkbox"
28
+ checked={dontShowAgain}
29
+ onChange={(e) => setDontShowAgain(e.target.checked)}
30
+ style={{ cursor: 'pointer' }}
31
+ />
32
+ Don't show this again
33
+ </label>
34
+ <button
35
+ onClick={onClose}
36
+ style={{
37
+ background: colors.buttonPrimary,
38
+ border: 'none',
39
+ color: colors.textInverse,
40
+ padding: '8px 20px',
41
+ borderRadius: '4px',
42
+ cursor: 'pointer',
43
+ fontSize: '14px',
44
+ fontWeight: '500',
45
+ fontFamily: fonts.body,
46
+ }}
47
+ onMouseEnter={(e) => {
48
+ e.currentTarget.style.background = colors.buttonPrimaryHover;
49
+ }}
50
+ onMouseLeave={(e) => {
51
+ e.currentTarget.style.background = colors.buttonPrimary;
52
+ }}
53
+ >
54
+ Got it!
55
+ </button>
56
+ </div>
57
+ );
58
+ }
@@ -0,0 +1,56 @@
1
+ import { colors, fonts } from '../theme';
2
+ import { IconHelp, IconX } from '@tabler/icons-react';
3
+
4
+ export default function HelpGuideHeader({ onClose }) {
5
+ return (
6
+ <div
7
+ style={{
8
+ padding: '20px 24px',
9
+ borderBottom: `1px solid ${colors.borderLight}`,
10
+ display: 'flex',
11
+ alignItems: 'center',
12
+ justifyContent: 'space-between',
13
+ }}
14
+ >
15
+ <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
16
+ <div style={{ color: colors.accentBlue }}>
17
+ <IconHelp size={24} stroke={1.5} />
18
+ </div>
19
+ <h2
20
+ style={{
21
+ margin: 0,
22
+ color: colors.textPrimary,
23
+ fontSize: '20px',
24
+ fontWeight: '600',
25
+ fontFamily: fonts.body,
26
+ }}
27
+ >
28
+ Welcome to MCP Shark
29
+ </h2>
30
+ </div>
31
+ <button
32
+ onClick={onClose}
33
+ style={{
34
+ background: 'transparent',
35
+ border: 'none',
36
+ color: colors.textTertiary,
37
+ cursor: 'pointer',
38
+ padding: '4px',
39
+ display: 'flex',
40
+ alignItems: 'center',
41
+ borderRadius: '8px',
42
+ }}
43
+ onMouseEnter={(e) => {
44
+ e.currentTarget.style.background = colors.bgHover;
45
+ e.currentTarget.style.color = colors.textPrimary;
46
+ }}
47
+ onMouseLeave={(e) => {
48
+ e.currentTarget.style.background = 'transparent';
49
+ e.currentTarget.style.color = colors.textTertiary;
50
+ }}
51
+ >
52
+ <IconX size={20} stroke={1.5} />
53
+ </button>
54
+ </div>
55
+ );
56
+ }
@@ -0,0 +1,65 @@
1
+ import { useState } from 'react';
2
+ import { colors } from './theme';
3
+ import HelpGuideHeader from './HelpGuide/HelpGuideHeader';
4
+ import HelpGuideContent from './HelpGuide/HelpGuideContent';
5
+ import HelpGuideFooter from './HelpGuide/HelpGuideFooter';
6
+
7
+ function HelpGuide({ onClose }) {
8
+ const [dontShowAgain, setDontShowAgain] = useState(false);
9
+
10
+ const handleClose = async () => {
11
+ if (dontShowAgain) {
12
+ try {
13
+ await fetch('/api/help/dismiss', { method: 'POST' });
14
+ } catch (error) {
15
+ console.error('Failed to save help state:', error);
16
+ }
17
+ }
18
+ onClose();
19
+ };
20
+
21
+ return (
22
+ <div
23
+ style={{
24
+ position: 'fixed',
25
+ top: 0,
26
+ left: 0,
27
+ right: 0,
28
+ bottom: 0,
29
+ background: 'rgba(0, 0, 0, 0.7)',
30
+ zIndex: 1000,
31
+ display: 'flex',
32
+ alignItems: 'center',
33
+ justifyContent: 'center',
34
+ padding: '20px',
35
+ }}
36
+ onClick={handleClose}
37
+ >
38
+ <div
39
+ style={{
40
+ background: colors.bgCard,
41
+ border: `1px solid ${colors.borderLight}`,
42
+ borderRadius: '12px',
43
+ maxWidth: '700px',
44
+ width: '100%',
45
+ maxHeight: '90vh',
46
+ overflow: 'auto',
47
+ boxShadow: '0 8px 32px rgba(0, 0, 0, 0.5)',
48
+ }}
49
+ onClick={(e) => e.stopPropagation()}
50
+ >
51
+ <HelpGuideHeader onClose={handleClose} />
52
+ <div style={{ padding: '24px' }}>
53
+ <HelpGuideContent />
54
+ <HelpGuideFooter
55
+ dontShowAgain={dontShowAgain}
56
+ setDontShowAgain={setDontShowAgain}
57
+ onClose={handleClose}
58
+ />
59
+ </div>
60
+ </div>
61
+ </div>
62
+ );
63
+ }
64
+
65
+ export default HelpGuide;