har-mcp 0.1.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.
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Schema Definition for Read HAR Tool
3
+ */
4
+
5
+ import { z } from "zod"
6
+
7
+ export const readHarSchema = z.object({
8
+ path: z.string().describe("Path to the HAR file"),
9
+
10
+ mode: z
11
+ .enum(["summary", "list", "detail", "content", "stats", "timeline", "size", "cookies"])
12
+ .default("summary")
13
+ .describe(
14
+ "Output mode: summary (overview), list (entries), detail (full metadata), content (with body), stats (aggregate by endpoint), timeline (waterfall visualization), size (payload size analysis), cookies (cookie propagation tracking)",
15
+ ),
16
+
17
+ // Pagination
18
+ page: z.number().int().min(1).default(1),
19
+ pageSize: z.number().int().min(1).max(100).default(20),
20
+
21
+ // Entry selection (required for content mode)
22
+ entries: z
23
+ .array(z.number().int().min(0))
24
+ .max(10)
25
+ .optional()
26
+ .describe("Specific entry indexes to return (required for content mode)"),
27
+
28
+ // Filtering
29
+ filter: z
30
+ .object({
31
+ url: z.string().optional().describe("URL pattern (substring, glob with *, or ~regex)"),
32
+ method: z.union([z.string(), z.array(z.string())]).optional(),
33
+ status: z
34
+ .union([
35
+ z.number(),
36
+ z.string().regex(/^\d{1}xx$/i),
37
+ z.object({ min: z.number().optional(), max: z.number().optional() }),
38
+ ])
39
+ .optional(),
40
+ contentType: z.string().optional(),
41
+ minDuration: z.number().optional(),
42
+ hasError: z.boolean().optional(),
43
+ bodyContains: z.string().optional().describe("Filter entries whose response body contains this string"),
44
+ })
45
+ .optional(),
46
+
47
+ // Include options for detail mode
48
+ include: z
49
+ .object({
50
+ headers: z.boolean().optional().default(false),
51
+ cookies: z.boolean().optional().default(false),
52
+ timing: z.boolean().optional().default(true),
53
+ queryParams: z.boolean().optional().default(true),
54
+ })
55
+ .optional(),
56
+
57
+ // Content options
58
+ contentOptions: z
59
+ .object({
60
+ includeRequestBody: z.boolean().optional().default(false),
61
+ includeResponseBody: z.boolean().optional().default(true),
62
+ maxContentLength: z.number().optional().default(50000),
63
+ })
64
+ .optional(),
65
+
66
+ // Sorting
67
+ sort: z
68
+ .object({
69
+ by: z.enum(["index", "time", "duration", "size", "status"]).default("index"),
70
+ order: z.enum(["asc", "desc"]).default("asc"),
71
+ })
72
+ .optional(),
73
+
74
+ // Output format
75
+ format: z
76
+ .enum(["markdown", "json"])
77
+ .default("markdown")
78
+ .describe("Output format: markdown (default) or json for programmatic use"),
79
+ })
80
+
81
+ export type ReadHarInput = z.infer<typeof readHarSchema>
82
+ export type ReadHarInputRaw = z.input<typeof readHarSchema>
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Read HAR Tool - Re-export for backward compatibility
3
+ *
4
+ * This file re-exports everything from the read-har module for backward compatibility.
5
+ * The actual implementation has been split into smaller, more maintainable sub-modules.
6
+ *
7
+ * @see ./read-har/index.ts for the main implementation
8
+ * @see ./read-har/schema.ts for schema definitions
9
+ * @see ./read-har/helpers.ts for helper functions
10
+ * @see ./read-har/filters.ts for filter and sort functions
11
+ * @see ./read-har/formatters/ for output formatters
12
+ */
13
+
14
+ // Re-export everything for backward compatibility
15
+ export * from "./read-har/index.ts"
@@ -0,0 +1,11 @@
1
+ declare module "har-to-curl" {
2
+ /**
3
+ * Converts a HAR entry to a cURL command string
4
+ * @param entry - A HAR entry object following HAR 1.2 specification
5
+ * @returns The cURL command as a string
6
+ */
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ function harToCurl(entry: any): string
9
+
10
+ export default harToCurl
11
+ }
@@ -0,0 +1,386 @@
1
+ import { z } from "zod"
2
+
3
+ // ============================================================================
4
+ // HAR 1.2 Type Definitions
5
+ // Based on W3C HAR 1.2 Specification
6
+ // ============================================================================
7
+
8
+ // --- Name/Value Types ---
9
+
10
+ export interface HarHeader {
11
+ name: string
12
+ value: string
13
+ comment?: string
14
+ }
15
+
16
+ export interface HarQueryParam {
17
+ name: string
18
+ value: string
19
+ comment?: string
20
+ }
21
+
22
+ export interface HarPostParam {
23
+ name: string
24
+ value?: string
25
+ fileName?: string
26
+ contentType?: string
27
+ comment?: string
28
+ }
29
+
30
+ export interface HarCookie {
31
+ name: string
32
+ value: string
33
+ path?: string
34
+ domain?: string
35
+ expires?: string
36
+ httpOnly?: boolean
37
+ secure?: boolean
38
+ comment?: string
39
+ }
40
+
41
+ // --- Creator/Browser ---
42
+
43
+ export interface HarCreator {
44
+ name: string
45
+ version: string
46
+ comment?: string
47
+ }
48
+
49
+ export interface HarBrowser {
50
+ name: string
51
+ version: string
52
+ comment?: string
53
+ }
54
+
55
+ // --- Page Timings ---
56
+
57
+ export interface HarPageTimings {
58
+ onContentLoad?: number
59
+ onLoad?: number
60
+ comment?: string
61
+ }
62
+
63
+ export interface HarPage {
64
+ startedDateTime: string
65
+ id: string
66
+ title: string
67
+ pageTimings: HarPageTimings
68
+ comment?: string
69
+ }
70
+
71
+ // --- Timings ---
72
+
73
+ export interface HarTimings {
74
+ blocked?: number
75
+ dns?: number
76
+ connect?: number
77
+ send: number
78
+ wait: number
79
+ receive: number
80
+ ssl?: number
81
+ comment?: string
82
+ }
83
+
84
+ // --- Cache ---
85
+
86
+ export interface HarCacheEntry {
87
+ expires?: string
88
+ lastAccess: string
89
+ eTag: string
90
+ hitCount: number
91
+ comment?: string
92
+ }
93
+
94
+ export interface HarCache {
95
+ beforeRequest?: HarCacheEntry | null
96
+ afterRequest?: HarCacheEntry | null
97
+ comment?: string
98
+ }
99
+
100
+ // --- Content ---
101
+
102
+ export interface HarContent {
103
+ size: number
104
+ compression?: number
105
+ mimeType: string
106
+ text?: string
107
+ encoding?: string
108
+ comment?: string
109
+ }
110
+
111
+ export interface HarPostData {
112
+ mimeType: string
113
+ params?: HarPostParam[]
114
+ text?: string
115
+ comment?: string
116
+ }
117
+
118
+ // --- Request/Response ---
119
+
120
+ export interface HarRequest {
121
+ method: string
122
+ url: string
123
+ httpVersion: string
124
+ cookies: HarCookie[]
125
+ headers: HarHeader[]
126
+ queryString: HarQueryParam[]
127
+ postData?: HarPostData
128
+ headersSize: number
129
+ bodySize: number
130
+ comment?: string
131
+ }
132
+
133
+ export interface HarResponse {
134
+ status: number
135
+ statusText: string
136
+ httpVersion: string
137
+ cookies: HarCookie[]
138
+ headers: HarHeader[]
139
+ content: HarContent
140
+ redirectURL: string
141
+ headersSize: number
142
+ bodySize: number
143
+ comment?: string
144
+ }
145
+
146
+ // --- Entry ---
147
+
148
+ export interface HarEntry {
149
+ pageref?: string
150
+ startedDateTime: string
151
+ time: number
152
+ request: HarRequest
153
+ response: HarResponse
154
+ cache: HarCache
155
+ timings: HarTimings
156
+ serverIPAddress?: string
157
+ connection?: string
158
+ comment?: string
159
+ }
160
+
161
+ // --- Log ---
162
+
163
+ export interface HarLog {
164
+ version: string
165
+ creator: HarCreator
166
+ browser?: HarBrowser
167
+ pages?: HarPage[]
168
+ entries: HarEntry[]
169
+ comment?: string
170
+ }
171
+
172
+ // --- Main HAR File ---
173
+
174
+ export interface HarFile {
175
+ log: HarLog
176
+ }
177
+
178
+ // ============================================================================
179
+ // Zod Schemas for Runtime Validation
180
+ // ============================================================================
181
+
182
+ export const HarHeaderSchema = z.object({
183
+ name: z.string(),
184
+ value: z.string(),
185
+ comment: z.string().optional(),
186
+ })
187
+
188
+ export const HarQueryParamSchema = z.object({
189
+ name: z.string(),
190
+ value: z.string(),
191
+ comment: z.string().optional(),
192
+ })
193
+
194
+ export const HarPostParamSchema = z.object({
195
+ name: z.string(),
196
+ value: z.string().optional(),
197
+ fileName: z.string().optional(),
198
+ contentType: z.string().optional(),
199
+ comment: z.string().optional(),
200
+ })
201
+
202
+ export const HarCookieSchema = z.object({
203
+ name: z.string(),
204
+ value: z.string(),
205
+ path: z.string().optional(),
206
+ domain: z.string().optional(),
207
+ expires: z.string().optional(),
208
+ httpOnly: z.boolean().optional(),
209
+ secure: z.boolean().optional(),
210
+ comment: z.string().optional(),
211
+ })
212
+
213
+ export const HarCreatorSchema = z.object({
214
+ name: z.string(),
215
+ version: z.string(),
216
+ comment: z.string().optional(),
217
+ })
218
+
219
+ export const HarBrowserSchema = z.object({
220
+ name: z.string(),
221
+ version: z.string(),
222
+ comment: z.string().optional(),
223
+ })
224
+
225
+ export const HarPageTimingsSchema = z.object({
226
+ onContentLoad: z.number().optional(),
227
+ onLoad: z.number().optional(),
228
+ comment: z.string().optional(),
229
+ })
230
+
231
+ export const HarPageSchema = z.object({
232
+ startedDateTime: z.string(),
233
+ id: z.string(),
234
+ title: z.string(),
235
+ pageTimings: HarPageTimingsSchema,
236
+ comment: z.string().optional(),
237
+ })
238
+
239
+ // Use .passthrough() to allow Chrome DevTools extensions (fields starting with _)
240
+ export const HarTimingsSchema = z
241
+ .object({
242
+ blocked: z.number().optional(),
243
+ dns: z.number().optional(),
244
+ connect: z.number().optional(),
245
+ send: z.number(),
246
+ wait: z.number(),
247
+ receive: z.number(),
248
+ ssl: z.number().optional(),
249
+ comment: z.string().optional(),
250
+ })
251
+ .passthrough()
252
+
253
+ export const HarCacheEntrySchema = z.object({
254
+ expires: z.string().optional(),
255
+ lastAccess: z.string(),
256
+ eTag: z.string(),
257
+ hitCount: z.number(),
258
+ comment: z.string().optional(),
259
+ })
260
+
261
+ // Chrome often exports empty cache objects - make this fully optional and passthrough
262
+ export const HarCacheSchema = z
263
+ .object({
264
+ beforeRequest: HarCacheEntrySchema.nullable().optional(),
265
+ afterRequest: HarCacheEntrySchema.nullable().optional(),
266
+ comment: z.string().optional(),
267
+ })
268
+ .passthrough()
269
+
270
+ // Chrome DevTools extensions: passthrough allows _transferSize, _error, _fetchedViaServiceWorker, etc.
271
+ export const HarContentSchema = z
272
+ .object({
273
+ size: z.number(),
274
+ compression: z.number().optional(),
275
+ mimeType: z.string(),
276
+ text: z.string().optional(),
277
+ encoding: z.string().optional(),
278
+ comment: z.string().optional(),
279
+ })
280
+ .passthrough()
281
+
282
+ export const HarPostDataSchema = z
283
+ .object({
284
+ mimeType: z.string(),
285
+ params: z.array(HarPostParamSchema).optional(),
286
+ text: z.string().optional(),
287
+ comment: z.string().optional(),
288
+ })
289
+ .passthrough()
290
+
291
+ export const HarRequestSchema = z
292
+ .object({
293
+ method: z.string(),
294
+ url: z.string(),
295
+ httpVersion: z.string(),
296
+ cookies: z.array(HarCookieSchema),
297
+ headers: z.array(HarHeaderSchema),
298
+ queryString: z.array(HarQueryParamSchema),
299
+ postData: HarPostDataSchema.optional(),
300
+ headersSize: z.number(),
301
+ bodySize: z.number(),
302
+ comment: z.string().optional(),
303
+ })
304
+ .passthrough()
305
+
306
+ // Chrome DevTools extensions: _transferSize, _error, _fetchedViaServiceWorker, etc.
307
+ export const HarResponseSchema = z
308
+ .object({
309
+ status: z.number(),
310
+ statusText: z.string(),
311
+ httpVersion: z.string(),
312
+ cookies: z.array(HarCookieSchema),
313
+ headers: z.array(HarHeaderSchema),
314
+ content: HarContentSchema,
315
+ redirectURL: z.string(),
316
+ headersSize: z.number(),
317
+ bodySize: z.number(),
318
+ comment: z.string().optional(),
319
+ })
320
+ .passthrough()
321
+
322
+ // Chrome DevTools extensions: _connectionId, _initiator, _priority, _resourceType, etc.
323
+ export const HarEntrySchema = z
324
+ .object({
325
+ pageref: z.string().optional(),
326
+ startedDateTime: z.string(),
327
+ time: z.number(),
328
+ request: HarRequestSchema,
329
+ response: HarResponseSchema,
330
+ cache: HarCacheSchema,
331
+ timings: HarTimingsSchema,
332
+ serverIPAddress: z.string().optional(),
333
+ connection: z.string().optional(),
334
+ comment: z.string().optional(),
335
+ })
336
+ .passthrough()
337
+
338
+ export const HarLogSchema = z
339
+ .object({
340
+ version: z.string(),
341
+ creator: HarCreatorSchema,
342
+ browser: HarBrowserSchema.optional(),
343
+ pages: z.array(HarPageSchema).optional(),
344
+ entries: z.array(HarEntrySchema),
345
+ comment: z.string().optional(),
346
+ })
347
+ .passthrough()
348
+
349
+ export const HarFileSchema = z
350
+ .object({
351
+ log: HarLogSchema,
352
+ })
353
+ .passthrough()
354
+
355
+ // ============================================================================
356
+ // Type Inference from Zod Schemas (alternative types)
357
+ // ============================================================================
358
+
359
+ export type HarFileFromSchema = z.infer<typeof HarFileSchema>
360
+ export type HarLogFromSchema = z.infer<typeof HarLogSchema>
361
+ export type HarEntryFromSchema = z.infer<typeof HarEntrySchema>
362
+ export type HarRequestFromSchema = z.infer<typeof HarRequestSchema>
363
+ export type HarResponseFromSchema = z.infer<typeof HarResponseSchema>
364
+
365
+ // ============================================================================
366
+ // Validation Helper Functions
367
+ // ============================================================================
368
+
369
+ /**
370
+ * Validates a HAR file object against the HAR 1.2 specification
371
+ * @param data - The data to validate
372
+ * @returns The validated HarFile object
373
+ * @throws ZodError if validation fails
374
+ */
375
+ export function validateHarFile(data: unknown): HarFile {
376
+ return HarFileSchema.parse(data)
377
+ }
378
+
379
+ /**
380
+ * Safely validates a HAR file object, returning a result object
381
+ * @param data - The data to validate
382
+ * @returns A Zod SafeParseReturnType with success status and data/error
383
+ */
384
+ export function safeValidateHarFile(data: unknown) {
385
+ return HarFileSchema.safeParse(data)
386
+ }