Skip to content

πŸŽƒ Import a HAR file (browser network capture) as REST toolsΒ #1005

Closed

Description

@helpcodeai

Part of the October Challenge #997.

Why

Many internal tools and SaaS products have an API but no OpenAPI spec or Postman collection: the only description of it is what their own web app sends. A HAR file (browser DevTools β†’ Network β†’ "Save all as HAR") records exactly those requests. Importing it turns "click through the app once" into a set of REST tools. Today people do this by hand, one cURL command at a time ("Copy as cURL" in DevTools, then source: 'curl'). Insomnia and other API clients import HAR files for the same reason.

What already exists: POST /api/connectors/:id/import with the sources openapi, wsdl, graphql, postman, curl, json, mcp and odata (connectors.controller.ts:335-376, :1613-1794). curl and json imports are additive: they add or update the given tools and retire nothing (:1776-1781). The cURL parser (parsers/curl.parser.ts) already maps query parameters, JSON bodies and headers to tool parameters and an endpointMapping; follow its approach.

Self-hosted vs Cloud

  • Self-hosted: enabled in Community and Business. No ee/ code. Parsing makes no outbound request: the HAR is uploaded as content and never fetched from a URL (no url option, so no SSRF surface).
  • Cloud (DEPLOYMENT_MODE=cloud): enabled. A HAR file is sensitive: it contains the user's session cookies, bearer tokens and full response bodies with personal data. These rules apply to both deployments: the browser removes response bodies, cookies and credential headers before upload (which also keeps the request under the 10 MB body limit, main.ts:53); the backend works in memory, never stores or logs the HAR, and never keeps a credential value in a tool, neither as a header mapping nor as a parameter default.
  • Who can use it: the same roles as the other import sources: the connector's owner or an org ADMIN, never VIEWER (assertCanWrite, connectors.controller.ts:595-603).

What to build

  1. Parser packages/backend/src/connectors/parsers/har.parser.ts (HarParser, added to PARSERS in connectors.module.ts:35) with parse(har: string, opts: { baseUrl: string }): ParsedTool[]:
    • Accept HAR 1.2 (log.entries[].request); anything else gets a clear error.
    • Keep only entries with the same origin as the connector's baseUrl whose path starts with the base URL's path, and strip that prefix so endpointMapping.path is relative, as with other imports. Skip OPTIONS and HEAD, static assets (by file extension and by _resourceType when present: script, stylesheet, image, font, media) and WebSocket entries.
    • Group by method and path template: segments that look like ids (numbers, UUIDs, long hex strings) become path parameters, so /orders/123 and /orders/456 produce one tool with an {id} parameter.
    • Query string β†’ optional parameters with the observed value as default. JSON body (postData.mimeType application/json) β†’ body mapping like the cURL parser. application/x-www-form-urlencoded β†’ fields from postData.params.
    • Drop credentials: Cookie, Authorization, Proxy-Authorization, HTTP/2 pseudo-headers (:authority …), and any header, query parameter or body field whose name matches /(token|secret|password|passwd|api[-_]?key|session|csrf|xsrf|auth|signature|sig)/i. A dropped body field stays a parameter, without a default. Also drop browser noise (User-Agent, Accept-*, Sec-*, Origin, Referer, Content-Length). The connector's own auth settings supply credentials at call time.
    • Tool names follow the cURL parser's scheme (<method>_<path>), capped with capToolName() (parsers/tool-name.util.ts) and made unique. Description: <METHOD> <path> (from HAR).
    • Never read response.content.
  2. Controller: add 'har' to ImportToolsDto.source and to the switch, require content, pass connector.baseUrl, and treat it as additive like curl/json (:1781). Return how many entries were skipped and why (other origin, static asset, duplicate).
  3. UI: add "HAR file (browser capture)" to IMPORT_SOURCES (connectors/[id]/page.tsx:23-32) with a file picker (.har, .json) instead of the URL and text fields. Before sending, the browser parses the file and removes response.content, request.cookies, response.cookies and the credential headers listed above, then sends the slimmed JSON as content. One line in the panel says that HAR files contain session data and that the import removes it.
  4. Docs: a "From a HAR file" section in docs/connectors/rest.md after "From cURL Commands" (:111), and an example in the Import Tools block of docs/api-reference.md:111-149.

Where to look

  • packages/backend/src/connectors/connectors.controller.ts:335-376 (ImportToolsDto), :1613-1794 (importTools), :2009 (createToolsFromParsed, which matches existing tools by operationId, then method and path, then name).
  • packages/backend/src/connectors/parsers/curl.parser.ts: header, query and body mapping, generateToolName.
  • packages/backend/src/connectors/parsers/openapi.parser.ts:12-35: the ParsedTool shape.
  • packages/backend/src/connectors/parsers/tool-name.util.ts: capToolName().
  • packages/backend/src/connectors/connectors.module.ts:35: parser registration.
  • packages/frontend/src/app/connectors/[id]/page.tsx:23-32 (IMPORT_SOURCES), :466-500 (handleImportTools), :1578-1660 (import panel).

