#
tokens: 12966/50000 10/10 files
lines: off (toggle) GitHub
raw markdown copy
# Directory Structure

```
├── build
│   ├── CacheManager.d.ts
│   ├── CacheManager.js
│   ├── index.d.ts
│   ├── index.js
│   ├── types.d.ts
│   └── types.js
├── config.json
├── Dockerfile
├── node_modules
│   ├── .bin
│   │   ├── tsc
│   │   └── tsserver
│   ├── .package-lock.json
│   ├── @modelcontextprotocol
│   │   └── sdk
│   │       ├── dist
│   │       │   ├── cli.d.ts
│   │       │   ├── cli.d.ts.map
│   │       │   ├── cli.js
│   │       │   ├── cli.js.map
│   │       │   ├── client
│   │       │   │   ├── index.d.ts
│   │       │   │   ├── index.d.ts.map
│   │       │   │   ├── index.js
│   │       │   │   ├── index.js.map
│   │       │   │   ├── index.test.d.ts
│   │       │   │   ├── index.test.d.ts.map
│   │       │   │   ├── index.test.js
│   │       │   │   ├── index.test.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
│   │       │   │   ├── stdio.test.d.ts
│   │       │   │   ├── stdio.test.d.ts.map
│   │       │   │   ├── stdio.test.js
│   │       │   │   ├── stdio.test.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
│   │       │   ├── inMemory.test.d.ts
│   │       │   ├── inMemory.test.d.ts.map
│   │       │   ├── inMemory.test.js
│   │       │   ├── inMemory.test.js.map
│   │       │   ├── server
│   │       │   │   ├── index.d.ts
│   │       │   │   ├── index.d.ts.map
│   │       │   │   ├── index.js
│   │       │   │   ├── index.js.map
│   │       │   │   ├── index.test.d.ts
│   │       │   │   ├── index.test.d.ts.map
│   │       │   │   ├── index.test.js
│   │       │   │   ├── index.test.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
│   │       │   │   ├── stdio.test.d.ts
│   │       │   │   ├── stdio.test.d.ts.map
│   │       │   │   ├── stdio.test.js
│   │       │   │   └── stdio.test.js.map
│   │       │   ├── shared
│   │       │   │   ├── protocol.d.ts
│   │       │   │   ├── protocol.d.ts.map
│   │       │   │   ├── protocol.js
│   │       │   │   ├── protocol.js.map
│   │       │   │   ├── stdio.d.ts
│   │       │   │   ├── stdio.d.ts.map
│   │       │   │   ├── stdio.js
│   │       │   │   ├── stdio.js.map
│   │       │   │   ├── stdio.test.d.ts
│   │       │   │   ├── stdio.test.d.ts.map
│   │       │   │   ├── stdio.test.js
│   │       │   │   ├── stdio.test.js.map
│   │       │   │   ├── transport.d.ts
│   │       │   │   ├── transport.d.ts.map
│   │       │   │   ├── transport.js
│   │       │   │   └── transport.js.map
│   │       │   ├── types.d.ts
│   │       │   ├── types.d.ts.map
│   │       │   ├── types.js
│   │       │   └── types.js.map
│   │       ├── LICENSE
│   │       ├── package.json
│   │       └── README.md
│   ├── @types
│   │   ├── fs-extra
│   │   │   ├── esm.d.mts
│   │   │   ├── index.d.ts
│   │   │   ├── LICENSE
│   │   │   ├── package.json
│   │   │   └── README.md
│   │   ├── jsonfile
│   │   │   ├── index.d.ts
│   │   │   ├── LICENSE
│   │   │   ├── package.json
│   │   │   ├── README.md
│   │   │   └── utils.d.ts
│   │   └── 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
│   ├── bytes
│   │   ├── History.md
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── Readme.md
│   ├── content-type
│   │   ├── HISTORY.md
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── README.md
│   ├── depd
│   │   ├── History.md
│   │   ├── index.js
│   │   ├── lib
│   │   │   └── browser
│   │   │       └── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── Readme.md
│   ├── fs-extra
│   │   ├── lib
│   │   │   ├── copy
│   │   │   │   ├── copy-sync.js
│   │   │   │   ├── copy.js
│   │   │   │   └── index.js
│   │   │   ├── empty
│   │   │   │   └── index.js
│   │   │   ├── ensure
│   │   │   │   ├── file.js
│   │   │   │   ├── index.js
│   │   │   │   ├── link.js
│   │   │   │   ├── symlink-paths.js
│   │   │   │   ├── symlink-type.js
│   │   │   │   └── symlink.js
│   │   │   ├── esm.mjs
│   │   │   ├── fs
│   │   │   │   └── index.js
│   │   │   ├── index.js
│   │   │   ├── json
│   │   │   │   ├── index.js
│   │   │   │   ├── jsonfile.js
│   │   │   │   ├── output-json-sync.js
│   │   │   │   └── output-json.js
│   │   │   ├── mkdirs
│   │   │   │   ├── index.js
│   │   │   │   ├── make-dir.js
│   │   │   │   └── utils.js
│   │   │   ├── move
│   │   │   │   ├── index.js
│   │   │   │   ├── move-sync.js
│   │   │   │   └── move.js
│   │   │   ├── output-file
│   │   │   │   └── index.js
│   │   │   ├── path-exists
│   │   │   │   └── index.js
│   │   │   ├── remove
│   │   │   │   └── index.js
│   │   │   └── util
│   │   │       ├── stat.js
│   │   │       └── utimes.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── README.md
│   ├── graceful-fs
│   │   ├── clone.js
│   │   ├── graceful-fs.js
│   │   ├── legacy-streams.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── polyfills.js
│   │   └── 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
│   ├── jsonfile
│   │   ├── CHANGELOG.md
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── README.md
│   │   └── utils.js
│   ├── raw-body
│   │   ├── HISTORY.md
│   │   ├── index.d.ts
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── README.md
│   │   └── SECURITY.md
│   ├── safer-buffer
│   │   ├── dangerous.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── Porting-Buffer.md
│   │   ├── Readme.md
│   │   ├── safer.js
│   │   └── tests.js
│   ├── setprototypeof
│   │   ├── index.d.ts
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── README.md
│   │   └── test
│   │       └── index.js
│   ├── statuses
│   │   ├── codes.json
│   │   ├── HISTORY.md
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── README.md
│   ├── toidentifier
│   │   ├── HISTORY.md
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── README.md
│   ├── typescript
│   │   ├── bin
│   │   │   ├── tsc
│   │   │   └── tsserver
│   │   ├── lib
│   │   │   ├── _tsc.js
│   │   │   ├── _tsserver.js
│   │   │   ├── _typingsInstaller.js
│   │   │   ├── cancellationToken.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.full.d.ts
│   │   │   ├── lib.esnext.intl.d.ts
│   │   │   ├── lib.esnext.iterator.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
│   ├── 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
│   ├── universalify
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── README.md
│   ├── unpipe
│   │   ├── HISTORY.md
│   │   ├── index.js
│   │   ├── LICENSE
│   │   ├── package.json
│   │   └── README.md
│   └── zod
│       ├── index.d.ts
│       ├── lib
│       │   ├── __tests__
│       │   │   ├── Mocker.d.ts
│       │   │   └── Mocker.js
│       │   ├── benchmarks
│       │   │   ├── datetime.d.ts
│       │   │   ├── datetime.js
│       │   │   ├── discriminatedUnion.d.ts
│       │   │   ├── discriminatedUnion.js
│       │   │   ├── index.d.ts
│       │   │   ├── index.js
│       │   │   ├── ipv4.d.ts
│       │   │   ├── ipv4.js
│       │   │   ├── object.d.ts
│       │   │   ├── object.js
│       │   │   ├── primitives.d.ts
│       │   │   ├── primitives.js
│       │   │   ├── realworld.d.ts
│       │   │   ├── realworld.js
│       │   │   ├── string.d.ts
│       │   │   ├── string.js
│       │   │   ├── union.d.ts
│       │   │   └── union.js
│       │   ├── errors.d.ts
│       │   ├── errors.js
│       │   ├── external.d.ts
│       │   ├── external.js
│       │   ├── helpers
│       │   │   ├── enumUtil.d.ts
│       │   │   ├── enumUtil.js
│       │   │   ├── errorUtil.d.ts
│       │   │   ├── errorUtil.js
│       │   │   ├── parseUtil.d.ts
│       │   │   ├── parseUtil.js
│       │   │   ├── partialUtil.d.ts
│       │   │   ├── partialUtil.js
│       │   │   ├── typeAliases.d.ts
│       │   │   ├── typeAliases.js
│       │   │   ├── util.d.ts
│       │   │   └── util.js
│       │   ├── index.d.ts
│       │   ├── index.js
│       │   ├── index.mjs
│       │   ├── index.umd.js
│       │   ├── locales
│       │   │   ├── en.d.ts
│       │   │   └── en.js
│       │   ├── standard-schema.d.ts
│       │   ├── standard-schema.js
│       │   ├── types.d.ts
│       │   ├── types.js
│       │   ├── ZodError.d.ts
│       │   └── ZodError.js
│       ├── LICENSE
│       ├── package.json
│       └── README.md
├── package-lock.json
├── package.json
├── project.md
├── README.md
├── smithery.yaml
├── src
│   ├── CacheManager.ts
│   ├── index.ts
│   └── types.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# Memory Cache Server
[![smithery badge](https://smithery.ai/badge/@tosin2013/mcp-memory-cache-server)](https://smithery.ai/server/@tosin2013/mcp-memory-cache-server)

A Model Context Protocol (MCP) server that reduces token consumption by efficiently caching data between language model interactions. Works with any MCP client and any language model that uses tokens.

## Installation

### Installing via Smithery

To install Memory Cache Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@tosin2013/mcp-memory-cache-server):

```bash
npx -y @smithery/cli install @tosin2013/mcp-memory-cache-server --client claude
```

### Installing Manually
1. Clone the repository:
```bash
git clone https://github.com/tosin2013/mcp-memory-cache-server.git
cd mcp-memory-cache-server
```

2. Install dependencies:
```bash
npm install
```

3. Build the project:
```bash
npm run build
```

4. Add to your MCP client settings:
```json
{
  "mcpServers": {
    "memory-cache": {
      "command": "node",
      "args": ["/path/to/ib-mcp-cache-server/build/index.js"]
    }
  }
}
```

5. The server will automatically start when you use your MCP client

## Verifying It Works

When the server is running properly, you'll see:
1. A message in the terminal: "Memory Cache MCP server running on stdio"
2. Improved performance when accessing the same data multiple times
3. No action required from you - the caching happens automatically

You can verify the server is running by:
1. Opening your MCP client
2. Looking for any error messages in the terminal where you started the server
3. Performing operations that would benefit from caching (like reading the same file multiple times)

## Configuration

The server can be configured through `config.json` or environment variables:

```json
{
  "maxEntries": 1000,        // Maximum number of items in cache
  "maxMemory": 104857600,    // Maximum memory usage in bytes (100MB)
  "defaultTTL": 3600,        // Default time-to-live in seconds (1 hour)
  "checkInterval": 60000,    // Cleanup interval in milliseconds (1 minute)
  "statsInterval": 30000     // Stats update interval in milliseconds (30 seconds)
}
```

### Configuration Settings Explained

1. **maxEntries** (default: 1000)
   - Maximum number of items that can be stored in cache
   - Prevents cache from growing indefinitely
   - When exceeded, oldest unused items are removed first

2. **maxMemory** (default: 100MB)
   - Maximum memory usage in bytes
   - Prevents excessive memory consumption
   - When exceeded, least recently used items are removed

3. **defaultTTL** (default: 1 hour)
   - How long items stay in cache by default
   - Items are automatically removed after this time
   - Prevents stale data from consuming memory

4. **checkInterval** (default: 1 minute)
   - How often the server checks for expired items
   - Lower values keep memory usage more accurate
   - Higher values reduce CPU usage

5. **statsInterval** (default: 30 seconds)
   - How often cache statistics are updated
   - Affects accuracy of hit/miss rates
   - Helps monitor cache effectiveness

## How It Reduces Token Consumption

The memory cache server reduces token consumption by automatically storing data that would otherwise need to be re-sent between you and the language model. You don't need to do anything special - the caching happens automatically when you interact with any language model through your MCP client.

Here are some examples of what gets cached:

### 1. File Content Caching
When reading a file multiple times:
- First time: Full file content is read and cached
- Subsequent times: Content is retrieved from cache instead of re-reading the file
- Result: Fewer tokens used for repeated file operations

### 2. Computation Results
When performing calculations or analysis:
- First time: Full computation is performed and results are cached
- Subsequent times: Results are retrieved from cache if the input is the same
- Result: Fewer tokens used for repeated computations

### 3. Frequently Accessed Data
When the same data is needed multiple times:
- First time: Data is processed and cached
- Subsequent times: Data is retrieved from cache until TTL expires
- Result: Fewer tokens used for accessing the same information

## Automatic Cache Management

The server automatically manages the caching process by:
- Storing data when first encountered
- Serving cached data when available
- Removing old/unused data based on settings
- Tracking effectiveness through statistics

## Optimization Tips

### 1. Set Appropriate TTLs
- Shorter for frequently changing data
- Longer for static content

### 2. Adjust Memory Limits
- Higher for more caching (more token savings)
- Lower if memory usage is a concern

### 3. Monitor Cache Stats
- High hit rate = good token savings
- Low hit rate = adjust TTL or limits

## Environment Variable Configuration

You can override config.json settings using environment variables in your MCP settings:

```json
{
  "mcpServers": {
    "memory-cache": {
      "command": "node",
      "args": ["/path/to/build/index.js"],
      "env": {
        "MAX_ENTRIES": "5000",
        "MAX_MEMORY": "209715200",  // 200MB
        "DEFAULT_TTL": "7200",      // 2 hours
        "CHECK_INTERVAL": "120000",  // 2 minutes
        "STATS_INTERVAL": "60000"    // 1 minute
      }
    }
  }
}
```

You can also specify a custom config file location:
```json
{
  "env": {
    "CONFIG_PATH": "/path/to/your/config.json"
  }
}
```

The server will:
1. Look for config.json in its directory
2. Apply any environment variable overrides
3. Use default values if neither is specified

## Testing the Cache in Practice

To see the cache in action, try these scenarios:

1. **File Reading Test**
   - Read and analyze a large file
   - Ask the same question about the file again
   - The second response should be faster as the file content is cached

2. **Data Analysis Test**
   - Perform analysis on some data
   - Request the same analysis again
   - The second analysis should use cached results

3. **Project Navigation Test**
   - Explore a project's structure
   - Query the same files/directories again
   - Directory listings and file contents will be served from cache

The cache is working when you notice:
- Faster responses for repeated operations
- Consistent answers about unchanged content
- No need to re-read files that haven't changed

```

