#
tokens: 15555/50000 10/10 files
lines: on (toggle) GitHub
raw markdown copy reset
# 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
  1 | # Memory Cache Server
  2 | [![smithery badge](https://smithery.ai/badge/@tosin2013/mcp-memory-cache-server)](https://smithery.ai/server/@tosin2013/mcp-memory-cache-server)
  3 | 
  4 | 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.
  5 | 
  6 | ## Installation
  7 | 
  8 | ### Installing via Smithery
  9 | 
 10 | To install Memory Cache Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@tosin2013/mcp-memory-cache-server):
 11 | 
 12 | ```bash
 13 | npx -y @smithery/cli install @tosin2013/mcp-memory-cache-server --client claude
 14 | ```
 15 | 
 16 | ### Installing Manually
 17 | 1. Clone the repository:
 18 | ```bash
 19 | git clone https://github.com/tosin2013/mcp-memory-cache-server.git
 20 | cd mcp-memory-cache-server
 21 | ```
 22 | 
 23 | 2. Install dependencies:
 24 | ```bash
 25 | npm install
 26 | ```
 27 | 
 28 | 3. Build the project:
 29 | ```bash
 30 | npm run build
 31 | ```
 32 | 
 33 | 4. Add to your MCP client settings:
 34 | ```json
 35 | {
 36 |   "mcpServers": {
 37 |     "memory-cache": {
 38 |       "command": "node",
 39 |       "args": ["/path/to/ib-mcp-cache-server/build/index.js"]
 40 |     }
 41 |   }
 42 | }
 43 | ```
 44 | 
 45 | 5. The server will automatically start when you use your MCP client
 46 | 
 47 | ## Verifying It Works
 48 | 
 49 | When the server is running properly, you'll see:
 50 | 1. A message in the terminal: "Memory Cache MCP server running on stdio"
 51 | 2. Improved performance when accessing the same data multiple times
 52 | 3. No action required from you - the caching happens automatically
 53 | 
 54 | You can verify the server is running by:
 55 | 1. Opening your MCP client
 56 | 2. Looking for any error messages in the terminal where you started the server
 57 | 3. Performing operations that would benefit from caching (like reading the same file multiple times)
 58 | 
 59 | ## Configuration
 60 | 
 61 | The server can be configured through `config.json` or environment variables:
 62 | 
 63 | ```json
 64 | {
 65 |   "maxEntries": 1000,        // Maximum number of items in cache
 66 |   "maxMemory": 104857600,    // Maximum memory usage in bytes (100MB)
 67 |   "defaultTTL": 3600,        // Default time-to-live in seconds (1 hour)
 68 |   "checkInterval": 60000,    // Cleanup interval in milliseconds (1 minute)
 69 |   "statsInterval": 30000     // Stats update interval in milliseconds (30 seconds)
 70 | }
 71 | ```
 72 | 
 73 | ### Configuration Settings Explained
 74 | 
 75 | 1. **maxEntries** (default: 1000)
 76 |    - Maximum number of items that can be stored in cache
 77 |    - Prevents cache from growing indefinitely
 78 |    - When exceeded, oldest unused items are removed first
 79 | 
 80 | 2. **maxMemory** (default: 100MB)
 81 |    - Maximum memory usage in bytes
 82 |    - Prevents excessive memory consumption
 83 |    - When exceeded, least recently used items are removed
 84 | 
 85 | 3. **defaultTTL** (default: 1 hour)
 86 |    - How long items stay in cache by default
 87 |    - Items are automatically removed after this time
 88 |    - Prevents stale data from consuming memory
 89 | 
 90 | 4. **checkInterval** (default: 1 minute)
 91 |    - How often the server checks for expired items
 92 |    - Lower values keep memory usage more accurate
 93 |    - Higher values reduce CPU usage
 94 | 
 95 | 5. **statsInterval** (default: 30 seconds)
 96 |    - How often cache statistics are updated
 97 |    - Affects accuracy of hit/miss rates
 98 |    - Helps monitor cache effectiveness
 99 | 
100 | ## How It Reduces Token Consumption
101 | 
102 | 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.
103 | 
104 | Here are some examples of what gets cached:
105 | 
106 | ### 1. File Content Caching
107 | When reading a file multiple times:
108 | - First time: Full file content is read and cached
109 | - Subsequent times: Content is retrieved from cache instead of re-reading the file
110 | - Result: Fewer tokens used for repeated file operations
111 | 
112 | ### 2. Computation Results
113 | When performing calculations or analysis:
114 | - First time: Full computation is performed and results are cached
115 | - Subsequent times: Results are retrieved from cache if the input is the same
116 | - Result: Fewer tokens used for repeated computations
117 | 
118 | ### 3. Frequently Accessed Data
119 | When the same data is needed multiple times:
120 | - First time: Data is processed and cached
121 | - Subsequent times: Data is retrieved from cache until TTL expires
122 | - Result: Fewer tokens used for accessing the same information
123 | 
124 | ## Automatic Cache Management
125 | 
126 | The server automatically manages the caching process by:
127 | - Storing data when first encountered
128 | - Serving cached data when available
129 | - Removing old/unused data based on settings
130 | - Tracking effectiveness through statistics
131 | 
132 | ## Optimization Tips
133 | 
134 | ### 1. Set Appropriate TTLs
135 | - Shorter for frequently changing data
136 | - Longer for static content
137 | 
138 | ### 2. Adjust Memory Limits
139 | - Higher for more caching (more token savings)
140 | - Lower if memory usage is a concern
141 | 
142 | ### 3. Monitor Cache Stats
143 | - High hit rate = good token savings
144 | - Low hit rate = adjust TTL or limits
145 | 
146 | ## Environment Variable Configuration
147 | 
148 | You can override config.json settings using environment variables in your MCP settings:
149 | 
150 | ```json
151 | {
152 |   "mcpServers": {
153 |     "memory-cache": {
154 |       "command": "node",
155 |       "args": ["/path/to/build/index.js"],
156 |       "env": {
157 |         "MAX_ENTRIES": "5000",
158 |         "MAX_MEMORY": "209715200",  // 200MB
159 |         "DEFAULT_TTL": "7200",      // 2 hours
160 |         "CHECK_INTERVAL": "120000",  // 2 minutes
161 |         "STATS_INTERVAL": "60000"    // 1 minute
162 |       }
163 |     }
164 |   }
165 | }
166 | ```
167 | 
168 | You can also specify a custom config file location:
169 | ```json
170 | {
171 |   "env": {
172 |     "CONFIG_PATH": "/path/to/your/config.json"
173 |   }
174 | }
175 | ```
176 | 
177 | The server will:
178 | 1. Look for config.json in its directory
179 | 2. Apply any environment variable overrides
180 | 3. Use default values if neither is specified
181 | 
182 | ## Testing the Cache in Practice
183 | 
184 | To see the cache in action, try these scenarios:
185 | 
186 | 1. **File Reading Test**
187 |    - Read and analyze a large file
188 |    - Ask the same question about the file again
189 |    - The second response should be faster as the file content is cached
190 | 
191 | 2. **Data Analysis Test**
192 |    - Perform analysis on some data
193 |    - Request the same analysis again
194 |    - The second analysis should use cached results
195 | 
196 | 3. **Project Navigation Test**
197 |    - Explore a project's structure
198 |    - Query the same files/directories again
199 |    - Directory listings and file contents will be served from cache
200 | 
201 | The cache is working when you notice:
202 | - Faster responses for repeated operations
203 | - Consistent answers about unchanged content
204 | - No need to re-read files that haven't changed
205 | 
```

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

```json
1 | {
2 |   "maxEntries": 1000,
3 |   "maxMemory": 104857600,
4 |   "defaultTTL": 3600,
5 |   "checkInterval": 60000,
6 |   "statsInterval": 30000
7 | }
8 | 
```

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

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2020",
 4 |     "module": "ES2020",
 5 |     "moduleResolution": "node",
 6 |     "outDir": "./build",
 7 |     "rootDir": "./src",
 8 |     "strict": true,
 9 |     "esModuleInterop": true,
10 |     "skipLibCheck": true,
11 |     "forceConsistentCasingInFileNames": true,
12 |     "declaration": true
13 |   },
14 |   "include": ["src/**/*"],
15 |   "exclude": ["node_modules", "build"]
16 | }
17 | 
```

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

```typescript
 1 | export interface CacheEntry {
 2 |   value: any;
 3 |   created: number;
 4 |   lastAccessed: number;
 5 |   ttl?: number;
 6 |   size: number;
 7 | }
 8 | 
 9 | export interface CacheStats {
10 |   totalEntries: number;
11 |   memoryUsage: number;
12 |   hits: number;
13 |   misses: number;
14 |   hitRate: number;
15 |   avgAccessTime: number;
16 | }
17 | 
18 | export interface CacheConfig {
19 |   maxEntries?: number;
20 |   maxMemory?: number;
21 |   defaultTTL?: number;
22 |   checkInterval?: number;
23 |   statsInterval?: number;
24 | }
25 | 
```

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

```json
 1 | {
 2 |   "name": "charly-memory-cache-server",
 3 |   "version": "1.0.0",
 4 |   "description": "MCP server for memory caching and optimization",
 5 |   "type": "module",
 6 |   "main": "build/index.js",
 7 |   "scripts": {
 8 |     "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
 9 |     "start": "node build/index.js",
10 |     "dev": "tsc -w",
11 |     "prepare": "npm run build",
12 |     "test": "echo \"Error: no test specified\" && exit 1"
13 |   },
14 |   "keywords": [
15 |     "mcp",
16 |     "cache",
17 |     "memory",
18 |     "optimization"
19 |   ],
20 |   "author": "",
21 |   "license": "ISC",
22 |   "devDependencies": {
23 |     "@types/node": "^20.10.6",
24 |     "@types/fs-extra": "^11.0.4",
25 |     "typescript": "^5.3.3"
26 |   },
27 |   "dependencies": {
28 |     "@modelcontextprotocol/sdk": "0.6.0",
29 |     "fs-extra": "^11.2.0"
30 |   }
31 | }
32 | 
```

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

```dockerfile
 1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
 2 | # Use a Node.js image to build the project
 3 | FROM node:18-alpine AS builder
 4 | 
 5 | # Set the working directory inside the container
 6 | WORKDIR /app
 7 | 
 8 | # Copy the package.json and package-lock.json files
 9 | COPY package.json package-lock.json ./
10 | 
11 | # Install dependencies
12 | RUN npm install --ignore-scripts
13 | 
14 | # Copy the rest of the project files
15 | COPY . .
16 | 
17 | # Build the project
18 | RUN npm run build
19 | 
20 | # Use a lighter Node.js image for the production stage
21 | FROM node:18-alpine
22 | 
23 | # Set the working directory inside the container
24 | WORKDIR /app
25 | 
26 | # Copy the built files and node_modules from the builder stage
27 | COPY --from=builder /app/build /app/build
28 | COPY --from=builder /app/node_modules /app/node_modules
29 | COPY --from=builder /app/package.json /app/package.json
30 | 
31 | # Set the entry point to start the server
32 | ENTRYPOINT ["node", "build/index.js"]
33 | 
```

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

```yaml
 1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
 2 | 
 3 | startCommand:
 4 |   type: stdio
 5 |   configSchema:
 6 |     # JSON Schema defining the configuration options for the MCP.
 7 |     type: object
 8 |     required:
 9 |       - maxEntries
10 |       - maxMemory
11 |       - defaultTTL
12 |       - checkInterval
13 |       - statsInterval
14 |     properties:
15 |       maxEntries:
16 |         type: number
17 |         description: Maximum number of items in cache
18 |       maxMemory:
19 |         type: number
20 |         description: Maximum memory usage in bytes
21 |       defaultTTL:
22 |         type: number
23 |         description: Default time-to-live for cached items in seconds
24 |       checkInterval:
25 |         type: number
26 |         description: Interval for checking expired items in milliseconds
27 |       statsInterval:
28 |         type: number
29 |         description: Interval for updating cache statistics in milliseconds
30 |   commandFunction:
31 |     # A function that produces the CLI command to start the MCP on stdio.
32 |     |-
33 |     (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) } })
34 | 
```

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

```markdown
  1 | # Charly Memory Cache Server - Technical Documentation
  2 | 
  3 | Repository: [email protected]:ibproduct/charlymcpcacheserver.git
  4 | 
  5 | ## Architecture Overview
  6 | 
  7 | ### Core Components
  8 | 
  9 | 1. **CacheManager**
 10 |    - In-memory storage using Map
 11 |    - LRU eviction strategy
 12 |    - TTL management
 13 |    - Memory usage tracking
 14 |    - Statistics collection
 15 | 
 16 | 2. **MCP Server**
 17 |    - Tool registration
 18 |    - Resource endpoints
 19 |    - Request handling
 20 |    - Error management
 21 | 
 22 | ### Data Structures
 23 | 
 24 | ```typescript
 25 | interface CacheEntry {
 26 |   value: any;          // Cached data
 27 |   created: number;     // Creation timestamp
 28 |   lastAccessed: number;// Last access timestamp
 29 |   ttl?: number;        // Time-to-live in seconds
 30 |   size: number;        // Memory size estimation
 31 | }
 32 | 
 33 | interface CacheStats {
 34 |   totalEntries: number;
 35 |   memoryUsage: number;
 36 |   hits: number;
 37 |   misses: number;
 38 |   hitRate: number;
 39 |   avgAccessTime: number;
 40 | }
 41 | 
 42 | interface CacheConfig {
 43 |   maxEntries?: number;
 44 |   maxMemory?: number;
 45 |   defaultTTL?: number;
 46 |   checkInterval?: number;
 47 |   statsInterval?: number;
 48 | }
 49 | ```
 50 | 
 51 | ## Implementation Details
 52 | 
 53 | ### Memory Management
 54 | 
 55 | 1. Size Calculation
 56 | ```typescript
 57 | private calculateSize(value: any): number {
 58 |   const str = JSON.stringify(value);
 59 |   return str.length * 2; // UTF-16 encoding size
 60 | }
 61 | ```
 62 | 
 63 | 2. LRU Implementation
 64 | ```typescript
 65 | private enforceMemoryLimit(requiredSize: number): void {
 66 |   const entries = Array.from(this.cache.entries())
 67 |     .sort(([, a], [, b]) => a.lastAccessed - b.lastAccessed);
 68 | 
 69 |   while (this.stats.memoryUsage + requiredSize > this.config.maxMemory 
 70 |          && entries.length > 0) {
 71 |     const [key] = entries.shift()!;
 72 |     this.delete(key);
 73 |   }
 74 | }
 75 | ```
 76 | 
 77 | ### MCP Integration
 78 | 
 79 | 1. Tool Registration
 80 | ```typescript
 81 | this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
 82 |   tools: [
 83 |     {
 84 |       name: 'store_data',
 85 |       description: 'Store data in cache',
 86 |       inputSchema: {
 87 |         type: 'object',
 88 |         properties: {
 89 |           key: { type: 'string' },
 90 |           value: { type: 'any' },
 91 |           ttl: { type: 'number' }
 92 |         },
 93 |         required: ['key', 'value']
 94 |       }
 95 |     }
 96 |     // ... other tools
 97 |   ]
 98 | }));
 99 | ```
100 | 
101 | 2. Resource Endpoints
102 | ```typescript
103 | this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
104 |   resources: [{
105 |     uri: 'cache://stats',
106 |     name: 'Cache Statistics',
107 |     mimeType: 'application/json'
108 |   }]
109 | }));
110 | ```
111 | 
112 | ## Performance Considerations
113 | 
114 | 1. Memory Optimization
115 |    - JSON.stringify for size estimation
116 |    - LRU eviction for memory limits
117 |    - Periodic cleanup of expired entries
118 | 
119 | 2. Concurrency
120 |    - Map operations are atomic
121 |    - Stats updates are synchronized
122 |    - Resource access is thread-safe
123 | 
124 | 3. Error Handling
125 |    - Graceful degradation on memory limits
126 |    - Error propagation through MCP protocol
127 |    - Automatic recovery mechanisms
128 | 
129 | ## Development Guidelines
130 | 
131 | 1. Code Style
132 |    - TypeScript strict mode
133 |    - Async/await for asynchronous operations
134 |    - Private methods for internal logic
135 |    - Clear error messages
136 | 
137 | 2. Testing
138 |    - Unit tests for CacheManager
139 |    - Integration tests for MCP tools
140 |    - Performance benchmarks
141 |    - Memory leak detection
142 | 
143 | 3. Documentation
144 |    - TSDoc comments
145 |    - Clear method signatures
146 |    - Example usage
147 |    - Error scenarios
148 | 
149 | ## Future Development
150 | 
151 | 1. Performance Enhancements
152 |    - More accurate memory tracking
153 |    - Optimized data serialization
154 |    - Batch operations support
155 | 
156 | 2. Feature Additions
157 |    - Pattern-based cache invalidation
158 |    - Cache warming strategies
159 |    - Custom eviction policies
160 | 
161 | 3. Monitoring
162 |    - Detailed performance metrics
163 |    - Debug logging system
164 |    - Health check endpoints
165 | 
166 | 4. Scaling
167 |    - Multi-process support
168 |    - Distributed caching
169 |    - Cache synchronization
170 | 
```

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

