# Directory Structure ``` ├── .gitignore ├── build │ ├── index.d.ts │ ├── index.js │ └── index.js.map ├── LICENSE ├── node_modules │ ├── .bin │ │ ├── node-which │ │ ├── nodemon │ │ ├── nodetouch │ │ ├── semver │ │ ├── tsc │ │ └── tsserver │ ├── .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 │ │ │ │ │ │ ├── providers │ │ │ │ │ │ │ ├── proxyProvider.d.ts │ │ │ │ │ │ │ ├── proxyProvider.d.ts.map │ │ │ │ │ │ │ ├── proxyProvider.js │ │ │ │ │ │ │ └── proxyProvider.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 │ │ │ │ │ ├── providers │ │ │ │ │ │ ├── proxyProvider.d.ts │ │ │ │ │ │ ├── proxyProvider.d.ts.map │ │ │ │ │ │ ├── proxyProvider.js │ │ │ │ │ │ └── proxyProvider.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 │ │ ├── package.json │ │ └── README.md │ ├── @types │ │ └── node │ │ ├── assert │ │ │ └── strict.d.ts │ │ ├── assert.d.ts │ │ ├── async_hooks.d.ts │ │ ├── buffer.buffer.d.ts │ │ ├── buffer.d.ts │ │ ├── child_process.d.ts │ │ ├── cluster.d.ts │ │ ├── compatibility │ │ │ ├── disposable.d.ts │ │ │ ├── index.d.ts │ │ │ ├── indexable.d.ts │ │ │ └── iterators.d.ts │ │ ├── console.d.ts │ │ ├── constants.d.ts │ │ ├── crypto.d.ts │ │ ├── dgram.d.ts │ │ ├── diagnostics_channel.d.ts │ │ ├── dns │ │ │ └── promises.d.ts │ │ ├── dns.d.ts │ │ ├── dom-events.d.ts │ │ ├── domain.d.ts │ │ ├── events.d.ts │ │ ├── fs │ │ │ └── promises.d.ts │ │ ├── fs.d.ts │ │ ├── globals.d.ts │ │ ├── globals.typedarray.d.ts │ │ ├── http.d.ts │ │ ├── http2.d.ts │ │ ├── https.d.ts │ │ ├── index.d.ts │ │ ├── inspector.d.ts │ │ ├── LICENSE │ │ ├── module.d.ts │ │ ├── net.d.ts │ │ ├── os.d.ts │ │ ├── package.json │ │ ├── path.d.ts │ │ ├── perf_hooks.d.ts │ │ ├── process.d.ts │ │ ├── punycode.d.ts │ │ ├── querystring.d.ts │ │ ├── readline │ │ │ └── promises.d.ts │ │ ├── readline.d.ts │ │ ├── README.md │ │ ├── repl.d.ts │ │ ├── sea.d.ts │ │ ├── stream │ │ │ ├── consumers.d.ts │ │ │ ├── promises.d.ts │ │ │ └── web.d.ts │ │ ├── stream.d.ts │ │ ├── string_decoder.d.ts │ │ ├── test.d.ts │ │ ├── timers │ │ │ └── promises.d.ts │ │ ├── timers.d.ts │ │ ├── tls.d.ts │ │ ├── trace_events.d.ts │ │ ├── ts5.6 │ │ │ ├── buffer.buffer.d.ts │ │ │ ├── globals.typedarray.d.ts │ │ │ └── index.d.ts │ │ ├── tty.d.ts │ │ ├── url.d.ts │ │ ├── util.d.ts │ │ ├── v8.d.ts │ │ ├── vm.d.ts │ │ ├── wasi.d.ts │ │ ├── worker_threads.d.ts │ │ └── zlib.d.ts │ ├── accepts │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── node_modules │ │ │ ├── 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 │ │ ├── package.json │ │ └── README.md │ ├── anymatch │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── asynckit │ │ ├── bench.js │ │ ├── index.js │ │ ├── lib │ │ │ ├── abort.js │ │ │ ├── async.js │ │ │ ├── defer.js │ │ │ ├── iterate.js │ │ │ ├── readable_asynckit.js │ │ │ ├── readable_parallel.js │ │ │ ├── readable_serial_ordered.js │ │ │ ├── readable_serial.js │ │ │ ├── state.js │ │ │ ├── streamify.js │ │ │ └── terminator.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── parallel.js │ │ ├── README.md │ │ ├── serial.js │ │ ├── serialOrdered.js │ │ └── stream.js │ ├── axios │ │ ├── CHANGELOG.md │ │ ├── dist │ │ │ ├── axios.js │ │ │ ├── axios.js.map │ │ │ ├── axios.min.js │ │ │ ├── axios.min.js.map │ │ │ ├── browser │ │ │ │ ├── axios.cjs │ │ │ │ └── axios.cjs.map │ │ │ ├── esm │ │ │ │ ├── axios.js │ │ │ │ ├── axios.js.map │ │ │ │ ├── axios.min.js │ │ │ │ └── axios.min.js.map │ │ │ └── node │ │ │ ├── axios.cjs │ │ │ └── axios.cjs.map │ │ ├── index.d.cts │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── lib │ │ │ ├── adapters │ │ │ │ ├── adapters.js │ │ │ │ ├── fetch.js │ │ │ │ ├── http.js │ │ │ │ ├── README.md │ │ │ │ └── xhr.js │ │ │ ├── axios.js │ │ │ ├── cancel │ │ │ │ ├── CanceledError.js │ │ │ │ ├── CancelToken.js │ │ │ │ └── isCancel.js │ │ │ ├── core │ │ │ │ ├── Axios.js │ │ │ │ ├── AxiosError.js │ │ │ │ ├── AxiosHeaders.js │ │ │ │ ├── buildFullPath.js │ │ │ │ ├── dispatchRequest.js │ │ │ │ ├── InterceptorManager.js │ │ │ │ ├── mergeConfig.js │ │ │ │ ├── README.md │ │ │ │ ├── settle.js │ │ │ │ └── transformData.js │ │ │ ├── defaults │ │ │ │ ├── index.js │ │ │ │ └── transitional.js │ │ │ ├── env │ │ │ │ ├── classes │ │ │ │ │ └── FormData.js │ │ │ │ ├── data.js │ │ │ │ └── README.md │ │ │ ├── helpers │ │ │ │ ├── AxiosTransformStream.js │ │ │ │ ├── AxiosURLSearchParams.js │ │ │ │ ├── bind.js │ │ │ │ ├── buildURL.js │ │ │ │ ├── callbackify.js │ │ │ │ ├── combineURLs.js │ │ │ │ ├── composeSignals.js │ │ │ │ ├── cookies.js │ │ │ │ ├── deprecatedMethod.js │ │ │ │ ├── formDataToJSON.js │ │ │ │ ├── formDataToStream.js │ │ │ │ ├── fromDataURI.js │ │ │ │ ├── HttpStatusCode.js │ │ │ │ ├── isAbsoluteURL.js │ │ │ │ ├── isAxiosError.js │ │ │ │ ├── isURLSameOrigin.js │ │ │ │ ├── null.js │ │ │ │ ├── parseHeaders.js │ │ │ │ ├── parseProtocol.js │ │ │ │ ├── progressEventReducer.js │ │ │ │ ├── readBlob.js │ │ │ │ ├── README.md │ │ │ │ ├── resolveConfig.js │ │ │ │ ├── speedometer.js │ │ │ │ ├── spread.js │ │ │ │ ├── throttle.js │ │ │ │ ├── toFormData.js │ │ │ │ ├── toURLEncodedForm.js │ │ │ │ ├── trackStream.js │ │ │ │ ├── validator.js │ │ │ │ └── ZlibHeaderTransformStream.js │ │ │ ├── platform │ │ │ │ ├── browser │ │ │ │ │ ├── classes │ │ │ │ │ │ ├── Blob.js │ │ │ │ │ │ ├── FormData.js │ │ │ │ │ │ └── URLSearchParams.js │ │ │ │ │ └── index.js │ │ │ │ ├── common │ │ │ │ │ └── utils.js │ │ │ │ ├── index.js │ │ │ │ └── node │ │ │ │ ├── classes │ │ │ │ │ ├── FormData.js │ │ │ │ │ └── URLSearchParams.js │ │ │ │ └── index.js │ │ │ └── utils.js │ │ ├── LICENSE │ │ ├── MIGRATION_GUIDE.md │ │ ├── package.json │ │ └── README.md │ ├── balanced-match │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── index.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ └── README.md │ ├── binary-extensions │ │ ├── binary-extensions.json │ │ ├── binary-extensions.json.d.ts │ │ ├── index.d.ts │ │ ├── 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 │ │ │ └── utils.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── brace-expansion │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── braces │ │ ├── index.js │ │ ├── lib │ │ │ ├── compile.js │ │ │ ├── constants.js │ │ │ ├── expand.js │ │ │ ├── parse.js │ │ │ ├── stringify.js │ │ │ └── utils.js │ │ ├── LICENSE │ │ ├── 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 │ ├── chokidar │ │ ├── index.js │ │ ├── lib │ │ │ ├── constants.js │ │ │ ├── fsevents-handler.js │ │ │ └── nodefs-handler.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── types │ │ └── index.d.ts │ ├── combined-stream │ │ ├── lib │ │ │ └── combined_stream.js │ │ ├── License │ │ ├── package.json │ │ ├── Readme.md │ │ └── yarn.lock │ ├── concat-map │ │ ├── .travis.yml │ │ ├── example │ │ │ └── map.js │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.markdown │ │ └── test │ │ └── map.js │ ├── 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 │ │ ├── History.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── cors │ │ ├── CONTRIBUTING.md │ │ ├── HISTORY.md │ │ ├── lib │ │ │ └── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── cross-spawn │ │ ├── index.js │ │ ├── lib │ │ │ ├── enoent.js │ │ │ ├── parse.js │ │ │ └── util │ │ │ ├── escape.js │ │ │ ├── readShebang.js │ │ │ └── resolveCommand.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── debug │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── src │ │ ├── browser.js │ │ ├── common.js │ │ ├── index.js │ │ └── node.js │ ├── delayed-stream │ │ ├── .npmignore │ │ ├── lib │ │ │ └── delayed_stream.js │ │ ├── License │ │ ├── Makefile │ │ ├── package.json │ │ └── Readme.md │ ├── depd │ │ ├── History.md │ │ ├── index.js │ │ ├── lib │ │ │ └── browser │ │ │ └── index.js │ │ ├── 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 │ ├── encodeurl │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── es-define-property │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── es-errors │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── CHANGELOG.md │ │ ├── eval.d.ts │ │ ├── eval.js │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── range.d.ts │ │ ├── range.js │ │ ├── README.md │ │ ├── ref.d.ts │ │ ├── ref.js │ │ ├── syntax.d.ts │ │ ├── syntax.js │ │ ├── test │ │ │ └── index.js │ │ ├── tsconfig.json │ │ ├── type.d.ts │ │ ├── type.js │ │ ├── uri.d.ts │ │ └── uri.js │ ├── es-object-atoms │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── isObject.d.ts │ │ ├── isObject.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── RequireObjectCoercible.d.ts │ │ ├── RequireObjectCoercible.js │ │ ├── test │ │ │ └── index.js │ │ ├── ToObject.d.ts │ │ ├── ToObject.js │ │ └── tsconfig.json │ ├── es-set-tostringtag │ │ ├── .eslintrc │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── escape-html │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── etag │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── eventsource │ │ ├── dist │ │ │ ├── index.cjs │ │ │ ├── index.cjs.map │ │ │ ├── index.d.cts │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── index.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── src │ │ ├── errors.ts │ │ ├── EventSource.ts │ │ ├── index.ts │ │ └── types.ts │ ├── eventsource-parser │ │ ├── dist │ │ │ ├── index.cjs │ │ │ ├── index.cjs.map │ │ │ ├── index.d.cts │ │ │ ├── index.d.ts │ │ │ ├── index.esm.js │ │ │ ├── index.esm.js.map │ │ │ ├── index.js │ │ │ ├── index.js.map │ │ │ ├── stats.html │ │ │ ├── stream.cjs │ │ │ ├── stream.cjs.map │ │ │ ├── stream.d.cts │ │ │ ├── stream.d.ts │ │ │ ├── stream.esm.js │ │ │ ├── stream.esm.js.map │ │ │ ├── stream.js │ │ │ └── stream.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── src │ │ │ ├── errors.ts │ │ │ ├── index.ts │ │ │ ├── parse.ts │ │ │ ├── stream.ts │ │ │ └── types.ts │ │ └── stream.js │ ├── express │ │ ├── History.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── application.js │ │ │ ├── express.js │ │ │ ├── request.js │ │ │ ├── response.js │ │ │ ├── utils.js │ │ │ └── view.js │ │ ├── LICENSE │ │ ├── node_modules │ │ │ ├── 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 │ │ ├── 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 │ ├── fill-range │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── finalhandler │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── follow-redirects │ │ ├── debug.js │ │ ├── http.js │ │ ├── https.js │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── form-data │ │ ├── index.d.ts │ │ ├── lib │ │ │ ├── browser.js │ │ │ ├── form_data.js │ │ │ └── populate.js │ │ ├── License │ │ ├── package.json │ │ └── Readme.md │ ├── forwarded │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── fresh │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── fsevents │ │ ├── fsevents.d.ts │ │ ├── fsevents.js │ │ ├── fsevents.node │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── function-bind │ │ ├── .eslintrc │ │ ├── .github │ │ │ ├── FUNDING.yml │ │ │ └── SECURITY.md │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── implementation.js │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ ├── .eslintrc │ │ └── index.js │ ├── get-intrinsic │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ └── GetIntrinsic.js │ ├── get-proto │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── Object.getPrototypeOf.d.ts │ │ ├── Object.getPrototypeOf.js │ │ ├── package.json │ │ ├── README.md │ │ ├── Reflect.getPrototypeOf.d.ts │ │ ├── Reflect.getPrototypeOf.js │ │ ├── test │ │ │ └── index.js │ │ └── tsconfig.json │ ├── glob-parent │ │ ├── CHANGELOG.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── 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-flag │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── 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 │ ├── has-tostringtag │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ ├── shams.d.ts │ │ ├── shams.js │ │ ├── test │ │ │ ├── index.js │ │ │ ├── shams │ │ │ │ ├── core-js.js │ │ │ │ └── get-own-property-symbols.js │ │ │ └── tests.js │ │ └── tsconfig.json │ ├── hasown │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── tsconfig.json │ ├── http-errors │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── iconv-lite │ │ ├── .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 │ ├── ignore-by-default │ │ ├── index.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-binary-path │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── is-extglob │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── is-glob │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── is-number │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── is-promise │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── index.mjs │ │ ├── LICENSE │ │ ├── package.json │ │ └── readme.md │ ├── isexe │ │ ├── .npmignore │ │ ├── index.js │ │ ├── LICENSE │ │ ├── mode.js │ │ ├── package.json │ │ ├── README.md │ │ ├── test │ │ │ └── basic.js │ │ └── windows.js │ ├── 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 │ │ ├── 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 │ │ ├── package.json │ │ └── README.md │ ├── minimatch │ │ ├── LICENSE │ │ ├── minimatch.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 │ ├── nodemon │ │ ├── .prettierrc.json │ │ ├── bin │ │ │ ├── nodemon.js │ │ │ └── windows-kill.exe │ │ ├── doc │ │ │ └── cli │ │ │ ├── authors.txt │ │ │ ├── config.txt │ │ │ ├── help.txt │ │ │ ├── logo.txt │ │ │ ├── options.txt │ │ │ ├── topics.txt │ │ │ ├── usage.txt │ │ │ └── whoami.txt │ │ ├── index.d.ts │ │ ├── jsconfig.json │ │ ├── lib │ │ │ ├── cli │ │ │ │ ├── index.js │ │ │ │ └── parse.js │ │ │ ├── config │ │ │ │ ├── command.js │ │ │ │ ├── defaults.js │ │ │ │ ├── exec.js │ │ │ │ ├── index.js │ │ │ │ └── load.js │ │ │ ├── help │ │ │ │ └── index.js │ │ │ ├── index.js │ │ │ ├── monitor │ │ │ │ ├── index.js │ │ │ │ ├── match.js │ │ │ │ ├── run.js │ │ │ │ ├── signals.js │ │ │ │ └── watch.js │ │ │ ├── nodemon.js │ │ │ ├── rules │ │ │ │ ├── add.js │ │ │ │ ├── index.js │ │ │ │ └── parse.js │ │ │ ├── spawn.js │ │ │ ├── utils │ │ │ │ ├── bus.js │ │ │ │ ├── clone.js │ │ │ │ ├── colour.js │ │ │ │ ├── index.js │ │ │ │ ├── log.js │ │ │ │ └── merge.js │ │ │ └── version.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── normalize-path │ │ ├── index.js │ │ ├── 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 │ ├── parseurl │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── path-key │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── path-to-regexp │ │ ├── dist │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ └── index.js.map │ │ ├── LICENSE │ │ ├── package.json │ │ └── Readme.md │ ├── picomatch │ │ ├── CHANGELOG.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── constants.js │ │ │ ├── parse.js │ │ │ ├── picomatch.js │ │ │ ├── scan.js │ │ │ └── utils.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── pkce-challenge │ │ ├── dist │ │ │ ├── index.browser.d.ts │ │ │ ├── index.browser.js │ │ │ ├── index.node.cjs │ │ │ ├── index.node.d.cts │ │ │ ├── index.node.d.ts │ │ │ └── index.node.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── proxy-addr │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── proxy-from-env │ │ ├── .eslintrc │ │ ├── .travis.yml │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── test.js │ ├── pstree.remy │ │ ├── .travis.yml │ │ ├── lib │ │ │ ├── index.js │ │ │ ├── tree.js │ │ │ └── utils.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── tests │ │ ├── fixtures │ │ │ ├── index.js │ │ │ ├── out1 │ │ │ └── out2 │ │ └── index.test.js │ ├── qs │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── .nycrc │ │ ├── CHANGELOG.md │ │ ├── dist │ │ │ └── qs.js │ │ ├── lib │ │ │ ├── formats.js │ │ │ ├── index.js │ │ │ ├── parse.js │ │ │ ├── stringify.js │ │ │ └── utils.js │ │ ├── LICENSE.md │ │ ├── package.json │ │ ├── README.md │ │ └── test │ │ ├── empty-keys-cases.js │ │ ├── parse.js │ │ ├── stringify.js │ │ └── utils.js │ ├── range-parser │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── raw-body │ │ ├── HISTORY.md │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── SECURITY.md │ ├── readdirp │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── router │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── layer.js │ │ │ └── route.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.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 │ ├── semver │ │ ├── bin │ │ │ └── semver.js │ │ ├── classes │ │ │ ├── comparator.js │ │ │ ├── index.js │ │ │ ├── range.js │ │ │ └── semver.js │ │ ├── functions │ │ │ ├── clean.js │ │ │ ├── cmp.js │ │ │ ├── coerce.js │ │ │ ├── compare-build.js │ │ │ ├── compare-loose.js │ │ │ ├── compare.js │ │ │ ├── diff.js │ │ │ ├── eq.js │ │ │ ├── gt.js │ │ │ ├── gte.js │ │ │ ├── inc.js │ │ │ ├── lt.js │ │ │ ├── lte.js │ │ │ ├── major.js │ │ │ ├── minor.js │ │ │ ├── neq.js │ │ │ ├── parse.js │ │ │ ├── patch.js │ │ │ ├── prerelease.js │ │ │ ├── rcompare.js │ │ │ ├── rsort.js │ │ │ ├── satisfies.js │ │ │ ├── sort.js │ │ │ └── valid.js │ │ ├── index.js │ │ ├── internal │ │ │ ├── constants.js │ │ │ ├── debug.js │ │ │ ├── identifiers.js │ │ │ ├── lrucache.js │ │ │ ├── parse-options.js │ │ │ └── re.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── preload.js │ │ ├── range.bnf │ │ ├── ranges │ │ │ ├── gtr.js │ │ │ ├── intersects.js │ │ │ ├── ltr.js │ │ │ ├── max-satisfying.js │ │ │ ├── min-satisfying.js │ │ │ ├── min-version.js │ │ │ ├── outside.js │ │ │ ├── simplify.js │ │ │ ├── subset.js │ │ │ ├── to-comparators.js │ │ │ └── valid.js │ │ └── README.md │ ├── send │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── node_modules │ │ │ ├── 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 │ │ ├── package.json │ │ └── README.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 │ ├── shebang-command │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── shebang-regex │ │ ├── index.d.ts │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── 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 │ ├── simple-update-notifier │ │ ├── build │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── src │ │ ├── borderedText.ts │ │ ├── cache.spec.ts │ │ ├── cache.ts │ │ ├── getDistVersion.spec.ts │ │ ├── getDistVersion.ts │ │ ├── hasNewVersion.spec.ts │ │ ├── hasNewVersion.ts │ │ ├── index.spec.ts │ │ ├── index.ts │ │ ├── isNpmOrYarn.ts │ │ └── types.ts │ ├── statuses │ │ ├── codes.json │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── supports-color │ │ ├── browser.js │ │ ├── index.js │ │ ├── license │ │ ├── package.json │ │ └── readme.md │ ├── to-regex-range │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── toidentifier │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── touch │ │ ├── bin │ │ │ └── nodetouch.js │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── type-is │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── node_modules │ │ │ ├── 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 │ │ ├── package.json │ │ └── README.md │ ├── typescript │ │ ├── bin │ │ │ ├── tsc │ │ │ └── tsserver │ │ ├── lib │ │ │ ├── _tsc.js │ │ │ ├── _tsserver.js │ │ │ ├── _typingsInstaller.js │ │ │ ├── cs │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── de │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── es │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── fr │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── it │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ja │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ko │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── lib.d.ts │ │ │ ├── lib.decorators.d.ts │ │ │ ├── lib.decorators.legacy.d.ts │ │ │ ├── lib.dom.asynciterable.d.ts │ │ │ ├── lib.dom.d.ts │ │ │ ├── lib.dom.iterable.d.ts │ │ │ ├── lib.es2015.collection.d.ts │ │ │ ├── lib.es2015.core.d.ts │ │ │ ├── lib.es2015.d.ts │ │ │ ├── lib.es2015.generator.d.ts │ │ │ ├── lib.es2015.iterable.d.ts │ │ │ ├── lib.es2015.promise.d.ts │ │ │ ├── lib.es2015.proxy.d.ts │ │ │ ├── lib.es2015.reflect.d.ts │ │ │ ├── lib.es2015.symbol.d.ts │ │ │ ├── lib.es2015.symbol.wellknown.d.ts │ │ │ ├── lib.es2016.array.include.d.ts │ │ │ ├── lib.es2016.d.ts │ │ │ ├── lib.es2016.full.d.ts │ │ │ ├── lib.es2016.intl.d.ts │ │ │ ├── lib.es2017.arraybuffer.d.ts │ │ │ ├── lib.es2017.d.ts │ │ │ ├── lib.es2017.date.d.ts │ │ │ ├── lib.es2017.full.d.ts │ │ │ ├── lib.es2017.intl.d.ts │ │ │ ├── lib.es2017.object.d.ts │ │ │ ├── lib.es2017.sharedmemory.d.ts │ │ │ ├── lib.es2017.string.d.ts │ │ │ ├── lib.es2017.typedarrays.d.ts │ │ │ ├── lib.es2018.asyncgenerator.d.ts │ │ │ ├── lib.es2018.asynciterable.d.ts │ │ │ ├── lib.es2018.d.ts │ │ │ ├── lib.es2018.full.d.ts │ │ │ ├── lib.es2018.intl.d.ts │ │ │ ├── lib.es2018.promise.d.ts │ │ │ ├── lib.es2018.regexp.d.ts │ │ │ ├── lib.es2019.array.d.ts │ │ │ ├── lib.es2019.d.ts │ │ │ ├── lib.es2019.full.d.ts │ │ │ ├── lib.es2019.intl.d.ts │ │ │ ├── lib.es2019.object.d.ts │ │ │ ├── lib.es2019.string.d.ts │ │ │ ├── lib.es2019.symbol.d.ts │ │ │ ├── lib.es2020.bigint.d.ts │ │ │ ├── lib.es2020.d.ts │ │ │ ├── lib.es2020.date.d.ts │ │ │ ├── lib.es2020.full.d.ts │ │ │ ├── lib.es2020.intl.d.ts │ │ │ ├── lib.es2020.number.d.ts │ │ │ ├── lib.es2020.promise.d.ts │ │ │ ├── lib.es2020.sharedmemory.d.ts │ │ │ ├── lib.es2020.string.d.ts │ │ │ ├── lib.es2020.symbol.wellknown.d.ts │ │ │ ├── lib.es2021.d.ts │ │ │ ├── lib.es2021.full.d.ts │ │ │ ├── lib.es2021.intl.d.ts │ │ │ ├── lib.es2021.promise.d.ts │ │ │ ├── lib.es2021.string.d.ts │ │ │ ├── lib.es2021.weakref.d.ts │ │ │ ├── lib.es2022.array.d.ts │ │ │ ├── lib.es2022.d.ts │ │ │ ├── lib.es2022.error.d.ts │ │ │ ├── lib.es2022.full.d.ts │ │ │ ├── lib.es2022.intl.d.ts │ │ │ ├── lib.es2022.object.d.ts │ │ │ ├── lib.es2022.regexp.d.ts │ │ │ ├── lib.es2022.string.d.ts │ │ │ ├── lib.es2023.array.d.ts │ │ │ ├── lib.es2023.collection.d.ts │ │ │ ├── lib.es2023.d.ts │ │ │ ├── lib.es2023.full.d.ts │ │ │ ├── lib.es2023.intl.d.ts │ │ │ ├── lib.es2024.arraybuffer.d.ts │ │ │ ├── lib.es2024.collection.d.ts │ │ │ ├── lib.es2024.d.ts │ │ │ ├── lib.es2024.full.d.ts │ │ │ ├── lib.es2024.object.d.ts │ │ │ ├── lib.es2024.promise.d.ts │ │ │ ├── lib.es2024.regexp.d.ts │ │ │ ├── lib.es2024.sharedmemory.d.ts │ │ │ ├── lib.es2024.string.d.ts │ │ │ ├── lib.es5.d.ts │ │ │ ├── lib.es6.d.ts │ │ │ ├── lib.esnext.array.d.ts │ │ │ ├── lib.esnext.collection.d.ts │ │ │ ├── lib.esnext.d.ts │ │ │ ├── lib.esnext.decorators.d.ts │ │ │ ├── lib.esnext.disposable.d.ts │ │ │ ├── lib.esnext.float16.d.ts │ │ │ ├── lib.esnext.full.d.ts │ │ │ ├── lib.esnext.intl.d.ts │ │ │ ├── lib.esnext.iterator.d.ts │ │ │ ├── lib.esnext.promise.d.ts │ │ │ ├── lib.scripthost.d.ts │ │ │ ├── lib.webworker.asynciterable.d.ts │ │ │ ├── lib.webworker.d.ts │ │ │ ├── lib.webworker.importscripts.d.ts │ │ │ ├── lib.webworker.iterable.d.ts │ │ │ ├── pl │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── pt-br │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── ru │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── tr │ │ │ │ └── diagnosticMessages.generated.json │ │ │ ├── tsc.js │ │ │ ├── tsserver.js │ │ │ ├── tsserverlibrary.d.ts │ │ │ ├── tsserverlibrary.js │ │ │ ├── typescript.d.ts │ │ │ ├── typescript.js │ │ │ ├── typesMap.json │ │ │ ├── typingsInstaller.js │ │ │ ├── watchGuard.js │ │ │ ├── zh-cn │ │ │ │ └── diagnosticMessages.generated.json │ │ │ └── zh-tw │ │ │ └── diagnosticMessages.generated.json │ │ ├── LICENSE.txt │ │ ├── package.json │ │ ├── README.md │ │ ├── SECURITY.md │ │ └── ThirdPartyNoticeText.txt │ ├── undefsafe │ │ ├── .github │ │ │ └── workflows │ │ │ └── release.yml │ │ ├── .jscsrc │ │ ├── .jshintrc │ │ ├── .travis.yml │ │ ├── example.js │ │ ├── lib │ │ │ └── undefsafe.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── undici-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 │ │ ├── LICENSE │ │ ├── mock-agent.d.ts │ │ ├── mock-client.d.ts │ │ ├── mock-errors.d.ts │ │ ├── mock-interceptor.d.ts │ │ ├── mock-pool.d.ts │ │ ├── package.json │ │ ├── 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 │ ├── vary │ │ ├── HISTORY.md │ │ ├── index.js │ │ ├── LICENSE │ │ ├── package.json │ │ └── README.md │ ├── which │ │ ├── bin │ │ │ └── node-which │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── which.js │ ├── wrappy │ │ ├── LICENSE │ │ ├── package.json │ │ ├── README.md │ │ └── wrappy.js │ ├── 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 │ ├── LICENSE │ ├── package.json │ ├── postcjs.ts │ ├── postesm.ts │ ├── README.md │ └── SECURITY.md ├── package-lock.json ├── package.json ├── README.md ├── src │ └── index.ts ├── tsconfig.json ├── watchbase_api_reference.md └── watchbase-mcp ├── .gitignore ├── package.json ├── README.md ├── src │ └── index.ts └── tsconfig.json ``` # Files -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` 1 | .DS_Store 2 | ``` -------------------------------------------------------------------------------- /watchbase-mcp/.gitignore: -------------------------------------------------------------------------------- ``` 1 | node_modules/ 2 | build/ 3 | *.log 4 | .env* ``` -------------------------------------------------------------------------------- /watchbase-mcp/README.md: -------------------------------------------------------------------------------- ```markdown 1 | # watchbase-mcp MCP Server 2 | 3 | Structured and standardized querying of watch-related metadata such as brands, families, and reference details from WatchBase.com 4 | 5 | This is a TypeScript-based MCP server that implements a simple notes system. It demonstrates core MCP concepts by providing: 6 | 7 | - Resources representing text notes with URIs and metadata 8 | - Tools for creating new notes 9 | - Prompts for generating summaries of notes 10 | 11 | ## Features 12 | 13 | ### Resources 14 | - List and access notes via `note://` URIs 15 | - Each note has a title, content and metadata 16 | - Plain text mime type for simple content access 17 | 18 | ### Tools 19 | - `create_note` - Create new text notes 20 | - Takes title and content as required parameters 21 | - Stores note in server state 22 | 23 | ### Prompts 24 | - `summarize_notes` - Generate a summary of all stored notes 25 | - Includes all note contents as embedded resources 26 | - Returns structured prompt for LLM summarization 27 | 28 | ## Development 29 | 30 | Install dependencies: 31 | ```bash 32 | npm install 33 | ``` 34 | 35 | Build the server: 36 | ```bash 37 | npm run build 38 | ``` 39 | 40 | For development with auto-rebuild: 41 | ```bash 42 | npm run watch 43 | ``` 44 | 45 | ## Installation 46 | 47 | To use with Claude Desktop, add the server config: 48 | 49 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 50 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json` 51 | 52 | ```json 53 | { 54 | "mcpServers": { 55 | "watchbase-mcp": { 56 | "command": "/path/to/watchbase-mcp/build/index.js" 57 | } 58 | } 59 | } 60 | ``` 61 | 62 | ### Debugging 63 | 64 | Since MCP servers communicate over stdio, debugging can be challenging. We recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector), which is available as a package script: 65 | 66 | ```bash 67 | npm run inspector 68 | ``` 69 | 70 | The Inspector will provide a URL to access debugging tools in your browser. 71 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown 1 | # WatchBase MCP Server 2 | 3 | An MCP (Model Context Protocol) server providing access to the WatchBase Data Feed API for querying watch metadata. 4 | 5 | ## About WatchBase API 6 | 7 | The WatchBase Data Feed API provides structured access to a comprehensive database of watch information, including brands, families (collections), specific watch models, reference numbers, technical details, and images. It allows developers to integrate detailed watch data into their applications. More information can be found on the [WatchBase API Documentation](https://api.watchbase.com/docs). 8 | 9 | ## Features 10 | 11 | This MCP server exposes the following tools corresponding to the WatchBase API endpoints: 12 | 13 | * **`search`**: Search the database by brand name, family name, watch name, and reference number (matches whole words). 14 | * **`search_refnr`**: Search the database by reference number (allows partial matches). 15 | * **`list_brands`**: Retrieve a list of all watch brands in the database. 16 | * **`list_families`**: Retrieve a list of all families (collections) for a given brand ID. 17 | * **`list_watches`**: Retrieve a list of watches for a particular Brand ID and optionally Family ID. Can be filtered by update date. 18 | * **`get_watch_details`**: Retrieve the full details (all data fields) for a particular watch by its WatchBase ID. 19 | 20 | ## Prerequisites 21 | 22 | * **Node.js and npm:** Required to install dependencies and run the server. 23 | * **WatchBase API Key:** You need an API key from WatchBase. Visit the [WatchBase API page](https://api.watchbase.com/) to request access and obtain a key. 24 | 25 | ## Installation 26 | 27 | 1. **Clone the repository:** 28 | ```bash 29 | git clone https://github.com/watchdealer-pavel/watchbase-mcp.git 30 | cd watchbase-mcp 31 | ``` 32 | 33 | 2. **Install dependencies:** 34 | ```bash 35 | npm install 36 | ``` 37 | 38 | 3. **Build the server:** 39 | ```bash 40 | npm run build 41 | ``` 42 | This command compiles the TypeScript source code into JavaScript, placing the output in the `build/` directory (specifically `build/index.js`). 43 | 44 | ## Configuration 45 | 46 | The server requires your WatchBase API key to be provided via the `WATCHBASE_API_KEY` environment variable. You need to configure your MCP client (like Cline/Roo Code or the Claude Desktop App) to run this server and pass the environment variable. 47 | 48 | **Example Configuration:** 49 | 50 | Below are examples for common MCP clients. **Remember to replace `/path/to/your/watchbase-mcp/build/index.js` with the actual absolute path to the compiled server file on your system, and `YOUR_WATCHBASE_API_KEY` with your real WatchBase API key.** 51 | 52 | ### Cline / Roo Code (VS Code Extension) 53 | 54 | 1. Open your VS Code settings for MCP servers. On macOS, this is typically located at: 55 | `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` 56 | *(Note: The exact path might vary based on your operating system and VS Code installation type. For Roo Code, replace `saoudrizwan.claude-dev` with `rooveterinaryinc.roo-cline`)* 57 | 58 | 2. Add the following configuration block under the `mcpServers` key: 59 | 60 | ```json 61 | "watchbase-mcp": { 62 | "command": "node", 63 | "args": ["/path/to/your/watchbase-mcp/build/index.js"], // <-- IMPORTANT: Replace with the ACTUAL absolute path to build/index.js 64 | "env": { 65 | "WATCHBASE_API_KEY": "YOUR_WATCHBASE_API_KEY" // <-- IMPORTANT: Replace with your WatchBase API Key 66 | }, 67 | "disabled": false, 68 | "autoApprove": [] // Or add specific tools you want to auto-approve 69 | } 70 | ``` 71 | 72 | ### Claude Desktop App 73 | 74 | 1. Open the Claude Desktop App configuration file. On macOS, this is typically located at: 75 | `~/Library/Application Support/Claude/claude_desktop_config.json` 76 | *(Note: The exact path might vary based on your operating system.)* 77 | 78 | 2. Add the following configuration block under the `mcpServers` key: 79 | 80 | ```json 81 | "watchbase-mcp": { 82 | "command": "node", 83 | "args": ["/path/to/your/watchbase-mcp/build/index.js"], // <-- IMPORTANT: Replace with the ACTUAL absolute path to build/index.js 84 | "env": { 85 | "WATCHBASE_API_KEY": "YOUR_WATCHBASE_API_KEY" // <-- IMPORTANT: Replace with your WatchBase API Key 86 | }, 87 | "disabled": false, 88 | "autoApprove": [] // Or add specific tools you want to auto-approve 89 | } 90 | ``` 91 | 92 | ## Usage 93 | 94 | Once configured, you can invoke the server's tools from your AI assistant using the `use_mcp_tool` command/tool. 95 | 96 | ### `search` Example 97 | 98 | ```xml 99 | <use_mcp_tool> 100 | <server_name>watchbase-mcp</server_name> 101 | <tool_name>search</tool_name> 102 | <arguments> 103 | { 104 | "q": "priors court" 105 | } 106 | </arguments> 107 | </use_mcp_tool> 108 | ``` 109 | 110 | ### `search_refnr` Example 111 | 112 | ```xml 113 | <use_mcp_tool> 114 | <server_name>watchbase-mcp</server_name> 115 | <tool_name>search_refnr</tool_name> 116 | <arguments> 117 | { 118 | "q": "P2/" 119 | } 120 | </arguments> 121 | </use_mcp_tool> 122 | ``` 123 | 124 | ### `list_brands` Example 125 | 126 | ```xml 127 | <use_mcp_tool> 128 | <server_name>watchbase-mcp</server_name> 129 | <tool_name>list_brands</tool_name> 130 | <arguments> 131 | {} 132 | </arguments> 133 | </use_mcp_tool> 134 | ``` 135 | 136 | ### `list_families` Example 137 | 138 | ```xml 139 | <use_mcp_tool> 140 | <server_name>watchbase-mcp</server_name> 141 | <tool_name>list_families</tool_name> 142 | <arguments> 143 | { 144 | "brand_id": 37 145 | } 146 | </arguments> 147 | </use_mcp_tool> 148 | ``` 149 | 150 | ### `list_watches` Example 151 | 152 | ```xml 153 | <use_mcp_tool> 154 | <server_name>watchbase-mcp</server_name> 155 | <tool_name>list_watches</tool_name> 156 | <arguments> 157 | { 158 | "brand_id": 37, 159 | "family_id": 279 160 | } 161 | </arguments> 162 | </use_mcp_tool> 163 | ``` 164 | 165 | ### `get_watch_details` Example 166 | 167 | ```xml 168 | <use_mcp_tool> 169 | <server_name>watchbase-mcp</server_name> 170 | <tool_name>get_watch_details</tool_name> 171 | <arguments> 172 | { 173 | "id": 17289 174 | } 175 | </arguments> 176 | </use_mcp_tool> 177 | ``` 178 | 179 | ## License 180 | 181 | This MCP server project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 182 | 183 | Please also refer to WatchBase terms of service regarding API usage. 184 | ``` -------------------------------------------------------------------------------- /watchbase-mcp/tsconfig.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "outDir": "./build", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "include": ["src/**/*"], 14 | "exclude": ["node_modules"] 15 | } 16 | ``` -------------------------------------------------------------------------------- /watchbase-mcp/package.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "name": "watchbase-mcp", 3 | "version": "0.1.0", 4 | "description": "Structured and standardized querying of watch-related metadata such as brands, families, and reference details from WatchBase.com", 5 | "private": true, 6 | "type": "module", 7 | "bin": { 8 | "watchbase-mcp": "./build/index.js" 9 | }, 10 | "files": [ 11 | "build" 12 | ], 13 | "scripts": { 14 | "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 15 | "prepare": "npm run build", 16 | "watch": "tsc --watch", 17 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 18 | }, 19 | "dependencies": { 20 | "@modelcontextprotocol/sdk": "0.6.0" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^20.11.24", 24 | "typescript": "^5.3.3" 25 | } 26 | } 27 | ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "name": "watchbase-mcp", 3 | "version": "0.1.0", 4 | "description": "Structured and standardized querying of watch-related metadata such as brands families and reference details from WatchBase.com", 5 | "main": "build/index.js", 6 | "type": "module", 7 | "scripts": { 8 | "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 9 | "watch": "tsc --watch", 10 | "start": "node build/index.js", 11 | "dev": "npm run watch & nodemon build/index.js", 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "bin": { 15 | "watchbase-mcp": "build/index.js" 16 | }, 17 | "keywords": [ 18 | "mcp", 19 | "watchbase", 20 | "watches" 21 | ], 22 | "author": "Cline", 23 | "license": "ISC", 24 | "dependencies": { 25 | "@modelcontextprotocol/sdk": "^1.9.0", 26 | "axios": "^1.8.4" 27 | }, 28 | "devDependencies": { 29 | "@types/node": "^20.11.19", 30 | "nodemon": "^3.0.3", 31 | "typescript": "^5.3.3" 32 | } 33 | } 34 | ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", // Target modern ECMAScript version 4 | "module": "NodeNext", // Use Node.js native ES module support 5 | "moduleResolution": "NodeNext", // Module resolution strategy for NodeNext 6 | "outDir": "./build", // Output directory for compiled JavaScript 7 | "rootDir": "./src", // Root directory of source files 8 | "lib": ["ES2022", "DOM"], // Add ES library definitions 9 | "strict": true, // Enable all strict type-checking options 10 | "esModuleInterop": true, // Enables compatibility with CommonJS modules 11 | "skipLibCheck": true, // Skip type checking of declaration files 12 | "forceConsistentCasingInFileNames": true, // Disallow inconsistently-cased references 13 | "resolveJsonModule": true, // Allow importing JSON files 14 | "declaration": true, // Generate corresponding '.d.ts' files 15 | "sourceMap": true // Generate source maps for debugging 16 | }, 17 | "include": ["src/**/*"], // Include all files in the src directory 18 | "exclude": ["node_modules", "build"] // Exclude node_modules and build output 19 | } 20 | ``` -------------------------------------------------------------------------------- /watchbase_api_reference.md: -------------------------------------------------------------------------------- ```markdown 1 | # WatchBase Data Feed API (v1) 2 | _A concise reference for building an API connector_ 3 | 4 | > **Base URL:** `https://api.watchbase.com/v1/` 5 | > **Auth:** Every request must include `key=<YOUR_API_KEY>` as a query or POST parameter. 6 | > **Response formats:** XML (default) or JSON via `format=json`. 7 | 8 | --- 9 | 10 | ## 1 · Search Endpoints 11 | 12 | | Endpoint | Purpose | Required params | Optional params | Notes | 13 | |----------|---------|-----------------|-----------------|-------| 14 | | **`GET /search`** | Whole-word search across brand, family, watch name & reference number | `q` | `format` | Exact-match on words. | 15 | | **`GET /search/refnr`** | Sub-string search on reference numbers | `q` | `format` | Use for partial ref. numbers.| 16 | 17 | Example: 18 | 19 | ``` 20 | /search?q=priors+court&key=YOUR_KEY 21 | /search/refnr?q=p2/&key=YOUR_KEY&format=json 22 | ``` 23 | 24 | --- 25 | 26 | ## 2 · Reference Lists 27 | 28 | | Endpoint | Purpose | Required params | Optional params | 29 | |----------|---------|-----------------|-----------------| 30 | | **`GET /brands`** | All brands (`id`, `name`) | — | `format` | 31 | | **`GET /families`** | Families for a brand | `brand-id` | `format` | 32 | 33 | --- 34 | 35 | ## 3 · Watch Collections 36 | 37 | | Endpoint | Purpose | Required params | Optional params | Tip | 38 | |----------|---------|-----------------|-----------------|-----| 39 | | **`GET /watches`** | List watches for a brand and/or family | `brand-id` | `family-id`, `updated-since (YYYY-MM-DD)`, `format` | Use `updated-since` for incremental syncs. | 40 | | **`GET /watch`** | Full detail for one watch | `id` | `format` | Returns every data field (specs, images, metadata). | 41 | 42 | --- 43 | 44 | ## 4 · Entity Schemas (JSON) 45 | 46 | <details> 47 | <summary>⚙️ Click to view simplified field layout</summary> 48 | 49 | **Brand** 50 | ```jsonc 51 | { 52 | "id": 59, 53 | "name": "Audemars Piguet" 54 | } 55 | ``` 56 | 57 | **Family** 58 | ```jsonc 59 | { 60 | "id": 234, 61 | "name": "P-Series" 62 | } 63 | ``` 64 | 65 | **Watch (list response)** 66 | ```jsonc 67 | { 68 | "id": 11702, 69 | "refnr": "M1", 70 | "name": "M1", 71 | "brand": { ... }, 72 | "family": { ... }, 73 | "thumb": "http://cdn.watchbase.com/watch/medium/...", 74 | "updated": "2016-02-25" 75 | } 76 | ``` 77 | 78 | **Watch (detail response)** – adds nested objects such as `caliber`, `case`, `dial`, plus meta‐dates (`added`, `modified`, `published`). 79 | </details> 80 | 81 | --- 82 | 83 | ## 5 · Typical Integration Workflow 84 | 85 | 1. **Seed lookup tables** 86 | - `GET /brands` → store locally. 87 | - For each brand: `GET /families?brand-id={id}`. 88 | 89 | 2. **Initial import** 90 | - `GET /watches?brand-id={id}` (or include `family-id`) to pull IDs & basic data. 91 | 92 | 3. **Incremental updates** 93 | - Daily/weekly: `GET /watches?brand-id={id}&updated-since={YYYY-MM-DD}`. 94 | 95 | 4. **On-demand detail** 96 | - `GET /watch?id={watchId}` whenever full specifications are needed. 97 | 98 | --- 99 | 100 | ## 6 · Design Notes & Alternatives 101 | 102 | | Approach | When to choose it | Trade-offs | 103 | |----------|------------------|------------| 104 | | **Local mirror** of full watch details | Heavy read load, advanced search, offline ops | Larger storage; must schedule updates. | 105 | | **On-demand detail fetch** | Occasional look-ups, small apps | Slower first load; dependent on API uptime. | 106 | 107 | Additional tips: 108 | 109 | * Thumbnails in list results use `/medium/`; swap with `/large/` for hi-res images. 110 | * Rate limits are not documented—throttle conservatively and implement retry/backoff logic. 111 | * Check `num_results` before iterating to avoid null arrays. 112 | * Search endpoint is **whole-word**; use `/search/refnr` for fuzzy matching. 113 | 114 | --- 115 | 116 | ## 7 · Error Handling 117 | 118 | | HTTP Code | Likely cause | Suggested action | 119 | |-----------|--------------|------------------| 120 | | `401 / 403` | Missing or invalid `key` | Verify key, regenerate if needed | 121 | | `400` | Bad parameter name or type | Validate query string / body | 122 | | `500` | WatchBase internal error | Retry with backoff, alert if persistent | 123 | 124 | --- 125 | 126 | ## 8 · Change Log Strategy 127 | 128 | Store these dates per watch to detect changes: 129 | 130 | * `added` – first import date 131 | * `modified` – last metadata edit 132 | * `published` – publication date 133 | * `updated` (list responses) – identical to latest `modified` 134 | 135 | Use whichever best fits your sync policy (e.g., `modified >= lastSync`). 136 | 137 | --- 138 | 139 | _Source: [WatchBase Data Feed API documentation](https://watchbase.com/data-feed), accessed May 12 2025._ 140 | ``` -------------------------------------------------------------------------------- /watchbase-mcp/src/index.ts: -------------------------------------------------------------------------------- ```typescript 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * This is a template MCP server that implements a simple notes system. 5 | * It demonstrates core MCP concepts like resources and tools by allowing: 6 | * - Listing notes as resources 7 | * - Reading individual notes 8 | * - Creating new notes via a tool 9 | * - Summarizing all notes via a prompt 10 | */ 11 | 12 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 13 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 14 | import { 15 | CallToolRequestSchema, 16 | ListResourcesRequestSchema, 17 | ListToolsRequestSchema, 18 | ReadResourceRequestSchema, 19 | ListPromptsRequestSchema, 20 | GetPromptRequestSchema, 21 | } from "@modelcontextprotocol/sdk/types.js"; 22 | 23 | /** 24 | * Type alias for a note object. 25 | */ 26 | type Note = { title: string, content: string }; 27 | 28 | /** 29 | * Simple in-memory storage for notes. 30 | * In a real implementation, this would likely be backed by a database. 31 | */ 32 | const notes: { [id: string]: Note } = { 33 | "1": { title: "First Note", content: "This is note 1" }, 34 | "2": { title: "Second Note", content: "This is note 2" } 35 | }; 36 | 37 | /** 38 | * Create an MCP server with capabilities for resources (to list/read notes), 39 | * tools (to create new notes), and prompts (to summarize notes). 40 | */ 41 | const server = new Server( 42 | { 43 | name: "watchbase-mcp", 44 | version: "0.1.0", 45 | }, 46 | { 47 | capabilities: { 48 | resources: {}, 49 | tools: {}, 50 | prompts: {}, 51 | }, 52 | } 53 | ); 54 | 55 | /** 56 | * Handler for listing available notes as resources. 57 | * Each note is exposed as a resource with: 58 | * - A note:// URI scheme 59 | * - Plain text MIME type 60 | * - Human readable name and description (now including the note title) 61 | */ 62 | server.setRequestHandler(ListResourcesRequestSchema, async () => { 63 | return { 64 | resources: Object.entries(notes).map(([id, note]) => ({ 65 | uri: `note:///${id}`, 66 | mimeType: "text/plain", 67 | name: note.title, 68 | description: `A text note: ${note.title}` 69 | })) 70 | }; 71 | }); 72 | 73 | /** 74 | * Handler for reading the contents of a specific note. 75 | * Takes a note:// URI and returns the note content as plain text. 76 | */ 77 | server.setRequestHandler(ReadResourceRequestSchema, async (request) => { 78 | const url = new URL(request.params.uri); 79 | const id = url.pathname.replace(/^\//, ''); 80 | const note = notes[id]; 81 | 82 | if (!note) { 83 | throw new Error(`Note ${id} not found`); 84 | } 85 | 86 | return { 87 | contents: [{ 88 | uri: request.params.uri, 89 | mimeType: "text/plain", 90 | text: note.content 91 | }] 92 | }; 93 | }); 94 | 95 | /** 96 | * Handler that lists available tools. 97 | * Exposes a single "create_note" tool that lets clients create new notes. 98 | */ 99 | server.setRequestHandler(ListToolsRequestSchema, async () => { 100 | return { 101 | tools: [ 102 | { 103 | name: "create_note", 104 | description: "Create a new note", 105 | inputSchema: { 106 | type: "object", 107 | properties: { 108 | title: { 109 | type: "string", 110 | description: "Title of the note" 111 | }, 112 | content: { 113 | type: "string", 114 | description: "Text content of the note" 115 | } 116 | }, 117 | required: ["title", "content"] 118 | } 119 | } 120 | ] 121 | }; 122 | }); 123 | 124 | /** 125 | * Handler for the create_note tool. 126 | * Creates a new note with the provided title and content, and returns success message. 127 | */ 128 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 129 | switch (request.params.name) { 130 | case "create_note": { 131 | const title = String(request.params.arguments?.title); 132 | const content = String(request.params.arguments?.content); 133 | if (!title || !content) { 134 | throw new Error("Title and content are required"); 135 | } 136 | 137 | const id = String(Object.keys(notes).length + 1); 138 | notes[id] = { title, content }; 139 | 140 | return { 141 | content: [{ 142 | type: "text", 143 | text: `Created note ${id}: ${title}` 144 | }] 145 | }; 146 | } 147 | 148 | default: 149 | throw new Error("Unknown tool"); 150 | } 151 | }); 152 | 153 | /** 154 | * Handler that lists available prompts. 155 | * Exposes a single "summarize_notes" prompt that summarizes all notes. 156 | */ 157 | server.setRequestHandler(ListPromptsRequestSchema, async () => { 158 | return { 159 | prompts: [ 160 | { 161 | name: "summarize_notes", 162 | description: "Summarize all notes", 163 | } 164 | ] 165 | }; 166 | }); 167 | 168 | /** 169 | * Handler for the summarize_notes prompt. 170 | * Returns a prompt that requests summarization of all notes, with the notes' contents embedded as resources. 171 | */ 172 | server.setRequestHandler(GetPromptRequestSchema, async (request) => { 173 | if (request.params.name !== "summarize_notes") { 174 | throw new Error("Unknown prompt"); 175 | } 176 | 177 | const embeddedNotes = Object.entries(notes).map(([id, note]) => ({ 178 | type: "resource" as const, 179 | resource: { 180 | uri: `note:///${id}`, 181 | mimeType: "text/plain", 182 | text: note.content 183 | } 184 | })); 185 | 186 | return { 187 | messages: [ 188 | { 189 | role: "user", 190 | content: { 191 | type: "text", 192 | text: "Please summarize the following notes:" 193 | } 194 | }, 195 | ...embeddedNotes.map(note => ({ 196 | role: "user" as const, 197 | content: note 198 | })), 199 | { 200 | role: "user", 201 | content: { 202 | type: "text", 203 | text: "Provide a concise summary of all the notes above." 204 | } 205 | } 206 | ] 207 | }; 208 | }); 209 | 210 | /** 211 | * Start the server using stdio transport. 212 | * This allows the server to communicate via standard input/output streams. 213 | */ 214 | async function main() { 215 | const transport = new StdioServerTransport(); 216 | await server.connect(transport); 217 | } 218 | 219 | main().catch((error) => { 220 | console.error("Server error:", error); 221 | process.exit(1); 222 | }); 223 | ``` -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- ```typescript 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 | ErrorCode, 7 | ListToolsRequestSchema, 8 | McpError, 9 | // ToolDefinition removed - type will be inferred or is not needed explicitly 10 | } from '@modelcontextprotocol/sdk/types.js'; 11 | import axios, { type AxiosInstance, type AxiosError } from 'axios'; 12 | 13 | // Retrieve API key from environment variable set in MCP settings 14 | const API_KEY = process.env.WATCHBASE_API_KEY; 15 | if (!API_KEY) { 16 | console.error('WATCHBASE_API_KEY environment variable is required'); 17 | process.exit(1); // Exit if API key is not provided 18 | } 19 | 20 | // --- Type guards for tool arguments --- 21 | 22 | const isSearchArgs = (args: any): args is { q: string } => 23 | typeof args === 'object' && args !== null && typeof args.q === 'string'; 24 | 25 | const isListFamiliesArgs = (args: any): args is { brand_id: string | number } => 26 | typeof args === 'object' && 27 | args !== null && 28 | (typeof args.brand_id === 'string' || typeof args.brand_id === 'number'); 29 | 30 | const isListWatchesArgs = ( 31 | args: any 32 | ): args is { 33 | brand_id: string | number; 34 | family_id?: string | number; 35 | updated_since?: string; 36 | } => 37 | typeof args === 'object' && 38 | args !== null && 39 | (typeof args.brand_id === 'string' || typeof args.brand_id === 'number') && 40 | (args.family_id === undefined || 41 | typeof args.family_id === 'string' || 42 | typeof args.family_id === 'number') && 43 | (args.updated_since === undefined || 44 | (typeof args.updated_since === 'string' && 45 | /^\d{4}-\d{2}-\d{2}$/.test(args.updated_since))); // Basic YYYY-MM-DD check 46 | 47 | const isGetWatchDetailsArgs = (args: any): args is { id: string | number } => 48 | typeof args === 'object' && 49 | args !== null && 50 | (typeof args.id === 'string' || typeof args.id === 'number'); 51 | 52 | // --- Main Server Class --- 53 | 54 | class WatchBaseServer { 55 | private server: Server; 56 | private axiosInstance: AxiosInstance; 57 | 58 | constructor() { 59 | this.server = new Server( 60 | { 61 | name: 'watchbase-mcp', 62 | version: '0.1.0', 63 | description: 64 | 'Structured and standardized querying of watch-related metadata such as brands families and reference details from WatchBase.com', 65 | }, 66 | { 67 | capabilities: { 68 | resources: {}, // No resources defined for this server 69 | tools: {}, 70 | }, 71 | } 72 | ); 73 | 74 | this.axiosInstance = axios.create({ 75 | baseURL: 'https://api.watchbase.com/v1/', 76 | params: { 77 | key: API_KEY, 78 | format: 'json', // Default to JSON format 79 | }, 80 | timeout: 15000, // 15 second timeout 81 | }); 82 | 83 | this.setupToolHandlers(); 84 | 85 | // Basic error handling 86 | this.server.onerror = (error) => console.error('[MCP Error]', error); 87 | process.on('SIGINT', async () => { 88 | await this.server.close(); 89 | process.exit(0); 90 | }); 91 | process.on('SIGTERM', async () => { 92 | await this.server.close(); 93 | process.exit(0); 94 | }); 95 | } 96 | 97 | private setupToolHandlers() { 98 | // Type annotation removed for tools - structure defines the type 99 | const tools = [ 100 | { 101 | name: 'search', 102 | description: 103 | 'Search the database by brand name, family name, watch name and reference number (whole words).', 104 | inputSchema: { 105 | type: 'object', 106 | properties: { 107 | q: { type: 'string', description: 'Search keywords' }, 108 | }, 109 | required: ['q'], 110 | }, 111 | }, 112 | { 113 | name: 'search_refnr', 114 | description: 115 | 'Search the database by reference number (allows partial matches).', 116 | inputSchema: { 117 | type: 'object', 118 | properties: { 119 | q: { type: 'string', description: 'Search keywords (reference number)' }, 120 | }, 121 | required: ['q'], 122 | }, 123 | }, 124 | { 125 | name: 'list_brands', 126 | description: 'Retrieve a list of all brands in the database.', 127 | inputSchema: { type: 'object', properties: {} }, // No input required 128 | }, 129 | { 130 | name: 'list_families', 131 | description: 'Retrieve a list of all families for a given brand.', 132 | inputSchema: { 133 | type: 'object', 134 | properties: { 135 | brand_id: { 136 | oneOf: [{ type: 'string' }, { type: 'number' }], 137 | description: 'BrandID of the brand', 138 | }, 139 | }, 140 | required: ['brand_id'], 141 | }, 142 | }, 143 | { 144 | name: 'list_watches', 145 | description: 146 | 'Retrieve a list of watches for a particular Brand and/or Family, optionally filtered by update date.', 147 | inputSchema: { 148 | type: 'object', 149 | properties: { 150 | brand_id: { 151 | oneOf: [{ type: 'string' }, { type: 'number' }], 152 | description: 'BrandID of the brand', 153 | }, 154 | family_id: { 155 | oneOf: [{ type: 'string' }, { type: 'number' }], 156 | description: 'Optional: FamilyID of the family', 157 | }, 158 | updated_since: { 159 | type: 'string', 160 | format: 'date', // Indicates YYYY-MM-DD format 161 | description: 162 | 'Optional: Limit results to watches updated after this date (YYYY-MM-DD)', 163 | }, 164 | }, 165 | required: ['brand_id'], 166 | }, 167 | }, 168 | { 169 | name: 'get_watch_details', 170 | description: 'Retrieve the full details for a particular watch by its ID.', 171 | inputSchema: { 172 | type: 'object', 173 | properties: { 174 | id: { 175 | oneOf: [{ type: 'string' }, { type: 'number' }], 176 | description: 'ID of the watch', 177 | }, 178 | }, 179 | required: ['id'], 180 | }, 181 | }, 182 | ]; 183 | 184 | this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools })); 185 | 186 | this.server.setRequestHandler(CallToolRequestSchema, async (request) => { 187 | const { name, arguments: args } = request.params; 188 | let apiPath = ''; 189 | let apiParams: Record<string, any> = {}; 190 | 191 | try { 192 | switch (name) { 193 | case 'search': 194 | if (!isSearchArgs(args)) throw new McpError(ErrorCode.InvalidParams, 'Invalid arguments for search'); 195 | apiPath = 'search'; 196 | apiParams = { q: args.q }; 197 | break; 198 | 199 | case 'search_refnr': 200 | if (!isSearchArgs(args)) throw new McpError(ErrorCode.InvalidParams, 'Invalid arguments for search_refnr'); 201 | apiPath = 'search/refnr'; 202 | apiParams = { q: args.q }; 203 | break; 204 | 205 | case 'list_brands': 206 | // No specific argument validation needed 207 | apiPath = 'brands'; 208 | break; 209 | 210 | case 'list_families': 211 | if (!isListFamiliesArgs(args)) throw new McpError(ErrorCode.InvalidParams, 'Invalid arguments for list_families'); 212 | apiPath = 'families'; 213 | apiParams = { 'brand-id': args.brand_id }; // API uses hyphen 214 | break; 215 | 216 | case 'list_watches': 217 | if (!isListWatchesArgs(args)) throw new McpError(ErrorCode.InvalidParams, 'Invalid arguments for list_watches'); 218 | apiPath = 'watches'; 219 | apiParams = { 'brand-id': args.brand_id }; // API uses hyphen 220 | if (args.family_id !== undefined) { 221 | apiParams['family-id'] = args.family_id; // API uses hyphen 222 | } 223 | if (args.updated_since !== undefined) { 224 | apiParams['updated-since'] = args.updated_since; // API uses hyphen 225 | } 226 | break; 227 | 228 | case 'get_watch_details': 229 | if (!isGetWatchDetailsArgs(args)) throw new McpError(ErrorCode.InvalidParams, 'Invalid arguments for get_watch_details'); 230 | apiPath = 'watch'; 231 | apiParams = { id: args.id }; 232 | break; 233 | 234 | default: 235 | throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`); 236 | } 237 | 238 | // Make the API call 239 | const response = await this.axiosInstance.get(apiPath, { params: apiParams }); 240 | 241 | // Return successful response 242 | return { 243 | content: [ 244 | { 245 | type: 'text', // Corrected type to 'text' 246 | text: JSON.stringify(response.data, null, 2), // JSON content is in the text field 247 | }, 248 | ], 249 | }; 250 | } catch (error) { 251 | console.error(`Error calling tool ${name}:`, error); // Log the error server-side 252 | 253 | let errorMessage = `Failed to execute tool ${name}.`; 254 | let errorCode = ErrorCode.InternalError; 255 | 256 | if (axios.isAxiosError(error)) { 257 | const axiosError = error as AxiosError<any>; 258 | errorMessage = `WatchBase API error: ${axiosError.response?.data?.error || axiosError.response?.statusText || axiosError.message}`; 259 | // Map HTTP status codes to MCP error codes if desired 260 | if (axiosError.response?.status === 401 || axiosError.response?.status === 403) { 261 | errorCode = ErrorCode.InternalError; // Changed from PermissionDenied 262 | errorMessage = `WatchBase API error: Invalid or unauthorized API key. Status: ${axiosError.response?.status}`; 263 | } else if (axiosError.response?.status === 404) { 264 | errorCode = ErrorCode.InvalidRequest; // Changed from NotFound 265 | errorMessage = `WatchBase API error: Resource not found. Status: 404`; 266 | } else if (axiosError.response?.status === 400) { 267 | errorCode = ErrorCode.InvalidParams; // Bad request, likely invalid params 268 | errorMessage = `WatchBase API error: Bad request (check parameters). Status: 400. ${axiosError.response?.data?.error || ''}`; 269 | } 270 | } else if (error instanceof McpError) { 271 | // Re-throw specific MCP errors (like InvalidParams, MethodNotFound) 272 | throw error; 273 | } 274 | 275 | // Return error content 276 | return { 277 | content: [ 278 | { 279 | type: 'text', 280 | text: errorMessage, 281 | }, 282 | ], 283 | isError: true, 284 | errorCode: errorCode, // Provide specific error code 285 | }; 286 | } 287 | }); 288 | } 289 | 290 | async run() { 291 | const transport = new StdioServerTransport(); 292 | await this.server.connect(transport); 293 | // Use console.error for logs to avoid interfering with MCP stdout communication 294 | console.error('WatchBase MCP server running on stdio'); 295 | } 296 | } 297 | 298 | // Instantiate and run the server 299 | const server = new WatchBaseServer(); 300 | server.run().catch((err) => { 301 | console.error('Server failed to start:', err); 302 | process.exit(1); 303 | }); 304 | ```