--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------

```json
{
  "maxEntries": 1000,
  "maxMemory": 104857600,
  "defaultTTL": 3600,
  "checkInterval": 60000,
  "statsInterval": 30000
}

```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ES2020",
    "moduleResolution": "node",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build"]
}

```

--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------

```typescript
export interface CacheEntry {
  value: any;
  created: number;
  lastAccessed: number;
  ttl?: number;
  size: number;
}

export interface CacheStats {
  totalEntries: number;
  memoryUsage: number;
  hits: number;
  misses: number;
  hitRate: number;
  avgAccessTime: number;
}

export interface CacheConfig {
  maxEntries?: number;
  maxMemory?: number;
  defaultTTL?: number;
  checkInterval?: number;
  statsInterval?: number;
}

```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "charly-memory-cache-server",
  "version": "1.0.0",
  "description": "MCP server for memory caching and optimization",
  "type": "module",
  "main": "build/index.js",
  "scripts": {
    "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
    "start": "node build/index.js",
    "dev": "tsc -w",
    "prepare": "npm run build",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "mcp",
    "cache",
    "memory",
    "optimization"
  ],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^20.10.6",
    "@types/fs-extra": "^11.0.4",
    "typescript": "^5.3.3"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "0.6.0",
    "fs-extra": "^11.2.0"
  }
}

```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
# Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
# Use a Node.js image to build the project
FROM node:18-alpine AS builder