Acceptance criteria

  • har.parser.spec.ts with a small HAR fixture exported from a browser and scrubbed by hand (in parsers/__fixtures__/): other origins and static assets are skipped; /orders/123 and /orders/456 become one tool with an {id} parameter; query and JSON body parameters are mapped; a base URL with a path prefix works.
  • Credential spec: a HAR with Cookie, Authorization, X-API-Key, ?access_token= and a password body field yields tools in which none of those values appear (assert on JSON.stringify(tools)).
  • An invalid file returns { error } like the other sources; importing the same HAR twice updates the tools instead of duplicating them.
  • cd packages/backend && npx jest src/connectors/parsers passes.
  • Manual check: capture a HAR from a web app you use, import it into a local instance and call one generated tool (describe it in the PR, without attaching the HAR).
  • Docs updated.

Out of scope

  • Building outputSchema or response mappings from recorded responses.
  • Detecting the auth scheme and configuring the connector's auth automatically.
  • Creating a new connector from a HAR in one step.
  • Splitting GraphQL requests in a HAR into separate tools.

Size

M (1–2 days)

How to claim

Comment "I'd like to work on this" and we'll assign you. Rules in #997.

Activity

  1. rangarajan19 commented on Oct 11, 2026

    @rangarajan19
    Contributor

    I'd like to work on this.

    Plan for this one:

    1. Parser β€” packages/backend/src/connectors/parsers/har.parser.ts

    • HarParser.parse(har: string, opts: { baseUrl: string }): ParsedTool[], registered in connectors.module.ts's PARSERS array.
    • Validate HAR 1.2 shape; clear error otherwise.
    • Keep only entries matching the connector's baseUrl origin + path prefix, stripped for a relative endpointMapping.path. Skip OPTIONS/HEAD, static assets (extension + _resourceType), WebSocket entries.
    • Group by method + path template, collapsing numeric/UUID/long-hex segments into a path parameter (/orders/123 + /orders/456 β†’ one tool with {id}).
    • Map query string β†’ optional params with observed defaults; JSON body β†’ body mapping (mirroring curl.parser.ts); form-urlencoded β†’ fields from postData.params.
    • Drop Cookie, Authorization, Proxy-Authorization, HTTP/2 pseudo-headers, and any header/query/body field matching /(token|secret|password|passwd|api[-_]?key|session|csrf|xsrf|auth|signature|sig)/i (scrubbed body fields stay as parameters with no default). Also drop browser noise headers. Never read response.content.
    • Tool names via capToolName(), made unique; description "<METHOD> <path> (from HAR)".

    2. Controller β€” connectors.controller.ts

    • Add 'har' to ImportToolsDto.source and the switch, require content, pass connector.baseUrl, treat as additive like curl/json. Response reports skip counts/reasons (other origin, static asset, duplicate).

    3. Frontend β€” connectors/[id]/page.tsx

    • Add "HAR file (browser capture)" to IMPORT_SOURCES with a .har/.json file picker.
    • Client-side pre-scrub before upload (strip response.content, cookies, credential headers) in addition to the backend's own scrubbing, with a line of copy explaining why.

    4. Docs

    • "From a HAR file" section in docs/connectors/rest.md after "From cURL Commands"; example in the Import Tools block of docs/api-reference.md.

    5. Tests

    • har.parser.spec.ts: origin/static-asset filtering, path-param collapsing, query/body mapping, base-URL-with-path-prefix.
    • Dedicated credential-scrubbing test asserting none of Cookie/Authorization/X-API-Key/?access_token=/body password survive in the output.
    • Invalid-file error shape; re-importing the same HAR updates rather than duplicates.
    • Manual check: capture a real HAR locally, import it, call a generated tool, describe the result in the PR without attaching the HAR itself.

    Out of scope, per the issue: response-schema inference, auto-detecting/configuring auth, one-step connector creation from a HAR, splitting GraphQL requests in a HAR.

    If my plan good to go , i will start working on this and Will open a PR referencing this issue once it's ready.

  2. helpcodeai commented on Oct 12, 2026

    @helpcodeai
    ContributorAuthor

    @rangarajan19 go ahead, it's yours (#1019 is merged, so you're free). The plan matches the issue.

    One thing to plan for early: the backend takes JSON bodies up to 10 MB (main.ts), and a HAR with response bodies is often way bigger than that. So the browser-side slimming isn't optional. Strip response.content and the cookies before upload, and if the slimmed file is still over the limit, say so in the panel instead of letting the request fail with a 413.

  3. rangarajan19 commented on Oct 12, 2026

    @rangarajan19
    Contributor

    Hi @helpcodeai, PR is opened for this: #1057. Please check.

  4. added a commit that references this issue on Oct 14, 2026
    8a55fab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesthacktoberfestGood for Hacktoberfest contributorshelp wantedExtra attention is needed

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions