This is page 1 of 2. Use http://codebase.md/mgsrevolver/seo-inspector-mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .cursor
│ └── mcp.json
├── .gitignore
├── console-spy-mcp.js
├── cs-mcp-server.js
├── mcp-tools.js
├── node_modules
│ ├── .bin
│ │ ├── mime
│ │ └── supergateway
│ ├── .package-lock.json
│ ├── @modelcontextprotocol
│ │ └── sdk
│ │ ├── dist
│ │ │ ├── cjs
│ │ │ │ ├── cli.d.ts
│ │ │ │ ├── cli.d.ts.map
│ │ │ │ ├── cli.js
│ │ │ │ ├── cli.js.map
│ │ │ │ ├── client
│ │ │ │ │ ├── auth.d.ts
│ │ │ │ │ ├── auth.d.ts.map
│ │ │ │ │ ├── auth.js
│ │ │ │ │ ├── auth.js.map
│ │ │ │ │ ├── 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
│ │ │ │ │ ├── auth
│ │ │ │ │ │ ├── clients.d.ts
│ │ │ │ │ │ ├── clients.d.ts.map
│ │ │ │ │ │ ├── clients.js
│ │ │ │ │ │ ├── clients.js.map
│ │ │ │ │ │ ├── errors.d.ts
│ │ │ │ │ │ ├── errors.d.ts.map
│ │ │ │ │ │ ├── errors.js
│ │ │ │ │ │ ├── errors.js.map
│ │ │ │ │ │ ├── handlers
│ │ │ │ │ │ │ ├── authorize.d.ts
│ │ │ │ │ │ │ ├── authorize.d.ts.map
│ │ │ │ │ │ │ ├── authorize.js
│ │ │ │ │ │ │ ├── authorize.js.map
│ │ │ │ │ │ │ ├── metadata.d.ts
│ │ │ │ │ │ │ ├── metadata.d.ts.map
│ │ │ │ │ │ │ ├── metadata.js
│ │ │ │ │ │ │ ├── metadata.js.map
│ │ │ │ │ │ │ ├── register.d.ts
│ │ │ │ │ │ │ ├── register.d.ts.map
│ │ │ │ │ │ │ ├── register.js
│ │ │ │ │ │ │ ├── register.js.map
│ │ │ │ │ │ │ ├── revoke.d.ts
│ │ │ │ │ │ │ ├── revoke.d.ts.map
│ │ │ │ │ │ │ ├── revoke.js
│ │ │ │ │ │ │ ├── revoke.js.map
│ │ │ │ │ │ │ ├── token.d.ts
│ │ │ │ │ │ │ ├── token.d.ts.map
│ │ │ │ │ │ │ ├── token.js
│ │ │ │ │ │ │ └── token.js.map
│ │ │ │ │ │ ├── middleware
│ │ │ │ │ │ │ ├── allowedMethods.d.ts
│ │ │ │ │ │ │ ├── allowedMethods.d.ts.map
│ │ │ │ │ │ │ ├── allowedMethods.js
│ │ │ │ │ │ │ ├── allowedMethods.js.map
│ │ │ │ │ │ │ ├── bearerAuth.d.ts
│ │ │ │ │ │ │ ├── bearerAuth.d.ts.map
│ │ │ │ │ │ │ ├── bearerAuth.js
│ │ │ │ │ │ │ ├── bearerAuth.js.map
│ │ │ │ │ │ │ ├── clientAuth.d.ts
│ │ │ │ │ │ │ ├── clientAuth.d.ts.map
│ │ │ │ │ │ │ ├── clientAuth.js
│ │ │ │ │ │ │ └── clientAuth.js.map
│ │ │ │ │ │ ├── provider.d.ts
│ │ │ │ │ │ ├── provider.d.ts.map
│ │ │ │ │ │ ├── provider.js
│ │ │ │ │ │ ├── provider.js.map
│ │ │ │ │ │ ├── router.d.ts
│ │ │ │ │ │ ├── router.d.ts.map
│ │ │ │ │ │ ├── router.js
│ │ │ │ │ │ ├── router.js.map
│ │ │ │ │ │ ├── types.d.ts
│ │ │ │ │ │ ├── types.d.ts.map
│ │ │ │ │ │ ├── types.js
│ │ │ │ │ │ └── types.js.map
│ │ │ │ │ ├── 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
│ │ │ │ │ ├── auth.d.ts
│ │ │ │ │ ├── auth.d.ts.map
│ │ │ │ │ ├── auth.js
│ │ │ │ │ ├── auth.js.map
│ │ │ │ │ ├── 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
│ │ │ │ ├── auth.d.ts
│ │ │ │ ├── auth.d.ts.map
│ │ │ │ ├── auth.js
│ │ │ │ ├── auth.js.map
│ │ │ │ ├── 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
│ │ │ │ ├── auth
│ │ │ │ │ ├── clients.d.ts
│ │ │ │ │ ├── clients.d.ts.map
│ │ │ │ │ ├── clients.js
│ │ │ │ │ ├── clients.js.map
│ │ │ │ │ ├── errors.d.ts
│ │ │ │ │ ├── errors.d.ts.map
│ │ │ │ │ ├── errors.js
│ │ │ │ │ ├── errors.js.map
│ │ │ │ │ ├── handlers
│ │ │ │ │ │ ├── authorize.d.ts
│ │ │ │ │ │ ├── authorize.d.ts.map
│ │ │ │ │ │ ├── authorize.js
│ │ │ │ │ │ ├── authorize.js.map
│ │ │ │ │ │ ├── metadata.d.ts
│ │ │ │ │ │ ├── metadata.d.ts.map
│ │ │ │ │ │ ├── metadata.js
│ │ │ │ │ │ ├── metadata.js.map
│ │ │ │ │ │ ├── register.d.ts
│ │ │ │ │ │ ├── register.d.ts.map
│ │ │ │ │ │ ├── register.js
│ │ │ │ │ │ ├── register.js.map
│ │ │ │ │ │ ├── revoke.d.ts
│ │ │ │ │ │ ├── revoke.d.ts.map
│ │ │ │ │ │ ├── revoke.js
│ │ │ │ │ │ ├── revoke.js.map
│ │ │ │ │ │ ├── token.d.ts
│ │ │ │ │ │ ├── token.d.ts.map
│ │ │ │ │ │ ├── token.js
│ │ │ │ │ │ └── token.js.map
│ │ │ │ │ ├── middleware
│ │ │ │ │ │ ├── allowedMethods.d.ts
│ │ │ │ │ │ ├── allowedMethods.d.ts.map
│ │ │ │ │ │ ├── allowedMethods.js
│ │ │ │ │ │ ├── allowedMethods.js.map
│ │ │ │ │ │ ├── bearerAuth.d.ts
│ │ │ │ │ │ ├── bearerAuth.d.ts.map
│ │ │ │ │ │ ├── bearerAuth.js
│ │ │ │ │ │ ├── bearerAuth.js.map
│ │ │ │ │ │ ├── clientAuth.d.ts
│ │ │ │ │ │ ├── clientAuth.d.ts.map
│ │ │ │ │ │ ├── clientAuth.js
│ │ │ │ │ │ └── clientAuth.js.map
│ │ │ │ │ ├── provider.d.ts
│ │ │ │ │ ├── provider.d.ts.map
│ │ │ │ │ ├── provider.js
│ │ │ │ │ ├── provider.js.map
│ │ │ │ │ ├── router.d.ts
│ │ │ │ │ ├── router.d.ts.map
│ │ │ │ │ ├── router.js
│ │ │ │ │ ├── router.js.map
│ │ │ │ │ ├── types.d.ts
│ │ │ │ │ ├── types.d.ts.map
│ │ │ │ │ ├── types.js
│ │ │ │ │ └── types.js.map
│ │ │ │ ├── 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
│ │ │ │ ├── auth.d.ts
│ │ │ │ ├── auth.d.ts.map
│ │ │ │ ├── auth.js
│ │ │ │ ├── auth.js.map
│ │ │ │ ├── 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
│ │ │ ├── accepts
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.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
│ │ │ │ ├── node_modules
│ │ │ │ │ ├── debug
│ │ │ │ │ │ ├── LICENSE
│ │ │ │ │ │ ├── package.json
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── src
│ │ │ │ │ │ ├── browser.js
│ │ │ │ │ │ ├── common.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── node.js
│ │ │ │ │ ├── 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
│ │ │ │ │ │ │ ├── utf32.js
│ │ │ │ │ │ │ └── utf7.js
│ │ │ │ │ │ ├── lib
│ │ │ │ │ │ │ ├── bom-handling.js
│ │ │ │ │ │ │ ├── extend-node.js
│ │ │ │ │ │ │ ├── index.d.ts
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── streams.js
│ │ │ │ │ │ ├── LICENSE
│ │ │ │ │ │ ├── package.json
│ │ │ │ │ │ └── README.md
│ │ │ │ │ ├── ms
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── license.md
│ │ │ │ │ │ ├── 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
│ │ │ │ ├── package.json
│ │ │ │ ├── README.md
│ │ │ │ └── SECURITY.md
│ │ │ ├── content-disposition
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── cookie-signature
│ │ │ │ ├── History.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ └── Readme.md
│ │ │ ├── debug
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ ├── README.md
│ │ │ │ └── src
│ │ │ │ ├── browser.js
│ │ │ │ ├── common.js
│ │ │ │ ├── index.js
│ │ │ │ └── node.js
│ │ │ ├── express
│ │ │ │ ├── History.md
│ │ │ │ ├── index.js
│ │ │ │ ├── lib
│ │ │ │ │ ├── application.js
│ │ │ │ │ ├── express.js
│ │ │ │ │ ├── request.js
│ │ │ │ │ ├── response.js
│ │ │ │ │ ├── utils.js
│ │ │ │ │ └── view.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ └── Readme.md
│ │ │ ├── finalhandler
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── node_modules
│ │ │ │ │ ├── debug
│ │ │ │ │ │ ├── LICENSE
│ │ │ │ │ │ ├── package.json
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── src
│ │ │ │ │ │ ├── browser.js
│ │ │ │ │ │ ├── common.js
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ └── node.js
│ │ │ │ │ └── ms
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── license.md
│ │ │ │ │ ├── package.json
│ │ │ │ │ └── readme.md
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── fresh
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── media-typer
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── merge-descriptors
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── license
│ │ │ │ ├── package.json
│ │ │ │ └── readme.md
│ │ │ ├── mime-db
│ │ │ │ ├── db.json
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ ├── mime-types
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── mimeScore.js
│ │ │ │ ├── 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
│ │ │ ├── raw-body
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ ├── README.md
│ │ │ │ └── SECURITY.md
│ │ │ ├── send
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── node_modules
│ │ │ │ │ ├── fresh
│ │ │ │ │ │ ├── HISTORY.md
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── LICENSE
│ │ │ │ │ │ ├── package.json
│ │ │ │ │ │ └── README.md
│ │ │ │ │ ├── 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
│ │ │ │ ├── package.json
│ │ │ │ ├── README.md
│ │ │ │ └── SECURITY.md
│ │ │ ├── serve-static
│ │ │ │ ├── HISTORY.md
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── package.json
│ │ │ │ └── README.md
│ │ │ └── type-is
│ │ │ ├── HISTORY.md
│ │ │ ├── index.js
│ │ │ ├── LICENSE
│ │ │ ├── package.json
│ │ │ └── README.md
│ │ ├── package.json
│ │ └── README.md
│ ├── accepts
│ │ ├── HISTORY.md
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── ansi-regex
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── license
│ │ ├── package.json
│ │ └── readme.md
│ ├── ansi-styles
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── license
│ │ ├── 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
│ │ ├── node_modules
│ │ │ └── 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
│ │ ├── package.json
│ │ ├── README.md
│ │ └── SECURITY.md
│ ├── boolbase
│ │ ├── index.js
│ │ ├── package.json
│ │ └── README.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
│ ├── cheerio
│ │ ├── dist
│ │ │ ├── browser
│ │ │ │ ├── api
│ │ │ │ │ ├── attributes.d.ts
│ │ │ │ │ ├── attributes.d.ts.map
│ │ │ │ │ ├── attributes.js
│ │ │ │ │ ├── attributes.js.map
│ │ │ │ │ ├── css.d.ts
│ │ │ │ │ ├── css.d.ts.map
│ │ │ │ │ ├── css.js
│ │ │ │ │ ├── css.js.map
│ │ │ │ │ ├── extract.d.ts
│ │ │ │ │ ├── extract.d.ts.map
│ │ │ │ │ ├── extract.js
│ │ │ │ │ ├── extract.js.map
│ │ │ │ │ ├── forms.d.ts
│ │ │ │ │ ├── forms.d.ts.map
│ │ │ │ │ ├── forms.js
│ │ │ │ │ ├── forms.js.map
│ │ │ │ │ ├── manipulation.d.ts
│ │ │ │ │ ├── manipulation.d.ts.map
│ │ │ │ │ ├── manipulation.js
│ │ │ │ │ ├── manipulation.js.map
│ │ │ │ │ ├── traversing.d.ts
│ │ │ │ │ ├── traversing.d.ts.map
│ │ │ │ │ ├── traversing.js
│ │ │ │ │ └── traversing.js.map
│ │ │ │ ├── cheerio.d.ts
│ │ │ │ ├── cheerio.d.ts.map
│ │ │ │ ├── cheerio.js
│ │ │ │ ├── cheerio.js.map
│ │ │ │ ├── index-browser.d.mts.map
│ │ │ │ ├── index-browser.mjs.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── load-parse.d.ts
│ │ │ │ ├── load-parse.d.ts.map
│ │ │ │ ├── load-parse.js
│ │ │ │ ├── load-parse.js.map
│ │ │ │ ├── load.d.ts
│ │ │ │ ├── load.d.ts.map
│ │ │ │ ├── load.js
│ │ │ │ ├── load.js.map
│ │ │ │ ├── options.d.ts
│ │ │ │ ├── options.d.ts.map
│ │ │ │ ├── options.js
│ │ │ │ ├── options.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── parse.d.ts
│ │ │ │ ├── parse.d.ts.map
│ │ │ │ ├── parse.js
│ │ │ │ ├── parse.js.map
│ │ │ │ ├── parsers
│ │ │ │ │ ├── parse5-adapter.d.ts
│ │ │ │ │ ├── parse5-adapter.d.ts.map
│ │ │ │ │ ├── parse5-adapter.js
│ │ │ │ │ └── parse5-adapter.js.map
│ │ │ │ ├── slim.d.ts
│ │ │ │ ├── slim.d.ts.map
│ │ │ │ ├── slim.js
│ │ │ │ ├── slim.js.map
│ │ │ │ ├── static.d.ts
│ │ │ │ ├── static.d.ts.map
│ │ │ │ ├── static.js
│ │ │ │ ├── static.js.map
│ │ │ │ ├── types.d.ts
│ │ │ │ ├── types.d.ts.map
│ │ │ │ ├── types.js
│ │ │ │ ├── types.js.map
│ │ │ │ ├── utils.d.ts
│ │ │ │ ├── utils.d.ts.map
│ │ │ │ ├── utils.js
│ │ │ │ └── utils.js.map
│ │ │ ├── commonjs
│ │ │ │ ├── api
│ │ │ │ │ ├── attributes.d.ts
│ │ │ │ │ ├── attributes.d.ts.map
│ │ │ │ │ ├── attributes.js
│ │ │ │ │ ├── attributes.js.map
│ │ │ │ │ ├── css.d.ts
│ │ │ │ │ ├── css.d.ts.map
│ │ │ │ │ ├── css.js
│ │ │ │ │ ├── css.js.map
│ │ │ │ │ ├── extract.d.ts
│ │ │ │ │ ├── extract.d.ts.map
│ │ │ │ │ ├── extract.js
│ │ │ │ │ ├── extract.js.map
│ │ │ │ │ ├── forms.d.ts
│ │ │ │ │ ├── forms.d.ts.map
│ │ │ │ │ ├── forms.js
│ │ │ │ │ ├── forms.js.map
│ │ │ │ │ ├── manipulation.d.ts
│ │ │ │ │ ├── manipulation.d.ts.map
│ │ │ │ │ ├── manipulation.js
│ │ │ │ │ ├── manipulation.js.map
│ │ │ │ │ ├── traversing.d.ts
│ │ │ │ │ ├── traversing.d.ts.map
│ │ │ │ │ ├── traversing.js
│ │ │ │ │ └── traversing.js.map
│ │ │ │ ├── cheerio.d.ts
│ │ │ │ ├── cheerio.d.ts.map
│ │ │ │ ├── cheerio.js
│ │ │ │ ├── cheerio.js.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── load-parse.d.ts
│ │ │ │ ├── load-parse.d.ts.map
│ │ │ │ ├── load-parse.js
│ │ │ │ ├── load-parse.js.map
│ │ │ │ ├── load.d.ts
│ │ │ │ ├── load.d.ts.map
│ │ │ │ ├── load.js
│ │ │ │ ├── load.js.map
│ │ │ │ ├── options.d.ts
│ │ │ │ ├── options.d.ts.map
│ │ │ │ ├── options.js
│ │ │ │ ├── options.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── parse.d.ts
│ │ │ │ ├── parse.d.ts.map
│ │ │ │ ├── parse.js
│ │ │ │ ├── parse.js.map
│ │ │ │ ├── parsers
│ │ │ │ │ ├── parse5-adapter.d.ts
│ │ │ │ │ ├── parse5-adapter.d.ts.map
│ │ │ │ │ ├── parse5-adapter.js
│ │ │ │ │ └── parse5-adapter.js.map
│ │ │ │ ├── slim.d.ts
│ │ │ │ ├── slim.d.ts.map
│ │ │ │ ├── slim.js
│ │ │ │ ├── slim.js.map
│ │ │ │ ├── static.d.ts
│ │ │ │ ├── static.d.ts.map
│ │ │ │ ├── static.js
│ │ │ │ ├── static.js.map
│ │ │ │ ├── types.d.ts
│ │ │ │ ├── types.d.ts.map
│ │ │ │ ├── types.js
│ │ │ │ ├── types.js.map
│ │ │ │ ├── utils.d.ts
│ │ │ │ ├── utils.d.ts.map
│ │ │ │ ├── utils.js
│ │ │ │ └── utils.js.map
│ │ │ └── esm
│ │ │ ├── api
│ │ │ │ ├── attributes.d.ts
│ │ │ │ ├── attributes.d.ts.map
│ │ │ │ ├── attributes.js
│ │ │ │ ├── attributes.js.map
│ │ │ │ ├── css.d.ts
│ │ │ │ ├── css.d.ts.map
│ │ │ │ ├── css.js
│ │ │ │ ├── css.js.map
│ │ │ │ ├── extract.d.ts
│ │ │ │ ├── extract.d.ts.map
│ │ │ │ ├── extract.js
│ │ │ │ ├── extract.js.map
│ │ │ │ ├── forms.d.ts
│ │ │ │ ├── forms.d.ts.map
│ │ │ │ ├── forms.js
│ │ │ │ ├── forms.js.map
│ │ │ │ ├── manipulation.d.ts
│ │ │ │ ├── manipulation.d.ts.map
│ │ │ │ ├── manipulation.js
│ │ │ │ ├── manipulation.js.map
│ │ │ │ ├── traversing.d.ts
│ │ │ │ ├── traversing.d.ts.map
│ │ │ │ ├── traversing.js
│ │ │ │ └── traversing.js.map
│ │ │ ├── cheerio.d.ts
│ │ │ ├── cheerio.d.ts.map
│ │ │ ├── cheerio.js
│ │ │ ├── cheerio.js.map
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ │ ├── load-parse.d.ts
│ │ │ ├── load-parse.d.ts.map
│ │ │ ├── load-parse.js
│ │ │ ├── load-parse.js.map
│ │ │ ├── load.d.ts
│ │ │ ├── load.d.ts.map
│ │ │ ├── load.js
│ │ │ ├── load.js.map
│ │ │ ├── options.d.ts
│ │ │ ├── options.d.ts.map
│ │ │ ├── options.js
│ │ │ ├── options.js.map
│ │ │ ├── package.json
│ │ │ ├── parse.d.ts
│ │ │ ├── parse.d.ts.map
│ │ │ ├── parse.js
│ │ │ ├── parse.js.map
│ │ │ ├── parsers
│ │ │ │ ├── parse5-adapter.d.ts
│ │ │ │ ├── parse5-adapter.d.ts.map
│ │ │ │ ├── parse5-adapter.js
│ │ │ │ └── parse5-adapter.js.map
│ │ │ ├── slim.d.ts
│ │ │ ├── slim.d.ts.map
│ │ │ ├── slim.js
│ │ │ ├── slim.js.map
│ │ │ ├── static.d.ts
│ │ │ ├── static.d.ts.map
│ │ │ ├── static.js
│ │ │ ├── static.js.map
│ │ │ ├── types.d.ts
│ │ │ ├── types.d.ts.map
│ │ │ ├── types.js
│ │ │ ├── types.js.map
│ │ │ ├── utils.d.ts
│ │ │ ├── utils.d.ts.map
│ │ │ ├── utils.js
│ │ │ └── utils.js.map
│ │ ├── LICENSE
│ │ ├── package.json
│ │ ├── Readme.md
│ │ └── src
│ │ ├── __fixtures__
│ │ │ └── fixtures.ts
│ │ ├── __tests__
│ │ │ ├── deprecated.spec.ts
│ │ │ └── xml.spec.ts
│ │ ├── api
│ │ │ ├── attributes.spec.ts
│ │ │ ├── attributes.ts
│ │ │ ├── css.spec.ts
│ │ │ ├── css.ts
│ │ │ ├── extract.spec.ts
│ │ │ ├── extract.ts
│ │ │ ├── forms.spec.ts
│ │ │ ├── forms.ts
│ │ │ ├── manipulation.spec.ts
│ │ │ ├── manipulation.ts
│ │ │ ├── traversing.spec.ts
│ │ │ └── traversing.ts
│ │ ├── cheerio.spec.ts
│ │ ├── cheerio.ts
│ │ ├── index-browser.mts
│ │ ├── index.spec.ts
│ │ ├── index.ts
│ │ ├── load-parse.ts
│ │ ├── load.spec.ts
│ │ ├── load.ts
│ │ ├── options.ts
│ │ ├── parse.spec.ts
│ │ ├── parse.ts
│ │ ├── parsers
│ │ │ └── parse5-adapter.ts
│ │ ├── slim.ts
│ │ ├── static.spec.ts
│ │ ├── static.ts
│ │ ├── types.ts
│ │ ├── utils.spec.ts
│ │ └── utils.ts
│ ├── cheerio-select
│ │ ├── lib
│ │ │ ├── esm
│ │ │ │ ├── helpers.d.ts
│ │ │ │ ├── helpers.d.ts.map
│ │ │ │ ├── helpers.js
│ │ │ │ ├── helpers.js.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── positionals.d.ts
│ │ │ │ ├── positionals.d.ts.map
│ │ │ │ ├── positionals.js
│ │ │ │ └── positionals.js.map
│ │ │ ├── helpers.d.ts
│ │ │ ├── helpers.d.ts.map
│ │ │ ├── helpers.js
│ │ │ ├── helpers.js.map
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ │ ├── positionals.d.ts
│ │ │ ├── positionals.d.ts.map
│ │ │ ├── positionals.js
│ │ │ └── positionals.js.map
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── cliui
│ │ ├── build
│ │ │ ├── index.cjs
│ │ │ ├── index.d.cts
│ │ │ └── lib
│ │ │ ├── index.js
│ │ │ └── string-utils.js
│ │ ├── CHANGELOG.md
│ │ ├── index.mjs
│ │ ├── LICENSE.txt
│ │ ├── package.json
│ │ └── README.md
│ ├── color-convert
│ │ ├── CHANGELOG.md
│ │ ├── conversions.js
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ ├── README.md
│ │ └── route.js
│ ├── color-name
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── 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
│ ├── cors
│ │ ├── CONTRIBUTING.md
│ │ ├── HISTORY.md
│ │ ├── lib
│ │ │ └── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── css-select
│ │ ├── lib
│ │ │ ├── attributes.d.ts
│ │ │ ├── attributes.d.ts.map
│ │ │ ├── attributes.js
│ │ │ ├── attributes.js.map
│ │ │ ├── compile.d.ts
│ │ │ ├── compile.d.ts.map
│ │ │ ├── compile.js
│ │ │ ├── compile.js.map
│ │ │ ├── esm
│ │ │ │ ├── attributes.d.ts
│ │ │ │ ├── attributes.d.ts.map
│ │ │ │ ├── attributes.js
│ │ │ │ ├── attributes.js.map
│ │ │ │ ├── compile.d.ts
│ │ │ │ ├── compile.d.ts.map
│ │ │ │ ├── compile.js
│ │ │ │ ├── compile.js.map
│ │ │ │ ├── general.d.ts
│ │ │ │ ├── general.d.ts.map
│ │ │ │ ├── general.js
│ │ │ │ ├── general.js.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── pseudo-selectors
│ │ │ │ │ ├── aliases.d.ts
│ │ │ │ │ ├── aliases.d.ts.map
│ │ │ │ │ ├── aliases.js
│ │ │ │ │ ├── aliases.js.map
│ │ │ │ │ ├── filters.d.ts
│ │ │ │ │ ├── filters.d.ts.map
│ │ │ │ │ ├── filters.js
│ │ │ │ │ ├── filters.js.map
│ │ │ │ │ ├── index.d.ts
│ │ │ │ │ ├── index.d.ts.map
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── index.js.map
│ │ │ │ │ ├── pseudos.d.ts
│ │ │ │ │ ├── pseudos.d.ts.map
│ │ │ │ │ ├── pseudos.js
│ │ │ │ │ ├── pseudos.js.map
│ │ │ │ │ ├── subselects.d.ts
│ │ │ │ │ ├── subselects.d.ts.map
│ │ │ │ │ ├── subselects.js
│ │ │ │ │ └── subselects.js.map
│ │ │ │ ├── sort.d.ts
│ │ │ │ ├── sort.d.ts.map
│ │ │ │ ├── sort.js
│ │ │ │ ├── sort.js.map
│ │ │ │ ├── types.d.ts
│ │ │ │ ├── types.d.ts.map
│ │ │ │ ├── types.js
│ │ │ │ └── types.js.map
│ │ │ ├── general.d.ts
│ │ │ ├── general.d.ts.map
│ │ │ ├── general.js
│ │ │ ├── general.js.map
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ │ ├── pseudo-selectors
│ │ │ │ ├── aliases.d.ts
│ │ │ │ ├── aliases.d.ts.map
│ │ │ │ ├── aliases.js
│ │ │ │ ├── aliases.js.map
│ │ │ │ ├── filters.d.ts
│ │ │ │ ├── filters.d.ts.map
│ │ │ │ ├── filters.js
│ │ │ │ ├── filters.js.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── pseudos.d.ts
│ │ │ │ ├── pseudos.d.ts.map
│ │ │ │ ├── pseudos.js
│ │ │ │ ├── pseudos.js.map
│ │ │ │ ├── subselects.d.ts
│ │ │ │ ├── subselects.d.ts.map
│ │ │ │ ├── subselects.js
│ │ │ │ └── subselects.js.map
│ │ │ ├── sort.d.ts
│ │ │ ├── sort.d.ts.map
│ │ │ ├── sort.js
│ │ │ ├── sort.js.map
│ │ │ ├── types.d.ts
│ │ │ ├── types.d.ts.map
│ │ │ ├── types.js
│ │ │ └── types.js.map
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── css-what
│ │ ├── lib
│ │ │ ├── commonjs
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── parse.d.ts
│ │ │ │ ├── parse.d.ts.map
│ │ │ │ ├── parse.js
│ │ │ │ ├── stringify.d.ts
│ │ │ │ ├── stringify.d.ts.map
│ │ │ │ ├── stringify.js
│ │ │ │ ├── types.d.ts
│ │ │ │ ├── types.d.ts.map
│ │ │ │ └── types.js
│ │ │ └── es
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── parse.d.ts
│ │ │ ├── parse.d.ts.map
│ │ │ ├── parse.js
│ │ │ ├── stringify.d.ts
│ │ │ ├── stringify.d.ts.map
│ │ │ ├── stringify.js
│ │ │ ├── types.d.ts
│ │ │ ├── types.d.ts.map
│ │ │ └── types.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
│ ├── dom-serializer
│ │ ├── lib
│ │ │ ├── esm
│ │ │ │ ├── foreignNames.d.ts
│ │ │ │ ├── foreignNames.d.ts.map
│ │ │ │ ├── foreignNames.js
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ ├── foreignNames.d.ts
│ │ │ ├── foreignNames.d.ts.map
│ │ │ ├── foreignNames.js
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ └── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── domelementtype
│ │ ├── lib
│ │ │ ├── esm
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ └── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── readme.md
│ ├── domhandler
│ │ ├── lib
│ │ │ ├── esm
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── node.d.ts
│ │ │ │ ├── node.d.ts.map
│ │ │ │ ├── node.js
│ │ │ │ └── package.json
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── node.d.ts
│ │ │ ├── node.d.ts.map
│ │ │ └── node.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── readme.md
│ ├── domutils
│ │ ├── lib
│ │ │ ├── esm
│ │ │ │ ├── feeds.d.ts
│ │ │ │ ├── feeds.d.ts.map
│ │ │ │ ├── feeds.js
│ │ │ │ ├── feeds.js.map
│ │ │ │ ├── helpers.d.ts
│ │ │ │ ├── helpers.d.ts.map
│ │ │ │ ├── helpers.js
│ │ │ │ ├── helpers.js.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── legacy.d.ts
│ │ │ │ ├── legacy.d.ts.map
│ │ │ │ ├── legacy.js
│ │ │ │ ├── legacy.js.map
│ │ │ │ ├── manipulation.d.ts
│ │ │ │ ├── manipulation.d.ts.map
│ │ │ │ ├── manipulation.js
│ │ │ │ ├── manipulation.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── querying.d.ts
│ │ │ │ ├── querying.d.ts.map
│ │ │ │ ├── querying.js
│ │ │ │ ├── querying.js.map
│ │ │ │ ├── stringify.d.ts
│ │ │ │ ├── stringify.d.ts.map
│ │ │ │ ├── stringify.js
│ │ │ │ ├── stringify.js.map
│ │ │ │ ├── traversal.d.ts
│ │ │ │ ├── traversal.d.ts.map
│ │ │ │ ├── traversal.js
│ │ │ │ └── traversal.js.map
│ │ │ ├── feeds.d.ts
│ │ │ ├── feeds.d.ts.map
│ │ │ ├── feeds.js
│ │ │ ├── feeds.js.map
│ │ │ ├── helpers.d.ts
│ │ │ ├── helpers.d.ts.map
│ │ │ ├── helpers.js
│ │ │ ├── helpers.js.map
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ │ ├── legacy.d.ts
│ │ │ ├── legacy.d.ts.map
│ │ │ ├── legacy.js
│ │ │ ├── legacy.js.map
│ │ │ ├── manipulation.d.ts
│ │ │ ├── manipulation.d.ts.map
│ │ │ ├── manipulation.js
│ │ │ ├── manipulation.js.map
│ │ │ ├── querying.d.ts
│ │ │ ├── querying.d.ts.map
│ │ │ ├── querying.js
│ │ │ ├── querying.js.map
│ │ │ ├── stringify.d.ts
│ │ │ ├── stringify.d.ts.map
│ │ │ ├── stringify.js
│ │ │ ├── stringify.js.map
│ │ │ ├── traversal.d.ts
│ │ │ ├── traversal.d.ts.map
│ │ │ ├── traversal.js
│ │ │ └── traversal.js.map
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── readme.md
│ ├── 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
│ ├── emoji-regex
│ │ ├── es2015
│ │ │ ├── index.js
│ │ │ └── text.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── LICENSE-MIT.txt
│ │ ├── package.json
│ │ ├── README.md
│ │ └── text.js
│ ├── encodeurl
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── encoding-sniffer
│ │ ├── dist
│ │ │ ├── commonjs
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── sniffer.d.ts
│ │ │ │ ├── sniffer.d.ts.map
│ │ │ │ ├── sniffer.js
│ │ │ │ └── sniffer.js.map
│ │ │ └── esm
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ │ ├── package.json
│ │ │ ├── sniffer.d.ts
│ │ │ ├── sniffer.d.ts.map
│ │ │ ├── sniffer.js
│ │ │ └── sniffer.js.map
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── entities
│ │ ├── lib
│ │ │ ├── decode_codepoint.d.ts
│ │ │ ├── decode_codepoint.d.ts.map
│ │ │ ├── decode_codepoint.js
│ │ │ ├── decode_codepoint.js.map
│ │ │ ├── decode.d.ts
│ │ │ ├── decode.d.ts.map
│ │ │ ├── decode.js
│ │ │ ├── decode.js.map
│ │ │ ├── encode.d.ts
│ │ │ ├── encode.d.ts.map
│ │ │ ├── encode.js
│ │ │ ├── encode.js.map
│ │ │ ├── escape.d.ts
│ │ │ ├── escape.d.ts.map
│ │ │ ├── escape.js
│ │ │ ├── escape.js.map
│ │ │ ├── esm
│ │ │ │ ├── decode_codepoint.d.ts
│ │ │ │ ├── decode_codepoint.d.ts.map
│ │ │ │ ├── decode_codepoint.js
│ │ │ │ ├── decode_codepoint.js.map
│ │ │ │ ├── decode.d.ts
│ │ │ │ ├── decode.d.ts.map
│ │ │ │ ├── decode.js
│ │ │ │ ├── decode.js.map
│ │ │ │ ├── encode.d.ts
│ │ │ │ ├── encode.d.ts.map
│ │ │ │ ├── encode.js
│ │ │ │ ├── encode.js.map
│ │ │ │ ├── escape.d.ts
│ │ │ │ ├── escape.d.ts.map
│ │ │ │ ├── escape.js
│ │ │ │ ├── escape.js.map
│ │ │ │ ├── generated
│ │ │ │ │ ├── decode-data-html.d.ts
│ │ │ │ │ ├── decode-data-html.d.ts.map
│ │ │ │ │ ├── decode-data-html.js
│ │ │ │ │ ├── decode-data-html.js.map
│ │ │ │ │ ├── decode-data-xml.d.ts
│ │ │ │ │ ├── decode-data-xml.d.ts.map
│ │ │ │ │ ├── decode-data-xml.js
│ │ │ │ │ ├── decode-data-xml.js.map
│ │ │ │ │ ├── encode-html.d.ts
│ │ │ │ │ ├── encode-html.d.ts.map
│ │ │ │ │ ├── encode-html.js
│ │ │ │ │ └── encode-html.js.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ └── package.json
│ │ │ ├── generated
│ │ │ │ ├── decode-data-html.d.ts
│ │ │ │ ├── decode-data-html.d.ts.map
│ │ │ │ ├── decode-data-html.js
│ │ │ │ ├── decode-data-html.js.map
│ │ │ │ ├── decode-data-xml.d.ts
│ │ │ │ ├── decode-data-xml.d.ts.map
│ │ │ │ ├── decode-data-xml.js
│ │ │ │ ├── decode-data-xml.js.map
│ │ │ │ ├── encode-html.d.ts
│ │ │ │ ├── encode-html.d.ts.map
│ │ │ │ ├── encode-html.js
│ │ │ │ └── encode-html.js.map
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ └── index.js.map
│ │ ├── 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
│ ├── escalade
│ │ ├── dist
│ │ │ ├── index.js
│ │ │ └── index.mjs
│ │ ├── index.d.mts
│ │ ├── index.d.ts
│ │ ├── license
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── sync
│ │ ├── index.d.mts
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ └── index.mjs
│ ├── 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
│ ├── express-rate-limit
│ │ ├── dist
│ │ │ ├── index.cjs
│ │ │ ├── index.d.cts
│ │ │ ├── index.d.mts
│ │ │ ├── index.d.ts
│ │ │ └── index.mjs
│ │ ├── license.md
│ │ ├── package.json
│ │ ├── readme.md
│ │ └── tsconfig.json
│ ├── 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
│ ├── 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-caller-file
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.js.map
│ │ ├── LICENSE.md
│ │ ├── package.json
│ │ └── README.md
│ ├── 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
│ ├── htmlparser2
│ │ ├── lib
│ │ │ ├── esm
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── Parser.d.ts
│ │ │ │ ├── Parser.d.ts.map
│ │ │ │ ├── Parser.js
│ │ │ │ ├── Parser.js.map
│ │ │ │ ├── Tokenizer.d.ts
│ │ │ │ ├── Tokenizer.d.ts.map
│ │ │ │ ├── Tokenizer.js
│ │ │ │ ├── Tokenizer.js.map
│ │ │ │ ├── WritableStream.d.ts
│ │ │ │ ├── WritableStream.d.ts.map
│ │ │ │ ├── WritableStream.js
│ │ │ │ └── WritableStream.js.map
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ │ ├── Parser.d.ts
│ │ │ ├── Parser.d.ts.map
│ │ │ ├── Parser.js
│ │ │ ├── Parser.js.map
│ │ │ ├── Tokenizer.d.ts
│ │ │ ├── Tokenizer.d.ts.map
│ │ │ ├── Tokenizer.js
│ │ │ ├── Tokenizer.js.map
│ │ │ ├── WritableStream.d.ts
│ │ │ ├── WritableStream.d.ts.map
│ │ │ ├── WritableStream.js
│ │ │ └── WritableStream.js.map
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── http-errors
│ │ ├── HISTORY.md
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── 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
│ ├── 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
│ ├── is-fullwidth-code-point
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── license
│ │ ├── package.json
│ │ └── readme.md
│ ├── is-promise
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.mjs
│ │ ├── 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
│ ├── nth-check
│ │ ├── lib
│ │ │ ├── compile.d.ts
│ │ │ ├── compile.d.ts.map
│ │ │ ├── compile.js
│ │ │ ├── compile.js.map
│ │ │ ├── esm
│ │ │ │ ├── compile.d.ts
│ │ │ │ ├── compile.d.ts.map
│ │ │ │ ├── compile.js
│ │ │ │ ├── compile.js.map
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.d.ts.map
│ │ │ │ ├── index.js
│ │ │ │ ├── index.js.map
│ │ │ │ ├── package.json
│ │ │ │ ├── parse.d.ts
│ │ │ │ ├── parse.d.ts.map
│ │ │ │ ├── parse.js
│ │ │ │ └── parse.js.map
│ │ │ ├── index.d.ts
│ │ │ ├── index.d.ts.map
│ │ │ ├── index.js
│ │ │ ├── index.js.map
│ │ │ ├── parse.d.ts
│ │ │ ├── parse.d.ts.map
│ │ │ ├── parse.js
│ │ │ └── parse.js.map
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── object-assign
│ │ ├── index.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
│ ├── once
│ │ ├── LICENSE
│ │ ├── once.js
│ │ ├── package.json
│ │ └── README.md
│ ├── parse5
│ │ ├── dist
│ │ │ ├── cjs
│ │ │ │ ├── common
│ │ │ │ │ ├── doctype.d.ts
│ │ │ │ │ ├── doctype.js
│ │ │ │ │ ├── error-codes.d.ts
│ │ │ │ │ ├── error-codes.js
│ │ │ │ │ ├── foreign-content.d.ts
│ │ │ │ │ ├── foreign-content.js
│ │ │ │ │ ├── html.d.ts
│ │ │ │ │ ├── html.js
│ │ │ │ │ ├── token.d.ts
│ │ │ │ │ ├── token.js
│ │ │ │ │ ├── unicode.d.ts
│ │ │ │ │ └── unicode.js
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── package.json
│ │ │ │ ├── parser
│ │ │ │ │ ├── formatting-element-list.d.ts
│ │ │ │ │ ├── formatting-element-list.js
│ │ │ │ │ ├── index.d.ts
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── open-element-stack.d.ts
│ │ │ │ │ └── open-element-stack.js
│ │ │ │ ├── serializer
│ │ │ │ │ ├── index.d.ts
│ │ │ │ │ └── index.js
│ │ │ │ ├── tokenizer
│ │ │ │ │ ├── index.d.ts
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── preprocessor.d.ts
│ │ │ │ │ └── preprocessor.js
│ │ │ │ └── tree-adapters
│ │ │ │ ├── default.d.ts
│ │ │ │ ├── default.js
│ │ │ │ ├── interface.d.ts
│ │ │ │ └── interface.js
│ │ │ ├── common
│ │ │ │ ├── doctype.d.ts
│ │ │ │ ├── doctype.js
│ │ │ │ ├── error-codes.d.ts
│ │ │ │ ├── error-codes.js
│ │ │ │ ├── foreign-content.d.ts
│ │ │ │ ├── foreign-content.js
│ │ │ │ ├── html.d.ts
│ │ │ │ ├── html.js
│ │ │ │ ├── token.d.ts
│ │ │ │ ├── token.js
│ │ │ │ ├── unicode.d.ts
│ │ │ │ └── unicode.js
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── parser
│ │ │ │ ├── formatting-element-list.d.ts
│ │ │ │ ├── formatting-element-list.js
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── open-element-stack.d.ts
│ │ │ │ └── open-element-stack.js
│ │ │ ├── serializer
│ │ │ │ ├── index.d.ts
│ │ │ │ └── index.js
│ │ │ ├── tokenizer
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── preprocessor.d.ts
│ │ │ │ └── preprocessor.js
│ │ │ └── tree-adapters
│ │ │ ├── default.d.ts
│ │ │ ├── default.js
│ │ │ ├── interface.d.ts
│ │ │ └── interface.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── parse5-htmlparser2-tree-adapter
│ │ ├── dist
│ │ │ ├── cjs
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ ├── index.d.ts
│ │ │ └── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── parse5-parser-stream
│ │ ├── dist
│ │ │ ├── cjs
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ └── package.json
│ │ │ ├── index.d.ts
│ │ │ └── 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
│ ├── pkce-challenge
│ │ ├── dist
│ │ │ ├── index.browser.d.ts
│ │ │ ├── index.browser.js
│ │ │ ├── index.node.d.ts
│ │ │ └── index.node.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── 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
│ │ ├── node_modules
│ │ │ └── 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
│ │ ├── package.json
│ │ ├── README.md
│ │ └── SECURITY.md
│ ├── require-directory
│ │ ├── .jshintrc
│ │ ├── .npmignore
│ │ ├── .travis.yml
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.markdown
│ ├── router
│ │ ├── HISTORY.md
│ │ ├── index.js
│ │ ├── lib
│ │ │ ├── layer.js
│ │ │ └── route.js
│ │ ├── LICENSE
│ │ ├── node_modules
│ │ │ └── path-to-regexp
│ │ │ ├── dist
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ └── index.js.map
│ │ │ ├── LICENSE
│ │ │ ├── package.json
│ │ │ └── Readme.md
│ │ ├── 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
│ ├── string-width
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── license
│ │ ├── package.json
│ │ └── readme.md
│ ├── strip-ansi
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── license
│ │ ├── package.json
│ │ └── readme.md
│ ├── supergateway
│ │ ├── dist
│ │ │ └── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── supergateway.png
│ │ └── tsconfig.json
│ ├── toidentifier
│ │ ├── HISTORY.md
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── type-is
│ │ ├── HISTORY.md
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── undici
│ │ ├── docs
│ │ │ └── docs
│ │ │ ├── api
│ │ │ │ ├── Agent.md
│ │ │ │ ├── api-lifecycle.md
│ │ │ │ ├── BalancedPool.md
│ │ │ │ ├── CacheStorage.md
│ │ │ │ ├── Client.md
│ │ │ │ ├── Connector.md
│ │ │ │ ├── ContentType.md
│ │ │ │ ├── Cookies.md
│ │ │ │ ├── Debug.md
│ │ │ │ ├── DiagnosticsChannel.md
│ │ │ │ ├── Dispatcher.md
│ │ │ │ ├── DispatchInterceptor.md
│ │ │ │ ├── EnvHttpProxyAgent.md
│ │ │ │ ├── Errors.md
│ │ │ │ ├── EventSource.md
│ │ │ │ ├── Fetch.md
│ │ │ │ ├── MockAgent.md
│ │ │ │ ├── MockClient.md
│ │ │ │ ├── MockErrors.md
│ │ │ │ ├── MockPool.md
│ │ │ │ ├── Pool.md
│ │ │ │ ├── PoolStats.md
│ │ │ │ ├── ProxyAgent.md
│ │ │ │ ├── RedirectHandler.md
│ │ │ │ ├── RetryAgent.md
│ │ │ │ ├── RetryHandler.md
│ │ │ │ ├── Util.md
│ │ │ │ └── WebSocket.md
│ │ │ └── best-practices
│ │ │ ├── client-certificate.md
│ │ │ ├── mocking-request.md
│ │ │ ├── proxy.md
│ │ │ └── writing-tests.md
│ │ ├── index-fetch.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── lib
│ │ │ ├── api
│ │ │ │ ├── abort-signal.js
│ │ │ │ ├── api-connect.js
│ │ │ │ ├── api-pipeline.js
│ │ │ │ ├── api-request.js
│ │ │ │ ├── api-stream.js
│ │ │ │ ├── api-upgrade.js
│ │ │ │ ├── index.js
│ │ │ │ ├── readable.js
│ │ │ │ └── util.js
│ │ │ ├── core
│ │ │ │ ├── connect.js
│ │ │ │ ├── constants.js
│ │ │ │ ├── diagnostics.js
│ │ │ │ ├── errors.js
│ │ │ │ ├── request.js
│ │ │ │ ├── symbols.js
│ │ │ │ ├── tree.js
│ │ │ │ └── util.js
│ │ │ ├── dispatcher
│ │ │ │ ├── agent.js
│ │ │ │ ├── balanced-pool.js
│ │ │ │ ├── client-h1.js
│ │ │ │ ├── client-h2.js
│ │ │ │ ├── client.js
│ │ │ │ ├── dispatcher-base.js
│ │ │ │ ├── dispatcher.js
│ │ │ │ ├── env-http-proxy-agent.js
│ │ │ │ ├── fixed-queue.js
│ │ │ │ ├── pool-base.js
│ │ │ │ ├── pool-stats.js
│ │ │ │ ├── pool.js
│ │ │ │ ├── proxy-agent.js
│ │ │ │ └── retry-agent.js
│ │ │ ├── global.js
│ │ │ ├── handler
│ │ │ │ ├── decorator-handler.js
│ │ │ │ ├── redirect-handler.js
│ │ │ │ └── retry-handler.js
│ │ │ ├── interceptor
│ │ │ │ ├── dns.js
│ │ │ │ ├── dump.js
│ │ │ │ ├── redirect-interceptor.js
│ │ │ │ ├── redirect.js
│ │ │ │ ├── response-error.js
│ │ │ │ └── retry.js
│ │ │ ├── llhttp
│ │ │ │ ├── .gitkeep
│ │ │ │ ├── constants.js
│ │ │ │ ├── llhttp_simd-wasm.js
│ │ │ │ ├── llhttp-wasm.js
│ │ │ │ └── utils.js
│ │ │ ├── mock
│ │ │ │ ├── mock-agent.js
│ │ │ │ ├── mock-client.js
│ │ │ │ ├── mock-errors.js
│ │ │ │ ├── mock-interceptor.js
│ │ │ │ ├── mock-pool.js
│ │ │ │ ├── mock-symbols.js
│ │ │ │ ├── mock-utils.js
│ │ │ │ ├── pending-interceptors-formatter.js
│ │ │ │ └── pluralizer.js
│ │ │ ├── util
│ │ │ │ └── timers.js
│ │ │ └── web
│ │ │ ├── cache
│ │ │ │ ├── cache.js
│ │ │ │ ├── cachestorage.js
│ │ │ │ ├── symbols.js
│ │ │ │ └── util.js
│ │ │ ├── cookies
│ │ │ │ ├── constants.js
│ │ │ │ ├── index.js
│ │ │ │ ├── parse.js
│ │ │ │ └── util.js
│ │ │ ├── eventsource
│ │ │ │ ├── eventsource-stream.js
│ │ │ │ ├── eventsource.js
│ │ │ │ └── util.js
│ │ │ ├── fetch
│ │ │ │ ├── body.js
│ │ │ │ ├── constants.js
│ │ │ │ ├── data-url.js
│ │ │ │ ├── dispatcher-weakref.js
│ │ │ │ ├── file.js
│ │ │ │ ├── formdata-parser.js
│ │ │ │ ├── formdata.js
│ │ │ │ ├── global.js
│ │ │ │ ├── headers.js
│ │ │ │ ├── index.js
│ │ │ │ ├── LICENSE
│ │ │ │ ├── request.js
│ │ │ │ ├── response.js
│ │ │ │ ├── symbols.js
│ │ │ │ ├── util.js
│ │ │ │ └── webidl.js
│ │ │ ├── fileapi
│ │ │ │ ├── encoding.js
│ │ │ │ ├── filereader.js
│ │ │ │ ├── progressevent.js
│ │ │ │ ├── symbols.js
│ │ │ │ └── util.js
│ │ │ └── websocket
│ │ │ ├── connection.js
│ │ │ ├── constants.js
│ │ │ ├── events.js
│ │ │ ├── frame.js
│ │ │ ├── permessage-deflate.js
│ │ │ ├── receiver.js
│ │ │ ├── sender.js
│ │ │ ├── symbols.js
│ │ │ ├── util.js
│ │ │ └── websocket.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── scripts
│ │ │ └── strip-comments.js
│ │ └── types
│ │ ├── agent.d.ts
│ │ ├── api.d.ts
│ │ ├── balanced-pool.d.ts
│ │ ├── cache.d.ts
│ │ ├── client.d.ts
│ │ ├── connector.d.ts
│ │ ├── content-type.d.ts
│ │ ├── cookies.d.ts
│ │ ├── diagnostics-channel.d.ts
│ │ ├── dispatcher.d.ts
│ │ ├── env-http-proxy-agent.d.ts
│ │ ├── errors.d.ts
│ │ ├── eventsource.d.ts
│ │ ├── fetch.d.ts
│ │ ├── file.d.ts
│ │ ├── filereader.d.ts
│ │ ├── formdata.d.ts
│ │ ├── global-dispatcher.d.ts
│ │ ├── global-origin.d.ts
│ │ ├── handlers.d.ts
│ │ ├── header.d.ts
│ │ ├── index.d.ts
│ │ ├── interceptors.d.ts
│ │ ├── mock-agent.d.ts
│ │ ├── mock-client.d.ts
│ │ ├── mock-errors.d.ts
│ │ ├── mock-interceptor.d.ts
│ │ ├── mock-pool.d.ts
│ │ ├── patch.d.ts
│ │ ├── pool-stats.d.ts
│ │ ├── pool.d.ts
│ │ ├── proxy-agent.d.ts
│ │ ├── readable.d.ts
│ │ ├── README.md
│ │ ├── retry-agent.d.ts
│ │ ├── retry-handler.d.ts
│ │ ├── util.d.ts
│ │ ├── webidl.d.ts
│ │ └── websocket.d.ts
│ ├── unpipe
│ │ ├── HISTORY.md
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── utils-merge
│ │ ├── .npmignore
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── vary
│ │ ├── HISTORY.md
│ │ ├── index.js
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── whatwg-encoding
│ │ ├── lib
│ │ │ ├── labels-to-names.json
│ │ │ ├── supported-names.json
│ │ │ └── whatwg-encoding.js
│ │ ├── LICENSE.txt
│ │ ├── package.json
│ │ └── README.md
│ ├── whatwg-mimetype
│ │ ├── lib
│ │ │ ├── mime-type-parameters.js
│ │ │ ├── mime-type.js
│ │ │ ├── parser.js
│ │ │ ├── serializer.js
│ │ │ └── utils.js
│ │ ├── LICENSE.txt
│ │ ├── package.json
│ │ └── README.md
│ ├── wrap-ansi
│ │ ├── index.js
│ │ ├── license
│ │ ├── package.json
│ │ └── readme.md
│ ├── wrappy
│ │ ├── LICENSE
│ │ ├── package.json
│ │ ├── README.md
│ │ └── wrappy.js
│ ├── y18n
│ │ ├── build
│ │ │ ├── index.cjs
│ │ │ └── lib
│ │ │ ├── cjs.js
│ │ │ ├── index.js
│ │ │ └── platform-shims
│ │ │ └── node.js
│ │ ├── CHANGELOG.md
│ │ ├── index.mjs
│ │ ├── LICENSE
│ │ ├── package.json
│ │ └── README.md
│ ├── yargs
│ │ ├── browser.d.ts
│ │ ├── browser.mjs
│ │ ├── build
│ │ │ ├── index.cjs
│ │ │ └── lib
│ │ │ ├── argsert.js
│ │ │ ├── command.js
│ │ │ ├── completion-templates.js
│ │ │ ├── completion.js
│ │ │ ├── middleware.js
│ │ │ ├── parse-command.js
│ │ │ ├── typings
│ │ │ │ ├── common-types.js
│ │ │ │ └── yargs-parser-types.js
│ │ │ ├── usage.js
│ │ │ ├── utils
│ │ │ │ ├── apply-extends.js
│ │ │ │ ├── is-promise.js
│ │ │ │ ├── levenshtein.js
│ │ │ │ ├── maybe-async-result.js
│ │ │ │ ├── obj-filter.js
│ │ │ │ ├── process-argv.js
│ │ │ │ ├── set-blocking.js
│ │ │ │ └── which-module.js
│ │ │ ├── validation.js
│ │ │ ├── yargs-factory.js
│ │ │ └── yerror.js
│ │ ├── helpers
│ │ │ ├── helpers.mjs
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── index.cjs
│ │ ├── index.mjs
│ │ ├── lib
│ │ │ └── platform-shims
│ │ │ ├── browser.mjs
│ │ │ └── esm.mjs
│ │ ├── LICENSE
│ │ ├── locales
│ │ │ ├── be.json
│ │ │ ├── cs.json
│ │ │ ├── de.json
│ │ │ ├── en.json
│ │ │ ├── es.json
│ │ │ ├── fi.json
│ │ │ ├── fr.json
│ │ │ ├── hi.json
│ │ │ ├── hu.json
│ │ │ ├── id.json
│ │ │ ├── it.json
│ │ │ ├── ja.json
│ │ │ ├── ko.json
│ │ │ ├── nb.json
│ │ │ ├── nl.json
│ │ │ ├── nn.json
│ │ │ ├── pirate.json
│ │ │ ├── pl.json
│ │ │ ├── pt_BR.json
│ │ │ ├── pt.json
│ │ │ ├── ru.json
│ │ │ ├── th.json
│ │ │ ├── tr.json
│ │ │ ├── uk_UA.json
│ │ │ ├── uz.json
│ │ │ ├── zh_CN.json
│ │ │ └── zh_TW.json
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── yargs
│ │ └── yargs.mjs
│ ├── yargs-parser
│ │ ├── browser.js
│ │ ├── build
│ │ │ ├── index.cjs
│ │ │ └── lib
│ │ │ ├── index.js
│ │ │ ├── string-utils.js
│ │ │ ├── tokenize-arg-string.js
│ │ │ ├── yargs-parser-types.js
│ │ │ └── yargs-parser.js
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.txt
│ │ ├── 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
│ │ ├── CR_logotype-full-color.png
│ │ └── 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
│ │ │ ├── parseTypes.js
│ │ │ ├── Refs.js
│ │ │ ├── selectParser.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
│ │ │ ├── parseTypes.js
│ │ │ ├── Refs.js
│ │ │ ├── selectParser.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
│ │ ├── parseTypes.d.ts
│ │ ├── Refs.d.ts
│ │ ├── selectParser.d.ts
│ │ └── zodToJsonSchema.d.ts
│ ├── dist-test
│ │ ├── cjs
│ │ │ ├── index.js
│ │ │ ├── node_modules
│ │ │ │ ├── .package-lock.json
│ │ │ │ └── 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
│ │ │ ├── package-lock.json
│ │ │ └── package.json
│ │ ├── esm
│ │ │ ├── index.js
│ │ │ ├── node_modules
│ │ │ │ ├── .package-lock.json
│ │ │ │ └── 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
│ │ │ ├── package-lock.json
│ │ │ └── package.json
│ │ ├── package.json
│ │ └── types
│ │ ├── index.ts
│ │ ├── node_modules
│ │ │ ├── .package-lock.json
│ │ │ └── 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
│ │ ├── package-lock.json
│ │ └── package.json
│ ├── LICENSE
│ ├── package.json
│ ├── postcjs.ts
│ ├── postesm.ts
│ ├── README.md
│ └── SECURITY.md
├── package-lock.json
├── package.json
├── README.md
├── run-mcp.sh
├── seo-mcp-server.js
├── seo-requirements.js
└── src
├── analyzers
│ ├── html-analyzer.js
│ └── keyword-analyzer.js
├── formatters
│ └── text-formatter.js
├── server.js
└── utils
└── file-utils.js
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
1 | # Dependencies
2 | /node_modules
3 | /.pnp
4 | .pnp.js
5 |
6 | # Testing
7 | /coverage
8 |
9 | # Production
10 | /build
11 | /dist
12 |
13 | # Misc
14 | .DS_Store
15 | .env
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | # Logs
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 | logs
26 | *.log
27 |
28 | # Editor directories and files
29 | .idea
30 | .vscode
31 | *.swp
32 | *.swo
33 | .DS_Store
34 |
35 | # OS generated files
36 | .DS_Store
37 | .DS_Store?
38 | ._*
39 | .Spotlight-V100
40 | .Trashes
41 | ehthumbs.db
42 | Thumbs.db
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
1 | // README.md - Instructions for setup and use
2 |
3 | # SEO Inspector & Schema Validator MCP
4 |
5 | A Model Context Protocol (MCP) server for Cursor that analyzes web pages for SEO issues and validates structured data schemas.
6 |
7 | ## Features
8 |
9 | - Analyze HTML files in a codebase for SEO issues
10 | - Validate JSON-LD structured data
11 | - Get recommendations to improve SEO
12 | - No browser extension required - works directly with your codebase
13 |
14 | ## Installation
15 |
16 | 1. Clone this repository:
17 |
18 | ```
19 | git clone https://github.com/yourusername/seo-inspector-mcp.git
20 | cd seo-inspector-mcp
21 | ```
22 |
23 | 2. Install dependencies:
24 |
25 | ```
26 | npm install
27 | ```
28 |
29 | 3. Configure Cursor to use this MCP server:
30 | - Go to Settings > Features > MCP in Cursor
31 | - Add a new MCP server with:
32 | - Name: SEO Inspector
33 | - Type: sse
34 | - URL: http://localhost:8767/sse
35 |
36 | ## Usage
37 |
38 | 1. Start the MCP server:
39 |
40 | ```
41 | ./run-mcp.sh
42 | ```
43 |
44 | 2. In Cursor, you can now use the SEO Inspector tools:
45 | - `seo.analyze-codebase` - Analyze HTML files in a directory
46 | - `seo.analyze-html` - Analyze a specific HTML string
47 |
48 | ## Prioritized SEO Components
49 |
50 | The tool checks for these key SEO elements (in order of importance):
51 |
52 | ### Critical
53 |
54 | - Page Title
55 | - Meta Description
56 | - H1 Heading
57 | - Canonical URL
58 |
59 | ### Important
60 |
61 | - Heading Structure (H2-H6)
62 | - Image Alt Text
63 | - Structured Data (JSON-LD)
64 | - Robots Directives
65 |
66 | ### Recommended
67 |
68 | - Open Graph Tags
69 | - Twitter Cards
70 | - Internal Linking
71 | - URL Structure
72 | - Mobile Friendliness
73 |
74 | ## Schema Validation
75 |
76 | The tool validates the following schema types:
77 |
78 | - Organization
79 | - LocalBusiness
80 | - Product
81 | - Article
82 | - WebPage
83 | - FAQPage
84 | - Event
85 | - Recipe
86 | - Review
87 |
88 | ## License
89 |
90 | MIT
91 |
```
--------------------------------------------------------------------------------
/.cursor/mcp.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "mcpServers": {
3 | "seo-inspector": {
4 | "url": "http://localhost:8768/sse"
5 | }
6 | }
7 | }
8 |
```
--------------------------------------------------------------------------------
/run-mcp.sh:
--------------------------------------------------------------------------------
```bash
1 | #!/bin/bash
2 | # Script to start the MCP server
3 | npx supergateway --port 8768 --stdio "node ./src/server.js"
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "name": "seo-inspector-mcp",
3 | "version": "1.0.0",
4 | "description": "SEO Inspector and Schema Validator MCP for Cursor",
5 | "main": "src/server.js",
6 | "type": "module",
7 | "scripts": {
8 | "start": "node src/server.js",
9 | "start-mcp": "npx supergateway --port 8768 --stdio \"node src/server.js\"",
10 | "seo-analysis": "npx supergateway --port 8768 --stdio \"node src/server.js\""
11 | },
12 | "dependencies": {
13 | "cheerio": "^1.0.0-rc.12",
14 | "cors": "^2.8.5",
15 | "express": "^4.18.2",
16 | "puppeteer": "^19.7.2",
17 | "supergateway": "*"
18 | }
19 | }
20 |
```
--------------------------------------------------------------------------------
/src/utils/file-utils.js:
--------------------------------------------------------------------------------
```javascript
1 | // src/utils/file-utils.js
2 | import fs from 'fs/promises';
3 | import path from 'path';
4 |
5 | export async function findHtmlFiles(directory) {
6 | const htmlFiles = [];
7 |
8 | // Check if directory exists first
9 | try {
10 | await fs.access(directory);
11 | } catch (error) {
12 | console.error(`Directory does not exist: ${directory}`);
13 | return htmlFiles; // Return empty array instead of crashing
14 | }
15 |
16 | async function traverse(dir) {
17 | try {
18 | const entries = await fs.readdir(dir, { withFileTypes: true });
19 |
20 | for (const entry of entries) {
21 | if (entry.name === 'node_modules' || entry.name === '.git') {
22 | continue;
23 | }
24 |
25 | const fullPath = path.join(dir, entry.name);
26 |
27 | if (entry.isDirectory()) {
28 | await traverse(fullPath);
29 | } else if (
30 | entry.name.endsWith('.html') ||
31 | entry.name.endsWith('.htm')
32 | ) {
33 | htmlFiles.push(fullPath);
34 | }
35 | }
36 | } catch (error) {
37 | console.error(`Error traversing ${dir}:`, error);
38 | // Continue execution instead of crashing
39 | }
40 | }
41 |
42 | await traverse(directory);
43 | return htmlFiles;
44 | }
45 |
```
--------------------------------------------------------------------------------
/mcp-tools.js:
--------------------------------------------------------------------------------
```javascript
1 | // mcp-tools.js - The interface for Cursor MCP
2 | const MCP_TOOLS = {
3 | namespace: 'seo',
4 | displayName: 'SEO Inspector',
5 | description: 'Analyze web pages for SEO issues and validate structured data',
6 | tools: [
7 | {
8 | name: 'analyze-codebase',
9 | description: 'Scan HTML files in a directory for SEO issues',
10 | parameters: {
11 | type: 'object',
12 | properties: {
13 | directoryPath: {
14 | type: 'string',
15 | description:
16 | 'Path to the directory containing HTML files to analyze',
17 | },
18 | },
19 | required: ['directoryPath'],
20 | },
21 | handler: async ({ directoryPath }) => {
22 | // This will be implemented in the MCP framework
23 | // The actual implementation is in the /analyze-codebase endpoint
24 | },
25 | },
26 | {
27 | name: 'analyze-html',
28 | description: 'Analyze a specific HTML string for SEO issues',
29 | parameters: {
30 | type: 'object',
31 | properties: {
32 | html: {
33 | type: 'string',
34 | description: 'HTML content to analyze',
35 | },
36 | url: {
37 | type: 'string',
38 | description: 'Optional URL for context',
39 | },
40 | },
41 | required: ['html'],
42 | },
43 | handler: async ({ html, url }) => {
44 | // This will be implemented in the MCP framework
45 | // The actual implementation is in the /analyze-html endpoint
46 | },
47 | },
48 | ],
49 | };
50 |
51 | module.exports = MCP_TOOLS;
52 |
```
--------------------------------------------------------------------------------
/src/formatters/text-formatter.js:
--------------------------------------------------------------------------------
```javascript
1 | // src/formatters/text-formatter.js
2 | export function formatAnalysisResult(result) {
3 | return `SEO ANALYSIS FOR: ${result.pageIdentifier}
4 |
5 | PAGE INFO:
6 | - Title: ${result.title || 'Missing'} (${
7 | result.title ? result.title.length : 0
8 | } chars)
9 | - Meta Description: ${result.metaDescription || 'Missing'} (${
10 | result.metaDescription ? result.metaDescription.length : 0
11 | } chars)
12 | - Heading Structure: H1: ${result.headingStructure.h1}, H2: ${
13 | result.headingStructure.h2
14 | }, H3: ${result.headingStructure.h3}
15 | - Schema Count: ${result.schemaCount}
16 | ${
17 | result.isReactApp ? '- React App: Yes (client-side rendering detected)' : ''
18 | }
19 |
20 | POTENTIAL TARGET KEYWORDS:
21 | ${
22 | result.keywordAnalysis.phrases.length > 0
23 | ? `- Primary phrase: ${result.keywordAnalysis.phrases[0].phrase}
24 | - Other phrases: ${result.keywordAnalysis.phrases
25 | .slice(1)
26 | .map((p) => p.phrase)
27 | .join(', ')}`
28 | : '- No clear target keywords detected'
29 | }
30 |
31 | ISSUES (sorted by impact):
32 | ${result.issues
33 | .map(
34 | (issue) =>
35 | `- [${issue.severity.toUpperCase()}] [Impact: ${issue.impact}] ${
36 | issue.message
37 | }`
38 | )
39 | .join('\n')}
40 |
41 | RECOMMENDATIONS (sorted by impact):
42 | ${result.recommendations
43 | .map(
44 | (rec) => `- [Impact: ${rec.impact}] ${rec.text}
45 | Why: ${rec.reason}
46 | How: ${rec.implementation}`
47 | )
48 | .join('\n\n')}
49 |
50 | ${
51 | result.isReactApp
52 | ? '\nNOTE: This is a static HTML analysis. For JavaScript-heavy sites like React apps, the rendered content may differ from the static HTML.'
53 | : ''
54 | }`;
55 | }
56 |
57 | export function formatDirectoryAnalysisResults(results, directoryPath) {
58 | // Implementation...
59 | }
60 |
```
--------------------------------------------------------------------------------
/console-spy-mcp.js:
--------------------------------------------------------------------------------
```javascript
1 | #!/usr/bin/env node
2 | import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4 | import {
5 | CallToolRequestSchema,
6 | ListToolsRequestSchema,
7 | } from '@modelcontextprotocol/sdk/types.js';
8 | import http from 'http';
9 |
10 | // Define the Console Spy tool
11 | const CONSOLE_SPY_TOOL = {
12 | name: 'getConsoleLogs',
13 | description: 'Get console logs from the browser',
14 | inputSchema: {
15 | type: 'object',
16 | properties: {},
17 | required: [],
18 | },
19 | };
20 |
21 | // Create the server
22 | const server = new Server(
23 | {
24 | name: 'console-spy-server',
25 | version: '1.0.0',
26 | },
27 | {
28 | capabilities: {
29 | tools: {},
30 | },
31 | }
32 | );
33 |
34 | // Handle tool listing requests
35 | server.setRequestHandler(ListToolsRequestSchema, async () => ({
36 | tools: [CONSOLE_SPY_TOOL],
37 | }));
38 |
39 | // Handle tool call requests
40 | server.setRequestHandler(CallToolRequestSchema, async (request) => {
41 | if (request.params.name === 'getConsoleLogs') {
42 | try {
43 | // Fetch logs from original MCP server
44 | const logs = await fetchConsoleLogs();
45 | return {
46 | content: [
47 | {
48 | type: 'text',
49 | text: logs.content,
50 | },
51 | ],
52 | };
53 | } catch (error) {
54 | return {
55 | content: [
56 | {
57 | type: 'text',
58 | text: `Error fetching console logs: ${error.message}`,
59 | },
60 | ],
61 | isError: true,
62 | };
63 | }
64 | }
65 |
66 | return {
67 | content: [
68 | {
69 | type: 'text',
70 | text: `Unknown tool: ${request.params.name}`,
71 | },
72 | ],
73 | isError: true,
74 | };
75 | });
76 |
77 | // Function to fetch console logs
78 | async function fetchConsoleLogs() {
79 | return new Promise((resolve, reject) => {
80 | http
81 | .get('http://localhost:3333/mcp', (mcpRes) => {
82 | let responseData = '';
83 |
84 | mcpRes.on('data', (chunk) => {
85 | responseData += chunk;
86 | });
87 |
88 | mcpRes.on('end', () => {
89 | try {
90 | const logs = JSON.parse(responseData);
91 | resolve(logs);
92 | } catch (error) {
93 | reject(new Error('Failed to parse logs: ' + error.message));
94 | }
95 | });
96 | })
97 | .on('error', (error) => {
98 | reject(new Error('Failed to fetch logs: ' + error.message));
99 | });
100 | });
101 | }
102 |
103 | // Start the server
104 | async function runServer() {
105 | const transport = new StdioServerTransport();
106 | await server.connect(transport);
107 | console.error('Console Spy MCP Server running on stdio');
108 | }
109 |
110 | runServer().catch((error) => {
111 | console.error('Fatal error running server:', error);
112 | process.exit(1);
113 | });
114 |
```
--------------------------------------------------------------------------------
/seo-requirements.js:
--------------------------------------------------------------------------------
```javascript
1 | // seo-requirements.js - Prioritized list of SEO components to check
2 | const SEO_REQUIREMENTS = {
3 | critical: [
4 | {
5 | id: 'title',
6 | name: 'Page Title',
7 | description:
8 | 'Each page should have a unique, descriptive title between 30-60 characters',
9 | impact: 'Critical for search engine rankings and click-through rates',
10 | },
11 | {
12 | id: 'meta-description',
13 | name: 'Meta Description',
14 | description:
15 | 'Compelling summary of page content between 50-160 characters',
16 | impact: 'Affects click-through rates from search results',
17 | },
18 | {
19 | id: 'h1',
20 | name: 'H1 Heading',
21 | description:
22 | 'Each page should have exactly one H1 heading that describes the content',
23 | impact: 'Important for search engines to understand page content',
24 | },
25 | {
26 | id: 'canonical',
27 | name: 'Canonical URL',
28 | description: 'Specify the preferred URL for duplicate or similar content',
29 | impact:
30 | 'Prevents duplicate content issues and consolidates ranking signals',
31 | },
32 | ],
33 | important: [
34 | {
35 | id: 'heading-structure',
36 | name: 'Heading Structure',
37 | description: 'Proper use of H2-H6 headings to create content hierarchy',
38 | impact:
39 | 'Helps search engines understand content structure and importance',
40 | },
41 | {
42 | id: 'img-alt',
43 | name: 'Image Alt Text',
44 | description: 'Descriptive alternative text for all non-decorative images',
45 | impact: 'Improves accessibility and helps images rank in image search',
46 | },
47 | {
48 | id: 'schema',
49 | name: 'Structured Data',
50 | description: 'JSON-LD schema markup for relevant entity types',
51 | impact: 'Enables rich snippets and enhanced search features',
52 | },
53 | {
54 | id: 'meta-robots',
55 | name: 'Robots Directives',
56 | description:
57 | 'Appropriate use of index/noindex and follow/nofollow directives',
58 | impact: 'Controls how search engines crawl and index pages',
59 | },
60 | ],
61 | recommended: [
62 | {
63 | id: 'open-graph',
64 | name: 'Open Graph Tags',
65 | description: 'OG tags for title, description, image, and type',
66 | impact: 'Controls how content appears when shared on social media',
67 | },
68 | {
69 | id: 'twitter-cards',
70 | name: 'Twitter Cards',
71 | description: 'Twitter-specific metadata for shared content',
72 | impact: 'Enhances appearance of links shared on Twitter',
73 | },
74 | {
75 | id: 'internal-links',
76 | name: 'Internal Linking',
77 | description: 'Descriptive anchor text for internal links',
78 | impact:
79 | 'Distributes page authority and helps search engines understand content relationships',
80 | },
81 | {
82 | id: 'url-structure',
83 | name: 'URL Structure',
84 | description: 'Clean, descriptive URLs with keywords when relevant',
85 | impact: 'Affects user experience and keyword relevance',
86 | },
87 | {
88 | id: 'mobile-friendly',
89 | name: 'Mobile Friendliness',
90 | description: 'Responsive design and appropriate viewport settings',
91 | impact: 'Critical for mobile search rankings',
92 | },
93 | ],
94 | };
95 |
96 | module.exports = SEO_REQUIREMENTS;
97 |
```
--------------------------------------------------------------------------------
/src/analyzers/keyword-analyzer.js:
--------------------------------------------------------------------------------
```javascript
1 | // src/analyzers/keyword-analyzer.js
2 | import * as cheerio from 'cheerio';
3 |
4 | // Simple stemming function (very basic, but works for common cases)
5 | function simpleStem(word) {
6 | word = word.toLowerCase();
7 |
8 | // Handle common endings
9 | if (word.endsWith('ing')) return word.slice(0, -3);
10 | if (word.endsWith('ly')) return word.slice(0, -2);
11 | if (word.endsWith('es')) return word.slice(0, -2);
12 | if (word.endsWith('s')) return word.slice(0, -1);
13 | if (word.endsWith('ed')) return word.slice(0, -2);
14 | if (word.endsWith('er')) return word.slice(0, -2);
15 | if (word.endsWith('ment')) return word.slice(0, -4);
16 | if (word.endsWith('tion')) return word.slice(0, -4);
17 |
18 | return word;
19 | }
20 |
21 | export function detectTargetKeywords(html, title, metaDescription) {
22 | const $ = cheerio.load(html);
23 | const bodyText = $('body').text().toLowerCase();
24 |
25 | // Remove common words and keep only potential keywords
26 | const commonWords = [
27 | 'a',
28 | 'an',
29 | 'the',
30 | 'and',
31 | 'or',
32 | 'but',
33 | 'in',
34 | 'on',
35 | 'at',
36 | 'to',
37 | 'for',
38 | 'with',
39 | 'by',
40 | 'about',
41 | 'as',
42 | 'of',
43 | 'from',
44 | 'is',
45 | 'are',
46 | 'was',
47 | 'were',
48 | 'be',
49 | 'been',
50 | 'being',
51 | 'have',
52 | 'has',
53 | 'had',
54 | 'do',
55 | 'does',
56 | 'did',
57 | 'will',
58 | 'would',
59 | 'should',
60 | 'could',
61 | 'can',
62 | 'may',
63 | 'might',
64 | 'must',
65 | 'shall',
66 | 'this',
67 | 'that',
68 | 'these',
69 | 'those',
70 | 'it',
71 | 'they',
72 | 'them',
73 | 'their',
74 | 'we',
75 | 'us',
76 | 'our',
77 | 'you',
78 | 'your',
79 | 'he',
80 | 'him',
81 | 'his',
82 | 'she',
83 | 'her',
84 | 'hers',
85 | 'i',
86 | 'me',
87 | 'my',
88 | 'mine',
89 | 'who',
90 | 'whom',
91 | 'whose',
92 | 'which',
93 | 'what',
94 | 'when',
95 | 'where',
96 | 'why',
97 | 'how',
98 | 'all',
99 | 'any',
100 | 'both',
101 | 'each',
102 | 'few',
103 | 'more',
104 | 'most',
105 | 'some',
106 | 'such',
107 | 'no',
108 | 'nor',
109 | 'not',
110 | 'only',
111 | 'own',
112 | 'same',
113 | 'so',
114 | 'than',
115 | 'too',
116 | 'very',
117 | ];
118 |
119 | // Extract words from title, meta description, and headings
120 | const titleWords = title ? title.toLowerCase().split(/\s+/) : [];
121 | const metaWords = metaDescription
122 | ? metaDescription.toLowerCase().split(/\s+/)
123 | : [];
124 | const h1Words = [];
125 | $('h1').each((i, el) => {
126 | h1Words.push(...$(el).text().toLowerCase().split(/\s+/));
127 | });
128 |
129 | // Add h2 words collection
130 | const h2Words = [];
131 | $('h2').each((i, el) => {
132 | h2Words.push(...$(el).text().toLowerCase().split(/\s+/));
133 | });
134 |
135 | // Combine all important words
136 | const importantWords = [...titleWords, ...metaWords, ...h1Words, ...h2Words];
137 |
138 | // Count word frequency in body text
139 | const wordCounts = {};
140 | const stemmedWordMap = {}; // Maps stemmed words to original forms
141 | const words = bodyText.split(/\s+/);
142 | const totalWords = words.length;
143 |
144 | words.forEach((word) => {
145 | // Clean the word (remove punctuation, etc.)
146 | const cleanWord = word.replace(/[^\w\s]/g, '').trim();
147 | if (cleanWord && cleanWord.length > 3 && !commonWords.includes(cleanWord)) {
148 | // Get the stem of the word
149 | const stemmed = simpleStem(cleanWord);
150 |
151 | // Count the stemmed word
152 | wordCounts[stemmed] = (wordCounts[stemmed] || 0) + 1;
153 |
154 | // Keep track of the original form (use the most frequent one)
155 | if (
156 | !stemmedWordMap[stemmed] ||
157 | words.filter((w) => w === cleanWord).length >
158 | words.filter((w) => w === stemmedWordMap[stemmed]).length
159 | ) {
160 | stemmedWordMap[stemmed] = cleanWord;
161 | }
162 | }
163 | });
164 |
165 | // Count 2-word phrases (potential keywords)
166 | const phraseCounts = {};
167 | const originalPhraseMap = {}; // Maps normalized phrases to original forms
168 |
169 | for (let i = 0; i < words.length - 1; i++) {
170 | const word1 = words[i].replace(/[^\w\s]/g, '').trim();
171 | const word2 = words[i + 1].replace(/[^\w\s]/g, '').trim();
172 |
173 | if (
174 | word1 &&
175 | word2 &&
176 | word1.length > 2 &&
177 | word2.length > 2 &&
178 | !commonWords.includes(word1) &&
179 | !commonWords.includes(word2)
180 | ) {
181 | const phrase = `${word1} ${word2}`;
182 | const normalizedPhrase = `${simpleStem(word1)} ${simpleStem(word2)}`;
183 |
184 | phraseCounts[normalizedPhrase] =
185 | (phraseCounts[normalizedPhrase] || 0) + 1;
186 |
187 | // Keep track of the original form
188 | if (!originalPhraseMap[normalizedPhrase]) {
189 | originalPhraseMap[normalizedPhrase] = phrase;
190 | }
191 | }
192 | }
193 |
194 | // Prioritize words that appear in title, meta description, and h1
195 | const scoredWords = Object.keys(wordCounts).map((stemmed) => {
196 | let score = wordCounts[stemmed];
197 | const originalWord = stemmedWordMap[stemmed];
198 |
199 | // Boost score if word appears in important elements
200 | const stemmedImportantWords = importantWords.map((w) => simpleStem(w));
201 | if (stemmedImportantWords.includes(stemmed)) {
202 | score += 10;
203 | }
204 |
205 | if (titleWords.map((w) => simpleStem(w)).includes(stemmed)) score += 10;
206 | if (metaWords.map((w) => simpleStem(w)).includes(stemmed)) score += 5;
207 | if (h1Words.map((w) => simpleStem(w)).includes(stemmed)) score += 8;
208 | if (h2Words.map((w) => simpleStem(w)).includes(stemmed)) score += 6;
209 |
210 | // Calculate density (for analysis only, not for recommendations)
211 | const density = ((wordCounts[stemmed] / totalWords) * 100).toFixed(2);
212 |
213 | return {
214 | word: originalWord,
215 | score,
216 | density,
217 | inTitle: titleWords.map((w) => simpleStem(w)).includes(stemmed),
218 | inMetaDescription: metaWords.map((w) => simpleStem(w)).includes(stemmed),
219 | inH1: h1Words.map((w) => simpleStem(w)).includes(stemmed),
220 | inH2: h2Words.map((w) => simpleStem(w)).includes(stemmed),
221 | };
222 | });
223 |
224 | // Prioritize phrases that appear in title, meta description, and h1
225 | const scoredPhrases = Object.keys(phraseCounts).map((normalizedPhrase) => {
226 | let score = phraseCounts[normalizedPhrase] * 1.5; // Phrases are more valuable than single words
227 | const originalPhrase = originalPhraseMap[normalizedPhrase];
228 | const phraseWords = normalizedPhrase.split(' ');
229 |
230 | // Boost score if phrase appears in important elements
231 | const inTitle =
232 | title && phraseWords.every((pw) => title.toLowerCase().includes(pw));
233 | const inMetaDescription =
234 | metaDescription &&
235 | phraseWords.every((pw) => metaDescription.toLowerCase().includes(pw));
236 |
237 | if (inTitle) score += 15;
238 | if (inMetaDescription) score += 10;
239 |
240 | let inH1 = false;
241 | $('h1').each((i, el) => {
242 | const h1Text = $(el).text().toLowerCase();
243 | if (phraseWords.every((pw) => h1Text.includes(pw))) {
244 | inH1 = true;
245 | }
246 | });
247 |
248 | let inH2 = false;
249 | $('h2').each((i, el) => {
250 | const h2Text = $(el).text().toLowerCase();
251 | if (phraseWords.every((pw) => h2Text.includes(pw))) {
252 | inH2 = true;
253 | }
254 | });
255 |
256 | if (inH1) score += 12;
257 | if (inH2) score += 8;
258 |
259 | // Calculate density (for analysis only, not for recommendations)
260 | const density = (
261 | (phraseCounts[normalizedPhrase] / (totalWords - 1)) *
262 | 100
263 | ).toFixed(2);
264 |
265 | return {
266 | phrase: originalPhrase,
267 | score,
268 | density,
269 | inTitle,
270 | inMetaDescription,
271 | inH1,
272 | inH2,
273 | };
274 | });
275 |
276 | // Sort by score and take top results
277 | const topWords = scoredWords.sort((a, b) => b.score - a.score).slice(0, 5);
278 | const topPhrases = scoredPhrases
279 | .sort((a, b) => b.score - a.score)
280 | .slice(0, 5);
281 |
282 | // Add placement analysis for the top phrase
283 | const placementAnalysis =
284 | topPhrases.length > 0
285 | ? {
286 | primaryPhrase: topPhrases[0].phrase,
287 | inTitle: topPhrases[0].inTitle,
288 | inMetaDescription: topPhrases[0].inMetaDescription,
289 | inH1: topPhrases[0].inH1,
290 | inH2: topPhrases[0].inH2,
291 | missingFrom: [],
292 | }
293 | : null;
294 |
295 | if (!placementAnalysis.inTitle) placementAnalysis.missingFrom.push('title');
296 | if (!placementAnalysis.inMetaDescription)
297 | placementAnalysis.missingFrom.push('meta description');
298 | if (!placementAnalysis.inH1) placementAnalysis.missingFrom.push('H1 heading');
299 | if (!placementAnalysis.inH2)
300 | placementAnalysis.missingFrom.push('H2 headings');
301 |
302 | return {
303 | singleWords: topWords,
304 | phrases: topPhrases,
305 | placementAnalysis,
306 | keywordSummary: {
307 | primaryPhrase: topPhrases.length > 0 ? topPhrases[0].phrase : null,
308 | secondaryPhrases: topPhrases.slice(1, 3).map((p) => p.phrase),
309 | topSingleWords: topWords.slice(0, 3).map((w) => w.word),
310 | },
311 | };
312 | }
313 |
```
--------------------------------------------------------------------------------
/cs-mcp-server.js:
--------------------------------------------------------------------------------
```javascript
1 | console.log('Starting MCP server initialization...');
2 |
3 | try {
4 | console.log('Loading express...');
5 | const express = require('express');
6 | console.log('Express loaded successfully');
7 |
8 | console.log('Loading cors...');
9 | const cors = require('cors');
10 | console.log('CORS loaded successfully');
11 |
12 | console.log('Creating express app...');
13 | const app = express();
14 | console.log('Express app created');
15 |
16 | const port = 3333;
17 |
18 | // In-memory storage for logs with improved structure
19 | const sessions = {};
20 | const MAX_LOGS_PER_SESSION = 500; // Increased from 100
21 |
22 | console.log('Setting up middleware...');
23 | app.use(
24 | cors({
25 | origin: '*', // Allow all origins
26 | methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
27 | credentials: true,
28 | preflightContinue: false,
29 | optionsSuccessStatus: 204,
30 | })
31 | );
32 | console.log('CORS middleware added');
33 |
34 | app.use(express.json({ limit: '1mb' }));
35 | console.log('JSON middleware added');
36 |
37 | // Add a simple root route with strict CSP
38 | app.get('/', (req, res) => {
39 | console.log('Root endpoint hit');
40 | // Set strict Content-Security-Policy header
41 | res.setHeader(
42 | 'Content-Security-Policy',
43 | "default-src 'self'; style-src 'unsafe-inline'; script-src 'unsafe-inline'"
44 | );
45 |
46 | res.send(`
47 | <html>
48 | <head>
49 | <title>Console to Cursor MCP</title>
50 | <style>
51 | body {
52 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
53 | max-width: 800px;
54 | margin: 0 auto;
55 | padding: 20px;
56 | }
57 | h1 { color: #333; }
58 | p { line-height: 1.6; }
59 | code {
60 | background: #f4f4f4;
61 | padding: 2px 5px;
62 | border-radius: 3px;
63 | font-family: monospace;
64 | }
65 | button {
66 | background: #4CAF50;
67 | border: none;
68 | color: white;
69 | padding: 10px 15px;
70 | text-align: center;
71 | text-decoration: none;
72 | display: inline-block;
73 | font-size: 16px;
74 | margin: 4px 2px;
75 | cursor: pointer;
76 | border-radius: 4px;
77 | }
78 | .manual-logging {
79 | margin-top: 30px;
80 | padding: 15px;
81 | background: #f9f9f9;
82 | border: 1px solid #ddd;
83 | border-radius: 5px;
84 | }
85 | </style>
86 | </head>
87 | <body>
88 | <h1>Console to Cursor MCP</h1>
89 | <p>This server is running correctly. Available endpoints:</p>
90 | <ul>
91 | <li><code>/console-logs</code> - POST endpoint for receiving logs from browser extension</li>
92 | <li><code>/mcp</code> - GET endpoint for Cursor to retrieve logs</li>
93 | <li><code>/test</code> - GET endpoint for testing server connectivity</li>
94 | <li><code>/view-logs</code> - GET endpoint for viewing logs in browser</li>
95 | </ul>
96 |
97 | <h2>Test Console Logging</h2>
98 | <p>Click the button below to test console logging:</p>
99 | <button id="test-log">Test Console Log</button>
100 |
101 | <div class="manual-logging">
102 | <h2>Manual Logging</h2>
103 | <p>If automatic console capture isn't working, you can use these manual logging functions:</p>
104 | <ul>
105 | <li><code>window.mcpLog("Your message here")</code> - Send a log message</li>
106 | <li><code>window.mcpWarn("Your warning here")</code> - Send a warning message</li>
107 | <li><code>window.mcpError("Your error here")</code> - Send an error message</li>
108 | </ul>
109 | <p>Example: Open your browser console and type <code>mcpLog("Hello from manual logging")</code></p>
110 | </div>
111 |
112 | <script>
113 | document.getElementById('test-log').addEventListener('click', function() {
114 | console.log('Test log from button click', new Date().toISOString());
115 | console.warn('Test warning from button click');
116 | console.error('Test error from button click');
117 | alert('Test logs sent! Check the /view-logs endpoint to see them.');
118 | });
119 | </script>
120 | </body>
121 | </html>
122 | `);
123 | });
124 |
125 | console.log('Setting up /console-logs endpoint...');
126 | // Endpoint to receive logs from browser extension
127 | app.post('/console-logs', (req, res) => {
128 | console.log('Received request to /console-logs');
129 |
130 | try {
131 | const { logs, sessionId, url } = req.body;
132 |
133 | if (!logs || !sessionId || !url) {
134 | console.log('Missing required fields in request');
135 | return res
136 | .status(400)
137 | .json({ success: false, error: 'Missing required fields' });
138 | }
139 |
140 | // Log the content for debugging
141 | logs.forEach((log) => {
142 | console.log(`Received ${log.type} log from ${url}:`, log.content);
143 | });
144 |
145 | if (!sessions[sessionId]) {
146 | sessions[sessionId] = {
147 | logs: [],
148 | url: url,
149 | firstSeen: new Date(),
150 | lastSeen: new Date(),
151 | };
152 | } else {
153 | sessions[sessionId].lastSeen = new Date();
154 | }
155 |
156 | // Add new logs
157 | sessions[sessionId].logs.push(...logs);
158 |
159 | // Trim if too many
160 | if (sessions[sessionId].logs.length > MAX_LOGS_PER_SESSION) {
161 | sessions[sessionId].logs = sessions[sessionId].logs.slice(
162 | -MAX_LOGS_PER_SESSION
163 | );
164 | }
165 |
166 | res.json({ success: true, logCount: sessions[sessionId].logs.length });
167 | } catch (error) {
168 | console.error('Error processing /console-logs request:', error);
169 | res.status(500).json({ success: false, error: 'Server error' });
170 | }
171 | });
172 |
173 | console.log('Setting up /mcp endpoint...');
174 | // MCP endpoint for Cursor
175 | app.get('/mcp', (req, res) => {
176 | try {
177 | // Get all sessions sorted by last activity
178 | const allSessions = Object.values(sessions).sort(
179 | (a, b) => new Date(b.lastSeen) - new Date(a.lastSeen)
180 | );
181 |
182 | if (allSessions.length === 0) {
183 | return res.json({
184 | content:
185 | 'No console logs captured. Toggle the Console to Cursor extension on your localhost tab.',
186 | });
187 | }
188 |
189 | // Use the most recently active session
190 | const activeSession = allSessions[0];
191 |
192 | // Format logs for Cursor
193 | const formattedLogs = activeSession.logs
194 | .map(
195 | (log) =>
196 | `[${log.timestamp}] ${log.type.toUpperCase()}: ${JSON.stringify(
197 | log.content
198 | )}`
199 | )
200 | .join('\n');
201 |
202 | // Make sure we're returning the exact format Cursor expects
203 | res.json({
204 | content: `Console logs from ${activeSession.url} (${activeSession.logs.length} logs):\n\n${formattedLogs}`,
205 | });
206 | } catch (error) {
207 | console.error('Error processing /mcp request:', error);
208 | res.status(200).json({
209 | // Still return 200 with error message
210 | content: 'Error retrieving logs: ' + error.message,
211 | });
212 | }
213 | });
214 |
215 | // New endpoint to view logs in browser
216 | app.get('/view-logs', (req, res) => {
217 | try {
218 | // Get all sessions sorted by last activity
219 | const allSessions = Object.values(sessions).sort(
220 | (a, b) => new Date(b.lastSeen) - new Date(a.lastSeen)
221 | );
222 |
223 | if (allSessions.length === 0) {
224 | return res.send(`
225 | <html>
226 | <head>
227 | <title>MCP Logs</title>
228 | <style>
229 | body { font-family: sans-serif; padding: 20px; }
230 | h1 { color: #333; }
231 | .refresh { margin-bottom: 20px; }
232 | </style>
233 | </head>
234 | <body>
235 | <h1>MCP Logs</h1>
236 | <div class="refresh">
237 | <button onclick="location.reload()">Refresh</button>
238 | </div>
239 | <p>No logs captured yet. Make sure the console capture script is running.</p>
240 | <p><a href="/">Back to home</a></p>
241 | </body>
242 | </html>
243 | `);
244 | }
245 |
246 | // Generate HTML for logs
247 | let html = `
248 | <html>
249 | <head>
250 | <title>MCP Logs</title>
251 | <style>
252 | body { font-family: sans-serif; padding: 20px; }
253 | h1, h2 { color: #333; }
254 | .refresh { margin-bottom: 20px; }
255 | .log-entry { margin-bottom: 5px; font-family: monospace; white-space: pre-wrap; }
256 | .log { color: black; }
257 | .warn { color: orange; }
258 | .error { color: red; }
259 | .info { color: blue; }
260 | .debug { color: gray; }
261 | .timestamp { color: #666; font-size: 0.8em; }
262 | .session { margin-bottom: 30px; border: 1px solid #ddd; padding: 15px; border-radius: 5px; }
263 | .controls { margin-bottom: 20px; }
264 | .controls button { margin-right: 10px; }
265 | .log-content { max-height: 500px; overflow: auto; }
266 | .filter { margin-bottom: 15px; }
267 | .filter label { margin-right: 10px; }
268 | .nav { margin-bottom: 20px; }
269 | .nav a { margin-right: 15px; }
270 | </style>
271 | </head>
272 | <body>
273 | <h1>MCP Logs</h1>
274 | <div class="nav">
275 | <a href="/">Home</a>
276 | <a href="/test">Test Server</a>
277 | </div>
278 | <div class="refresh">
279 | <button onclick="location.reload()">Refresh</button>
280 | <span>(Auto-refreshes every 5 seconds)</span>
281 | <button onclick="window.location.href='/clear-logs'" style="margin-left: 20px; background-color: #f44336;">Clear All Logs</button>
282 | </div>
283 | <div class="filter">
284 | <label><input type="checkbox" class="filter-type" value="log" checked> Logs</label>
285 | <label><input type="checkbox" class="filter-type" value="warn" checked> Warnings</label>
286 | <label><input type="checkbox" class="filter-type" value="error" checked> Errors</label>
287 | <label><input type="checkbox" class="filter-type" value="info" checked> Info</label>
288 | <label><input type="checkbox" class="filter-type" value="debug" checked> Debug</label>
289 | </div>
290 | `;
291 |
292 | // Add each session
293 | allSessions.forEach((session, index) => {
294 | const firstSeen = new Date(session.firstSeen).toLocaleString();
295 | const lastSeen = new Date(session.lastSeen).toLocaleString();
296 |
297 | html += `
298 | <div class="session">
299 | <h2>Session ${index + 1}: ${session.url}</h2>
300 | <p>First seen: ${firstSeen} | Last seen: ${lastSeen} | Total logs: ${
301 | session.logs.length
302 | }</p>
303 | <div class="log-content">
304 | `;
305 |
306 | // Add logs
307 | if (session.logs.length === 0) {
308 | html += `<p>No logs in this session.</p>`;
309 | } else {
310 | session.logs.forEach((log) => {
311 | const timestamp = new Date(log.timestamp).toLocaleTimeString();
312 | let content;
313 | try {
314 | content = JSON.stringify(log.content, null, 2);
315 | } catch (e) {
316 | content = String(log.content);
317 | }
318 | html += `
319 | <div class="log-entry ${log.type}" data-type="${log.type}">
320 | <span class="timestamp">[${timestamp}]</span>
321 | <span class="${log.type}">${log.type.toUpperCase()}:</span>
322 | ${content}
323 | </div>
324 | `;
325 | });
326 | }
327 |
328 | html += `
329 | </div>
330 | </div>`;
331 | });
332 |
333 | html += `
334 | <script>
335 | // Auto-refresh every 5 seconds
336 | setTimeout(() => {
337 | location.reload();
338 | }, 5000);
339 |
340 | // Set up filtering
341 | document.querySelectorAll('.filter-type').forEach(checkbox => {
342 | checkbox.addEventListener('change', function() {
343 | const type = this.value;
344 | const checked = this.checked;
345 |
346 | document.querySelectorAll(\`.log-entry[data-type="\${type}"]\`).forEach(entry => {
347 | entry.style.display = checked ? 'block' : 'none';
348 | });
349 | });
350 | });
351 | </script>
352 | </body>
353 | </html>
354 | `;
355 |
356 | res.send(html);
357 | } catch (error) {
358 | console.error('Error generating logs view:', error);
359 | res.status(500).send('Error generating logs view: ' + error.message);
360 | }
361 | });
362 |
363 | app.listen(port, () => {
364 | console.log(`MCP server is running on port ${port}`);
365 | });
366 | } catch (error) {
367 | console.error('Error initializing MCP server:', error);
368 | }
369 |
```