# Set the working directory inside the container
WORKDIR /app

# Copy the package.json and package-lock.json files
COPY package.json package-lock.json ./

# Install dependencies
RUN npm install --ignore-scripts

# Copy the rest of the project files
COPY . .

# Build the project
RUN npm run build

# Use a lighter Node.js image for the production stage
FROM node:18-alpine

# Set the working directory inside the container
WORKDIR /app

# Copy the built files and node_modules from the builder stage
COPY --from=builder /app/build /app/build
COPY --from=builder /app/node_modules /app/node_modules
COPY --from=builder /app/package.json /app/package.json

# Set the entry point to start the server
ENTRYPOINT ["node", "build/index.js"]

```

--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------

```yaml
# Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml

startCommand:
  type: stdio
  configSchema:
    # JSON Schema defining the configuration options for the MCP.
    type: object
    required:
      - maxEntries
      - maxMemory
      - defaultTTL
      - checkInterval
      - statsInterval
    properties:
      maxEntries:
        type: number
        description: Maximum number of items in cache
      maxMemory:
        type: number
        description: Maximum memory usage in bytes
      defaultTTL:
        type: number
        description: Default time-to-live for cached items in seconds
      checkInterval:
        type: number
        description: Interval for checking expired items in milliseconds
      statsInterval:
        type: number
        description: Interval for updating cache statistics in milliseconds
  commandFunction:
    # A function that produces the CLI command to start the MCP on stdio.
    |-
    (config) => ({ command: 'node', args: ['build/index.js'], env: { MAX_ENTRIES: String(config.maxEntries), MAX_MEMORY: String(config.maxMemory), DEFAULT_TTL: String(config.defaultTTL), CHECK_INTERVAL: String(config.checkInterval), STATS_INTERVAL: String(config.statsInterval) } })

```

--------------------------------------------------------------------------------
/project.md:
--------------------------------------------------------------------------------

```markdown
# Charly Memory Cache Server - Technical Documentation

Repository: [email protected]:ibproduct/charlymcpcacheserver.git

## Architecture Overview

### Core Components

1. **CacheManager**
   - In-memory storage using Map
   - LRU eviction strategy
   - TTL management
   - Memory usage tracking
   - Statistics collection

2. **MCP Server**
   - Tool registration
   - Resource endpoints
   - Request handling
   - Error management

### Data Structures

```typescript
interface CacheEntry {
  value: any;          // Cached data
  created: number;     // Creation timestamp
  lastAccessed: number;// Last access timestamp
  ttl?: number;        // Time-to-live in seconds
  size: number;        // Memory size estimation
}

interface CacheStats {
  totalEntries: number;
  memoryUsage: number;
  hits: number;
  misses: number;
  hitRate: number;
  avgAccessTime: number;
}

interface CacheConfig {
  maxEntries?: number;
  maxMemory?: number;
  defaultTTL?: number;
  checkInterval?: number;
  statsInterval?: number;
}
```

## Implementation Details

### Memory Management

1. Size Calculation
```typescript
private calculateSize(value: any): number {
  const str = JSON.stringify(value);
  return str.length * 2; // UTF-16 encoding size
}
```

