# 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: -------------------------------------------------------------------------------- ``` BASE_URL= AUTH_TOKEN= SWAGGER_URL=http://localhost:8080 ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown # Swagger Explorer MCP A Management Control Plane (MCP) server for exploring and analyzing Swagger/OpenAPI specifications through Claude. ## Quick Start Install and run globally using npx: ```bash npx -y @johnneerdael/swagger-mcp ``` Or install with environment variables: ```bash npx -y @johnneerdael/swagger-mcp \ --env BASE_URL=/api \ --env AUTH_TOKEN=your-token \ --env PORT=3000 ``` ## Installation for Claude Desktop 1. Open Claude Desktop 2. Click on Settings (gear icon) 3. Select "Tools & Integrations" 4. Click "Add MCP Server" 5. Enter the following: ``` Name: Swagger Explorer Command: npx -y @johnneerdael/swagger-mcp Arguments: --swagger-url=$SWAGGER_URL ``` 6. Click "Install" ## Usage with Claude Here are some example interactions with Claude: ### Basic Swagger Exploration ``` Human: Can you explore the Swagger documentation at http://localhost:8080/docs? Claude: I'll help you explore that Swagger documentation using the Swagger Explorer MCP. Let me analyze the API endpoints and schemas for you: [Claude would then use the MCP to fetch and analyze the Swagger documentation] ``` ### Analyzing Specific Endpoints ``` Human: What are the available response schemas for the /pets POST endpoint? Claude: I'll check the response schemas for that endpoint using the MCP. [Claude would use the MCP to fetch specific endpoint details] ``` ### Schema Analysis ``` Human: Can you show me the detailed structure of the Pet schema? Claude: I'll retrieve the detailed schema information using the MCP. [Claude would use the MCP to analyze the schema structure] ``` ## Features 1. **Authentication Support** - Bearer token authentication - Configurable through environment variables 2. **Custom Response Formatting** - Minimal format: Removes null/empty values - Detailed format: Includes metadata and timestamps - Raw format: Unmodified response 3. **Schema Analysis** - Detailed property exploration - Response schema analysis - Schema relationships 4. **API Exploration** - Path listing - Method filtering - Response format analysis ## Configuration Environment Variables: - `BASE_URL`: Base path for the API (default: '') - `AUTH_TOKEN`: Bearer token for authentication - `PORT`: Server port (default: 3000) - `SWAGGER_URL`: Default Swagger documentation URL ## API Endpoints ### Explore API ```bash curl -X POST http://localhost:3000/api/explore \ -H "Authorization: Bearer your-token" \ -H "Content-Type: application/json" \ -d '{ "url": "http://your-swagger-url", "options": { "paths": true, "schemas": true } }' ``` ### Get Schema Details ```bash curl -X POST http://localhost:3000/api/schema-details \ -H "Authorization: Bearer your-token" \ -H "Content-Type: application/json" \ -d '{ "url": "http://your-swagger-url", "schemaName": "Pet" }' ``` ### Get Response Schemas ```bash curl -X POST http://localhost:3000/api/response-schemas \ -H "Authorization: Bearer your-token" \ -H "Content-Type: application/json" \ -d '{ "url": "http://your-swagger-url", "path": "/pets", "method": "post" }' ``` ## Response Formats ### Minimal Format ```json { "status": "success", "data": { // Only non-null values } } ``` ### Detailed Format ```json { "status": "success", "timestamp": "2025-01-29T10:00:00.000Z", "data": { // Full response }, "metadata": { "version": "1.0", "format": "detailed" } } ``` ## Common Use Cases 1. **API Documentation Review** ``` Human: Can you summarize all the available endpoints and their purposes? ``` 2. **Schema Validation** ``` Human: What fields are required for creating a new pet? ``` 3. **Response Analysis** ``` Human: What are the possible error responses for the login endpoint? ``` 4. **Integration Planning** ``` Human: How should I structure my request to create a new order? ``` ## Troubleshooting 1. **Connection Issues** - Ensure the Swagger URL is accessible - Check if authentication token is correct - Verify port is not in use 2. **Authorization Errors** - Verify AUTH_TOKEN is set correctly - Ensure bearer token is included in requests 3. **Schema Not Found** - Check if schema name is exact match - Verify Swagger spec is loaded correctly ## Security Notes 1. The MCP requires authentication if AUTH_TOKEN is set 2. All requests are logged for debugging 3. Sensitive information is not cached 4. Rate limiting is applied to prevent abuse ## Development To contribute or modify: 1. Clone the repository 2. Install dependencies: ```bash npm install ``` 3. Build: ```bash npm run build ``` 4. Run locally: ```bash npm start ``` ## License MIT License - See LICENSE file for details ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "target": "es2018", "module": "commonjs", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- ```json { "name": "swagger-explorer-mcp", "version": "1.2.0", "main": "dist/index.js", "bin": { "swagger-mcp": "./bin/cli.js" }, "scripts": { "build": "tsc", "start": "node ./bin/cli.js", "dev": "ts-node src/index.ts" }, "dependencies": { "@modelcontextprotocol/sdk": "latest", "express": "latest", "playwright": "latest", "yaml": "latest", "zod": "latest" }, "devDependencies": { "@types/express": "latest", "@types/node": "latest", "typescript": "latest", "ts-node": "latest" } } ``` -------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- ```javascript #!/usr/bin/env node const { createServer } = require('../dist/server'); const config = { baseUrl: process.env.BASE_URL, authToken: process.env.AUTH_TOKEN }; createServer(config) .then(({ server, swaggerExplorer }) => { process.on('SIGTERM', async () => { console.log('Received SIGTERM. Shutting down gracefully...'); await swaggerExplorer.stop(); server.close(); }); process.on('SIGINT', async () => { console.log('Received SIGINT. Shutting down gracefully...'); await swaggerExplorer.stop(); server.close(); }); }) .catch(error => { console.error('Failed to start server:', error); process.exit(1); }); ``` -------------------------------------------------------------------------------- /src/schemas.ts: -------------------------------------------------------------------------------- ```typescript import { z } from 'zod'; // Basic input schemas export const SwaggerUrlSchema = z.object({ url: z.string().url(), format: z.enum(['minimal', 'detailed']).optional(), }); export const SwaggerOptionsSchema = z.object({ paths: z.boolean().optional(), schemas: z.boolean().optional(), methodFilter: z.array(z.string()).optional(), }); export const PathMethodSchema = z.object({ url: z.string().url(), path: z.string(), method: z.string(), format: z.enum(['minimal', 'detailed']).optional(), }); // Response schemas export const SchemaPropertySchema = z.object({ type: z.string().optional(), format: z.string().optional(), description: z.string().optional(), required: z.boolean().optional(), enum: z.array(z.unknown()).optional(), items: z.object({ type: z.string().optional(), $ref: z.string().optional(), }).optional(), $ref: z.string().optional(), }); export const SchemaDetailsSchema = z.object({ type: z.string(), properties: z.record(SchemaPropertySchema), required: z.array(z.string()).optional(), description: z.string().optional(), example: z.unknown().optional(), responses: z.array(z.object({ code: z.string(), description: z.string(), formats: z.array(z.object({ contentType: z.string(), schema: z.unknown(), example: z.unknown().optional(), encoding: z.unknown().optional(), })), })).optional(), }); // MCP method schemas export const ExploreInputSchema = SwaggerUrlSchema.merge(z.object({ options: SwaggerOptionsSchema.optional(), })); export const ExploreOutputSchema = z.object({ paths: z.array(z.object({ path: z.string(), methods: z.array(z.string()), })).optional(), schemas: z.array(z.string()).optional(), }); export const ResponseSchemaInputSchema = PathMethodSchema; export const ResponseSchemaOutputSchema = z.array(z.object({ code: z.string(), description: z.string(), formats: z.array(z.object({ contentType: z.string(), schema: z.unknown(), example: z.unknown().optional(), encoding: z.unknown().optional(), })), })); ``` -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- ```typescript import { createMCPServer, MCPRequest, MCPResponse } from '@modelcontextprotocol/sdk'; import { SwaggerExplorerMCP } from './index'; import { ExploreInputSchema, ExploreOutputSchema, ResponseSchemaInputSchema, ResponseSchemaOutputSchema, } from './schemas'; export async function createServer(config: any) { const swaggerExplorer = new SwaggerExplorerMCP(config); const port = await swaggerExplorer.start(); const server = createMCPServer({ methods: { explore: { description: 'Explore a Swagger/OpenAPI specification', input: ExploreInputSchema, output: ExploreOutputSchema, handler: async (request: MCPRequest) => { try { const result = await fetch(`http://localhost:${port}/api/explore`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...(config.authToken ? { 'Authorization': `Bearer ${config.authToken}` } : {}), }, body: JSON.stringify(request.input), }); if (!result.ok) { throw new Error(`Failed to explore Swagger: ${result.statusText}`); } const data = await result.json(); return new MCPResponse(data); } catch (error) { throw new Error(`Explore failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } }, }, getResponseSchemas: { description: 'Get response schemas for a specific path and method', input: ResponseSchemaInputSchema, output: ResponseSchemaOutputSchema, handler: async (request: MCPRequest) => { try { const result = await fetch(`http://localhost:${port}/api/response-schemas`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...(config.authToken ? { 'Authorization': `Bearer ${config.authToken}` } : {}), }, body: JSON.stringify(request.input), }); if (!result.ok) { throw new Error(`Failed to get response schemas: ${result.statusText}`); } const data = await result.json(); return new MCPResponse(data); } catch (error) { throw new Error(`Get response schemas failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } }, }, }, }); return { server, swaggerExplorer, }; } ``` -------------------------------------------------------------------------------- /swagger-mcp.ts: -------------------------------------------------------------------------------- ```typescript import express from 'express'; import { chromium } from 'playwright'; import yaml from 'yaml'; class SwaggerExplorerMCP { private app; private browser; private port; constructor(port = 3000) { this.port = port; this.app = express(); this.app.use(express.json()); this.setupRoutes(); } private setupRoutes() { // Health check endpoint this.app.get('/health', (req, res) => { res.json({ status: 'healthy' }); }); // Main API to explore Swagger this.app.post('/api/explore', async (req, res) => { try { const { url, options = {} } = req.body; if (!url) { return res.status(400).json({ error: 'URL is required' }); } const result = await this.extractSwaggerInfo(url, options); res.json(result); } catch (error) { console.error('Error exploring Swagger:', error); res.status(500).json({ error: error.message }); } }); // Get cached schemas this.app.get('/api/schemas', (req, res) => { // Implement schema caching if needed res.json({ message: 'Schema cache endpoint' }); }); } private async extractSwaggerInfo(url: string, options: { paths?: boolean; schemas?: boolean; methodFilter?: string[]; }) { const page = await this.browser.newPage(); let swaggerData = null; try { // Intercept network requests page.on('response', async (response) => { const responseUrl = response.url(); if (responseUrl.includes('swagger') || responseUrl.includes('openapi')) { try { swaggerData = await response.json(); } catch (e) { const text = await response.text(); if (text.includes('openapi:') || text.includes('swagger:')) { swaggerData = yaml.parse(text); } } } }); await page.goto(url, { waitUntil: 'networkidle' }); if (!swaggerData) { swaggerData = await page.evaluate(() => { // @ts-ignore return window.ui?.spec?.json; }); } if (!swaggerData) { throw new Error('Could not find Swagger/OpenAPI specification'); } const result: any = {}; if (options.paths) { result.paths = Object.entries(swaggerData.paths || {}) .filter(([_, methods]) => { if (!options.methodFilter) return true; return Object.keys(methods as object) .some(method => options.methodFilter.includes(method.toLowerCase())); }) .map(([path, methods]) => ({ path, methods: Object.keys(methods as object) })); } if (options.schemas) { const schemas = swaggerData.components?.schemas || swaggerData.definitions || {}; result.schemas = Object.keys(schemas); } return result; } finally { await page.close(); } } async start() { try { this.browser = await chromium.launch(); this.app.listen(this.port, () => { console.log(`Swagger Explorer MCP running on port ${this.port}`); }); } catch (error) { console.error('Failed to start MCP:', error); process.exit(1); } } async stop() { if (this.browser) { await this.browser.close(); } process.exit(0); } } // Handle graceful shutdown process.on('SIGTERM', async () => { console.log('Received SIGTERM. Shutting down gracefully...'); if (global.mcp) { await global.mcp.stop(); } }); process.on('SIGINT', async () => { console.log('Received SIGINT. Shutting down gracefully...'); if (global.mcp) { await global.mcp.stop(); } }); // Start the MCP if this is the main module if (require.main === module) { const port = process.env.PORT ? parseInt(process.env.PORT) : 3000; const mcp = new SwaggerExplorerMCP(port); // @ts-ignore global.mcp = mcp; mcp.start(); } export { SwaggerExplorerMCP }; ``` -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- ```typescript import express, { Request, Response } from 'express'; import { chromium, Browser, Page } from 'playwright'; import yaml from 'yaml'; import { createServer, Server } from 'net'; async function findAvailablePort(startPort: number = 3000, endPort: number = 65535): Promise<number> { for (let port = startPort; port <= endPort; port++) { try { const server = createServer(); const available = await new Promise<boolean>((resolve, reject) => { server.once('error', (err: NodeJS.ErrnoException) => { if (err.code === 'EADDRINUSE') { resolve(false); } else { reject(err); } }); server.once('listening', () => { server.close(); resolve(true); }); server.listen(port); }); if (available) { return port; } } catch (err) { continue; } } throw new Error('No available ports found'); } declare global { var mcp: SwaggerExplorerMCP; } interface SwaggerExplorerConfig { baseUrl?: string; authToken?: string; port?: number; } interface SwaggerOptions { paths?: boolean; schemas?: boolean; methodFilter?: string[]; } interface ResponseFormat { contentType: string; schema: any; example?: any; encoding?: any; } interface PathResponse { code: string; description: string; formats: ResponseFormat[]; } interface SchemaProperty { type?: string; format?: string; description?: string; required?: boolean; enum?: unknown[]; items?: { type?: string; $ref?: string; }; $ref?: string; } interface SchemaDetails { type: string; properties: Record<string, SchemaProperty>; required?: string[]; description?: string; example?: any; responses?: PathResponse[]; } class SwaggerExplorerMCP { private app; private browser!: Browser; private config: SwaggerExplorerConfig; private schemaCache: Map<string, any>; private port?: number; private server?: Server; constructor(config: SwaggerExplorerConfig = {}) { this.config = { ...config }; this.app = express(); this.schemaCache = new Map(); this.setupMiddleware(); this.setupRoutes(); } private setupMiddleware() { this.app.use(express.json()); // Authentication middleware const authMiddleware = (req: Request, res: Response, next: express.NextFunction) => { const authHeader = req.headers.authorization; if (!this.config.authToken) { return next(); } if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ error: 'Missing or invalid authorization header' }); } const token = authHeader.split(' ')[1]; if (token !== this.config.authToken) { return res.status(401).json({ error: 'Invalid token' }); } next(); }; // Apply auth middleware to all routes except health this.app.use((req, res, next) => { if (req.path === '/health') { return next(); } authMiddleware(req, res, next); }); } private setupRoutes() { const basePath = this.config.baseUrl || ''; // Custom response format handler const formatResponse = (data: unknown, format?: string) => { switch (format?.toLowerCase()) { case 'minimal': return { status: 'success', data: this.minimizeResponse(data) }; case 'detailed': return { status: 'success', timestamp: new Date().toISOString(), data, metadata: { version: '1.0', format: 'detailed' } }; default: return data; } }; // Health check endpoint this.app.get('/health', (req, res) => { res.json({ status: 'healthy', port: this.port, baseUrl: this.config.baseUrl }); }); // Main API to explore Swagger this.app.post(`${basePath}/api/explore`, async (req, res) => { try { const { url, options = {} } = req.body; if (!url) { return res.status(400).json({ error: 'URL is required' }); } const page = await this.browser.newPage(); try { const swaggerData = await this.getSwaggerData(url, page); const result = await this.processSwaggerData(swaggerData, options as SwaggerOptions); res.json(formatResponse(result, req.body.format)); } finally { await page.close(); } } catch (error) { console.error('Error exploring Swagger:', error); res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' }); } }); // Get response schemas for a path this.app.post(`${basePath}/api/response-schemas`, async (req, res) => { try { const { url, path, method, format } = req.body; if (!url || !path || !method) { return res.status(400).json({ error: 'URL, path, and method are required' }); } const page = await this.browser.newPage(); try { const swaggerData = await this.getSwaggerData(url, page); const responses = await this.extractResponseSchemas(swaggerData, path, method); res.json(formatResponse(responses, format)); } finally { await page.close(); } } catch (error) { console.error('Error getting response schemas:', error); res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' }); } }); } private minimizeResponse(data: unknown): unknown { if (Array.isArray(data)) { return data.map(item => this.minimizeResponse(item)); } if (typeof data === 'object' && data !== null) { const minimized: Record<string, unknown> = {}; for (const [key, value] of Object.entries(data)) { if (value !== null && value !== undefined && value !== '') { minimized[key] = this.minimizeResponse(value); } } return minimized; } return data; } private async processSwaggerData(swaggerData: any, options: SwaggerOptions) { const result: any = {}; if (options.paths) { result.paths = Object.entries(swaggerData.paths || {}) .filter(([_, methods]) => { if (!options.methodFilter?.length) return true; const methodKeys = Object.keys(methods as object); return methodKeys.some(method => options.methodFilter?.includes(method.toLowerCase()) ?? false); }) .map(([path, methods]) => ({ path, methods: Object.keys(methods as object) })); } if (options.schemas) { const schemas = swaggerData.components?.schemas || swaggerData.definitions || {}; result.schemas = Object.keys(schemas); } return result; } private async extractResponseSchemas(swaggerData: any, path: string, method: string): Promise<PathResponse[]> { const responses = swaggerData.paths[path]?.[method]?.responses || {}; return Object.entries(responses).map(([code, response]: [string, any]) => ({ code, description: response.description || '', formats: Object.entries(response.content || {}).map(([contentType, content]: [string, any]) => ({ contentType, schema: content.schema, example: content.example, encoding: content.encoding })) })); } async start(): Promise<number> { try { this.browser = await chromium.launch(); // Find an available port if none is specified if (!this.port) { this.port = await findAvailablePort(); } return new Promise((resolve, reject) => { const server = this.app.listen(this.port) .once('listening', () => { console.log(`Swagger Explorer MCP running on port ${this.port}`); if (this.config.baseUrl) { console.log(`Base URL: ${this.config.baseUrl}`); } if (this.config.authToken) { console.log('Authentication enabled'); } resolve(this.port!); }) .once('error', async (err: NodeJS.ErrnoException) => { if (err.code === 'EADDRINUSE') { console.log(`Port ${this.port} in use, trying another port...`); this.port = undefined; // Reset port to try again try { const newPort = await this.start(); resolve(newPort); } catch (retryError) { reject(retryError); } } else { console.error('Failed to start MCP:', err); reject(err); } }); // Store server reference for proper shutdown this.server = server; }); } catch (error) { console.error('Failed to start MCP:', error); throw error; } } async stop() { if (this.browser) { await this.browser.close(); } if (this.server) { await new Promise<void>((resolve) => { this.server!.close(() => resolve()); }); } process.exit(0); } private async getSwaggerData(url: string, page: Page): Promise<any> { let swaggerData = null; // Listen for swagger spec in network requests const responsePromise = new Promise((resolve) => { page.on('response', async (response) => { const responseUrl = response.url(); if (responseUrl.includes('swagger') || responseUrl.includes('openapi')) { try { const data = await response.json(); resolve(data); } catch (e) { const text = await response.text(); if (text.includes('openapi:') || text.includes('swagger:')) { resolve(yaml.parse(text)); } } } }); }); await page.goto(url, { waitUntil: 'networkidle' }); // Try network response first swaggerData = await Promise.race([ responsePromise, new Promise(resolve => setTimeout(resolve, 5000)) ]); // Fallback to window object if needed if (!swaggerData) { swaggerData = await page.evaluate(() => { // @ts-ignore return window.ui?.spec?.json; }); } if (!swaggerData) { throw new Error('Could not find Swagger/OpenAPI specification'); } return swaggerData; } } // Handle graceful shutdown process.on('SIGTERM', async () => { console.log('Received SIGTERM. Shutting down gracefully...'); if (global.mcp) { await global.mcp.stop(); } }); process.on('SIGINT', async () => { console.log('Received SIGINT. Shutting down gracefully...'); if (global.mcp) { await global.mcp.stop(); } }); export { SwaggerExplorerMCP }; ```