Skip to content

Commit 11d536e

Browse files
committed
fix: type errors in StreamableHttpStats.tsx
1 parent 930d254 commit 11d536e

File tree

2 files changed

+40
-23
lines changed

2 files changed

+40
-23
lines changed

client/src/components/StreamableHttpStats.tsx

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
44
import { Badge } from "@/components/ui/badge";
55
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
66

7-
// Define the shape of the transport stats
87
interface TransportStats {
98
sessionId?: string;
109
lastRequestTime: number;
@@ -18,7 +17,6 @@ interface TransportStats {
1817
connectionEstablished: boolean;
1918
}
2019

21-
// Interface for JSON-RPC message structure
2220
interface JsonRpcMessage {
2321
jsonrpc: string;
2422
id?: string | number;
@@ -32,7 +30,6 @@ interface JsonRpcMessage {
3230
};
3331
}
3432

35-
// Interface for enhanced transport events
3633
interface TransportLogEntry {
3734
type: string;
3835
timestamp: number;
@@ -50,7 +47,6 @@ interface TransportLogEntry {
5047
[key: string]: unknown;
5148
}
5249

53-
// Interface for tool tracking
5450
interface ToolEvent {
5551
id: string | number;
5652
name: string;
@@ -84,11 +80,9 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
8480
const transportRef = useRef<TransportWithStats | null>(null);
8581
const logCallbackRegistered = useRef(false);
8682

87-
// Function to identify tool-related requests in logs
8883
const processToolLogs = (logs: TransportLogEntry[]) => {
8984
const toolCalls: ToolEvent[] = [];
9085

91-
// Find all tool call requests
9286
const toolRequests = logs.filter(log => {
9387
const body = log.body as Record<string, unknown> | undefined;
9488
return log.type === 'request' &&
@@ -99,7 +93,6 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
9993
'id' in body;
10094
});
10195

102-
// Process each tool request and find matching responses
10396
toolRequests.forEach(request => {
10497
const body = request.body as Record<string, unknown> | undefined;
10598
if (!body || !('id' in body) || !('params' in body)) return;
@@ -108,7 +101,6 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
108101
const params = body.params as Record<string, unknown> | undefined;
109102
const toolName = params?.name as string || 'unknown';
110103

111-
// Find matching response from the logs
112104
const responseLog = logs.find(log => {
113105
const data = log.data as Record<string, unknown> | undefined;
114106
return (log.type === 'response' || log.type === 'sseMessage') &&
@@ -143,11 +135,9 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
143135
return toolCalls;
144136
};
145137

146-
// Function to check for spec violations
147138
const checkSpecViolations = (logs: TransportLogEntry[], stats: TransportStats) => {
148139
const violations: string[] = [];
149140

150-
// Check for HTTP status codes that might indicate spec violations
151141
if (httpStatus['404'] && httpStatus['404'] > 0) {
152142
if (stats.sessionId) {
153143
violations.push("Session expired or not recognized (HTTP 404) while using a valid session ID");
@@ -158,7 +148,6 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
158148
violations.push("Server returned HTTP 405 - Method Not Allowed. Server must support both GET and POST methods.");
159149
}
160150

161-
// Check for notification responses that aren't 202 Accepted
162151
const notificationLogs = logs.filter(log => {
163152
const body = log.body as Record<string, unknown> | undefined;
164153
return log.type === 'request' &&
@@ -180,7 +169,6 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
180169
}
181170
});
182171

183-
// Check for responses containing JSON-RPC errors
184172
const errorResponseLogs = logs.filter(log => {
185173
const data = log.data as Record<string, unknown> | undefined;
186174
return (log.type === 'response' || log.type === 'sseMessage') &&
@@ -201,7 +189,6 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
201189
if (!mcpClient) return;
202190

203191
try {
204-
// Access private _transport property using type cast
205192
const client = mcpClient as unknown as { _transport?: unknown };
206193
const transport = client._transport as unknown as TransportWithStats;
207194

@@ -210,36 +197,31 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
210197
const transportStats = transport.getTransportStats();
211198
setStats(transportStats);
212199

213-
// Get active streams if available
214200
if (transport.getActiveStreams && typeof transport.getActiveStreams === 'function') {
215201
setActiveStreams(transport.getActiveStreams());
216202
}
217203

218-
// Register log callback if not already done
219204
if (transport.registerLogCallback && typeof transport.registerLogCallback === 'function' && !logCallbackRegistered.current) {
220205
transport.registerLogCallback((logEntry: TransportLogEntry) => {
221206
setLogs(prevLogs => {
222207
const newLogs = [...prevLogs, logEntry];
223208

224-
// Update tool events based on logs
225209
const updatedToolEvents = processToolLogs(newLogs);
226210
setToolEvents(updatedToolEvents);
227211

228-
// Track HTTP status codes
229-
if (logEntry.type === 'response' && logEntry.statusCode) {
212+
if (logEntry.type === 'response' && typeof logEntry.statusCode === 'number') {
213+
const statusCodeStr = logEntry.statusCode.toString();
230214
setHttpStatus(prev => ({
231215
...prev,
232-
[logEntry.statusCode.toString()]: (prev[logEntry.statusCode.toString()] || 0) + 1
216+
[statusCodeStr]: (prev[statusCodeStr] || 0) + 1
233217
}));
234218
}
235219

236-
// Check for spec violations with updated logs and stats
237220
if (transportStats) {
238221
const violations = checkSpecViolations(newLogs, transportStats);
239222
setSpecViolations(violations);
240223
}
241224

242-
// Keep last 100 logs for memory efficiency
243225
return newLogs.slice(-100);
244226
});
245227
});
@@ -253,7 +235,6 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
253235

254236
fetchStats();
255237

256-
// Refresh stats every 2 seconds
257238
const interval = setInterval(fetchStats, 2000);
258239

259240
return () => clearInterval(interval);
@@ -280,7 +261,7 @@ const StreamableHttpStats: React.FC<StreamableHttpStatsProps> = ({ mcpClient })
280261
const formatJson = (data: unknown) => {
281262
try {
282263
return JSON.stringify(data, null, 2);
283-
} catch (_) {
264+
} catch {
284265
return 'Unable to format data';
285266
}
286267
};

client/src/components/ui/badge.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as React from "react";
2+
import { cva, type VariantProps } from "class-variance-authority";
3+
4+
import { cn } from "@/lib/utils";
5+
6+
const badgeVariants = cva(
7+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8+
{
9+
variants: {
10+
variant: {
11+
default:
12+
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
13+
secondary:
14+
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
15+
destructive:
16+
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
17+
outline: "text-foreground",
18+
},
19+
},
20+
defaultVariants: {
21+
variant: "default",
22+
},
23+
}
24+
);
25+
26+
export interface BadgeProps
27+
extends React.HTMLAttributes<HTMLDivElement>,
28+
VariantProps<typeof badgeVariants> {}
29+
30+
function Badge({ className, variant, ...props }: BadgeProps) {
31+
return (
32+
<div className={cn(badgeVariants({ variant }), className)} {...props} />
33+
);
34+
}
35+
36+
export { Badge, badgeVariants };

0 commit comments

Comments
 (0)