2. LRU Implementation
```typescript
private enforceMemoryLimit(requiredSize: number): void {
  const entries = Array.from(this.cache.entries())
    .sort(([, a], [, b]) => a.lastAccessed - b.lastAccessed);

  while (this.stats.memoryUsage + requiredSize > this.config.maxMemory 
         && entries.length > 0) {
    const [key] = entries.shift()!;
    this.delete(key);
  }
}
```

### MCP Integration

1. Tool Registration
```typescript
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: 'store_data',
      description: 'Store data in cache',
      inputSchema: {
        type: 'object',
        properties: {
          key: { type: 'string' },
          value: { type: 'any' },
          ttl: { type: 'number' }
        },
        required: ['key', 'value']
      }
    }
    // ... other tools
  ]
}));
```

2. Resource Endpoints
```typescript
this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
  resources: [{
    uri: 'cache://stats',
    name: 'Cache Statistics',
    mimeType: 'application/json'
  }]
}));
```

## Performance Considerations

1. Memory Optimization
   - JSON.stringify for size estimation
   - LRU eviction for memory limits
   - Periodic cleanup of expired entries

2. Concurrency
   - Map operations are atomic
   - Stats updates are synchronized
   - Resource access is thread-safe

3. Error Handling
   - Graceful degradation on memory limits
   - Error propagation through MCP protocol
   - Automatic recovery mechanisms