```typescript
  1 | import { CacheEntry, CacheStats, CacheConfig } from './types.js';
  2 | 
  3 | export class CacheManager {
  4 |   private cache: Map<string, CacheEntry>;
  5 |   private stats: CacheStats;
  6 |   private config: Required<CacheConfig>;
  7 |   private cleanupInterval: ReturnType<typeof setInterval>;
  8 |   private statsUpdateInterval: ReturnType<typeof setInterval>;
  9 | 
 10 |   constructor(config: CacheConfig = {}) {
 11 |     this.cache = new Map();
 12 |     this.stats = {
 13 |       totalEntries: 0,
 14 |       memoryUsage: 0,
 15 |       hits: 0,
 16 |       misses: 0,
 17 |       hitRate: 0,
 18 |       avgAccessTime: 0
 19 |     };
 20 |     
 21 |     // Set default configuration
 22 |     this.config = {
 23 |       maxEntries: config.maxEntries ?? 1000,
 24 |       maxMemory: config.maxMemory ?? 100 * 1024 * 1024, // 100MB default
 25 |       defaultTTL: config.defaultTTL ?? 3600, // 1 hour default
 26 |       checkInterval: config.checkInterval ?? 60 * 1000, // 1 minute default
 27 |       statsInterval: config.statsInterval ?? 30 * 1000 // 30 seconds default
 28 |     };
 29 | 
 30 |     // Start maintenance intervals
 31 |     this.cleanupInterval = setInterval(() => this.evictStale(), this.config.checkInterval);
 32 |     this.statsUpdateInterval = setInterval(() => this.updateStats(), this.config.statsInterval);
 33 |   }
 34 | 
 35 |   set(key: string, value: any, ttl?: number): void {
 36 |     const startTime = performance.now();
 37 |     
 38 |     // Calculate approximate size in bytes
 39 |     const size = this.calculateSize(value);
 40 |     
 41 |     // Check if adding this entry would exceed memory limit
 42 |     if (this.stats.memoryUsage + size > this.config.maxMemory) {
 43 |       this.enforceMemoryLimit(size);
 44 |     }
 45 | 
 46 |     const entry: CacheEntry = {
 47 |       value,
 48 |       created: Date.now(),
 49 |       lastAccessed: Date.now(),
 50 |       ttl: ttl ?? this.config.defaultTTL,
 51 |       size
 52 |     };
 53 | 
 54 |     this.cache.set(key, entry);
 55 |     this.stats.totalEntries = this.cache.size;
 56 |     this.stats.memoryUsage += size;
 57 | 
 58 |     const endTime = performance.now();
 59 |     this.updateAccessTime(endTime - startTime);
 60 |   }
 61 | 
 62 |   get(key: string): any {
 63 |     const startTime = performance.now();
 64 |     const entry = this.cache.get(key);
 65 | 
 66 |     if (!entry) {
 67 |       this.stats.misses++;
 68 |       this.updateHitRate();
 69 |       return undefined;
 70 |     }
 71 | 
 72 |     // Check if entry has expired
 73 |     if (this.isExpired(entry)) {
 74 |       this.delete(key);
 75 |       this.stats.misses++;
 76 |       this.updateHitRate();
 77 |       return undefined;
 78 |     }
 79 | 
 80 |     // Update last accessed time
 81 |     entry.lastAccessed = Date.now();
 82 |     this.stats.hits++;
 83 |     this.updateHitRate();
 84 | 
 85 |     const endTime = performance.now();
 86 |     this.updateAccessTime(endTime - startTime);
 87 | 
 88 |     return entry.value;
 89 |   }
 90 | 
 91 |   delete(key: string): boolean {
 92 |     const entry = this.cache.get(key);
 93 |     if (entry) {
 94 |       this.stats.memoryUsage -= entry.size;
 95 |       this.cache.delete(key);
 96 |       this.stats.totalEntries = this.cache.size;
 97 |       return true;
 98 |     }
 99 |     return false;
100 |   }
101 | 
102 |   clear(): void {
103 |     this.cache.clear();
104 |     this.resetStats();
105 |   }
106 | 
107 |   getStats(): CacheStats {
108 |     return { ...this.stats };
109 |   }
110 | 
111 |   private isExpired(entry: CacheEntry): boolean {
112 |     return Date.now() > entry.created + (entry.ttl ?? this.config.defaultTTL) * 1000;
113 |   }
114 | 
115 |   private evictStale(): void {
116 |     for (const [key, entry] of this.cache.entries()) {
117 |       if (this.isExpired(entry)) {
118 |         this.delete(key);
119 |       }
120 |     }
121 |   }
122 | 
123 |   private enforceMemoryLimit(requiredSize: number): void {
124 |     // Use LRU strategy to remove entries until we have enough space
125 |     const entries = Array.from(this.cache.entries())
126 |       .sort(([, a], [, b]) => a.lastAccessed - b.lastAccessed);
127 | 
128 |     while (this.stats.memoryUsage + requiredSize > this.config.maxMemory && entries.length > 0) {
129 |       const [key] = entries.shift()!;
130 |       this.delete(key);
131 |     }
132 |   }
133 | 
134 |   private calculateSize(value: any): number {
135 |     // Rough estimation of memory usage in bytes
136 |     const str = JSON.stringify(value);
137 |     return str.length * 2; // Approximate UTF-16 encoding size
138 |   }
139 | 
140 |   private updateHitRate(): void {
141 |     const total = this.stats.hits + this.stats.misses;
142 |     this.stats.hitRate = total > 0 ? (this.stats.hits / total) * 100 : 0;
143 |   }
144 | 
145 |   private updateAccessTime(duration: number): void {
146 |     const total = this.stats.hits + this.stats.misses;
147 |     this.stats.avgAccessTime = 
148 |       ((this.stats.avgAccessTime * (total - 1)) + duration) / total;
149 |   }
150 | 
151 |   private resetStats(): void {
152 |     this.stats = {
153 |       totalEntries: 0,
154 |       memoryUsage: 0,
155 |       hits: 0,
156 |       misses: 0,
157 |       hitRate: 0,
158 |       avgAccessTime: 0
159 |     };
160 |   }
161 | 
162 |   private updateStats(): void {
163 |     // Additional periodic stats updates could be added here
164 |     this.updateHitRate();
165 |   }
166 | 
167 |   destroy(): void {
168 |     if (this.cleanupInterval) clearInterval(this.cleanupInterval);
169 |     if (this.statsUpdateInterval) clearInterval(this.statsUpdateInterval);
170 |     this.clear();
171 |   }
172 | }
173 | 
```

