# Directory Structure ``` ├── .env.example ├── bin │ ├── .DS_Store │ └── cli.js ├── dist │ └── index.js ├── node_modules │ ├── .bin │ │ ├── acorn │ │ ├── mime │ │ ├── playwright │ │ ├── playwright-core │ │ ├── ts-node │ │ ├── ts-node-cwd │ │ ├── ts-node-esm │ │ ├── ts-node-script │ │ ├── ts-node-transpile-only │ │ ├── ts-script │ │ ├── tsc │ │ ├── tsserver │ │ └── yaml │ ├── .package-lock.json │ ├── @cspotcode │ │ └── source-map-support │ │ ├── browser-source-map-support.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ ├── register-hook-require.d.ts │ │ ├── register-hook-require.js │ │ ├── register.d.ts │ │ ├── register.js │ │ ├── source-map-support.d.ts │ │ └── source-map-support.js │ ├── @jridgewell │ │ ├── resolve-uri │ │ │ ├── dist │ │ │ │ ├── resolve-uri.mjs │ │ │ │ ├── resolve-uri.mjs.map │ │ │ │ ├── resolve-uri.umd.js │ │ │ │ ├── resolve-uri.umd.js.map │ │ │ │ └── types │ │ │ │ └── resolve-uri.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── sourcemap-codec │ │ │ ├── dist │ │ │ │ ├── sourcemap-codec.mjs │ │ │ │ ├── sourcemap-codec.mjs.map │ │ │ │ ├── sourcemap-codec.umd.js │ │ │ │ ├── sourcemap-codec.umd.js.map │ │ │ │ └── types │ │ │ │ ├── scopes.d.ts │ │ │ │ ├── sourcemap-codec.d.ts │ │ │ │ ├── strings.d.ts │ │ │ │ └── vlq.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ └── trace-mapping │ │ ├── dist │ │ │ ├── trace-mapping.mjs │ │ │ ├── trace-mapping.mjs.map │ │ │ ├── trace-mapping.umd.js │ │ │ ├── trace-mapping.umd.js.map │ │ │ └── types │ │ │ ├── any-map.d.ts │ │ │ ├── binary-search.d.ts │ │ │ ├── by-source.d.ts │ │ │ ├── resolve.d.ts │ │ │ ├── sort.d.ts │ │ │ ├── sourcemap-segment.d.ts │ │ │ ├── strip-filename.d.ts │ │ │ ├── trace-mapping.d.ts │ │ │ └── types.d.ts │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── @modelcontextprotocol │ │ └── sdk │ │ ├── dist │ │ │ ├── cjs │ │ │ │ ├── cli.d.ts │ │ │ │ ├── cli.d.ts.map │ │ │ │ ├── cli.js │ │ │ │ ├── cli.js.map │ │ │ │ ├── client │ │ │ │ │ ├── index.d.ts │ │ │ │ │ ├── index.d.ts.map │ │ │ │ │ ├── index.js │ │ │ │ │ ├── index.js.map │ │ │ │ │ ├── sse.d.ts │ │ │ │ │ ├── sse.d.ts.map │ │ │ │ │ ├── sse.js │ │ │ │ │ ├── sse.js.map │ │ │ │ │ ├── stdio.d.ts │ │ │ │ │ ├── stdio.d.ts.map │ │ │ │ │ ├── stdio.js │ │ │ │ │ ├── stdio.js.map │ │ │ │ │ ├── websocket.d.ts │ │ │ │ │ ├── websocket.d.ts.map │ │ │ │ │ ├── websocket.js │ │ │ │ │ └── websocket.js.map │ │ │ │ ├── inMemory.d.ts │ │ │ │ ├── inMemory.d.ts.map │ │ │ │ ├── inMemory.js │ │ │ │ ├── inMemory.js.map │ │ │ │ ├── package.json │ │ │ │ ├── server │ │ │ │ │ ├── completable.d.ts │ │ │ │ │ ├── completable.d.ts.map │ │ │ │ │ ├── completable.js │ │ │ │ │ ├── completable.js.map │ │ │ │ │ ├── index.d.ts │ │ │ │ │ ├── index.d.ts.map │ │ │ │ │ ├── index.js │ │ │ │ │ ├── index.js.map │ │ │ │ │ ├── mcp.d.ts │ │ │ │ │ ├── mcp.d.ts.map │ │ │ │ │ ├── mcp.js │ │ │ │ │ ├── mcp.js.map │ │ │ │ │ ├── sse.d.ts │ │ │ │ │ ├── sse.d.ts.map │ │ │ │ │ ├── sse.js │ │ │ │ │ ├── sse.js.map │ │ │ │ │ ├── stdio.d.ts │ │ │ │ │ ├── stdio.d.ts.map │ │ │ │ │ ├── stdio.js │ │ │ │ │ └── stdio.js.map │ │ │ │ ├── shared │ │ │ │ │ ├── protocol.d.ts │ │ │ │ │ ├── protocol.d.ts.map │ │ │ │ │ ├── protocol.js │ │ │ │ │ ├── protocol.js.map │ │ │ │ │ ├── stdio.d.ts │ │ │ │ │ ├── stdio.d.ts.map │ │ │ │ │ ├── stdio.js │ │ │ │ │ ├── stdio.js.map │ │ │ │ │ ├── transport.d.ts │ │ │ │ │ ├── transport.d.ts.map │ │ │ │ │ ├── transport.js │ │ │ │ │ ├── transport.js.map │ │ │ │ │ ├── uriTemplate.d.ts │ │ │ │ │ ├── uriTemplate.d.ts.map │ │ │ │ │ ├── uriTemplate.js │ │ │ │ │ └── uriTemplate.js.map │ │ │ │ ├── types.d.ts │ │ │ │ ├── types.d.ts.map │ │ │ │ ├── types.js │ │ │ │ └── types.js.map │ │ │ └── esm │ │ │ ├── cli.d.ts │ │ │ ├── cli.d.ts.map │ │ │ ├── cli.js │ │ │ ├── cli.js.map │ │ │ ├── client │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── sse.d.ts │ │ │ │ ├── sse.d.ts.map │ │ │ │ ├── sse.js │ │ │ │ ├── sse.js.map │ │ │ │ ├── stdio.d.ts │ │ │ │ ├── stdio.d.ts.map │ │ │ │ ├── stdio.js │ │ │ │ ├── stdio.js.map │ │ │ │ ├── websocket.d.ts │ │ │ │ ├── websocket.d.ts.map │ │ │ │ ├── websocket.js │ │ │ │ └── websocket.js.map │ │ │ ├── inMemory.d.ts │ │ │ ├── inMemory.d.ts.map │ │ │ ├── inMemory.js │ │ │ ├── inMemory.js.map │ │ │ ├── package.json │ │ │ ├── server │ │ │ │ ├── completable.d.ts │ │ │ │ ├── completable.d.ts.map │ │ │ │ ├── completable.js │ │ │ │ ├── completable.js.map │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.d.ts.map │ │ │ │ ├── index.js │ │ │ │ ├── index.js.map │ │ │ │ ├── mcp.d.ts │ │ │ │ ├── mcp.d.ts.map │ │ │ │ ├── mcp.js │ │ │ │ ├── mcp.js.map │ │ │ │ ├── sse.d.ts │ │ │ │ ├── sse.d.ts.map │ │ │ │ ├── sse.js │ │ │ │ ├── sse.js.map │ │ │ │ ├── stdio.d.ts │ │ │ │ ├── stdio.d.ts.map │ │ │ │ ├── stdio.js │ │ │ │ └── stdio.js.map │ │ │ ├── shared │ │ │ │ ├── protocol.d.ts │ │ │ │ ├── protocol.d.ts.map │ │ │ │ ├── protocol.js │ │ │ │ ├── protocol.js.map │ │ │ │ ├── stdio.d.ts │ │ │ │ ├── stdio.d.ts.map │ │ │ │ ├── stdio.js │ │ │ │ ├── stdio.js.map │ │ │ │ ├── transport.d.ts │ │ │ │ ├── transport.d.ts.map │ │ │ │ ├── transport.js │ │ │ │ ├── transport.js.map │ │ │ │ ├── uriTemplate.d.ts │ │ │ │ ├── uriTemplate.d.ts.map │ │ │ │ ├── uriTemplate.js │ │ │ │ └── uriTemplate.js.map │ │ │ ├── types.d.ts │ │ │ ├── types.d.ts.map │ │ │ ├── types.js │ │ │ └── types.js.map │ │ ├── LICENSE │ │ ├── node_modules │ │ │ ├── iconv-lite │ │ │ │ ├── .github │ │ │ │ │ └── dependabot.yml │ │ │ │ ├── .idea │ │ │ │ │ ├── codeStyles │ │ │ │ │ │ ├── codeStyleConfig.xml │ │ │ │ │ │ └── Project.xml │ │ │ │ │ ├── iconv-lite.iml │ │ │ │ │ ├── inspectionProfiles │ │ │ │ │ │ └── Project_Default.xml │ │ │ │ │ ├── modules.xml │ │ │ │ │ └── vcs.xml │ │ │ │ ├── Changelog.md │ │ │ │ ├── encodings │ │ │ │ │ ├── dbcs-codec.js │ │ │ │ │ ├── dbcs-data.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── internal.js │ │ │ │ │ ├── sbcs-codec.js │ │ │ │ │ ├── sbcs-data-generated.js │ │ │ │ │ ├── sbcs-data.js │ │ │ │ │ ├── tables │ │ │ │ │ │ ├── big5-added.json │ │ │ │ │ │ ├── cp936.json │ │ │ │ │ │ ├── cp949.json │ │ │ │ │ │ ├── cp950.json │ │ │ │ │ │ ├── eucjp.json │ │ │ │ │ │ ├── gb18030-ranges.json │ │ │ │ │ │ ├── gbk-added.json │ │ │ │ │ │ └── shiftjis.json │ │ │ │ │ ├── utf16.js │ │ │ │ │ ├── utf32.js │ │ │ │ │ └── utf7.js │ │ │ │ ├── lib │ │ │ │ │ ├── bom-handling.js │ │ │ │ │ ├── index.d.ts │ │ │ │ │ ├── index.js │ │ │ │ │ └── streams.js │ │ │ │ ├── LICENSE │ │ │ │ ├── package.json │ │ │ │ └── README.md │ │ │ └── raw-body │ │ │ ├── HISTORY.md │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ └── SECURITY.md │ │ ├── package.json │ │ └── README.md │ ├── @tsconfig │ │ ├── node10 │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ └── tsconfig.json │ │ ├── node12 │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ └── tsconfig.json │ │ ├── node14 │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ └── tsconfig.json │ │ └── node16 │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── tsconfig.json │ ├── @types │ │ ├── body-parser │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── connect │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── express │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── express-serve-static-core │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── http-errors │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── mime │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── lite.d.ts │ │ │ ├── Mime.d.ts │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── node │ │ │ ├── assert │ │ │ │ └── strict.d.ts │ │ │ ├── assert.d.ts │ │ │ ├── async_hooks.d.ts │ │ │ ├── buffer.buffer.d.ts │ │ │ ├── buffer.d.ts │ │ │ ├── child_process.d.ts │ │ │ ├── cluster.d.ts │ │ │ ├── compatibility │ │ │ │ ├── index.d.ts │ │ │ │ ├── indexable.d.ts │ │ │ │ └── iterators.d.ts │ │ │ ├── console.d.ts │ │ │ ├── constants.d.ts │ │ │ ├── crypto.d.ts │ │ │ ├── dgram.d.ts │ │ │ ├── diagnostics_channel.d.ts │ │ │ ├── dns │ │ │ │ └── promises.d.ts │ │ │ ├── dns.d.ts │ │ │ ├── dom-events.d.ts │ │ │ ├── domain.d.ts │ │ │ ├── events.d.ts │ │ │ ├── fs │ │ │ │ └── promises.d.ts │ │ │ ├── fs.d.ts │ │ │ ├── globals.d.ts │ │ │ ├── globals.typedarray.d.ts │ │ │ ├── http.d.ts │ │ │ ├── http2.d.ts │ │ │ ├── https.d.ts │ │ │ ├── index.d.ts │ │ │ ├── inspector.d.ts │ │ │ ├── LICENSE │ │ │ ├── module.d.ts │ │ │ ├── net.d.ts │ │ │ ├── os.d.ts │ │ │ ├── package.json │ │ │ ├── path.d.ts │ │ │ ├── perf_hooks.d.ts │ │ │ ├── process.d.ts │ │ │ ├── punycode.d.ts │ │ │ ├── querystring.d.ts │ │ │ ├── readline.d.ts │ │ │ ├── README.md │ │ │ ├── repl.d.ts │ │ │ ├── stream │ │ │ │ ├── consumers.d.ts │ │ │ │ ├── promises.d.ts │ │ │ │ └── web.d.ts │ │ │ ├── stream.d.ts │ │ │ ├── string_decoder.d.ts │ │ │ ├── test.d.ts │ │ │ ├── timers │ │ │ │ └── promises.d.ts │ │ │ ├── timers.d.ts │ │ │ ├── tls.d.ts │ │ │ ├── trace_events.d.ts │ │ │ ├── ts5.6 │ │ │ │ ├── buffer.buffer.d.ts │ │ │ │ ├── globals.typedarray.d.ts │ │ │ │ └── index.d.ts │ │ │ ├── tty.d.ts │ │ │ ├── url.d.ts │ │ │ ├── util.d.ts │ │ │ ├── v8.d.ts │ │ │ ├── vm.d.ts │ │ │ ├── wasi.d.ts │ │ │ ├── worker_threads.d.ts │ │ │ └── zlib.d.ts │ │ ├── qs │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── range-parser │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── send │ │ │ ├── index.d.ts │ │ │ ├── LICENSE │ │ │ ├── package.json │ │ │ └── README.md │ │ └── serve-static │ │ ├── index.d.ts │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── accepts │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── acorn │ │ ├── bin │ │ │ └── acorn │ │ ├── CHANGELOG.md │ │ ├── dist │ │ │ ├── acorn.d.mts │ │ │ ├── acorn.d.ts │ │ │ ├── acorn.js │ │ │ ├── acorn.mjs │ │ │ └── bin.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── acorn-walk │ │ ├── CHANGELOG.md │ │ ├── dist │ │ │ ├── walk.d.mts │ │ │ ├── walk.d.ts │ │ │ ├── walk.js │ │ │ └── walk.mjs │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── arg │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ └── README.md │ ├── array-flatten │ │ ├── array-flatten.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── body-parser │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── read.js │ │ │ └── types │ │ │ ├── json.js │ │ │ ├── raw.js │ │ │ ├── text.js │ │ │ └── urlencoded.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── SECURITY.md │ ├── bytes │ │ ├── History.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── call-bind-apply-helpers │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── actualApply.d.ts │ │ ├── actualApply.js │ │ ├── applyBind.d.ts │ │ ├── applyBind.js │ │ ├── CHANGELOG.md │ │ ├── functionApply.d.ts │ │ ├── functionApply.js │ │ ├── functionCall.d.ts │ │ ├── functionCall.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── reflectApply.d.ts │ │ ├── reflectApply.js │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── call-bound │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── content-disposition │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── content-type │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── cookie │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── SECURITY.md │ ├── cookie-signature │ │ ├── .npmignore │ │ ├── History.md │ │ ├── index.js │ │ ├── package.json │ │ └── Readme.md │ ├── create-require │ │ ├── CHANGELOG.md │ │ ├── create-require.d.ts │ │ ├── create-require.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── debug │ │ ├── .coveralls.yml │ │ ├── .eslintrc │ │ ├── .npmignore │ │ ├── .travis.yml │ │ ├── CHANGELOG.md │ │ ├── component.json │ │ ├── karma.conf.js │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── node.js │ │ ├── package.json │ │ ├── README.md │ │ └── src │ │ ├── browser.js │ │ ├── debug.js │ │ ├── index.js │ │ ├── inspector-log.js │ │ └── node.js │ ├── depd │ │ ├── History.md │ │ ├── index.js │ │ ├── lib │ │ │ └── browser │ │ │ └── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── destroy │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── diff │ │ ├── CONTRIBUTING.md │ │ ├── dist │ │ │ ├── diff.js │ │ │ └── diff.min.js │ │ ├── lib │ │ │ ├── convert │ │ │ │ ├── dmp.js │ │ │ │ └── xml.js │ │ │ ├── diff │ │ │ │ ├── array.js │ │ │ │ ├── base.js │ │ │ │ ├── character.js │ │ │ │ ├── css.js │ │ │ │ ├── json.js │ │ │ │ ├── line.js │ │ │ │ ├── sentence.js │ │ │ │ └── word.js │ │ │ ├── index.es6.js │ │ │ ├── index.js │ │ │ ├── patch │ │ │ │ ├── apply.js │ │ │ │ ├── create.js │ │ │ │ ├── merge.js │ │ │ │ └── parse.js │ │ │ └── util │ │ │ ├── array.js │ │ │ ├── distance-iterator.js │ │ │ └── params.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── release-notes.md │ │ └── runtime.js │ ├── dunder-proto │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── get.d.ts │ │ ├── get.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── set.d.ts │ │ ├── set.js │ │ ├── test │ │ │ ├── get.js │ │ │ ├── index.js │ │ │ └── set.js │ │ └── tsconfig.json │ ├── ee-first │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── encodeurl │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── es-define-property │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── es-errors │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── CHANGELOG.md │ │ ├── eval.d.ts │ │ ├── eval.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── range.d.ts │ │ ├── range.js │ │ ├── README.md │ │ ├── ref.d.ts │ │ ├── ref.js │ │ ├── syntax.d.ts │ │ ├── syntax.js │ │ ├── test │ │ │ └── index.js │ │ ├── tsconfig.json │ │ ├── type.d.ts │ │ ├── type.js │ │ ├── uri.d.ts │ │ └── uri.js │ ├── es-object-atoms │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── isObject.d.ts │ │ ├── isObject.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── RequireObjectCoercible.d.ts │ │ ├── RequireObjectCoercible.js │ │ ├── test │ │ │ └── index.js │ │ ├── ToObject.d.ts │ │ ├── ToObject.js │ │ └── tsconfig.json │ ├── escape-html │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── etag │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── eventsource │ │ ├── dist │ │ │ ├── index.cjs │ │ │ ├── index.cjs.map │ │ │ ├── index.d.cts │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── index.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── src │ │ ├── errors.ts │ │ ├── EventSource.ts │ │ ├── index.ts │ │ └── types.ts │ ├── eventsource-parser │ │ ├── dist │ │ │ ├── index.cjs │ │ │ ├── index.cjs.map │ │ │ ├── index.d.cts │ │ │ ├── index.d.ts │ │ │ ├── index.esm.js │ │ │ ├── index.esm.js.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── stats.html │ │ │ ├── stream.cjs │ │ │ ├── stream.cjs.map │ │ │ ├── stream.d.cts │ │ │ ├── stream.d.ts │ │ │ ├── stream.esm.js │ │ │ ├── stream.esm.js.map │ │ │ ├── stream.js │ │ │ └── stream.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ ├── parse.ts │ │ │ ├── stream.ts │ │ │ └── types.ts │ │ └── stream.js │ ├── express │ │ ├── History.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── application.js │ │ │ ├── express.js │ │ │ ├── middleware │ │ │ │ ├── init.js │ │ │ │ └── query.js │ │ │ ├── request.js │ │ │ ├── response.js │ │ │ ├── router │ │ │ │ ├── index.js │ │ │ │ ├── layer.js │ │ │ │ └── route.js │ │ │ ├── utils.js │ │ │ └── view.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── finalhandler │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── SECURITY.md │ ├── forwarded │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── fresh │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── fsevents │ │ ├── fsevents.d.ts │ │ ├── fsevents.js │ │ ├── fsevents.node │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── function-bind │ │ ├── .eslintrc │ │ ├── .github │ │ │ ├── FUNDING.yml │ │ │ └── SECURITY.md │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── implementation.js │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ ├── .eslintrc │ │ └── index.js │ ├── get-intrinsic │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ └── GetIntrinsic.js │ ├── get-proto │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── Object.getPrototypeOf.d.ts │ │ ├── Object.getPrototypeOf.js │ │ ├── package.json │ │ ├── README.md │ │ ├── Reflect.getPrototypeOf.d.ts │ │ ├── Reflect.getPrototypeOf.js │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── gopd │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── CHANGELOG.md │ │ ├── gOPD.d.ts │ │ ├── gOPD.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── has-symbols │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── shams.d.ts │ │ ├── shams.js │ │ ├── test │ │ │ ├── index.js │ │ │ ├── shams │ │ │ │ ├── core-js.js │ │ │ │ └── get-own-property-symbols.js │ │ │ └── tests.js │ │ └── tsconfig.json │ ├── hasown │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── tsconfig.json │ ├── http-errors │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── iconv-lite │ │ ├── Changelog.md │ │ ├── encodings │ │ │ ├── dbcs-codec.js │ │ │ ├── dbcs-data.js │ │ │ ├── index.js │ │ │ ├── internal.js │ │ │ ├── sbcs-codec.js │ │ │ ├── sbcs-data-generated.js │ │ │ ├── sbcs-data.js │ │ │ ├── tables │ │ │ │ ├── big5-added.json │ │ │ │ ├── cp936.json │ │ │ │ ├── cp949.json │ │ │ │ ├── cp950.json │ │ │ │ ├── eucjp.json │ │ │ │ ├── gb18030-ranges.json │ │ │ │ ├── gbk-added.json │ │ │ │ └── shiftjis.json │ │ │ ├── utf16.js │ │ │ └── utf7.js │ │ ├── lib │ │ │ ├── bom-handling.js │ │ │ ├── extend-node.js │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── streams.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── inherits │ │ ├── inherits_browser.js │ │ ├── inherits.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── ipaddr.js │ │ ├── ipaddr.min.js │ │ ├── lib │ │ │ ├── ipaddr.js │ │ │ └── ipaddr.js.d.ts │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── make-error │ │ ├── dist │ │ │ └── make-error.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── math-intrinsics │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── abs.d.ts │ │ ├── abs.js │ │ ├── CHANGELOG.md │ │ ├── constants │ │ │ ├── maxArrayLength.d.ts │ │ │ ├── maxArrayLength.js │ │ │ ├── maxSafeInteger.d.ts │ │ │ ├── maxSafeInteger.js │ │ │ ├── maxValue.d.ts │ │ │ └── maxValue.js │ │ ├── floor.d.ts │ │ ├── floor.js │ │ ├── isFinite.d.ts │ │ ├── isFinite.js │ │ ├── isInteger.d.ts │ │ ├── isInteger.js │ │ ├── isNaN.d.ts │ │ ├── isNaN.js │ │ ├── isNegativeZero.d.ts │ │ ├── isNegativeZero.js │ │ ├── LICENSE │ │ ├── max.d.ts │ │ ├── max.js │ │ ├── min.d.ts │ │ ├── min.js │ │ ├── mod.d.ts │ │ ├── mod.js │ │ ├── package.json │ │ ├── pow.d.ts │ │ ├── pow.js │ │ ├── README.md │ │ ├── round.d.ts │ │ ├── round.js │ │ ├── sign.d.ts │ │ ├── sign.js │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── media-typer │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── merge-descriptors │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── methods │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── mime │ │ ├── .npmignore │ │ ├── CHANGELOG.md │ │ ├── cli.js │ │ ├── LICENSE │ │ ├── mime.js │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── build.js │ │ │ └── test.js │ │ └── types.json │ ├── mime-db │ │ ├── db.json │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── mime-types │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── ms │ │ ├── index.js │ │ ├── license.md │ │ ├── package.json │ │ └── readme.md │ ├── negotiator │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── charset.js │ │ │ ├── encoding.js │ │ │ ├── language.js │ │ │ └── mediaType.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── object-inspect │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── example │ │ │ ├── all.js │ │ │ ├── circular.js │ │ │ ├── fn.js │ │ │ └── inspect.js │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package-support.json │ │ ├── package.json │ │ ├── readme.markdown │ │ ├── test │ │ │ ├── bigint.js │ │ │ ├── browser │ │ │ │ └── dom.js │ │ │ ├── circular.js │ │ │ ├── deep.js │ │ │ ├── element.js │ │ │ ├── err.js │ │ │ ├── fakes.js │ │ │ ├── fn.js │ │ │ ├── global.js │ │ │ ├── has.js │ │ │ ├── holes.js │ │ │ ├── indent-option.js │ │ │ ├── inspect.js │ │ │ ├── lowbyte.js │ │ │ ├── number.js │ │ │ ├── quoteStyle.js │ │ │ ├── toStringTag.js │ │ │ ├── undef.js │ │ │ └── values.js │ │ ├── test-core-js.js │ │ └── util.inspect.js │ ├── on-finished │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── parseurl │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── path-to-regexp │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── playwright │ │ ├── .eslintrc.js │ │ ├── cli.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── index.mjs │ │ ├── jsx-runtime.js │ │ ├── jsx-runtime.mjs │ │ ├── lib │ │ │ ├── common │ │ │ │ ├── config.js │ │ │ │ ├── configLoader.js │ │ │ │ ├── esmLoaderHost.js │ │ │ │ ├── expectBundle.js │ │ │ │ ├── expectBundleImpl.js │ │ │ │ ├── fixtures.js │ │ │ │ ├── globals.js │ │ │ │ ├── ipc.js │ │ │ │ ├── poolBuilder.js │ │ │ │ ├── process.js │ │ │ │ ├── suiteUtils.js │ │ │ │ ├── test.js │ │ │ │ ├── testLoader.js │ │ │ │ └── testType.js │ │ │ ├── fsWatcher.js │ │ │ ├── index.js │ │ │ ├── internalsForTest.js │ │ │ ├── isomorphic │ │ │ │ ├── events.js │ │ │ │ ├── folders.js │ │ │ │ ├── stringInternPool.js │ │ │ │ ├── teleReceiver.js │ │ │ │ ├── teleSuiteUpdater.js │ │ │ │ ├── testServerConnection.js │ │ │ │ ├── testServerInterface.js │ │ │ │ └── testTree.js │ │ │ ├── loader │ │ │ │ └── loaderMain.js │ │ │ ├── matchers │ │ │ │ ├── expect.js │ │ │ │ ├── matcherHint.js │ │ │ │ ├── matchers.js │ │ │ │ ├── toBeTruthy.js │ │ │ │ ├── toEqual.js │ │ │ │ ├── toMatchAriaSnapshot.js │ │ │ │ ├── toMatchSnapshot.js │ │ │ │ └── toMatchText.js │ │ │ ├── plugins │ │ │ │ ├── gitCommitInfoPlugin.js │ │ │ │ ├── index.js │ │ │ │ └── webServerPlugin.js │ │ │ ├── program.js │ │ │ ├── reporters │ │ │ │ ├── base.js │ │ │ │ ├── blob.js │ │ │ │ ├── dot.js │ │ │ │ ├── empty.js │ │ │ │ ├── github.js │ │ │ │ ├── html.js │ │ │ │ ├── internalReporter.js │ │ │ │ ├── json.js │ │ │ │ ├── junit.js │ │ │ │ ├── line.js │ │ │ │ ├── list.js │ │ │ │ ├── markdown.js │ │ │ │ ├── merge.js │ │ │ │ ├── multiplexer.js │ │ │ │ ├── reporterV2.js │ │ │ │ ├── teleEmitter.js │ │ │ │ └── versions │ │ │ │ └── blobV1.js │ │ │ ├── runner │ │ │ │ ├── dispatcher.js │ │ │ │ ├── failureTracker.js │ │ │ │ ├── lastRun.js │ │ │ │ ├── loaderHost.js │ │ │ │ ├── loadUtils.js │ │ │ │ ├── processHost.js │ │ │ │ ├── projectUtils.js │ │ │ │ ├── rebase.js │ │ │ │ ├── reporters.js │ │ │ │ ├── runner.js │ │ │ │ ├── sigIntWatcher.js │ │ │ │ ├── taskRunner.js │ │ │ │ ├── tasks.js │ │ │ │ ├── testGroups.js │ │ │ │ ├── testServer.js │ │ │ │ ├── uiModeReporter.js │ │ │ │ ├── vcs.js │ │ │ │ ├── watchMode.js │ │ │ │ └── workerHost.js │ │ │ ├── third_party │ │ │ │ └── tsconfig-loader.js │ │ │ ├── transform │ │ │ │ ├── babelBundle.js │ │ │ │ ├── babelBundleImpl.js │ │ │ │ ├── compilationCache.js │ │ │ │ ├── esmLoader.js │ │ │ │ ├── esmUtils.js │ │ │ │ ├── portTransport.js │ │ │ │ └── transform.js │ │ │ ├── util.js │ │ │ ├── utilsBundle.js │ │ │ ├── utilsBundleImpl.js │ │ │ └── worker │ │ │ ├── fixtureRunner.js │ │ │ ├── testInfo.js │ │ │ ├── testTracing.js │ │ │ ├── timeoutManager.js │ │ │ ├── util.js │ │ │ └── workerMain.js │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── package.json │ │ ├── README.md │ │ ├── test.d.ts │ │ ├── test.js │ │ ├── test.mjs │ │ ├── ThirdPartyNotices.txt │ │ └── types │ │ ├── test.d.ts │ │ └── testReporter.d.ts │ ├── playwright-core │ │ ├── bin │ │ │ ├── install_media_pack.ps1 │ │ │ ├── reinstall_chrome_beta_linux.sh │ │ │ ├── reinstall_chrome_beta_mac.sh │ │ │ ├── reinstall_chrome_beta_win.ps1 │ │ │ ├── reinstall_chrome_stable_linux.sh │ │ │ ├── reinstall_chrome_stable_mac.sh │ │ │ ├── reinstall_chrome_stable_win.ps1 │ │ │ ├── reinstall_msedge_beta_linux.sh │ │ │ ├── reinstall_msedge_beta_mac.sh │ │ │ ├── reinstall_msedge_beta_win.ps1 │ │ │ ├── reinstall_msedge_dev_linux.sh │ │ │ ├── reinstall_msedge_dev_mac.sh │ │ │ ├── reinstall_msedge_dev_win.ps1 │ │ │ ├── reinstall_msedge_stable_linux.sh │ │ │ ├── reinstall_msedge_stable_mac.sh │ │ │ └── reinstall_msedge_stable_win.ps1 │ │ ├── browsers.json │ │ ├── cli.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── index.mjs │ │ ├── lib │ │ │ ├── androidServerImpl.js │ │ │ ├── browserServerImpl.js │ │ │ ├── cli │ │ │ │ ├── driver.js │ │ │ │ ├── program.js │ │ │ │ └── programWithTestStub.js │ │ │ ├── client │ │ │ │ ├── accessibility.js │ │ │ │ ├── android.js │ │ │ │ ├── api.js │ │ │ │ ├── artifact.js │ │ │ │ ├── browser.js │ │ │ │ ├── browserContext.js │ │ │ │ ├── browserType.js │ │ │ │ ├── cdpSession.js │ │ │ │ ├── channelOwner.js │ │ │ │ ├── clientHelper.js │ │ │ │ ├── clientInstrumentation.js │ │ │ │ ├── clock.js │ │ │ │ ├── connection.js │ │ │ │ ├── consoleMessage.js │ │ │ │ ├── coverage.js │ │ │ │ ├── dialog.js │ │ │ │ ├── download.js │ │ │ │ ├── electron.js │ │ │ │ ├── elementHandle.js │ │ │ │ ├── errors.js │ │ │ │ ├── eventEmitter.js │ │ │ │ ├── events.js │ │ │ │ ├── fetch.js │ │ │ │ ├── fileChooser.js │ │ │ │ ├── frame.js │ │ │ │ ├── harRouter.js │ │ │ │ ├── input.js │ │ │ │ ├── jsHandle.js │ │ │ │ ├── jsonPipe.js │ │ │ │ ├── localUtils.js │ │ │ │ ├── locator.js │ │ │ │ ├── network.js │ │ │ │ ├── page.js │ │ │ │ ├── playwright.js │ │ │ │ ├── selectors.js │ │ │ │ ├── stream.js │ │ │ │ ├── tracing.js │ │ │ │ ├── types.js │ │ │ │ ├── video.js │ │ │ │ ├── waiter.js │ │ │ │ ├── webError.js │ │ │ │ ├── worker.js │ │ │ │ └── writableStream.js │ │ │ ├── common │ │ │ │ ├── socksProxy.js │ │ │ │ ├── timeoutSettings.js │ │ │ │ └── types.js │ │ │ ├── generated │ │ │ │ ├── clockSource.js │ │ │ │ ├── consoleApiSource.js │ │ │ │ ├── injectedScriptSource.js │ │ │ │ ├── pollingRecorderSource.js │ │ │ │ ├── utilityScriptSource.js │ │ │ │ └── webSocketMockSource.js │ │ │ ├── image_tools │ │ │ │ ├── colorUtils.js │ │ │ │ ├── compare.js │ │ │ │ ├── imageChannel.js │ │ │ │ └── stats.js │ │ │ ├── inprocess.js │ │ │ ├── inProcessFactory.js │ │ │ ├── outofprocess.js │ │ │ ├── protocol │ │ │ │ ├── debug.js │ │ │ │ ├── serializers.js │ │ │ │ ├── transport.js │ │ │ │ ├── validator.js │ │ │ │ └── validatorPrimitives.js │ │ │ ├── remote │ │ │ │ ├── playwrightConnection.js │ │ │ │ └── playwrightServer.js │ │ │ ├── server │ │ │ │ ├── accessibility.js │ │ │ │ ├── android │ │ │ │ │ ├── android.js │ │ │ │ │ └── backendAdb.js │ │ │ │ ├── artifact.js │ │ │ │ ├── bidi │ │ │ │ │ ├── bidiBrowser.js │ │ │ │ │ ├── bidiChromium.js │ │ │ │ │ ├── bidiConnection.js │ │ │ │ │ ├── bidiExecutionContext.js │ │ │ │ │ ├── bidiFirefox.js │ │ │ │ │ ├── bidiInput.js │ │ │ │ │ ├── bidiNetworkManager.js │ │ │ │ │ ├── bidiOverCdp.js │ │ │ │ │ ├── bidiPage.js │ │ │ │ │ ├── bidiPdf.js │ │ │ │ │ └── third_party │ │ │ │ │ ├── bidiDeserializer.js │ │ │ │ │ ├── bidiKeyboard.js │ │ │ │ │ ├── bidiProtocol.js │ │ │ │ │ ├── bidiSerializer.js │ │ │ │ │ └── firefoxPrefs.js │ │ │ │ ├── browser.js │ │ │ │ ├── browserContext.js │ │ │ │ ├── browserType.js │ │ │ │ ├── chromium │ │ │ │ │ ├── appIcon.png │ │ │ │ │ ├── chromium.js │ │ │ │ │ ├── chromiumSwitches.js │ │ │ │ │ ├── crAccessibility.js │ │ │ │ │ ├── crBrowser.js │ │ │ │ │ ├── crConnection.js │ │ │ │ │ ├── crCoverage.js │ │ │ │ │ ├── crDevTools.js │ │ │ │ │ ├── crDragDrop.js │ │ │ │ │ ├── crExecutionContext.js │ │ │ │ │ ├── crInput.js │ │ │ │ │ ├── crNetworkManager.js │ │ │ │ │ ├── crPage.js │ │ │ │ │ ├── crPdf.js │ │ │ │ │ ├── crProtocolHelper.js │ │ │ │ │ ├── crServiceWorker.js │ │ │ │ │ ├── defaultFontFamilies.js │ │ │ │ │ └── videoRecorder.js │ │ │ │ ├── clock.js │ │ │ │ ├── codegen │ │ │ │ │ ├── csharp.js │ │ │ │ │ ├── java.js │ │ │ │ │ ├── javascript.js │ │ │ │ │ ├── jsonl.js │ │ │ │ │ ├── language.js │ │ │ │ │ ├── languages.js │ │ │ │ │ ├── python.js │ │ │ │ │ └── types.js │ │ │ │ ├── console.js │ │ │ │ ├── cookieStore.js │ │ │ │ ├── debugController.js │ │ │ │ ├── debugger.js │ │ │ │ ├── deviceDescriptors.js │ │ │ │ ├── deviceDescriptorsSource.json │ │ │ │ ├── dialog.js │ │ │ │ ├── dispatchers │ │ │ │ │ ├── androidDispatcher.js │ │ │ │ │ ├── artifactDispatcher.js │ │ │ │ │ ├── browserContextDispatcher.js │ │ │ │ │ ├── browserDispatcher.js │ │ │ │ │ ├── browserTypeDispatcher.js │ │ │ │ │ ├── cdpSessionDispatcher.js │ │ │ │ │ ├── debugControllerDispatcher.js │ │ │ │ │ ├── dialogDispatcher.js │ │ │ │ │ ├── dispatcher.js │ │ │ │ │ ├── electronDispatcher.js │ │ │ │ │ ├── elementHandlerDispatcher.js │ │ │ │ │ ├── frameDispatcher.js │ │ │ │ │ ├── jsHandleDispatcher.js │ │ │ │ │ ├── jsonPipeDispatcher.js │ │ │ │ │ ├── localUtilsDispatcher.js │ │ │ │ │ ├── networkDispatchers.js │ │ │ │ │ ├── pageDispatcher.js │ │ │ │ │ ├── playwrightDispatcher.js │ │ │ │ │ ├── selectorsDispatcher.js │ │ │ │ │ ├── streamDispatcher.js │ │ │ │ │ ├── tracingDispatcher.js │ │ │ │ │ ├── webSocketRouteDispatcher.js │ │ │ │ │ └── writableStreamDispatcher.js │ │ │ │ ├── dom.js │ │ │ │ ├── download.js │ │ │ │ ├── electron │ │ │ │ │ ├── electron.js │ │ │ │ │ └── loader.js │ │ │ │ ├── errors.js │ │ │ │ ├── fetch.js │ │ │ │ ├── fileChooser.js │ │ │ │ ├── fileUploadUtils.js │ │ │ │ ├── firefox │ │ │ │ │ ├── ffAccessibility.js │ │ │ │ │ ├── ffBrowser.js │ │ │ │ │ ├── ffConnection.js │ │ │ │ │ ├── ffExecutionContext.js │ │ │ │ │ ├── ffInput.js │ │ │ │ │ ├── ffNetworkManager.js │ │ │ │ │ ├── ffPage.js │ │ │ │ │ └── firefox.js │ │ │ │ ├── formData.js │ │ │ │ ├── frames.js │ │ │ │ ├── frameSelectors.js │ │ │ │ ├── har │ │ │ │ │ ├── harRecorder.js │ │ │ │ │ └── harTracer.js │ │ │ │ ├── helper.js │ │ │ │ ├── index.js │ │ │ │ ├── input.js │ │ │ │ ├── instrumentation.js │ │ │ │ ├── isomorphic │ │ │ │ │ └── utilityScriptSerializers.js │ │ │ │ ├── javascript.js │ │ │ │ ├── launchApp.js │ │ │ │ ├── macEditingCommands.js │ │ │ │ ├── network.js │ │ │ │ ├── page.js │ │ │ │ ├── pipeTransport.js │ │ │ │ ├── playwright.js │ │ │ │ ├── progress.js │ │ │ │ ├── protocolError.js │ │ │ │ ├── recorder │ │ │ │ │ ├── chat.js │ │ │ │ │ ├── contextRecorder.js │ │ │ │ │ ├── recorderApp.js │ │ │ │ │ ├── recorderCollection.js │ │ │ │ │ ├── recorderFrontend.js │ │ │ │ │ ├── recorderRunner.js │ │ │ │ │ ├── recorderUtils.js │ │ │ │ │ └── throttledFile.js │ │ │ │ ├── recorder.js │ │ │ │ ├── registry │ │ │ │ │ ├── browserFetcher.js │ │ │ │ │ ├── dependencies.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── nativeDeps.js │ │ │ │ │ └── oopDownloadBrowserMain.js │ │ │ │ ├── screenshotter.js │ │ │ │ ├── selectors.js │ │ │ │ ├── socksClientCertificatesInterceptor.js │ │ │ │ ├── socksInterceptor.js │ │ │ │ ├── trace │ │ │ │ │ ├── recorder │ │ │ │ │ │ ├── snapshotter.js │ │ │ │ │ │ ├── snapshotterInjected.js │ │ │ │ │ │ └── tracing.js │ │ │ │ │ ├── test │ │ │ │ │ │ └── inMemorySnapshotter.js │ │ │ │ │ └── viewer │ │ │ │ │ └── traceViewer.js │ │ │ │ ├── transport.js │ │ │ │ ├── types.js │ │ │ │ ├── usKeyboardLayout.js │ │ │ │ └── webkit │ │ │ │ ├── webkit.js │ │ │ │ ├── wkAccessibility.js │ │ │ │ ├── wkBrowser.js │ │ │ │ ├── wkConnection.js │ │ │ │ ├── wkExecutionContext.js │ │ │ │ ├── wkInput.js │ │ │ │ ├── wkInterceptableRequest.js │ │ │ │ ├── wkPage.js │ │ │ │ ├── wkProvisionalPage.js │ │ │ │ └── wkWorkers.js │ │ │ ├── third_party │ │ │ │ └── pixelmatch.js │ │ │ ├── utils │ │ │ │ ├── ascii.js │ │ │ │ ├── comparators.js │ │ │ │ ├── crypto.js │ │ │ │ ├── debug.js │ │ │ │ ├── debugLogger.js │ │ │ │ ├── env.js │ │ │ │ ├── eventsHelper.js │ │ │ │ ├── expectUtils.js │ │ │ │ ├── fileUtils.js │ │ │ │ ├── happy-eyeballs.js │ │ │ │ ├── headers.js │ │ │ │ ├── hostPlatform.js │ │ │ │ ├── httpServer.js │ │ │ │ ├── index.js │ │ │ │ ├── isomorphic │ │ │ │ │ ├── ariaSnapshot.js │ │ │ │ │ ├── cssParser.js │ │ │ │ │ ├── cssTokenizer.js │ │ │ │ │ ├── locatorGenerators.js │ │ │ │ │ ├── locatorParser.js │ │ │ │ │ ├── locatorUtils.js │ │ │ │ │ ├── mimeType.js │ │ │ │ │ ├── selectorParser.js │ │ │ │ │ ├── stringUtils.js │ │ │ │ │ ├── traceUtils.js │ │ │ │ │ └── urlMatch.js │ │ │ │ ├── linuxUtils.js │ │ │ │ ├── manualPromise.js │ │ │ │ ├── multimap.js │ │ │ │ ├── network.js │ │ │ │ ├── processLauncher.js │ │ │ │ ├── profiler.js │ │ │ │ ├── rtti.js │ │ │ │ ├── semaphore.js │ │ │ │ ├── sequence.js │ │ │ │ ├── spawnAsync.js │ │ │ │ ├── stackTrace.js │ │ │ │ ├── task.js │ │ │ │ ├── time.js │ │ │ │ ├── timeoutRunner.js │ │ │ │ ├── traceUtils.js │ │ │ │ ├── userAgent.js │ │ │ │ ├── wsServer.js │ │ │ │ ├── zipFile.js │ │ │ │ └── zones.js │ │ │ ├── utilsBundle.js │ │ │ ├── utilsBundleImpl │ │ │ │ ├── index.js │ │ │ │ └── xdg-open │ │ │ ├── vite │ │ │ │ ├── htmlReport │ │ │ │ │ └── index.html │ │ │ │ ├── recorder │ │ │ │ │ ├── assets │ │ │ │ │ │ ├── codeMirrorModule-DOkeDGCx.js │ │ │ │ │ │ ├── codeMirrorModule-ez37Vkbh.css │ │ │ │ │ │ ├── codicon-DCmgc-ay.ttf │ │ │ │ │ │ ├── index-BvqiUOy-.js │ │ │ │ │ │ └── index-CAQewHss.css │ │ │ │ │ ├── index.html │ │ │ │ │ └── playwright-logo.svg │ │ │ │ └── traceViewer │ │ │ │ ├── assets │ │ │ │ │ ├── codeMirrorModule-aLkSUGpW.js │ │ │ │ │ ├── defaultSettingsView-CxUo6zd3.js │ │ │ │ │ └── xtermModule-BeNbaIVa.js │ │ │ │ ├── codeMirrorModule.ez37Vkbh.css │ │ │ │ ├── codicon.DCmgc-ay.ttf │ │ │ │ ├── defaultSettingsView.DtIkrKWn.css │ │ │ │ ├── index.Bhu5cv5R.js │ │ │ │ ├── index.CrbWWHbf.css │ │ │ │ ├── index.html │ │ │ │ ├── playwright-logo.svg │ │ │ │ ├── snapshot.html │ │ │ │ ├── sw.bundle.js │ │ │ │ ├── uiMode.BBy7FOVd.js │ │ │ │ ├── uiMode.Be_ME-Go.css │ │ │ │ ├── uiMode.html │ │ │ │ └── xtermModule.DSXBckUd.css │ │ │ ├── zipBundle.js │ │ │ └── zipBundleImpl.js │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── package.json │ │ ├── README.md │ │ ├── ThirdPartyNotices.txt │ │ └── types │ │ ├── protocol.d.ts │ │ ├── structs.d.ts │ │ └── types.d.ts │ ├── proxy-addr │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── qs │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── dist │ │ │ └── qs.js │ │ ├── lib │ │ │ ├── formats.js │ │ │ ├── index.js │ │ │ ├── parse.js │ │ │ ├── stringify.js │ │ │ └── utils.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ ├── empty-keys-cases.js │ │ ├── parse.js │ │ ├── stringify.js │ │ └── utils.js │ ├── range-parser │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── raw-body │ │ ├── HISTORY.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── SECURITY.md │ ├── safe-buffer │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── safer-buffer │ │ ├── dangerous.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── Porting-Buffer.md │ │ ├── Readme.md │ │ ├── safer.js │ │ └── tests.js │ ├── send │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── node_modules │ │ │ ├── encodeurl │ │ │ │ ├── HISTORY.md │ │ │ │ ├── index.js │ │ │ │ ├── LICENSE │ │ │ │ ├── package.json │ │ │ │ └── README.md │ │ │ └── ms │ │ │ ├── index.js │ │ │ ├── license.md │ │ │ ├── package.json │ │ │ └── readme.md │ │ ├── package.json │ │ ├── README.md │ │ └── SECURITY.md │ ├── serve-static │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── setprototypeof │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ └── index.js │ ├── side-channel │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── side-channel-list │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── list.d.ts │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── side-channel-map │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── side-channel-weakmap │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── statuses │ │ ├── codes.json │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── toidentifier │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── ts-node │ │ ├── child-loader.mjs │ │ ├── dist │ │ │ ├── bin-cwd.d.ts │ │ │ ├── bin-cwd.js │ │ │ ├── bin-cwd.js.map │ │ │ ├── bin-esm.d.ts │ │ │ ├── bin-esm.js │ │ │ ├── bin-esm.js.map │ │ │ ├── bin-script-deprecated.d.ts │ │ │ ├── bin-script-deprecated.js │ │ │ ├── bin-script-deprecated.js.map │ │ │ ├── bin-script.d.ts │ │ │ ├── bin-script.js │ │ │ ├── bin-script.js.map │ │ │ ├── bin-transpile.d.ts │ │ │ ├── bin-transpile.js │ │ │ ├── bin-transpile.js.map │ │ │ ├── bin.d.ts │ │ │ ├── bin.js │ │ │ ├── bin.js.map │ │ │ ├── child │ │ │ │ ├── argv-payload.d.ts │ │ │ │ ├── argv-payload.js │ │ │ │ ├── argv-payload.js.map │ │ │ │ ├── child-entrypoint.d.ts │ │ │ │ ├── child-entrypoint.js │ │ │ │ ├── child-entrypoint.js.map │ │ │ │ ├── child-loader.d.ts │ │ │ │ ├── child-loader.js │ │ │ │ ├── child-loader.js.map │ │ │ │ ├── child-require.d.ts │ │ │ │ ├── child-require.js │ │ │ │ ├── child-require.js.map │ │ │ │ ├── spawn-child.d.ts │ │ │ │ ├── spawn-child.js │ │ │ │ └── spawn-child.js.map │ │ │ ├── cjs-resolve-hooks.d.ts │ │ │ ├── cjs-resolve-hooks.js │ │ │ ├── cjs-resolve-hooks.js.map │ │ │ ├── configuration.d.ts │ │ │ ├── configuration.js │ │ │ ├── configuration.js.map │ │ │ ├── esm.d.ts │ │ │ ├── esm.js │ │ │ ├── esm.js.map │ │ │ ├── file-extensions.d.ts │ │ │ ├── file-extensions.js │ │ │ ├── file-extensions.js.map │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── module-type-classifier.d.ts │ │ │ ├── module-type-classifier.js │ │ │ ├── module-type-classifier.js.map │ │ │ ├── node-module-type-classifier.d.ts │ │ │ ├── node-module-type-classifier.js │ │ │ ├── node-module-type-classifier.js.map │ │ │ ├── repl.d.ts │ │ │ ├── repl.js │ │ │ ├── repl.js.map │ │ │ ├── resolver-functions.d.ts │ │ │ ├── resolver-functions.js │ │ │ ├── resolver-functions.js.map │ │ │ ├── transpilers │ │ │ │ ├── swc.d.ts │ │ │ │ ├── swc.js │ │ │ │ ├── swc.js.map │ │ │ │ ├── types.d.ts │ │ │ │ ├── types.js │ │ │ │ └── types.js.map │ │ │ ├── ts-compiler-types.d.ts │ │ │ ├── ts-compiler-types.js │ │ │ ├── ts-compiler-types.js.map │ │ │ ├── ts-internals.d.ts │ │ │ ├── ts-internals.js │ │ │ ├── ts-internals.js.map │ │ │ ├── ts-transpile-module.d.ts │ │ │ ├── ts-transpile-module.js │ │ │ ├── ts-transpile-module.js.map │ │ │ ├── tsconfig-schema.d.ts │ │ │ ├── tsconfig-schema.js │ │ │ ├── tsconfig-schema.js.map │ │ │ ├── tsconfigs.d.ts │ │ │ ├── tsconfigs.js │ │ │ ├── tsconfigs.js.map │ │ │ ├── util.d.ts │ │ │ ├── util.js │ │ │ └── util.js.map │ │ ├── dist-raw │ │ │ ├── node-internal-constants.js │ │ │ ├── node-internal-errors.js │ │ │ ├── node-internal-modules-cjs-helpers.js │ │ │ ├── node-internal-modules-cjs-loader.js │ │ │ ├── node-internal-modules-esm-get_format.js │ │ │ ├── node-internal-modules-esm-resolve.js │ │ │ ├── node-internal-modules-package_json_reader.js │ │ │ ├── node-internal-repl-await.js │ │ │ ├── node-internalBinding-fs.js │ │ │ ├── NODE-LICENSE.md │ │ │ ├── node-nativemodule.js │ │ │ ├── node-options.js │ │ │ ├── node-primordials.js │ │ │ ├── README.md │ │ │ └── runmain-hack.js │ │ ├── esm │ │ │ └── transpile-only.mjs │ │ ├── esm.mjs │ │ ├── LICENSE │ │ ├── node10 │ │ │ └── tsconfig.json │ │ ├── node12 │ │ │ └── tsconfig.json │ │ ├── node14 │ │ │ └── tsconfig.json │ │ ├── node16 │ │ │ └── tsconfig.json │ │ ├── package.json │ │ ├── README.md │ │ ├── register │ │ │ ├── files.js │ │ │ ├── index.js │ │ │ ├── transpile-only.js │ │ │ └── type-check.js │ │ ├── transpilers │ │ │ ├── swc-experimental.js │ │ │ └── swc.js │ │ ├── tsconfig.schema.json │ │ └── tsconfig.schemastore-schema.json │ ├── type-is │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── typescript │ │ ├── bin │ │ │ ├── tsc │ │ │ └── tsserver │ │ ├── lib │ │ │ ├── cancellationToken.js │ │ │ ├── cs │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── de │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── dynamicImportCompat.js │ │ │ ├── es │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── fr │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── it │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ja │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ko │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── lib.d.ts │ │ │ ├── lib.dom.d.ts │ │ │ ├── lib.dom.iterable.d.ts │ │ │ ├── lib.es2015.collection.d.ts │ │ │ ├── lib.es2015.core.d.ts │ │ │ ├── lib.es2015.d.ts │ │ │ ├── lib.es2015.generator.d.ts │ │ │ ├── lib.es2015.iterable.d.ts │ │ │ ├── lib.es2015.promise.d.ts │ │ │ ├── lib.es2015.proxy.d.ts │ │ │ ├── lib.es2015.reflect.d.ts │ │ │ ├── lib.es2015.symbol.d.ts │ │ │ ├── lib.es2015.symbol.wellknown.d.ts │ │ │ ├── lib.es2016.array.include.d.ts │ │ │ ├── lib.es2016.d.ts │ │ │ ├── lib.es2016.full.d.ts │ │ │ ├── lib.es2017.d.ts │ │ │ ├── lib.es2017.full.d.ts │ │ │ ├── lib.es2017.intl.d.ts │ │ │ ├── lib.es2017.object.d.ts │ │ │ ├── lib.es2017.sharedmemory.d.ts │ │ │ ├── lib.es2017.string.d.ts │ │ │ ├── lib.es2017.typedarrays.d.ts │ │ │ ├── lib.es2018.asyncgenerator.d.ts │ │ │ ├── lib.es2018.asynciterable.d.ts │ │ │ ├── lib.es2018.d.ts │ │ │ ├── lib.es2018.full.d.ts │ │ │ ├── lib.es2018.intl.d.ts │ │ │ ├── lib.es2018.promise.d.ts │ │ │ ├── lib.es2018.regexp.d.ts │ │ │ ├── lib.es2019.array.d.ts │ │ │ ├── lib.es2019.d.ts │ │ │ ├── lib.es2019.full.d.ts │ │ │ ├── lib.es2019.intl.d.ts │ │ │ ├── lib.es2019.object.d.ts │ │ │ ├── lib.es2019.string.d.ts │ │ │ ├── lib.es2019.symbol.d.ts │ │ │ ├── lib.es2020.bigint.d.ts │ │ │ ├── lib.es2020.d.ts │ │ │ ├── lib.es2020.date.d.ts │ │ │ ├── lib.es2020.full.d.ts │ │ │ ├── lib.es2020.intl.d.ts │ │ │ ├── lib.es2020.number.d.ts │ │ │ ├── lib.es2020.promise.d.ts │ │ │ ├── lib.es2020.sharedmemory.d.ts │ │ │ ├── lib.es2020.string.d.ts │ │ │ ├── lib.es2020.symbol.wellknown.d.ts │ │ │ ├── lib.es2021.d.ts │ │ │ ├── lib.es2021.full.d.ts │ │ │ ├── lib.es2021.intl.d.ts │ │ │ ├── lib.es2021.promise.d.ts │ │ │ ├── lib.es2021.string.d.ts │ │ │ ├── lib.es2021.weakref.d.ts │ │ │ ├── lib.es2022.array.d.ts │ │ │ ├── lib.es2022.d.ts │ │ │ ├── lib.es2022.error.d.ts │ │ │ ├── lib.es2022.full.d.ts │ │ │ ├── lib.es2022.intl.d.ts │ │ │ ├── lib.es2022.object.d.ts │ │ │ ├── lib.es2022.sharedmemory.d.ts │ │ │ ├── lib.es2022.string.d.ts │ │ │ ├── lib.es5.d.ts │ │ │ ├── lib.es6.d.ts │ │ │ ├── lib.esnext.d.ts │ │ │ ├── lib.esnext.full.d.ts │ │ │ ├── lib.esnext.intl.d.ts │ │ │ ├── lib.esnext.promise.d.ts │ │ │ ├── lib.esnext.string.d.ts │ │ │ ├── lib.esnext.weakref.d.ts │ │ │ ├── lib.scripthost.d.ts │ │ │ ├── lib.webworker.d.ts │ │ │ ├── lib.webworker.importscripts.d.ts │ │ │ ├── lib.webworker.iterable.d.ts │ │ │ ├── pl │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── protocol.d.ts │ │ │ ├── pt-br │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── README.md │ │ │ ├── ru │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── tr │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── tsc.js │ │ │ ├── tsserver.js │ │ │ ├── tsserverlibrary.d.ts │ │ │ ├── tsserverlibrary.js │ │ │ ├── typescript.d.ts │ │ │ ├── typescript.js │ │ │ ├── typescriptServices.d.ts │ │ │ ├── typescriptServices.js │ │ │ ├── typesMap.json │ │ │ ├── typingsInstaller.js │ │ │ ├── watchGuard.js │ │ │ ├── zh-cn │ │ │ │ └── diagnosticMessages.generated.json │ │ │ └── zh-tw │ │ │ └── diagnosticMessages.generated.json │ │ ├── LICENSE.txt │ │ ├── package.json │ │ ├── README.md │ │ ├── SECURITY.md │ │ └── ThirdPartyNoticeText.txt │ ├── unpipe │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── utils-merge │ │ ├── .npmignore │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── v8-compile-cache-lib │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── v8-compile-cache.d.ts │ │ └── v8-compile-cache.js │ ├── vary │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── yaml │ │ ├── bin.mjs │ │ ├── browser │ │ │ ├── dist │ │ │ │ ├── compose │ │ │ │ │ ├── compose-collection.js │ │ │ │ │ ├── compose-doc.js │ │ │ │ │ ├── compose-node.js │ │ │ │ │ ├── compose-scalar.js │ │ │ │ │ ├── composer.js │ │ │ │ │ ├── resolve-block-map.js │ │ │ │ │ ├── resolve-block-scalar.js │ │ │ │ │ ├── resolve-block-seq.js │ │ │ │ │ ├── resolve-end.js │ │ │ │ │ ├── resolve-flow-collection.js │ │ │ │ │ ├── resolve-flow-scalar.js │ │ │ │ │ ├── resolve-props.js │ │ │ │ │ ├── util-contains-newline.js │ │ │ │ │ ├── util-empty-scalar-position.js │ │ │ │ │ ├── util-flow-indent-check.js │ │ │ │ │ └── util-map-includes.js │ │ │ │ ├── doc │ │ │ │ │ ├── anchors.js │ │ │ │ │ ├── applyReviver.js │ │ │ │ │ ├── createNode.js │ │ │ │ │ ├── directives.js │ │ │ │ │ └── Document.js │ │ │ │ ├── errors.js │ │ │ │ ├── index.js │ │ │ │ ├── log.js │ │ │ │ ├── nodes │ │ │ │ │ ├── addPairToJSMap.js │ │ │ │ │ ├── Alias.js │ │ │ │ │ ├── Collection.js │ │ │ │ │ ├── identity.js │ │ │ │ │ ├── Node.js │ │ │ │ │ ├── Pair.js │ │ │ │ │ ├── Scalar.js │ │ │ │ │ ├── toJS.js │ │ │ │ │ ├── YAMLMap.js │ │ │ │ │ └── YAMLSeq.js │ │ │ │ ├── parse │ │ │ │ │ ├── cst-scalar.js │ │ │ │ │ ├── cst-stringify.js │ │ │ │ │ ├── cst-visit.js │ │ │ │ │ ├── cst.js │ │ │ │ │ ├── lexer.js │ │ │ │ │ ├── line-counter.js │ │ │ │ │ └── parser.js │ │ │ │ ├── public-api.js │ │ │ │ ├── schema │ │ │ │ │ ├── common │ │ │ │ │ │ ├── map.js │ │ │ │ │ │ ├── null.js │ │ │ │ │ │ ├── seq.js │ │ │ │ │ │ └── string.js │ │ │ │ │ ├── core │ │ │ │ │ │ ├── bool.js │ │ │ │ │ │ ├── float.js │ │ │ │ │ │ ├── int.js │ │ │ │ │ │ └── schema.js │ │ │ │ │ ├── json │ │ │ │ │ │ └── schema.js │ │ │ │ │ ├── Schema.js │ │ │ │ │ ├── tags.js │ │ │ │ │ └── yaml-1.1 │ │ │ │ │ ├── binary.js │ │ │ │ │ ├── bool.js │ │ │ │ │ ├── float.js │ │ │ │ │ ├── int.js │ │ │ │ │ ├── merge.js │ │ │ │ │ ├── omap.js │ │ │ │ │ ├── pairs.js │ │ │ │ │ ├── schema.js │ │ │ │ │ ├── set.js │ │ │ │ │ └── timestamp.js │ │ │ │ ├── stringify │ │ │ │ │ ├── foldFlowLines.js │ │ │ │ │ ├── stringify.js │ │ │ │ │ ├── stringifyCollection.js │ │ │ │ │ ├── stringifyComment.js │ │ │ │ │ ├── stringifyDocument.js │ │ │ │ │ ├── stringifyNumber.js │ │ │ │ │ ├── stringifyPair.js │ │ │ │ │ └── stringifyString.js │ │ │ │ ├── util.js │ │ │ │ └── visit.js │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── dist │ │ │ ├── cli.d.ts │ │ │ ├── cli.mjs │ │ │ ├── compose │ │ │ │ ├── compose-collection.d.ts │ │ │ │ ├── compose-collection.js │ │ │ │ ├── compose-doc.d.ts │ │ │ │ ├── compose-doc.js │ │ │ │ ├── compose-node.d.ts │ │ │ │ ├── compose-node.js │ │ │ │ ├── compose-scalar.d.ts │ │ │ │ ├── compose-scalar.js │ │ │ │ ├── composer.d.ts │ │ │ │ ├── composer.js │ │ │ │ ├── resolve-block-map.d.ts │ │ │ │ ├── resolve-block-map.js │ │ │ │ ├── resolve-block-scalar.d.ts │ │ │ │ ├── resolve-block-scalar.js │ │ │ │ ├── resolve-block-seq.d.ts │ │ │ │ ├── resolve-block-seq.js │ │ │ │ ├── resolve-end.d.ts │ │ │ │ ├── resolve-end.js │ │ │ │ ├── resolve-flow-collection.d.ts │ │ │ │ ├── resolve-flow-collection.js │ │ │ │ ├── resolve-flow-scalar.d.ts │ │ │ │ ├── resolve-flow-scalar.js │ │ │ │ ├── resolve-props.d.ts │ │ │ │ ├── resolve-props.js │ │ │ │ ├── util-contains-newline.d.ts │ │ │ │ ├── util-contains-newline.js │ │ │ │ ├── util-empty-scalar-position.d.ts │ │ │ │ ├── util-empty-scalar-position.js │ │ │ │ ├── util-flow-indent-check.d.ts │ │ │ │ ├── util-flow-indent-check.js │ │ │ │ ├── util-map-includes.d.ts │ │ │ │ └── util-map-includes.js │ │ │ ├── doc │ │ │ │ ├── anchors.d.ts │ │ │ │ ├── anchors.js │ │ │ │ ├── applyReviver.d.ts │ │ │ │ ├── applyReviver.js │ │ │ │ ├── createNode.d.ts │ │ │ │ ├── createNode.js │ │ │ │ ├── directives.d.ts │ │ │ │ ├── directives.js │ │ │ │ ├── Document.d.ts │ │ │ │ └── Document.js │ │ │ ├── errors.d.ts │ │ │ ├── errors.js │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── log.d.ts │ │ │ ├── log.js │ │ │ ├── nodes │ │ │ │ ├── addPairToJSMap.d.ts │ │ │ │ ├── addPairToJSMap.js │ │ │ │ ├── Alias.d.ts │ │ │ │ ├── Alias.js │ │ │ │ ├── Collection.d.ts │ │ │ │ ├── Collection.js │ │ │ │ ├── identity.d.ts │ │ │ │ ├── identity.js │ │ │ │ ├── Node.d.ts │ │ │ │ ├── Node.js │ │ │ │ ├── Pair.d.ts │ │ │ │ ├── Pair.js │ │ │ │ ├── Scalar.d.ts │ │ │ │ ├── Scalar.js │ │ │ │ ├── toJS.d.ts │ │ │ │ ├── toJS.js │ │ │ │ ├── YAMLMap.d.ts │ │ │ │ ├── YAMLMap.js │ │ │ │ ├── YAMLSeq.d.ts │ │ │ │ └── YAMLSeq.js │ │ │ ├── options.d.ts │ │ │ ├── parse │ │ │ │ ├── cst-scalar.d.ts │ │ │ │ ├── cst-scalar.js │ │ │ │ ├── cst-stringify.d.ts │ │ │ │ ├── cst-stringify.js │ │ │ │ ├── cst-visit.d.ts │ │ │ │ ├── cst-visit.js │ │ │ │ ├── cst.d.ts │ │ │ │ ├── cst.js │ │ │ │ ├── lexer.d.ts │ │ │ │ ├── lexer.js │ │ │ │ ├── line-counter.d.ts │ │ │ │ ├── line-counter.js │ │ │ │ ├── parser.d.ts │ │ │ │ └── parser.js │ │ │ ├── public-api.d.ts │ │ │ ├── public-api.js │ │ │ ├── schema │ │ │ │ ├── common │ │ │ │ │ ├── map.d.ts │ │ │ │ │ ├── map.js │ │ │ │ │ ├── null.d.ts │ │ │ │ │ ├── null.js │ │ │ │ │ ├── seq.d.ts │ │ │ │ │ ├── seq.js │ │ │ │ │ ├── string.d.ts │ │ │ │ │ └── string.js │ │ │ │ ├── core │ │ │ │ │ ├── bool.d.ts │ │ │ │ │ ├── bool.js │ │ │ │ │ ├── float.d.ts │ │ │ │ │ ├── float.js │ │ │ │ │ ├── int.d.ts │ │ │ │ │ ├── int.js │ │ │ │ │ ├── schema.d.ts │ │ │ │ │ └── schema.js │ │ │ │ ├── json │ │ │ │ │ ├── schema.d.ts │ │ │ │ │ └── schema.js │ │ │ │ ├── json-schema.d.ts │ │ │ │ ├── Schema.d.ts │ │ │ │ ├── Schema.js │ │ │ │ ├── tags.d.ts │ │ │ │ ├── tags.js │ │ │ │ ├── types.d.ts │ │ │ │ └── yaml-1.1 │ │ │ │ ├── binary.d.ts │ │ │ │ ├── binary.js │ │ │ │ ├── bool.d.ts │ │ │ │ ├── bool.js │ │ │ │ ├── float.d.ts │ │ │ │ ├── float.js │ │ │ │ ├── int.d.ts │ │ │ │ ├── int.js │ │ │ │ ├── merge.d.ts │ │ │ │ ├── merge.js │ │ │ │ ├── omap.d.ts │ │ │ │ ├── omap.js │ │ │ │ ├── pairs.d.ts │ │ │ │ ├── pairs.js │ │ │ │ ├── schema.d.ts │ │ │ │ ├── schema.js │ │ │ │ ├── set.d.ts │ │ │ │ ├── set.js │ │ │ │ ├── timestamp.d.ts │ │ │ │ └── timestamp.js │ │ │ ├── stringify │ │ │ │ ├── foldFlowLines.d.ts │ │ │ │ ├── foldFlowLines.js │ │ │ │ ├── stringify.d.ts │ │ │ │ ├── stringify.js │ │ │ │ ├── stringifyCollection.d.ts │ │ │ │ ├── stringifyCollection.js │ │ │ │ ├── stringifyComment.d.ts │ │ │ │ ├── stringifyComment.js │ │ │ │ ├── stringifyDocument.d.ts │ │ │ │ ├── stringifyDocument.js │ │ │ │ ├── stringifyNumber.d.ts │ │ │ │ ├── stringifyNumber.js │ │ │ │ ├── stringifyPair.d.ts │ │ │ │ ├── stringifyPair.js │ │ │ │ ├── stringifyString.d.ts │ │ │ │ └── stringifyString.js │ │ │ ├── test-events.d.ts │ │ │ ├── test-events.js │ │ │ ├── util.d.ts │ │ │ ├── util.js │ │ │ ├── visit.d.ts │ │ │ └── visit.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── util.js │ ├── yn │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── lenient.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── zod │ │ ├── index.d.ts │ │ ├── lib │ │ │ ├── __tests__ │ │ │ │ ├── Mocker.d.ts │ │ │ │ └── Mocker.js │ │ │ ├── benchmarks │ │ │ │ ├── datetime.d.ts │ │ │ │ ├── datetime.js │ │ │ │ ├── discriminatedUnion.d.ts │ │ │ │ ├── discriminatedUnion.js │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── ipv4.d.ts │ │ │ │ ├── ipv4.js │ │ │ │ ├── object.d.ts │ │ │ │ ├── object.js │ │ │ │ ├── primitives.d.ts │ │ │ │ ├── primitives.js │ │ │ │ ├── realworld.d.ts │ │ │ │ ├── realworld.js │ │ │ │ ├── string.d.ts │ │ │ │ ├── string.js │ │ │ │ ├── union.d.ts │ │ │ │ └── union.js │ │ │ ├── errors.d.ts │ │ │ ├── errors.js │ │ │ ├── external.d.ts │ │ │ ├── external.js │ │ │ ├── helpers │ │ │ │ ├── enumUtil.d.ts │ │ │ │ ├── enumUtil.js │ │ │ │ ├── errorUtil.d.ts │ │ │ │ ├── errorUtil.js │ │ │ │ ├── parseUtil.d.ts │ │ │ │ ├── parseUtil.js │ │ │ │ ├── partialUtil.d.ts │ │ │ │ ├── partialUtil.js │ │ │ │ ├── typeAliases.d.ts │ │ │ │ ├── typeAliases.js │ │ │ │ ├── util.d.ts │ │ │ │ └── util.js │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── index.mjs │ │ │ ├── index.umd.js │ │ │ ├── locales │ │ │ │ ├── en.d.ts │ │ │ │ └── en.js │ │ │ ├── standard-schema.d.ts │ │ │ ├── standard-schema.js │ │ │ ├── types.d.ts │ │ │ ├── types.js │ │ │ ├── ZodError.d.ts │ │ │ └── ZodError.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ └── zod-to-json-schema │ ├── .github │ │ └── FUNDING.yml │ ├── .prettierrc.json │ ├── changelog.md │ ├── contributing.md │ ├── createIndex.ts │ ├── dist │ │ ├── cjs │ │ │ ├── errorMessages.js │ │ │ ├── index.js │ │ │ ├── Options.js │ │ │ ├── package.json │ │ │ ├── parseDef.js │ │ │ ├── parsers │ │ │ │ ├── any.js │ │ │ │ ├── array.js │ │ │ │ ├── bigint.js │ │ │ │ ├── boolean.js │ │ │ │ ├── branded.js │ │ │ │ ├── catch.js │ │ │ │ ├── date.js │ │ │ │ ├── default.js │ │ │ │ ├── effects.js │ │ │ │ ├── enum.js │ │ │ │ ├── intersection.js │ │ │ │ ├── literal.js │ │ │ │ ├── map.js │ │ │ │ ├── nativeEnum.js │ │ │ │ ├── never.js │ │ │ │ ├── null.js │ │ │ │ ├── nullable.js │ │ │ │ ├── number.js │ │ │ │ ├── object.js │ │ │ │ ├── optional.js │ │ │ │ ├── pipeline.js │ │ │ │ ├── promise.js │ │ │ │ ├── readonly.js │ │ │ │ ├── record.js │ │ │ │ ├── set.js │ │ │ │ ├── string.js │ │ │ │ ├── tuple.js │ │ │ │ ├── undefined.js │ │ │ │ ├── union.js │ │ │ │ └── unknown.js │ │ │ ├── Refs.js │ │ │ └── zodToJsonSchema.js │ │ ├── esm │ │ │ ├── errorMessages.js │ │ │ ├── index.js │ │ │ ├── Options.js │ │ │ ├── package.json │ │ │ ├── parseDef.js │ │ │ ├── parsers │ │ │ │ ├── any.js │ │ │ │ ├── array.js │ │ │ │ ├── bigint.js │ │ │ │ ├── boolean.js │ │ │ │ ├── branded.js │ │ │ │ ├── catch.js │ │ │ │ ├── date.js │ │ │ │ ├── default.js │ │ │ │ ├── effects.js │ │ │ │ ├── enum.js │ │ │ │ ├── intersection.js │ │ │ │ ├── literal.js │ │ │ │ ├── map.js │ │ │ │ ├── nativeEnum.js │ │ │ │ ├── never.js │ │ │ │ ├── null.js │ │ │ │ ├── nullable.js │ │ │ │ ├── number.js │ │ │ │ ├── object.js │ │ │ │ ├── optional.js │ │ │ │ ├── pipeline.js │ │ │ │ ├── promise.js │ │ │ │ ├── readonly.js │ │ │ │ ├── record.js │ │ │ │ ├── set.js │ │ │ │ ├── string.js │ │ │ │ ├── tuple.js │ │ │ │ ├── undefined.js │ │ │ │ ├── union.js │ │ │ │ └── unknown.js │ │ │ ├── Refs.js │ │ │ └── zodToJsonSchema.js │ │ └── types │ │ ├── errorMessages.d.ts │ │ ├── index.d.ts │ │ ├── Options.d.ts │ │ ├── parseDef.d.ts │ │ ├── parsers │ │ │ ├── any.d.ts │ │ │ ├── array.d.ts │ │ │ ├── bigint.d.ts │ │ │ ├── boolean.d.ts │ │ │ ├── branded.d.ts │ │ │ ├── catch.d.ts │ │ │ ├── date.d.ts │ │ │ ├── default.d.ts │ │ │ ├── effects.d.ts │ │ │ ├── enum.d.ts │ │ │ ├── intersection.d.ts │ │ │ ├── literal.d.ts │ │ │ ├── map.d.ts │ │ │ ├── nativeEnum.d.ts │ │ │ ├── never.d.ts │ │ │ ├── null.d.ts │ │ │ ├── nullable.d.ts │ │ │ ├── number.d.ts │ │ │ ├── object.d.ts │ │ │ ├── optional.d.ts │ │ │ ├── pipeline.d.ts │ │ │ ├── promise.d.ts │ │ │ ├── readonly.d.ts │ │ │ ├── record.d.ts │ │ │ ├── set.d.ts │ │ │ ├── string.d.ts │ │ │ ├── tuple.d.ts │ │ │ ├── undefined.d.ts │ │ │ ├── union.d.ts │ │ │ └── unknown.d.ts │ │ ├── Refs.d.ts │ │ └── zodToJsonSchema.d.ts │ ├── LICENSE │ ├── package.json │ ├── postcjs.ts │ ├── postesm.ts │ ├── README.md │ └── SECURITY.md ├── package-lock.json ├── package.json ├── README.md ├── src │ ├── index.ts │ ├── schemas.ts │ └── server.ts ├── swagger-mcp.ts └── tsconfig.json ``` # Files -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- ``` 1 | BASE_URL= 2 | AUTH_TOKEN= 3 | SWAGGER_URL=http://localhost:8080 4 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown 1 | # Swagger Explorer MCP 2 | 3 | A Management Control Plane (MCP) server for exploring and analyzing Swagger/OpenAPI specifications through Claude. 4 | 5 | ## Quick Start 6 | 7 | Install and run globally using npx: 8 | ```bash 9 | npx -y @johnneerdael/swagger-mcp 10 | ``` 11 | 12 | Or install with environment variables: 13 | ```bash 14 | npx -y @johnneerdael/swagger-mcp \ 15 | --env BASE_URL=/api \ 16 | --env AUTH_TOKEN=your-token \ 17 | --env PORT=3000 18 | ``` 19 | 20 | ## Installation for Claude Desktop 21 | 22 | 1. Open Claude Desktop 23 | 2. Click on Settings (gear icon) 24 | 3. Select "Tools & Integrations" 25 | 4. Click "Add MCP Server" 26 | 5. Enter the following: 27 | ``` 28 | Name: Swagger Explorer 29 | Command: npx -y @johnneerdael/swagger-mcp 30 | Arguments: --swagger-url=$SWAGGER_URL 31 | ``` 32 | 6. Click "Install" 33 | 34 | ## Usage with Claude 35 | 36 | Here are some example interactions with Claude: 37 | 38 | ### Basic Swagger Exploration 39 | 40 | ``` 41 | Human: Can you explore the Swagger documentation at http://localhost:8080/docs? 42 | 43 | Claude: I'll help you explore that Swagger documentation using the Swagger Explorer MCP. 44 | 45 | Let me analyze the API endpoints and schemas for you: 46 | 47 | [Claude would then use the MCP to fetch and analyze the Swagger documentation] 48 | ``` 49 | 50 | ### Analyzing Specific Endpoints 51 | 52 | ``` 53 | Human: What are the available response schemas for the /pets POST endpoint? 54 | 55 | Claude: I'll check the response schemas for that endpoint using the MCP. 56 | 57 | [Claude would use the MCP to fetch specific endpoint details] 58 | ``` 59 | 60 | ### Schema Analysis 61 | 62 | ``` 63 | Human: Can you show me the detailed structure of the Pet schema? 64 | 65 | Claude: I'll retrieve the detailed schema information using the MCP. 66 | 67 | [Claude would use the MCP to analyze the schema structure] 68 | ``` 69 | 70 | ## Features 71 | 72 | 1. **Authentication Support** 73 | - Bearer token authentication 74 | - Configurable through environment variables 75 | 76 | 2. **Custom Response Formatting** 77 | - Minimal format: Removes null/empty values 78 | - Detailed format: Includes metadata and timestamps 79 | - Raw format: Unmodified response 80 | 81 | 3. **Schema Analysis** 82 | - Detailed property exploration 83 | - Response schema analysis 84 | - Schema relationships 85 | 86 | 4. **API Exploration** 87 | - Path listing 88 | - Method filtering 89 | - Response format analysis 90 | 91 | ## Configuration 92 | 93 | Environment Variables: 94 | - `BASE_URL`: Base path for the API (default: '') 95 | - `AUTH_TOKEN`: Bearer token for authentication 96 | - `PORT`: Server port (default: 3000) 97 | - `SWAGGER_URL`: Default Swagger documentation URL 98 | 99 | ## API Endpoints 100 | 101 | ### Explore API 102 | ```bash 103 | curl -X POST http://localhost:3000/api/explore \ 104 | -H "Authorization: Bearer your-token" \ 105 | -H "Content-Type: application/json" \ 106 | -d '{ 107 | "url": "http://your-swagger-url", 108 | "options": { 109 | "paths": true, 110 | "schemas": true 111 | } 112 | }' 113 | ``` 114 | 115 | ### Get Schema Details 116 | ```bash 117 | curl -X POST http://localhost:3000/api/schema-details \ 118 | -H "Authorization: Bearer your-token" \ 119 | -H "Content-Type: application/json" \ 120 | -d '{ 121 | "url": "http://your-swagger-url", 122 | "schemaName": "Pet" 123 | }' 124 | ``` 125 | 126 | ### Get Response Schemas 127 | ```bash 128 | curl -X POST http://localhost:3000/api/response-schemas \ 129 | -H "Authorization: Bearer your-token" \ 130 | -H "Content-Type: application/json" \ 131 | -d '{ 132 | "url": "http://your-swagger-url", 133 | "path": "/pets", 134 | "method": "post" 135 | }' 136 | ``` 137 | 138 | ## Response Formats 139 | 140 | ### Minimal Format 141 | ```json 142 | { 143 | "status": "success", 144 | "data": { 145 | // Only non-null values 146 | } 147 | } 148 | ``` 149 | 150 | ### Detailed Format 151 | ```json 152 | { 153 | "status": "success", 154 | "timestamp": "2025-01-29T10:00:00.000Z", 155 | "data": { 156 | // Full response 157 | }, 158 | "metadata": { 159 | "version": "1.0", 160 | "format": "detailed" 161 | } 162 | } 163 | ``` 164 | 165 | ## Common Use Cases 166 | 167 | 1. **API Documentation Review** 168 | ``` 169 | Human: Can you summarize all the available endpoints and their purposes? 170 | ``` 171 | 172 | 2. **Schema Validation** 173 | ``` 174 | Human: What fields are required for creating a new pet? 175 | ``` 176 | 177 | 3. **Response Analysis** 178 | ``` 179 | Human: What are the possible error responses for the login endpoint? 180 | ``` 181 | 182 | 4. **Integration Planning** 183 | ``` 184 | Human: How should I structure my request to create a new order? 185 | ``` 186 | 187 | ## Troubleshooting 188 | 189 | 1. **Connection Issues** 190 | - Ensure the Swagger URL is accessible 191 | - Check if authentication token is correct 192 | - Verify port is not in use 193 | 194 | 2. **Authorization Errors** 195 | - Verify AUTH_TOKEN is set correctly 196 | - Ensure bearer token is included in requests 197 | 198 | 3. **Schema Not Found** 199 | - Check if schema name is exact match 200 | - Verify Swagger spec is loaded correctly 201 | 202 | ## Security Notes 203 | 204 | 1. The MCP requires authentication if AUTH_TOKEN is set 205 | 2. All requests are logged for debugging 206 | 3. Sensitive information is not cached 207 | 4. Rate limiting is applied to prevent abuse 208 | 209 | ## Development 210 | 211 | To contribute or modify: 212 | 213 | 1. Clone the repository 214 | 2. Install dependencies: 215 | ```bash 216 | npm install 217 | ``` 218 | 3. Build: 219 | ```bash 220 | npm run build 221 | ``` 222 | 4. Run locally: 223 | ```bash 224 | npm start 225 | ``` 226 | 227 | ## License 228 | 229 | MIT License - See LICENSE file for details 230 | ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "outDir": "./dist", 6 | "rootDir": "./src", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["node_modules", "dist"] 14 | } 15 | ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "name": "swagger-explorer-mcp", 3 | "version": "1.2.0", 4 | "main": "dist/index.js", 5 | "bin": { 6 | "swagger-mcp": "./bin/cli.js" 7 | }, 8 | "scripts": { 9 | "build": "tsc", 10 | "start": "node ./bin/cli.js", 11 | "dev": "ts-node src/index.ts" 12 | }, 13 | "dependencies": { 14 | "@modelcontextprotocol/sdk": "latest", 15 | "express": "latest", 16 | "playwright": "latest", 17 | "yaml": "latest", 18 | "zod": "latest" 19 | }, 20 | "devDependencies": { 21 | "@types/express": "latest", 22 | "@types/node": "latest", 23 | "typescript": "latest", 24 | "ts-node": "latest" 25 | } 26 | } 27 | ``` -------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- ```javascript 1 | #!/usr/bin/env node 2 | 3 | const { createServer } = require('../dist/server'); 4 | 5 | const config = { 6 | baseUrl: process.env.BASE_URL, 7 | authToken: process.env.AUTH_TOKEN 8 | }; 9 | 10 | createServer(config) 11 | .then(({ server, swaggerExplorer }) => { 12 | process.on('SIGTERM', async () => { 13 | console.log('Received SIGTERM. Shutting down gracefully...'); 14 | await swaggerExplorer.stop(); 15 | server.close(); 16 | }); 17 | 18 | process.on('SIGINT', async () => { 19 | console.log('Received SIGINT. Shutting down gracefully...'); 20 | await swaggerExplorer.stop(); 21 | server.close(); 22 | }); 23 | }) 24 | .catch(error => { 25 | console.error('Failed to start server:', error); 26 | process.exit(1); 27 | }); 28 | ``` -------------------------------------------------------------------------------- /src/schemas.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { z } from 'zod'; 2 | 3 | // Basic input schemas 4 | export const SwaggerUrlSchema = z.object({ 5 | url: z.string().url(), 6 | format: z.enum(['minimal', 'detailed']).optional(), 7 | }); 8 | 9 | export const SwaggerOptionsSchema = z.object({ 10 | paths: z.boolean().optional(), 11 | schemas: z.boolean().optional(), 12 | methodFilter: z.array(z.string()).optional(), 13 | }); 14 | 15 | export const PathMethodSchema = z.object({ 16 | url: z.string().url(), 17 | path: z.string(), 18 | method: z.string(), 19 | format: z.enum(['minimal', 'detailed']).optional(), 20 | }); 21 | 22 | // Response schemas 23 | export const SchemaPropertySchema = z.object({ 24 | type: z.string().optional(), 25 | format: z.string().optional(), 26 | description: z.string().optional(), 27 | required: z.boolean().optional(), 28 | enum: z.array(z.unknown()).optional(), 29 | items: z.object({ 30 | type: z.string().optional(), 31 | $ref: z.string().optional(), 32 | }).optional(), 33 | $ref: z.string().optional(), 34 | }); 35 | 36 | export const SchemaDetailsSchema = z.object({ 37 | type: z.string(), 38 | properties: z.record(SchemaPropertySchema), 39 | required: z.array(z.string()).optional(), 40 | description: z.string().optional(), 41 | example: z.unknown().optional(), 42 | responses: z.array(z.object({ 43 | code: z.string(), 44 | description: z.string(), 45 | formats: z.array(z.object({ 46 | contentType: z.string(), 47 | schema: z.unknown(), 48 | example: z.unknown().optional(), 49 | encoding: z.unknown().optional(), 50 | })), 51 | })).optional(), 52 | }); 53 | 54 | // MCP method schemas 55 | export const ExploreInputSchema = SwaggerUrlSchema.merge(z.object({ 56 | options: SwaggerOptionsSchema.optional(), 57 | })); 58 | 59 | export const ExploreOutputSchema = z.object({ 60 | paths: z.array(z.object({ 61 | path: z.string(), 62 | methods: z.array(z.string()), 63 | })).optional(), 64 | schemas: z.array(z.string()).optional(), 65 | }); 66 | 67 | export const ResponseSchemaInputSchema = PathMethodSchema; 68 | 69 | export const ResponseSchemaOutputSchema = z.array(z.object({ 70 | code: z.string(), 71 | description: z.string(), 72 | formats: z.array(z.object({ 73 | contentType: z.string(), 74 | schema: z.unknown(), 75 | example: z.unknown().optional(), 76 | encoding: z.unknown().optional(), 77 | })), 78 | })); 79 | ``` -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { createMCPServer, MCPRequest, MCPResponse } from '@modelcontextprotocol/sdk'; 2 | import { SwaggerExplorerMCP } from './index'; 3 | import { 4 | ExploreInputSchema, 5 | ExploreOutputSchema, 6 | ResponseSchemaInputSchema, 7 | ResponseSchemaOutputSchema, 8 | } from './schemas'; 9 | 10 | export async function createServer(config: any) { 11 | const swaggerExplorer = new SwaggerExplorerMCP(config); 12 | const port = await swaggerExplorer.start(); 13 | 14 | const server = createMCPServer({ 15 | methods: { 16 | explore: { 17 | description: 'Explore a Swagger/OpenAPI specification', 18 | input: ExploreInputSchema, 19 | output: ExploreOutputSchema, 20 | handler: async (request: MCPRequest) => { 21 | try { 22 | const result = await fetch(`http://localhost:${port}/api/explore`, { 23 | method: 'POST', 24 | headers: { 25 | 'Content-Type': 'application/json', 26 | ...(config.authToken ? { 'Authorization': `Bearer ${config.authToken}` } : {}), 27 | }, 28 | body: JSON.stringify(request.input), 29 | }); 30 | 31 | if (!result.ok) { 32 | throw new Error(`Failed to explore Swagger: ${result.statusText}`); 33 | } 34 | 35 | const data = await result.json(); 36 | return new MCPResponse(data); 37 | } catch (error) { 38 | throw new Error(`Explore failed: ${error instanceof Error ? error.message : 'Unknown error'}`); 39 | } 40 | }, 41 | }, 42 | getResponseSchemas: { 43 | description: 'Get response schemas for a specific path and method', 44 | input: ResponseSchemaInputSchema, 45 | output: ResponseSchemaOutputSchema, 46 | handler: async (request: MCPRequest) => { 47 | try { 48 | const result = await fetch(`http://localhost:${port}/api/response-schemas`, { 49 | method: 'POST', 50 | headers: { 51 | 'Content-Type': 'application/json', 52 | ...(config.authToken ? { 'Authorization': `Bearer ${config.authToken}` } : {}), 53 | }, 54 | body: JSON.stringify(request.input), 55 | }); 56 | 57 | if (!result.ok) { 58 | throw new Error(`Failed to get response schemas: ${result.statusText}`); 59 | } 60 | 61 | const data = await result.json(); 62 | return new MCPResponse(data); 63 | } catch (error) { 64 | throw new Error(`Get response schemas failed: ${error instanceof Error ? error.message : 'Unknown error'}`); 65 | } 66 | }, 67 | }, 68 | }, 69 | }); 70 | 71 | return { 72 | server, 73 | swaggerExplorer, 74 | }; 75 | } 76 | ``` -------------------------------------------------------------------------------- /swagger-mcp.ts: -------------------------------------------------------------------------------- ```typescript 1 | import express from 'express'; 2 | import { chromium } from 'playwright'; 3 | import yaml from 'yaml'; 4 | 5 | class SwaggerExplorerMCP { 6 | private app; 7 | private browser; 8 | private port; 9 | 10 | constructor(port = 3000) { 11 | this.port = port; 12 | this.app = express(); 13 | this.app.use(express.json()); 14 | this.setupRoutes(); 15 | } 16 | 17 | private setupRoutes() { 18 | // Health check endpoint 19 | this.app.get('/health', (req, res) => { 20 | res.json({ status: 'healthy' }); 21 | }); 22 | 23 | // Main API to explore Swagger 24 | this.app.post('/api/explore', async (req, res) => { 25 | try { 26 | const { url, options = {} } = req.body; 27 | if (!url) { 28 | return res.status(400).json({ error: 'URL is required' }); 29 | } 30 | 31 | const result = await this.extractSwaggerInfo(url, options); 32 | res.json(result); 33 | } catch (error) { 34 | console.error('Error exploring Swagger:', error); 35 | res.status(500).json({ error: error.message }); 36 | } 37 | }); 38 | 39 | // Get cached schemas 40 | this.app.get('/api/schemas', (req, res) => { 41 | // Implement schema caching if needed 42 | res.json({ message: 'Schema cache endpoint' }); 43 | }); 44 | } 45 | 46 | private async extractSwaggerInfo(url: string, options: { 47 | paths?: boolean; 48 | schemas?: boolean; 49 | methodFilter?: string[]; 50 | }) { 51 | const page = await this.browser.newPage(); 52 | let swaggerData = null; 53 | 54 | try { 55 | // Intercept network requests 56 | page.on('response', async (response) => { 57 | const responseUrl = response.url(); 58 | if (responseUrl.includes('swagger') || responseUrl.includes('openapi')) { 59 | try { 60 | swaggerData = await response.json(); 61 | } catch (e) { 62 | const text = await response.text(); 63 | if (text.includes('openapi:') || text.includes('swagger:')) { 64 | swaggerData = yaml.parse(text); 65 | } 66 | } 67 | } 68 | }); 69 | 70 | await page.goto(url, { waitUntil: 'networkidle' }); 71 | 72 | if (!swaggerData) { 73 | swaggerData = await page.evaluate(() => { 74 | // @ts-ignore 75 | return window.ui?.spec?.json; 76 | }); 77 | } 78 | 79 | if (!swaggerData) { 80 | throw new Error('Could not find Swagger/OpenAPI specification'); 81 | } 82 | 83 | const result: any = {}; 84 | 85 | if (options.paths) { 86 | result.paths = Object.entries(swaggerData.paths || {}) 87 | .filter(([_, methods]) => { 88 | if (!options.methodFilter) return true; 89 | return Object.keys(methods as object) 90 | .some(method => options.methodFilter.includes(method.toLowerCase())); 91 | }) 92 | .map(([path, methods]) => ({ 93 | path, 94 | methods: Object.keys(methods as object) 95 | })); 96 | } 97 | 98 | if (options.schemas) { 99 | const schemas = swaggerData.components?.schemas || 100 | swaggerData.definitions || {}; 101 | result.schemas = Object.keys(schemas); 102 | } 103 | 104 | return result; 105 | } finally { 106 | await page.close(); 107 | } 108 | } 109 | 110 | async start() { 111 | try { 112 | this.browser = await chromium.launch(); 113 | this.app.listen(this.port, () => { 114 | console.log(`Swagger Explorer MCP running on port ${this.port}`); 115 | }); 116 | } catch (error) { 117 | console.error('Failed to start MCP:', error); 118 | process.exit(1); 119 | } 120 | } 121 | 122 | async stop() { 123 | if (this.browser) { 124 | await this.browser.close(); 125 | } 126 | process.exit(0); 127 | } 128 | } 129 | 130 | // Handle graceful shutdown 131 | process.on('SIGTERM', async () => { 132 | console.log('Received SIGTERM. Shutting down gracefully...'); 133 | if (global.mcp) { 134 | await global.mcp.stop(); 135 | } 136 | }); 137 | 138 | process.on('SIGINT', async () => { 139 | console.log('Received SIGINT. Shutting down gracefully...'); 140 | if (global.mcp) { 141 | await global.mcp.stop(); 142 | } 143 | }); 144 | 145 | // Start the MCP if this is the main module 146 | if (require.main === module) { 147 | const port = process.env.PORT ? parseInt(process.env.PORT) : 3000; 148 | const mcp = new SwaggerExplorerMCP(port); 149 | // @ts-ignore 150 | global.mcp = mcp; 151 | mcp.start(); 152 | } 153 | 154 | export { SwaggerExplorerMCP }; 155 | ``` -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- ```typescript 1 | import express, { Request, Response } from 'express'; 2 | import { chromium, Browser, Page } from 'playwright'; 3 | import yaml from 'yaml'; 4 | import { createServer, Server } from 'net'; 5 | 6 | async function findAvailablePort(startPort: number = 3000, endPort: number = 65535): Promise<number> { 7 | for (let port = startPort; port <= endPort; port++) { 8 | try { 9 | const server = createServer(); 10 | const available = await new Promise<boolean>((resolve, reject) => { 11 | server.once('error', (err: NodeJS.ErrnoException) => { 12 | if (err.code === 'EADDRINUSE') { 13 | resolve(false); 14 | } else { 15 | reject(err); 16 | } 17 | }); 18 | server.once('listening', () => { 19 | server.close(); 20 | resolve(true); 21 | }); 22 | server.listen(port); 23 | }); 24 | if (available) { 25 | return port; 26 | } 27 | } catch (err) { 28 | continue; 29 | } 30 | } 31 | throw new Error('No available ports found'); 32 | } 33 | 34 | declare global { 35 | var mcp: SwaggerExplorerMCP; 36 | } 37 | 38 | interface SwaggerExplorerConfig { 39 | baseUrl?: string; 40 | authToken?: string; 41 | port?: number; 42 | } 43 | 44 | interface SwaggerOptions { 45 | paths?: boolean; 46 | schemas?: boolean; 47 | methodFilter?: string[]; 48 | } 49 | 50 | interface ResponseFormat { 51 | contentType: string; 52 | schema: any; 53 | example?: any; 54 | encoding?: any; 55 | } 56 | 57 | interface PathResponse { 58 | code: string; 59 | description: string; 60 | formats: ResponseFormat[]; 61 | } 62 | 63 | interface SchemaProperty { 64 | type?: string; 65 | format?: string; 66 | description?: string; 67 | required?: boolean; 68 | enum?: unknown[]; 69 | items?: { 70 | type?: string; 71 | $ref?: string; 72 | }; 73 | $ref?: string; 74 | } 75 | 76 | interface SchemaDetails { 77 | type: string; 78 | properties: Record<string, SchemaProperty>; 79 | required?: string[]; 80 | description?: string; 81 | example?: any; 82 | responses?: PathResponse[]; 83 | } 84 | 85 | class SwaggerExplorerMCP { 86 | private app; 87 | private browser!: Browser; 88 | private config: SwaggerExplorerConfig; 89 | private schemaCache: Map<string, any>; 90 | private port?: number; 91 | private server?: Server; 92 | 93 | constructor(config: SwaggerExplorerConfig = {}) { 94 | this.config = { 95 | ...config 96 | }; 97 | this.app = express(); 98 | this.schemaCache = new Map(); 99 | this.setupMiddleware(); 100 | this.setupRoutes(); 101 | } 102 | 103 | private setupMiddleware() { 104 | this.app.use(express.json()); 105 | 106 | // Authentication middleware 107 | const authMiddleware = (req: Request, res: Response, next: express.NextFunction) => { 108 | const authHeader = req.headers.authorization; 109 | 110 | if (!this.config.authToken) { 111 | return next(); 112 | } 113 | 114 | if (!authHeader || !authHeader.startsWith('Bearer ')) { 115 | return res.status(401).json({ error: 'Missing or invalid authorization header' }); 116 | } 117 | 118 | const token = authHeader.split(' ')[1]; 119 | if (token !== this.config.authToken) { 120 | return res.status(401).json({ error: 'Invalid token' }); 121 | } 122 | 123 | next(); 124 | }; 125 | 126 | // Apply auth middleware to all routes except health 127 | this.app.use((req, res, next) => { 128 | if (req.path === '/health') { 129 | return next(); 130 | } 131 | authMiddleware(req, res, next); 132 | }); 133 | } 134 | 135 | private setupRoutes() { 136 | const basePath = this.config.baseUrl || ''; 137 | 138 | // Custom response format handler 139 | const formatResponse = (data: unknown, format?: string) => { 140 | switch (format?.toLowerCase()) { 141 | case 'minimal': 142 | return { 143 | status: 'success', 144 | data: this.minimizeResponse(data) 145 | }; 146 | case 'detailed': 147 | return { 148 | status: 'success', 149 | timestamp: new Date().toISOString(), 150 | data, 151 | metadata: { 152 | version: '1.0', 153 | format: 'detailed' 154 | } 155 | }; 156 | default: 157 | return data; 158 | } 159 | }; 160 | 161 | // Health check endpoint 162 | this.app.get('/health', (req, res) => { 163 | res.json({ 164 | status: 'healthy', 165 | port: this.port, 166 | baseUrl: this.config.baseUrl 167 | }); 168 | }); 169 | 170 | // Main API to explore Swagger 171 | this.app.post(`${basePath}/api/explore`, async (req, res) => { 172 | try { 173 | const { url, options = {} } = req.body; 174 | if (!url) { 175 | return res.status(400).json({ error: 'URL is required' }); 176 | } 177 | 178 | const page = await this.browser.newPage(); 179 | try { 180 | const swaggerData = await this.getSwaggerData(url, page); 181 | const result = await this.processSwaggerData(swaggerData, options as SwaggerOptions); 182 | res.json(formatResponse(result, req.body.format)); 183 | } finally { 184 | await page.close(); 185 | } 186 | } catch (error) { 187 | console.error('Error exploring Swagger:', error); 188 | res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' }); 189 | } 190 | }); 191 | 192 | // Get response schemas for a path 193 | this.app.post(`${basePath}/api/response-schemas`, async (req, res) => { 194 | try { 195 | const { url, path, method, format } = req.body; 196 | if (!url || !path || !method) { 197 | return res.status(400).json({ error: 'URL, path, and method are required' }); 198 | } 199 | 200 | const page = await this.browser.newPage(); 201 | try { 202 | const swaggerData = await this.getSwaggerData(url, page); 203 | const responses = await this.extractResponseSchemas(swaggerData, path, method); 204 | res.json(formatResponse(responses, format)); 205 | } finally { 206 | await page.close(); 207 | } 208 | } catch (error) { 209 | console.error('Error getting response schemas:', error); 210 | res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' }); 211 | } 212 | }); 213 | } 214 | 215 | private minimizeResponse(data: unknown): unknown { 216 | if (Array.isArray(data)) { 217 | return data.map(item => this.minimizeResponse(item)); 218 | } 219 | if (typeof data === 'object' && data !== null) { 220 | const minimized: Record<string, unknown> = {}; 221 | for (const [key, value] of Object.entries(data)) { 222 | if (value !== null && value !== undefined && value !== '') { 223 | minimized[key] = this.minimizeResponse(value); 224 | } 225 | } 226 | return minimized; 227 | } 228 | return data; 229 | } 230 | 231 | private async processSwaggerData(swaggerData: any, options: SwaggerOptions) { 232 | const result: any = {}; 233 | 234 | if (options.paths) { 235 | result.paths = Object.entries(swaggerData.paths || {}) 236 | .filter(([_, methods]) => { 237 | if (!options.methodFilter?.length) return true; 238 | const methodKeys = Object.keys(methods as object); 239 | return methodKeys.some(method => 240 | options.methodFilter?.includes(method.toLowerCase()) ?? false); 241 | }) 242 | .map(([path, methods]) => ({ 243 | path, 244 | methods: Object.keys(methods as object) 245 | })); 246 | } 247 | 248 | if (options.schemas) { 249 | const schemas = swaggerData.components?.schemas || swaggerData.definitions || {}; 250 | result.schemas = Object.keys(schemas); 251 | } 252 | 253 | return result; 254 | } 255 | 256 | private async extractResponseSchemas(swaggerData: any, path: string, method: string): Promise<PathResponse[]> { 257 | const responses = swaggerData.paths[path]?.[method]?.responses || {}; 258 | return Object.entries(responses).map(([code, response]: [string, any]) => ({ 259 | code, 260 | description: response.description || '', 261 | formats: Object.entries(response.content || {}).map(([contentType, content]: [string, any]) => ({ 262 | contentType, 263 | schema: content.schema, 264 | example: content.example, 265 | encoding: content.encoding 266 | })) 267 | })); 268 | } 269 | 270 | async start(): Promise<number> { 271 | try { 272 | this.browser = await chromium.launch(); 273 | 274 | // Find an available port if none is specified 275 | if (!this.port) { 276 | this.port = await findAvailablePort(); 277 | } 278 | 279 | return new Promise((resolve, reject) => { 280 | const server = this.app.listen(this.port) 281 | .once('listening', () => { 282 | console.log(`Swagger Explorer MCP running on port ${this.port}`); 283 | if (this.config.baseUrl) { 284 | console.log(`Base URL: ${this.config.baseUrl}`); 285 | } 286 | if (this.config.authToken) { 287 | console.log('Authentication enabled'); 288 | } 289 | resolve(this.port!); 290 | }) 291 | .once('error', async (err: NodeJS.ErrnoException) => { 292 | if (err.code === 'EADDRINUSE') { 293 | console.log(`Port ${this.port} in use, trying another port...`); 294 | this.port = undefined; // Reset port to try again 295 | try { 296 | const newPort = await this.start(); 297 | resolve(newPort); 298 | } catch (retryError) { 299 | reject(retryError); 300 | } 301 | } else { 302 | console.error('Failed to start MCP:', err); 303 | reject(err); 304 | } 305 | }); 306 | 307 | // Store server reference for proper shutdown 308 | this.server = server; 309 | }); 310 | } catch (error) { 311 | console.error('Failed to start MCP:', error); 312 | throw error; 313 | } 314 | } 315 | 316 | async stop() { 317 | if (this.browser) { 318 | await this.browser.close(); 319 | } 320 | if (this.server) { 321 | await new Promise<void>((resolve) => { 322 | this.server!.close(() => resolve()); 323 | }); 324 | } 325 | process.exit(0); 326 | } 327 | 328 | private async getSwaggerData(url: string, page: Page): Promise<any> { 329 | let swaggerData = null; 330 | 331 | // Listen for swagger spec in network requests 332 | const responsePromise = new Promise((resolve) => { 333 | page.on('response', async (response) => { 334 | const responseUrl = response.url(); 335 | if (responseUrl.includes('swagger') || responseUrl.includes('openapi')) { 336 | try { 337 | const data = await response.json(); 338 | resolve(data); 339 | } catch (e) { 340 | const text = await response.text(); 341 | if (text.includes('openapi:') || text.includes('swagger:')) { 342 | resolve(yaml.parse(text)); 343 | } 344 | } 345 | } 346 | }); 347 | }); 348 | 349 | await page.goto(url, { waitUntil: 'networkidle' }); 350 | 351 | // Try network response first 352 | swaggerData = await Promise.race([ 353 | responsePromise, 354 | new Promise(resolve => setTimeout(resolve, 5000)) 355 | ]); 356 | 357 | // Fallback to window object if needed 358 | if (!swaggerData) { 359 | swaggerData = await page.evaluate(() => { 360 | // @ts-ignore 361 | return window.ui?.spec?.json; 362 | }); 363 | } 364 | 365 | if (!swaggerData) { 366 | throw new Error('Could not find Swagger/OpenAPI specification'); 367 | } 368 | 369 | return swaggerData; 370 | } 371 | } 372 | 373 | // Handle graceful shutdown 374 | process.on('SIGTERM', async () => { 375 | console.log('Received SIGTERM. Shutting down gracefully...'); 376 | if (global.mcp) { 377 | await global.mcp.stop(); 378 | } 379 | }); 380 | 381 | process.on('SIGINT', async () => { 382 | console.log('Received SIGINT. Shutting down gracefully...'); 383 | if (global.mcp) { 384 | await global.mcp.stop(); 385 | } 386 | }); 387 | 388 | export { SwaggerExplorerMCP }; 389 | ```