## Development Guidelines

1. Code Style
   - TypeScript strict mode
   - Async/await for asynchronous operations
   - Private methods for internal logic
   - Clear error messages

2. Testing
   - Unit tests for CacheManager
   - Integration tests for MCP tools
   - Performance benchmarks
   - Memory leak detection

3. Documentation
   - TSDoc comments
   - Clear method signatures
   - Example usage
   - Error scenarios

## Future Development

1. Performance Enhancements
   - More accurate memory tracking
   - Optimized data serialization
   - Batch operations support

2. Feature Additions
   - Pattern-based cache invalidation
   - Cache warming strategies
   - Custom eviction policies

3. Monitoring
   - Detailed performance metrics
   - Debug logging system
   - Health check endpoints

4. Scaling
   - Multi-process support
   - Distributed caching
   - Cache synchronization

```

--------------------------------------------------------------------------------
/src/CacheManager.ts:
--------------------------------------------------------------------------------

```typescript
import { CacheEntry, CacheStats, CacheConfig } from './types.js';

export class CacheManager {
  private cache: Map<string, CacheEntry>;
  private stats: CacheStats;
  private config: Required<CacheConfig>;
  private cleanupInterval: ReturnType<typeof setInterval>;
  private statsUpdateInterval: ReturnType<typeof setInterval>;

  constructor(config: CacheConfig = {}) {
    this.cache = new Map();
    this.stats = {
      totalEntries: 0,
      memoryUsage: 0,
      hits: 0,
      misses: 0,
      hitRate: 0,
      avgAccessTime: 0
    };
    
    // Set default configuration
    this.config = {
      maxEntries: config.maxEntries ?? 1000,
      maxMemory: config.maxMemory ?? 100 * 1024 * 1024, // 100MB default
      defaultTTL: config.defaultTTL ?? 3600, // 1 hour default
      checkInterval: config.checkInterval ?? 60 * 1000, // 1 minute default
      statsInterval: config.statsInterval ?? 30 * 1000 // 30 seconds default
    };

    // Start maintenance intervals
    this.cleanupInterval = setInterval(() => this.evictStale(), this.config.checkInterval);
    this.statsUpdateInterval = setInterval(() => this.updateStats(), this.config.statsInterval);
  }

  set(key: string, value: any, ttl?: number): void {
    const startTime = performance.now();
    
    // Calculate approximate size in bytes
    const size = this.calculateSize(value);
    
    // Check if adding this entry would exceed memory limit
    if (this.stats.memoryUsage + size > this.config.maxMemory) {
      this.enforceMemoryLimit(size);
    }

    const entry: CacheEntry = {
      value,
      created: Date.now(),
      lastAccessed: Date.now(),
      ttl: ttl ?? this.config.defaultTTL,
      size
    };

    this.cache.set(key, entry);
    this.stats.totalEntries = this.cache.size;
    this.stats.memoryUsage += size;

    const endTime = performance.now();
    this.updateAccessTime(endTime - startTime);
  }

  get(key: string): any {
    const startTime = performance.now();
    const entry = this.cache.get(key);

    if (!entry) {
      this.stats.misses++;
      this.updateHitRate();
      return undefined;
    }

    // Check if entry has expired
    if (this.isExpired(entry)) {
      this.delete(key);
      this.stats.misses++;
      this.updateHitRate();
      return undefined;
    }

    // Update last accessed time
    entry.lastAccessed = Date.now();
    this.stats.hits++;
    this.updateHitRate();

    const endTime = performance.now();
    this.updateAccessTime(endTime - startTime);

    return entry.value;
  }