--------------------------------------------------------------------------------
/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 |   ListResourcesRequestSchema,
  8 |   ListToolsRequestSchema,
  9 |   McpError,
 10 |   ReadResourceRequestSchema,
 11 | } from '@modelcontextprotocol/sdk/types.js';
 12 | import { CacheManager } from './CacheManager.js';
 13 | import fs from 'fs-extra';
 14 | import path from 'path';
 15 | 
 16 | class MemoryCacheServer {
 17 |   private server: Server;
 18 |   private cacheManager: CacheManager;
 19 | 
 20 |   constructor() {
 21 |     // Load configuration
 22 |     const configPath = process.env.CONFIG_PATH || path.join(process.cwd(), 'config.json');
 23 |     const config = fs.existsSync(configPath) 
 24 |       ? fs.readJsonSync(configPath)
 25 |       : {};
 26 |     
 27 |     // Allow environment variable overrides
 28 |     const finalConfig = {
 29 |       maxEntries: parseInt(process.env.MAX_ENTRIES as string) || config.maxEntries,
 30 |       maxMemory: parseInt(process.env.MAX_MEMORY as string) || config.maxMemory,
 31 |       defaultTTL: parseInt(process.env.DEFAULT_TTL as string) || config.defaultTTL,
 32 |       checkInterval: parseInt(process.env.CHECK_INTERVAL as string) || config.checkInterval,
 33 |       statsInterval: parseInt(process.env.STATS_INTERVAL as string) || config.statsInterval
 34 |     };
 35 | 
 36 |     this.server = new Server(
 37 |       {
 38 |         name: 'charly-memory-cache-server',
 39 |         version: '0.1.0',
 40 |       },
 41 |       {
 42 |         capabilities: {
 43 |           resources: {},
 44 |           tools: {},
 45 |         },
 46 |       }
 47 |     );
 48 | 
 49 |     this.cacheManager = new CacheManager(finalConfig);
 50 | 
 51 |     this.setupResourceHandlers();
 52 |     this.setupToolHandlers();
 53 |     
 54 |     // Error handling
 55 |     this.server.onerror = (error) => console.error('[MCP Error]', error);
 56 |     process.on('SIGINT', async () => {
 57 |       await this.close();
 58 |       process.exit(0);
 59 |     });
 60 |   }
 61 | 
 62 |   private setupResourceHandlers() {
 63 |     // List available resources
 64 |     this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
 65 |       resources: [
 66 |         {
 67 |           uri: 'cache://stats',
 68 |           name: 'Cache Statistics',
 69 |           mimeType: 'application/json',
 70 |           description: 'Real-time cache performance metrics',
 71 |         },
 72 |       ],
 73 |     }));
 74 | 
 75 |     // Handle resource reads
 76 |     this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
 77 |       if (request.params.uri === 'cache://stats') {
 78 |         return {
 79 |           contents: [
 80 |             {
 81 |               uri: request.params.uri,
 82 |               mimeType: 'application/json',
 83 |               text: JSON.stringify(this.cacheManager.getStats(), null, 2),
 84 |             },
 85 |           ],
 86 |         };
 87 |       }
 88 | 
 89 |       throw new McpError(
 90 |         ErrorCode.InvalidRequest,
 91 |         `Unknown resource: ${request.params.uri}`
 92 |       );
 93 |     });
 94 |   }
 95 | 
 96 |   private setupToolHandlers() {
 97 |     this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
 98 |       tools: [
 99 |         {
100 |           name: 'store_data',
101 |           description: 'Store data in the cache with optional TTL',
102 |           inputSchema: {
103 |             type: 'object',
104 |             properties: {
105 |               key: {
106 |                 type: 'string',
107 |                 description: 'Unique identifier for the cached data',
108 |               },
109 |               value: {
110 |                 type: 'any',
111 |                 description: 'Data to cache',
112 |               },
113 |               ttl: {
114 |                 type: 'number',
115 |                 description: 'Time-to-live in seconds (optional)',
116 |               },
117 |             },
118 |             required: ['key', 'value'],
119 |           },
120 |         },
121 |         {
122 |           name: 'retrieve_data',
123 |           description: 'Retrieve data from the cache',
124 |           inputSchema: {
125 |             type: 'object',
126 |             properties: {
127 |               key: {
128 |                 type: 'string',
129 |                 description: 'Key of the cached data to retrieve',
130 |               },
131 |             },
132 |             required: ['key'],
133 |           },
134 |         },
135 |         {
136 |           name: 'clear_cache',
137 |           description: 'Clear specific or all cache entries',
138 |           inputSchema: {
139 |             type: 'object',
140 |             properties: {
141 |               key: {
142 |                 type: 'string',
143 |                 description: 'Specific key to clear (optional - clears all if not provided)',
144 |               },
145 |             },
146 |           },
147 |         },
148 |         {
149 |           name: 'get_cache_stats',
150 |           description: 'Get cache statistics',
151 |           inputSchema: {
152 |             type: 'object',
153 |             properties: {},
154 |           },
155 |         },
156 |       ],
157 |     }));
158 | 
159 |     this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
160 |       try {
161 |         switch (request.params.name) {
162 |           case 'store_data': {
163 |             const { key, value, ttl } = request.params.arguments as {
164 |               key: string;
165 |               value: any;
166 |               ttl?: number;
167 |             };
168 |             this.cacheManager.set(key, value, ttl);
169 |             return {
170 |               content: [
171 |                 {
172 |                   type: 'text',
173 |                   text: `Successfully stored data with key: ${key}`,
174 |                 },
175 |               ],
176 |             };
177 |           }
178 | 
179 |           case 'retrieve_data': {
180 |             const { key } = request.params.arguments as { key: string };
181 |             const value = this.cacheManager.get(key);
182 |             if (value === undefined) {
183 |               return {
184 |                 content: [
185 |                   {
186 |                     type: 'text',
187 |                     text: `No data found for key: ${key}`,
188 |                   },
189 |                 ],
190 |                 isError: true,
191 |               };
192 |             }
193 |             return {
194 |               content: [
195 |                 {
196 |                   type: 'text',
197 |                   text: JSON.stringify(value, null, 2),
198 |                 },
199 |               ],
200 |             };
201 |           }
202 | 
203 |           case 'clear_cache': {
204 |             const { key } = request.params.arguments as { key?: string };
205 |             if (key) {
206 |               const success = this.cacheManager.delete(key);
207 |               return {
208 |                 content: [
209 |                   {
210 |                     type: 'text',
211 |                     text: success
212 |                       ? `Successfully cleared cache entry: ${key}`
213 |                       : `No cache entry found for key: ${key}`,
214 |                   },
215 |                 ],
216 |               };
217 |             } else {
218 |               this.cacheManager.clear();
219 |               return {
220 |                 content: [
221 |                   {
222 |                     type: 'text',
223 |                     text: 'Successfully cleared all cache entries',
224 |                   },
225 |                 ],
226 |               };
227 |             }
228 |           }
229 | 
230 |           case 'get_cache_stats': {
231 |             const stats = this.cacheManager.getStats();
232 |             return {
233 |               content: [
234 |                 {
235 |                   type: 'text',
236 |                   text: JSON.stringify(stats, null, 2),
237 |                 },
238 |               ],
239 |             };
240 |           }
241 | 
242 |           default:
243 |             throw new McpError(
244 |               ErrorCode.MethodNotFound,
245 |               `Unknown tool: ${request.params.name}`
246 |             );
247 |         }
248 |       } catch (error) {
249 |         return {
250 |           content: [
251 |             {
252 |               type: 'text',
253 |               text: error instanceof Error ? error.message : String(error),
254 |             },
255 |           ],
256 |           isError: true,
257 |         };
258 |       }
259 |     });
260 |   }
261 | 
262 |   async run() {
263 |     const transport = new StdioServerTransport();
264 |     await this.server.connect(transport);
265 |     console.error('Memory Cache MCP server running on stdio');
266 |   }
267 | 
268 |   async close() {
269 |     this.cacheManager.destroy();
270 |     await this.server.close();
271 |   }
272 | }
273 | 
274 | const server = new MemoryCacheServer();
275 | server.run().catch(console.error);
276 | 
```