  delete(key: string): boolean {
    const entry = this.cache.get(key);
    if (entry) {
      this.stats.memoryUsage -= entry.size;
      this.cache.delete(key);
      this.stats.totalEntries = this.cache.size;
      return true;
    }
    return false;
  }

  clear(): void {
    this.cache.clear();
    this.resetStats();
  }

  getStats(): CacheStats {
    return { ...this.stats };
  }

  private isExpired(entry: CacheEntry): boolean {
    return Date.now() > entry.created + (entry.ttl ?? this.config.defaultTTL) * 1000;
  }

  private evictStale(): void {
    for (const [key, entry] of this.cache.entries()) {
      if (this.isExpired(entry)) {
        this.delete(key);
      }
    }
  }

  private enforceMemoryLimit(requiredSize: number): void {
    // Use LRU strategy to remove entries until we have enough space
    const entries = Array.from(this.cache.entries())
      .sort(([, a], [, b]) => a.lastAccessed - b.lastAccessed);

    while (this.stats.memoryUsage + requiredSize > this.config.maxMemory && entries.length > 0) {
      const [key] = entries.shift()!;
      this.delete(key);
    }
  }

  private calculateSize(value: any): number {
    // Rough estimation of memory usage in bytes
    const str = JSON.stringify(value);
    return str.length * 2; // Approximate UTF-16 encoding size
  }

  private updateHitRate(): void {
    const total = this.stats.hits + this.stats.misses;
    this.stats.hitRate = total > 0 ? (this.stats.hits / total) * 100 : 0;
  }

  private updateAccessTime(duration: number): void {
    const total = this.stats.hits + this.stats.misses;
    this.stats.avgAccessTime = 
      ((this.stats.avgAccessTime * (total - 1)) + duration) / total;
  }

  private resetStats(): void {
    this.stats = {
      totalEntries: 0,
      memoryUsage: 0,
      hits: 0,
      misses: 0,
      hitRate: 0,
      avgAccessTime: 0
    };
  }

  private updateStats(): void {
    // Additional periodic stats updates could be added here
    this.updateHitRate();
  }

  destroy(): void {
    if (this.cleanupInterval) clearInterval(this.cleanupInterval);
    if (this.statsUpdateInterval) clearInterval(this.statsUpdateInterval);
    this.clear();
  }
}

```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ErrorCode,
  ListResourcesRequestSchema,
  ListToolsRequestSchema,
  McpError,
  ReadResourceRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { CacheManager } from './CacheManager.js';
import fs from 'fs-extra';
import path from 'path';

class MemoryCacheServer {
  private server: Server;
  private cacheManager: CacheManager;

  constructor() {
    // Load configuration
    const configPath = process.env.CONFIG_PATH || path.join(process.cwd(), 'config.json');
    const config = fs.existsSync(configPath) 
      ? fs.readJsonSync(configPath)
      : {};
    
    // Allow environment variable overrides
    const finalConfig = {
      maxEntries: parseInt(process.env.MAX_ENTRIES as string) || config.maxEntries,
      maxMemory: parseInt(process.env.MAX_MEMORY as string) || config.maxMemory,
      defaultTTL: parseInt(process.env.DEFAULT_TTL as string) || config.defaultTTL,
      checkInterval: parseInt(process.env.CHECK_INTERVAL as string) || config.checkInterval,
      statsInterval: parseInt(process.env.STATS_INTERVAL as string) || config.statsInterval
    };

    this.server = new Server(
      {
        name: 'charly-memory-cache-server',
        version: '0.1.0',
      },
      {
        capabilities: {
          resources: {},
          tools: {},
        },
      }
    );

    this.cacheManager = new CacheManager(finalConfig);

    this.setupResourceHandlers();
    this.setupToolHandlers();
    
    // Error handling
    this.server.onerror = (error) => console.error('[MCP Error]', error);
    process.on('SIGINT', async () => {
      await this.close();
      process.exit(0);
    });
  }

  private setupResourceHandlers() {
    // List available resources
    this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
      resources: [
        {
          uri: 'cache://stats',
          name: 'Cache Statistics',
          mimeType: 'application/json',
          description: 'Real-time cache performance metrics',
        },
      ],
    }));

    // Handle resource reads
    this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
      if (request.params.uri === 'cache://stats') {
        return {
          contents: [
            {
              uri: request.params.uri,
              mimeType: 'application/json',
              text: JSON.stringify(this.cacheManager.getStats(), null, 2),
            },
          ],
        };
      }

      throw new McpError(
        ErrorCode.InvalidRequest,
        `Unknown resource: ${request.params.uri}`
      );
    });
  }

  private setupToolHandlers() {
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: 'store_data',
          description: 'Store data in the cache with optional TTL',
          inputSchema: {
            type: 'object',
            properties: {
              key: {
                type: 'string',
                description: 'Unique identifier for the cached data',
              },
              value: {
                type: 'any',
                description: 'Data to cache',
              },
              ttl: {
                type: 'number',
                description: 'Time-to-live in seconds (optional)',
              },
            },
            required: ['key', 'value'],
          },
        },
        {
          name: 'retrieve_data',
          description: 'Retrieve data from the cache',
          inputSchema: {
            type: 'object',
            properties: {
              key: {
                type: 'string',
                description: 'Key of the cached data to retrieve',
              },
            },
            required: ['key'],
          },
        },
        {
          name: 'clear_cache',
          description: 'Clear specific or all cache entries',
          inputSchema: {
            type: 'object',
            properties: {
              key: {
                type: 'string',
                description: 'Specific key to clear (optional - clears all if not provided)',
              },
            },
          },
        },
        {
          name: 'get_cache_stats',
          description: 'Get cache statistics',
          inputSchema: {
            type: 'object',
            properties: {},
          },
        },
      ],
    }));

    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      try {
        switch (request.params.name) {
          case 'store_data': {
            const { key, value, ttl } = request.params.arguments as {
              key: string;
              value: any;
              ttl?: number;
            };
            this.cacheManager.set(key, value, ttl);
            return {
              content: [
                {
                  type: 'text',
                  text: `Successfully stored data with key: ${key}`,
                },
              ],
            };
          }

          case 'retrieve_data': {
            const { key } = request.params.arguments as { key: string };
            const value = this.cacheManager.get(key);
            if (value === undefined) {
              return {
                content: [
                  {
                    type: 'text',
                    text: `No data found for key: ${key}`,
                  },
                ],
                isError: true,
              };
            }
            return {
              content: [
                {
                  type: 'text',
                  text: JSON.stringify(value, null, 2),
                },
              ],
            };
          }

          case 'clear_cache': {
            const { key } = request.params.arguments as { key?: string };
            if (key) {
              const success = this.cacheManager.delete(key);
              return {
                content: [
                  {
                    type: 'text',
                    text: success
                      ? `Successfully cleared cache entry: ${key}`
                      : `No cache entry found for key: ${key}`,
                  },
                ],
              };
            } else {
              this.cacheManager.clear();
              return {
                content: [
                  {
                    type: 'text',
                    text: 'Successfully cleared all cache entries',
                  },
                ],
              };
            }
          }

          case 'get_cache_stats': {
            const stats = this.cacheManager.getStats();
            return {
              content: [
                {
                  type: 'text',
                  text: JSON.stringify(stats, null, 2),
                },
              ],
            };
          }

          default:
            throw new McpError(
              ErrorCode.MethodNotFound,
              `Unknown tool: ${request.params.name}`
            );
        }
      } catch (error) {
        return {
          content: [
            {
              type: 'text',
              text: error instanceof Error ? error.message : String(error),
            },
          ],
          isError: true,
        };
      }
    });
  }

  async run() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('Memory Cache MCP server running on stdio');
  }

  async close() {
    this.cacheManager.destroy();
    await this.server.close();
  }
}

const server = new MemoryCacheServer();
server.run().catch(console.error);

```