diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml
index a1edc0c9..a9981da4 100644
--- a/.github/workflows/python.yml
+++ b/.github/workflows/python.yml
@@ -23,8 +23,45 @@ jobs:
PACKAGES=$(find . -name pyproject.toml -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]')
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
- build:
+ test:
needs: [detect-packages]
+ strategy:
+ matrix:
+ package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
+ name: Test ${{ matrix.package }}
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install uv
+ uses: astral-sh/setup-uv@v3
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version-file: "src/${{ matrix.package }}/.python-version"
+
+ - name: Install dependencies
+ working-directory: src/${{ matrix.package }}
+ run: uv sync --frozen --all-extras --dev
+
+ - name: Check if tests exist
+ id: check-tests
+ working-directory: src/${{ matrix.package }}
+ run: |
+ if [ -d "tests" ] || [ -d "test" ] || grep -q "pytest" pyproject.toml; then
+ echo "has-tests=true" >> $GITHUB_OUTPUT
+ else
+ echo "has-tests=false" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Run tests
+ if: steps.check-tests.outputs.has-tests == 'true'
+ working-directory: src/${{ matrix.package }}
+ run: uv run pytest
+
+ build:
+ needs: [detect-packages, test]
strategy:
matrix:
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 4e0a6579..b37f2c0b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -212,10 +212,3 @@ jobs:
--title "Release $VERSION" \
--notes-file RELEASE_NOTES.md
- - name: Docker MCP images
- uses: peter-evans/repository-dispatch@v3
- with:
- token: ${{ secrets.DOCKER_TOKEN }}
- repository: docker/labs-ai-tools-for-devs
- event-type: build-mcp-images
- client-payload: '{"ref": "${{ needs.create-metadata.outputs.version }}"}'
diff --git a/.github/workflows/typescript.yml b/.github/workflows/typescript.yml
index a87cdd8f..87717166 100644
--- a/.github/workflows/typescript.yml
+++ b/.github/workflows/typescript.yml
@@ -22,8 +22,43 @@ jobs:
PACKAGES=$(find . -name package.json -not -path "*/node_modules/*" -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]')
echo "packages=$PACKAGES" >> $GITHUB_OUTPUT
- build:
+ test:
needs: [detect-packages]
+ strategy:
+ matrix:
+ package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
+ name: Test ${{ matrix.package }}
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 22
+ cache: npm
+
+ - name: Install dependencies
+ working-directory: src/${{ matrix.package }}
+ run: npm ci
+
+ - name: Check if tests exist
+ id: check-tests
+ working-directory: src/${{ matrix.package }}
+ run: |
+ if npm run test --silent 2>/dev/null; then
+ echo "has-tests=true" >> $GITHUB_OUTPUT
+ else
+ echo "has-tests=false" >> $GITHUB_OUTPUT
+ fi
+ continue-on-error: true
+
+ - name: Run tests
+ if: steps.check-tests.outputs.has-tests == 'true'
+ working-directory: src/${{ matrix.package }}
+ run: npm test
+
+ build:
+ needs: [detect-packages, test]
strategy:
matrix:
package: ${{ fromJson(needs.detect-packages.outputs.packages) }}
diff --git a/.github/workflows/version-check.yml b/.github/workflows/version-check.yml
deleted file mode 100644
index b327649f..00000000
--- a/.github/workflows/version-check.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Version Consistency Check
-
-on:
- push:
- branches:
- - main
- pull_request:
- release:
- types: [published]
-
-jobs:
- github:
- name: Check GitHub server version consistency
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
-
- - name: Check version consistency
- run: |
- PACKAGE_VERSION=$(node -p "require('./src/github/package.json').version")
- TS_VERSION=$(grep -o '".*"' ./src/github/common/version.ts | tr -d '"')
-
- if [ "$PACKAGE_VERSION" != "$TS_VERSION" ]; then
- echo "::error::Version mismatch detected!"
- echo "::error::package.json version: $PACKAGE_VERSION"
- echo "::error::version.ts version: $TS_VERSION"
- exit 1
- else
- echo "✅ Versions match: $PACKAGE_VERSION"
- fi
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/README.md b/README.md
index c36ccc11..be4cb1e5 100644
--- a/README.md
+++ b/README.md
@@ -4,35 +4,46 @@ This repository is a collection of *reference implementations* for the [Model Co
to community built servers and additional resources.
The servers in this repository showcase the versatility and extensibility of MCP, demonstrating how it can be used to give Large Language Models (LLMs) secure, controlled access to tools and data sources.
-Each MCP server is implemented with either the [Typescript MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk) or [Python MCP SDK](https://github.com/modelcontextprotocol/python-sdk).
+Typically, each MCP server is implemented with an MCP SDK:
+- [C# MCP SDK](https://github.com/modelcontextprotocol/csharp-sdk)
+- [Go MCP SDK](https://github.com/modelcontextprotocol/go-sdk)
+- [Java MCP SDK](https://github.com/modelcontextprotocol/java-sdk)
+- [Kotlin MCP SDK](https://github.com/modelcontextprotocol/kotlin-sdk)
+- [Python MCP SDK](https://github.com/modelcontextprotocol/python-sdk)
+- [Typescript MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk)
> Note: Lists in this README are maintained in alphabetical order to minimize merge conflicts when adding new items.
## 🌟 Reference Servers
-These servers aim to demonstrate MCP features and the TypeScript and Python SDKs.
+These servers aim to demonstrate MCP features and the official SDKs.
-- **[AWS KB Retrieval](src/aws-kb-retrieval-server)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime
-- **[Brave Search](src/brave-search)** - Web and local search using Brave's Search API
-- **[EverArt](src/everart)** - AI image generation using various models
- **[Everything](src/everything)** - Reference / test server with prompts, resources, and tools
- **[Fetch](src/fetch)** - Web content fetching and conversion for efficient LLM usage
- **[Filesystem](src/filesystem)** - Secure file operations with configurable access controls
- **[Git](src/git)** - Tools to read, search, and manipulate Git repositories
-- **[GitHub](src/github)** - Repository management, file operations, and GitHub API integration
-- **[GitLab](src/gitlab)** - GitLab API, enabling project management
-- **[Google Drive](src/gdrive)** - File access and search capabilities for Google Drive
-- **[Google Maps](src/google-maps)** - Location services, directions, and place details
- **[Memory](src/memory)** - Knowledge graph-based persistent memory system
-- **[PostgreSQL](src/postgres)** - Read-only database access with schema inspection
-- **[Puppeteer](src/puppeteer)** - Browser automation and web scraping
-- **[Redis](src/redis)** - Interact with Redis key-value stores
-- **[Sentry](src/sentry)** - Retrieving and analyzing issues from Sentry.io
- **[Sequential Thinking](src/sequentialthinking)** - Dynamic and reflective problem-solving through thought sequences
-- **[Slack](src/slack)** - Channel management and messaging capabilities
-- **[Sqlite](src/sqlite)** - Database interaction and business intelligence capabilities
- **[Time](src/time)** - Time and timezone conversion capabilities
+### Archived
+
+The following reference servers are now archived and can be found at [servers-archived](https://github.com/modelcontextprotocol/servers-archived).
+
+- **[AWS KB Retrieval](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/aws-kb-retrieval-server)** - Retrieval from AWS Knowledge Base using Bedrock Agent Runtime
+- **[Brave Search](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/brave-search)** - Web and local search using Brave's Search API
+- **[EverArt](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/everart)** - AI image generation using various models
+- **[GitHub](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/github)** - Repository management, file operations, and GitHub API integration
+- **[GitLab](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/gitlab)** - GitLab API, enabling project management
+- **[Google Drive](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/gdrive)** - File access and search capabilities for Google Drive
+- **[Google Maps](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/google-maps)** - Location services, directions, and place details
+- **[PostgreSQL](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/postgres)** - Read-only database access with schema inspection
+- **[Puppeteer](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/puppeteer)** - Browser automation and web scraping
+- **[Redis](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/redis)** - Interact with Redis key-value stores
+- **[Sentry](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/sentry)** - Retrieving and analyzing issues from Sentry.io
+- **[Slack](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/slack)** - Channel management and messaging capabilities. Now maintained by [Zencoder](https://github.com/zencoderai/slack-mcp-server)
+- **[SQLite](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/sqlite)** - Database interaction and business intelligence capabilities
+
## 🤝 Third-Party Servers
### 🎖️ Official Integrations
@@ -40,380 +51,1013 @@ These servers aim to demonstrate MCP features and the TypeScript and Python SDKs
Official integrations are maintained by companies building production ready MCP servers for their platforms.
-
**[21st.dev Magic](https://github.com/21st-dev/magic-mcp)** - Create crafted UI components inspired by the best 21st.dev design engineers.
+-
**[ActionKit by Paragon](https://github.com/useparagon/paragon-mcp)** - Connect to 130+ SaaS integrations (e.g. Slack, Salesforce, Gmail) with Paragon’s [ActionKit](https://www.useparagon.com/actionkit) API.
-
**[Adfin](https://github.com/Adfin-Engineering/mcp-server-adfin)** - The only platform you need to get paid - all payments in one place, invoicing and accounting reconciliations with [Adfin](https://www.adfin.com/).
-
**[AgentQL](https://github.com/tinyfish-io/agentql-mcp)** - Enable AI agents to get structured data from unstructured web with [AgentQL](https://www.agentql.com/).
-
**[AgentRPC](https://github.com/agentrpc/agentrpc)** - Connect to any function, any language, across network boundaries using [AgentRPC](https://www.agentrpc.com/).
+- **[Agentset](https://github.com/agentset-ai/mcp-server)** - RAG for your knowledge base connected to [Agentset](https://agentset.ai).
-
**[Aiven](https://github.com/Aiven-Open/mcp-aiven)** - Navigate your [Aiven projects](https://go.aiven.io/mcp-server) and interact with the PostgreSQL®, Apache Kafka®, ClickHouse® and OpenSearch® services
+-
**[Alation](https://github.com/Alation/alation-ai-agent-sdk)** - Unlock the power of the enterprise Data Catalog by harnessing tools provided by the Alation MCP server.
+-
**[Alby Bitcoin Payments](https://github.com/getAlby/mcp)** - Connect any bitcoin lightning wallet to your agent to send and receive instant payments globally with your agent.
+- **[Algolia](https://github.com/algolia/mcp)** - Use AI agents to provision, configure, and query your [Algolia](https://algolia.com) search indices.
+-
**[Alibaba Cloud AnalyticDB for MySQL](https://github.com/aliyun/alibabacloud-adb-mysql-mcp-server)** - Connect to a [AnalyticDB for MySQL](https://www.alibabacloud.com/en/product/analyticdb-for-mysql) cluster for getting database or table metadata, querying and analyzing data.It will be supported to add the openapi for cluster operation in the future.
+-
**[Alibaba Cloud AnalyticDB for PostgreSQL](https://github.com/aliyun/alibabacloud-adbpg-mcp-server)** - An MCP server to connect to [AnalyticDB for PostgreSQL](https://github.com/aliyun/alibabacloud-adbpg-mcp-server) instances, query and analyze data.
+-
**[Alibaba Cloud DataWorks](https://github.com/aliyun/alibabacloud-dataworks-mcp-server)** - A Model Context Protocol (MCP) server that provides tools for AI, allowing it to interact with the [DataWorks](https://www.alibabacloud.com/help/en/dataworks/) Open API through a standardized interface. This implementation is based on the Alibaba Cloud Open API and enables AI agents to perform cloud resources operations seamlessly.
+-
**[Alibaba Cloud OpenSearch](https://github.com/aliyun/alibabacloud-opensearch-mcp-server)** - This MCP server equips AI Agents with tools to interact with [OpenSearch](https://help.aliyun.com/zh/open-search/?spm=5176.7946605.J_5253785160.6.28098651AaYZXC) through a standardized and extensible interface.
+-
**[Alibaba Cloud OPS](https://github.com/aliyun/alibaba-cloud-ops-mcp-server)** - Manage the lifecycle of your Alibaba Cloud resources with [CloudOps Orchestration Service](https://www.alibabacloud.com/en/product/oos) and Alibaba Cloud OpenAPI.
+-
**[Alibaba Cloud RDS](https://github.com/aliyun/alibabacloud-rds-openapi-mcp-server)** - An MCP server designed to interact with the Alibaba Cloud RDS OpenAPI, enabling programmatic management of RDS resources via an LLM.
+-
**[AllVoiceLab](https://www.allvoicelab.com/mcp)** - An AI voice toolkit with TTS, voice cloning, and video translation, now available as an MCP server for smarter agent integration.
+-
**[Alpaca](https://github.com/alpacahq/alpaca-mcp-server)** – Alpaca's MCP server lets you trade stocks and options, analyze market data, and build strategies through [Alpaca's Trading API](https://alpaca.markets/)
+-
**[AlphaVantage](https://github.com/calvernaz/alphavantage)** - Connect to 100+ APIs for financial market data, including stock prices, fundamentals, and more from [AlphaVantage](https://www.alphavantage.co)
+-
**[Apache Doris](https://github.com/apache/doris-mcp-server)** - MCP Server For [Apache Doris](https://doris.apache.org/), an MPP-based real-time data warehouse.
-
**[Apache IoTDB](https://github.com/apache/iotdb-mcp-server)** - MCP Server for [Apache IoTDB](https://github.com/apache/iotdb) database and its tools
-
**[Apify](https://github.com/apify/actors-mcp-server)** - [Actors MCP Server](https://apify.com/apify/actors-mcp-server): Use 3,000+ pre-built cloud tools to extract data from websites, e-commerce, social media, search engines, maps, and more
--
**[APIMatic MCP](https://github.com/apimatic/apimatic-validator-mcp)** - APIMatic MCP Server is used to validate OpenAPI specifications using [APIMatic](https://www.apimatic.io/). The server processes OpenAPI files and returns validation summaries by leveraging APIMatic’s API.
+-
**[APIMatic MCP](https://github.com/apimatic/apimatic-validator-mcp)** - APIMatic MCP Server is used to validate OpenAPI specifications using [APIMatic](https://www.apimatic.io/). The server processes OpenAPI files and returns validation summaries by leveraging APIMatic's API.
+-
**[Apollo MCP Server](https://github.com/apollographql/apollo-mcp-server/)** - Connect your GraphQL APIs to AI agents
+-
**[Aqara MCP Server](https://github.com/aqara/aqara-mcp-server/)** - Control [Aqara](https://www.aqara.com/) smart home devices, query status, execute scenes, and much more using natural language.
+-
**[Archbee](https://www.npmjs.com/package/@archbee/mcp)** - Write and publish documentation that becomes the trusted source for instant answers with AI. Stop cobbling tools and use [Archbee](https://www.archbee.com/) — the first complete documentation platform.
+-
**[Arize Phoenix](https://github.com/Arize-ai/phoenix/tree/main/js/packages/phoenix-mcp)** - Inspect traces, manage prompts, curate datasets, and run experiments using [Arize Phoenix](https://github.com/Arize-ai/phoenix), an open-source AI and LLM observability tool.
+-
**[Armor Crypto MCP](https://github.com/armorwallet/armor-crypto-mcp)** - MCP to interface with multiple blockchains, staking, DeFi, swap, bridging, wallet management, DCA, Limit Orders, Coin Lookup, Tracking and more.
+-
**[Asgardeo](https://github.com/asgardeo/asgardeo-mcp-server)** - MCP server to interact with your [Asgardeo](https://wso2.com/asgardeo) organization through LLM tools.
-
**[Astra DB](https://github.com/datastax/astra-db-mcp)** - Comprehensive tools for managing collections and documents in a [DataStax Astra DB](https://www.datastax.com/products/datastax-astra) NoSQL database with a full range of operations such as create, update, delete, find, and associated bulk actions.
+-
**[Atla](https://github.com/atla-ai/atla-mcp-server)** - Enable AI agents to interact with the [Atla API](https://docs.atla-ai.com/) for state-of-the-art LLMJ evaluation.
+-
**[Atlan](https://github.com/atlanhq/agent-toolkit/tree/main/modelcontextprotocol)** - The Atlan Model Context Protocol server allows you to interact with the [Atlan](https://www.atlan.com/) services through multiple tools.
+-
**[Atlassian](https://www.atlassian.com/platform/remote-mcp-server)** - Securely interact with Jira work items and Confluence pages, and search across both.
+-
**[AtomGit](https://atomgit.com/atomgit-open-source-ecosystem/atomgit-mcp-server)** - Official AtomGit server for integration with repository management, PRs, issues, branches, labels, and more.
-
**[Audiense Insights](https://github.com/AudienseCo/mcp-audiense-insights)** - Marketing insights and audience analysis from [Audiense](https://www.audiense.com/products/audiense-insights) reports, covering demographic, cultural, influencer, and content engagement analysis.
+-
**[Auth0](https://github.com/auth0/auth0-mcp-server)** - MCP server for interacting with your Auth0 tenant, supporting creating and modifying actions, applications, forms, logs, resource servers, and more.
+-
**[Authenticator App · 2FA](https://github.com/firstorderai/authenticator_mcp)** - A secure MCP (Model Context Protocol) server that enables AI agents to interact with the Authenticator App.
+-
**[AWS](https://github.com/awslabs/mcp)** - Specialized MCP servers that bring AWS best practices directly to your development workflow.
-
**[Axiom](https://github.com/axiomhq/mcp-server-axiom)** - Query and analyze your Axiom logs, traces, and all other event data in natural language
+-
**[Azure](https://github.com/Azure/azure-mcp)** - The Azure MCP Server gives MCP Clients access to key Azure services and tools like Azure Storage, Cosmos DB, the Azure CLI, and more.
+-
**[Baidu Map](https://github.com/baidu-maps/mcp)** - [Baidu Map MCP Server](https://lbsyun.baidu.com/faq/api?title=mcpserver/base) provides tools for AI agents to interact with Baidu Maps APIs, enabling location-based services and geospatial data analysis.
-
**[Bankless Onchain](https://github.com/bankless/onchain-mcp)** - Query Onchain data, like ERC20 tokens, transaction history, smart contract state.
-
**[BICScan](https://github.com/ahnlabio/bicscan-mcp)** - Risk score / asset holdings of EVM blockchain address (EOA, CA, ENS) and even domain names.
+-
**[Bitrise](https://github.com/bitrise-io/bitrise-mcp)** - Chat with your builds, CI, and [more](https://bitrise.io/blog/post/chat-with-your-builds-ci-and-more-introducing-the-bitrise-mcp-server).
+-
**[BoldSign](https://github.com/boldsign/boldsign-mcp)** - Search, request, and manage e-signature contracts effortlessly with [BoldSign](https://boldsign.com/).
+-
**[Boost.space](https://github.com/boostspace/boostspace-mcp-server)** - An MCP server integrating with [Boost.space](https://boost.space) for centralized, automated business data from 2000+ sources.
-
**[Box](https://github.com/box-community/mcp-server-box)** - Interact with the Intelligent Content Management platform through Box AI.
+-
**[BrightData](https://github.com/luminati-io/brightdata-mcp)** - Discover, extract, and interact with the web - one interface powering automated access across the public internet.
-
**[Browserbase](https://github.com/browserbase/mcp-server-browserbase)** - Automate browser interactions in the cloud (e.g. web navigation, data extraction, form filling, and more)
--
**[Chargebee](https://github.com/chargebee/agentkit/tree/main/modelcontextprotocol)** - MCP Server that connects AI agents to [Chargebee platform](https://www.chargebee.com).
--
**[Chroma](https://github.com/chroma-core/chroma-mcp)** - Embeddings, vector search, document storage, and full-text search with the open-source AI application database
+-
**[BrowserStack](https://github.com/browserstack/mcp-server)** - Access BrowserStack's [Test Platform](https://www.browserstack.com/test-platform) to debug, write and fix tests, do accessibility testing and more.
+-
**[Bucket](https://github.com/bucketco/bucket-javascript-sdk/tree/main/packages/cli#model-context-protocol)** - Flag features, manage company data, and control feature access using [Bucket](https://bucket.co)
+-
**[Buildable](https://github.com/chunkydotdev/bldbl-mcp)** (Typescript) - Official MCP server for Buildable AI-powered development platform. Enables AI assistants to manage tasks, track progress, get project context, and collaborate with humans on software projects.
+-
**[BuiltWith](https://github.com/builtwith/mcp)** - Identify the technology stack behind any website.
+-
**[Burp Suite](https://github.com/PortSwigger/mcp-server)** - MCP Server extension allowing AI clients to connect to [Burp Suite](https://portswigger.net)
+-
**[Campertunity](https://github.com/campertunity/mcp-server)** - Search campgrounds around the world on campertunity, check availability, and provide booking links.
+-
**[Cartesia](https://github.com/cartesia-ai/cartesia-mcp)** - Connect to the [Cartesia](https://cartesia.ai/) voice platform to perform text-to-speech, voice cloning etc.
+-
**[Cashfree](https://github.com/cashfree/cashfree-mcp)** - [Cashfree Payments](https://www.cashfree.com/) official MCP server.
+- **[CB Insights](https://github.com/cbinsights/cbi-mcp-server)** - Use the [CB Insights](https://www.cbinsights.com) MCP Server to connect to [ChatCBI](https://www.cbinsights.com/chatcbi/)
+-
**[Chargebee](https://github.com/chargebee/agentkit/tree/main/modelcontextprotocol)** - MCP Server that connects AI agents to [Chargebee platform](https://www.chargebee.com).
+-
**[Cheqd](https://github.com/cheqd/mcp-toolkit)** - Enable AI Agents to be trusted, verified, prevent fraud, protect your reputation, and more through [cheqd's](https://cheqd.io) Trust Registries and Credentials.
+-
**[Chiki StudIO](https://chiki.studio/galimybes/mcp/)** - Create your own configurable MCP servers purely via configuration (no code), with instructions, prompts, and tools support.
+-
**[Chroma](https://github.com/chroma-core/chroma-mcp)** - Embeddings, vector search, document storage, and full-text search with the open-source AI application database
-
**[Chronulus AI](https://github.com/ChronulusAI/chronulus-mcp)** - Predict anything with Chronulus AI forecasting and prediction agents.
-
**[CircleCI](https://github.com/CircleCI-Public/mcp-server-circleci)** - Enable AI Agents to fix build failures from CircleCI.
-
**[ClickHouse](https://github.com/ClickHouse/mcp-clickhouse)** - Query your [ClickHouse](https://clickhouse.com/) database server.
+-
**[Cloudera Iceberg](https://github.com/cloudera/iceberg-mcp-server)** - enabling AI on the [Open Data Lakehouse](https://www.cloudera.com/products/open-data-lakehouse.html).
-
**[Cloudflare](https://github.com/cloudflare/mcp-server-cloudflare)** - Deploy, configure & interrogate your resources on the Cloudflare developer platform (e.g. Workers/KV/R2/D1)
+-
**[Cloudinary](https://github.com/cloudinary/mcp-servers)** - Exposes Cloudinary's media upload, transformation, AI analysis, management, optimization and delivery as tools usable by AI agents
-
**[Codacy](https://github.com/codacy/codacy-mcp-server/)** - Interact with [Codacy](https://www.codacy.com) API to query code quality issues, vulnerabilities, and coverage insights about your code.
-
**[CodeLogic](https://github.com/CodeLogicIncEngineering/codelogic-mcp-server)** - Interact with [CodeLogic](https://codelogic.com), a Software Intelligence platform that graphs complex code and data architecture dependencies, to boost AI accuracy and insight.
--
**[Comet Opik](https://github.com/comet-ml/opik-mcp)** - Query and analyze your [Opik](https://github.com/comet-ml/opik) logs, traces, prompts and all other telemtry data from your LLMs in natural language.
--
**[Convex](https://stack.convex.dev/convex-mcp-server)** - Introspect and query your apps deployed to Convex.
+-
**[CoinGecko](https://github.com/coingecko/coingecko-typescript/tree/main/packages/mcp-server)** - Official [CoinGecko API](https://www.coingecko.com/en/api) MCP Server for Crypto Price & Market Data, across 200+ Blockchain Networks and 8M+ Tokens.
+-
**[Comet Opik](https://github.com/comet-ml/opik-mcp)** - Query and analyze your [Opik](https://github.com/comet-ml/opik) logs, traces, prompts and all other telemetry data from your LLMs in natural language.
+-
**[Conductor](https://github.com/conductor-oss/conductor-mcp)** - Interact with Conductor (OSS and Orkes) REST APIs.
+-
**[Confluent](https://github.com/confluentinc/mcp-confluent)** - Interact with Confluent Kafka and Confluent Cloud REST APIs.
+-
**[Contrast Security](https://github.com/Contrast-Security-OSS/mcp-contrast)** - Brings Contrast's vulnerability and SCA data into your coding agent to quickly remediate vulnerabilities.
+-
**[Convex](https://stack.convex.dev/convex-mcp-server)** - Introspect and query your apps deployed to Convex.
+-
**[Couchbase](https://github.com/Couchbase-Ecosystem/mcp-server-couchbase)** - Interact with the data stored in Couchbase clusters.
+-
**[CRIC Wuye AI](https://github.com/wuye-ai/mcp-server-wuye-ai)** - Interact with capabilities of the CRIC Wuye AI platform, an intelligent assistant specifically for the property management industry.
+-
**[Cycode](https://github.com/cycodehq/cycode-cli#mcp-command-experiment)** - Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning with [Cycode](https://cycode.com/).
-
**[Dart](https://github.com/its-dart/dart-mcp-server)** - Interact with task, doc, and project data in [Dart](https://itsdart.com), an AI-native project management tool
+-
**[CTERA Portal](https://github.com/ctera/mcp-ctera-core)** - CTERA Portal is a multi-tenant, multi-cloud platform that delivers a global namespace and unified management across petabytes of distributed content.
+-
**[CTERA Edge Filer](https://github.com/ctera/mcp-ctera-edge)** - CTERA Edge Filer delivers intelligent edge caching and multiprotocol file access, enabling fast, secure access to files across core and remote sites.
+-
**[DataHub](https://github.com/acryldata/mcp-server-datahub)** - Search your data assets, traverse data lineage, write SQL queries, and more using [DataHub](https://datahub.com/) metadata.
+-
**[Daytona](https://github.com/daytonaio/daytona/tree/main/apps/cli/mcp)** - Fast and secure execution of your AI generated code with [Daytona](https://daytona.io) sandboxes
+-
**[Debugg.AI](https://github.com/debugg-ai/debugg-ai-mcp)** - Zero-Config, Fully AI-Managed End-to-End Testing for any code gen platform via [Debugg.AI](https://debugg.ai) remote browsing test agents.
+-
**[DeepL](https://github.com/DeepLcom/deepl-mcp-server)** - Translate or rewrite text with [DeepL](https://deepl.com)'s very own AI models using [the DeepL API](https://developers.deepl.com/docs)
+-
**[Defang](https://github.com/DefangLabs/defang/blob/main/src/pkg/mcp/README.md)** - Deploy your project to the cloud seamlessly with the [Defang](https://www.defang.io) platform without leaving your integrated development environment
+-
**[Detailer](https://detailer.ginylil.com/)** – Instantly generate rich, AI-powered documentation for your GitHub repositories. Designed for AI agents to gain deep project context before taking action.
-
**[DevHub](https://github.com/devhub/devhub-cms-mcp)** - Manage and utilize website content within the [DevHub](https://www.devhub.com) CMS platform
+-
**[DevRev](https://github.com/devrev/mcp-server)** - An MCP server to integrate with DevRev APIs to search through your DevRev Knowledge Graph where objects can be imported from diff. Sources listed [here](https://devrev.ai/docs/import#available-sources).
+-
**[DexPaprika (CoinPaprika)](https://github.com/coinpaprika/dexpaprika-mcp)** - Access real-time DEX data, liquidity pools, token information, and trading analytics across multiple blockchain networks with [DexPaprika](https://dexpaprika.com) by CoinPaprika.
+-
**[Drata](https://drata.com/mcp)** - Get hands-on with our experimental MCP server—bringing real-time compliance intelligence into your AI workflows.
+-
**[Dumpling AI](https://github.com/Dumpling-AI/mcp-server-dumplingai)** - Access data, web scraping, and document conversion APIs by [Dumpling AI](https://www.dumplingai.com/)
+-
**[Dynatrace](https://github.com/dynatrace-oss/dynatrace-mcp)** - Manage and interact with the [Dynatrace Platform ](https://www.dynatrace.com/platform) for real-time observability and monitoring.
-
**[E2B](https://github.com/e2b-dev/mcp-server)** - Run code in secure sandboxes hosted by [E2B](https://e2b.dev)
+-
**[Edgee](https://github.com/edgee-cloud/mcp-server-edgee)** - Deploy and manage [Edgee](https://www.edgee.cloud) components and projects
-
**[EduBase](https://github.com/EduBase/MCP)** - Interact with [EduBase](https://www.edubase.net), a comprehensive e-learning platform with advanced quizzing, exam management, and content organization capabilities
-
**[Elasticsearch](https://github.com/elastic/mcp-server-elasticsearch)** - Query your data in [Elasticsearch](https://www.elastic.co/elasticsearch)
+-
**[Endor Labs](https://docs.endorlabs.com/deployment/ide/mcp/)** - Find and fix security risks in you code. Integrate [Endor Labs](https://endorlabs.com) to scan and secure your code from vulnerabilities and secret leaks.
-
**[eSignatures](https://github.com/esignaturescom/mcp-server-esignatures)** - Contract and template management for drafting, reviewing, and sending binding contracts.
-
**[Exa](https://github.com/exa-labs/exa-mcp-server)** - Search Engine made for AIs by [Exa](https://exa.ai)
+- **[FalkorDB](https://github.com/FalkorDB/FalkorDB-MCPServer)** - FalkorDB graph database server get schema and read/write-cypher [FalkorDB](https://www.falkordb.com)
+-
**[fetchSERP](https://github.com/fetchSERP/fetchserp-mcp-server-node)** - All-in-One SEO & Web Intelligence Toolkit API [fetchSERP](https://www.fetchserp.com/)
-
**[Fewsats](https://github.com/Fewsats/fewsats-mcp)** - Enable AI Agents to purchase anything in a secure way using [Fewsats](https://fewsats.com)
-
**[Fibery](https://github.com/Fibery-inc/fibery-mcp-server)** - Perform queries and entity operations in your [Fibery](https://fibery.io) workspace.
-
**[Financial Datasets](https://github.com/financial-datasets/mcp-server)** - Stock market API made for AI agents
+-
**[Firebase](https://github.com/firebase/firebase-tools/blob/master/src/mcp)** - Firebase's experimental [MCP Server](https://firebase.google.com/docs/cli/mcp-server) to power your AI Tools
-
**[Firecrawl](https://github.com/mendableai/firecrawl-mcp-server)** - Extract web data with [Firecrawl](https://firecrawl.dev)
+-
**[Firefly](https://github.com/gofireflyio/firefly-mcp)** - Integrates, discovers, manages, and codifies cloud resources with [Firefly](https://firefly.ai).
-
**[Fireproof](https://github.com/fireproof-storage/mcp-database-server)** - Immutable ledger database with live synchronization
+-
**[FIXParser](https://gitlab.com/logotype/fixparser/-/tree/main/packages/fixparser-plugin-mcp)** - A modern FIX Protocol engine for AI-powered trading agents
+-
**[Fluid Attacks](https://github.com/fluidattacks/mcp)** - Interact with the [Fluid Attacks](https://fluidattacks.com/) API, enabling vulnerability management, organization insights, and GraphQL query execution.
+-
**[ForeverVM](https://github.com/jamsocket/forevervm/tree/main/javascript/mcp-server)** - Run Python in a code sandbox.
+-
**[GibsonAI](https://github.com/GibsonAI/mcp)** - AI-Powered Cloud databases: Build, migrate, and deploy database instances with AI
+-
**[Gitea](https://gitea.com/gitea/gitea-mcp)** - Interact with Gitea instances with MCP.
-
**[Gitee](https://github.com/oschina/mcp-gitee)** - Gitee API integration, repository, issue, and pull request management, and more.
+-
**[GitHub](https://github.com/github/github-mcp-server)** - GitHub's official MCP Server.
+-
**[Glean](https://github.com/gleanwork/mcp-server)** - Enterprise search and chat using Glean's API.
+-
**[Globalping](https://github.com/jsdelivr/globalping-mcp-server)** - Access a network of thousands of probes to run network commands like ping, traceroute, mtr, http and DNS resolve.
+-
**[gNucleus Text-To-CAD](https://github.com/gNucleus/text-to-cad-mcp)** - Generate CAD parts and assemblies from text using gNucleus AI models.
+-
**[Google Cloud Run](https://github.com/GoogleCloudPlatform/cloud-run-mcp)** - Deploy code to Google Cloud Run
+-
**[GoLogin MCP server](https://github.com/gologinapp/gologin-mcp)** - Manage your GoLogin browser profiles and automation directly through AI conversations!
-
**[gotoHuman](https://github.com/gotohuman/gotohuman-mcp-server)** - Human-in-the-loop platform - Allow AI agents and automations to send requests for approval to your [gotoHuman](https://www.gotohuman.com) inbox.
-
**[Grafana](https://github.com/grafana/mcp-grafana)** - Search dashboards, investigate incidents and query datasources in your Grafana instance
+-
**[Grafbase](https://github.com/grafbase/grafbase/tree/main/crates/mcp)** - Turn your GraphQL API into an efficient MCP server with schema intelligence in a single command.
+-
**[Grain](https://grain.com/release-note/06-18-2025)** - Access your Grain meetings notes & transcripts directly in claude and generate reports with native Claude Prompts.
-
**[Graphlit](https://github.com/graphlit/graphlit-mcp-server)** - Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a searchable [Graphlit](https://www.graphlit.com) project.
-
**[GreptimeDB](https://github.com/GreptimeTeam/greptimedb-mcp-server)** - Provides AI assistants with a secure and structured way to explore and analyze data in [GreptimeDB](https://github.com/GreptimeTeam/greptimedb).
+-
**[GROWI](https://github.com/growilabs/growi-mcp-server)** - Official MCP Server to integrate with GROWI APIs.
+-
**[Gyazo](https://github.com/nota/gyazo-mcp-server)** - Search, fetch, upload, and interact with Gyazo images, including metadata and OCR data.
+-
**[Harper](https://github.com/HarperDB/mcp-server)** - An MCP server providing an interface for MCP clients to access data within [Harper](https://www.harpersystems.dev/).
-
**[Heroku](https://github.com/heroku/heroku-mcp-server)** - Interact with the Heroku Platform through LLM-driven tools for managing apps, add-ons, dynos, databases, and more.
+-
**[Hiveflow](https://github.com/hiveflowai/hiveflow-mcp-server)** - Create, manage, and execute agentic AI workflows directly from your assistant.
-
**[Hologres](https://github.com/aliyun/alibabacloud-hologres-mcp-server)** - Connect to a [Hologres](https://www.alibabacloud.com/en/product/hologres) instance, get table metadata, query and analyze data.
+-
**[Honeycomb](https://github.com/honeycombio/honeycomb-mcp)** Allows [Honeycomb](https://www.honeycomb.io/) Enterprise customers to query and analyze their data, alerts, dashboards, and more; and cross-reference production behavior with the codebase.
+-
**[HubSpot](https://developer.hubspot.com/mcp)** - Connect, manage, and interact with [HubSpot](https://www.hubspot.com/) CRM data
+-
**[Hugging Face](https://huggingface.co/settings/mcp)** - Connect to the Hugging Face Hub APIs programmatically: semantic search for spaces and papers, exploration of datasets and models, and access to all compatible MCP Gradio tool spaces!
+-
**[Hunter](https://github.com/hunter-io/hunter-mcp)** - Interact with the [Hunter API](https://hunter.io) to get B2B data using natural language.
+-
**[Hyperbolic](https://github.com/HyperbolicLabs/hyperbolic-mcp)** - Interact with Hyperbolic's GPU cloud, enabling agents and LLMs to view and rent available GPUs, SSH into them, and run GPU-powered workloads for you.
-
**[Hyperbrowser](https://github.com/hyperbrowserai/mcp)** - [Hyperbrowser](https://www.hyperbrowser.ai/) is the next-generation platform empowering AI agents and enabling effortless, scalable browser automation.
- **[IBM wxflows](https://github.com/IBM/wxflows/tree/main/examples/mcp/javascript)** - Tool platform by IBM to build, test and deploy tools for any data source
--
**[ForeverVM](https://github.com/jamsocket/forevervm/tree/main/javascript/mcp-server)** - Run Python in a code sandbox.
-
**[Inbox Zero](https://github.com/elie222/inbox-zero/tree/main/apps/mcp-server)** - AI personal assistant for email [Inbox Zero](https://www.getinboxzero.com)
+-
**[Inflectra Spira](https://github.com/Inflectra/mcp-server-spira)** - Connect to your instance of the SpiraTest, SpiraTeam or SpiraPlan application lifecycle management platform by [Inflectra](https://www.inflectra.com)
-
**[Inkeep](https://github.com/inkeep/mcp-server-python)** - RAG Search over your content powered by [Inkeep](https://inkeep.com)
-
**[Integration App](https://github.com/integration-app/mcp-server)** - Interact with any other SaaS applications on behalf of your customers.
+-
**[IP2Location.io](https://github.com/ip2location/mcp-ip2location-io)** - Interact with IP2Location.io API to retrieve the geolocation information for an IP address.
-
**[JetBrains](https://github.com/JetBrains/mcp-jetbrains)** – Work on your code with JetBrains IDEs
+-
**[JFrog](https://github.com/jfrog/mcp-jfrog)** - Model Context Protocol (MCP) Server for the [JFrog](https://jfrog.com/) Platform API, enabling repository management, build tracking, release lifecycle management, and more.
-
**[Kagi Search](https://github.com/kagisearch/kagimcp)** - Search the web using Kagi's search API
-
**[Keboola](https://github.com/keboola/keboola-mcp-server)** - Build robust data workflows, integrations, and analytics on a single intuitive platform.
--
**[Lara Translate](https://github.com/translated/lara-mcp)** - MCP Server for Lara Translate API, enabling powerful translation capabilities with support for language detection and context-aware translations.
--
**[Logfire](https://github.com/pydantic/logfire-mcp)** - Provides access to OpenTelemetry traces and metrics through Logfire.
+-
**[KeywordsPeopleUse.com](https://github.com/data-skunks/kpu-mcp)** - Find questions people ask online with [KeywordsPeopleUse](https://keywordspeopleuse.com).
+-
**[Klavis ReportGen](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/report_generation)** - Create professional reports from a simple user query.
+-
**[Klaviyo](https://developers.klaviyo.com/en/docs/klaviyo_mcp_server)** - Interact with your [Klaviyo](https://www.klaviyo.com/) marketing data.
+-
**[kluster.ai](https://docs.kluster.ai/get-started/mcp/overview/)** - kluster.ai provides MCP servers that bring AI services directly into your development workflow, including guardrails like hallucination detection.
+-
**[Knit MCP Server](https://developers.getknit.dev/docs/knit-mcp-server-getting-started)** - Production-ready remote MCP servers that enable you to connect with 10000+ tools across CRM, HRIS, Payroll, Accounting, ERP, Calendar, Expense Management, and Chat categories.
+-
**[Knock MCP Server](https://github.com/knocklabs/agent-toolkit#model-context-protocol-mcp)** - Send product and customer messaging across email, in-app, push, SMS, Slack, MS Teams.
+-
**[KurrentDB](https://github.com/kurrent-io/mcp-server)** - This is a simple MCP server to help you explore data and prototype projections faster on top of KurrentDB.
+-
**[Kuzu](https://github.com/kuzudb/kuzu-mcp-server)** - This server enables LLMs to inspect database schemas and execute queries on the provided Kuzu graph database. See [blog](https://blog.kuzudb.com/post/2025-03-23-kuzu-mcp-server/)) for a debugging use case.
+-
**[KWDB](https://github.com/KWDB/kwdb-mcp-server)** - Reading, writing, querying, modifying data, and performing DDL operations with data in your KWDB Database.
+-
**[Label Studio](https://github.com/HumanSignal/label-studio-mcp-server)** - Open Source data labeling platform.
+-
**[Lambda Capture](https://github.com/lambda-capture/mcp-server)** - Macroeconomic Forecasts & Semantic Context from Federal Reserve, Bank of England, ECB.
-
**[Langfuse Prompt Management](https://github.com/langfuse/mcp-server-langfuse)** - Open-source tool for collaborative editing, versioning, evaluating, and releasing prompts.
+-
**[Lara Translate](https://github.com/translated/lara-mcp)** - MCP Server for Lara Translate API, enabling powerful translation capabilities with support for language detection and context-aware translations.
+-
**[Last9](https://github.com/last9/last9-mcp-server)** - Seamlessly bring real-time production context—logs, metrics, and traces—into your local environment to auto-fix code faster.
+-
**[LaunchDarkly](https://github.com/launchdarkly/mcp-server)** - LaunchDarkly is a continuous delivery platform that provides feature flags as a service and allows developers to iterate quickly and safely.
+-
**[LINE](https://github.com/line/line-bot-mcp-server)** - Integrates the LINE Messaging API to connect an AI Agent to the LINE Official Account.
+-
**[Linear](https://linear.app/docs/mcp)** - Search, create, and update Linear issues, projects, and comments.
-
**[Lingo.dev](https://github.com/lingodotdev/lingo.dev/blob/main/mcp.md)** - Make your AI agent speak every language on the planet, using [Lingo.dev](https://lingo.dev) Localization Engine.
+-
**[LinkedIn MCP Runner](https://github.com/ertiqah/linkedin-mcp-runner)** - Write, edit, and schedule LinkedIn posts right from ChatGPT and Claude with [LiGo](https://ligo.ertiqah.com/).
+-
**[Lisply](https://github.com/gornskew/lisply-mcp)** - Flexible frontend for compliant Lisp-speaking backends.
+-
**[Litmus.io](https://github.com/litmusautomation/litmus-mcp-server)** - Official MCP server for configuring [Litmus](https://litmus.io) Edge for Industrial Data Collection, Edge Analytics & Industrial AI.
+-
**[Liveblocks](https://github.com/liveblocks/liveblocks-mcp-server)** - Ready‑made features for AI & human collaboration—use this to develop your [Liveblocks](https://liveblocks.io) app quicker.
+-
**[Logfire](https://github.com/pydantic/logfire-mcp)** - Provides access to OpenTelemetry traces and metrics through Logfire.
+-
**[Magic Meal Kits](https://github.com/pureugong/mmk-mcp)** - Unleash Make's Full Potential by [Magic Meal Kits](https://make.magicmealkits.com/)
-
**[Mailgun](https://github.com/mailgun/mailgun-mcp-server)** - Interact with Mailgun API.
-
**[Make](https://github.com/integromat/make-mcp-server)** - Turn your [Make](https://www.make.com/) scenarios into callable tools for AI assistants.
+-
**[Mapbox](https://github.com/mapbox/mcp-server)** - Unlock geospatial intelligence through Mapbox APIs like geocoding, POI search, directions, isochrones and more.
+-
**[MariaDB](https://github.com/mariadb/mcp)** - A standard interface for managing and querying MariaDB databases, supporting both standard SQL operations and advanced vector/embedding-based search.
+-
**[MCP Discovery](https://github.com/rust-mcp-stack/mcp-discovery)** - A lightweight CLI tool built in Rust for discovering MCP server capabilities.
+-
**[MCP Toolbox for Databases](https://github.com/googleapis/genai-toolbox)** - Open source MCP server specializing in easy, fast, and secure tools for Databases. Supports AlloyDB, BigQuery, Bigtable, Cloud SQL, Dgraph, MySQL, Neo4j, Postgres, Spanner, and more.
-
**[Meilisearch](https://github.com/meilisearch/meilisearch-mcp)** - Interact & query with Meilisearch (Full-text & semantic search API)
--
**[Metoro](https://github.com/metoro-io/metoro-mcp-server)** - Query and interact with kubernetes environments monitored by Metoro
+-
**[Memgraph](https://github.com/memgraph/mcp-memgraph)** - Query your data in [Memgraph](https://memgraph.com/) graph database.
+-
**[Memgraph](https://github.com/memgraph/ai-toolkit/tree/main/integrations/mcp-memgraph)** - Query your data in [Memgraph](https://memgraph.com/) graph database.
+-
**[Mercado Pago](https://mcp.mercadopago.com/)** - Mercado Pago's official MCP server.
+-
**[Metoro](https://github.com/metoro-io/metoro-mcp-server)** - Query and interact with kubernetes environments monitored by Metoro
+-
**[Microsoft Clarity](https://github.com/microsoft/clarity-mcp-server)** - Official MCP Server to get your behavioral analytics data and insights from [Clarity](https://clarity.microsoft.com)
+-
**[Microsoft Dataverse](https://go.microsoft.com/fwlink/?linkid=2320176)** - Chat over your business data using NL - Discover tables, run queries, retrieve data, insert or update records, and execute custom prompts grounded in business knowledge and context.
+-
**[Microsoft Learn Docs](https://github.com/microsoftdocs/mcp)** - An MCP server that provides structured access to Microsoft’s official documentation. Retrieves accurate, authoritative, and context-aware technical content for code generation, question answering, and workflow grounding.
-
**[Milvus](https://github.com/zilliztech/mcp-server-milvus)** - Search, Query and interact with data in your Milvus Vector Database.
+-
**[Mobb](https://github.com/mobb-dev/bugsy?tab=readme-ov-file#model-context-protocol-mcp-server)** - The [Mobb Vibe Shield](https://vibe.mobb.ai/) MCP server identifies and remediates vulnerabilities in both human and AI-written code, ensuring your applications remain secure without slowing development.
-
**[Momento](https://github.com/momentohq/mcp-momento)** - Momento Cache lets you quickly improve your performance, reduce costs, and handle load at any scale.
+-
**[MongoDB](https://github.com/mongodb-js/mongodb-mcp-server)** - Both MongoDB Community Server and MongoDB Atlas are supported.
-
**[MotherDuck](https://github.com/motherduckdb/mcp-server-motherduck)** - Query and analyze data with MotherDuck and local DuckDB
+-
**[Mulesoft](https://www.npmjs.com/package/@mulesoft/mcp-server)** - Build, deploy, and manage MuleSoft applications with natural language, directly inside any compatible IDE.
+-
**[NanoVMs](https://github.com/nanovms/ops-mcp)** - Easily Build and Deploy unikernels to any cloud.
-
**[Needle](https://github.com/needle-ai/needle-mcp)** - Production-ready RAG out of the box to search and retrieve data from your own documents.
-
**[Neo4j](https://github.com/neo4j-contrib/mcp-neo4j/)** - Neo4j graph database server (schema + read/write-cypher) and separate graph database backed memory
-
**[Neon](https://github.com/neondatabase/mcp-server-neon)** - Interact with the Neon serverless Postgres platform
+-
**[Nerve](https://github.com/nerve-hq/nerve-mcp-server)** - Search and Act on all your company data across all your SaaS apps via [Nerve](https://www.usenerve.com/)
+-
**[Netdata](https://github.com/netdata/netdata/blob/master/src/web/mcp/README.md)** - Discovery, exploration, reporting and root cause analysis using all observability data, including metrics, logs, systems, containers, processes, and network connections
+-
**[Netlify](https://docs.netlify.com/welcome/build-with-ai/netlify-mcp-server/)** - Create, build, deploy, and manage your websites with Netlify web platform.
+-
**[Nile](https://github.com/niledatabase/nile-mcp-server)** - An MCP server that talks to Nile - Postgres re-engineered for B2B apps. Manage and query databases, tenants, users, auth using LLMs
+-
**[Nodit](https://github.com/noditlabs/nodit-mcp-server)** - Official Nodit MCP Server enabling access to multi-chain RPC Nodes and Data APIs for blockchain data.
+-
**[Norman Finance](https://github.com/norman-finance/norman-mcp-server)** - MCP server for managing accounting and taxes with Norman Finance.
-
**[Notion](https://github.com/makenotion/notion-mcp-server#readme)** - This project implements an MCP server for the Notion API.
+-
**[Nutrient](https://github.com/PSPDFKit/nutrient-dws-mcp-server)** - Create, Edit, Sign, Extract Documents using Natural Language
+-
**[Nx](https://github.com/nrwl/nx-console/blob/master/apps/nx-mcp)** - Makes [Nx's understanding](https://nx.dev/features/enhance-AI) of your codebase accessible to LLMs, providing insights into the codebase architecture, project relationships and runnable tasks thus allowing AI to make precise code suggestions.
-
**[OceanBase](https://github.com/oceanbase/mcp-oceanbase)** - MCP Server for OceanBase database and its tools
-
**[Octagon](https://github.com/OctagonAI/octagon-mcp-server)** - Deliver real-time investment research with extensive private and public market data.
+-
**[OctoEverywhere](https://github.com/OctoEverywhere/mcp)** - A 3D Printing MCP server that allows for querying for live state, webcam snapshots, and 3D printer control.
+-
**[Offorte](https://github.com/offorte/offorte-mcp-server#readme)** - Offorte Proposal Software official MCP server enables creation and sending of business proposals.
-
**[OlaMaps](https://pypi.org/project/ola-maps-mcp-server)** - Official Ola Maps MCP Server for services like geocode, directions, place details and many more.
+-
**[ONLYOFFICE DocSpace](https://github.com/ONLYOFFICE/docspace-mcp)** - Interact with [ONLYOFFICE DocSpace](https://www.onlyoffice.com/docspace.aspx) API to create rooms, manage files and folders.
+-
**[OP.GG](https://github.com/opgginc/opgg-mcp)** - Access real-time gaming data across popular titles like League of Legends, TFT, and Valorant, offering champion analytics, esports schedules, meta compositions, and character statistics.
+-
**[OpenSearch](https://github.com/opensearch-project/opensearch-mcp-server-py)** - MCP server that enables AI agents to perform search and analytics use cases on data stored in [OpenSearch](https://opensearch.org/).
+-
**[OpsLevel](https://github.com/opslevel/opslevel-mcp)** - Official MCP Server for [OpsLevel](https://www.opslevel.com).
+-
**[Optuna](https://github.com/optuna/optuna-mcp)** - Official MCP server enabling seamless orchestration of hyperparameter search and other optimization tasks with [Optuna](https://optuna.org/).
+-
**[Orshot](https://github.com/rishimohan/orshot-mcp-server)** - Official [Orshot](https://orshot.com) MCP server to dynamically generate images from custom design templates.
-
**[Oxylabs](https://github.com/oxylabs/oxylabs-mcp)** - Scrape websites with Oxylabs Web API, supporting dynamic rendering and parsing for structured data extraction.
-
**[Paddle](https://github.com/PaddleHQ/paddle-mcp-server)** - Interact with the Paddle API. Manage product catalog, billing and subscriptions, and reports.
+- **[Pagos](https://github.com/pagos-ai/pagos-mcp)** - Interact with the Pagos API. Query Credit Card BIN Data with more to come.
+-
**[PAIML MCP Agent Toolkit](https://github.com/paiml/paiml-mcp-agent-toolkit)** - Professional project scaffolding toolkit with zero-configuration AI context generation, template generation for Rust/Deno/Python projects, and hybrid neuro-symbolic code analysis.
+-
**[Paper](https://github.com/paperinvest/mcp-server)** - Realistic paper trading platform with market simulation, 22 broker emulations, and professional tools for risk-free trading practice. First trading platform with MCP integration.
+- **[Patronus AI](https://github.com/patronus-ai/patronus-mcp-server)** - Test, evaluate, and optimize AI agents and RAG apps
-
**[PayPal](https://mcp.paypal.com)** - PayPal's official MCP server.
+-
**[Pearl](https://github.com/Pearl-com/pearl_mcp_server)** - Official MCP Server to interact with Pearl API. Connect your AI Agents with 12,000+ certified experts instantly.
-
**[Perplexity](https://github.com/ppl-ai/modelcontextprotocol)** - An MCP server that connects to Perplexity's Sonar API, enabling real-time web-wide research in conversational AI.
+-
**[Pinecone](https://github.com/pinecone-io/pinecone-mcp)** - [Pinecone](https://docs.pinecone.io/guides/operations/mcp-server)'s developer MCP Server assist developers in searching documentation and managing data within their development environment.
+-
**[Pinecone Assistant](https://github.com/pinecone-io/assistant-mcp)** - Retrieves context from your [Pinecone Assistant](https://docs.pinecone.io/guides/assistant/mcp-server) knowledge base.
+-
**[Pipedream](https://github.com/PipedreamHQ/pipedream/tree/master/modelcontextprotocol)** - Connect with 2,500 APIs with 8,000+ prebuilt tools.
+-
**[PlayCanvas](https://github.com/playcanvas/editor-mcp-server)** - Create interactive 3D web apps with the PlayCanvas Editor.
+-
**[Plugged.in](https://github.com/VeriTeknik/pluggedin-mcp)** - A comprehensive proxy that combines multiple MCP servers into a single MCP. It provides discovery and management of tools, prompts, resources, and templates across servers, plus a playground for debugging when building MCP servers.
+-
**[Port IO](https://github.com/port-labs/port-mcp-server)** - Access and manage your software catalog to improve service quality and compliance.
+- **[PostHog](https://github.com/posthog/mcp)** - Interact with PostHog analytics, feature flags, error tracking and more with the official PostHog MCP server.
+- **[Postman API](https://github.com/postmanlabs/postman-api-mcp)** - Manage your Postman resources using the [Postman API](https://www.postman.com/postman/postman-public-workspace/collection/i2uqzpp/postman-api).
+-
**[Powerdrill](https://github.com/powerdrillai/powerdrill-mcp)** - An MCP server that provides tools to interact with Powerdrill datasets, enabling smart AI data analysis and insights.
+-
**[Prisma](https://www.prisma.io/docs/postgres/mcp-server)** - Create and manage Prisma Postgres databases
+-
**[proxymock](https://docs.speedscale.com/proxymock/reference/mcp/)** - An MCP server that automatically generates tests and mocks by recording a live app.
+-
**[PubNub](https://github.com/pubnub/pubnub-mcp-server)** - Retrieves context for developing with PubNub SDKs and calling APIs.
+-
**[Pulumi](https://github.com/pulumi/mcp-server)** - Deploy and manage cloud infrastructure using [Pulumi](https://pulumi.com).
+-
**[Pure.md](https://github.com/puremd/puremd-mcp)** - Reliably access web content in markdown format with [pure.md](https://pure.md) (bot detection avoidance, proxy rotation, and headless JS rendering built in).
+-
**[Put.io](https://github.com/putdotio/putio-mcp-server)** - Interact with your Put.io account to download torrents.
-
**[Qdrant](https://github.com/qdrant/mcp-server-qdrant/)** - Implement semantic memory layer on top of the Qdrant vector search engine
+- **[Quickchat AI](https://github.com/incentivai/quickchat-ai-mcp)** - Launch your conversational [Quickchat AI](https://quickchat.ai) agent as an MCP to give AI apps real-time access to its Knowledge Base and conversational capabilities
+-
**[Ragie](https://github.com/ragieai/ragie-mcp-server/)** - Retrieve context from your [Ragie](https://www.ragie.ai) (RAG) knowledge base connected to integrations like Google Drive, Notion, JIRA and more.
-
**[Ramp](https://github.com/ramp-public/ramp-mcp)** - Interact with [Ramp](https://ramp.com)'s Developer API to run analysis on your spend and gain insights leveraging LLMs
- **[Raygun](https://github.com/MindscapeHQ/mcp-server-raygun)** - Interact with your crash reporting and real using monitoring data on your Raygun account
+-
**[Razorpay](https://github.com/razorpay/razorpay-mcp-server)** - Razorpay's official MCP server
+-
**[Recraft](https://github.com/recraft-ai/mcp-recraft-server)** - Generate raster and vector (SVG) images using [Recraft](https://recraft.ai). Also you can edit, upscale images, create your own styles, and vectorize raster images
+-
**[Redis](https://github.com/redis/mcp-redis/)** - The Redis official MCP Server offers an interface to manage and search data in Redis.
+-
**[Redis Cloud API](https://github.com/redis/mcp-redis-cloud/)** - The Redis Cloud API MCP Server allows you to manage your Redis Cloud resources using natural language.
+-
**[Reexpress](https://github.com/ReexpressAI/reexpress_mcp_server)** - Enable Similarity-Distance-Magnitude statistical verification for your search, software, and data science workflows
-
**[Rember](https://github.com/rember/rember-mcp)** - Create spaced repetition flashcards in [Rember](https://rember.com) to remember anything you learn in your chats
+-
**[Revit](https://github.com/NonicaTeam/AI-Connector-for-Revit)** - Connect and interact with your Revit models live.
+-
**[Rill Data](https://docs.rilldata.com/explore/mcp)** - Interact with Rill Data to query and analyze your data.
-
**[Riza](https://github.com/riza-io/riza-mcp)** - Arbitrary code execution and tool-use platform for LLMs by [Riza](https://riza.io)
--
[Search1API](https://github.com/fatwang2/search1api-mcp) - One API for Search, Crawling, and Sitemaps
+-
**[Roblox Studio](https://github.com/Roblox/studio-rust-mcp-server)** - Roblox Studio MCP Server, create and manipulate scenes, scripts in Roblox Studio
+-
**[Rodin](https://github.com/DeemosTech/rodin-api-mcp)** - Generate 3D Models with [Hyper3D Rodin](https://hyper3d.ai)
+-
**[Root Signals](https://github.com/root-signals/root-signals-mcp)** - Improve and quality control your outputs with evaluations using LLM-as-Judge
+- **[Routine](https://github.com/routineco/mcp-server)** - MCP server to interact with [Routine](https://routine.co/): calendars, tasks, notes, etc.
+-
**[SafeDep](https://github.com/safedep/vet/blob/main/docs/mcp.md)** - SafeDep `vet-mcp` helps in vetting open source packages for security risks—such as vulnerabilities and malicious code—before they're used in your project, especially with AI-generated code suggestions.
+-
**[SafeLine](https://github.com/chaitin/SafeLine/tree/main/mcp_server)** - [SafeLine](https://safepoint.cloud/landing/safeline) is a self-hosted WAF(Web Application Firewall) to protect your web apps from attacks and exploits.
+-
**[ScrAPI](https://github.com/DevEnterpriseSoftware/scrapi-mcp)** - Web scraping using [ScrAPI](https://scrapi.tech). Extract website content that is difficult to access because of bot detection, captchas or even geolocation restrictions.
-
**[ScreenshotOne](https://github.com/screenshotone/mcp/)** - Render website screenshots with [ScreenshotOne](https://screenshotone.com/)
+-
**[Search1API](https://github.com/fatwang2/search1api-mcp)** - One API for Search, Crawling, and Sitemaps
+-
**[Secureframe](https://github.com/secureframe/secureframe-mcp-server)** - Query security controls, monitor compliance tests, and access audit data across SOC 2, ISO 27001, CMMC, FedRAMP, and other frameworks from [Secureframe](https://secureframe.com).
-
**[Semgrep](https://github.com/semgrep/mcp)** - Enable AI agents to secure code with [Semgrep](https://semgrep.dev/).
+-
**[Shortcut](https://github.com/useshortcut/mcp-server-shortcut)** - Access and implement all of your projects and tasks (Stories) from [Shortcut](https://shortcut.com/).
-
**[SingleStore](https://github.com/singlestore-labs/mcp-server-singlestore)** - Interact with the SingleStore database platform
+-
**[Smooth Operator](https://smooth-operator.online/agent-tools-api-docs/toolserverdocs)** - Tools to automate Windows via AI Vision, Mouse, Keyboard, Automation Trees, Webbrowser
+-
**[Snyk](https://github.com/snyk/snyk-ls/blob/main/mcp_extension/README.md)** - Enhance security posture by embedding [Snyk](https://snyk.io/) vulnerability scanning directly into agentic workflows.
+-
**[SonarQube](https://github.com/SonarSource/sonarqube-mcp-server)** - Enables seamless integration with [SonarQube](https://www.sonarsource.com/) Server or Cloud and allows for code snippet analysis within the agent context.
+-
**[Sophtron](https://github.com/sophtron/Sophtron-Integration/tree/main/modelcontextprotocol)** - Connect to your bank, credit card, utilities accounts to retrieve account balances and transactions with [Sophtron Bank Integration](https://sophtron.com).
-
**[StarRocks](https://github.com/StarRocks/mcp-server-starrocks)** - Interact with [StarRocks](https://www.starrocks.io/)
+-
**[Steadybit](https://github.com/steadybit/mcp)** - Interact with [Steadybit](https://www.steadybit.com/)
-
**[Stripe](https://github.com/stripe/agent-toolkit)** - Interact with Stripe API
+-
**[Supabase](https://github.com/supabase-community/supabase-mcp)** - Interact with Supabase: Create tables, query data, deploy edge functions, and more.
+-
**[Tako](https://github.com/TakoData/tako-mcp)** - Use natural language to search [Tako](https://trytako.com) for real-time financial, sports, weather, and public data with visualization
-
**[Tavily](https://github.com/tavily-ai/tavily-mcp)** - Search engine for AI agents (search + extract) powered by [Tavily](https://tavily.com/)
+-
**[Teradata](https://github.com/Teradata/teradata-mcp-server)** - This MCP Server support tools and prompts for multi task data analytics on a [Teradata](https://teradata.com) platform.
+-
**[Terraform](https://github.com/hashicorp/terraform-mcp-server)** - Seamlessly integrate with Terraform ecosystem, enabling advanced automation and interaction capabilities for Infrastructure as Code (IaC) development powered by [Terraform](https://www.hashicorp.com/en/products/terraform)
+-
**[TextIn](https://github.com/intsig-textin/textin-mcp)** - An MCP server for the [TextIn](https://www.textin.com/?from=github_mcp) API, is a tool for extracting text and performing OCR on documents, it also supports converting documents into Markdown
+-
**[Thena](https://mcp.thena.ai)** - Thena's MCP server for enabling users and AI agents to interact with Thena's services and manage customers across different channels such as Slack, Email, Web, Discord etc.
+-
**[ThinQ Connect](https://github.com/thinq-connect/thinqconnect-mcp)** - Interact with LG ThinQ smart home devices and appliances through the ThinQ Connect MCP server.
-
**[Thirdweb](https://github.com/thirdweb-dev/ai/tree/main/python/thirdweb-mcp)** - Read/write to over 2k blockchains, enabling data querying, contract analysis/deployment, and transaction execution, powered by [Thirdweb](https://thirdweb.com/)
+-
**[ThoughtSpot](https://github.com/thoughtspot/mcp-server)** - AI is the new BI. A dedicated data analyst for everyone on your team. Bring [ThoughtSpot](https://thoughtspot.com) powers into Claude or any MCP host.
+-
**[Tianji](https://github.com/msgbyte/tianji/tree/master/apps/mcp-server)** - Interact with Tianji platform whatever selfhosted or cloud platform, powered by [Tianji](https://tianji.msgbyte.com/).
+-
**[TiDB](https://github.com/pingcap/pytidb)** - MCP Server to interact with TiDB database platform.
-
**[Tinybird](https://github.com/tinybirdco/mcp-tinybird)** - Interact with Tinybird serverless ClickHouse platform
+-
**[Tldv](https://gitlab.com/tldv/tldv-mcp-server)** - Connect your AI agents to Google-Meet, Zoom & Microsoft Teams through [tl;dv](https://tldv.io)
+-
**[Token Metrics](https://github.com/token-metrics/mcp)** - [Token Metrics](https://www.tokenmetrics.com/) integration for fetching real-time crypto market data, trading signals, price predictions, and advanced analytics.
+-
**[Trade Agent](https://github.com/Trade-Agent/trade-agent-mcp)** - Execute stock and crypto trades on your brokerage via [Trade Agent](https://thetradeagent.ai)
+-
**[Twilio](https://github.com/twilio-labs/mcp)** - Interact with [Twilio](https://www.twilio.com/en-us) APIs to send SMS messages, manage phone numbers, configure your account, and more.
-
**[UnifAI](https://github.com/unifai-network/unifai-mcp-server)** - Dynamically search and call tools using [UnifAI Network](https://unifai.network)
-
**[Unstructured](https://github.com/Unstructured-IO/UNS-MCP)** - Set up and interact with your unstructured data processing workflows in [Unstructured Platform](https://unstructured.io)
+-
**[Upstash](https://github.com/upstash/mcp-server)** - Manage Redis databases and run Redis commands on [Upstash](https://upstash.com/) with natural language.
+-
**[Vantage](https://github.com/vantage-sh/vantage-mcp-server)** - Interact with your organization's cloud cost spend.
+-
**[VariFlight](https://github.com/variflight/variflight-mcp)** - VariFlight's official MCP server provides tools to query flight information, weather data, comfort metrics, the lowest available fares, and other civil aviation-related data.
+-
**[VCAgents](https://github.com/OctagonAI/octagon-vc-agents)** - Interact with investor agents—think Wilson or Thiel—continuously updated with market intel.
- **[Vectorize](https://github.com/vectorize-io/vectorize-mcp-server/)** - [Vectorize](https://vectorize.io) MCP server for advanced retrieval, Private Deep Research, Anything-to-Markdown file extraction and text chunking.
+-
**[Verbwire](https://github.com/verbwire/verbwire-mcp-server)** - Deploy smart contracts, mint NFTs, manage IPFS storage, and more through the Verbwire API
-
**[Verodat](https://github.com/Verodat/verodat-mcp-server)** - Interact with Verodat AI Ready Data platform
-
**[VeyraX](https://github.com/VeyraX/veyrax-mcp)** - Single tool to control all 100+ API integrations, and UI components
+-
**[VictoriaMetrics](https://github.com/VictoriaMetrics-Community/mcp-victoriametrics)** - Comprehensive integration with [VictoriaMetrics APIs](https://docs.victoriametrics.com/victoriametrics/url-examples/) and [documentation](https://docs.victoriametrics.com/) for monitoring, observability, and debugging tasks related to your VictoriaMetrics instances.
+-
**[VideoDB Director](https://github.com/video-db/agent-toolkit/tree/main/modelcontextprotocol)** - Create AI-powered video workflows including automatic editing, content moderation, voice cloning, highlight generation, and searchable video moments—all accessible via simple APIs and intuitive chat-based interfaces.
+-
**[VisionAgent MCP](https://github.com/landing-ai/vision-agent-mcp)** - A simple MCP server that enables your LLM to better reason over images, video and documents.
+-
**[Vizro](https://github.com/mckinsey/vizro/tree/main/vizro-mcp)** - Tools and templates to create validated and maintainable data charts and dashboards
+-
**[WaveSpeed](https://github.com/WaveSpeedAI/mcp-server)** - WaveSpeed MCP server providing AI agents with image and video generation capabilities.
+-
**[WayStation](https://github.com/waystation-ai/mcp)** - Universal MCP server to connect to popular productivity tools such as Notion, Monday, AirTable, and many more
+-
**[Webflow](https://github.com/webflow/mcp-server)** - Interact with Webflow sites, pages, and collections
+-
**[WebScraping.AI](https://github.com/webscraping-ai/webscraping-ai-mcp-server)** - Interact with **[WebScraping.AI](https://WebScraping.AI)** for web data extraction and scraping
+-
**[Winston AI](https://github.com/gowinston-ai/winston-ai-mcp-server)** - AI detector MCP server with industry leading accuracy rates in detecting use of AI in text and images. The [Winston AI](https://gowinston.ai) MCP server also offers a robust plagiarism checker to help maintain integrity.
-
**[Xero](https://github.com/XeroAPI/xero-mcp-server)** - Interact with the accounting data in your business using our official MCP server
+-
**[YDB](https://github.com/ydb-platform/ydb-mcp)** - Query [YDB](https://ydb.tech/) databases
+-
**[YepCode](https://github.com/yepcode/mcp-server-js)** - Run code in a secure, scalable sandbox environment with full support for dependencies, secrets, logs, and access to APIs or databases. Powered by [YepCode](https://yepcode.io)
+-
**[YugabyteDB](https://github.com/yugabyte/yugabytedb-mcp-server)** - MCP Server to interact with your [YugabyteDB](https://www.yugabyte.com/) database
+-
**[Yunxin](https://github.com/netease-im/yunxin-mcp-server)** - An MCP server that connects to Yunxin's IM/RTC/DATA Open-API
-
**[Zapier](https://zapier.com/mcp)** - Connect your AI Agents to 8,000 apps instantly.
- **[ZenML](https://github.com/zenml-io/mcp-zenml)** - Interact with your MLOps and LLMOps pipelines through your [ZenML](https://www.zenml.io) MCP server
+-
**[ZIZAI Recruitment](https://github.com/zaiwork/mcp)** - Interact with the next-generation intelligent recruitment platform for employees and employers, powered by [ZIZAI Recruitment](https://zizai.work).
### 🌎 Community Servers
A growing set of community-developed and maintained servers demonstrates various applications of MCP across different domains.
> **Note:** Community servers are **untested** and should be used at **your own risk**. They are not affiliated with or endorsed by Anthropic.
+- **[1Panel](https://github.com/1Panel-dev/mcp-1panel)** - MCP server implementation that provides 1Panel interaction.
+- **[A2A](https://github.com/GongRzhe/A2A-MCP-Server)** - An MCP server that bridges the Model Context Protocol (MCP) with the Agent-to-Agent (A2A) protocol, enabling MCP-compatible AI assistants (like Claude) to seamlessly interact with A2A agents.
- **[Ableton Live](https://github.com/Simon-Kansara/ableton-live-mcp-server)** - an MCP server to control Ableton Live.
- **[Adobe Commerce](https://github.com/rafaelstz/adobe-commerce-dev-mcp)** — MCP to interact with Adobe Commerce GraphQL API, including orders, products, customers, etc.
-- **[Airbnb](https://github.com/openbnb-org/mcp-server-airbnb)** - Provides tools to search Airbnb and get listing details.
+- **[Ableton Live](https://github.com/ahujasid/ableton-mcp)** (by ahujasid) - Ableton integration allowing prompt enabled music creation.
+- **[Actor Critic Thinking](https://github.com/aquarius-wing/actor-critic-thinking-mcp)** - Actor-critic thinking for performance evaluation
+- **[AgentBay](https://github.com/Michael98671/agentbay)** - An MCP server for providing serverless cloud infrastructure for AI agents.
- **[AI Agent Marketplace Index](https://github.com/AI-Agent-Hub/ai-agent-marketplace-index-mcp)** - MCP server to search more than 5000+ AI agents and tools of various categories from [AI Agent Marketplace Index](http://www.deepnlp.org/store/ai-agent) and monitor traffic of AI Agents.
-- **[Algorand](https://github.com/GoPlausible/algorand-mcp)** - A comprehensive MCP server for tooling interactions (40+) and resource accessibility (60+) plus many useful prompts for interacting with the Algorand blockchain.
+- **[AI Tasks](https://github.com/jbrinkman/valkey-ai-tasks)** - Let the AI manage complex plans with integrated task management and tracking tools. Supports STDIO, SSE and Streamable HTTP transports.
+- **[ai-Bible](https://github.com/AdbC99/ai-bible)** - Search the bible reliably and repeatably [ai-Bible Labs](https://ai-bible.com)
+- **[Airbnb](https://github.com/openbnb-org/mcp-server-airbnb)** - Provides tools to search Airbnb and get listing details.
- **[Airflow](https://github.com/yangkyeongmo/mcp-server-apache-airflow)** - A MCP Server that connects to [Apache Airflow](https://airflow.apache.org/) using official python client.
- **[Airtable](https://github.com/domdomegg/airtable-mcp-server)** - Read and write access to [Airtable](https://airtable.com/) databases, with schema inspection.
- **[Airtable](https://github.com/felores/airtable-mcp)** - Airtable Model Context Protocol Server.
-- **[AlphaVantage](https://github.com/calvernaz/alphavantage)** - MCP server for stock market data API [AlphaVantage](https://www.alphavantage.co)
+- **[Algorand](https://github.com/GoPlausible/algorand-mcp)** - A comprehensive MCP server for tooling interactions (40+) and resource accessibility (60+) plus many useful prompts for interacting with the Algorand blockchain.
- **[Amadeus](https://github.com/donghyun-chae/mcp-amadeus)** (by donghyun-chae) - An MCP server to access, explore, and interact with Amadeus Flight Offers Search API for retrieving detailed flight options, including airline, times, duration, and pricing data.
+- **[Amazon Ads](https://github.com/MarketplaceAdPros/amazon-ads-mcp-server)** - MCP Server that provides interaction capabilities with Amazon Advertising through [MarketplaceAdPros](https://marketplaceadpros.com)/
+- **[AniList](https://github.com/yuna0x0/anilist-mcp)** (by yuna0x0) - An MCP server to interact with AniList API, allowing you to search for anime and manga, retrieve user data, and manage your watchlist.
- **[Anki](https://github.com/scorzeth/anki-mcp-server)** - An MCP server for interacting with your [Anki](https://apps.ankiweb.net) decks and cards.
+- **[AntV Chart](https://github.com/antvis/mcp-server-chart)** - A Model Context Protocol server for generating 15+ visual charts using [AntV](https://github.com/antvis).
- **[Any Chat Completions](https://github.com/pyroprompts/any-chat-completions-mcp)** - Interact with any OpenAI SDK Compatible Chat Completions API like OpenAI, Perplexity, Groq, xAI and many more.
+- **[Apache Gravitino(incubating)](https://github.com/datastrato/mcp-server-gravitino)** - Allow LLMs to explore metadata of structured data and unstructured data with Gravitino, and perform data governance tasks including tagging/classification.
+- **[APIWeaver](https://github.com/GongRzhe/APIWeaver)** - An MCP server that dynamically creates MCP servers from web API configurations. This allows you to easily integrate any REST API, GraphQL endpoint, or web service into an MCP-compatible tool that can be used by AI assistants like Claude.
+- **[Apple Books](https://github.com/vgnshiyer/apple-books-mcp)** - Interact with your library on Apple Books, manage your book collection, summarize highlights, notes, and much more.
- **[Apple Calendar](https://github.com/Omar-v2/mcp-ical)** - An MCP server that allows you to interact with your MacOS Calendar through natural language, including features such as event creation, modification, schedule listing, finding free time slots etc.
+- **[Apple Docs](https://github.com/kimsungwhee/apple-docs-mcp)** - A powerful Model Context Protocol (MCP) server that provides seamless access to Apple Developer Documentation through natural language queries. Search, explore, and get detailed information about Apple frameworks, APIs, sample code, and more directly in your AI-powered development environment.
+- **[Apple Script](https://github.com/peakmojo/applescript-mcp)** - MCP server that lets LLM run AppleScript code to to fully control anything on Mac, no setup needed.
+- **[APT MCP](https://github.com/GdMacmillan/apt-mcp-server)** - MCP server which runs debian package manager (apt) commands for you using ai agents.
+- **[Aranet4](https://github.com/diegobit/aranet4-mcp-server)** - MCP Server to manage your Aranet4 CO2 sensor. Fetch data and store in a local SQLite. Ask questions about historical data.
- **[ArangoDB](https://github.com/ravenwits/mcp-server-arangodb)** - MCP Server that provides database interaction capabilities through [ArangoDB](https://arangodb.com/).
- **[Arduino](https://github.com/vishalmysore/choturobo)** - MCP Server that enables AI-powered robotics using Claude AI and Arduino (ESP32) for real-world automation and interaction with robots.
+- **[arXiv API](https://github.com/prashalruchiranga/arxiv-mcp-server)** - An MCP server that enables interacting with the arXiv API using natural language.
+- **[arxiv-latex-mcp](https://github.com/takashiishida/arxiv-latex-mcp)** - MCP server that fetches and processes arXiv LaTeX sources for precise interpretation of mathematical expressions in papers.
- **[Atlassian](https://github.com/sooperset/mcp-atlassian)** - Interact with Atlassian Cloud products (Confluence and Jira) including searching/reading Confluence spaces/pages, accessing Jira issues, and project metadata.
-- **[Attestable MCP](https://github.com/co-browser/attestable-mcp-server)** - An MCP server running inside a trusted execution environment (TEE) via Gramine, showcasing remote attestation using [RA-TLS](https://gramine.readthedocs.io/en/stable/attestation.html). This allows an MCP client to verify the server before conencting.
+- **[Atlassian Server (by phuc-nt)](https://github.com/phuc-nt/mcp-atlassian-server)** - An MCP server that connects AI agents (Cline, Claude Desktop, Cursor, etc.) to Atlassian Jira & Confluence, enabling data queries and actions through the Model Context Protocol.
+- **[Attestable MCP](https://github.com/co-browser/attestable-mcp-server)** - An MCP server running inside a trusted execution environment (TEE) via Gramine, showcasing remote attestation using [RA-TLS](https://gramine.readthedocs.io/en/stable/attestation.html). This allows an MCP client to verify the server before connecting.
+- **[Audius](https://github.com/glassBead-tc/audius-mcp-atris)** - Audius + AI = Atris. Interact with fans, stream music, tip your favorite artists, and more on Audius: all through Claude.
+- **[AutoML](https://github.com/emircansoftware/MCP_Server_DataScience)** – An MCP server for data analysis workflows including reading, preprocessing, feature engineering, model selection, visualization, and hyperparameter tuning.
- **[AWS](https://github.com/rishikavikondala/mcp-server-aws)** - Perform operations on your AWS resources using an LLM.
- **[AWS Athena](https://github.com/lishenxydlgzs/aws-athena-mcp)** - A MCP server for AWS Athena to run SQL queries on Glue Catalog.
+- **[AWS Cognito](https://github.com/gitCarrot/mcp-server-aws-cognito)** - A MCP server that connects to AWS Cognito for authentication and user management.
- **[AWS Cost Explorer](https://github.com/aarora79/aws-cost-explorer-mcp-server)** - Optimize your AWS spend (including Amazon Bedrock spend) with this MCP server by examining spend across regions, services, instance types and foundation models ([demo video](https://www.youtube.com/watch?v=WuVOmYLRFmI&feature=youtu.be)).
- **[AWS Resources Operations](https://github.com/baryhuang/mcp-server-aws-resources-python)** - Run generated python code to securely query or modify any AWS resources supported by boto3.
- **[AWS S3](https://github.com/aws-samples/sample-mcp-server-s3)** - A sample MCP server for AWS S3 that flexibly fetches objects from S3 such as PDF documents.
+- **[AWS SES](https://github.com/aws-samples/sample-for-amazon-ses-mcp)** Sample MCP Server for Amazon SES (SESv2). See [AWS blog post](https://aws.amazon.com/blogs/messaging - and-targeting/use-ai-agents-and-the-model-context-protocol-with-amazon-ses/) for more details.
- **[Azure ADX](https://github.com/pab1it0/adx-mcp-server)** - Query and analyze Azure Data Explorer databases.
- **[Azure DevOps](https://github.com/Vortiago/mcp-azure-devops)** - An MCP server that provides a bridge to Azure DevOps services, enabling AI assistants to query and manage work items.
+- **[Azure MCP Hub](https://github.com/Azure-Samples/mcp)** - A curated list of all MCP servers and related resources for Azure developers by **[Arun Sekhar](https://github.com/achandmsft)**
+- **[Azure OpenAI DALL-E 3 MCP Server](https://github.com/jacwu/mcp-server-aoai-dalle3)** - A MCP server for Azure OpenAI DALL-E 3 service to generate image from text.
+- **[Azure Wiki Search](https://github.com/coder-linping/azure-wiki-search-server)** - An MCP that enables AI to query the wiki hosted on Azure Devops Wiki.
- **[Baidu AI Search](https://github.com/baidubce/app-builder/tree/master/python/mcp_server/ai_search)** - Web search with Baidu Cloud's AI Search
+- **[BambooHR MCP](https://github.com/encoreshao/bamboohr-mcp)** - An MCP server that interfaces with the BambooHR APIs, providing access to employee data, time tracking, and HR management features.
- **[Base Free USDC Transfer](https://github.com/magnetai/mcp-free-usdc-transfer)** - Send USDC on [Base](https://base.org) for free using Claude AI! Built with [Coinbase CDP](https://docs.cdp.coinbase.com/mpc-wallet/docs/welcome).
-* **[Basic Memory](https://github.com/basicmachines-co/basic-memory)** - Local-first knowledge management system that builds a semantic graph from Markdown files, enabling persistent memory across conversations with LLMs.
+- **[Basic Memory](https://github.com/basicmachines-co/basic-memory)** - Local-first knowledge management system that builds a semantic graph from Markdown files, enabling persistent memory across conversations with LLMs.
+- **[BGG MCP](https://github.com/kkjdaniel/bgg-mcp)** (by kkjdaniel) - MCP to enable interaction with the BoardGameGeek API via AI tooling.
- **[BigQuery](https://github.com/LucasHild/mcp-server-bigquery)** (by LucasHild) - This server enables LLMs to inspect database schemas and execute queries on BigQuery.
- **[BigQuery](https://github.com/ergut/mcp-bigquery-server)** (by ergut) - Server implementation for Google BigQuery integration that enables direct BigQuery database access and querying capabilities
+- **[Bilibili](https://github.com/wangshunnn/bilibili-mcp-server)** - This MCP server provides tools to fetch Bilibili user profiles, video metadata, search videos, and more.
+- **[Binance](https://github.com/ethancod1ng/binance-mcp-server)** - Cryptocurrency trading and market data access through Binance API integration.
- **[Bing Web Search API](https://github.com/leehanchung/bing-search-mcp)** (by hanchunglee) - Server implementation for Microsoft Bing Web Search API.
+- **[BioMCP](https://github.com/genomoncology/biomcp)** (by imaurer) - Biomedical research assistant server providing access to PubMed, ClinicalTrials.gov, and MyVariant.info.
+- **[bioRxiv](https://github.com/JackKuo666/bioRxiv-MCP-Server)** - 🔍 Enable AI assistants to search and access bioRxiv papers through a simple MCP interface.
- **[Bitable MCP](https://github.com/lloydzhou/bitable-mcp)** (by lloydzhou) - MCP server provides access to Lark Bitable through the Model Context Protocol. It allows users to interact with Bitable tables using predefined tools.
- **[Blender](https://github.com/ahujasid/blender-mcp)** (by ahujasid) - Blender integration allowing prompt enabled 3D scene creation, modeling and manipulation.
+- **[Blockchain MCP](https://github.com/tatumio/blockchain-mcp)** - MCP Server for Blockchain Data from **[Tatum](http://tatum.io/mcp)** that instantly unlocks blockchain access for your AI agents. This official Tatum MCP server connects to any LLM in seconds.
+- **[Bluesky](https://github.com/semioz/bluesky-mcp)** (by semioz) - An MCP server for Bluesky, a decentralized social network. It enables automated interactions with the AT Protocol, supporting features like posting, liking, reposting, timeline management, and profile operations.
+- **[Bluetooth MCP Server](https://github.com/Hypijump31/bluetooth-mcp-server)** - Control Bluetooth devices and manage connections through natural language commands, including device discovery, pairing, and audio controls.
+- **[BNBChain MCP](https://github.com/bnb-chain/bnbchain-mcp)** - An MCP server for interacting with BSC, opBNB, and the Greenfield blockchain.
+- **[Braintree](https://github.com/QuentinCody/braintree-mcp-server)** - Unofficial PayPal Braintree payment gateway MCP Server for AI agents to process payments, manage customers, and handle transactions securely.
+- **[Brazilian Law](https://github.com/pdmtt/brlaw_mcp_server/)** (by pdmtt) - Agent-driven research on Brazilian law using official sources.
+- **[BreakoutRoom](https://github.com/agree-able/room-mcp)** - Agents accomplishing goals together in p2p rooms
- **[browser-use](https://github.com/co-browser/browser-use-mcp-server)** (by co-browser) - browser-use MCP server with dockerized playwright + chromium + vnc. supports stdio & resumable http.
+- **[Browser MCP](https://github.com/bytedance/UI-TARS-desktop/tree/main/packages/agent-infra/mcp-servers/browser)** (by UI-TARS) - A fast, lightweight MCP server that empowers LLMs with browser automation via Puppeteer’s structured accessibility data, featuring optional vision mode for complex visual understanding and flexible, cross-platform configuration.
+- **[BrowserLoop](https://github.com/mattiasw/browserloop)** - An MCP server for taking screenshots of web pages using Playwright. Supports high-quality capture with configurable formats, viewport sizes, cookie-based authentication, and both full page and element-specific screenshots.
- **[Bsc-mcp](https://github.com/TermiX-official/bsc-mcp)** The first MCP server that serves as the bridge between AI and BNB Chain, enabling AI agents to execute complex on-chain operations through seamless integration with the BNB Chain, including transfer, swap, launch, security check on any token and even more.
+- **[BVG MCP Server - (Unofficial) ](https://github.com/svkaizoku/mcp-bvg)** - Unofficial MCP server for Berliner Verkehrsbetriebe Api.
+- **[CAD-MCP](https://github.com/daobataotie/CAD-MCP#)** (by daobataotie) - Drawing CAD(Line,Circle,Text,Annotation...) through MCP server, supporting mainstream CAD software.
- **[Calculator](https://github.com/githejie/mcp-server-calculator)** - This server enables LLMs to use calculator for precise numerical calculations.
+- **[CalDAV MCP](https://github.com/dominik1001/caldav-mcp)** - A CalDAV MCP server to expose calendar operations as tools for AI assistants.
+- **[Catalysis Hub](https://github.com/QuentinCody/catalysishub-mcp-server)** - Unofficial MCP server for searching and retrieving scientific data from the Catalysis Hub database, providing access to computational catalysis research and surface reaction data.
+- **[CCTV VMS MCP](https://github.com/jyjune/mcp_vms)** - A Model Context Protocol (MCP) server designed to connect to a CCTV recording program (VMS) to retrieve recorded and live video streams. It also provides tools to control the VMS software, such as showing live or playback dialogs for specific channels at specified times.
- **[CFBD API](https://github.com/lenwood/cfbd-mcp-server)** - An MCP server for the [College Football Data API](https://collegefootballdata.com/).
- **[ChatMCP](https://github.com/AI-QL/chat-mcp)** – An Open Source Cross-platform GUI Desktop application compatible with Linux, macOS, and Windows, enabling seamless interaction with MCP servers across dynamically selectable LLMs, by **[AIQL](https://github.com/AI-QL)**
- **[ChatSum](https://github.com/mcpso/mcp-server-chatsum)** - Query and Summarize chat messages with LLM. by [mcpso](https://mcp.so)
- **[Chess.com](https://github.com/pab1it0/chess-mcp)** - Access Chess.com player data, game records, and other public information through standardized MCP interfaces, allowing AI assistants to search and analyze chess information.
+- **[ChessPal Chess Engine (stockfish)](https://github.com/wilson-urdaneta/chesspal-mcp-engine)** - A Stockfish-powered chess engine exposed as an MCP server. Calculates best moves and supports both HTTP/SSE and stdio transports.
- **[Chroma](https://github.com/privetin/chroma)** - Vector database server for semantic document search and metadata filtering, built on Chroma
+- **[CipherTrust Manager](https://github.com/sanyambassi/ciphertrust-manager-mcp-server)** - MCP server for Thales CipherTrust Manager integration, enabling secure key management and cryptographic operations.
+- **[Claude Thread Continuity](https://github.com/peless/claude-thread-continuity)** - Persistent memory system enabling Claude Desktop conversations to resume with full context across sessions. Maintains conversation history, project states, and user preferences for seamless multi-session workflows.
- **[ClaudePost](https://github.com/ZilongXue/claude-post)** - ClaudePost enables seamless email management for Gmail, offering secure features like email search, reading, and sending.
+- **[CLDGeminiPDF Analyzer](https://github.com/tfll37/CLDGeminiPDF-Analyzer)** - MCP server tool enabling sharing large PDF files to Google LLMs via API for further/additional analysis and response retrieval to Claude Desktop.
+- **[ClearML MCP](https://github.com/prassanna-ravishankar/clearml-mcp)** - Get comprehensive ML experiment context and analysis directly from [ClearML](https://clear.ml) in your AI conversations.
+- **[ClickUp](https://github.com/TaazKareem/clickup-mcp-server)** - MCP server for ClickUp task management, supporting task creation, updates, bulk operations, and markdown descriptions.
- **[Cloudinary](https://github.com/felores/cloudinary-mcp-server)** - Cloudinary Model Context Protocol Server to upload media to Cloudinary and get back the media link and details.
+- **[CockroachDB](https://github.com/amineelkouhen/mcp-cockroachdb)** - MCP server enabling AI agents and LLMs to manage, monitor, and query **[CockroachDB](https://www.cockroachlabs.com/)** using natural language.
+- **[CockroachDB MCP Server](https://github.com/viragtripathi/cockroachdb-mcp-server)** – Full - featured MCP implementation built with FastAPI and CockroachDB. Supports schema bootstrapping, JSONB storage, LLM-ready CLI, and optional `/debug` endpoints.
- **[code-assistant](https://github.com/stippi/code-assistant)** - A coding assistant MCP server that allows to explore a code-base and make changes to code. Should be used with trusted repos only (insufficient protection against prompt injections).
+- **[code-context-provider-mcp](https://github.com/AB498/code-context-provider-mcp)** - MCP server that provides code context and analysis for AI assistants. Extracts directory structure and code symbols using WebAssembly Tree-sitter parsers without Native Dependencies.
- **[code-executor](https://github.com/bazinga012/mcp_code_executor)** - An MCP server that allows LLMs to execute Python code within a specified Conda environment.
- **[code-sandbox-mcp](https://github.com/Automata-Labs-team/code-sandbox-mcp)** - An MCP server to create secure code sandbox environment for executing code within Docker containers.
- **[cognee-mcp](https://github.com/topoteretes/cognee/tree/main/cognee-mcp)** - GraphRAG memory server with customizable ingestion, data processing and search
- **[coin_api_mcp](https://github.com/longmans/coin_api_mcp)** - Provides access to [coinmarketcap](https://coinmarketcap.com/) cryptocurrency data.
+- **[CoinMarketCap](https://github.com/shinzo-labs/coinmarketcap-mcp)** - Implements the complete [CoinMarketCap](https://coinmarketcap.com/) API for accessing cryptocurrency market data, exchange information, and other blockchain-related metrics.
+- **[commands](https://github.com/g0t4/mcp-server-commands)** - Run commands and scripts. Just like in a terminal.
+- **[computer-control-mcp](https://github.com/AB498/computer-control-mcp)** - MCP server that provides computer control capabilities, like mouse, keyboard, OCR, etc. using PyAutoGUI, RapidOCR, ONNXRuntime Without External Dependencies.
+- **[Computer-Use - Remote MacOS Use](https://github.com/baryhuang/mcp-remote-macos-use)** - Open-source out-of-the-box alternative to OpenAI Operator, providing a full desktop experience and optimized for using remote macOS machines as autonomous AI agents.
+- **[Congress.gov API](https://github.com/AshwinSundar/congress_gov_mcp)** - An MCP server to interact with real-time data from the Congress.gov API, which is the official API for the United States Congress.
+- **[consul-mcp](https://github.com/kocierik/consul-mcp-server)** - A consul MCP server for service management, health check and Key-Value Store
+- **[consult7](https://github.com/szeider/consult7)** - Analyze large codebases and document collections using high-context models via OpenRouter, OpenAI, or Google AI -- very useful, e.g., with Claude Code
- **[Contentful-mcp](https://github.com/ivo-toby/contentful-mcp)** - Read, update, delete, publish content in your [Contentful](https://contentful.com) space(s) from this MCP Server.
+- **[context-portal](https://github.com/GreatScottyMac/context-portal)** - Context Portal (ConPort) is a memory bank database system that effectively builds a project-specific knowledge graph, capturing entities like decisions, progress, and architecture, along with their relationships. This serves as a powerful backend for Retrieval Augmented Generation (RAG), enabling AI assistants to access precise, up-to-date project information.
+- **[CreateveAI Nexus](https://github.com/spgoodman/createveai-nexus-server)** - Open-Source Bridge Between AI Agents and Enterprise Systems, with simple custom API plug-in capabilities (including close compatibility with ComfyUI nodes), support for Copilot Studio's MCP agent integations, and support for Azure deployment in secure environments with secrets stored in Azure Key Vault, as well as straightforward on-premises deployment.
+- **[Creatify](https://github.com/TSavo/creatify-mcp)** - MCP Server that exposes Creatify AI API capabilities for AI video generation, including avatar videos, URL-to-video conversion, text-to-speech, and AI-powered editing tools.
+- **[Cronlytic](https://github.com/Cronlytic/cronlytic-mcp-server)** - Create CRUD operations for serverless cron jobs through [Cronlytic](https://cronlytic.com) MCP Server
- **[crypto-feargreed-mcp](https://github.com/kukapay/crypto-feargreed-mcp)** - Providing real-time and historical Crypto Fear & Greed Index data.
+- **[crypto-indicators-mcp](https://github.com/kukapay/crypto-indicators-mcp)** - An MCP server providing a range of cryptocurrency technical analysis indicators and strategies.
+- **[crypto-sentiment-mcp](https://github.com/kukapay/crypto-sentiment-mcp)** - An MCP server that delivers cryptocurrency sentiment analysis to AI agents.
- **[cryptopanic-mcp-server](https://github.com/kukapay/cryptopanic-mcp-server)** - Providing latest cryptocurrency news to AI agents, powered by CryptoPanic.
+- **[Cursor MCP Installer](https://github.com/matthewdcage/cursor-mcp-installer)** - A tool to easily install and configure other MCP servers within Cursor IDE, with support for npm packages, local directories, and Git repositories.
- **[Dappier](https://github.com/DappierAI/dappier-mcp)** - Connect LLMs to real-time, rights-cleared, proprietary data from trusted sources. Access specialized models for Real-Time Web Search, News, Sports, Financial Data, Crypto, and premium publisher content. Explore data models at [marketplace.dappier.com](https://marketplace.dappier.com/marketplace).
-- **[Databricks](https://github.com/JordiNeil/mcp-databricks-server)** - Allows LLMs to run SQL queries, list and get details of jobs executions in a Databricks account.
-- **[Datadog](https://github.com/GeLi2001/datadog-mcp-server)** - Datadog MCP Server for application tracing, monitoring, dashboard, incidents queries built on official datadog api.
- **[Data Exploration](https://github.com/reading-plus-ai/mcp-server-data-exploration)** - MCP server for autonomous data exploration on .csv-based datasets, providing intelligent insights with minimal effort. NOTE: Will execute arbitrary Python code on your machine, please use with caution!
+- **[Databricks](https://github.com/JordiNeil/mcp-databricks-server)** - Allows LLMs to run SQL queries, list and get details of jobs executions in a Databricks account.
+- **[Databricks Genie](https://github.com/yashshingvi/databricks-genie-MCP)** - A server that connects to the Databricks Genie, allowing LLMs to ask natural language questions, run SQL queries, and interact with Databricks conversational agents.
+- **[Databricks Smart SQL](https://github.com/RafaelCartenet/mcp-databricks-server)** - Leveraging Databricks Unity Catalog metadata, perform smart efficient SQL queries to solve Ad-hoc queries and explore data.
+- **[Datadog](https://github.com/GeLi2001/datadog-mcp-server)** - Datadog MCP Server for application tracing, monitoring, dashboard, incidents queries built on official datadog api.
- **[Dataset Viewer](https://github.com/privetin/dataset-viewer)** - Browse and analyze Hugging Face datasets with features like search, filtering, statistics, and data export
-- **[DBHub](https://github.com/bytebase/dbhub/)** - Universal database MCP server connecting to MySQL, PostgreSQL, SQLite, DuckDB and etc.
+- **[DaVinci Resolve](https://github.com/samuelgursky/davinci-resolve-mcp)** - MCP server integration for DaVinci Resolve providing powerful tools for video editing, color grading, media management, and project control.
+- **[DBHub](https://github.com/bytebase/dbhub/)** - Universal database MCP server connecting to MySQL, MariaDB, PostgreSQL, and SQL Server.
+- **[Deebo](https://github.com/snagasuri/deebo-prototype)** – Agentic debugging MCP server that helps AI coding agents delegate and fix hard bugs through isolated multi-agent hypothesis testing.
+- **[Deep Research](https://github.com/reading-plus-ai/mcp-server-deep-research)** - Lightweight MCP server offering Grok/OpenAI/Gemini/Perplexity-style automated deep research exploration and structured reporting.
- **[DeepSeek MCP Server](https://github.com/DMontgomery40/deepseek-mcp-server)** - Model Context Protocol server integrating DeepSeek's advanced language models, in addition to [other useful API endpoints](https://github.com/DMontgomery40/deepseek-mcp-server?tab=readme-ov-file#features)
-- **[Deepseek_R1](https://github.com/66julienmartin/MCP-server-Deepseek_R1)** - A Model Context Protocol (MCP) server implementation connecting Claude Desktop with DeepSeek's language models (R1/V3)
- **[deepseek-thinker-mcp](https://github.com/ruixingshi/deepseek-thinker-mcp)** - A MCP (Model Context Protocol) provider Deepseek reasoning content to MCP-enabled AI Clients, like Claude Desktop. Supports access to Deepseek's thought processes from the Deepseek API service or from a local Ollama server.
+- **[Deepseek_R1](https://github.com/66julienmartin/MCP-server-Deepseek_R1)** - A Model Context Protocol (MCP) server implementation connecting Claude Desktop with DeepSeek's language models (R1/V3)
- **[Descope](https://github.com/descope-sample-apps/descope-mcp-server)** - An MCP server to integrate with [Descope](https://descope.com) to search audit logs, manage users, and more.
-- **[DevRev](https://github.com/kpsunil97/devrev-mcp-server)** - An MCP server to integrate with DevRev APIs to search through your DevRev Knowledge Graph where objects can be imported from diff. sources listed [here](https://devrev.ai/docs/import#available-sources).
+- **[DesktopCommander](https://github.com/wonderwhy-er/DesktopCommanderMCP)** - Let AI edit and manage files on your computer, run terminal commands, and connect to remote servers via SSH - all powered by one of the most popular local MCP servers.
+- **[DevDb](https://github.com/damms005/devdb-vscode?tab=readme-ov-file#mcp-configuration)** - An MCP server that runs right inside the IDE, for connecting to MySQL, Postgres, SQLite, and MSSQL databases.
- **[Dicom](https://github.com/ChristianHinge/dicom-mcp)** - An MCP server to query and retrieve medical images and for parsing and reading dicom-encapsulated documents (pdf etc.).
- **[Dify](https://github.com/YanxingLiu/dify-mcp-server)** - A simple implementation of an MCP server for dify workflows.
+- **[Discogs](https://github.com/cswkim/discogs-mcp-server)** - A MCP server that connects to the Discogs API for interacting with your music collection.
- **[Discord](https://github.com/v-3/discordmcp)** - A MCP server to connect to Discord guilds through a bot and read and write messages in channels
- **[Discord](https://github.com/SaseQ/discord-mcp)** - A MCP server, which connects to Discord through a bot, and provides comprehensive integration with Discord.
+- **[Discord](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/discord)** - For Discord API integration by Klavis AI
- **[Discourse](https://github.com/AshDevFr/discourse-mcp-server)** - A MCP server to search Discourse posts on a Discourse forum.
- **[Docker](https://github.com/ckreiling/mcp-server-docker)** - Integrate with Docker to manage containers, images, volumes, and networks.
+- **[Docs](https://github.com/da1z/docsmcp)** - Enable documentation access for the AI agent, supporting llms.txt and other remote or local files.
+- **[Docy](https://github.com/oborchers/mcp-server-docy)** - Docy gives your AI direct access to the technical documentation it needs, right when it needs it. No more outdated information, broken links, or rate limits - just accurate, real-time documentation access for more precise coding assistance.
+- **[Dodo Payments](https://github.com/dodopayments/dodopayments-node/tree/main/packages/mcp-server)** - Enables AI agents to securely perform payment operations via a lightweight, serverless-compatible interface to the [Dodo Payments](https://dodopayments.com) API.
+- **[Domain Tools](https://github.com/deshabhishek007/domain-tools-mcp-server)** - A Model Context Protocol (MCP) server for comprehensive domain analysis: WHOIS, DNS records, and DNS health checks.
+- **[DPLP](https://github.com/szeider/mcp-dblp)** - Searches the [DBLP](https://dblp.org) computer science bibliography database.
+- **[Druid MCP Server](https://github.com/iunera/druid-mcp-server)** - STDIO/SEE MCP Server for Apache Druid by [iunera](https://www.iunera.com) that provides extensive tools, resources, and prompts for managing and analyzing Druid clusters.
- **[Drupal](https://github.com/Omedia/mcp-server-drupal)** - Server for interacting with [Drupal](https://www.drupal.org/project/mcp) using STDIO transport layer.
- **[dune-analytics-mcp](https://github.com/kukapay/dune-analytics-mcp)** - A mcp server that bridges Dune Analytics data to AI agents.
+- **[DynamoDB-Toolbox](https://www.dynamodbtoolbox.com/docs/databases/actions/mcp-toolkit)** - Leverages your Schemas and Access Patterns to interact with your [DynamoDB](https://aws.amazon.com/dynamodb) Database using natural language.
+- **[eBook-mcp](https://github.com/onebirdrocks/ebook-mcp)** - A lightweight MCP server that allows LLMs to read and interact with your personal PDF and EPUB ebooks. Ideal for building AI reading assistants or chat-based ebook interfaces.
- **[EdgeOne Pages MCP](https://github.com/TencentEdgeOne/edgeone-pages-mcp)** - An MCP service for deploying HTML content to EdgeOne Pages and obtaining a publicly accessible URL.
+- **[Edwin](https://github.com/edwin-finance/edwin/tree/main/examples/mcp-server)** - MCP server for edwin SDK - enabling AI agents to interact with DeFi protocols across EVM, Solana and other blockchains.
+- **[eechat](https://github.com/Lucassssss/eechat)** - An open-source, cross-platform desktop application that seamlessly connects with MCP servers, across Linux, macOS, and Windows.
- **[Elasticsearch](https://github.com/cr7258/elasticsearch-mcp-server)** - MCP server implementation that provides Elasticsearch interaction.
- **[ElevenLabs](https://github.com/mamertofabian/elevenlabs-mcp-server)** - A server that integrates with ElevenLabs text-to-speech API capable of generating full voiceovers with multiple voices.
+- **[Email](https://github.com/Shy2593666979/mcp-server-email)** - This server enables users to send emails through various email providers, including Gmail, Outlook, Yahoo, Sina, Sohu, 126, 163, and QQ Mail. It also supports attaching files from specified directories, making it easy to upload attachments along with the email content.
+- **[Email SMTP](https://github.com/egyptianego17/email-mcp-server)** - A simple MCP server that lets your AI agent send emails and attach files through SMTP.
+- **[Enhance Prompt](https://github.com/FelixFoster/mcp-enhance-prompt)** - An MCP service for enhance you prompt.
- **[Ergo Blockchain MCP](https://github.com/marctheshark3/ergo-mcp)** -An MCP server to integrate Ergo Blockchain Node and Explorer APIs for checking address balances, analyzing transactions, viewing transaction history, performing forensic analysis of addresses, searching for tokens, and monitoring network status.
+- **[ESP MCP Server](https://github.com/horw/esp-mcp)** - An MCP server that integrates ESP IDF commands like building and flashing code for ESP Microcontrollers using an LLM.
- **[Eunomia](https://github.com/whataboutyou-ai/eunomia-MCP-server)** - Extension of the Eunomia framework that connects Eunomia instruments with MCP servers
-- **[EVM MCP Server](https://github.com/mcpdotdirect/evm-mcp-server)** - Comprehensive blockchain services for 30+ EVM networks, supporting native tokens, ERC20, NFTs, smart contracts, transactions, and ENS resolution.
- **[Everything Search](https://github.com/mamertofabian/mcp-everything-search)** - Fast file searching capabilities across Windows (using [Everything SDK](https://www.voidtools.com/support/everything/sdk/)), macOS (using mdfind command), and Linux (using locate/plocate command).
+- **[EVM MCP Server](https://github.com/mcpdotdirect/evm-mcp-server)** - Comprehensive blockchain services for 30+ EVM networks, supporting native tokens, ERC20, NFTs, smart contracts, transactions, and ENS resolution.
- **[Excel](https://github.com/haris-musa/excel-mcp-server)** - Excel manipulation including data reading/writing, worksheet management, formatting, charts, and pivot table.
+- **[Excel to JSON MCP by WTSolutions](https://github.com/he-yang/excel-to-json-mcp)** - MCP Server providing a standardized interface for converting (1) Excel or CSV data into JSON format ;(2) Excel(.xlsx) file into Structured JSON.
+- **[Extended Memory](https://github.com/ssmirnovpro/extended-memory-mcp)** - Persistent memory across Claude conversations with multi-project support, automatic importance scoring, and tag-based organization. Production-ready with 400+ tests.
+- **[F1](https://github.com/AbhiJ2706/f1-mcp/tree/main)** - Access to Formula 1 data including race results, driver information, lap times, telemetry, and circuit details.
+- **[Fabric MCP](https://github.com/aci-labs/ms-fabric-mcp)** - Microsoft Fabric MCP server to accelerate working in your Fabric Tenant with the help of your favorite LLM models.
+- **[fabric-mcp-server](https://github.com/adapoet/fabric-mcp-server)** - The fabric-mcp-server is an MCP server that integrates [Fabric](https://github.com/danielmiessler/fabric) patterns with [Cline](https://cline.bot/), exposing them as tools for AI-driven task execution and enhancing Cline's capabilities.
+- **[Facebook Ads](https://github.com/gomarble-ai/facebook-ads-mcp-server)** - MCP server acting as an interface to the Facebook Ads, enabling programmatic access to Facebook Ads data and management features.
+- **[Facebook Ads Library](https://github.com/trypeggy/facebook-ads-library-mcp)** - Get any answer from the Facebook Ads Library, conduct deep research including messaging, creative testing and comparisons in seconds.
- **[Fantasy PL](https://github.com/rishijatia/fantasy-pl-mcp)** - Give your coding agent direct access to up-to date Fantasy Premier League data
- **[fastn.ai – Unified API MCP Server](https://github.com/fastnai/mcp-fastn)** - A remote, dynamic MCP server with a unified API that connects to 1,000+ tools, actions, and workflows, featuring built-in authentication and monitoring.
+- **[FDIC BankFind MCP Server - (Unofficial)](https://github.com/clafollett/fdic-bank-find-mcp-server)** - The is a MCPserver that brings the power of FDIC BankFind APIs straight to your AI tools and workflows. Structured U.S. banking data, delivered with maximum vibes. 😎📊
+- **[Federal Reserve Economic Data (FRED)](https://github.com/stefanoamorelli/fred-mcp-server)** (by Stefano Amorelli) - Community developed MCP server to interact with the Federal Reserve Economic Data.
- **[Fetch](https://github.com/zcaceres/fetch-mcp)** - A server that flexibly fetches HTML, JSON, Markdown, or plaintext.
-- **[Fingertip](https://github.com/fingertip-com/fingertip-mcp)** - MCP server for Fingertip.com to search and create new sites.
+- **[Feyod](https://github.com/jeroenvdmeer/feyod-mcp)** - A server that answers questions about football matches, and specialised in the football club Feyenoord.
+- **[Fibaro HC3](https://github.com/coding-sailor/mcp-server-hc3)** - MCP server for Fibaro Home Center 3 smart home systems.
- **[Figma](https://github.com/GLips/Figma-Context-MCP)** - Give your coding agent direct access to Figma file data, helping it one-shot design implementation.
+- **[Figma](https://github.com/paulvandermeijs/figma-mcp)** - A blazingly fast MCP server to read and export your Figma design files.
- **[Firebase](https://github.com/gannonh/firebase-mcp)** - Server to interact with Firebase services including Firebase Authentication, Firestore, and Firebase Storage.
- **[FireCrawl](https://github.com/vrknetha/mcp-server-firecrawl)** - Advanced web scraping with JavaScript rendering, PDF support, and smart rate limiting
+- **[Fish Audio](https://github.com/da-okazaki/mcp-fish-audio-server)** - Text-to-Speech integration with Fish Audio's API, supporting multiple voices, streaming, and real-time playback
+- **[FitBit MCP Server](https://github.com/NitayRabi/fitbit-mcp)** - An MCP server that connects to FitBit API using a token obtained from OAuth flow.
- **[FlightRadar24](https://github.com/sunsetcoder/flightradar24-mcp-server)** - A Claude Desktop MCP server that helps you track flights in real-time using Flightradar24 data.
+- **[Fluent-MCP](https://github.com/modesty/fluent-mcp)** - MCP server for Fluent (ServiceNow SDK) providing access to ServiceNow SDK CLI, API specifications, code snippets, and more.
+- **[Flyworks Avatar](https://github.com/Flyworks-AI/flyworks-mcp)** - Fast and free zeroshot lipsync MCP server.
+- **[fmp-mcp-server](https://github.com/vipbat/fmp-mcp-server)** - Enable your agent for M&A analysis and investment banking workflows. Access company profiles, financial statements, ratios, and perform sector analysis with the [Financial Modeling Prep APIs]
+- **[FoundationModels](https://github.com/phimage/mcp-foundation-models)** - An MCP server that integrates Apple's [FoundationModels](https://developer.apple.com/documentation/foundationmodels) for text generation.
+- **[Foursquare](https://github.com/foursquare/foursquare-places-mcp)** - Enable your agent to recommend places around the world with the [Foursquare Places API](https://location.foursquare.com/products/places-api/)
+- **[FrankfurterMCP](https://github.com/anirbanbasu/frankfurtermcp)** - MCP server acting as an interface to the [Frankfurter API](https://frankfurter.dev/) for currency exchange data.
+- **[freqtrade-mcp](https://github.com/kukapay/freqtrade-mcp)** - An MCP server that integrates with the Freqtrade cryptocurrency trading bot.
+- **[GDB](https://github.com/pansila/mcp_server_gdb)** - A GDB/MI protocol server based on the MCP protocol, providing remote application debugging capabilities with AI assistants.
+- **[ggRMCP](https://github.com/aalobaidi/ggRMCP)** - A Go gateway that converts gRPC services into MCP-compatible tools, allowing AI models like Claude to directly call your gRPC services.
- **[Ghost](https://github.com/MFYDev/ghost-mcp)** - A Model Context Protocol (MCP) server for interacting with Ghost CMS through LLM interfaces like Claude.
-- **[Github Actions](https://github.com/ko1ynnky/github-actions-mcp-server)** - A Model Context Protocol (MCP) server for interacting with Github Actions.
+- **[Git](https://github.com/geropl/git-mcp-go)** - Allows LLM to interact with a local git repository, incl. optional push support.
+- **[Git Mob](https://github.com/Mubashwer/git-mob-mcp-server)** - MCP server that interfaces with the [git-mob](https://github.com/Mubashwer/git-mob) CLI app for managing co-authors in git commits during pair/mob programming.
+- **[GitHub Actions](https://github.com/ko1ynnky/github-actions-mcp-server)** - A Model Context Protocol (MCP) server for interacting with GitHub Actions.
+- **[GitHub Enterprise MCP](https://github.com/ddukbg/github-enterprise-mcp)** - A Model Context Protocol (MCP) server for interacting with GitHub Enterprise.
+- **[GitHub GraphQL](https://github.com/QuentinCody/github-graphql-mcp-server)** - Unofficial GitHub MCP server that provides access to GitHub's GraphQL API, enabling more powerful and flexible queries for repository data, issues, pull requests, and other GitHub resources.
+- **[GitHub Repos Manager MCP Server](https://github.com/kurdin/github-repos-manager-mcp)** - Token-based GitHub automation management. No Docker, Flexible configuration, 80+ tools with direct API integration.
+- **[GitMCP](https://github.com/idosal/git-mcp)** - gitmcp.io is a generic remote MCP server to connect to ANY GitHub repository or project documentation effortlessly
- **[Glean](https://github.com/longyi1207/glean-mcp-server)** - A server that uses Glean API to search and chat.
+- **[Gmail MCP](https://github.com/gangradeamitesh/mcp-google-email)** - A Gmail service implementation using MCP (Model Context Protocol) that provides functionality for sending, receiving, and managing emails through Gmail's API.
- **[Gmail](https://github.com/GongRzhe/Gmail-MCP-Server)** - A Model Context Protocol (MCP) server for Gmail integration in Claude Desktop with auto authentication support.
+- **[Gmail](https://github.com/Ayush-k-Shukla/gmail-mcp-server)** - A Simple MCP server for Gmail with support for all basic operations with oauth2.0.
- **[Gmail Headless](https://github.com/baryhuang/mcp-headless-gmail)** - Remote hostable MCP server that can get and send Gmail messages without local credential or file system setup.
+- **[Gnuradio](https://github.com/yoelbassin/gnuradioMCP)** - An MCP server for GNU Radio that enables LLMs to autonomously create and modify RF .grc flowcharts.
- **[Goal Story](https://github.com/hichana/goalstory-mcp)** - a Goal Tracker and Visualization Tool for personal and professional development.
- **[GOAT](https://github.com/goat-sdk/goat/tree/main/typescript/examples/by-framework/model-context-protocol)** - Run more than +200 onchain actions on any blockchain including Ethereum, Solana and Base.
- **[Godot](https://github.com/Coding-Solo/godot-mcp)** - A MCP server providing comprehensive Godot engine integration for project editing, debugging, and scene management.
- **[Golang Filesystem Server](https://github.com/mark3labs/mcp-filesystem-server)** - Secure file operations with configurable access controls built with Go!
- **[Goodnews](https://github.com/VectorInstitute/mcp-goodnews)** - A simple MCP server that delivers curated positive and uplifting news stories.
+- **[Google Ads](https://github.com/gomarble-ai/google-ads-mcp-server)** - MCP server acting as an interface to the Google Ads, enabling programmatic access to Facebook Ads data and management features.
+- **[Google Analytics](https://github.com/surendranb/google-analytics-mcp)** - Google Analytics MCP Server to bring data across 200+ dimensions & metrics for LLMs to analyse.
- **[Google Calendar](https://github.com/v-3/google-calendar)** - Integration with Google Calendar to check schedules, find time, and add/delete events
- **[Google Calendar](https://github.com/nspady/google-calendar-mcp)** - Google Calendar MCP Server for managing Google calendar events. Also supports searching for events by attributes like title and location.
- **[Google Custom Search](https://github.com/adenot/mcp-google-search)** - Provides Google Search results via the Google Custom Search API
+- **[Google Sheets](https://github.com/xing5/mcp-google-sheets)** - Access and editing data to your Google Sheets.
+- **[Google Sheets](https://github.com/rohans2/mcp-google-sheets)** - A MCP Server written in TypeScript to access and edit data in your Google Sheets.
- **[Google Tasks](https://github.com/zcaceres/gtasks-mcp)** - Google Tasks API Model Context Protocol Server.
+- **[Google Vertex AI Search](https://github.com/ubie-oss/mcp-vertexai-search)** - Provides Google Vertex AI Search results by grounding a Gemini model with your own private data
+- **[Google Workspace](https://github.com/taylorwilsdon/google_workspace_mcp)** - Comprehensive Google Workspace MCP with full support for Calendar, Drive, Gmail, and Docs using Streamable HTTP or SSE transport.
+- **[Google-Scholar](https://github.com/JackKuo666/Google-Scholar-MCP-Server)** - Enable AI assistants to search and access Google Scholar papers through a simple MCP interface.
+- **[Gralio SaaS Database](https://github.com/tymonTe/gralio-mcp)** - Find and compare SaaS products, including data from G2 reviews, Trustpilot, Crunchbase, Linkedin, pricing, features and more, using [Gralio MCP](https://gralio.ai/mcp) server
+- **[GraphQL](https://github.com/drestrepom/mcp_graphql)** - Comprehensive GraphQL API integration that automatically exposes each GraphQL query as a separate tool.
- **[GraphQL Schema](https://github.com/hannesj/mcp-graphql-schema)** - Allow LLMs to explore large GraphQL schemas without bloating the context.
+- **[HackMD](https://github.com/yuna0x0/hackmd-mcp)** (by yuna0x0) - An MCP server for HackMD, a collaborative markdown editor. It allows users to create, read, and update documents in HackMD using the Model Context Protocol.
+- **[HAProxy](https://github.com/tuannvm/haproxy-mcp-server)** - A Model Context Protocol (MCP) server for HAProxy implemented in Go, leveraging HAProxy Runtime API.
+- **[Hashing MCP Server](https://github.com/kanad13/MCP-Server-for-Hashing)** - MCP Server with cryptographic hashing functions e.g. SHA256, MD5, etc.
- **[HDW LinkedIn](https://github.com/horizondatawave/hdw-mcp-server)** - Access to profile data and management of user account with [HorizonDataWave.ai](https://horizondatawave.ai/).
+- **[HeatPump](https://github.com/jiweiqi/heatpump-mcp-server)** — Residential heat - pump sizing & cost-estimation tools by **HeatPumpHQ**.
+- **[Helm Chart CLI](https://github.com/jeff-nasseri/helm-chart-cli-mcp)** - Helm MCP provides a bridge between AI assistants and the Helm package manager for Kubernetes. It allows AI assistants to interact with Helm through natural language requests, executing commands like installing charts, managing repositories, and more.
- **[Heurist Mesh Agent](https://github.com/heurist-network/heurist-mesh-mcp-server)** - Access specialized web3 AI agents for blockchain analysis, smart contract security, token metrics, and blockchain interactions through the [Heurist Mesh network](https://github.com/heurist-network/heurist-agent-framework/tree/main/mesh).
- **[Holaspirit](https://github.com/syucream/holaspirit-mcp-server)** - Interact with [Holaspirit](https://www.holaspirit.com/).
- **[Home Assistant](https://github.com/tevonsb/homeassistant-mcp)** - Interact with [Home Assistant](https://www.home-assistant.io/) including viewing and controlling lights, switches, sensors, and all other Home Assistant entities.
- **[Home Assistant](https://github.com/voska/hass-mcp)** - Docker-ready MCP server for Home Assistant with entity management, domain summaries, automation support, and guided conversations. Includes pre-built container images for easy installation.
- **[HubSpot](https://github.com/buryhuang/mcp-hubspot)** - HubSpot CRM integration for managing contacts and companies. Create and retrieve CRM data directly through Claude chat.
- **[HuggingFace Spaces](https://github.com/evalstate/mcp-hfspace)** - Server for using HuggingFace Spaces, supporting Open Source Image, Audio, Text Models and more. Claude Desktop mode for easy integration.
+- **[Human-In-the-Loop](https://github.com/GongRzhe/Human-In-the-Loop-MCP-Server)** - A powerful MCP Server that enables AI assistants like Claude to interact with humans through intuitive GUI dialogs. This server bridges the gap between automated AI processes and human decision-making by providing real-time user input tools, choices, confirmations, and feedback mechanisms.
+- **[Human-use](https://github.com/RapidataAI/human-use)** - Instant human feedback through an MCP, have your AI interact with humans around the world. Powered by [Rapidata](https://www.rapidata.ai/)
+- **[Hyperledger Fabric Agent Suite](https://github.com/padmarajkore/hlf-fabric-agent)** - Modular toolkit for managing Fabric test networks and chaincode lifecycle via MCP tools.
- **[Hyperliquid](https://github.com/mektigboy/server-hyperliquid)** - An MCP server implementation that integrates the Hyperliquid SDK for exchange data.
+- **[hyprmcp](https://github.com/stefanoamorelli/hyprmcp)** (by Stefano Amorelli) - Lightweight MCP server for `hyprland`.
+- **[iFlytek SparkAgent Platform](https://github.com/iflytek/ifly-spark-agent-mcp)** - This is a simple example of using MCP Server to invoke the task chain of the iFlytek SparkAgent Platform.
- **[iFlytek Workflow](https://github.com/iflytek/ifly-workflow-mcp-server)** - Connect to iFlytek Workflow via the MCP server and run your own Agent.
- **[Image Generation](https://github.com/GongRzhe/Image-Generation-MCP-Server)** - This MCP server provides image generation capabilities using the Replicate Flux model.
+- **[ImageSorcery MCP](https://github.com/sunriseapps/imagesorcery-mcp)** - ComputerVision-based 🪄 sorcery of image recognition and editing tools for AI assistants.
+- **[IMAP MCP](https://github.com/dominik1001/imap-mcp)** - 📧 An IMAP Model Context Protocol (MCP) server to expose IMAP operations as tools for AI assistants.
+- **[iMCP](https://github.com/loopwork-ai/iMCP)** - A macOS app that provides an MCP server for your iMessage, Reminders, and other Apple services.
- **[InfluxDB](https://github.com/idoru/influxdb-mcp-server)** - Run queries against InfluxDB OSS API v2.
- **[Inoyu](https://github.com/sergehuber/inoyu-mcp-unomi-server)** - Interact with an Apache Unomi CDP customer data platform to retrieve and update customer profiles
+- **[Instagram DM](https://github.com/trypeggy/instagram_dm_mcp)** - Send DMs on Instagram via your LLM
+- **[interactive-mcp](https://github.com/ttommyth/interactive-mcp)** - Enables interactive LLM workflows by adding local user prompts and chat capabilities directly into the MCP loop.
- **[Intercom](https://github.com/raoulbia-ai/mcp-server-for-intercom)** - An MCP-compliant server for retrieving customer support tickets from Intercom. This tool enables AI assistants like Claude Desktop and Cline to access and analyze your Intercom support tickets.
- **[iOS Simulator](https://github.com/InditexTech/mcp-server-simulator-ios-idb)** - A Model Context Protocol (MCP) server that enables LLMs to interact with iOS simulators (iPhone, iPad, etc.) through natural language commands.
+- **[itemit MCP](https://github.com/umin-ai/itemit-mcp)** - itemit is Asset Tracking MCP that manage the inventory, monitoring and location tracking that powers over +300 organizations.
- **[iTerm MCP](https://github.com/ferrislucas/iterm-mcp)** - Integration with iTerm2 terminal emulator for macOS, enabling LLMs to execute and monitor terminal commands.
-- **[JavaFX](https://github.com/mcpso/mcp-server-javafx)** - Make drawings using a JavaFX canvas
-- **[JDBC](https://github.com/quarkiverse/quarkus-mcp-servers/tree/main/jdbc)** - Connect to any JDBC-compatible database and query, insert, update, delete, and more. Supports MySQL, PostgreSQL, Oracle, SQL Server, sqllite and [more](https://github.com/quarkiverse/quarkus-mcp-servers/tree/main/jdbc#supported-jdbc-variants).
+- **[iTerm MCP Server](https://github.com/rishabkoul/iTerm-MCP-Server)** - A Model Context Protocol (MCP) server implementation for iTerm2 terminal integration. Able to manage multiple iTerm Sessions.
+- **[Java Decompiler](https://github.com/idachev/mcp-javadc)** - Decompile Java bytecode into readable source code from .class files, package names, or JAR archives using CFR decompiler
+- **[JavaFX](https://github.com/quarkiverse/quarkus-mcp-servers/tree/main/jfx)** - Make drawings using a JavaFX canvas
+- **[JDBC](https://github.com/quarkiverse/quarkus-mcp-servers/tree/main/jdbc)** - Connect to any JDBC-compatible database and query, insert, update, delete, and more. Supports MySQL, PostgreSQL, Oracle, SQL Server, SQLite and [more](https://github.com/quarkiverse/quarkus-mcp-servers/tree/main/jdbc#supported-jdbc-variants).
+- **[JMeter](https://github.com/QAInsights/jmeter-mcp-server)** - Run load testing using Apache JMeter via MCP-compliant tools.
+- **[Job Searcher](https://github.com/0xDAEF0F/job-searchoor)** - A FastMCP server that provides tools for retrieving and filtering job listings based on time period, keywords, and remote work preferences.
+- **[jobswithgpt](https://github.com/jobswithgpt/mcp)** - Job search MCP using jobswithgpt which indexes 500K+ public job listings and refreshed continously.
- **[JSON](https://github.com/GongRzhe/JSON-MCP-Server)** - JSON handling and processing server with advanced query capabilities using JSONPath syntax and support for array, string, numeric, and date operations.
-- **[KiCad MCP](https://github.com/lamaalrajih/kicad-mcp)** - MCP server for KiCad on Mac, Windows, and Linux.
+- **[JSON2Video MCP](https://github.com/omergocmen/json2video-mcp-server)** - A Model Context Protocol (MCP) server implementation for programmatically generating videos using the json2video API. This server exposes powerful video generation and status-checking tools for use with LLMs, agents, or any MCP-compatible client.
+- **[jupiter-mcp](https://github.com/kukapay/jupiter-mcp)** - An MCP server for executing token swaps on the Solana blockchain using Jupiter's new Ultra API.
+- **[Jupyter MCP Server](https://github.com/datalayer/jupyter-mcp-server)** – Real-time interaction with Jupyter Notebooks, allowing AI to edit, document and execute code for data analysis, visualization etc. Compatible with any Jupyter deployment (local, JupyterHub, ...).
+- **[Jupyter Notebook](https://github.com/jjsantos01/jupyter-notebook-mcp)** - connects Jupyter Notebook to Claude AI, allowing Claude to directly interact with and control Jupyter Notebooks. This integration enables AI-assisted code execution, data analysis, visualization, and more.
+- **[k8s-multicluster-mcp](https://github.com/razvanmacovei/k8s-multicluster-mcp)** - An MCP server for interact with multiple Kubernetes clusters simultaneously using multiple kubeconfig files.
+- **[Kafka](https://github.com/tuannvm/kafka-mcp-server)** - A Model Context Protocol (MCP) server for Apache Kafka implemented in Go, leveraging [franz-go](https://github.com/twmb/franz-go).
+- **[Kafka Schema Registry MCP](https://github.com/aywengo/kafka-schema-reg-mcp)** \ - A comprehensive MCP server for Kafka Schema Registry with 48 tools, multi-registry support, authentication, and production safety features. Enables AI-powered schema management with enterprise-grade capabilities including schema contexts, migration tools, and comprehensive export capabilities.
+- **[kafka-mcp](https://github.com/shivamxtech/kafka-mcp)** - An MCP Server for Kafka clusters to interact with kafka environment via tools on messages, topics, offsets, partitions for consumer and producers along with seamless integration with MCP clients.
- **[Keycloak MCP](https://github.com/ChristophEnglisch/keycloak-model-context-protocol)** - This MCP server enables natural language interaction with Keycloak for user and realm management including creating, deleting, and listing users and realms.
+- **[Kibana MCP](https://github.com/TocharianOU/mcp-server-kibana.git)** (by TocharianOU) - A community-maintained MCP server implementation that allows any MCP-compatible client to access and manage Kibana instances through natural language or programmatic requests.
- **[Kibela](https://github.com/kiwamizamurai/mcp-kibela-server)** (by kiwamizamurai) - Interact with Kibela API.
+- **[KiCad MCP](https://github.com/lamaalrajih/kicad-mcp)** - MCP server for KiCad on Mac, Windows, and Linux.
+- **[kill-process-mcp](https://github.com/misiektoja/kill-process-mcp)** - List and terminate OS processes via natural language queries
+- **[Kindred Offers & Discounts MCP](https://github.com/kindred-app/mcp-server-kindred-offers)** (by kindred.co) - This MCP server allows you to get live deals and offers/coupons from e-commerce merchant sites all over the world.
- **[kintone](https://github.com/macrat/mcp-server-kintone)** - Manage records and apps in [kintone](https://kintone.com) through LLM tools.
+- **[Kokoro TTS](https://github.com/mberg/kokoro-tts-mcp)** - Use Kokoro text to speech to convert text to MP3s with optional autoupload to S3.
- **[Kong Konnect](https://github.com/Kong/mcp-konnect)** - A Model Context Protocol (MCP) server for interacting with Kong Konnect APIs, allowing AI assistants to query and analyze Kong Gateway configurations, traffic, and analytics.
- **[Kubernetes](https://github.com/Flux159/mcp-server-kubernetes)** - Connect to Kubernetes cluster and manage pods, deployments, and services.
- **[Kubernetes and OpenShift](https://github.com/manusa/kubernetes-mcp-server)** - A powerful Kubernetes MCP server with additional support for OpenShift. Besides providing CRUD operations for any Kubernetes resource, this server provides specialized tools to interact with your cluster.
+- **[KubeSphere](https://github.com/kubesphere/ks-mcp-server)** - The KubeSphere MCP Server is a Model Context Protocol(MCP) server that provides integration with KubeSphere APIs, enabling to get resources from KubeSphere. Divided into four tools modules: Workspace Management, Cluster Management, User and Roles, Extensions Center.
+- **[Kukapay MCP Servers](https://github.com/kukapay/kukapay-mcp-servers)** - A comprehensive suite of Model Context Protocol (MCP) servers dedicated to cryptocurrency, blockchain, and Web3 data aggregation, analysis, and services from Kukapay.
- **[Langflow-DOC-QA-SERVER](https://github.com/GongRzhe/Langflow-DOC-QA-SERVER)** - A Model Context Protocol server for document Q&A powered by Langflow. It demonstrates core MCP concepts by providing a simple interface to query documents through a Langflow backend.
+- **[Language Server](https://github.com/isaacphi/mcp-language-server)** - MCP Language Server helps MCP enabled clients navigate codebases more easily by giving them access to semantic tools like get definition, references, rename, and diagnostics.
+- **[Lark(Feishu)](https://github.com/kone-net/mcp_server_lark)** - A Model Context Protocol(MCP) server for Lark(Feishu) sheet, message, doc and etc.
+- **[Lazy Toggl MCP](https://github.com/movstox/lazy-toggl-mcp)** - Simple unofficial MCP server to track time via Toggl API
+- **[lean-lsp-mcp](https://github.com/oOo0oOo/lean-lsp-mcp)** - Interact with the [Lean theorem prover](https://lean-lang.org/) via the Language Server Protocol.
+- **[libvirt-mcp](https://github.com/MatiasVara/libvirt-mcp)** - Allows LLM to interact with libvirt thus enabling to create, destroy or list the Virtual Machines in a system.
- **[Lightdash](https://github.com/syucream/lightdash-mcp-server)** - Interact with [Lightdash](https://www.lightdash.com/), a BI tool.
+- **[LINE](https://github.com/amornpan/py-mcp-line)** (by amornpan) - Implementation for LINE Bot integration that enables Language Models to read and analyze LINE conversations through a standardized interface. Features asynchronous operation, comprehensive logging, webhook event handling, and support for various message types.
+- **[Linear](https://github.com/tacticlaunch/mcp-linear)** - Interact with Linear project management system.
- **[Linear](https://github.com/jerhadf/linear-mcp-server)** - Allows LLM to interact with Linear's API for project management, including searching, creating, and updating issues.
- **[Linear (Go)](https://github.com/geropl/linear-mcp-go)** - Allows LLM to interact with Linear's API via a single static binary.
-- **[LINE](https://github.com/amornpan/py-mcp-line)** (by amornpan) - Implementation for LINE Bot integration that enables Language Models to read and analyze LINE conversations through a standardized interface. Features asynchronous operation, comprehensive logging, webhook event handling, and support for various message types.
+- **[Linear MCP](https://github.com/anoncam/linear-mcp)** - Full blown implementation of the Linear SDK to support comprehensive Linear management of projects, initiatives, issues, users, teams and states.
- **[LlamaCloud](https://github.com/run-llama/mcp-server-llamacloud)** (by marcusschiesser) - Integrate the data stored in a managed index on [LlamaCloud](https://cloud.llamaindex.ai/)
+- **[lldb-mcp](https://github.com/stass/lldb-mcp)** - A Model Context Protocol server for LLDB that provides LLM-driven debugging.
- **[llm-context](https://github.com/cyberchitta/llm-context.py)** - Provides a repo-packing MCP tool with configurable profiles that specify file inclusion/exclusion patterns and optional prompts.
+- **[Locust](https://github.com/QAInsights/locust-mcp-server)** - Allows running and analyzing Locust tests using MCP compatible clients.
+- **[Loki](https://github.com/scottlepp/loki-mcp)** - Golang based MCP Server to query logs from [Grafana Loki](https://github.com/grafana/loki).
+- **[LottieFiles](https://github.com/junmer/mcp-server-lottiefiles)** - Searching and retrieving Lottie animations from [LottieFiles](https://lottiefiles.com/)
+- **[lsp-mcp](https://github.com/Tritlo/lsp-mcp)** - Interact with Language Servers usint the Language Server Protocol to provide additional context information via hover, code actions and completions.
+- **[Lspace](https://github.com/Lspace-io/lspace-server)** - Turn scattered ChatGPT/Claude/Cursor conversations into persistent, searchable knowledge.
+- **[lucene-mcp-server](https://github.com/VivekKumarNeu/MCP-Lucene-Server)** - spring boot server using Lucene for fast document search and management.
+- **[lucid-mcp-server](https://github.com/smartzan63/lucid-mcp-server)** – An MCP server for Lucidchart and Lucidspark: connect, search, and obtain text representations of your Lucid documents and diagrams via LLM - driven AI Vision analysis. [npm](https://www.npmjs.com/package/lucid-mcp-server)
+- **[LunarCrush Remote MCP](https://github.com/lunarcrush/mcp-server)** - Get the latest social metrics and posts for both current live social context as well as historical metrics in LLM and token optimized outputs. Ideal for automated trading / financial advisory.
- **[mac-messages-mcp](https://github.com/carterlasalle/mac_messages_mcp)** - An MCP server that securely interfaces with your iMessage database via the Model Context Protocol (MCP), allowing LLMs to query and analyze iMessage conversations. It includes robust phone number validation, attachment processing, contact management, group chat handling, and full support for sending and receiving messages.
+- **[Maestro MCP](https://github.com/maestro-org/maestro-mcp)** - An MCP server for interacting with Bitcoin via the Maestro RPC API.
+- **[MalwareBazaar_MCP](https://github.com/mytechnotalent/MalwareBazaar_MCP)** (by Kevin Thomas) - An AI-driven MCP server that autonomously interfaces with MalwareBazaar, delivering real-time threat intel and sample metadata for authorized cybersecurity research workflows.
+- **[man-mcp-server](https://github.com/guyru/man-mcp-server)** - MCP to search and access man pages on the local machine.
- **[MariaDB](https://github.com/abel9851/mcp-server-mariadb)** - MariaDB database integration with configurable access controls in Python.
+- **[Markdown2doc](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/pandoc)** - Convert between various file formats using Pandoc
+- **[Markdownify](https://github.com/zcaceres/mcp-markdownify-server)** - MCP to convert almost anything to Markdown (PPTX, HTML, PDF, Youtube Transcripts and more)
+- **[Markitdown](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/markitdown)** - Convert files to Markdown
+- **[Masquerade](https://github.com/postralai/masquerade)** - Redact sensitive information from your PDF documents before sending them to Claude. Masquerade serves as a privacy firewall for LLMs.
+- **[MasterGo](https://github.com/mastergo-design/mastergo-magic-mcp)** - The server designed to connect MasterGo design tools with AI models. It enables AI models to directly retrieve DSL data from MasterGo design files.
+- **[Matlab-MCP-Tools](https://github.com/neuromechanist/matlab-mcp-tools)** - An MCP to write and execute MATLAB scripts, maintain workspace context between MCP calls, visualize plots, and perform section-by-section analysis of MATLAB code with full access to MATLAB's computational capabilities.
- **[Maton](https://github.com/maton-ai/agent-toolkit/tree/main/modelcontextprotocol)** - Connect to your SaaS tools like HubSpot, Salesforce, and more.
- **[MCP Compass](https://github.com/liuyoshio/mcp-compass)** - Suggest the right MCP server for your needs
- **[MCP Create](https://github.com/tesla0225/mcp-create)** - A dynamic MCP server management service that creates, runs, and manages Model Context Protocol servers on-the-fly.
+- **[MCP Documentation Server](https://github.com/andrea9293/mcp-documentation-server)** - Server that provides local document management and semantic search capabilities. Upload documents, search them with AI embeddings, and integrate seamlessly with MCP clients like Claude Desktop and vs code.
- **[MCP Installer](https://github.com/anaisbetts/mcp-installer)** - This server is a server that installs other MCP servers for you.
+- **[MCP Proxy Server](https://github.com/TBXark/mcp-proxy)** - An MCP proxy server that aggregates and serves multiple MCP resource servers through a single HTTP server.
+- **[MCP Server Creator](https://github.com/GongRzhe/MCP-Server-Creator)** - A powerful Model Context Protocol (MCP) server that creates other MCP servers! This meta-server provides tools for dynamically generating FastMCP server configurations and Python code.
+- **[MCP Server Generator](https://github.com/SerhatUzbas/mcp-server-generator)** - An MCP server that creates and manages MCP servers! Helps both non-technical users and developers build custom JavaScript MCP servers with AI guidance, automatic dependency management, and Claude Desktop integration.
+- **[MCP STDIO to Streamable HTTP Adapter](https://github.com/pyroprompts/mcp-stdio-to-streamable-http-adapter)** - Connect to Streamable HTTP MCP Servers even if the MCP Client only supports STDIO.
+- **[mcp-containerd](https://github.com/jokemanfire/mcp-containerd)** - The containerd MCP implemented by Rust supports the operation of the CRI interface.
+- **[MCP-Database-Server](https://github.com/executeautomation/mcp-database-server)** - Fastest way to interact with your Database such as SQL Server, SQLite and PostgreSQL
+- **[mcp-grep](https://github.com/erniebrodeur/mcp-grep)** - Python-based MCP server that brings grep functionality to LLMs. Supports common grep features including pattern searching, case-insensitive matching, context lines, and recursive directory searches.
- **[mcp-k8s-go](https://github.com/strowk/mcp-k8s-go)** - Golang-based Kubernetes server for MCP to browse pods and their logs, events, namespaces and more. Built to be extensible.
-- **[mcp-local-rag](https://github.com/nkapila6/mcp-local-rag)** - "primitive" RAG-like web search model context protocol (MCP) server that runs locally using Google's MediaPipe Text Embedder and DuckDuckGo Search. ✨ no APIs required ✨.
+- **[mcp-local-rag](https://github.com/nkapila6/mcp-local-rag)** - "primitive" RAG-like web search model context protocol (MCP) server that runs locally using Google's MediaPipe Text Embedder and DuckDuckGo Search.
+- **[mcp-mcp](https://github.com/wojtyniak/mcp-mcp)** - Meta-MCP Server that acts as a tool discovery service for MCP clients.
+- **[mcp-meme-sticky](https://github.com/nkapila6/mcp-meme-sticky)** - Make memes or stickers using MCP server for WhatsApp or Telegram.
+- **[MCP-NixOS](https://github.com/utensils/mcp-nixos)** - A Model Context Protocol server that provides AI assistants with accurate, real-time information about NixOS packages, system options, Home Manager settings, and nix-darwin macOS configurations.
+- **[mcp-open-library](https://github.com/8enSmith/mcp-open-library)** - A Model Context Protocol (MCP) server for the Open Library API that enables AI assistants to search for book and author information.
- **[mcp-proxy](https://github.com/sparfenyuk/mcp-proxy)** - Connect to MCP servers that run on SSE transport, or expose stdio servers as an SSE server.
+- **[mcp-read-website-fast](https://github.com/just-every/mcp-read-website-fast)** - Fast, token-efficient web content extraction that converts websites to clean Markdown. Features Mozilla Readability, smart caching, polite crawling with robots.txt support, and concurrent fetching with minimal dependencies.
+- **[mcp-salesforce](https://github.com/lciesielski/mcp-salesforce-example)** - MCP server with basic demonstration of interactions with your Salesforce instance
+- **[mcp-sanctions](https://github.com/madupay/mcp-sanctions)** - Screen individuals and organizations against global sanctions lists (OFAC, SDN, UN, etc). Query by prompt or document upload.
+- **[mcp-screenshot-website-fast](https://github.com/just-every/mcp-screenshot-website-fast)** - High-quality screenshot capture optimized for Claude Vision API. Automatically tiles full pages into 1072x1072 chunks (1.15 megapixels) with configurable viewports and wait strategies for dynamic content.
+- **[mcp-server-leetcode](https://github.com/doggybee/mcp-server-leetcode)** - Practice and retrieve problems from LeetCode. Automate problem retrieval, solutions, and insights for coding practice and competitions.
+- **[mcp-vision](https://github.com/groundlight/mcp-vision)** - A MCP server exposing HuggingFace computer vision models such as zero-shot object detection as tools, enhancing the vision capabilities of large language or vision-language models.
+- **[mcp-weather](https://github.com/TimLukaHorstmann/mcp-weather)** - Accurate weather forecasts via the AccuWeather API (free tier available).
+- **[mcp-youtube-extract](https://github.com/sinjab/mcp_youtube_extract)** - A Model Context Protocol server for YouTube operations, extracting video information and transcripts with intelligent fallback logic. Features comprehensive logging, error handling, and support for both auto-generated and manual transcripts.
+- **[mcp_weather](https://github.com/isdaniel/mcp_weather_server)** - Get weather information from https://api.open-meteo.com API.
+- **[MCPfinder](https://github.com/mcpfinder/server)** - The AI Agent's "App Store": Discover, install, and monetize AI capabilities — all within the MCP ecosystem.
+- **[MCPIgnore Filesytem](https://github.com/CyberhavenInc/filesystem-mcpignore)** - A Data Security First filesystem MCP server that implements .mcpignore to prevent MCP clients from accessing sensitive data.
+- **[Md2doc](https://github.com/Yorick-Ryu/md2doc-mcp)** - Convert Markdown text to DOCX format using an external conversion service
+- **[MeasureSpace MCP](https://github.com/MeasureSpace/measure-space-mcp-server)** - A free [Model Context Protocol (MCP) Server](https://smithery.ai/server/@MeasureSpace/measure-space-mcp-server) that provides global weather, climate, air quality forecast and geocoding services by [measurespace.io](https://measurespace.io).
+- **[MediaWiki](https://github.com/ProfessionalWiki/MediaWiki-MCP-Server)** - A Model Context Protocol (MCP) Server that interacts with any MediaWiki wiki
+- **[MediaWiki MCP adapter](https://github.com/lucamauri/MediaWiki-MCP-adapter)** - A custom Model Context Protocol adapter for MediaWiki and WikiBase APIs
+- **[medRxiv](https://github.com/JackKuo666/medRxiv-MCP-Server)** - Enable AI assistants to search and access medRxiv papers through a simple MCP interface.
- **[mem0-mcp](https://github.com/mem0ai/mem0-mcp)** - A Model Context Protocol server for Mem0, which helps with managing coding preferences.
- **[Membase](https://github.com/unibaseio/membase-mcp)** - Save and query your agent memory in distributed way by Membase.
-- **[MSSQL](https://github.com/aekanun2020/mcp-server/)** - MSSQL database integration with configurable access controls and schema inspection
-- **[MSSQL](https://github.com/JexinSam/mssql_mcp_server)** (by jexin) - MCP Server for MSSQL database in Python
-- **[MSSQL-Python](https://github.com/amornpan/py-mcp-mssql)** (by amornpan) - A read-only Python implementation for MSSQL database access with enhanced security features, configurable access controls, and schema inspection capabilities. Focuses on safe database interaction through Python ecosystem.
-- **[MSSQL-MCP](https://github.com/daobataotie/mssql-mcp)** (by daobataotie) - MSSQL MCP that refer to the official website's SQLite MCP for modifications to adapt to MSSQL
-- **[Markdownify](https://github.com/zcaceres/mcp-markdownify-server)** - MCP to convert almost anything to Markdown (PPTX, HTML, PDF, Youtube Transcripts and more)
+- **[Meta Ads Remote MCP](https://github.com/pipeboard-co/meta-ads-mcp)** - Remote MCP server to interact with Meta Ads API - access, analyze, and manage Facebook, Instagram, and other Meta platforms advertising campaigns.
+- **[Meme MCP](https://github.com/lidorshimoni/meme-mcp)** - Generate memes via AI using the Imgflip API through the Model Context Protocol.
+- **[memento-mcp](https://github.com/gannonh/memento-mcp)** - Knowledge graph memory system built on Neo4j with semantic search, temporal awareness.
+- **[MetaTrader MCP](https://github.com/ariadng/metatrader-mcp-server)** - Enable AI LLMs to execute trades using MetaTrader 5 platform.
+- **[Metricool MCP](https://github.com/metricool/mcp-metricool)** - A Model Context Protocol server that integrates with Metricool's social media analytics platform to retrieve performance metrics and schedule content across networks like Instagram, Facebook, Twitter, LinkedIn, TikTok and YouTube.
+- **[Microsoft 365](https://github.com/merill/lokka)** - (by Merill) A Model Context Protocol (MCP) server for Microsoft 365. Includes support for all services including Teams, SharePoint, Exchange, OneDrive, Entra, Intune and more. See [Lokka](https://lokka.dev/) for more details.
+- **[Microsoft 365](https://github.com/softeria/ms-365-mcp-server)** - MCP server that connects to Microsoft Office and the whole Microsoft 365 suite using Graph API (including Outlook/mail, files, Excel, calendar)
+- **[Microsoft 365](https://github.com/pnp/cli-microsoft365-mcp-server)** - Single MCP server that allows to manage many different areas of Microsoft 365, for example: Entra ID, OneDrive, OneNote, Outlook, Planner, Power Apps, Power Automate, Power Platform, SharePoint Embedded, SharePoint Online, Teams, Viva Engage, and many more.
+- **[Microsoft 365 Files (SharePoint/OneDrive)](https://github.com/godwin3737/mcp-server-microsoft365-filesearch)** (by godwin3737) - MCP server with tools to search and get file content from Microsoft 365 including Onedrive and SharePoint. Works with Documents (pdf/docx), Presentations, Spreadsheets and Images.
- **[Microsoft Teams](https://github.com/InditexTech/mcp-teams-server)** - MCP server that integrates Microsoft Teams messaging (read, post, mention, list members and threads)
+- **[Mifos X](https://github.com/openMF/mcp-mifosx)** - A MCP server for the Mifos X Open Source Banking useful for managing clients, loans, savings, shares, financial transactions and generating financial reports.
+- **[Mikrotik](https://github.com/jeff-nasseri/mikrotik-mcp)** - Mikrotik MCP server which cover networking operations (IP, DHCP, Firewall, etc)
- **[Mindmap](https://github.com/YuChenSSR/mindmap-mcp-server)** (by YuChenSSR) - A server that generates mindmaps from input containing markdown code.
- **[Minima](https://github.com/dmayboroda/minima)** - MCP server for RAG on local files
- **[Mobile MCP](https://github.com/mobile-next/mobile-mcp)** (by Mobile Next) - MCP server for Mobile(iOS/Android) automation, app scraping and development using physical devices or simulators/emulators.
-- **[MongoDB](https://github.com/kiliczsh/mcp-mongo-server)** - A Model Context Protocol Server for MongoDB.
-- **[MongoDB Lens](https://github.com/furey/mongodb-lens)** - Full Featured MCP Server for MongoDB Databases.
- **[Monday.com](https://github.com/sakce/mcp-server-monday)** - MCP Server to interact with Monday.com boards and items.
+- **[MongoDB](https://github.com/kiliczsh/mcp-mongo-server)** - A Model Context Protocol Server for MongoDB.
+- **[MongoDB & Mongoose](https://github.com/nabid-pf/mongo-mongoose-mcp)** - MongoDB MCP Server with Mongoose Schema and Validation.
+- **[MongoDB Lens](https://github.com/furey/mongodb-lens)** - Full Featured MCP Server for MongoDB Databases.
+- **[Monzo](https://github.com/BfdCampos/monzo-mcp-bfdcampos)** - Access and manage your Monzo bank accounts through natural language, including balance checking, pot management, transaction listing, and transaction annotation across multiple account types (personal, joint, flex).
+- **[Morningstar](https://github.com/Morningstar/morningstar-mcp-server)** - MCP Server to interact with Morningstar Research, Editorial and Datapoints
+- **[MSSQL](https://github.com/aekanun2020/mcp-server/)** - MSSQL database integration with configurable access controls and schema inspection
+- **[MSSQL](https://github.com/JexinSam/mssql_mcp_server)** (by jexin) - MCP Server for MSSQL database in Python
+- **[MSSQL-MCP](https://github.com/daobataotie/mssql-mcp)** (by daobataotie) - MSSQL MCP that refer to the official website's SQLite MCP for modifications to adapt to MSSQL
+- **[MSSQL-MCP-Node](https://github.com/mihai-dulgheru/mssql-mcp-node)** (by mihai - dulgheru) – Node.js MCP server for Microsoft SQL Server featuring auto-detected single / multi-database configs, execute-SQL and schema tools, robust Zod validation, and optional Express endpoints for local testing
+- **[MSSQL-Python](https://github.com/amornpan/py-mcp-mssql)** (by amornpan) - A read-only Python implementation for MSSQL database access with enhanced security features, configurable access controls, and schema inspection capabilities. Focuses on safe database interaction through Python ecosystem.
+- **[Multi-Model Advisor](https://github.com/YuChenSSR/multi-ai-advisor-mcp)** - A Model Context Protocol (MCP) server that orchestrates queries across multiple Ollama models, synthesizing their insights to deliver a comprehensive and multifaceted AI perspective on any given query.
- **[Multicluster-MCP-Sever](https://github.com/yanmxa/multicluster-mcp-server)** - The gateway for GenAI systems to interact with multiple Kubernetes clusters.
- **[MySQL](https://github.com/benborla/mcp-server-mysql)** (by benborla) - MySQL database integration in NodeJS with configurable access controls and schema inspection
- **[MySQL](https://github.com/designcomputer/mysql_mcp_server)** (by DesignComputer) - MySQL database integration in Python with configurable access controls and schema inspection
+- **[MySQL-Server](https://github.com/tonycai/mcp-mysql-server)** (by TonyCai) - MySQL Database Integration using Python script with configurable access controls and schema inspection, usng stdio mode to suitable local deployment, you can run it in docker container.
- **[n8n](https://github.com/leonardsellem/n8n-mcp-server)** - This MCP server provides tools and resources for AI assistants to manage n8n workflows and executions, including listing, creating, updating, and deleting workflows, as well as monitoring their execution status.
+- **[Nacos MCP Router](https://github.com/nacos-group/nacos-mcp-router)** - This MCP(Model Context Protocol) Server provides tools to search, install, proxy other MCP servers.
- **[NASA](https://github.com/ProgramComputer/NASA-MCP-server)** (by ProgramComputer) - Access to a unified gateway of NASA's data sources including but not limited to APOD, NEO, EPIC, GIBS.
-- **[Nasdaq Data Link](https://github.com/stefanoamorelli/nasdaq-data-link-mcp)** (by stefanoamorelli) - An MCP server to access, explore, and interact with Nasdaq Data Link’s extensive and valuable financial and economic datasets.
+- **[NASA Image MCP Server](https://github.com/adithya1012/NASA-MCP-Server/blob/main/README.md)** - MCP server providing access to NASA's visual data APIs including Mars Rover photos, Earth satellite imagery (EPIC/GIBS), and Astronomy picture of the day. Features built-in image analysis tools with automatic format detection, compression, and base64 conversion for LLM integration.
+- **[Nasdaq Data Link](https://github.com/stefanoamorelli/nasdaq-data-link-mcp)** (by stefanoamorelli) - An MCP server to access, explore, and interact with Nasdaq Data Link's extensive and valuable financial and economic datasets.
- **[National Parks](https://github.com/KyrieTangSheng/mcp-server-nationalparks)** - The server provides latest information of park details, alerts, visitor centers, campgrounds, hiking trails, and events for U.S. National Parks.
- **[NAVER](https://github.com/pfldy2850/py-mcp-naver)** (by pfldy2850) - This MCP server provides tools to interact with various Naver services, such as searching blogs, news, books, and more.
-- **[NS Travel Information](https://github.com/r-huijts/ns-mcp-server)** - Access Dutch Railways (NS) real-time train travel information and disruptions through the official NS API.
+- **[Naver](https://github.com/isnow890/naver-search-mcp)** (by isnow890) - MCP server for Naver Search API integration, supporting blog, news, shopping search and DataLab analytics features.
+- **[NBA](https://github.com/Taidgh-Robinson/nba-mcp-server)** - This MCP server provides tools to fetch recent and historical NBA games including basic and advanced statistics.
- **[Neo4j](https://github.com/da-okazaki/mcp-neo4j-server)** - A community built server that interacts with Neo4j Graph Database.
- **[Neovim](https://github.com/bigcodegen/mcp-neovim-server)** - An MCP Server for your Neovim session.
+- **[Netbird](https://github.com/aantti/mcp-netbird)** - List and analyze Netbird network peers, groups, policies, and more.
+- **[NetMind ParsePro](https://github.com/protagolabs/Netmind-Parse-PDF-MCP)** - The PDF Parser AI service, built and customized by the [NetMind](https://www.netmind.ai/) team.
+- **[NocoDB](https://github.com/edwinbernadus/nocodb-mcp-server)** - Read and write access to NocoDB database.
+- **[Node Code Sandbox](https://github.com/alfonsograziano/node-code-sandbox-mcp)** – A Node.js MCP server that spins up isolated Docker - based sandboxes for executing JavaScript snippets with on-the-fly npm dependency installation
+- **[nomad-mcp](https://github.com/kocierik/mcp-nomad)** - A server that provides a set of tools for managing Nomad clusters through the MCP.
- **[Notion](https://github.com/suekou/mcp-notion-server)** (by suekou) - Interact with Notion API.
- **[Notion](https://github.com/v-3/notion-server)** (by v-3) - Notion MCP integration. Search, Read, Update, and Create pages through Claude chat.
+- **[NS Travel Information](https://github.com/r-huijts/ns-mcp-server)** - Access Dutch Railways (NS) real-time train travel information and disruptions through the official NS API.
- **[ntfy-mcp](https://github.com/teddyzxcv/ntfy-mcp)** (by teddyzxcv) - The MCP server that keeps you informed by sending the notification on phone using ntfy
+- **[ntfy-me-mcp](https://github.com/gitmotion/ntfy-me-mcp)** (by gitmotion) - An ntfy MCP server for sending/fetching ntfy notifications to your self-hosted ntfy server from AI Agents 📤 (supports secure token auth & more - use with npx or docker!)
- **[oatpp-mcp](https://github.com/oatpp/oatpp-mcp)** - C++ MCP integration for Oat++. Use [Oat++](https://oatpp.io) to build MCP servers.
- **[Obsidian Markdown Notes](https://github.com/calclavia/mcp-obsidian)** - Read and search through your Obsidian vault or any directory containing Markdown notes
- **[obsidian-mcp](https://github.com/StevenStavrakis/obsidian-mcp)** - (by Steven Stavrakis) An MCP server for Obsidian.md with tools for searching, reading, writing, and organizing notes.
- **[OceanBase](https://github.com/yuanoOo/oceanbase_mcp_server)** - (by yuanoOo) A Model Context Protocol (MCP) server that enables secure interaction with OceanBase databases.
+- **[Octocode](https://github.com/bgauryy/octocode-mcp)** - (by Guy Bary) AI-powered developer assistant that enables advanced code research, analysis and discovery across GitHub and NPM realms in realtime
+- **[Odoo](https://github.com/ivnvxd/mcp-server-odoo)** - Connect AI assistants to Odoo ERP systems for business data access and workflow automation.
+- **[Office-PowerPoint-MCP-Server](https://github.com/GongRzhe/Office-PowerPoint-MCP-Server)** - A Model Context Protocol (MCP) server for creating, reading, and manipulating Microsoft PowerPoint documents.
+- **[Office-Visio-MCP-Server](https://github.com/GongRzhe/Office-Visio-MCP-Server)** - A Model Context Protocol (MCP) server for creating, reading, and manipulating Microsoft Visio documents.
+- **[Office-Word-MCP-Server](https://github.com/GongRzhe/Office-Word-MCP-Server)** - A Model Context Protocol (MCP) server for creating, reading, and manipulating Microsoft Word documents.
- **[Okta](https://github.com/kapilduraphe/okta-mcp-server)** - Interact with Okta API.
+- **[OKX-MCP-Server](https://github.com/memetus/okx-mcp-playground)** - An MCP server provides various blockchain data and market price data via the OKX API. The server enables Claude to perform operations like retrieve assets prices, transaction data, account history data and trade instruction data.
- **[OneNote](https://github.com/rajvirtual/MCP-Servers/tree/master/onenote)** - (by Rajesh Vijay) An MCP server that connects to Microsoft OneNote using the Microsoft Graph API. Reading notebooks, sections, and pages from OneNote,Creating new notebooks, sections, and pages in OneNote.
-- **[OpenAI WebSearch MCP](https://github.com/ConechoAI/openai-websearch-mcp)** - This is a Python-based MCP server that provides OpenAI `web_search` build-in tool.
+- **[Open Strategy Partners Marketing Tools](https://github.com/open-strategy-partners/osp_marketing_tools)** - Content editing codes, value map, and positioning tools for product marketing.
+- **[OpenAI WebSearch MCP](https://github.com/ConechoAI/openai-websearch-mcp)** - This is a Python-based MCP server that provides OpenAI `web_search` built-in tool.
+- **[OpenAlex.org MCP](https://github.com/drAbreu/alex-mcp)** - Professional MCP server providing ML-powered author disambiguation and comprehensive researcher profiles using the OpenAlex database.
- **[OpenAPI](https://github.com/snaggle-ai/openapi-mcp-server)** - Interact with [OpenAPI](https://www.openapis.org/) APIs.
- **[OpenAPI AnyApi](https://github.com/baryhuang/mcp-server-any-openapi)** - Interact with large [OpenAPI](https://www.openapis.org/) docs using built-in semantic search for endpoints. Allows for customizing the MCP server prefix.
- **[OpenAPI Schema](https://github.com/hannesj/mcp-openapi-schema)** - Allow LLMs to explore large [OpenAPI](https://www.openapis.org/) schemas without bloating the context.
+- **[OpenAPI Schema Explorer](https://github.com/kadykov/mcp-openapi-schema-explorer)** - Token-efficient access to local or remote OpenAPI/Swagger specs via MCP Resources.
- **[OpenCTI](https://github.com/Spathodea-Network/opencti-mcp)** - Interact with OpenCTI platform to retrieve threat intelligence data including reports, indicators, malware and threat actors.
+- **[OpenCV](https://github.com/GongRzhe/opencv-mcp-server)** - A MCP server providing OpenCV computer vision capabilities. This allows AI assistants and language models to access powerful computer vision tools.
- **[OpenDota](https://github.com/asusevski/opendota-mcp-server)** - Interact with OpenDota API to retrieve Dota 2 match data, player statistics, and more.
+- **[OpenMetadata](https://github.com/yangkyeongmo/mcp-server-openmetadata)** - MCP Server for OpenMetadata, an open-source metadata management platform.
- **[OpenRPC](https://github.com/shanejonas/openrpc-mpc-server)** - Interact with and discover JSON-RPC APIs via [OpenRPC](https://open-rpc.org).
-- **[Open Strategy Partners Marketing Tools](https://github.com/open-strategy-partners/osp_marketing_tools)** - Content editing codes, value map, and positioning tools for product marketing.
+- **[OpenStack](https://github.com/wangsqly0407/openstack-mcp-server)** - MCP server implementation that provides OpenStack interaction.
+- **[OpenWeather](https://github.com/mschneider82/mcp-openweather)** - Interact with the free openweathermap API to get the current and forecast weather for a location.
+- **[Operative WebEvalAgent](https://github.com/Operative-Sh/web-eval-agent)** (by [Operative.sh](https://www.operative.sh)) - An MCP server to test, debug, and fix web applications autonomously.
+- **[OPNSense MCP](https://github.com/vespo92/OPNSenseMCP)** - MCP Server for OPNSense Firewall Management and API access
+- **[Optimade MCP](https://github.com/dianfengxiaobo/optimade-mcp-server)** - An MCP server conducts real-time material science data queries with the Optimade database (for example, elemental composition, crystal structure).
+- **[Oracle](https://github.com/marcelo-ochoa/servers)** (by marcelo-ochoa) - Oracle Database integration in NodeJS with configurable access controls, query explain, stats and schema inspection
+- **[Oura MCP server](https://github.com/tomekkorbak/oura-mcp-server)** - MCP server for Oura API to retrieve one's sleep data
+- **[Oura Ring](https://github.com/rajvirtual/oura-mcp-server)** (by Rajesh Vijay) - MCP Server to access and analyze your Oura Ring data. It provides a structured way to fetch and understand your health metrics.
+- **[Outline](https://github.com/Vortiago/mcp-outline)** - MCP Server to interact with [Outline](https://www.getoutline.com) knowledge base to search, read, create, and manage documents and their content, access collections, add comments, and manage document backlinks.
+- **[Pacman](https://github.com/oborchers/mcp-server-pacman)** - An MCP server that provides package index querying capabilities. This server is able to search and retrieve information from package repositories like PyPI, npm, crates.io, Docker Hub, and Terraform Registry.
+- **[pancakeswap-poolspy-mcp](https://github.com/kukapay/pancakeswap-poolspy-mcp)** - An MCP server that tracks newly created liquidity pools on Pancake Swap.
- **[Pandoc](https://github.com/vivekVells/mcp-pandoc)** - MCP server for seamless document format conversion using Pandoc, supporting Markdown, HTML, PDF, DOCX (.docx), csv and more.
+- **[Paradex MCP](https://github.com/sv/mcp-paradex-py)** - MCP native server for interacting with Paradex platform, including fully features trading.
+- **[PDF reader MCP](https://github.com/gpetraroli/mcp_pdf_reader)** - MCP server to read and search text in a local PDF file.
+- **[PDF Tools MCP](https://github.com/Sohaib-2/pdf-mcp-server)** - Comprehensive PDF manipulation toolkit (merge, split, encrypt, optimize and much more)
+- **[Peacock for VS Code](https://github.com/johnpapa/peacock-mcp)** - MCP Server for the Peacock extension for VS Code, coloring your world, one Code editor at a time. The main goal of the project is to show how an MCP server can be used to interact with APIs.
+- **[Phone MCP](https://github.com/hao-cyber/phone-mcp)** - 📱 A powerful plugin that lets you control your Android phone. Enables AI agents to perform complex tasks like automatically playing music based on weather or making calls and sending texts.
- **[PIF](https://github.com/hungryrobot1/MCP-PIF)** - A Personal Intelligence Framework (PIF), providing tools for file operations, structured reasoning, and journal-based documentation to support continuity and evolving human-AI collaboration across sessions.
- **[Pinecone](https://github.com/sirmews/mcp-pinecone)** - MCP server for searching and uploading records to Pinecone. Allows for simple RAG features, leveraging Pinecone's Inference API.
+- **[Pinner MCP](https://github.com/safedep/pinner-mcp)** - A MCP server for pinning GitHub Actions and container base images to their immutable SHA hashes to prevent supply chain attacks.
- **[Placid.app](https://github.com/felores/placid-mcp-server)** - Generate image and video creatives using Placid.app templates
+- **[Plane](https://github.com/kelvin6365/plane-mcp-server)** - This MCP Server will help you to manage projects and issues through Plane's API
- **[Playwright](https://github.com/executeautomation/mcp-playwright)** - This MCP Server will help you run browser automation and webscraping using Playwright
+- **[Podbean](https://github.com/amurshak/podbeanMCP)** - MCP server for managing your podcasts, episodes, and analytics through the Podbean API. Allows for updating, adding, deleting podcasts, querying show description, notes, analytics, and more.
+- **[Polarsteps](https://github.com/remuzel/polarsteps-mcp)** - An MCP server to help you review your previous Trips and plan new ones!
+- **[PostgreSQL](https://github.com/ahmedmustahid/postgres-mcp-server)** - A PostgreSQL MCP server offering dual HTTP/Stdio transports for database schema inspection and read-only query execution with session management and Podman(or Docker) support.
- **[Postman](https://github.com/shannonlal/mcp-postman)** - MCP server for running Postman Collections locally via Newman. Allows for simple execution of Postman Server and returns the results of whether the collection passed all the tests.
+- **[Powerdrill](https://github.com/powerdrillai/powerdrill-mcp)** - Interact with Powerdrill datasets, authenticated with [Powerdrill](https://powerdrill.ai) User ID and Project API Key.
+- **[Prefect](https://github.com/allen-munsch/mcp-prefect)** - MCP Server for workflow orchestration and ELT/ETL with Prefect Server, and Prefect Cloud [https://www.prefect.io/] using the `prefect` python client.
- **[Productboard](https://github.com/kenjihikmatullah/productboard-mcp)** - Integrate the Productboard API into agentic workflows via MCP.
- **[Prometheus](https://github.com/pab1it0/prometheus-mcp-server)** - Query and analyze Prometheus - open-source monitoring system.
+- **[PubChem](https://github.com/sssjiang/pubchem_mcp_server)** - extract drug information from pubchem API.
+- **[PubMed](https://github.com/JackKuo666/PubMed-MCP-Server)** - Enable AI assistants to search, access, and analyze PubMed articles through a simple MCP interface.
- **[Pulumi](https://github.com/dogukanakkaya/pulumi-mcp-server)** - MCP Server to Interact with Pulumi API, creates and lists Stacks
+- **[Puppeteer vision](https://github.com/djannot/puppeteer-vision-mcp)** - Use Puppeteer to browse a webpage and return a high quality Markdown. Use AI vision capabilities to handle cookies, captchas, and other interactive elements automatically.
- **[Pushover](https://github.com/ashiknesin/pushover-mcp)** - Send instant notifications to your devices using [Pushover.net](https://pushover.net/)
+- **[py-mcp-qdrant-rag](https://github.com/amornpan/py-mcp-qdrant-rag)** (by amornpan) - A Model Context Protocol server implementation that provides RAG capabilities through Qdrant vector database integration, enabling AI agents to perform semantic search and document retrieval with local or cloud-based embedding generation support across Mac, Linux, and Windows platforms.
+- **[pydantic/pydantic-ai/mcp-run-python](https://github.com/pydantic/pydantic-ai/tree/main/mcp-run-python)** - Run Python code in a secure sandbox via MCP tool calls, powered by Deno and Pyodide
+- **[Python CLI MCP](https://github.com/ofek/pycli-mcp)** - Interact with local Python command line applications.
- **[QGIS](https://github.com/jjsantos01/qgis_mcp)** - connects QGIS to Claude AI through the MCP. This integration enables prompt-assisted project creation, layer loading, code execution, and more.
+- **[Qiniu MCP Server](https://github.com/qiniu/qiniu-mcp-server)** - The Model Context Protocol (MCP) Server built on Qiniu Cloud products supports users in accessing Qiniu Cloud Storage, intelligent multimedia services, and more through this MCP Server within the context of AI large model clients.
+- **[Quarkus](https://github.com/quarkiverse/quarkus-mcp-servers)** - MCP servers for the Quarkus Java framework.
- **[QuickChart](https://github.com/GongRzhe/Quickchart-MCP-Server)** - A Model Context Protocol server for generating charts using QuickChart.io
- **[Qwen_Max](https://github.com/66julienmartin/MCP-server-Qwen_Max)** - A Model Context Protocol (MCP) server implementation for the Qwen models.
- **[RabbitMQ](https://github.com/kenliao94/mcp-server-rabbitmq)** - The MCP server that interacts with RabbitMQ to publish and consume messages.
+- **[RAE](https://github.com/rae-api-com/rae-mcp)** - MPC Server to connect your preferred model with rae-api.com, Roya Academy of Spanish Dictionary
+- **[RAG Local](https://github.com/renl/mcp-rag-local)** - This MCP server for storing and retrieving text passages locally based on their semantic meaning.
- **[RAG Web Browser](https://github.com/apify/mcp-server-rag-web-browser)** An MCP server for Apify's open-source RAG Web Browser [Actor](https://apify.com/apify/rag-web-browser) to perform web searches, scrape URLs, and return content in Markdown.
+- **[Raindrop.io](https://github.com/hiromitsusasaki/raindrop-io-mcp-server)** - An integration that allows LLMs to interact with Raindrop.io bookmarks using the Model Context Protocol (MCP).
+- **[Random Number](https://github.com/zazencodes/random-number-mcp)** - Provides LLMs with essential random generation abilities, built entirely on Python's standard library.
- **[Reaper](https://github.com/dschuler36/reaper-mcp-server)** - Interact with your [Reaper](https://www.reaper.fm/) (Digital Audio Workstation) projects.
- **[Redis](https://github.com/GongRzhe/REDIS-MCP-Server)** - Redis database operations and caching microservice server with support for key-value operations, expiration management, and pattern-based key listing.
- **[Redis](https://github.com/prajwalnayak7/mcp-server-redis)** MCP server to interact with Redis Server, AWS Memory DB, etc for caching or other use-cases where in-memory and key-value based storage is appropriate
+- **[RedNote MCP](https://github.com/ifuryst/rednote-mcp)** - MCP server for accessing RedNote(XiaoHongShu, xhs) content
+- **[Reed Jobs](https://github.com/kld3v/reed_jobs_mcp)** - Search and retrieve job listings from Reed.co.uk.
- **[Rememberizer AI](https://github.com/skydeckai/mcp-server-rememberizer)** - An MCP server designed for interacting with the Rememberizer data source, facilitating enhanced knowledge retrieval.
- **[Replicate](https://github.com/deepfates/mcp-replicate)** - Search, run and manage machine learning models on Replicate through a simple tool-based interface. Browse models, create predictions, track their status, and handle generated images.
-- **[Rquest](https://github.com/xxxbrian/mcp-rquest)** - An MCP server providing realistic browser-like HTTP request capabilities with accurate TLS/JA3/JA4 fingerprints for bypassing anti-bot measures.
+- **[Resend](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/resend)** - Send email using Resend services
+- **[Revit MCP](https://github.com/revit-mcp)** - A service implementing the MCP protocol for Autodesk Revit.
- **[Rijksmuseum](https://github.com/r-huijts/rijksmuseum-mcp)** - Interface with the Rijksmuseum API to search artworks, retrieve artwork details, access image tiles, and explore user collections.
+- **[Riot Games](https://github.com/jifrozen0110/mcp-riot)** - MCP server for League of Legends – fetch player info, ranks, champion stats, and match history via Riot API.
+- **[Rquest](https://github.com/xxxbrian/mcp-rquest)** - An MCP server providing realistic browser-like HTTP request capabilities with accurate TLS/JA3/JA4 fingerprints for bypassing anti-bot measures.
+- **[Rust MCP Filesystem](https://github.com/rust-mcp-stack/rust-mcp-filesystem)** - Fast, asynchronous MCP server for efficient handling of various filesystem operations built with the power of Rust.
+- **[SafetySearch](https://github.com/surabhya/SafetySearch)** - Real-time FDA food safety data: recalls, adverse events, analysis.
- **[Salesforce MCP](https://github.com/smn2gnt/MCP-Salesforce)** - Interact with Salesforce Data and Metadata
+- **[Salesforce MCP (AiondaDotCom)](https://github.com/AiondaDotCom/mcp-salesforce)** - Universal Salesforce integration with OAuth authentication, smart learning system, comprehensive backup capabilities, and full CRUD operations for any Salesforce org including custom objects and fields.
+- **[Salesforce MCP Server](https://github.com/tsmztech/mcp-server-salesforce)** - Comprehensive Salesforce integration with tools for querying records, executing Apex, managing fields/objects, and handling debug logs
+- **[SchemaCrawler](https://github.com/schemacrawler/SchemaCrawler-MCP-Server-Usage)** - Connect to any relational database, and be able to get valid SQL, and ask questions like what does a certain column prefix mean.
+- **[SchemaFlow](https://github.com/CryptoRadi/schemaflow-mcp-server)** - Real-time PostgreSQL & Supabase database schema access for AI-IDEs via Model Context Protocol. Provides live database context through secure SSE connections with three powerful tools: get_schema, analyze_database, and check_schema_alignment. [SchemaFlow](https://schemaflow.dev)
- **[Scholarly](https://github.com/adityak74/mcp-scholarly)** - A MCP server to search for scholarly and academic articles.
- **[scrapling-fetch](https://github.com/cyberchitta/scrapling-fetch-mcp)** - Access text content from bot-protected websites. Fetches HTML/markdown from sites with anti-automation measures using Scrapling.
+- **[Screeny](https://github.com/rohanrav/screeny)** - Privacy-first macOS MCP server that provides visual context for AI agents through window screenshots
- **[SearXNG](https://github.com/ihor-sokoliuk/mcp-searxng)** - A Model Context Protocol Server for [SearXNG](https://docs.searxng.org)
+- **[SearXNG](https://github.com/erhwenkuo/mcp-searxng)** - A MCP server provide web searching via [SearXNG](https://docs.searxng.org) & retrieve url as makrdown.
+- **[SearXNG Public](https://github.com/pwilkin/mcp-searxng-public)** - A Model Context Protocol Server for retrieving data from public [SearXNG](https://docs.searxng.org) instances, with fallback support
- **[SEC EDGAR](https://github.com/stefanoamorelli/sec-edgar-mcp)** - (by Stefano Amorelli) A community Model Context Protocol Server to access financial filings and data through the U.S. Securities and Exchange Commission ([SEC](https://www.sec.gov/)) `Electronic Data Gathering, Analysis, and Retrieval` ([EDGAR](https://www.sec.gov/submit-filings/about-edgar)) database
+- **[SEO MCP](https://github.com/cnych/seo-mcp)** - A free SEO tool MCP (Model Control Protocol) service based on Ahrefs data. Includes features such as backlinks, keyword ideas, and more. by [claudemcp](https://www.claudemcp.com/servers/seo-mcp).
+- **[Serper](https://github.com/garymengcom/serper-mcp-server)** - An MCP server that performs Google searches using [Serper](https://serper.dev).
- **[ServiceNow](https://github.com/osomai/servicenow-mcp)** - A MCP server to interact with a ServiceNow instance
+- **[ShaderToy](https://github.com/wilsonchenghy/ShaderToy-MCP)** - This MCP server lets LLMs to interact with the ShaderToy API, allowing LLMs to learn from compute shaders examples and enabling them to create complex GLSL shaders that they are previously not capable of.
+- **[ShareSeer](https://github.com/shareseer/shareseer-mcp-server)** - MCP to Access SEC filings, financials & insider trading data in real time using [ShareSeer](https://shareseer.com)
+- **[Shell](https://github.com/sonirico/mcp-shell)** - Give hands to AI. MCP server to run shell commands securely, auditably, and on demand
+- **[Shodan MCP](https://github.com/Hexix23/shodan-mcp)** - MCP server to interact with [Shodan](https://www.shodan.io/)
- **[Shopify](https://github.com/GeLi2001/shopify-mcp)** - MCP to interact with Shopify API including order, product, customers and so on.
+- **[Shopify Storefront](https://github.com/QuentinCody/shopify-storefront-mcp-server)** - Unofficial MCP server that allows AI agents to discover Shopify storefronts and interact with them to fetch products, collections, and other store data through the Storefront API.
+- **[Simple Loki MCP](https://github.com/ghrud92/simple-loki-mcp)** - A simple MCP server to query Loki logs using logcli.
- **[Siri Shortcuts](https://github.com/dvcrn/mcp-server-siri-shortcuts)** - MCP to interact with Siri Shortcuts on macOS. Exposes all Shortcuts as MCP tools.
+- **[Skyvern](https://github.com/Skyvern-AI/skyvern/tree/main/integrations/mcp)** - MCP to let Claude / Windsurf / Cursor / your LLM control the browser
+- **[Slack](https://github.com/korotovsky/slack-mcp-server)** - The most powerful MCP server for Slack Workspaces. This integration supports both Stdio and SSE transports, proxy settings and does not require any permissions or bots being created or approved by Workspace admins 😏.
+- **[Slack](https://github.com/zencoderai/slack-mcp-server)** - Slack MCP server which supports both stdio and Streamable HTTP transports. Extended from the original Anthropic's implementation which is now [archived](https://github.com/modelcontextprotocol/servers-archived/tree/main/src/slack)
+- **[Slidespeak](https://github.com/SlideSpeak/slidespeak-mcp)** - Create PowerPoint presentations using the [Slidespeak](https://slidespeak.com/) API.
+- **[Smartlead](https://github.com/jean-technologies/smartlead-mcp-server-local)** - MCP to connect to Smartlead. Additional, tooling, functionality, and connection to workflow automation platforms also available.
- **[Snowflake](https://github.com/isaacwasserman/mcp-snowflake-server)** - This MCP server enables LLMs to interact with Snowflake databases, allowing for secure and controlled data operations.
- **[SoccerDataAPI](https://github.com/yeonupark/mcp-soccer-data)** - This MCP server provides real-time football match data based on the SoccerDataAPI.
-- **[Solana Agent Kit](https://github.com/sendaifun/solana-agent-kit/tree/main/examples/agent-kit-mcp-server)** - This MCP server enables LLMs to interact with the Solana blockchain with help of Solana Agent Kit by SendAI, allowing for 40+ protcool actions and growing
+- **[Solana Agent Kit](https://github.com/sendaifun/solana-agent-kit/tree/main/examples/agent-kit-mcp-server)** - This MCP server enables LLMs to interact with the Solana blockchain with help of Solana Agent Kit by SendAI, allowing for 40+ protocol actions and growing
+- **[Solr MCP](https://github.com/mjochum64/mcp-solr-search)** - This MCP server offers a basic functionality to perform a search on Solr servers.
+- **[Solver](https://github.com/szeider/mcp-solver)** - Solves constraint satisfaction and optimization problems .
+- **[Specbridge](https://github.com/TBosak/specbridge)** - Easily turn your OpenAPI specs into MCP Tools.
+- **[Splunk](https://github.com/jkosik/mcp-server-splunk)** - Golang MCP server for Splunk (lists saved searches, alerts, indexes, macros...). Supports SSE and STDIO.
- **[Spotify](https://github.com/varunneal/spotify-mcp)** - This MCP allows an LLM to play and use Spotify.
+- **[Spring Initializr](https://github.com/hpalma/springinitializr-mcp)** - This MCP allows an LLM to create Spring Boot projects with custom configurations. Instead of manually visiting start.spring.io, you can now ask your AI assistant to generate projects with specific dependencies, Java versions, and project structures.
+- **[SSH](https://github.com/AiondaDotCom/mcp-ssh)** - Agent for managing and controlling SSH connections.
+- **[SSH](https://github.com/classfang/ssh-mcp-server)** - An MCP server that can execute SSH commands remotely, upload files, download files, and so on.
+- **[Standard Korean Dictionary](https://github.com/privetin/stdict)** - Search the dictionary using API
+- **[Star Wars](https://github.com/johnpapa/mcp-starwars)** -MCP Server for the SWAPI Star Wars API. The main goal of the project is to show how an MCP server can be used to interact with APIs.
+- **[Starknet MCP Server](https://github.com/mcpdotdirect/starknet-mcp-server)** - A comprehensive MCP server for interacting with the Starknet blockchain, providing tools for querying blockchain data, resolving StarknetIDs, and performing token transfers.
- **[Starwind UI](https://github.com/Boston343/starwind-ui-mcp/)** - This MCP provides relevant commands, documentation, and other information to allow LLMs to take full advantage of Starwind UI's open source Astro components.
+- **[Stellar](https://github.com/syronlabs/stellar-mcp/)** - This MCP server enables LLMs to interact with the Stellar blockchain to create accounts, check address balances, analyze transactions, view transaction history, mint new assets, interact with smart contracts and much more.
+- **[Stitch AI](https://github.com/StitchAI/stitch-ai-mcp/)** - Knowledge management system for AI agents with memory space creation and retrieval capabilities.
+- **[Stockfish](https://github.com/sonirico/mcp-stockfish)** - MCP server connecting AI systems to Stockfish chess engine
+- **[Strava](https://github.com/r-huijts/strava-mcp)** - Connect to the Strava API to access activity data, athlete profiles, segments, and routes, enabling fitness tracking and analysis with Claude.
+- **[Strava API](https://github.com/tomekkorbak/strava-mcp-server)** - MCP server for Strava API to retrieve one's activities
- **[Stripe](https://github.com/atharvagupta2003/mcp-stripe)** - This MCP allows integration with Stripe for handling payments, customers, and refunds.
-- **[ShaderToy](https://github.com/wilsonchenghy/ShaderToy-MCP)** - This MCP server lets LLMs to interact with the ShaderToy API, allowing LLMs to learn from compute shaders examples and enabling them to create complex GLSL shaders that they are previously not capable of.
-- **[TMDB](https://github.com/Laksh-star/mcp-server-tmdb)** - This MCP server integrates with The Movie Database (TMDB) API to provide movie information, search capabilities, and recommendations.
+- **[Substack/Medium](https://github.com/jonathan-politzki/mcp-writer-substack)** - Connect Claude to your Substack/Medium writing, enabling semantic search and analysis of your published content.
+- **[System Health](https://github.com/thanhtung0201/mcp-remote-system-health)** - The MCP (Multi-Channel Protocol) System Health Monitoring is a robust, real-time monitoring solution designed to provide comprehensive health metrics and alerts for remote Linux servers.
+- **[Talk To Figma](https://github.com/sonnylazuardi/cursor-talk-to-figma-mcp)** - This MCP server enables LLMs to interact with Figma, allowing them to read and modify designs programmatically.
+- **[Talk To Figma via Claude](https://github.com/gaganmanku96/talk-with-figma-claude)** - TMCP server that provides seamless Figma integration specifically for Claude Desktop, enabling design creation, modification, and real-time collaboration through natural language commands.
+- **[TAM MCP Server](https://github.com/gvaibhav/TAM-MCP-Server)** - Market research and business intelligence with TAM/SAM calculations and integration across 8 economic data sources: Alpha Vantage, BLS, Census Bureau, FRED, IMF, Nasdaq Data Link, OECD, and World Bank.
- **[Tavily search](https://github.com/RamXX/mcp-tavily)** - An MCP server for Tavily's search & news API, with explicit site inclusions/exclusions
+- **[TeamRetro](https://github.com/adepanges/teamretro-mcp-server)** - This MCP server allows LLMs to interact with TeamRetro, allowing LLMs to manage user, team, team member, retrospective, health check, action, agreement and fetch the reports.
- **[Telegram](https://github.com/chigwell/telegram-mcp)** - An MCP server that provides paginated chat reading, message retrieval, and message sending capabilities for Telegram through Telethon integration.
- **[Telegram-Client](https://github.com/chaindead/telegram-mcp)** - A Telegram API bridge that manages user data, dialogs, messages, drafts, read status, and more for seamless interactions.
+- **[Telegram-mcp-server](https://github.com/DLHellMe/telegram-mcp-server)** - Access Telegram channels and groups directly in Claude. Features dual-mode operation with API access (100x faster) or web scraping, unlimited post retrieval, and search functionality.
+- **[Template MCP Server](https://github.com/mcpdotdirect/template-mcp-server)** - A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
+- **[Tempo](https://github.com/scottlepp/tempo-mcp-server)** - An MCP server to query traces/spans from [Grafana Tempo](https://github.com/grafana/tempo).
+- **[Teradata](https://github.com/arturborycki/mcp-teradata)** - his MCP server enables LLMs to interact with Teradata databases. This MCP Server support tools and prompts for multi task data analytics
- **[Terminal-Control](https://github.com/GongRzhe/terminal-controller-mcp)** - A MCP server that enables secure terminal command execution, directory navigation, and file system operations through a standardized interface.
+- **[Terraform-Cloud](https://github.com/severity1/terraform-cloud-mcp)** - An MCP server that integrates AI assistants with the Terraform Cloud API, allowing you to manage your infrastructure through natural conversation.
- **[TFT-Match-Analyzer](https://github.com/GeLi2001/tft-mcp-server)** - MCP server for teamfight tactics match history & match details fetching, providing user the detailed context for every match.
+- **[thegraph-mcp](https://github.com/kukapay/thegraph-mcp)** - An MCP server that powers AI agents with indexed blockchain data from The Graph.
+- **[Things3 MCP](https://github.com/urbanogardun/things3-mcp)** - Things3 task management integration for macOS with comprehensive TODO, project, and tag management.
+- **[Think MCP](https://github.com/Rai220/think-mcp)** - Enhances any agent's reasoning capabilities by integrating the think-tools, as described in [Anthropic's article](https://www.anthropic.com/engineering/claude-think-tool).
- **[Ticketmaster](https://github.com/delorenj/mcp-server-ticketmaster)** - Search for events, venues, and attractions through the Ticketmaster Discovery API
- **[TickTick](https://github.com/alexarevalo9/ticktick-mcp-server)** - A Model Context Protocol (MCP) server designed to integrate with the TickTick task management platform, enabling intelligent context-aware task operations and automation.
+- **[TigerGraph](https://github.com/custom-discoveries/TigerGraph_MCP)** - A community built MCP server that interacts with TigerGraph Graph Database.
+- **[tip.md](https://github.com/tipdotmd#-mcp-server-for-ai-assistants)** - An MCP server that enables AI assistants to interact with tip.md's crypto tipping functionality, allowing agents or supporters to tip registered developers directly from AI chat interfaces.
+- **[TMDB](https://github.com/Laksh-star/mcp-server-tmdb)** - This MCP server integrates with The Movie Database (TMDB) API to provide movie information, search capabilities, and recommendations.
- **[Todoist](https://github.com/abhiz123/todoist-mcp-server)** - Interact with Todoist to manage your tasks.
-- **[Typesense](https://github.com/suhail-ak-s/mcp-typesense-server)** - A Model Context Protocol (MCP) server implementation that provides AI models with access to Typesense search capabilities. This server enables LLMs to discover, search, and analyze data stored in Typesense collections.
+- **[Todos](https://github.com/tomelliot/todos-mcp)** - A practical todo list manager to use with your favourite chatbot.
+- **[token-minter-mcp](https://github.com/kukapay/token-minter-mcp)** - An MCP server providing tools for AI agents to mint ERC-20 tokens across multiple blockchains.
+- **[token-revoke-mcp](https://github.com/kukapay/token-revoke-mcp)** - An MCP server for checking and revoking ERC-20 token allowances across multiple blockchains.
+- **[Ton Blockchain MCP](https://github.com/devonmojito/ton-blockchain-mcp)** - An MCP server for interacting with Ton Blockchain.
+- **[TouchDesigner](https://github.com/8beeeaaat/touchdesigner-mcp)** - An MCP server for TouchDesigner, enabling interaction with TouchDesigner projects, nodes, and parameters.
- **[Travel Planner](https://github.com/GongRzhe/TRAVEL-PLANNER-MCP-Server)** - Travel planning and itinerary management server integrating with Google Maps API for location search, place details, and route calculations.
+- **[Trello MCP Server](https://github.com/lioarce01/trello-mcp-server)** - An MCP server that interact with user Trello boards, modifying them with prompting.
+- **[Trino](https://github.com/tuannvm/mcp-trino)** - A high-performance Model Context Protocol (MCP) server for Trino implemented in Go.
+- **[Tripadvisor](https://github.com/pab1it0/tripadvisor-mcp)** - A MCP server that enables LLMs to interact with Tripadvisor API, supporting location data, reviews, and photos through standardized MCP interfaces
+- **[TrueNAS Core MCP](https://github.com/vespo92/TrueNasCoreMCP)** - An MCP server for interacting with TrueNAS Core.
+- **[Tyk API Management](https://github.com/TykTechnologies/tyk-dashboard-mcp)** - Chat with all of your organization's managed APIs and perform other API lifecycle operations, managing tokens, users, analytics, and more.
+- **[Typesense](https://github.com/suhail-ak-s/mcp-typesense-server)** - A Model Context Protocol (MCP) server implementation that provides AI models with access to Typesense search capabilities. This server enables LLMs to discover, search, and analyze data stored in Typesense collections.
+- **[uniswap-poolspy-mcp](https://github.com/kukapay/uniswap-poolspy-mcp)** - An MCP server that tracks newly created liquidity pools on Uniswap across nine blockchain networks.
+- **[uniswap-trader-mcp](https://github.com/kukapay/uniswap-trader-mcp)** -An MCP server for AI agents to automate token swaps on Uniswap DEX across multiple blockchains.
- **[Unity Catalog](https://github.com/ognis1205/mcp-server-unitycatalog)** - An MCP server that enables LLMs to interact with Unity Catalog AI, supporting CRUD operations on Unity Catalog Functions and executing them as MCP tools.
-- **[Unity3d Game Engine](https://github.com/CoderGamester/mcp-unity)** - An MCP server that enables LLMs to interact with Unity3d Game Engine, supporting access to a variety of the Unit's Editor engine tools (e.g. Console Logs, Test Runner logs, Editor functions, hierarchy state, etc) and executing them as MCP tools or gather them as resources.
- **[Unity Integration (Advanced)](https://github.com/quazaai/UnityMCPIntegration)** - Advanced Unity3d Game Engine MCP which supports ,Execution of Any Editor Related Code Directly Inside of Unity, Fetch Logs, Get Editor State and Allow File Access of the Project making it much more useful in Script Editing or asset creation.
+- **[Unity3d Game Engine](https://github.com/CoderGamester/mcp-unity)** - An MCP server that enables LLMs to interact with Unity3d Game Engine, supporting access to a variety of the Unit's Editor engine tools (e.g. Console Logs, Test Runner logs, Editor functions, hierarchy state, etc) and executing them as MCP tools or gather them as resources.
+- **[Universal MCP Servers](https://github.com/universal-mcp)** - A collection of MCP servers created using the [AgentR Universal MCP SDK](https://github.com/universal-mcp/universal-mcp).
+- **[Unleash Integration (Feature Toggle)](https://github.com/cuongtl1992/unleash-mcp)** - A Model Context Protocol (MCP) server implementation that integrates with Unleash Feature Toggle system. Provide a bridge between LLM applications and Unleash feature flag system
+- **[Upbit MCP Server](https://github.com/solangii/upbit-mcp-server)** – An MCP server that enables real - time access to cryptocurrency prices, market summaries, and asset listings from the Upbit exchange.
+- **[use_aws_mcp](https://github.com/runjivu/use_aws_mcp)** - amazon-q-cli's use_aws tool extracted into independent mcp, for general aws api usage.
+- **[User Feedback](https://github.com/mrexodia/user-feedback-mcp)** - Simple MCP Server to enable a human-in-the-loop workflow in tools like Cline and Cursor.
+- **[USPTO](https://github.com/riemannzeta/patent_mcp_server)** - MCP server for accessing United States Patent & Trademark Office data through its Open Data Protocol (ODP) API.
+- **[Vectara](https://github.com/vectara/vectara-mcp)** - Query Vectara's trusted RAG-as-a-service platform.
- **[Vega-Lite](https://github.com/isaacwasserman/mcp-vegalite-server)** - Generate visualizations from fetched data using the VegaLite format and renderer.
+- **[Vertica](https://github.com/nolleh/mcp-vertica)** - Vertica database integration in Python with configurable access controls and schema inspection
+- **[Vibe Check](https://github.com/PV-Bhat/vibe-check-mcp-server)** - An MCP server leveraging an external oversight layer to "vibe check" agents, and also self-improve accuracy & user alignment over time. Prevents scope creep, code bloat, misalignment, misinterpretation, tunnel vision, and overcomplication.
- **[Video Editor](https://github.com/burningion/video-editing-mcp)** - A Model Context Protocol Server to add, edit, and search videos with [Video Jungle](https://www.video-jungle.com/).
+- **[Video Still Capture](https://github.com/13rac1/videocapture-mcp)** - 📷 Capture video stills from an OpenCV-compatible webcam or other video source.
- **[Virtual location (Google Street View,etc.)](https://github.com/mfukushim/map-traveler-mcp)** - Integrates Google Map, Google Street View, PixAI, Stability.ai, ComfyUI API and Bluesky to provide a virtual location simulation in LLM (written in Effect.ts)
+- **[VMware Fusion](https://github.com/yeahdongcn/vmware-fusion-mcp-server)** - Manage VMware Fusion virtual machines via the Fusion REST API.
+- **[Voice MCP](https://github.com/mbailey/voice-mcp)** - Enable voice conversations with Claude using any OpenAI-compatible STT/TTS service ([voice-mcp.com](https://voice-mcp.com))
+- **[Voice Status Report](https://github.com/tomekkorbak/voice-status-report-mcp-server)** - An MCP server that provides voice status updates using OpenAI's text-to-speech API, to be used with Cursor or Claude Code.
- **[VolcEngine TOS](https://github.com/dinghuazhou/sample-mcp-server-tos)** - A sample MCP server for VolcEngine TOS that flexibly get objects from TOS.
+- **[Voyp](https://github.com/paulotaylor/voyp-mcp)** - VOYP MCP server for making calls using Artificial Intelligence.
+- **[vulnicheck](https://github.com/andrasfe/vulnicheck)** - Real-time Python package vulnerability scanner that checks dependencies against OSV and NVD databases, providing comprehensive security analysis with CVE details, lock file support, and actionable upgrade recommendations.
- **[Wanaku MCP Router](https://github.com/wanaku-ai/wanaku/)** - The Wanaku MCP Router is a SSE-based MCP server that provides an extensible routing engine that allows integrating your enterprise systems with AI agents.
-- **[Webflow](https://github.com/kapilduraphe/webflow-mcp-server)** - Interfact with the Webflow APIs
-- **[whale-tracker-mcp](https://github.com/kukapay/whale-tracker-mcp)** - A mcp server for tracking cryptocurrency whale transactions.
-- **[Whois MCP](https://github.com/bharathvaj-ganesan/whois-mcp)** - MCP server that performs whois lookup against domain, IP, ASN and TLD.
+- **[weather-mcp-server](https://github.com/devilcoder01/weather-mcp-server)** - Get real-time weather data for any location using weatherapi.
+- **[Web Search MCP](https://github.com/mrkrsl/web-search-mcp)** - A server that provides full web search, summaries and page extration for use with Local LLMs.
+- **[Webex](https://github.com/Kashyap-AI-ML-Solutions/webex-messaging-mcp-server)** - A Model Context Protocol (MCP) server that provides AI assistants with comprehensive access to Cisco Webex messaging capabilities.
+- **[Webflow](https://github.com/kapilduraphe/webflow-mcp-server)** - Interact with the Webflow APIs
+- **[webhook-mcp](https://github.com/noobnooc/webhook-mcp)** (by Nooc) - A Model Context Protocol (MCP) server that sends webhook notifications when called.
+- **[whale-tracker-mcp](https://github.com/kukapay/whale-tracker-mcp)** - A mcp server for tracking cryptocurrency whale transactions.
+- **[WhatsApp MCP Server](https://github.com/lharries/whatsapp-mcp)** - MCP server for your personal WhatsApp handling individuals, groups, searching and sending.
+- **[Whois MCP](https://github.com/bharathvaj-ganesan/whois-mcp)** - MCP server that performs whois lookup against domain, IP, ASN and TLD.
- **[Wikidata MCP](https://github.com/zzaebok/mcp-wikidata)** - Wikidata MCP server that interact with Wikidata, by searching identifiers, extracting metadata, and executing sparql query.
+- **[Wikipedia MCP](https://github.com/Rudra-ravi/wikipedia-mcp)** - Access and search Wikipedia articles via MCP for AI-powered information retrieval.
- **[WildFly MCP](https://github.com/wildfly-extras/wildfly-mcp)** - WildFly MCP server that enables LLM to interact with running WildFly servers (retrieve metrics, logs, invoke operations, ...).
- **[Windows CLI](https://github.com/SimonB97/win-cli-mcp-server)** - MCP server for secure command-line interactions on Windows systems, enabling controlled access to PowerShell, CMD, and Git Bash shells.
+- **[WordPress MCP](https://github.com/Automattic/wordpress-mcp)** - Make your WordPress site into a simple MCP server, exposing functionality to LLMs and AI agents.
+- **[Workflowy](https://github.com/danield137/mcp-workflowy)** - A server that interacts with [workflowy](https://workflowy.com/).
- **[World Bank data API](https://github.com/anshumax/world_bank_mcp_server)** - A server that fetches data indicators available with the World Bank as part of their data API
+- **[Wren Engine](https://github.com/Canner/wren-engine)** - The Semantic Engine for Model Context Protocol(MCP) Clients and AI Agents
- **[X (Twitter)](https://github.com/EnesCinr/twitter-mcp)** (by EnesCinr) - Interact with twitter API. Post tweets and search for tweets by query.
- **[X (Twitter)](https://github.com/vidhupv/x-mcp)** (by vidhupv) - Create, manage and publish X/Twitter posts directly through Claude chat.
+- **[Xcode](https://github.com/r-huijts/xcode-mcp-server)** - MCP server that brings AI to your Xcode projects, enabling intelligent code assistance, file operations, project management, and automated development tasks.
- **[xcodebuild](https://github.com/ShenghaiWang/xcodebuild)** - 🍎 Build iOS Xcode workspace/project and feed back errors to llm.
- **[Xero-mcp-server](https://github.com/john-zhang-dev/xero-mcp)** - Enabling clients to interact with Xero system for streamlined accounting, invoicing, and business operations.
- **[XiYan](https://github.com/XGenerationLab/xiyan_mcp_server)** - 🗄️ An MCP server that supports fetching data from a database using natural language queries, powered by XiyanSQL as the text-to-SQL LLM.
- **[XMind](https://github.com/apeyroux/mcp-xmind)** - Read and search through your XMind directory containing XMind files.
+- **[yfinance](https://github.com/Adity-star/mcp-yfinance-server)** -💹The MCP YFinance Stock Server provides real-time and historical stock data in a standard format, powering dashboards, AI agents,and research tools with seamless financial insights.
+- **[YNAB](https://github.com/ChuckBryan/ynabmcpserver)** - A Model Context Protocol (MCP) server for integrating with YNAB (You Need A Budget), allowing AI assistants to securely access and analyze your financial data.
+- **[YouTrack](https://github.com/tonyzorin/youtrack-mcp)** - A Model Context Protocol (MCP) server implementation for JetBrains YouTrack, allowing AI assistants to interact with YouTrack issue tracking system.
+- **[YouTube](https://github.com/Klavis-AI/klavis/tree/main/mcp_servers/youtube)** - Extract Youtube video information (with proxies support).
- **[YouTube](https://github.com/ZubeidHendricks/youtube-mcp-server)** - Comprehensive YouTube API integration for video management, Shorts creation, and analytics.
-
+- **[Youtube Uploader MCP](https://github.com/anwerj/youtube-uploader-mcp)** - AI‑powered YouTube uploader—no CLI, no YouTube Studio.
+- **[YouTube Video Summarizer](https://github.com/nabid-pf/youtube-video-summarizer-mcp)** - Summarize lengthy youtube videos.
+- **[yutu](https://github.com/eat-pray-ai/yutu)** - A fully functional MCP server and CLI for YouTube to automate YouTube operation.
+- **[ZapCap](https://github.com/bogdan01m/zapcap-mcp-server)** - MCP server for ZapCap API providing video caption and B-roll generation via natural language
+- **[Zoom](https://github.com/Prathamesh0901/zoom-mcp-server/tree/main)** - Create, update, read and delete your zoom meetings.
## 📚 Frameworks
These are high-level frameworks that make it easier to build MCP servers or clients.
### For servers
+* **[ModelFetch](https://github.com/phuctm97/modelfetch/)** (TypeScript) - Runtime-agnostic SDK to create and deploy MCP servers anywhere TypeScript/JavaScript runs
* **[EasyMCP](https://github.com/zcaceres/easy-mcp/)** (TypeScript)
-- **[FastAPI to MCP auto generator](https://github.com/tadata-org/fastapi_mcp)** – A zero-configuration tool for automatically exposing FastAPI endpoints as MCP tools by **[Tadata](https://tadata.com/)**
+* **[FastAPI to MCP auto generator](https://github.com/tadata-org/fastapi_mcp)** – A zero-configuration tool for automatically exposing FastAPI endpoints as MCP tools by **[Tadata](https://tadata.com/)**
* **[FastMCP](https://github.com/punkpeye/fastmcp)** (TypeScript)
+* **[Foobara MCP Connector](https://github.com/foobara/mcp-connector)** - Easily expose Foobara commands written in Ruby as tools via MCP
* **[Foxy Contexts](https://github.com/strowk/foxy-contexts)** – A library to build MCP servers in Golang by **[strowk](https://github.com/strowk)**
* **[Higress MCP Server Hosting](https://github.com/alibaba/higress/tree/main/plugins/wasm-go/mcp-servers)** - A solution for hosting MCP Servers by extending the API Gateway (based on Envoy) with wasm plugins.
+* **[MCP Declarative Java SDK](https://github.com/codeboyzhou/mcp-declarative-java-sdk)** Annotation-driven MCP servers development with Java, no Spring Framework Required, minimize dependencies as much as possible.
* **[MCP-Framework](https://mcp-framework.com)** Build MCP servers with elegance and speed in Typescript. Comes with a CLI to create your project with `mcp create app`. Get started with your first server in under 5 minutes by **[Alex Andru](https://github.com/QuantGeekDev)**
+* **[MCP Plexus](https://github.com/Super-I-Tech/mcp_plexus)**: A secure, **multi-tenant** and Multi-user MCP python server framework built to integrate easily with external services via OAuth 2.1, offering scalable and robust solutions for managing complex AI applications.
+* **[mcp_sse (Elixir)](https://github.com/kEND/mcp_sse)** An SSE implementation in Elixir for rapidly creating MCP servers.
+* **[Next.js MCP Server Template](https://github.com/vercel-labs/mcp-for-next.js)** (Typescript) - A starter Next.js project that uses the MCP Adapter to allow MCP clients to connect and access resources.
* **[Quarkus MCP Server SDK](https://github.com/quarkiverse/quarkus-mcp-server)** (Java)
+* **[SAP ABAP MCP Server SDK](https://github.com/abap-ai/mcp)** - Build SAP ABAP based MCP servers. ABAP 7.52 based with 7.02 downport; runs on R/3 & S/4HANA on-premises, currently not cloud-ready.
+* **[Spring AI MCP Server](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html)** - Provides auto-configuration for setting up an MCP server in Spring Boot applications.
* **[Template MCP Server](https://github.com/mcpdotdirect/template-mcp-server)** - A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
+* **[AgentR Universal MCP SDK](https://github.com/universal-mcp/universal-mcp)** - A python SDK to build MCP Servers with inbuilt credential management by **[Agentr](https://agentr.dev/home)**
+* **[Vercel MCP Adapter](https://github.com/vercel/mcp-adapter)** (Typescript) - A simple package to start serving an MCP server on most major JS meta-frameworks including Next, Nuxt, Svelte, and more.
+* **[Hermes MCP](https://github.com/cloudwalk/hermes-mcp)** (Elixir) - A high-performance and high-level Model Context Protocol (MCP) implementation in Elixir. Think like "Live View" for MCP.
+
### For clients
* **[codemirror-mcp](https://github.com/marimo-team/codemirror-mcp)** - CodeMirror extension that implements the Model Context Protocol (MCP) for resource mentions and prompt commands
+* **[llm-analysis-assistant](https://github.com/xuzexin-hz/llm-analysis-assistant)**
- A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also supports monitoring and simulation of ollama/openai interface.
+* **[MCP-Agent](https://github.com/lastmile-ai/mcp-agent)** - A simple, composable framework to build agents using Model Context Protocol by **[LastMile AI](https://www.lastmileai.dev)**
+* **[Spring AI MCP Client](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html)** - Provides auto-configuration for MCP client functionality in Spring Boot applications.
+* **[MCP CLI Client](https://github.com/vincent-pli/mcp-cli-host)** - A CLI host application that enables Large Language Models (LLMs) to interact with external tools through the Model Context Protocol (MCP).
+* **[OpenMCP Client](https://github.com/LSTM-Kirigaya/openmcp-client/)** - An all-in-one vscode/trae/cursor plugin for MCP server debugging. [Document](https://kirigaya.cn/openmcp/) & [OpenMCP SDK](https://kirigaya.cn/openmcp/sdk-tutorial/).
+
## 📚 Resources
@@ -424,33 +1068,44 @@ Additional resources on MCP.
- **[Awesome MCP Servers by appcypher](https://github.com/appcypher/awesome-mcp-servers)** - A curated list of MCP servers by **[Stephen Akinyemi](https://github.com/appcypher)**
- **[Awesome MCP Servers by punkpeye](https://github.com/punkpeye/awesome-mcp-servers)** (**[website](https://glama.ai/mcp/servers)**) - A curated list of MCP servers by **[Frank Fiegel](https://github.com/punkpeye)**
- **[Awesome MCP Servers by wong2](https://github.com/wong2/awesome-mcp-servers)** (**[website](https://mcpservers.org)**) - A curated list of MCP servers by **[wong2](https://github.com/wong2)**
-- **[Discord Server](https://glama.ai/mcp/discord)** – A community discord server dedicated to MCP by **[Frank Fiegel](https://github.com/punkpeye)**
+- **[Awesome Remote MCP Servers by JAW9C](https://github.com/jaw9c/awesome-remote-mcp-servers)** - A curated list of **remote** MCP servers, including their authentication support by **[JAW9C](https://github.com/jaw9c)**
+- **[Discord Server](https://glama.ai/mcp/discord)** – A community discord server dedicated to MCP by **[Frank Fiegel](https://github.com/punkpeye)**
- **[Discord Server (ModelContextProtocol)](https://discord.gg/jHEGxQu2a5)** – Connect with developers, share insights, and collaborate on projects in an active Discord community dedicated to the Model Context Protocol by **[Alex Andru](https://github.com/QuantGeekDev)**
-
+-
**[Klavis AI](https://www.klavis.ai)** - Open Source MCP Infra. Hosted MCP servers and MCP clients on Slack and Discord.
- **[MCP Badges](https://github.com/mcpx-dev/mcp-badges)** – Quickly highlight your MCP project with clear, eye-catching badges, by **[Ironben](https://github.com/nanbingxyz)**
-- **[MCP Servers Hub](https://github.com/apappascs/mcp-servers-hub)** (**[website](https://mcp-servers-hub-website.pages.dev/)**) - A curated list of MCP servers by **[apappascs](https://github.com/apappascs)**
-- **[MCP X Community](https://x.com/i/communities/1861891349609603310)** – A X community for MCP by **[Xiaoyi](https://x.com/chxy)**
+- **[MCPRepository.com](https://mcprepository.com/)** - A repository that indexes and organizes all MCP servers for easy discovery.
- **[mcp-cli](https://github.com/wong2/mcp-cli)** - A CLI inspector for the Model Context Protocol by **[wong2](https://github.com/wong2)**
+- **[mcp-dockmaster](https://mcp-dockmaster.com)** - An Open-Sourced UI to install and manage MCP servers for Windows, Linux and MacOS.
- **[mcp-get](https://mcp-get.com)** - Command line tool for installing and managing MCP servers by **[Michael Latman](https://github.com/michaellatman)**
- **[mcp-guardian](https://github.com/eqtylab/mcp-guardian)** - GUI application + tools for proxying / managing control of MCP servers by **[EQTY Lab](https://eqtylab.io)**
-- **[mcpm](https://github.com/pathintegral-institute/mcpm.sh)** ([website](https://mcpm.sh)) - MCP Manager (MCPM) is a Homebrew-like service for managing Model Context Protocol (MCP) servers across clients by **[Pathintegral](https://github.com/pathintegral-institute)**
+- **[MCP Linker](https://github.com/milisp/mcp-linker)** - A cross-platform Tauri GUI tool for one-click setup and management of MCP servers, supporting Claude Desktop, Cursor, Windsurf, VS Code, Cline, and Neovim.
- **[mcp-manager](https://github.com/zueai/mcp-manager)** - Simple Web UI to install and manage MCP servers for Claude Desktop by **[Zue](https://github.com/zueai)**
-- **[MCPHub](https://github.com/Jeamee/MCPHub-Desktop)** – An Open Source MacOS & Windows GUI Desktop app for discovering, installing and managing MCP servers by **[Jeamee](https://github.com/jeamee)**
-- **[mcp.natoma.id](https://mcp.natoma.id)** - A Hosted MCP Platform to discover, install, manage and deploy MCP servers by **[Natoma Labs](https://www.natoma.id)**
+- **[MCP Marketplace Web Plugin](https://github.com/AI-Agent-Hub/mcp-marketplace)** MCP Marketplace is a small Web UX plugin to integrate with AI applications, Support various MCP Server API Endpoint (e.g pulsemcp.com/deepnlp.org and more). Allowing user to browse, paginate and select various MCP servers by different categories. [Pypi](https://pypi.org/project/mcp-marketplace) | [Maintainer](https://github.com/AI-Agent-Hub) | [Website](http://www.deepnlp.org/store/ai-agent/mcp-server)
+- **[mcp.natoma.id](https://mcp.natoma.id)** – A Hosted MCP Platform to discover, install, manage and deploy MCP servers by **[Natoma Labs](https://www.natoma.id)**
- **[mcp.run](https://mcp.run)** - A hosted registry and control plane to install & run secure + portable MCP Servers.
-- **[mcp-dockmaster](https://mcp-dockmaster.com)** - An Open-Sourced UI to install and manage MCP servers for Windows, Linux and MacOS.
+- **[MCPHub](https://www.mcphub.com)** - Website to list high quality MCP servers and reviews by real users. Also provide online chatbot for popular LLM models with MCP server support.
+- **[MCP Router](https://mcp-router.net)** – Free Windows and macOS app that simplifies MCP management while providing seamless app authentication and powerful log visualization by **[MCP Router](https://github.com/mcp-router/mcp-router)**
+- **[MCP Servers Hub](https://github.com/apappascs/mcp-servers-hub)** (**[website](https://mcp-servers-hub-website.pages.dev/)**) - A curated list of MCP servers by **[apappascs](https://github.com/apappascs)**
+- **[MCPServers.com](https://mcpservers.com)** - A growing directory of high-quality MCP servers with clear setup guides for a variety of MCP clients. Built by the team behind the **[Highlight MCP client](https://highlightai.com/)**
- **[MCP Servers Rating and User Reviews](http://www.deepnlp.org/store/ai-agent/mcp-server)** - Website to rate MCP servers, write authentic user reviews, and [search engine for agent & mcp](http://www.deepnlp.org/search/agent)
+- **[MCP X Community](https://x.com/i/communities/1861891349609603310)** – A X community for MCP by **[Xiaoyi](https://x.com/chxy)**
+- **[MCPHub](https://github.com/Jeamee/MCPHub-Desktop)** – An Open Source macOS & Windows GUI Desktop app for discovering, installing and managing MCP servers by **[Jeamee](https://github.com/jeamee)**
+- **[mcpm](https://github.com/pathintegral-institute/mcpm.sh)** ([website](https://mcpm.sh)) - MCP Manager (MCPM) is a Homebrew-like service for managing Model Context Protocol (MCP) servers across clients by **[Pathintegral](https://github.com/pathintegral-institute)**
- **[MCPVerse](https://mcpverse.dev)** - A portal for creating & hosting authenticated MCP servers and connecting to them securely.
+- **[MCP Servers Search](https://github.com/atonomus/mcp-servers-search)** - An MCP server that provides tools for querying and discovering available MCP servers from this list.
+- **[MCPWatch](https://github.com/kapilduraphe/mcp-watch)** - A comprehensive security scanner for Model Context Protocol (MCP) servers that detects vulnerabilities and security issues in your MCP server implementations.
-
**[mkinf](https://mkinf.io)** - An Open Source registry of hosted MCP Servers to accelerate AI agent workflows.
- **[Open-Sourced MCP Servers Directory](https://github.com/chatmcp/mcp-directory)** - A curated list of MCP servers by **[mcpso](https://mcp.so)**
-
**[OpenTools](https://opentools.com)** - An open registry for finding, installing, and building with MCP servers by **[opentoolsteam](https://github.com/opentoolsteam)**
- **[PulseMCP](https://www.pulsemcp.com)** ([API](https://www.pulsemcp.com/api)) - Community hub & weekly newsletter for discovering MCP servers, clients, articles, and news by **[Tadas Antanavicius](https://github.com/tadasant)**, **[Mike Coughlin](https://github.com/macoughl)**, and **[Ravina Patel](https://github.com/ravinahp)**
-- **[r/mcp](https://www.reddit.com/r/mcp)** – A Reddit community dedicated to MCP by **[Frank Fiegel](https://github.com/punkpeye)**
-- **[r/modelcontextprotocol](https://www.reddit.com/r/modelcontextprotocol)** – A Model Context Protocol community Reddit page - discuss ideas, get answers to your questions, network with like-minded people, and showcase your projects! by **[Alex Andru](https://github.com/QuantGeekDev)**
-
-
+- **[r/mcp](https://www.reddit.com/r/mcp)** – A Reddit community dedicated to MCP by **[Frank Fiegel](https://github.com/punkpeye)**
+- **[r/modelcontextprotocol](https://www.reddit.com/r/modelcontextprotocol)** – A Model Context Protocol community Reddit page - discuss ideas, get answers to your questions, network with like-minded people, and showcase your projects! by **[Alex Andru](https://github.com/QuantGeekDev)**
+- **[MCP.ing](https://mcp.ing/)** - A list of MCP services for discovering MCP servers in the community and providing a convenient search function for MCP services by **[iiiusky](https://github.com/iiiusky)**
+- **[MCP Hunt](https://mcp-hunt.com)** - Realtime platform for discovering trending MCP servers with momentum tracking, upvoting, and community discussions - like Product Hunt meets Reddit for MCP
- **[Smithery](https://smithery.ai/)** - A registry of MCP servers to find the right tools for your LLM agents by **[Henry Mao](https://github.com/calclavia)**
- **[Toolbase](https://gettoolbase.ai)** - Desktop application that manages tools and MCP servers with just a few clicks - no coding required by **[gching](https://github.com/gching)**
+- **[ToolHive](https://github.com/StacklokLabs/toolhive)** - A lightweight utility designed to simplify the deployment and management of MCP servers, ensuring ease of use, consistency, and security through containerization by **[StacklokLabs](https://github.com/StacklokLabs)**
+- **[NetMind](https://www.netmind.ai/AIServices)** - Access powerful AI services via simple APIs or MCP servers to supercharge your productivity.
## 🚀 Getting Started
diff --git a/SECURITY.md b/SECURITY.md
index ea10c024..f26aba9c 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,7 +1,7 @@
# Security Policy
Thank you for helping us keep our MCP servers secure.
-These servers are maintained by [Anthropic](https://www.anthropic.com/) as part of the Model Context Protocol project.
+The **reference servers** in this repo are maintained by [Anthropic](https://www.anthropic.com/) as part of the Model Context Protocol project.
The security of our systems and user data is Anthropic’s top priority. We appreciate the work of security researchers acting in good faith in identifying and reporting potential vulnerabilities.
diff --git a/package-lock.json b/package-lock.json
index d6821599..c785a237 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,672 +12,31 @@
"src/*"
],
"dependencies": {
- "@modelcontextprotocol/server-brave-search": "*",
- "@modelcontextprotocol/server-everart": "*",
"@modelcontextprotocol/server-everything": "*",
"@modelcontextprotocol/server-filesystem": "*",
- "@modelcontextprotocol/server-gdrive": "*",
"@modelcontextprotocol/server-memory": "*",
- "@modelcontextprotocol/server-postgres": "*",
- "@modelcontextprotocol/server-puppeteer": "*",
- "@modelcontextprotocol/server-sequential-thinking": "*",
- "@modelcontextprotocol/server-slack": "*"
+ "@modelcontextprotocol/server-sequential-thinking": "*"
}
},
- "node_modules/@aws-crypto/crc32": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
- "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
- "dependencies": {
- "@aws-crypto/util": "^5.2.0",
- "@aws-sdk/types": "^3.222.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-crypto/sha256-browser": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
- "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
- "dependencies": {
- "@aws-crypto/sha256-js": "^5.2.0",
- "@aws-crypto/supports-web-crypto": "^5.2.0",
- "@aws-crypto/util": "^5.2.0",
- "@aws-sdk/types": "^3.222.0",
- "@aws-sdk/util-locate-window": "^3.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
- "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
- "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
- "dependencies": {
- "@smithy/is-array-buffer": "^2.2.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": {
+ "node_modules/@ampproject/remapping": {
"version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
- "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/util-buffer-from": "^2.2.0",
- "tslib": "^2.6.2"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-crypto/sha256-js": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
- "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
- "dependencies": {
- "@aws-crypto/util": "^5.2.0",
- "@aws-sdk/types": "^3.222.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-crypto/supports-web-crypto": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
- "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
- "dependencies": {
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@aws-crypto/util": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
- "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
- "dependencies": {
- "@aws-sdk/types": "^3.222.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
- "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
- "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
- "dependencies": {
- "@smithy/is-array-buffer": "^2.2.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
- "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
- "dependencies": {
- "@smithy/util-buffer-from": "^2.2.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-sdk/client-bedrock-agent-runtime": {
- "version": "3.706.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-agent-runtime/-/client-bedrock-agent-runtime-3.706.0.tgz",
- "integrity": "sha512-XX9Nm88Pz8GdHQJ29h6xQlH21qRnaovtF2BeLdKJRKcS/ViZjqfSFt3B5p6BXf+wKW9YFciGwjuo0OOrDx1Oyw==",
- "dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/client-sso-oidc": "3.699.0",
- "@aws-sdk/client-sts": "3.699.0",
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/credential-provider-node": "3.699.0",
- "@aws-sdk/middleware-host-header": "3.696.0",
- "@aws-sdk/middleware-logger": "3.696.0",
- "@aws-sdk/middleware-recursion-detection": "3.696.0",
- "@aws-sdk/middleware-user-agent": "3.696.0",
- "@aws-sdk/region-config-resolver": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@aws-sdk/util-endpoints": "3.696.0",
- "@aws-sdk/util-user-agent-browser": "3.696.0",
- "@aws-sdk/util-user-agent-node": "3.696.0",
- "@smithy/config-resolver": "^3.0.12",
- "@smithy/core": "^2.5.3",
- "@smithy/eventstream-serde-browser": "^3.0.13",
- "@smithy/eventstream-serde-config-resolver": "^3.0.10",
- "@smithy/eventstream-serde-node": "^3.0.12",
- "@smithy/fetch-http-handler": "^4.1.1",
- "@smithy/hash-node": "^3.0.10",
- "@smithy/invalid-dependency": "^3.0.10",
- "@smithy/middleware-content-length": "^3.0.12",
- "@smithy/middleware-endpoint": "^3.2.3",
- "@smithy/middleware-retry": "^3.0.27",
- "@smithy/middleware-serde": "^3.0.10",
- "@smithy/middleware-stack": "^3.0.10",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/node-http-handler": "^3.3.1",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/smithy-client": "^3.4.4",
- "@smithy/types": "^3.7.1",
- "@smithy/url-parser": "^3.0.10",
- "@smithy/util-base64": "^3.0.0",
- "@smithy/util-body-length-browser": "^3.0.0",
- "@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.27",
- "@smithy/util-defaults-mode-node": "^3.0.27",
- "@smithy/util-endpoints": "^2.1.6",
- "@smithy/util-middleware": "^3.0.10",
- "@smithy/util-retry": "^3.0.10",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/client-sso": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz",
- "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==",
- "dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/middleware-host-header": "3.696.0",
- "@aws-sdk/middleware-logger": "3.696.0",
- "@aws-sdk/middleware-recursion-detection": "3.696.0",
- "@aws-sdk/middleware-user-agent": "3.696.0",
- "@aws-sdk/region-config-resolver": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@aws-sdk/util-endpoints": "3.696.0",
- "@aws-sdk/util-user-agent-browser": "3.696.0",
- "@aws-sdk/util-user-agent-node": "3.696.0",
- "@smithy/config-resolver": "^3.0.12",
- "@smithy/core": "^2.5.3",
- "@smithy/fetch-http-handler": "^4.1.1",
- "@smithy/hash-node": "^3.0.10",
- "@smithy/invalid-dependency": "^3.0.10",
- "@smithy/middleware-content-length": "^3.0.12",
- "@smithy/middleware-endpoint": "^3.2.3",
- "@smithy/middleware-retry": "^3.0.27",
- "@smithy/middleware-serde": "^3.0.10",
- "@smithy/middleware-stack": "^3.0.10",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/node-http-handler": "^3.3.1",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/smithy-client": "^3.4.4",
- "@smithy/types": "^3.7.1",
- "@smithy/url-parser": "^3.0.10",
- "@smithy/util-base64": "^3.0.0",
- "@smithy/util-body-length-browser": "^3.0.0",
- "@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.27",
- "@smithy/util-defaults-mode-node": "^3.0.27",
- "@smithy/util-endpoints": "^2.1.6",
- "@smithy/util-middleware": "^3.0.10",
- "@smithy/util-retry": "^3.0.10",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/client-sso-oidc": {
- "version": "3.699.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.699.0.tgz",
- "integrity": "sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==",
- "dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/credential-provider-node": "3.699.0",
- "@aws-sdk/middleware-host-header": "3.696.0",
- "@aws-sdk/middleware-logger": "3.696.0",
- "@aws-sdk/middleware-recursion-detection": "3.696.0",
- "@aws-sdk/middleware-user-agent": "3.696.0",
- "@aws-sdk/region-config-resolver": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@aws-sdk/util-endpoints": "3.696.0",
- "@aws-sdk/util-user-agent-browser": "3.696.0",
- "@aws-sdk/util-user-agent-node": "3.696.0",
- "@smithy/config-resolver": "^3.0.12",
- "@smithy/core": "^2.5.3",
- "@smithy/fetch-http-handler": "^4.1.1",
- "@smithy/hash-node": "^3.0.10",
- "@smithy/invalid-dependency": "^3.0.10",
- "@smithy/middleware-content-length": "^3.0.12",
- "@smithy/middleware-endpoint": "^3.2.3",
- "@smithy/middleware-retry": "^3.0.27",
- "@smithy/middleware-serde": "^3.0.10",
- "@smithy/middleware-stack": "^3.0.10",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/node-http-handler": "^3.3.1",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/smithy-client": "^3.4.4",
- "@smithy/types": "^3.7.1",
- "@smithy/url-parser": "^3.0.10",
- "@smithy/util-base64": "^3.0.0",
- "@smithy/util-body-length-browser": "^3.0.0",
- "@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.27",
- "@smithy/util-defaults-mode-node": "^3.0.27",
- "@smithy/util-endpoints": "^2.1.6",
- "@smithy/util-middleware": "^3.0.10",
- "@smithy/util-retry": "^3.0.10",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "@aws-sdk/client-sts": "^3.699.0"
- }
- },
- "node_modules/@aws-sdk/client-sts": {
- "version": "3.699.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.699.0.tgz",
- "integrity": "sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==",
- "dependencies": {
- "@aws-crypto/sha256-browser": "5.2.0",
- "@aws-crypto/sha256-js": "5.2.0",
- "@aws-sdk/client-sso-oidc": "3.699.0",
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/credential-provider-node": "3.699.0",
- "@aws-sdk/middleware-host-header": "3.696.0",
- "@aws-sdk/middleware-logger": "3.696.0",
- "@aws-sdk/middleware-recursion-detection": "3.696.0",
- "@aws-sdk/middleware-user-agent": "3.696.0",
- "@aws-sdk/region-config-resolver": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@aws-sdk/util-endpoints": "3.696.0",
- "@aws-sdk/util-user-agent-browser": "3.696.0",
- "@aws-sdk/util-user-agent-node": "3.696.0",
- "@smithy/config-resolver": "^3.0.12",
- "@smithy/core": "^2.5.3",
- "@smithy/fetch-http-handler": "^4.1.1",
- "@smithy/hash-node": "^3.0.10",
- "@smithy/invalid-dependency": "^3.0.10",
- "@smithy/middleware-content-length": "^3.0.12",
- "@smithy/middleware-endpoint": "^3.2.3",
- "@smithy/middleware-retry": "^3.0.27",
- "@smithy/middleware-serde": "^3.0.10",
- "@smithy/middleware-stack": "^3.0.10",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/node-http-handler": "^3.3.1",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/smithy-client": "^3.4.4",
- "@smithy/types": "^3.7.1",
- "@smithy/url-parser": "^3.0.10",
- "@smithy/util-base64": "^3.0.0",
- "@smithy/util-body-length-browser": "^3.0.0",
- "@smithy/util-body-length-node": "^3.0.0",
- "@smithy/util-defaults-mode-browser": "^3.0.27",
- "@smithy/util-defaults-mode-node": "^3.0.27",
- "@smithy/util-endpoints": "^2.1.6",
- "@smithy/util-middleware": "^3.0.10",
- "@smithy/util-retry": "^3.0.10",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/core": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz",
- "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/core": "^2.5.3",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/signature-v4": "^4.2.2",
- "@smithy/smithy-client": "^3.4.4",
- "@smithy/types": "^3.7.1",
- "@smithy/util-middleware": "^3.0.10",
- "fast-xml-parser": "4.4.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz",
- "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==",
- "dependencies": {
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/credential-provider-http": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz",
- "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==",
- "dependencies": {
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/fetch-http-handler": "^4.1.1",
- "@smithy/node-http-handler": "^3.3.1",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/smithy-client": "^3.4.4",
- "@smithy/types": "^3.7.1",
- "@smithy/util-stream": "^3.3.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.699.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.699.0.tgz",
- "integrity": "sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==",
- "dependencies": {
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/credential-provider-env": "3.696.0",
- "@aws-sdk/credential-provider-http": "3.696.0",
- "@aws-sdk/credential-provider-process": "3.696.0",
- "@aws-sdk/credential-provider-sso": "3.699.0",
- "@aws-sdk/credential-provider-web-identity": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/credential-provider-imds": "^3.2.6",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/shared-ini-file-loader": "^3.1.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "@aws-sdk/client-sts": "^3.699.0"
- }
- },
- "node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.699.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.699.0.tgz",
- "integrity": "sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==",
- "dependencies": {
- "@aws-sdk/credential-provider-env": "3.696.0",
- "@aws-sdk/credential-provider-http": "3.696.0",
- "@aws-sdk/credential-provider-ini": "3.699.0",
- "@aws-sdk/credential-provider-process": "3.696.0",
- "@aws-sdk/credential-provider-sso": "3.699.0",
- "@aws-sdk/credential-provider-web-identity": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/credential-provider-imds": "^3.2.6",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/shared-ini-file-loader": "^3.1.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz",
- "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==",
- "dependencies": {
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/shared-ini-file-loader": "^3.1.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.699.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.699.0.tgz",
- "integrity": "sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==",
- "dependencies": {
- "@aws-sdk/client-sso": "3.696.0",
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/token-providers": "3.699.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/shared-ini-file-loader": "^3.1.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz",
- "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==",
- "dependencies": {
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "@aws-sdk/client-sts": "^3.696.0"
- }
- },
- "node_modules/@aws-sdk/middleware-host-header": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz",
- "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-logger": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz",
- "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-recursion-detection": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz",
- "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-user-agent": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz",
- "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==",
- "dependencies": {
- "@aws-sdk/core": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@aws-sdk/util-endpoints": "3.696.0",
- "@smithy/core": "^2.5.3",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/region-config-resolver": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz",
- "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/types": "^3.7.1",
- "@smithy/util-config-provider": "^3.0.0",
- "@smithy/util-middleware": "^3.0.10",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/token-providers": {
- "version": "3.699.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.699.0.tgz",
- "integrity": "sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/property-provider": "^3.1.9",
- "@smithy/shared-ini-file-loader": "^3.1.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "@aws-sdk/client-sso-oidc": "^3.699.0"
- }
- },
- "node_modules/@aws-sdk/types": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz",
- "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/util-endpoints": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz",
- "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/types": "^3.7.1",
- "@smithy/util-endpoints": "^2.1.6",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/util-locate-window": {
- "version": "3.693.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz",
- "integrity": "sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@aws-sdk/util-user-agent-browser": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz",
- "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==",
- "dependencies": {
- "@aws-sdk/types": "3.696.0",
- "@smithy/types": "^3.7.1",
- "bowser": "^2.11.0",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@aws-sdk/util-user-agent-node": {
- "version": "3.696.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz",
- "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==",
- "dependencies": {
- "@aws-sdk/middleware-user-agent": "3.696.0",
- "@aws-sdk/types": "3.696.0",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "aws-crt": ">=1.0.0"
- },
- "peerDependenciesMeta": {
- "aws-crt": {
- "optional": true
- }
+ "node": ">=6.0.0"
}
},
"node_modules/@babel/code-frame": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+ "dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.25.9",
"js-tokens": "^4.0.0",
@@ -687,26 +46,585 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
- "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "node_modules/@babel/compat-data": {
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
+ "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@google-cloud/local-auth": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@google-cloud/local-auth/-/local-auth-3.0.1.tgz",
- "integrity": "sha512-YJ3GFbksfHyEarbVHPSCzhKpjbnlAhdzg2SEf79l6ODukrSM1qUOqfopY232Xkw26huKSndyzmJz+A6b2WYn7Q==",
+ "node_modules/@babel/core": {
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
+ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "arrify": "^2.0.1",
- "google-auth-library": "^9.0.0",
- "open": "^7.0.3",
- "server-destroy": "^1.0.1"
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.10",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.10",
+ "@babel/parser": "^7.26.10",
+ "@babel/template": "^7.26.9",
+ "@babel/traverse": "^7.26.10",
+ "@babel/types": "^7.26.10",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/core/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz",
+ "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz",
+ "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.26.8",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
+ "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
+ "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
+ "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.27.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+ "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
+ "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
+ "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
+ "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz",
+ "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.27.0",
+ "@babel/parser": "^7.27.0",
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/types": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
+ "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@isaacs/cliui": {
@@ -805,6 +723,504 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz",
+ "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/console/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz",
+ "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/reporters": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.7.0",
+ "jest-config": "^29.7.0",
+ "jest-haste-map": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-resolve-dependencies": "^29.7.0",
+ "jest-runner": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "jest-watcher": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/core/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@jest/environment": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
+ "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz",
+ "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^29.7.0",
+ "jest-snapshot": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
+ "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-get-type": "^29.6.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
+ "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@sinonjs/fake-timers": "^10.0.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.7.0",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
+ "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/expect": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "jest-mock": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz",
+ "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^6.0.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/reporters/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
+ "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz",
+ "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
+ "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "^29.7.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
+ "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.2"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
"node_modules/@modelcontextprotocol/sdk": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.5.0.tgz",
@@ -815,18 +1231,6 @@
"zod": "^3.23.8"
}
},
- "node_modules/@modelcontextprotocol/server-aws-kb-retrieval": {
- "resolved": "src/aws-kb-retrieval-server",
- "link": true
- },
- "node_modules/@modelcontextprotocol/server-brave-search": {
- "resolved": "src/brave-search",
- "link": true
- },
- "node_modules/@modelcontextprotocol/server-everart": {
- "resolved": "src/everart",
- "link": true
- },
"node_modules/@modelcontextprotocol/server-everything": {
"resolved": "src/everything",
"link": true
@@ -835,46 +1239,14 @@
"resolved": "src/filesystem",
"link": true
},
- "node_modules/@modelcontextprotocol/server-gdrive": {
- "resolved": "src/gdrive",
- "link": true
- },
- "node_modules/@modelcontextprotocol/server-github": {
- "resolved": "src/github",
- "link": true
- },
- "node_modules/@modelcontextprotocol/server-gitlab": {
- "resolved": "src/gitlab",
- "link": true
- },
- "node_modules/@modelcontextprotocol/server-google-maps": {
- "resolved": "src/google-maps",
- "link": true
- },
"node_modules/@modelcontextprotocol/server-memory": {
"resolved": "src/memory",
"link": true
},
- "node_modules/@modelcontextprotocol/server-postgres": {
- "resolved": "src/postgres",
- "link": true
- },
- "node_modules/@modelcontextprotocol/server-puppeteer": {
- "resolved": "src/puppeteer",
- "link": true
- },
- "node_modules/@modelcontextprotocol/server-redis": {
- "resolved": "src/redis",
- "link": true
- },
"node_modules/@modelcontextprotocol/server-sequential-thinking": {
"resolved": "src/sequentialthinking",
"link": true
},
- "node_modules/@modelcontextprotocol/server-slack": {
- "resolved": "src/slack",
- "link": true
- },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -885,688 +1257,106 @@
"node": ">=14"
}
},
- "node_modules/@puppeteer/browsers": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.1.tgz",
- "integrity": "sha512-0kdAbmic3J09I6dT8e9vE2JOCSt13wHCW5x/ly8TSt2bDtuIWe2TgLZZDHdcziw9AVCzflMAXCrVyRIhIs44Ng==",
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
- "debug": "^4.3.7",
- "extract-zip": "^2.0.1",
- "progress": "^2.0.3",
- "proxy-agent": "^6.4.0",
- "semver": "^7.6.3",
- "tar-fs": "^3.0.6",
- "unbzip2-stream": "^1.4.3",
- "yargs": "^17.7.2"
- },
- "bin": {
- "browsers": "lib/cjs/main-cli.js"
- },
- "engines": {
- "node": ">=18"
+ "type-detect": "4.0.8"
}
},
- "node_modules/@puppeteer/browsers/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
+ "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "@sinonjs/commons": "^3.0.0"
}
},
- "node_modules/@puppeteer/browsers/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/@redis/bloom": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
- "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
- "license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/@redis/client": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz",
- "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==",
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "cluster-key-slot": "1.1.2",
- "generic-pool": "3.9.0",
- "yallist": "4.0.0"
- },
- "engines": {
- "node": ">=14"
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
}
},
- "node_modules/@redis/graph": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
- "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
+ "dependencies": {
+ "@babel/types": "^7.0.0"
}
},
- "node_modules/@redis/json": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
- "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
}
},
- "node_modules/@redis/search": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
- "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
+ "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
+ "dev": true,
"license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@redis/time-series": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
- "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
- "license": "MIT",
- "peerDependencies": {
- "@redis/client": "^1.0.0"
- }
- },
- "node_modules/@smithy/abort-controller": {
- "version": "3.1.8",
- "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.8.tgz",
- "integrity": "sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ==",
"dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
+ "@babel/types": "^7.20.7"
}
},
- "node_modules/@smithy/config-resolver": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.12.tgz",
- "integrity": "sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ==",
- "dependencies": {
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/types": "^3.7.1",
- "@smithy/util-config-provider": "^3.0.0",
- "@smithy/util-middleware": "^3.0.10",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/core": {
- "version": "2.5.4",
- "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.4.tgz",
- "integrity": "sha512-iFh2Ymn2sCziBRLPuOOxRPkuCx/2gBdXtBGuCUFLUe6bWYjKnhHyIPqGeNkLZ5Aco/5GjebRTBFiWID3sDbrKw==",
- "dependencies": {
- "@smithy/middleware-serde": "^3.0.10",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/types": "^3.7.1",
- "@smithy/util-body-length-browser": "^3.0.0",
- "@smithy/util-middleware": "^3.0.10",
- "@smithy/util-stream": "^3.3.1",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/credential-provider-imds": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz",
- "integrity": "sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ==",
- "dependencies": {
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/property-provider": "^3.1.10",
- "@smithy/types": "^3.7.1",
- "@smithy/url-parser": "^3.0.10",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/eventstream-codec": {
- "version": "3.1.9",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.9.tgz",
- "integrity": "sha512-F574nX0hhlNOjBnP+noLtsPFqXnWh2L0+nZKCwcu7P7J8k+k+rdIDs+RMnrMwrzhUE4mwMgyN0cYnEn0G8yrnQ==",
- "dependencies": {
- "@aws-crypto/crc32": "5.2.0",
- "@smithy/types": "^3.7.1",
- "@smithy/util-hex-encoding": "^3.0.0",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@smithy/eventstream-serde-browser": {
- "version": "3.0.13",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.13.tgz",
- "integrity": "sha512-Nee9m+97o9Qj6/XeLz2g2vANS2SZgAxV4rDBMKGHvFJHU/xz88x2RwCkwsvEwYjSX4BV1NG1JXmxEaDUzZTAtw==",
- "dependencies": {
- "@smithy/eventstream-serde-universal": "^3.0.12",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/eventstream-serde-config-resolver": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.10.tgz",
- "integrity": "sha512-K1M0x7P7qbBUKB0UWIL5KOcyi6zqV5mPJoL0/o01HPJr0CSq3A9FYuJC6e11EX6hR8QTIR++DBiGrYveOu6trw==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/eventstream-serde-node": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.12.tgz",
- "integrity": "sha512-kiZymxXvZ4tnuYsPSMUHe+MMfc4FTeFWJIc0Q5wygJoUQM4rVHNghvd48y7ppuulNMbuYt95ah71pYc2+o4JOA==",
- "dependencies": {
- "@smithy/eventstream-serde-universal": "^3.0.12",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/eventstream-serde-universal": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.12.tgz",
- "integrity": "sha512-1i8ifhLJrOZ+pEifTlF0EfZzMLUGQggYQ6WmZ4d5g77zEKf7oZ0kvh1yKWHPjofvOwqrkwRDVuxuYC8wVd662A==",
- "dependencies": {
- "@smithy/eventstream-codec": "^3.1.9",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/fetch-http-handler": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz",
- "integrity": "sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA==",
- "dependencies": {
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/querystring-builder": "^3.0.10",
- "@smithy/types": "^3.7.1",
- "@smithy/util-base64": "^3.0.0",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@smithy/hash-node": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.10.tgz",
- "integrity": "sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "@smithy/util-buffer-from": "^3.0.0",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/invalid-dependency": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz",
- "integrity": "sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@smithy/is-array-buffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz",
- "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/middleware-content-length": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz",
- "integrity": "sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ==",
- "dependencies": {
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/middleware-endpoint": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.4.tgz",
- "integrity": "sha512-TybiW2LA3kYVd3e+lWhINVu1o26KJbBwOpADnf0L4x/35vLVica77XVR5hvV9+kWeTGeSJ3IHTcYxbRxlbwhsg==",
- "dependencies": {
- "@smithy/core": "^2.5.4",
- "@smithy/middleware-serde": "^3.0.10",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/shared-ini-file-loader": "^3.1.11",
- "@smithy/types": "^3.7.1",
- "@smithy/url-parser": "^3.0.10",
- "@smithy/util-middleware": "^3.0.10",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/middleware-retry": {
- "version": "3.0.28",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.28.tgz",
- "integrity": "sha512-vK2eDfvIXG1U64FEUhYxoZ1JSj4XFbYWkK36iz02i3pFwWiDz1Q7jKhGTBCwx/7KqJNk4VS7d7cDLXFOvP7M+g==",
- "dependencies": {
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/service-error-classification": "^3.0.10",
- "@smithy/smithy-client": "^3.4.5",
- "@smithy/types": "^3.7.1",
- "@smithy/util-middleware": "^3.0.10",
- "@smithy/util-retry": "^3.0.10",
- "tslib": "^2.6.2",
- "uuid": "^9.0.1"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/middleware-serde": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz",
- "integrity": "sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/middleware-stack": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz",
- "integrity": "sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/node-config-provider": {
- "version": "3.1.11",
- "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz",
- "integrity": "sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw==",
- "dependencies": {
- "@smithy/property-provider": "^3.1.10",
- "@smithy/shared-ini-file-loader": "^3.1.11",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/node-http-handler": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz",
- "integrity": "sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg==",
- "dependencies": {
- "@smithy/abort-controller": "^3.1.8",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/querystring-builder": "^3.0.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/property-provider": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.10.tgz",
- "integrity": "sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/protocol-http": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.7.tgz",
- "integrity": "sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/querystring-builder": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz",
- "integrity": "sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "@smithy/util-uri-escape": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/querystring-parser": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz",
- "integrity": "sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/service-error-classification": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz",
- "integrity": "sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ==",
- "dependencies": {
- "@smithy/types": "^3.7.1"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/shared-ini-file-loader": {
- "version": "3.1.11",
- "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz",
- "integrity": "sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/signature-v4": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.3.tgz",
- "integrity": "sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ==",
- "dependencies": {
- "@smithy/is-array-buffer": "^3.0.0",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/types": "^3.7.1",
- "@smithy/util-hex-encoding": "^3.0.0",
- "@smithy/util-middleware": "^3.0.10",
- "@smithy/util-uri-escape": "^3.0.0",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/smithy-client": {
- "version": "3.4.5",
- "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.5.tgz",
- "integrity": "sha512-k0sybYT9zlP79sIKd1XGm4TmK0AS1nA2bzDHXx7m0nGi3RQ8dxxQUs4CPkSmQTKAo+KF9aINU3KzpGIpV7UoMw==",
- "dependencies": {
- "@smithy/core": "^2.5.4",
- "@smithy/middleware-endpoint": "^3.2.4",
- "@smithy/middleware-stack": "^3.0.10",
- "@smithy/protocol-http": "^4.1.7",
- "@smithy/types": "^3.7.1",
- "@smithy/util-stream": "^3.3.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/types": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.1.tgz",
- "integrity": "sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/url-parser": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.10.tgz",
- "integrity": "sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ==",
- "dependencies": {
- "@smithy/querystring-parser": "^3.0.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@smithy/util-base64": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz",
- "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==",
- "dependencies": {
- "@smithy/util-buffer-from": "^3.0.0",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-body-length-browser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz",
- "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==",
- "dependencies": {
- "tslib": "^2.6.2"
- }
- },
- "node_modules/@smithy/util-body-length-node": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz",
- "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-buffer-from": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz",
- "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==",
- "dependencies": {
- "@smithy/is-array-buffer": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-config-provider": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz",
- "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-defaults-mode-browser": {
- "version": "3.0.28",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.28.tgz",
- "integrity": "sha512-6bzwAbZpHRFVJsOztmov5PGDmJYsbNSoIEfHSJJyFLzfBGCCChiO3od9k7E/TLgrCsIifdAbB9nqbVbyE7wRUw==",
- "dependencies": {
- "@smithy/property-provider": "^3.1.10",
- "@smithy/smithy-client": "^3.4.5",
- "@smithy/types": "^3.7.1",
- "bowser": "^2.11.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/@smithy/util-defaults-mode-node": {
- "version": "3.0.28",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.28.tgz",
- "integrity": "sha512-78ENJDorV1CjOQselGmm3+z7Yqjj5HWCbjzh0Ixuq736dh1oEnD9sAttSBNSLlpZsX8VQnmERqA2fEFlmqWn8w==",
- "dependencies": {
- "@smithy/config-resolver": "^3.0.12",
- "@smithy/credential-provider-imds": "^3.2.7",
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/property-provider": "^3.1.10",
- "@smithy/smithy-client": "^3.4.5",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/@smithy/util-endpoints": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz",
- "integrity": "sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA==",
- "dependencies": {
- "@smithy/node-config-provider": "^3.1.11",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-hex-encoding": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz",
- "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-middleware": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.10.tgz",
- "integrity": "sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A==",
- "dependencies": {
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-retry": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.10.tgz",
- "integrity": "sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA==",
- "dependencies": {
- "@smithy/service-error-classification": "^3.0.10",
- "@smithy/types": "^3.7.1",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-stream": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.1.tgz",
- "integrity": "sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw==",
- "dependencies": {
- "@smithy/fetch-http-handler": "^4.1.1",
- "@smithy/node-http-handler": "^3.3.1",
- "@smithy/types": "^3.7.1",
- "@smithy/util-base64": "^3.0.0",
- "@smithy/util-buffer-from": "^3.0.0",
- "@smithy/util-hex-encoding": "^3.0.0",
- "@smithy/util-utf8": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-uri-escape": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz",
- "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==",
- "dependencies": {
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@smithy/util-utf8": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz",
- "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==",
- "dependencies": {
- "@smithy/util-buffer-from": "^3.0.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/@tootallnate/quickjs-emscripten": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
- "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="
- },
"node_modules/@types/body-parser": {
"version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
@@ -1616,12 +1406,60 @@
"@types/send": "*"
}
},
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.9",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
+ "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/http-errors": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
"dev": true
},
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "29.5.14",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz",
+ "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^29.0.0",
+ "pretty-format": "^29.0.0"
+ }
+ },
"node_modules/@types/mime": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
@@ -1639,32 +1477,12 @@
"version": "22.10.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
"integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.20.0"
}
},
- "node_modules/@types/node-fetch": {
- "version": "2.6.12",
- "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
- "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "form-data": "^4.0.0"
- }
- },
- "node_modules/@types/pg": {
- "version": "8.11.10",
- "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.10.tgz",
- "integrity": "sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg==",
- "dev": true,
- "dependencies": {
- "@types/node": "*",
- "pg-protocol": "*",
- "pg-types": "^4.0.1"
- }
- },
"node_modules/@types/qs": {
"version": "6.9.17",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz",
@@ -1677,15 +1495,6 @@
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
"dev": true
},
- "node_modules/@types/redis": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/@types/redis/-/redis-4.0.10.tgz",
- "integrity": "sha512-7CLy5b5fzzEGVcOccgZjoMlNpPhX6d10jEeRy2YWbFuaMNrSPc9ExRsMYsd+0VxvEHucf4EWx24Ja7cSU1FGUA==",
- "license": "MIT",
- "dependencies": {
- "redis": "*"
- }
- },
"node_modules/@types/send": {
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
@@ -1707,6 +1516,13 @@
"@types/send": "*"
}
},
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/yargs": {
"version": "17.0.33",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
@@ -1722,15 +1538,6 @@
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
"dev": true
},
- "node_modules/@types/yauzl": {
- "version": "2.10.3",
- "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
- "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
- "optional": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -1743,37 +1550,63 @@
"node": ">= 0.6"
}
},
- "node_modules/agent-base": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
- "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
- "dependencies": {
- "debug": "^4.3.4"
+ "node_modules/acorn": {
+ "version": "8.14.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
},
"engines": {
- "node": ">= 14"
+ "node": ">=0.4.0"
}
},
- "node_modules/agent-base/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "ms": "^2.1.3"
+ "acorn": "^8.11.0"
},
"engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "node": ">=0.4.0"
}
},
- "node_modules/agent-base/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"node_modules/ansi-regex": {
"version": "5.0.1",
@@ -1797,145 +1630,187 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
- "node_modules/arrify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
- "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/babel-jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
+ "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/transform": "^29.7.0",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.6.3",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
+ }
+ },
+ "node_modules/babel-jest/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
"engines": {
"node": ">=8"
}
},
- "node_modules/ast-types": {
- "version": "0.13.4",
- "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
- "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
+ "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
- "tslib": "^2.0.1"
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^6.3.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "license": "MIT"
+ "node_modules/babel-plugin-istanbul/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
},
- "node_modules/axios": {
- "version": "1.7.8",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz",
- "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==",
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
+ "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "follow-redirects": "^1.15.6",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/b4a": {
- "version": "1.6.7",
- "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
- "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg=="
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
+ "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
+ "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^29.6.3",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
- "node_modules/bare-events": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz",
- "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==",
- "optional": true
- },
- "node_modules/bare-fs": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz",
- "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==",
- "optional": true,
- "dependencies": {
- "bare-events": "^2.0.0",
- "bare-path": "^2.0.0",
- "bare-stream": "^2.0.0"
- }
- },
- "node_modules/bare-os": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz",
- "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==",
- "optional": true
- },
- "node_modules/bare-path": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz",
- "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==",
- "optional": true,
- "dependencies": {
- "bare-os": "^2.1.0"
- }
- },
- "node_modules/bare-stream": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz",
- "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==",
- "optional": true,
- "dependencies": {
- "streamx": "^2.20.0"
- }
- },
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/basic-ftp": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
- "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/big-integer": {
- "version": "1.6.52",
- "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
- "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/bignumber.js": {
- "version": "9.1.2",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
- "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
- "engines": {
- "node": "*"
- }
- },
"node_modules/body-parser": {
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
@@ -1973,22 +1848,6 @@
"node": ">= 0.8"
}
},
- "node_modules/bowser": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
- "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="
- },
- "node_modules/bplist-parser": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
- "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==",
- "dependencies": {
- "big-integer": "^1.6.44"
- },
- "engines": {
- "node": ">= 5.10.0"
- }
- },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1999,56 +1858,82 @@
"concat-map": "0.0.1"
}
},
- "node_modules/buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
+ "dev": true,
"funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
{
"type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
+ "url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
- }
- },
- "node_modules/buffer-crc32": {
- "version": "0.2.13",
- "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
- },
- "node_modules/bundle-name": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
- "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==",
- "dependencies": {
- "run-applescript": "^5.0.0"
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
+ },
+ "bin": {
+ "browserslist": "cli.js"
},
"engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-json-stable-stringify": "2.x"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -2090,10 +1975,42 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
"engines": {
"node": ">=6"
}
},
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001713",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001713.tgz",
+ "integrity": "sha512-wCIWIg+A4Xr7NfhTuHdX+/FKh3+Op3LBbSp2N5Pfx6T/LhdQy3GTyoTg48BReaW/MyMNZAkTadsBtai3ldWK0Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
"node_modules/chalk": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
@@ -2105,19 +2022,39 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/chromium-bidi": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.8.0.tgz",
- "integrity": "sha512-uJydbGdTw0DEUjhoogGveneJVWX/9YuqkWePzMmkBYwtdAqo5d3J/ovNKFr+/2hWXYmYCr6it8mSSTIj6SS6Ug==",
- "dependencies": {
- "mitt": "3.0.1",
- "urlpattern-polyfill": "10.0.0",
- "zod": "3.23.8"
- },
- "peerDependencies": {
- "devtools-protocol": "*"
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
}
},
+ "node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
+ "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -2131,15 +2068,24 @@
"node": ">=12"
}
},
- "node_modules/cluster-key-slot": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
- "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
- "license": "Apache-2.0",
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
}
},
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -2156,18 +2102,6 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2193,6 +2127,13 @@
"node": ">= 0.6"
}
},
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
@@ -2219,31 +2160,52 @@
"node": ">= 0.10"
}
},
- "node_modules/cosmiconfig": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
- "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+ "node_modules/create-jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
+ "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "env-paths": "^2.2.1",
- "import-fresh": "^3.3.0",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.2.0"
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-config": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "prompts": "^2.0.1"
+ },
+ "bin": {
+ "create-jest": "bin/create-jest.js"
},
"engines": {
- "node": ">=14"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/create-jest/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
},
"funding": {
- "url": "https://github.com/sponsors/d-fischer"
- },
- "peerDependencies": {
- "typescript": ">=4.9.5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2258,14 +2220,6 @@
"node": ">= 8"
}
},
- "node_modules/data-uri-to-buffer": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
- "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -2274,69 +2228,29 @@
"ms": "2.0.0"
}
},
- "node_modules/default-browser": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz",
- "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==",
- "dependencies": {
- "bundle-name": "^3.0.0",
- "default-browser-id": "^3.0.0",
- "execa": "^7.1.1",
- "titleize": "^3.0.0"
+ "node_modules/dedent": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
+ "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "babel-plugin-macros": "^3.1.0"
},
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "peerDependenciesMeta": {
+ "babel-plugin-macros": {
+ "optional": true
+ }
}
},
- "node_modules/default-browser-id": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz",
- "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==",
- "dependencies": {
- "bplist-parser": "^0.2.0",
- "untildify": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/define-lazy-prop": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
- "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/degenerator": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
- "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
- "dependencies": {
- "ast-types": "^0.13.4",
- "escodegen": "^2.1.0",
- "esprima": "^4.0.1"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.4.0"
+ "node": ">=0.10.0"
}
},
"node_modules/depd": {
@@ -2356,10 +2270,15 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/devtools-protocol": {
- "version": "0.0.1367902",
- "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz",
- "integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg=="
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/diff": {
"version": "5.2.0",
@@ -2369,15 +2288,14 @@
"node": ">=0.3.1"
}
},
- "node_modules/dotenv": {
- "version": "16.4.6",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.6.tgz",
- "integrity": "sha512-JhcR/+KIjkkjiU8yEpaB/USlzVi3i5whwOjpIRNGi9svKEXZSe+Qp6IWAjFjv+2GViAoDRCUv/QLNziQxsLqDg==",
+ "node_modules/diff-sequences": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://dotenvx.com"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/dunder-proto": {
@@ -2400,19 +2318,47 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"license": "MIT"
},
- "node_modules/ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
- },
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.136",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.136.tgz",
+ "integrity": "sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -2426,26 +2372,11 @@
"node": ">= 0.8"
}
},
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dependencies": {
- "once": "^1.4.0"
- }
- },
- "node_modules/env-paths": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
- "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
"dependencies": {
"is-arrayish": "^0.2.1"
}
@@ -2493,30 +2424,21 @@
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
},
- "node_modules/escodegen": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
- "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
- "dependencies": {
- "esprima": "^4.0.1",
- "estraverse": "^5.2.0",
- "esutils": "^2.0.2"
- },
- "bin": {
- "escodegen": "bin/escodegen.js",
- "esgenerate": "bin/esgenerate.js"
- },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=6.0"
- },
- "optionalDependencies": {
- "source-map": "~0.6.1"
+ "node": ">=8"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
@@ -2525,22 +2447,6 @@
"node": ">=4"
}
},
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@@ -2570,67 +2476,32 @@
"node": ">=18.0.0"
}
},
- "node_modules/everart": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/everart/-/everart-1.2.2.tgz",
- "integrity": "sha512-V3BT+vFxLWAmmh9Qem9LWuolN5DuEIpAh+B6+fRkzi31Sgjo+rKC4YEotTGRcUP1l3TvQFkY1WdyPJV683iCrg==",
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
+ "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "axios": "^1.6.8",
- "dotenv": "^16.4.5",
- "fs-extra": "^11.2.0",
- "lodash": "^4.17.21",
- "uuid": "^9.0.1"
- }
- },
- "node_modules/execa": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz",
- "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.1",
- "human-signals": "^4.3.0",
- "is-stream": "^3.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^5.1.0",
- "onetime": "^6.0.0",
- "signal-exit": "^3.0.7",
- "strip-final-newline": "^3.0.0"
+ "@jest/expect-utils": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0"
},
"engines": {
- "node": "^14.18.0 || ^16.14.0 || >=18.0.0"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/execa/node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/execa/node_modules/is-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
- "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/execa/node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
- },
"node_modules/express": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
@@ -2692,106 +2563,72 @@
"express": "^4.11 || 5 || ^5.0.0-beta.1"
}
},
- "node_modules/extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
},
- "node_modules/extract-zip": {
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "license": "MIT"
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/filelist": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/brace-expansion": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
- "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
- "dependencies": {
- "debug": "^4.1.1",
- "get-stream": "^5.1.0",
- "yauzl": "^2.10.0"
- },
- "bin": {
- "extract-zip": "cli.js"
- },
- "engines": {
- "node": ">= 10.17.0"
- },
- "optionalDependencies": {
- "@types/yauzl": "^2.9.1"
- }
- },
- "node_modules/extract-zip/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/extract-zip/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
- "node_modules/fast-fifo": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
- "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
- },
- "node_modules/fast-xml-parser": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
- "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/NaturalIntelligence"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/naturalintelligence"
- }
- ],
- "dependencies": {
- "strnum": "^1.0.5"
- },
- "bin": {
- "fxparser": "src/cli/cli.js"
- }
- },
- "node_modules/fd-slicer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
- "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
- "dependencies": {
- "pend": "~1.2.0"
- }
- },
- "node_modules/fetch-blob": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
- "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "node-domexception": "^1.0.0",
- "web-streams-polyfill": "^3.0.3"
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": "^12.20 || >= 14.13"
+ "node": ">=10"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/finalhandler": {
@@ -2811,23 +2648,18 @@
"node": ">= 0.8"
}
},
- "node_modules/follow-redirects": {
- "version": "1.15.9",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
- "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "engines": {
- "node": ">=4.0"
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
},
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/foreground-child": {
@@ -2846,32 +2678,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/form-data": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
- "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/formdata-polyfill": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
- "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
- "license": "MIT",
- "dependencies": {
- "fetch-blob": "^3.1.2"
- },
- "engines": {
- "node": ">=12.20.0"
- }
- },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -2888,25 +2694,27 @@
"node": ">= 0.6"
}
},
- "node_modules/fs-extra": {
- "version": "11.2.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
- "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
},
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -2915,40 +2723,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/gaxios": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
- "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
- "dependencies": {
- "extend": "^3.0.2",
- "https-proxy-agent": "^7.0.1",
- "is-stream": "^2.0.0",
- "node-fetch": "^2.6.9",
- "uuid": "^9.0.1"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/gcp-metadata": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
- "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
- "dependencies": {
- "gaxios": "^6.0.0",
- "json-bigint": "^1.0.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/generic-pool": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
- "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 4"
+ "node": ">=6.9.0"
}
},
"node_modules/get-caller-file": {
@@ -2983,6 +2765,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
@@ -2996,55 +2788,6 @@
"node": ">= 0.4"
}
},
- "node_modules/get-stream": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
- "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
- "dependencies": {
- "pump": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/get-uri": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz",
- "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==",
- "dependencies": {
- "basic-ftp": "^5.0.2",
- "data-uri-to-buffer": "^6.0.2",
- "debug": "^4.3.4",
- "fs-extra": "^11.2.0"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/get-uri/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/get-uri/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -3066,48 +2809,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/google-auth-library": {
- "version": "9.15.0",
- "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz",
- "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==",
- "dependencies": {
- "base64-js": "^1.3.0",
- "ecdsa-sig-formatter": "^1.0.11",
- "gaxios": "^6.1.1",
- "gcp-metadata": "^6.1.0",
- "gtoken": "^7.0.0",
- "jws": "^4.0.0"
- },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=14"
- }
- },
- "node_modules/googleapis": {
- "version": "144.0.0",
- "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-144.0.0.tgz",
- "integrity": "sha512-ELcWOXtJxjPX4vsKMh+7V+jZvgPwYMlEhQFiu2sa9Qmt5veX8nwXPksOWGGN6Zk4xCiLygUyaz7xGtcMO+Onxw==",
- "dependencies": {
- "google-auth-library": "^9.0.0",
- "googleapis-common": "^7.0.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/googleapis-common": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.2.0.tgz",
- "integrity": "sha512-/fhDZEJZvOV3X5jmD+fKxMqma5q2Q9nZNSF3kn1F18tpxmA86BcTxAGBQdM0N89Z3bEaIs+HVznSmFJEAmMTjA==",
- "dependencies": {
- "extend": "^3.0.2",
- "gaxios": "^6.0.3",
- "google-auth-library": "^9.7.0",
- "qs": "^6.7.0",
- "url-template": "^2.0.8",
- "uuid": "^9.0.0"
- },
- "engines": {
- "node": ">=14.0.0"
+ "node": ">=4"
}
},
"node_modules/gopd": {
@@ -3125,18 +2834,17 @@
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
},
- "node_modules/gtoken": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
- "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
- "dependencies": {
- "gaxios": "^6.0.0",
- "jws": "^4.0.0"
- },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=14.0.0"
+ "node": ">=8"
}
},
"node_modules/has-symbols": {
@@ -3162,6 +2870,13 @@
"node": ">= 0.4"
}
},
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -3177,80 +2892,6 @@
"node": ">= 0.8"
}
},
- "node_modules/http-proxy-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
- "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/http-proxy-agent/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/http-proxy-agent/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
- "node_modules/https-proxy-agent": {
- "version": "7.0.5",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
- "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
- "dependencies": {
- "agent-base": "^7.0.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/https-proxy-agent/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/https-proxy-agent/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
- "node_modules/human-signals": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
- "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==",
- "engines": {
- "node": ">=14.18.0"
- }
- },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -3262,40 +2903,36 @@
"node": ">=0.10.0"
}
},
- "node_modules/ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "node_modules/import-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
},
"engines": {
- "node": ">=6"
+ "node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -3321,18 +2958,6 @@
"node": ">= 0.10"
}
},
- "node_modules/ip-address": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
- "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
- "dependencies": {
- "jsbn": "1.1.0",
- "sprintf-js": "^1.1.3"
- },
- "engines": {
- "node": ">= 12"
- }
- },
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -3344,7 +2969,8 @@
"node_modules/is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
},
"node_modules/is-core-module": {
"version": "2.15.1",
@@ -3361,20 +2987,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-docker": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
- "bin": {
- "is-docker": "cli.js"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -3383,35 +2995,24 @@
"node": ">=8"
}
},
- "node_modules/is-inside-container": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
- "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
- "dependencies": {
- "is-docker": "^3.0.0"
- },
- "bin": {
- "is-inside-container": "cli.js"
- },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=6"
}
},
- "node_modules/is-inside-container/node_modules/is-docker": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
- "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
- "bin": {
- "is-docker": "cli.js"
- },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=0.12.0"
}
},
"node_modules/is-promise": {
@@ -3424,6 +3025,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
"engines": {
"node": ">=8"
},
@@ -3431,23 +3033,108 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/is-wsl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
- "dependencies": {
- "is-docker": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"license": "ISC"
},
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/jackspeak": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
@@ -3463,86 +3150,1087 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/jake": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.3",
+ "chalk": "^4.0.2",
+ "filelist": "^1.0.4",
+ "minimatch": "^3.1.2"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jake/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
+ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.7.0"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
+ "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^5.0.0",
+ "jest-util": "^29.7.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jest-changed-files/node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz",
+ "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/expect": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^1.0.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.7.0",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.7.0",
+ "pure-rand": "^6.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-cli": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz",
+ "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "create-jest": "^29.7.0",
+ "exit": "^0.1.2",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-cli/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-config": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz",
+ "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "babel-jest": "^29.7.0",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.7.0",
+ "jest-environment-node": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-runner": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-diff": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
+ "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.6.3",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-diff/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-docblock": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
+ "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz",
+ "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-environment-node": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
+ "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-get-type": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
+ "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
+ "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
+ "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
+ "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-message-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
+ "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.6.3",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-mock": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
+ "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
+ "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
+ "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^2.0.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz",
+ "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-regex-util": "^29.6.3",
+ "jest-snapshot": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz",
+ "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/environment": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.7.0",
+ "jest-environment-node": "^29.7.0",
+ "jest-haste-map": "^29.7.0",
+ "jest-leak-detector": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-resolve": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-watcher": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runner/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
+ "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/globals": "^29.7.0",
+ "@jest/source-map": "^29.6.3",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-mock": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runtime/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
+ "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.7.0",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.7.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
+ "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-validate": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
+ "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.6.3",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-validate/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-watcher": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz",
+ "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.7.0",
+ "string-length": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-watcher/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
+ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.7.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
},
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dependencies": {
- "argparse": "^2.0.1"
- },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
"bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsbn": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
- "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
- },
- "node_modules/json-bigint": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
- "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
- "dependencies": {
- "bignumber.js": "^9.0.0"
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
},
- "node_modules/jsonfile": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
- "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "dependencies": {
- "universalify": "^2.0.0"
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
},
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/jwa": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
- "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
- "dependencies": {
- "buffer-equal-constant-time": "1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
}
},
- "node_modules/jws": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
- "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
- "dependencies": {
- "jwa": "^2.0.0",
- "safe-buffer": "^5.0.1"
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
},
- "node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "node_modules/lru-cache": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
- "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
"engines": {
- "node": ">=12"
+ "node": ">=8"
+ }
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tmpl": "1.0.5"
}
},
"node_modules/math-intrinsics": {
@@ -3573,7 +4261,8 @@
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
},
"node_modules/methods": {
"version": "1.1.2",
@@ -3583,6 +4272,20 @@
"node": ">= 0.6"
}
},
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -3613,17 +4316,6 @@
"node": ">= 0.6"
}
},
- "node_modules/mimic-fn": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
- "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -3654,16 +4346,18 @@
"node": ">=16 || 14 >=14.17"
}
},
- "node_modules/mitt": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
- "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
- },
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -3672,75 +4366,28 @@
"node": ">= 0.6"
}
},
- "node_modules/netmask": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
- "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
- "engines": {
- "node": ">= 0.4.0"
- }
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/node-domexception": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
- "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "github",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
+ "node_modules/node-releases": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=10.5.0"
- }
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/npm-run-path": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
- "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
- "dependencies": {
- "path-key": "^4.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm-run-path/node_modules/path-key": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
- "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=0.10.0"
}
},
"node_modules/object-assign": {
@@ -3763,12 +4410,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/obuf": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
- "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
- "dev": true
- },
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -3788,84 +4429,59 @@
"wrappy": "1"
}
},
- "node_modules/onetime": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
- "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "mimic-fn": "^4.0.0"
+ "yocto-queue": "^0.1.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/open": {
- "version": "7.4.2",
- "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
- "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "is-docker": "^2.0.0",
- "is-wsl": "^2.1.1"
+ "p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/pac-proxy-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz",
- "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==",
- "dependencies": {
- "@tootallnate/quickjs-emscripten": "^0.23.0",
- "agent-base": "^7.0.2",
- "debug": "^4.3.4",
- "get-uri": "^6.0.1",
- "http-proxy-agent": "^7.0.0",
- "https-proxy-agent": "^7.0.5",
- "pac-resolver": "^7.0.1",
- "socks-proxy-agent": "^8.0.4"
- },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">= 14"
- }
- },
- "node_modules/pac-proxy-agent/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/pac-proxy-agent/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
- "node_modules/pac-resolver": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
- "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
- "dependencies": {
- "degenerator": "^5.0.0",
- "netmask": "^2.0.2"
- },
- "engines": {
- "node": ">= 14"
+ "node": ">=6"
}
},
"node_modules/package-json-from-dist": {
@@ -3874,21 +4490,11 @@
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0"
},
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -3910,6 +4516,16 @@
"node": ">= 0.8"
}
},
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -3962,219 +4578,88 @@
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT"
},
- "node_modules/pend": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
- },
- "node_modules/pg": {
- "version": "8.13.1",
- "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.1.tgz",
- "integrity": "sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==",
- "dependencies": {
- "pg-connection-string": "^2.7.0",
- "pg-pool": "^3.7.0",
- "pg-protocol": "^1.7.0",
- "pg-types": "^2.1.0",
- "pgpass": "1.x"
- },
- "engines": {
- "node": ">= 8.0.0"
- },
- "optionalDependencies": {
- "pg-cloudflare": "^1.1.1"
- },
- "peerDependencies": {
- "pg-native": ">=3.0.1"
- },
- "peerDependenciesMeta": {
- "pg-native": {
- "optional": true
- }
- }
- },
- "node_modules/pg-cloudflare": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
- "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
- "optional": true
- },
- "node_modules/pg-connection-string": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz",
- "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA=="
- },
- "node_modules/pg-int8": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
- "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/pg-numeric": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz",
- "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/pg-pool": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz",
- "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==",
- "peerDependencies": {
- "pg": ">=8.0"
- }
- },
- "node_modules/pg-protocol": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz",
- "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ=="
- },
- "node_modules/pg-types": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz",
- "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==",
- "dev": true,
- "dependencies": {
- "pg-int8": "1.0.1",
- "pg-numeric": "1.0.2",
- "postgres-array": "~3.0.1",
- "postgres-bytea": "~3.0.0",
- "postgres-date": "~2.1.0",
- "postgres-interval": "^3.0.0",
- "postgres-range": "^1.1.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/pg/node_modules/pg-types": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
- "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
- "dependencies": {
- "pg-int8": "1.0.1",
- "postgres-array": "~2.0.0",
- "postgres-bytea": "~1.0.0",
- "postgres-date": "~1.0.4",
- "postgres-interval": "^1.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/pg/node_modules/postgres-array": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
- "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/pg/node_modules/postgres-bytea": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
- "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pg/node_modules/postgres-date": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
- "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pg/node_modules/postgres-interval": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
- "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
- "dependencies": {
- "xtend": "^4.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pgpass": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
- "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
- "dependencies": {
- "split2": "^4.1.0"
- }
- },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true
},
- "node_modules/pkce-challenge": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-4.1.0.tgz",
- "integrity": "sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==",
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=16.20.0"
- }
- },
- "node_modules/postgres-array": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz",
- "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/postgres-bytea": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz",
- "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==",
- "dev": true,
- "dependencies": {
- "obuf": "~1.1.2"
+ "node": ">=8.6"
},
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 6"
}
},
- "node_modules/postgres-date": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz",
- "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==",
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
"engines": {
- "node": ">=12"
+ "node": ">=8"
}
},
- "node_modules/postgres-interval": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz",
- "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==",
+ "node_modules/pretty-format": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
"engines": {
- "node": ">=12"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/postgres-range": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz",
- "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==",
- "dev": true
- },
- "node_modules/progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=0.4.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
"node_modules/proxy-addr": {
@@ -4189,115 +4674,31 @@
"node": ">= 0.10"
}
},
- "node_modules/proxy-agent": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz",
- "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==",
- "dependencies": {
- "agent-base": "^7.0.2",
- "debug": "^4.3.4",
- "http-proxy-agent": "^7.0.1",
- "https-proxy-agent": "^7.0.3",
- "lru-cache": "^7.14.1",
- "pac-proxy-agent": "^7.0.1",
- "proxy-from-env": "^1.1.0",
- "socks-proxy-agent": "^8.0.2"
- },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
"engines": {
- "node": ">= 14"
+ "node": ">=6"
}
},
- "node_modules/proxy-agent/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
+ "node_modules/pure-rand": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
+ "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
}
- }
- },
- "node_modules/proxy-agent/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
- },
- "node_modules/pump": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
- "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "node_modules/puppeteer": {
- "version": "23.8.0",
- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.8.0.tgz",
- "integrity": "sha512-MFWDMWoCcOpwNwQIjA9gPKWrEUbj8bLCzkK56w5lZPMUT6wK4FfpgOEPxKffVmXEMYMZzgcjxzqy15b/Q1ibaw==",
- "hasInstallScript": true,
- "dependencies": {
- "@puppeteer/browsers": "2.4.1",
- "chromium-bidi": "0.8.0",
- "cosmiconfig": "^9.0.0",
- "devtools-protocol": "0.0.1367902",
- "puppeteer-core": "23.8.0",
- "typed-query-selector": "^2.12.0"
- },
- "bin": {
- "puppeteer": "lib/cjs/puppeteer/node/cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/puppeteer-core": {
- "version": "23.8.0",
- "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.8.0.tgz",
- "integrity": "sha512-c2ymGN2M//We7pC+JhP2dE/g4+qnT89BO+EMSZyJmecN3DN6RNqErA7eH7DrWoNIcU75r2nP4VHa4pswAL6NVg==",
- "dependencies": {
- "@puppeteer/browsers": "2.4.1",
- "chromium-bidi": "0.8.0",
- "debug": "^4.3.7",
- "devtools-protocol": "0.0.1367902",
- "typed-query-selector": "^2.12.0",
- "ws": "^8.18.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/puppeteer-core/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/puppeteer-core/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ ],
+ "license": "MIT"
},
"node_modules/qs": {
"version": "6.13.0",
@@ -4313,11 +4714,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/queue-tick": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
- "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
- },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -4351,6 +4747,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
@@ -4363,10 +4766,6 @@
"node": ">= 0.10"
}
},
- "node_modules/redis": {
- "resolved": "src/redis",
- "link": true
- },
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -4392,20 +4791,47 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
"engines": {
- "node": ">=4"
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-cwd/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve.exports": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz",
+ "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/router": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.1.0.tgz",
- "integrity": "sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"license": "MIT",
"dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
"is-promise": "^4.0.0",
"parseurl": "^1.3.3",
"path-to-regexp": "^8.0.0"
@@ -4414,6 +4840,29 @@
"node": ">= 18"
}
},
+ "node_modules/router/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/router/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
"node_modules/router/node_modules/path-to-regexp": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
@@ -4423,107 +4872,6 @@
"node": ">=16"
}
},
- "node_modules/run-applescript": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz",
- "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==",
- "dependencies": {
- "execa": "^5.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/run-applescript/node_modules/execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/run-applescript/node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/run-applescript/node_modules/human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
- "engines": {
- "node": ">=10.17.0"
- }
- },
- "node_modules/run-applescript/node_modules/mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/run-applescript/node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dependencies": {
- "path-key": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/run-applescript/node_modules/onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dependencies": {
- "mimic-fn": "^2.1.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/run-applescript/node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
- },
- "node_modules/run-applescript/node_modules/strip-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -4552,6 +4900,7 @@
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
"bin": {
"semver": "bin/semver.js"
},
@@ -4609,11 +4958,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/server-destroy": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz",
- "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ=="
- },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -4757,83 +5101,55 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/smart-buffer": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
- "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
- "engines": {
- "node": ">= 6.0.0",
- "npm": ">= 3.0.0"
- }
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/socks": {
- "version": "2.8.3",
- "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
- "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
- "dependencies": {
- "ip-address": "^9.0.5",
- "smart-buffer": "^4.2.0"
- },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">= 10.0.0",
- "npm": ">= 3.0.0"
+ "node": ">=8"
}
},
- "node_modules/socks-proxy-agent": {
- "version": "8.0.4",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz",
- "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==",
- "dependencies": {
- "agent-base": "^7.1.1",
- "debug": "^4.3.4",
- "socks": "^2.8.3"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/socks-proxy-agent/node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/socks-proxy-agent/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "optional": true,
+ "dev": true,
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/split2": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
- "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
- "engines": {
- "node": ">= 10.x"
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
}
},
- "node_modules/sprintf-js": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
- "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
},
"node_modules/statuses": {
"version": "2.0.1",
@@ -4843,17 +5159,18 @@
"node": ">= 0.8"
}
},
- "node_modules/streamx": {
- "version": "2.20.2",
- "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.2.tgz",
- "integrity": "sha512-aDGDLU+j9tJcUdPGOaHmVF1u/hhI+CsGkT02V3OKlHDV7IukOI+nTWAGkiZEKCO35rWN1wIr4tS7YFr1f4qSvA==",
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "fast-fifo": "^1.3.2",
- "queue-tick": "^1.0.1",
- "text-decoder": "^1.1.0"
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
},
- "optionalDependencies": {
- "bare-events": "^2.2.0"
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/string-width": {
@@ -4908,21 +5225,41 @@
"node": ">=8"
}
},
- "node_modules/strip-final-newline": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
- "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/strnum": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
- "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
@@ -4936,48 +5273,39 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/tar-fs": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz",
- "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==",
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "pump": "^3.0.0",
- "tar-stream": "^3.1.5"
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
},
- "optionalDependencies": {
- "bare-fs": "^2.1.1",
- "bare-path": "^2.1.0"
- }
- },
- "node_modules/tar-stream": {
- "version": "3.1.7",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
- "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
- "dependencies": {
- "b4a": "^1.6.4",
- "fast-fifo": "^1.2.0",
- "streamx": "^2.15.0"
- }
- },
- "node_modules/text-decoder": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz",
- "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ=="
- },
- "node_modules/through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
- },
- "node_modules/titleize": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
- "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==",
"engines": {
- "node": ">=12"
+ "node": ">=8"
+ }
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": ">=8.0"
}
},
"node_modules/toidentifier": {
@@ -4988,15 +5316,158 @@
"node": ">=0.6"
}
},
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ "node_modules/ts-jest": {
+ "version": "29.3.2",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.2.tgz",
+ "integrity": "sha512-bJJkrWc6PjFVz5g2DGCNUo8z7oFEYaz1xP1NpeDU7KNLMWPpEyV8Chbpkn8xjzgRDpQhnGMyvyldoL7h8JXyug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bs-logger": "^0.2.6",
+ "ejs": "^3.1.10",
+ "fast-json-stable-stringify": "^2.1.0",
+ "jest-util": "^29.0.0",
+ "json5": "^2.2.3",
+ "lodash.memoize": "^4.1.2",
+ "make-error": "^1.3.6",
+ "semver": "^7.7.1",
+ "type-fest": "^4.39.1",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "ts-jest": "cli.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7.0.0-beta.0 <8",
+ "@jest/transform": "^29.0.0",
+ "@jest/types": "^29.0.0",
+ "babel-jest": "^29.0.0",
+ "jest": "^29.0.0",
+ "typescript": ">=4.3 <6"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@jest/transform": {
+ "optional": true
+ },
+ "@jest/types": {
+ "optional": true
+ },
+ "babel-jest": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ }
+ }
},
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
+ "node_modules/ts-jest/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ts-jest/node_modules/type-fest": {
+ "version": "4.39.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.1.tgz",
+ "integrity": "sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node/node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"node_modules/type-is": {
"version": "1.6.18",
@@ -5010,16 +5481,11 @@
"node": ">= 0.6"
}
},
- "node_modules/typed-query-selector": {
- "version": "2.12.0",
- "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz",
- "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg=="
- },
"node_modules/typescript": {
"version": "5.8.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
- "devOptional": true,
+ "dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -5029,35 +5495,13 @@
"node": ">=14.17"
}
},
- "node_modules/unbzip2-stream": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
- "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
- "dependencies": {
- "buffer": "^5.2.1",
- "through": "^2.3.8"
- }
- },
"node_modules/undici-types": {
"version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/universal-user-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
- "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
- "license": "ISC"
- },
- "node_modules/universalify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
- "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
- "engines": {
- "node": ">= 10.0.0"
- }
- },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -5066,23 +5510,45 @@
"node": ">= 0.8"
}
},
- "node_modules/untildify": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
- "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
- "engines": {
- "node": ">=8"
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
}
},
- "node_modules/url-template": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
- "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw=="
- },
- "node_modules/urlpattern-polyfill": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz",
- "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg=="
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
},
"node_modules/utils-merge": {
"version": "1.0.1",
@@ -5092,16 +5558,26 @@
"node": ">= 0.4.0"
}
},
- "node_modules/uuid": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
- "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "bin": {
- "uuid": "dist/bin/uuid"
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
}
},
"node_modules/vary": {
@@ -5112,27 +5588,14 @@
"node": ">= 0.8"
}
},
- "node_modules/web-streams-polyfill": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
- "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
+ "makeerror": "1.0.12"
}
},
"node_modules/which": {
@@ -5189,33 +5652,26 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
- "node_modules/ws": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
- "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+ "node_modules/write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ },
"engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
- "node_modules/xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "engines": {
- "node": ">=0.4"
- }
+ "node_modules/write-file-atomic/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/y18n": {
"version": "5.0.8",
@@ -5225,12 +5681,6 @@
"node": ">=10"
}
},
- "node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC"
- },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@@ -5256,13 +5706,27 @@
"node": ">=12"
}
},
- "node_modules/yauzl": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
- "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
- "dependencies": {
- "buffer-crc32": "~0.2.3",
- "fd-slicer": "~1.1.0"
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zod": {
@@ -5273,17 +5737,10 @@
"url": "https://github.com/sponsors/colinhacks"
}
},
- "node_modules/zod-to-json-schema": {
- "version": "3.23.5",
- "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.5.tgz",
- "integrity": "sha512-5wlSS0bXfF/BrL4jPAbz9da5hDlDptdEppYfe+x4eIJ7jioqKG9uUxOwPzqof09u/XeVdrgFu29lZi+8XNDJtA==",
- "peerDependencies": {
- "zod": "^3.23.3"
- }
- },
"src/aws-kb-retrieval-server": {
"name": "@modelcontextprotocol/server-aws-kb-retrieval",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@aws-sdk/client-bedrock-agent-runtime": "^3.0.0",
@@ -5301,6 +5758,7 @@
"src/brave-search": {
"name": "@modelcontextprotocol/server-brave-search",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1"
@@ -5314,16 +5772,6 @@
"typescript": "^5.6.2"
}
},
- "src/brave-search/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
"src/duckduckgo": {
"name": "@modelcontextprotocol/server-duckduckgo",
"version": "0.2.0",
@@ -5347,6 +5795,7 @@
"src/everart": {
"name": "@modelcontextprotocol/server-everart",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "0.5.0",
@@ -5363,54 +5812,12 @@
"typescript": "^5.3.3"
}
},
- "src/everart/node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
- "engines": {
- "node": ">= 12"
- }
- },
- "src/everart/node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
- "src/everart/node_modules/open": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz",
- "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==",
- "dependencies": {
- "default-browser": "^4.0.0",
- "define-lazy-prop": "^3.0.0",
- "is-inside-container": "^1.0.0",
- "is-wsl": "^2.2.0"
- },
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"src/everything": {
"name": "@modelcontextprotocol/server-everything",
"version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1",
+ "@modelcontextprotocol/sdk": "^1.12.0",
"express": "^4.21.1",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.23.5"
@@ -5425,13 +5832,326 @@
}
},
"src/everything/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.12.3.tgz",
+ "integrity": "sha512-DyVYSOafBvk3/j1Oka4z5BWT8o4AFmoNyZY9pALOm7Lh3GZglR71Co4r4dEUoqDWdDazIZQHBe7J2Nwkg6gHgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.6",
+ "content-type": "^1.0.5",
+ "cors": "^2.8.5",
+ "cross-spawn": "^7.0.5",
+ "eventsource": "^3.0.2",
+ "express": "^5.0.1",
+ "express-rate-limit": "^7.5.0",
+ "pkce-challenge": "^5.0.0",
+ "raw-body": "^3.0.0",
+ "zod": "^3.23.8",
+ "zod-to-json-schema": "^3.24.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "src/everything/node_modules/@modelcontextprotocol/sdk/node_modules/express": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
+ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.0",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "src/everything/node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/everything/node_modules/body-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
+ "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.0",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.6.3",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.0",
+ "type-is": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "src/everything/node_modules/content-disposition": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
+ "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/everything/node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "src/everything/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "src/everything/node_modules/finalhandler": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
+ "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "src/everything/node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "src/everything/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "src/everything/node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "src/everything/node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "src/everything/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/everything/node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/everything/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "src/everything/node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/everything/node_modules/pkce-challenge": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
+ "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "src/everything/node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "src/everything/node_modules/send": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
+ "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.5",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "mime-types": "^3.0.1",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "src/everything/node_modules/serve-static": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
+ "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "src/everything/node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
"dependencies": {
"content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/everything/node_modules/zod": {
+ "version": "3.25.64",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.64.tgz",
+ "integrity": "sha512-hbP9FpSZf7pkS7hRVUrOjhwKJNyampPgtXKc3AN6DsWtoHsg2Sb4SQaS4Tcay380zSwd2VPo9G9180emBACp5g==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "src/everything/node_modules/zod-to-json-schema": {
+ "version": "3.24.5",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz",
+ "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==",
+ "license": "ISC",
+ "peerDependencies": {
+ "zod": "^3.24.1"
}
},
"src/filesystem": {
@@ -5439,7 +6159,7 @@
"version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "^1.12.3",
"diff": "^5.1.0",
"glob": "^10.3.10",
"minimatch": "^10.0.1",
@@ -5449,21 +6169,71 @@
"mcp-server-filesystem": "dist/index.js"
},
"devDependencies": {
+ "@jest/globals": "^29.7.0",
"@types/diff": "^5.0.9",
+ "@types/jest": "^29.5.14",
"@types/minimatch": "^5.1.2",
"@types/node": "^22",
+ "jest": "^29.7.0",
"shx": "^0.3.4",
- "typescript": "^5.3.3"
+ "ts-jest": "^29.1.1",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.8.2"
}
},
"src/filesystem/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.12.3.tgz",
+ "integrity": "sha512-DyVYSOafBvk3/j1Oka4z5BWT8o4AFmoNyZY9pALOm7Lh3GZglR71Co4r4dEUoqDWdDazIZQHBe7J2Nwkg6gHgQ==",
+ "license": "MIT",
"dependencies": {
+ "ajv": "^6.12.6",
"content-type": "^1.0.5",
+ "cors": "^2.8.5",
+ "cross-spawn": "^7.0.5",
+ "eventsource": "^3.0.2",
+ "express": "^5.0.1",
+ "express-rate-limit": "^7.5.0",
+ "pkce-challenge": "^5.0.0",
"raw-body": "^3.0.0",
- "zod": "^3.23.8"
+ "zod": "^3.23.8",
+ "zod-to-json-schema": "^3.24.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "src/filesystem/node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/filesystem/node_modules/body-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
+ "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.0",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.6.3",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.0",
+ "type-is": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
}
},
"src/filesystem/node_modules/brace-expansion": {
@@ -5475,6 +6245,112 @@
"balanced-match": "^1.0.0"
}
},
+ "src/filesystem/node_modules/content-disposition": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
+ "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/filesystem/node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "src/filesystem/node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "src/filesystem/node_modules/express": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
+ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.0",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "src/filesystem/node_modules/finalhandler": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
+ "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "src/filesystem/node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"src/filesystem/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
@@ -5510,6 +6386,60 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "src/filesystem/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "src/filesystem/node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "src/filesystem/node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "src/filesystem/node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/filesystem/node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"src/filesystem/node_modules/minimatch": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
@@ -5525,9 +6455,118 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "src/filesystem/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "src/filesystem/node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/filesystem/node_modules/pkce-challenge": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
+ "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.20.0"
+ }
+ },
+ "src/filesystem/node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "src/filesystem/node_modules/send": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
+ "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.5",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "mime-types": "^3.0.1",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "src/filesystem/node_modules/serve-static": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
+ "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "src/filesystem/node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "src/filesystem/node_modules/zod": {
+ "version": "3.24.2",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
+ "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "src/filesystem/node_modules/zod-to-json-schema": {
+ "version": "3.24.5",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz",
+ "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==",
+ "license": "ISC",
+ "peerDependencies": {
+ "zod": "^3.24.1"
+ }
+ },
"src/gdrive": {
"name": "@modelcontextprotocol/server-gdrive",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@google-cloud/local-auth": "^3.0.1",
@@ -5543,19 +6582,10 @@
"typescript": "^5.6.2"
}
},
- "src/gdrive/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
"src/github": {
"name": "@modelcontextprotocol/server-github",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1",
@@ -5574,44 +6604,10 @@
"typescript": "^5.6.2"
}
},
- "src/github/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
- "src/github/node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
- "engines": {
- "node": ">= 12"
- }
- },
- "src/github/node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
"src/gitlab": {
"name": "@modelcontextprotocol/server-gitlab",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1",
@@ -5627,44 +6623,10 @@
"typescript": "^5.6.2"
}
},
- "src/gitlab/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
- "src/gitlab/node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
- "engines": {
- "node": ">= 12"
- }
- },
- "src/gitlab/node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
"src/google-maps": {
"name": "@modelcontextprotocol/server-google-maps",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1",
@@ -5679,41 +6641,6 @@
"typescript": "^5.6.2"
}
},
- "src/google-maps/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
- "src/google-maps/node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
- "engines": {
- "node": ">= 12"
- }
- },
- "src/google-maps/node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
"src/memory": {
"name": "@modelcontextprotocol/server-memory",
"version": "0.6.3",
@@ -5743,6 +6670,7 @@
"src/postgres": {
"name": "@modelcontextprotocol/server-postgres",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1",
@@ -5757,19 +6685,10 @@
"typescript": "^5.6.2"
}
},
- "src/postgres/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
"src/puppeteer": {
"name": "@modelcontextprotocol/server-puppeteer",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1",
@@ -5783,19 +6702,10 @@
"typescript": "^5.6.2"
}
},
- "src/puppeteer/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
"src/redis": {
"name": "@modelcontextprotocol/server-redis",
"version": "0.1.0",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.7.0",
@@ -5811,419 +6721,6 @@
"typescript": "^5.7.2"
}
},
- "src/redis/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.7.0.tgz",
- "integrity": "sha512-IYPe/FLpvF3IZrd/f5p5ffmWhMc3aEMuM2wGJASDqC2Ge7qatVCdbfPx3n/5xFeb19xN0j/911M2AaFuircsWA==",
- "license": "MIT",
- "dependencies": {
- "content-type": "^1.0.5",
- "cors": "^2.8.5",
- "eventsource": "^3.0.2",
- "express": "^5.0.1",
- "express-rate-limit": "^7.5.0",
- "pkce-challenge": "^4.1.0",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8",
- "zod-to-json-schema": "^3.24.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "src/redis/node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/body-parser": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.1.0.tgz",
- "integrity": "sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==",
- "license": "MIT",
- "dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^1.0.5",
- "debug": "^4.4.0",
- "http-errors": "^2.0.0",
- "iconv-lite": "^0.5.2",
- "on-finished": "^2.4.1",
- "qs": "^6.14.0",
- "raw-body": "^3.0.0",
- "type-is": "^2.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "src/redis/node_modules/body-parser/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "src/redis/node_modules/body-parser/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "src/redis/node_modules/body-parser/node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "src/redis/node_modules/content-disposition": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/cookie-signature": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.6.0"
- }
- },
- "src/redis/node_modules/debug": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
- "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "src/redis/node_modules/express": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz",
- "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==",
- "license": "MIT",
- "dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.0.1",
- "content-disposition": "^1.0.0",
- "content-type": "~1.0.4",
- "cookie": "0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "4.3.6",
- "depd": "2.0.0",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "^2.0.0",
- "fresh": "2.0.0",
- "http-errors": "2.0.0",
- "merge-descriptors": "^2.0.0",
- "methods": "~1.1.2",
- "mime-types": "^3.0.0",
- "on-finished": "2.4.1",
- "once": "1.4.0",
- "parseurl": "~1.3.3",
- "proxy-addr": "~2.0.7",
- "qs": "6.13.0",
- "range-parser": "~1.2.1",
- "router": "^2.0.0",
- "safe-buffer": "5.2.1",
- "send": "^1.1.0",
- "serve-static": "^2.1.0",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "^2.0.0",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "src/redis/node_modules/finalhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
- "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "on-finished": "^2.4.1",
- "parseurl": "^1.3.3",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "src/redis/node_modules/finalhandler/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "src/redis/node_modules/finalhandler/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "src/redis/node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "src/redis/node_modules/iconv-lite": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz",
- "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "src/redis/node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "src/redis/node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "src/redis/node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/mime-types": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz",
- "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.53.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "license": "MIT"
- },
- "src/redis/node_modules/negotiator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/redis": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz",
- "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==",
- "license": "MIT",
- "workspaces": [
- "./packages/*"
- ],
- "dependencies": {
- "@redis/bloom": "1.2.0",
- "@redis/client": "1.6.0",
- "@redis/graph": "1.1.1",
- "@redis/json": "1.0.7",
- "@redis/search": "1.2.0",
- "@redis/time-series": "1.1.0"
- }
- },
- "src/redis/node_modules/send": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz",
- "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.5",
- "destroy": "^1.2.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^0.5.2",
- "http-errors": "^2.0.0",
- "mime-types": "^2.1.35",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "src/redis/node_modules/send/node_modules/fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/send/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/send/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/send/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "src/redis/node_modules/serve-static": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz",
- "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.0.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "src/redis/node_modules/type-is": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz",
- "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==",
- "license": "MIT",
- "dependencies": {
- "content-type": "^1.0.5",
- "media-typer": "^1.1.0",
- "mime-types": "^3.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "src/redis/node_modules/zod": {
- "version": "3.24.2",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
- "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- },
- "src/redis/node_modules/zod-to-json-schema": {
- "version": "3.24.5",
- "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz",
- "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==",
- "license": "ISC",
- "peerDependencies": {
- "zod": "^3.24.1"
- }
- },
"src/sequentialthinking": {
"name": "@modelcontextprotocol/server-sequential-thinking",
"version": "0.6.2",
@@ -6246,6 +6743,7 @@
"src/slack": {
"name": "@modelcontextprotocol/server-slack",
"version": "0.6.2",
+ "extraneous": true,
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.0.1"
@@ -6258,16 +6756,6 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
- },
- "src/slack/node_modules/@modelcontextprotocol/sdk": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
- "integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
}
}
}
diff --git a/package.json b/package.json
index 9d5e5ee2..d8b4870d 100644
--- a/package.json
+++ b/package.json
@@ -20,14 +20,8 @@
},
"dependencies": {
"@modelcontextprotocol/server-everything": "*",
- "@modelcontextprotocol/server-gdrive": "*",
- "@modelcontextprotocol/server-postgres": "*",
- "@modelcontextprotocol/server-puppeteer": "*",
- "@modelcontextprotocol/server-slack": "*",
- "@modelcontextprotocol/server-brave-search": "*",
"@modelcontextprotocol/server-memory": "*",
"@modelcontextprotocol/server-filesystem": "*",
- "@modelcontextprotocol/server-everart": "*",
"@modelcontextprotocol/server-sequential-thinking": "*"
}
}
diff --git a/src/aws-kb-retrieval-server/Dockerfile b/src/aws-kb-retrieval-server/Dockerfile
deleted file mode 100644
index 80cbb388..00000000
--- a/src/aws-kb-retrieval-server/Dockerfile
+++ /dev/null
@@ -1,22 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-COPY src/aws-kb-retrieval-server /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-FROM node:22-alpine AS release
-
-WORKDIR /app
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/aws-kb-retrieval-server/README.md b/src/aws-kb-retrieval-server/README.md
deleted file mode 100644
index bcd9fc2f..00000000
--- a/src/aws-kb-retrieval-server/README.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# AWS Knowledge Base Retrieval MCP Server
-
-An MCP server implementation for retrieving information from the AWS Knowledge Base using the Bedrock Agent Runtime.
-
-## Features
-
-- **RAG (Retrieval-Augmented Generation)**: Retrieve context from the AWS Knowledge Base based on a query and a Knowledge Base ID.
-- **Supports multiple results retrieval**: Option to retrieve a customizable number of results.
-
-## Tools
-
-- **retrieve_from_aws_kb**
- - Perform retrieval operations using the AWS Knowledge Base.
- - Inputs:
- - `query` (string): The search query for retrieval.
- - `knowledgeBaseId` (string): The ID of the AWS Knowledge Base.
- - `n` (number, optional): Number of results to retrieve (default: 3).
-
-## Configuration
-
-### Setting up AWS Credentials
-
-1. Obtain AWS access key ID, secret access key, and region from the AWS Management Console.
-2. Ensure these credentials have appropriate permissions for Bedrock Agent Runtime operations.
-
-### Usage with Claude Desktop
-
-Add this to your `claude_desktop_config.json`:
-
-#### Docker
-
-```json
-{
- "mcpServers": {
- "aws-kb-retrieval": {
- "command": "docker",
- "args": [ "run", "-i", "--rm", "-e", "AWS_ACCESS_KEY_ID", "-e", "AWS_SECRET_ACCESS_KEY", "-e", "AWS_REGION", "mcp/aws-kb-retrieval-server" ],
- "env": {
- "AWS_ACCESS_KEY_ID": "YOUR_ACCESS_KEY_HERE",
- "AWS_SECRET_ACCESS_KEY": "YOUR_SECRET_ACCESS_KEY_HERE",
- "AWS_REGION": "YOUR_AWS_REGION_HERE"
- }
- }
- }
-}
-```
-
-```json
-{
- "mcpServers": {
- "aws-kb-retrieval": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-aws-kb-retrieval"
- ],
- "env": {
- "AWS_ACCESS_KEY_ID": "YOUR_ACCESS_KEY_HERE",
- "AWS_SECRET_ACCESS_KEY": "YOUR_SECRET_ACCESS_KEY_HERE",
- "AWS_REGION": "YOUR_AWS_REGION_HERE"
- }
- }
- }
-}
-```
-
-## Building
-
-Docker:
-
-```sh
-docker build -t mcp/aws-kb-retrieval -f src/aws-kb-retrieval-server/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
-
-This README assumes that your server package is named `@modelcontextprotocol/server-aws-kb-retrieval`. Adjust the package name and installation details if they differ in your setup. Also, ensure that your server script is correctly built and that all dependencies are properly managed in your `package.json`.
diff --git a/src/aws-kb-retrieval-server/index.ts b/src/aws-kb-retrieval-server/index.ts
deleted file mode 100644
index f60a544e..00000000
--- a/src/aws-kb-retrieval-server/index.ts
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env node
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListToolsRequestSchema,
- Tool,
-} from "@modelcontextprotocol/sdk/types.js";
-import {
- BedrockAgentRuntimeClient,
- RetrieveCommand,
- RetrieveCommandInput,
-} from "@aws-sdk/client-bedrock-agent-runtime";
-
-// AWS client initialization
-const bedrockClient = new BedrockAgentRuntimeClient({
- region: process.env.AWS_REGION,
- credentials: {
- accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
- secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
- },
-});
-
-interface RAGSource {
- id: string;
- fileName: string;
- snippet: string;
- score: number;
-}
-
-async function retrieveContext(
- query: string,
- knowledgeBaseId: string,
- n: number = 3
-): Promise<{
- context: string;
- isRagWorking: boolean;
- ragSources: RAGSource[];
-}> {
- try {
- if (!knowledgeBaseId) {
- console.error("knowledgeBaseId is not provided");
- return {
- context: "",
- isRagWorking: false,
- ragSources: [],
- };
- }
-
- const input: RetrieveCommandInput = {
- knowledgeBaseId: knowledgeBaseId,
- retrievalQuery: { text: query },
- retrievalConfiguration: {
- vectorSearchConfiguration: { numberOfResults: n },
- },
- };
-
- const command = new RetrieveCommand(input);
- const response = await bedrockClient.send(command);
- const rawResults = response?.retrievalResults || [];
- const ragSources: RAGSource[] = rawResults
- .filter((res) => res?.content?.text)
- .map((result, index) => {
- const uri = result?.location?.s3Location?.uri || "";
- const fileName = uri.split("/").pop() || `Source-${index}.txt`;
- return {
- id: (result.metadata?.["x-amz-bedrock-kb-chunk-id"] as string) || `chunk-${index}`,
- fileName: fileName.replace(/_/g, " ").replace(".txt", ""),
- snippet: result.content?.text || "",
- score: (result.score as number) || 0,
- };
- })
- .slice(0, 3);
-
- const context = rawResults
- .filter((res): res is { content: { text: string } } => res?.content?.text !== undefined)
- .map(res => res.content.text)
- .join("\n\n");
-
- return {
- context,
- isRagWorking: true,
- ragSources,
- };
- } catch (error) {
- console.error("RAG Error:", error);
- return { context: "", isRagWorking: false, ragSources: [] };
- }
-}
-
-// Define the retrieval tool
-const RETRIEVAL_TOOL: Tool = {
- name: "retrieve_from_aws_kb",
- description: "Performs retrieval from the AWS Knowledge Base using the provided query and Knowledge Base ID.",
- inputSchema: {
- type: "object",
- properties: {
- query: { type: "string", description: "The query to perform retrieval on" },
- knowledgeBaseId: { type: "string", description: "The ID of the AWS Knowledge Base" },
- n: { type: "number", default: 3, description: "Number of results to retrieve" },
- },
- required: ["query", "knowledgeBaseId"],
- },
-};
-
-// Server setup
-const server = new Server(
- {
- name: "aws-kb-retrieval-server",
- version: "0.2.0",
- },
- {
- capabilities: {
- tools: {},
- },
- },
-);
-
-// Request handlers
-server.setRequestHandler(ListToolsRequestSchema, async () => ({
- tools: [RETRIEVAL_TOOL],
-}));
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- const { name, arguments: args } = request.params;
-
- if (name === "retrieve_from_aws_kb") {
- const { query, knowledgeBaseId, n = 3 } = args as Record;
- try {
- const result = await retrieveContext(query, knowledgeBaseId, n);
- if (result.isRagWorking) {
- return {
- content: [
- { type: "text", text: `Context: ${result.context}` },
- { type: "text", text: `RAG Sources: ${JSON.stringify(result.ragSources)}` },
- ],
- };
- } else {
- return {
- content: [{ type: "text", text: "Retrieval failed or returned no results." }],
- };
- }
- } catch (error) {
- return {
- content: [{ type: "text", text: `Error occurred: ${error}` }],
- };
- }
- } else {
- return {
- content: [{ type: "text", text: `Unknown tool: ${name}` }],
- isError: true,
- };
- }
-});
-
-// Server startup
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
- console.error("AWS KB Retrieval Server running on stdio");
-}
-
-runServer().catch((error) => {
- console.error("Fatal error running server:", error);
- process.exit(1);
-});
diff --git a/src/aws-kb-retrieval-server/package.json b/src/aws-kb-retrieval-server/package.json
deleted file mode 100644
index 072fee11..00000000
--- a/src/aws-kb-retrieval-server/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-aws-kb-retrieval",
- "version": "0.6.2",
- "description": "MCP server for AWS Knowledge Base retrieval using Bedrock Agent Runtime",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-aws-kb-retrieval": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
- "@aws-sdk/client-bedrock-agent-runtime": "^3.0.0"
- },
- "devDependencies": {
- "@types/node": "^22",
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/aws-kb-retrieval-server/tsconfig.json b/src/aws-kb-retrieval-server/tsconfig.json
deleted file mode 100644
index 98b13da0..00000000
--- a/src/aws-kb-retrieval-server/tsconfig.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": ".",
- "composite": true,
- "incremental": true,
- "tsBuildInfoFile": "./dist/.tsbuildinfo"
- },
- "include": [
- "./**/*.ts"
- ],
- "exclude": [
- "node_modules",
- "dist"
- ]
-}
diff --git a/src/brave-search/Dockerfile b/src/brave-search/Dockerfile
deleted file mode 100644
index 7749c243..00000000
--- a/src/brave-search/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-# Must be entire project because `prepare` script is run during `npm install` and requires all files.
-COPY src/brave-search /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-FROM node:22-alpine AS release
-
-WORKDIR /app
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/brave-search/README.md b/src/brave-search/README.md
deleted file mode 100644
index 39f73535..00000000
--- a/src/brave-search/README.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# Brave Search MCP Server
-
-An MCP server implementation that integrates the Brave Search API, providing both web and local search capabilities.
-
-## Features
-
-- **Web Search**: General queries, news, articles, with pagination and freshness controls
-- **Local Search**: Find businesses, restaurants, and services with detailed information
-- **Flexible Filtering**: Control result types, safety levels, and content freshness
-- **Smart Fallbacks**: Local search automatically falls back to web when no results are found
-
-## Tools
-
-- **brave_web_search**
- - Execute web searches with pagination and filtering
- - Inputs:
- - `query` (string): Search terms
- - `count` (number, optional): Results per page (max 20)
- - `offset` (number, optional): Pagination offset (max 9)
-
-- **brave_local_search**
- - Search for local businesses and services
- - Inputs:
- - `query` (string): Local search terms
- - `count` (number, optional): Number of results (max 20)
- - Automatically falls back to web search if no local results found
-
-
-## Configuration
-
-### Getting an API Key
-1. Sign up for a [Brave Search API account](https://brave.com/search/api/)
-2. Choose a plan (Free tier available with 2,000 queries/month)
-3. Generate your API key [from the developer dashboard](https://api.search.brave.com/app/keys)
-
-### Usage with Claude Desktop
-Add this to your `claude_desktop_config.json`:
-
-### Docker
-
-```json
-{
- "mcpServers": {
- "brave-search": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "-e",
- "BRAVE_API_KEY",
- "mcp/brave-search"
- ],
- "env": {
- "BRAVE_API_KEY": "YOUR_API_KEY_HERE"
- }
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "brave-search": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-brave-search"
- ],
- "env": {
- "BRAVE_API_KEY": "YOUR_API_KEY_HERE"
- }
- }
- }
-}
-```
-
-
-## Build
-
-Docker build:
-
-```bash
-docker build -t mcp/brave-search:latest -f src/brave-search/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/brave-search/index.ts b/src/brave-search/index.ts
deleted file mode 100644
index e0f61623..00000000
--- a/src/brave-search/index.ts
+++ /dev/null
@@ -1,376 +0,0 @@
-#!/usr/bin/env node
-
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListToolsRequestSchema,
- Tool,
-} from "@modelcontextprotocol/sdk/types.js";
-
-const WEB_SEARCH_TOOL: Tool = {
- name: "brave_web_search",
- description:
- "Performs a web search using the Brave Search API, ideal for general queries, news, articles, and online content. " +
- "Use this for broad information gathering, recent events, or when you need diverse web sources. " +
- "Supports pagination, content filtering, and freshness controls. " +
- "Maximum 20 results per request, with offset for pagination. ",
- inputSchema: {
- type: "object",
- properties: {
- query: {
- type: "string",
- description: "Search query (max 400 chars, 50 words)"
- },
- count: {
- type: "number",
- description: "Number of results (1-20, default 10)",
- default: 10
- },
- offset: {
- type: "number",
- description: "Pagination offset (max 9, default 0)",
- default: 0
- },
- },
- required: ["query"],
- },
-};
-
-const LOCAL_SEARCH_TOOL: Tool = {
- name: "brave_local_search",
- description:
- "Searches for local businesses and places using Brave's Local Search API. " +
- "Best for queries related to physical locations, businesses, restaurants, services, etc. " +
- "Returns detailed information including:\n" +
- "- Business names and addresses\n" +
- "- Ratings and review counts\n" +
- "- Phone numbers and opening hours\n" +
- "Use this when the query implies 'near me' or mentions specific locations. " +
- "Automatically falls back to web search if no local results are found.",
- inputSchema: {
- type: "object",
- properties: {
- query: {
- type: "string",
- description: "Local search query (e.g. 'pizza near Central Park')"
- },
- count: {
- type: "number",
- description: "Number of results (1-20, default 5)",
- default: 5
- },
- },
- required: ["query"]
- }
-};
-
-// Server implementation
-const server = new Server(
- {
- name: "example-servers/brave-search",
- version: "0.1.0",
- },
- {
- capabilities: {
- tools: {},
- },
- },
-);
-
-// Check for API key
-const BRAVE_API_KEY = process.env.BRAVE_API_KEY!;
-if (!BRAVE_API_KEY) {
- console.error("Error: BRAVE_API_KEY environment variable is required");
- process.exit(1);
-}
-
-const RATE_LIMIT = {
- perSecond: 1,
- perMonth: 15000
-};
-
-let requestCount = {
- second: 0,
- month: 0,
- lastReset: Date.now()
-};
-
-function checkRateLimit() {
- const now = Date.now();
- if (now - requestCount.lastReset > 1000) {
- requestCount.second = 0;
- requestCount.lastReset = now;
- }
- if (requestCount.second >= RATE_LIMIT.perSecond ||
- requestCount.month >= RATE_LIMIT.perMonth) {
- throw new Error('Rate limit exceeded');
- }
- requestCount.second++;
- requestCount.month++;
-}
-
-interface BraveWeb {
- web?: {
- results?: Array<{
- title: string;
- description: string;
- url: string;
- language?: string;
- published?: string;
- rank?: number;
- }>;
- };
- locations?: {
- results?: Array<{
- id: string; // Required by API
- title?: string;
- }>;
- };
-}
-
-interface BraveLocation {
- id: string;
- name: string;
- address: {
- streetAddress?: string;
- addressLocality?: string;
- addressRegion?: string;
- postalCode?: string;
- };
- coordinates?: {
- latitude: number;
- longitude: number;
- };
- phone?: string;
- rating?: {
- ratingValue?: number;
- ratingCount?: number;
- };
- openingHours?: string[];
- priceRange?: string;
-}
-
-interface BravePoiResponse {
- results: BraveLocation[];
-}
-
-interface BraveDescription {
- descriptions: {[id: string]: string};
-}
-
-function isBraveWebSearchArgs(args: unknown): args is { query: string; count?: number } {
- return (
- typeof args === "object" &&
- args !== null &&
- "query" in args &&
- typeof (args as { query: string }).query === "string"
- );
-}
-
-function isBraveLocalSearchArgs(args: unknown): args is { query: string; count?: number } {
- return (
- typeof args === "object" &&
- args !== null &&
- "query" in args &&
- typeof (args as { query: string }).query === "string"
- );
-}
-
-async function performWebSearch(query: string, count: number = 10, offset: number = 0) {
- checkRateLimit();
- const url = new URL('https://api.search.brave.com/res/v1/web/search');
- url.searchParams.set('q', query);
- url.searchParams.set('count', Math.min(count, 20).toString()); // API limit
- url.searchParams.set('offset', offset.toString());
-
- const response = await fetch(url, {
- headers: {
- 'Accept': 'application/json',
- 'Accept-Encoding': 'gzip',
- 'X-Subscription-Token': BRAVE_API_KEY
- }
- });
-
- if (!response.ok) {
- throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
- }
-
- const data = await response.json() as BraveWeb;
-
- // Extract just web results
- const results = (data.web?.results || []).map(result => ({
- title: result.title || '',
- description: result.description || '',
- url: result.url || ''
- }));
-
- return results.map(r =>
- `Title: ${r.title}\nDescription: ${r.description}\nURL: ${r.url}`
- ).join('\n\n');
-}
-
-async function performLocalSearch(query: string, count: number = 5) {
- checkRateLimit();
- // Initial search to get location IDs
- const webUrl = new URL('https://api.search.brave.com/res/v1/web/search');
- webUrl.searchParams.set('q', query);
- webUrl.searchParams.set('search_lang', 'en');
- webUrl.searchParams.set('result_filter', 'locations');
- webUrl.searchParams.set('count', Math.min(count, 20).toString());
-
- const webResponse = await fetch(webUrl, {
- headers: {
- 'Accept': 'application/json',
- 'Accept-Encoding': 'gzip',
- 'X-Subscription-Token': BRAVE_API_KEY
- }
- });
-
- if (!webResponse.ok) {
- throw new Error(`Brave API error: ${webResponse.status} ${webResponse.statusText}\n${await webResponse.text()}`);
- }
-
- const webData = await webResponse.json() as BraveWeb;
- const locationIds = webData.locations?.results?.filter((r): r is {id: string; title?: string} => r.id != null).map(r => r.id) || [];
-
- if (locationIds.length === 0) {
- return performWebSearch(query, count); // Fallback to web search
- }
-
- // Get POI details and descriptions in parallel
- const [poisData, descriptionsData] = await Promise.all([
- getPoisData(locationIds),
- getDescriptionsData(locationIds)
- ]);
-
- return formatLocalResults(poisData, descriptionsData);
-}
-
-async function getPoisData(ids: string[]): Promise {
- checkRateLimit();
- const url = new URL('https://api.search.brave.com/res/v1/local/pois');
- ids.filter(Boolean).forEach(id => url.searchParams.append('ids', id));
- const response = await fetch(url, {
- headers: {
- 'Accept': 'application/json',
- 'Accept-Encoding': 'gzip',
- 'X-Subscription-Token': BRAVE_API_KEY
- }
- });
-
- if (!response.ok) {
- throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
- }
-
- const poisResponse = await response.json() as BravePoiResponse;
- return poisResponse;
-}
-
-async function getDescriptionsData(ids: string[]): Promise {
- checkRateLimit();
- const url = new URL('https://api.search.brave.com/res/v1/local/descriptions');
- ids.filter(Boolean).forEach(id => url.searchParams.append('ids', id));
- const response = await fetch(url, {
- headers: {
- 'Accept': 'application/json',
- 'Accept-Encoding': 'gzip',
- 'X-Subscription-Token': BRAVE_API_KEY
- }
- });
-
- if (!response.ok) {
- throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
- }
-
- const descriptionsData = await response.json() as BraveDescription;
- return descriptionsData;
-}
-
-function formatLocalResults(poisData: BravePoiResponse, descData: BraveDescription): string {
- return (poisData.results || []).map(poi => {
- const address = [
- poi.address?.streetAddress ?? '',
- poi.address?.addressLocality ?? '',
- poi.address?.addressRegion ?? '',
- poi.address?.postalCode ?? ''
- ].filter(part => part !== '').join(', ') || 'N/A';
-
- return `Name: ${poi.name}
-Address: ${address}
-Phone: ${poi.phone || 'N/A'}
-Rating: ${poi.rating?.ratingValue ?? 'N/A'} (${poi.rating?.ratingCount ?? 0} reviews)
-Price Range: ${poi.priceRange || 'N/A'}
-Hours: ${(poi.openingHours || []).join(', ') || 'N/A'}
-Description: ${descData.descriptions[poi.id] || 'No description available'}
-`;
- }).join('\n---\n') || 'No local results found';
-}
-
-// Tool handlers
-server.setRequestHandler(ListToolsRequestSchema, async () => ({
- tools: [WEB_SEARCH_TOOL, LOCAL_SEARCH_TOOL],
-}));
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- try {
- const { name, arguments: args } = request.params;
-
- if (!args) {
- throw new Error("No arguments provided");
- }
-
- switch (name) {
- case "brave_web_search": {
- if (!isBraveWebSearchArgs(args)) {
- throw new Error("Invalid arguments for brave_web_search");
- }
- const { query, count = 10 } = args;
- const results = await performWebSearch(query, count);
- return {
- content: [{ type: "text", text: results }],
- isError: false,
- };
- }
-
- case "brave_local_search": {
- if (!isBraveLocalSearchArgs(args)) {
- throw new Error("Invalid arguments for brave_local_search");
- }
- const { query, count = 5 } = args;
- const results = await performLocalSearch(query, count);
- return {
- content: [{ type: "text", text: results }],
- isError: false,
- };
- }
-
- default:
- return {
- content: [{ type: "text", text: `Unknown tool: ${name}` }],
- isError: true,
- };
- }
- } catch (error) {
- return {
- content: [
- {
- type: "text",
- text: `Error: ${error instanceof Error ? error.message : String(error)}`,
- },
- ],
- isError: true,
- };
- }
-});
-
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
- console.error("Brave Search MCP Server running on stdio");
-}
-
-runServer().catch((error) => {
- console.error("Fatal error running server:", error);
- process.exit(1);
-});
diff --git a/src/brave-search/package.json b/src/brave-search/package.json
deleted file mode 100644
index 163e5afc..00000000
--- a/src/brave-search/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-brave-search",
- "version": "0.6.2",
- "description": "MCP server for Brave Search API integration",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-brave-search": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1"
- },
- "devDependencies": {
- "@types/node": "^22",
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/brave-search/tsconfig.json b/src/brave-search/tsconfig.json
deleted file mode 100644
index 087f641d..00000000
--- a/src/brave-search/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
- }
diff --git a/src/everart/Dockerfile b/src/everart/Dockerfile
deleted file mode 100644
index d853b8ef..00000000
--- a/src/everart/Dockerfile
+++ /dev/null
@@ -1,24 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-COPY src/everart /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-FROM node:22-alpine AS release
-
-WORKDIR /app
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
-
-CMD ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/everart/README.md b/src/everart/README.md
deleted file mode 100644
index 57dab4d0..00000000
--- a/src/everart/README.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# EverArt MCP Server
-
-Image generation server for Claude Desktop using EverArt's API.
-
-## Install
-```bash
-npm install
-export EVERART_API_KEY=your_key_here
-```
-
-## Config
-Add to Claude Desktop config:
-
-### Docker
-```json
-{
- "mcpServers": {
- "everart": {
- "command": "docker",
- "args": ["run", "-i", "--rm", "-e", "EVERART_API_KEY", "mcp/everart"],
- "env": {
- "EVERART_API_KEY": "your_key_here"
- }
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "everart": {
- "command": "npx",
- "args": ["-y", "@modelcontextprotocol/server-everart"],
- "env": {
- "EVERART_API_KEY": "your_key_here"
- }
- }
- }
-}
-```
-
-## Tools
-
-### generate_image
-Generates images with multiple model options. Opens result in browser and returns URL.
-
-Parameters:
-```typescript
-{
- prompt: string, // Image description
- model?: string, // Model ID (default: "207910310772879360")
- image_count?: number // Number of images (default: 1)
-}
-```
-
-Models:
-- 5000: FLUX1.1 (standard)
-- 9000: FLUX1.1-ultra
-- 6000: SD3.5
-- 7000: Recraft-Real
-- 8000: Recraft-Vector
-
-All images generated at 1024x1024.
-
-Sample usage:
-```javascript
-const result = await client.callTool({
- name: "generate_image",
- arguments: {
- prompt: "A cat sitting elegantly",
- model: "7000",
- image_count: 1
- }
-});
-```
-
-Response format:
-```
-Image generated successfully!
-The image has been opened in your default browser.
-
-Generation details:
-- Model: 7000
-- Prompt: "A cat sitting elegantly"
-- Image URL: https://storage.googleapis.com/...
-
-You can also click the URL above to view the image again.
-```
-
-## Building w/ Docker
-
-```sh
-docker build -t mcp/everart -f src/everart/Dockerfile .
-```
diff --git a/src/everart/index.ts b/src/everart/index.ts
deleted file mode 100644
index bfdb2277..00000000
--- a/src/everart/index.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env node
-import EverArt from "everart";
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListToolsRequestSchema,
- ListResourcesRequestSchema,
- ReadResourceRequestSchema,
-} from "@modelcontextprotocol/sdk/types.js";
-import fetch from "node-fetch";
-import open from "open";
-
-const server = new Server(
- {
- name: "example-servers/everart",
- version: "0.2.0",
- },
- {
- capabilities: {
- tools: {},
- resources: {}, // Required for image resources
- },
- },
-);
-
-if (!process.env.EVERART_API_KEY) {
- console.error("EVERART_API_KEY environment variable is not set");
- process.exit(1);
-}
-
-const client = new EverArt.default(process.env.EVERART_API_KEY);
-
-server.setRequestHandler(ListToolsRequestSchema, async () => ({
- tools: [
- {
- name: "generate_image",
- description:
- "Generate images using EverArt Models and returns a clickable link to view the generated image. " +
- "The tool will return a URL that can be clicked to view the image in a browser. " +
- "Available models:\n" +
- "- 5000:FLUX1.1: Standard quality\n" +
- "- 9000:FLUX1.1-ultra: Ultra high quality\n" +
- "- 6000:SD3.5: Stable Diffusion 3.5\n" +
- "- 7000:Recraft-Real: Photorealistic style\n" +
- "- 8000:Recraft-Vector: Vector art style\n" +
- "\nThe response will contain a direct link to view the generated image.",
- inputSchema: {
- type: "object",
- properties: {
- prompt: {
- type: "string",
- description: "Text description of desired image",
- },
- model: {
- type: "string",
- description:
- "Model ID (5000:FLUX1.1, 9000:FLUX1.1-ultra, 6000:SD3.5, 7000:Recraft-Real, 8000:Recraft-Vector)",
- default: "5000",
- },
- image_count: {
- type: "number",
- description: "Number of images to generate",
- default: 1,
- },
- },
- required: ["prompt"],
- },
- },
- ],
-}));
-
-server.setRequestHandler(ListResourcesRequestSchema, async () => {
- return {
- resources: [
- {
- uri: "everart://images",
- mimeType: "image/png",
- name: "Generated Images",
- },
- ],
- };
-});
-
-server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
- if (request.params.uri === "everart://images") {
- return {
- contents: [
- {
- uri: "everart://images",
- mimeType: "image/png",
- blob: "", // Empty since this is just for listing
- },
- ],
- };
- }
- throw new Error("Resource not found");
-});
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- if (request.params.name === "generate_image") {
- try {
- const {
- prompt,
- model = "207910310772879360",
- image_count = 1,
- } = request.params.arguments as any;
-
- // Use correct EverArt API method
- const generation = await client.v1.generations.create(
- model,
- prompt,
- "txt2img",
- {
- imageCount: image_count,
- height: 1024,
- width: 1024,
- },
- );
-
- // Wait for generation to complete
- const completedGen = await client.v1.generations.fetchWithPolling(
- generation[0].id,
- );
-
- const imgUrl = completedGen.image_url;
- if (!imgUrl) throw new Error("No image URL");
-
- // Automatically open the image URL in the default browser
- await open(imgUrl);
-
- // Return a formatted message with the clickable link
- return {
- content: [
- {
- type: "text",
- text: `Image generated successfully!\nThe image has been opened in your default browser.\n\nGeneration details:\n- Model: ${model}\n- Prompt: "${prompt}"\n- Image URL: ${imgUrl}\n\nYou can also click the URL above to view the image again.`,
- },
- ],
- };
- } catch (error: unknown) {
- console.error("Detailed error:", error);
- const errorMessage =
- error instanceof Error ? error.message : "Unknown error";
- return {
- content: [{ type: "text", text: `Error: ${errorMessage}` }],
- isError: true,
- };
- }
- }
- throw new Error(`Unknown tool: ${request.params.name}`);
-});
-
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
- console.error("EverArt MCP Server running on stdio");
-}
-
-runServer().catch(console.error);
diff --git a/src/everart/package.json b/src/everart/package.json
deleted file mode 100644
index 653c654b..00000000
--- a/src/everart/package.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-everart",
- "version": "0.6.2",
- "description": "MCP server for EverArt API integration",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-everart": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
- "everart": "^1.0.0",
- "node-fetch": "^3.3.2",
- "open": "^9.1.0"
- },
- "devDependencies": {
- "@types/node": "^22",
- "shx": "^0.3.4",
- "typescript": "^5.3.3"
- }
-}
\ No newline at end of file
diff --git a/src/everart/tsconfig.json b/src/everart/tsconfig.json
deleted file mode 100644
index ec5da158..00000000
--- a/src/everart/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
-}
diff --git a/src/everything/README.md b/src/everything/README.md
index f0c4a550..3ab3299a 100644
--- a/src/everything/README.md
+++ b/src/everything/README.md
@@ -72,6 +72,14 @@ This MCP server attempts to exercise all the features of the MCP protocol. It is
- Embedded resource with `type: "resource"`
- Text instruction for using the resource URI
+9. `startElicitation`
+ - Initiates an elicitation (interaction) within the MCP client.
+ - Inputs:
+ - `color` (string): Favorite color
+ - `number` (number, 1-100): Favorite number
+ - `pets` (enum): Favorite pet
+ - Returns: Confirmation of the elicitation demo with selection summary.
+
### Resources
The server provides 100 test resources in two formats:
@@ -126,7 +134,7 @@ The server sends random-leveled log messages every 15 seconds, e.g.:
}
```
-## Usage with Claude Desktop
+## Usage with Claude Desktop (uses [stdio Transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#stdio))
Add to your `claude_desktop_config.json`:
@@ -143,3 +151,75 @@ Add to your `claude_desktop_config.json`:
}
}
```
+
+## Usage with VS Code
+
+For quick installation, use of of the one-click install buttons below...
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=everything&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-everything%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=everything&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-everything%22%5D%7D&quality=insiders)
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=everything&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Feverything%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=everything&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Feverything%22%5D%7D&quality=insiders)
+
+For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
+
+Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
+
+> Note that the `mcp` key is not needed in the `.vscode/mcp.json` file.
+
+#### NPX
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "everything": {
+ "command": "npx",
+ "args": ["-y", "@modelcontextprotocol/server-everything"]
+ }
+ }
+ }
+}
+```
+
+## Running from source with [HTTP+SSE Transport](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports#http-with-sse) (deprecated as of [2025-03-26](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports))
+
+```shell
+cd src/everything
+npm install
+npm run start:sse
+```
+
+## Run from source with [Streamable HTTP Transport](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http)
+
+```shell
+cd src/everything
+npm install
+npm run start:streamableHttp
+```
+
+## Running as an installed package
+### Install
+```shell
+npm install -g @modelcontextprotocol/server-everything@latest
+````
+
+### Run the default (stdio) server
+```shell
+npx @modelcontextprotocol/server-everything
+```
+
+### Or specify stdio explicitly
+```shell
+npx @modelcontextprotocol/server-everything stdio
+```
+
+### Run the SSE server
+```shell
+npx @modelcontextprotocol/server-everything sse
+```
+
+### Run the streamable HTTP server
+```shell
+npx @modelcontextprotocol/server-everything streamableHttp
+```
+
diff --git a/src/everything/everything.ts b/src/everything/everything.ts
index b16d8395..b1f6950b 100644
--- a/src/everything/everything.ts
+++ b/src/everything/everything.ts
@@ -20,6 +20,13 @@ import {
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
+import { readFileSync } from "fs";
+import { fileURLToPath } from "url";
+import { dirname, join } from "path";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+const instructions = readFileSync(join(__dirname, "instructions.md"), "utf-8");
const ToolInputSchema = ToolSchema.shape.inputSchema;
type ToolInput = z.infer;
@@ -79,6 +86,17 @@ const GetResourceReferenceSchema = z.object({
.describe("ID of the resource to reference (1-100)"),
});
+const ElicitationSchema = z.object({});
+
+const GetResourceLinksSchema = z.object({
+ count: z
+ .number()
+ .min(1)
+ .max(10)
+ .default(3)
+ .describe("Number of resource links to return (1-10)"),
+});
+
enum ToolName {
ECHO = "echo",
ADD = "add",
@@ -88,6 +106,8 @@ enum ToolName {
GET_TINY_IMAGE = "getTinyImage",
ANNOTATED_MESSAGE = "annotatedMessage",
GET_RESOURCE_REFERENCE = "getResourceReference",
+ ELICITATION = "startElicitation",
+ GET_RESOURCE_LINKS = "getResourceLinks",
}
enum PromptName {
@@ -108,7 +128,10 @@ export const createServer = () => {
resources: { subscribe: true },
tools: {},
logging: {},
+ completions: {},
+ elicitation: {},
},
+ instructions
}
);
@@ -159,9 +182,9 @@ export const createServer = () => {
// Set up update interval for stderr messages
stdErrUpdateInterval = setInterval(() => {
const shortTimestamp = new Date().toLocaleTimeString([], {
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit'
+ hour: "2-digit",
+ minute: "2-digit",
+ second: "2-digit"
});
server.notification({
method: "notifications/stderr",
@@ -197,6 +220,21 @@ export const createServer = () => {
return await server.request(request, CreateMessageResultSchema);
};
+ const requestElicitation = async (
+ message: string,
+ requestedSchema: any
+ ) => {
+ const request = {
+ method: 'elicitation/create',
+ params: {
+ message,
+ requestedSchema
+ }
+ };
+
+ return await server.request(request, z.any());
+ };
+
const ALL_RESOURCES: Resource[] = Array.from({ length: 100 }, (_, i) => {
const uri = `test://static/resource/${i + 1}`;
if (i % 2 === 0) {
@@ -450,6 +488,17 @@ export const createServer = () => {
"Returns a resource reference that can be used by MCP clients",
inputSchema: zodToJsonSchema(GetResourceReferenceSchema) as ToolInput,
},
+ {
+ name: ToolName.ELICITATION,
+ description: "Demonstrates the Elicitation feature by asking the user to provide information about their favorite color, number, and pets.",
+ inputSchema: zodToJsonSchema(ElicitationSchema) as ToolInput,
+ },
+ {
+ name: ToolName.GET_RESOURCE_LINKS,
+ description:
+ "Returns multiple resource links that reference different types of resources",
+ inputSchema: zodToJsonSchema(GetResourceLinksSchema) as ToolInput,
+ },
];
return { tools };
@@ -639,6 +688,91 @@ export const createServer = () => {
return { content };
}
+ if (name === ToolName.ELICITATION) {
+ ElicitationSchema.parse(args);
+
+ const elicitationResult = await requestElicitation(
+ 'What are your favorite things?',
+ {
+ type: 'object',
+ properties: {
+ color: { type: 'string', description: 'Favorite color' },
+ number: { type: 'integer', description: 'Favorite number', minimum: 1, maximum: 100 },
+ pets: {
+ type: 'string',
+ enum: ['cats', 'dogs', 'birds', 'fish', 'reptiles'],
+ description: 'Favorite pets'
+ },
+ }
+ }
+ );
+
+ // Handle different response actions
+ const content = [];
+
+ if (elicitationResult.action === 'accept' && elicitationResult.content) {
+ content.push({
+ type: "text",
+ text: `✅ User provided their favorite things!`,
+ });
+
+ // Only access elicitationResult.content when action is accept
+ const { color, number, pets } = elicitationResult.content;
+ content.push({
+ type: "text",
+ text: `Their favorites are:\n- Color: ${color || 'not specified'}\n- Number: ${number || 'not specified'}\n- Pets: ${pets || 'not specified'}`,
+ });
+ } else if (elicitationResult.action === 'decline') {
+ content.push({
+ type: "text",
+ text: `❌ User declined to provide their favorite things.`,
+ });
+ } else if (elicitationResult.action === 'cancel') {
+ content.push({
+ type: "text",
+ text: `⚠️ User cancelled the elicitation dialog.`,
+ });
+ }
+
+ // Include raw result for debugging
+ content.push({
+ type: "text",
+ text: `\nRaw result: ${JSON.stringify(elicitationResult, null, 2)}`,
+ });
+
+ return { content };
+ }
+
+ if (name === ToolName.GET_RESOURCE_LINKS) {
+ const { count } = GetResourceLinksSchema.parse(args);
+ const content = [];
+
+ // Add intro text
+ content.push({
+ type: "text",
+ text: `Here are ${count} resource links to resources available in this server (see full output in tool response if your client does not support resource_link yet):`,
+ });
+
+ // Return resource links to actual resources from ALL_RESOURCES
+ const actualCount = Math.min(count, ALL_RESOURCES.length);
+ for (let i = 0; i < actualCount; i++) {
+ const resource = ALL_RESOURCES[i];
+ content.push({
+ type: "resource_link",
+ uri: resource.uri,
+ name: resource.name,
+ description: `Resource ${i + 1}: ${
+ resource.mimeType === "text/plain"
+ ? "plaintext resource"
+ : "binary blob resource"
+ }`,
+ mimeType: resource.mimeType,
+ });
+ }
+
+ return { content };
+ }
+
throw new Error(`Unknown tool: ${name}`);
});
diff --git a/src/everything/index.ts b/src/everything/index.ts
index c0ab77a2..801fe721 100644
--- a/src/everything/index.ts
+++ b/src/everything/index.ts
@@ -1,23 +1,37 @@
#!/usr/bin/env node
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import { createServer } from "./everything.js";
+// Parse command line arguments first
+const args = process.argv.slice(2);
+const scriptName = args[0] || 'stdio';
-async function main() {
- const transport = new StdioServerTransport();
- const { server, cleanup } = createServer();
-
- await server.connect(transport);
-
- // Cleanup on exit
- process.on("SIGINT", async () => {
- await cleanup();
- await server.close();
- process.exit(0);
- });
+async function run() {
+ try {
+ // Dynamically import only the requested module to prevent all modules from initializing
+ switch (scriptName) {
+ case 'stdio':
+ // Import and run the default server
+ await import('./stdio.js');
+ break;
+ case 'sse':
+ // Import and run the SSE server
+ await import('./sse.js');
+ break;
+ case 'streamableHttp':
+ // Import and run the streamable HTTP server
+ await import('./streamableHttp.js');
+ break;
+ default:
+ console.error(`Unknown script: ${scriptName}`);
+ console.log('Available scripts:');
+ console.log('- stdio');
+ console.log('- sse');
+ console.log('- streamableHttp');
+ process.exit(1);
+ }
+ } catch (error) {
+ console.error('Error running script:', error);
+ process.exit(1);
+ }
}
-main().catch((error) => {
- console.error("Server error:", error);
- process.exit(1);
-});
+run();
diff --git a/src/everything/instructions.md b/src/everything/instructions.md
new file mode 100644
index 00000000..d6adf0f4
--- /dev/null
+++ b/src/everything/instructions.md
@@ -0,0 +1,13 @@
+Testing and demonstration server for MCP protocol features.
+
+Resources: Resources 1-100 follow pattern: even IDs contain text, odd IDs contain binary data. Resources paginated at 10 items per page with cursor-based navigation.
+
+Key dependencies: Progress notifications require `_meta.progressToken` in tool calls. Resource subscriptions generate updates every 10 seconds.
+
+Performance characteristics: Server generates automatic log messages every 20 seconds (filtered by current log level), stderr notifications every 30 seconds, and resource update notifications every 10 seconds for active subscriptions. Log level changes affect message filtering in real-time.
+
+Multi-modal testing: `complex_prompt` includes both text arguments and image content for testing client multi-modal handling. `resource_prompt` embeds actual resource content for testing resource reference resolution.
+
+Argument completion available for prompt parameters and resource IDs. Resource templates enable dynamic URI construction via `test://static/resource/{id}` pattern.
+
+Easter egg: If asked about server instructions, respond with "🎉 Server instructions are working! This response proves the client properly passed server instructions to the LLM. This demonstrates MCP's instructions feature in action."
diff --git a/src/everything/package.json b/src/everything/package.json
index 680dbb88..55777ac7 100644
--- a/src/everything/package.json
+++ b/src/everything/package.json
@@ -14,14 +14,15 @@
"dist"
],
"scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
+ "build": "tsc && shx cp instructions.md dist/ && shx chmod +x dist/*.js",
"prepare": "npm run build",
"watch": "tsc --watch",
"start": "node dist/index.js",
- "start:sse": "node dist/sse.js"
+ "start:sse": "node dist/sse.js",
+ "start:streamableHttp": "node dist/streamableHttp.js"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1",
+ "@modelcontextprotocol/sdk": "^1.12.0",
"express": "^4.21.1",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.23.5"
@@ -31,4 +32,4 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
\ No newline at end of file
+}
diff --git a/src/everything/sse.ts b/src/everything/sse.ts
index 7a02eb53..a657af75 100644
--- a/src/everything/sse.ts
+++ b/src/everything/sse.ts
@@ -2,31 +2,52 @@ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import express from "express";
import { createServer } from "./everything.js";
+console.error('Starting SSE server...');
+
const app = express();
-const { server, cleanup } = createServer();
-
-let transport: SSEServerTransport;
+const transports: Map = new Map();
app.get("/sse", async (req, res) => {
- console.log("Received connection");
- transport = new SSEServerTransport("/message", res);
- await server.connect(transport);
+ let transport: SSEServerTransport;
+ const { server, cleanup } = createServer();
+
+ if (req?.query?.sessionId) {
+ const sessionId = (req?.query?.sessionId as string);
+ transport = transports.get(sessionId) as SSEServerTransport;
+ console.error("Client Reconnecting? This shouldn't happen; when client has a sessionId, GET /sse should not be called again.", transport.sessionId);
+ } else {
+ // Create and store transport for new session
+ transport = new SSEServerTransport("/message", res);
+ transports.set(transport.sessionId, transport);
+
+ // Connect server to transport
+ await server.connect(transport);
+ console.error("Client Connected: ", transport.sessionId);
+
+ // Handle close of connection
+ server.onclose = async () => {
+ console.error("Client Disconnected: ", transport.sessionId);
+ transports.delete(transport.sessionId);
+ await cleanup();
+ };
+
+ }
- server.onclose = async () => {
- await cleanup();
- await server.close();
- process.exit(0);
- };
});
app.post("/message", async (req, res) => {
- console.log("Received message");
-
- await transport.handlePostMessage(req, res);
+ const sessionId = (req?.query?.sessionId as string);
+ const transport = transports.get(sessionId);
+ if (transport) {
+ console.error("Client Message from", sessionId);
+ await transport.handlePostMessage(req, res);
+ } else {
+ console.error(`No transport found for sessionId ${sessionId}`)
+ }
});
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
- console.log(`Server is running on port ${PORT}`);
+ console.error(`Server is running on port ${PORT}`);
});
diff --git a/src/everything/stdio.ts b/src/everything/stdio.ts
new file mode 100644
index 00000000..a98fbc53
--- /dev/null
+++ b/src/everything/stdio.ts
@@ -0,0 +1,26 @@
+#!/usr/bin/env node
+
+import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
+import { createServer } from "./everything.js";
+
+console.error('Starting default (STDIO) server...');
+
+async function main() {
+ const transport = new StdioServerTransport();
+ const {server, cleanup} = createServer();
+
+ await server.connect(transport);
+
+ // Cleanup on exit
+ process.on("SIGINT", async () => {
+ await cleanup();
+ await server.close();
+ process.exit(0);
+ });
+}
+
+main().catch((error) => {
+ console.error("Server error:", error);
+ process.exit(1);
+});
+
diff --git a/src/everything/streamableHttp.ts b/src/everything/streamableHttp.ts
new file mode 100644
index 00000000..f748fd2a
--- /dev/null
+++ b/src/everything/streamableHttp.ts
@@ -0,0 +1,176 @@
+import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
+import { InMemoryEventStore } from '@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js';
+import express, { Request, Response } from "express";
+import { createServer } from "./everything.js";
+import { randomUUID } from 'node:crypto';
+
+console.error('Starting Streamable HTTP server...');
+
+const app = express();
+
+const transports: Map = new Map();
+
+app.post('/mcp', async (req: Request, res: Response) => {
+ console.error('Received MCP POST request');
+ try {
+ // Check for existing session ID
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
+ let transport: StreamableHTTPServerTransport;
+
+ if (sessionId && transports.has(sessionId)) {
+ // Reuse existing transport
+ transport = transports.get(sessionId)!;
+ } else if (!sessionId) {
+
+ const { server, cleanup } = createServer();
+
+ // New initialization request
+ const eventStore = new InMemoryEventStore();
+ transport = new StreamableHTTPServerTransport({
+ sessionIdGenerator: () => randomUUID(),
+ eventStore, // Enable resumability
+ onsessioninitialized: (sessionId: string) => {
+ // Store the transport by session ID when session is initialized
+ // This avoids race conditions where requests might come in before the session is stored
+ console.error(`Session initialized with ID: ${sessionId}`);
+ transports.set(sessionId, transport);
+ }
+ });
+
+
+ // Set up onclose handler to clean up transport when closed
+ server.onclose = async () => {
+ const sid = transport.sessionId;
+ if (sid && transports.has(sid)) {
+ console.error(`Transport closed for session ${sid}, removing from transports map`);
+ transports.delete(sid);
+ await cleanup();
+ }
+ };
+
+ // Connect the transport to the MCP server BEFORE handling the request
+ // so responses can flow back through the same transport
+ await server.connect(transport);
+
+ await transport.handleRequest(req, res);
+ return; // Already handled
+ } else {
+ // Invalid request - no session ID or not initialization request
+ res.status(400).json({
+ jsonrpc: '2.0',
+ error: {
+ code: -32000,
+ message: 'Bad Request: No valid session ID provided',
+ },
+ id: req?.body?.id,
+ });
+ return;
+ }
+
+ // Handle the request with existing transport - no need to reconnect
+ // The existing transport is already connected to the server
+ await transport.handleRequest(req, res);
+ } catch (error) {
+ console.error('Error handling MCP request:', error);
+ if (!res.headersSent) {
+ res.status(500).json({
+ jsonrpc: '2.0',
+ error: {
+ code: -32603,
+ message: 'Internal server error',
+ },
+ id: req?.body?.id,
+ });
+ return;
+ }
+ }
+});
+
+// Handle GET requests for SSE streams (using built-in support from StreamableHTTP)
+app.get('/mcp', async (req: Request, res: Response) => {
+ console.error('Received MCP GET request');
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
+ if (!sessionId || !transports.has(sessionId)) {
+ res.status(400).json({
+ jsonrpc: '2.0',
+ error: {
+ code: -32000,
+ message: 'Bad Request: No valid session ID provided',
+ },
+ id: req?.body?.id,
+ });
+ return;
+ }
+
+ // Check for Last-Event-ID header for resumability
+ const lastEventId = req.headers['last-event-id'] as string | undefined;
+ if (lastEventId) {
+ console.error(`Client reconnecting with Last-Event-ID: ${lastEventId}`);
+ } else {
+ console.error(`Establishing new SSE stream for session ${sessionId}`);
+ }
+
+ const transport = transports.get(sessionId);
+ await transport!.handleRequest(req, res);
+});
+
+// Handle DELETE requests for session termination (according to MCP spec)
+app.delete('/mcp', async (req: Request, res: Response) => {
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
+ if (!sessionId || !transports.has(sessionId)) {
+ res.status(400).json({
+ jsonrpc: '2.0',
+ error: {
+ code: -32000,
+ message: 'Bad Request: No valid session ID provided',
+ },
+ id: req?.body?.id,
+ });
+ return;
+ }
+
+ console.error(`Received session termination request for session ${sessionId}`);
+
+ try {
+ const transport = transports.get(sessionId);
+ await transport!.handleRequest(req, res);
+ } catch (error) {
+ console.error('Error handling session termination:', error);
+ if (!res.headersSent) {
+ res.status(500).json({
+ jsonrpc: '2.0',
+ error: {
+ code: -32603,
+ message: 'Error handling session termination',
+ },
+ id: req?.body?.id,
+ });
+ return;
+ }
+ }
+});
+
+// Start the server
+const PORT = process.env.PORT || 3001;
+app.listen(PORT, () => {
+ console.error(`MCP Streamable HTTP Server listening on port ${PORT}`);
+});
+
+// Handle server shutdown
+process.on('SIGINT', async () => {
+ console.error('Shutting down server...');
+
+ // Close all active transports to properly clean up resources
+ for (const sessionId in transports) {
+ try {
+ console.error(`Closing transport for session ${sessionId}`);
+ await transports.get(sessionId)!.close();
+ transports.delete(sessionId);
+ } catch (error) {
+ console.error(`Error closing transport for session ${sessionId}:`, error);
+ }
+ }
+
+ console.error('Server shutdown complete');
+ process.exit(0);
+});
diff --git a/src/fetch/README.md b/src/fetch/README.md
index 01d99cac..5324e507 100644
--- a/src/fetch/README.md
+++ b/src/fetch/README.md
@@ -2,6 +2,9 @@
A Model Context Protocol server that provides web content fetching capabilities. This server enables LLMs to retrieve and process content from web pages, converting HTML to markdown for easier consumption.
+> [!CAUTION]
+> This server can access local/internal IP addresses and may represent a security risk. Exercise caution when using this MCP server to ensure this does not expose any sensitive data.
+
The fetch tool will truncate the response, but by using the `start_index` argument, you can specify where to start the content extraction. This lets models read a webpage in chunks, until they find the information they need.
### Available Tools
@@ -52,10 +55,12 @@ Add to your Claude settings:
Using uvx
```json
-"mcpServers": {
- "fetch": {
- "command": "uvx",
- "args": ["mcp-server-fetch"]
+{
+ "mcpServers": {
+ "fetch": {
+ "command": "uvx",
+ "args": ["mcp-server-fetch"]
+ }
}
}
```
@@ -65,10 +70,12 @@ Add to your Claude settings:
Using docker
```json
-"mcpServers": {
- "fetch": {
- "command": "docker",
- "args": ["run", "-i", "--rm", "mcp/fetch"]
+{
+ "mcpServers": {
+ "fetch": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm", "mcp/fetch"]
+ }
}
}
```
@@ -78,10 +85,60 @@ Add to your Claude settings:
Using pip installation
```json
-"mcpServers": {
- "fetch": {
- "command": "python",
- "args": ["-m", "mcp_server_fetch"]
+{
+ "mcpServers": {
+ "fetch": {
+ "command": "python",
+ "args": ["-m", "mcp_server_fetch"]
+ }
+ }
+}
+```
+
+
+### Configure for VS Code
+
+For quick installation, use one of the one-click install buttons below...
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=fetch&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-fetch%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=fetch&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-fetch%22%5D%7D&quality=insiders)
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=fetch&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Ffetch%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=fetch&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Ffetch%22%5D%7D&quality=insiders)
+
+For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
+
+Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
+
+> Note that the `mcp` key is needed when using the `mcp.json` file.
+
+
+Using uvx
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "fetch": {
+ "command": "uvx",
+ "args": ["mcp-server-fetch"]
+ }
+ }
+ }
+}
+```
+
+
+
+Using Docker
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "fetch": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm", "mcp/fetch"]
+ }
+ }
}
}
```
diff --git a/src/filesystem/README.md b/src/filesystem/README.md
index 3d3fb485..cd6d0a9f 100644
--- a/src/filesystem/README.md
+++ b/src/filesystem/README.md
@@ -9,8 +9,58 @@ Node.js server implementing Model Context Protocol (MCP) for filesystem operatio
- Move files/directories
- Search files
- Get file metadata
+- Dynamic directory access control via [Roots](https://modelcontextprotocol.io/docs/concepts/roots)
+
+## Directory Access Control
+
+The server uses a flexible directory access control system. Directories can be specified via command-line arguments or dynamically via [Roots](https://modelcontextprotocol.io/docs/concepts/roots).
+
+### Method 1: Command-line Arguments
+Specify Allowed directories when starting the server:
+```bash
+mcp-server-filesystem /path/to/dir1 /path/to/dir2
+```
+
+### Method 2: MCP Roots (Recommended)
+MCP clients that support [Roots](https://modelcontextprotocol.io/docs/concepts/roots) can dynamically update the Allowed directories.
+
+Roots notified by Client to Server, completely replace any server-side Allowed directories when provided.
+
+**Important**: If server starts without command-line arguments AND client doesn't support roots protocol (or provides empty roots), the server will throw an error during initialization.
+
+This is the recommended method, as this enables runtime directory updates via `roots/list_changed` notifications without server restart, providing a more flexible and modern integration experience.
+
+### How It Works
+
+The server's directory access control follows this flow:
+
+1. **Server Startup**
+ - Server starts with directories from command-line arguments (if provided)
+ - If no arguments provided, server starts with empty allowed directories
+
+2. **Client Connection & Initialization**
+ - Client connects and sends `initialize` request with capabilities
+ - Server checks if client supports roots protocol (`capabilities.roots`)
+
+3. **Roots Protocol Handling** (if client supports roots)
+ - **On initialization**: Server requests roots from client via `roots/list`
+ - Client responds with its configured roots
+ - Server replaces ALL allowed directories with client's roots
+ - **On runtime updates**: Client can send `notifications/roots/list_changed`
+ - Server requests updated roots and replaces allowed directories again
+
+4. **Fallback Behavior** (if client doesn't support roots)
+ - Server continues using command-line directories only
+ - No dynamic updates possible
+
+5. **Access Control**
+ - All filesystem operations are restricted to allowed directories
+ - Use `list_allowed_directories` tool to see current directories
+ - Server requires at least ONE allowed directory to operate
+
+**Note**: The server will only allow operations within directories specified either via `args` or via Roots.
+
-**Note**: The server will only allow operations within directories specified via `args`.
## API
@@ -143,6 +193,64 @@ Note: all directories must be mounted to `/projects` by default.
}
```
+## Usage with VS Code
+
+For quick installation, click the installation buttons below...
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-filesystem%22%2C%22%24%7BworkspaceFolder%7D%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-filesystem%22%2C%22%24%7BworkspaceFolder%7D%22%5D%7D&quality=insiders)
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22--mount%22%2C%22type%3Dbind%2Csrc%3D%24%7BworkspaceFolder%7D%2Cdst%3D%2Fprojects%2Fworkspace%22%2C%22mcp%2Ffilesystem%22%2C%22%2Fprojects%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=filesystem&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22--mount%22%2C%22type%3Dbind%2Csrc%3D%24%7BworkspaceFolder%7D%2Cdst%3D%2Fprojects%2Fworkspace%22%2C%22mcp%2Ffilesystem%22%2C%22%2Fprojects%22%5D%7D&quality=insiders)
+
+For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open Settings (JSON)`.
+
+Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
+
+> Note that the `mcp` key is not needed in the `.vscode/mcp.json` file.
+
+You can provide sandboxed directories to the server by mounting them to `/projects`. Adding the `ro` flag will make the directory readonly by the server.
+
+### Docker
+Note: all directories must be mounted to `/projects` by default.
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "filesystem": {
+ "command": "docker",
+ "args": [
+ "run",
+ "-i",
+ "--rm",
+ "--mount", "type=bind,src=${workspaceFolder},dst=/projects/workspace",
+ "mcp/filesystem",
+ "/projects"
+ ]
+ }
+ }
+ }
+}
+```
+
+### NPX
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "filesystem": {
+ "command": "npx",
+ "args": [
+ "-y",
+ "@modelcontextprotocol/server-filesystem",
+ "${workspaceFolder}"
+ ]
+ }
+ }
+ }
+}
+```
+
## Build
Docker build:
diff --git a/src/filesystem/__tests__/path-utils.test.ts b/src/filesystem/__tests__/path-utils.test.ts
new file mode 100644
index 00000000..00df4e04
--- /dev/null
+++ b/src/filesystem/__tests__/path-utils.test.ts
@@ -0,0 +1,169 @@
+import { describe, it, expect } from '@jest/globals';
+import { normalizePath, expandHome, convertToWindowsPath } from '../path-utils.js';
+
+describe('Path Utilities', () => {
+ describe('convertToWindowsPath', () => {
+ it('leaves Unix paths unchanged', () => {
+ expect(convertToWindowsPath('/usr/local/bin'))
+ .toBe('/usr/local/bin');
+ expect(convertToWindowsPath('/home/user/some path'))
+ .toBe('/home/user/some path');
+ });
+
+ it('converts WSL paths to Windows format', () => {
+ expect(convertToWindowsPath('/mnt/c/NS/MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ });
+
+ it('converts Unix-style Windows paths to Windows format', () => {
+ expect(convertToWindowsPath('/c/NS/MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ });
+
+ it('leaves Windows paths unchanged but ensures backslashes', () => {
+ expect(convertToWindowsPath('C:\\NS\\MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ expect(convertToWindowsPath('C:/NS/MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ });
+
+ it('handles Windows paths with spaces', () => {
+ expect(convertToWindowsPath('C:\\Program Files\\Some App'))
+ .toBe('C:\\Program Files\\Some App');
+ expect(convertToWindowsPath('C:/Program Files/Some App'))
+ .toBe('C:\\Program Files\\Some App');
+ });
+
+ it('handles uppercase and lowercase drive letters', () => {
+ expect(convertToWindowsPath('/mnt/d/some/path'))
+ .toBe('D:\\some\\path');
+ expect(convertToWindowsPath('/d/some/path'))
+ .toBe('D:\\some\\path');
+ });
+ });
+
+ describe('normalizePath', () => {
+ it('preserves Unix paths', () => {
+ expect(normalizePath('/usr/local/bin'))
+ .toBe('/usr/local/bin');
+ expect(normalizePath('/home/user/some path'))
+ .toBe('/home/user/some path');
+ expect(normalizePath('"/usr/local/some app/"'))
+ .toBe('/usr/local/some app');
+ });
+
+ it('removes surrounding quotes', () => {
+ expect(normalizePath('"C:\\NS\\My Kindle Content"'))
+ .toBe('C:\\NS\\My Kindle Content');
+ });
+
+ it('normalizes backslashes', () => {
+ expect(normalizePath('C:\\\\NS\\\\MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ });
+
+ it('converts forward slashes to backslashes on Windows', () => {
+ expect(normalizePath('C:/NS/MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ });
+
+ it('handles WSL paths', () => {
+ expect(normalizePath('/mnt/c/NS/MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ });
+
+ it('handles Unix-style Windows paths', () => {
+ expect(normalizePath('/c/NS/MyKindleContent'))
+ .toBe('C:\\NS\\MyKindleContent');
+ });
+
+ it('handles paths with spaces and mixed slashes', () => {
+ expect(normalizePath('C:/NS/My Kindle Content'))
+ .toBe('C:\\NS\\My Kindle Content');
+ expect(normalizePath('/mnt/c/NS/My Kindle Content'))
+ .toBe('C:\\NS\\My Kindle Content');
+ expect(normalizePath('C:\\Program Files (x86)\\App Name'))
+ .toBe('C:\\Program Files (x86)\\App Name');
+ expect(normalizePath('"C:\\Program Files\\App Name"'))
+ .toBe('C:\\Program Files\\App Name');
+ expect(normalizePath(' C:\\Program Files\\App Name '))
+ .toBe('C:\\Program Files\\App Name');
+ });
+
+ it('preserves spaces in all path formats', () => {
+ expect(normalizePath('/mnt/c/Program Files/App Name'))
+ .toBe('C:\\Program Files\\App Name');
+ expect(normalizePath('/c/Program Files/App Name'))
+ .toBe('C:\\Program Files\\App Name');
+ expect(normalizePath('C:/Program Files/App Name'))
+ .toBe('C:\\Program Files\\App Name');
+ });
+
+ it('handles special characters in paths', () => {
+ // Test ampersand in path
+ expect(normalizePath('C:\\NS\\Sub&Folder'))
+ .toBe('C:\\NS\\Sub&Folder');
+ expect(normalizePath('C:/NS/Sub&Folder'))
+ .toBe('C:\\NS\\Sub&Folder');
+ expect(normalizePath('/mnt/c/NS/Sub&Folder'))
+ .toBe('C:\\NS\\Sub&Folder');
+
+ // Test tilde in path (short names in Windows)
+ expect(normalizePath('C:\\NS\\MYKIND~1'))
+ .toBe('C:\\NS\\MYKIND~1');
+ expect(normalizePath('/Users/NEMANS~1/FOLDER~2/SUBFO~1/Public/P12PST~1'))
+ .toBe('/Users/NEMANS~1/FOLDER~2/SUBFO~1/Public/P12PST~1');
+
+ // Test other special characters
+ expect(normalizePath('C:\\Path with #hash'))
+ .toBe('C:\\Path with #hash');
+ expect(normalizePath('C:\\Path with (parentheses)'))
+ .toBe('C:\\Path with (parentheses)');
+ expect(normalizePath('C:\\Path with [brackets]'))
+ .toBe('C:\\Path with [brackets]');
+ expect(normalizePath('C:\\Path with @at+plus$dollar%percent'))
+ .toBe('C:\\Path with @at+plus$dollar%percent');
+ });
+
+ it('capitalizes lowercase drive letters for Windows paths', () => {
+ expect(normalizePath('c:/windows/system32'))
+ .toBe('C:\\windows\\system32');
+ expect(normalizePath('/mnt/d/my/folder')) // WSL path with lowercase drive
+ .toBe('D:\\my\\folder');
+ expect(normalizePath('/e/another/folder')) // Unix-style Windows path with lowercase drive
+ .toBe('E:\\another\\folder');
+ });
+
+ it('handles UNC paths correctly', () => {
+ // UNC paths should preserve the leading double backslash
+ const uncPath = '\\\\SERVER\\share\\folder';
+ expect(normalizePath(uncPath)).toBe('\\\\SERVER\\share\\folder');
+
+ // Test UNC path with double backslashes that need normalization
+ const uncPathWithDoubles = '\\\\\\\\SERVER\\\\share\\\\folder';
+ expect(normalizePath(uncPathWithDoubles)).toBe('\\\\SERVER\\share\\folder');
+ });
+
+ it('returns normalized non-Windows/WSL/Unix-style Windows paths as is after basic normalization', () => {
+ // Relative path
+ const relativePath = 'some/relative/path';
+ expect(normalizePath(relativePath)).toBe(relativePath.replace(/\//g, '\\'));
+
+ // A path that looks somewhat absolute but isn't a drive or recognized Unix root for Windows conversion
+ const otherAbsolutePath = '\\someserver\\share\\file';
+ expect(normalizePath(otherAbsolutePath)).toBe(otherAbsolutePath);
+ });
+ });
+
+ describe('expandHome', () => {
+ it('expands ~ to home directory', () => {
+ const result = expandHome('~/test');
+ expect(result).toContain('test');
+ expect(result).not.toContain('~');
+ });
+
+ it('leaves other paths unchanged', () => {
+ expect(expandHome('C:/test')).toBe('C:/test');
+ });
+ });
+});
diff --git a/src/filesystem/__tests__/path-validation.test.ts b/src/filesystem/__tests__/path-validation.test.ts
new file mode 100644
index 00000000..38a72573
--- /dev/null
+++ b/src/filesystem/__tests__/path-validation.test.ts
@@ -0,0 +1,844 @@
+import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
+import * as path from 'path';
+import * as fs from 'fs/promises';
+import * as os from 'os';
+import { isPathWithinAllowedDirectories } from '../path-validation.js';
+
+describe('Path Validation', () => {
+ it('allows exact directory match', () => {
+ const allowed = ['/home/user/project'];
+ expect(isPathWithinAllowedDirectories('/home/user/project', allowed)).toBe(true);
+ });
+
+ it('allows subdirectories', () => {
+ const allowed = ['/home/user/project'];
+ expect(isPathWithinAllowedDirectories('/home/user/project/src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/src/index.js', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/deeply/nested/file.txt', allowed)).toBe(true);
+ });
+
+ it('blocks similar directory names (prefix vulnerability)', () => {
+ const allowed = ['/home/user/project'];
+ expect(isPathWithinAllowedDirectories('/home/user/project2', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project_backup', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project-old', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/projectile', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project.bak', allowed)).toBe(false);
+ });
+
+ it('blocks paths outside allowed directories', () => {
+ const allowed = ['/home/user/project'];
+ expect(isPathWithinAllowedDirectories('/home/user/other', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/etc/passwd', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/', allowed)).toBe(false);
+ });
+
+ it('handles multiple allowed directories', () => {
+ const allowed = ['/home/user/project1', '/home/user/project2'];
+ expect(isPathWithinAllowedDirectories('/home/user/project1/src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project2/src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project3', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project1_backup', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project2-old', allowed)).toBe(false);
+ });
+
+ it('blocks parent and sibling directories', () => {
+ const allowed = ['/test/allowed'];
+
+ // Parent directory
+ expect(isPathWithinAllowedDirectories('/test', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/', allowed)).toBe(false);
+
+ // Sibling with common prefix
+ expect(isPathWithinAllowedDirectories('/test/allowed_sibling', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/test/allowed2', allowed)).toBe(false);
+ });
+
+ it('handles paths with special characters', () => {
+ const allowed = ['/home/user/my-project (v2)'];
+
+ expect(isPathWithinAllowedDirectories('/home/user/my-project (v2)', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/my-project (v2)/src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/my-project (v2)_backup', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/my-project', allowed)).toBe(false);
+ });
+
+ describe('Input validation', () => {
+ it('rejects empty inputs', () => {
+ const allowed = ['/home/user/project'];
+
+ expect(isPathWithinAllowedDirectories('', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project', [])).toBe(false);
+ });
+
+ it('handles trailing separators correctly', () => {
+ const allowed = ['/home/user/project'];
+
+ // Path with trailing separator should still match
+ expect(isPathWithinAllowedDirectories('/home/user/project/', allowed)).toBe(true);
+
+ // Allowed directory with trailing separator
+ const allowedWithSep = ['/home/user/project/'];
+ expect(isPathWithinAllowedDirectories('/home/user/project', allowedWithSep)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/', allowedWithSep)).toBe(true);
+
+ // Should still block similar names with or without trailing separators
+ expect(isPathWithinAllowedDirectories('/home/user/project2', allowedWithSep)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project2', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project2/', allowed)).toBe(false);
+ });
+
+ it('skips empty directory entries in allowed list', () => {
+ const allowed = ['', '/home/user/project', ''];
+ expect(isPathWithinAllowedDirectories('/home/user/project', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/src', allowed)).toBe(true);
+
+ // Should still validate properly with empty entries
+ expect(isPathWithinAllowedDirectories('/home/user/other', allowed)).toBe(false);
+ });
+
+ it('handles Windows paths with trailing separators', () => {
+ if (path.sep === '\\') {
+ const allowed = ['C:\\Users\\project'];
+
+ // Path with trailing separator
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project\\', allowed)).toBe(true);
+
+ // Allowed with trailing separator
+ const allowedWithSep = ['C:\\Users\\project\\'];
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project', allowedWithSep)).toBe(true);
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project\\', allowedWithSep)).toBe(true);
+
+ // Should still block similar names
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project2\\', allowed)).toBe(false);
+ }
+ });
+ });
+
+ describe('Error handling', () => {
+ it('normalizes relative paths to absolute', () => {
+ const allowed = [process.cwd()];
+
+ // Relative paths get normalized to absolute paths based on cwd
+ expect(isPathWithinAllowedDirectories('relative/path', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('./file', allowed)).toBe(true);
+
+ // Parent directory references that escape allowed directory
+ const parentAllowed = ['/home/user/project'];
+ expect(isPathWithinAllowedDirectories('../parent', parentAllowed)).toBe(false);
+ });
+
+ it('returns false for relative paths in allowed directories', () => {
+ const badAllowed = ['relative/path', '/some/other/absolute/path'];
+
+ // Relative paths in allowed dirs are normalized to absolute based on cwd
+ // The normalized 'relative/path' won't match our test path
+ expect(isPathWithinAllowedDirectories('/some/other/absolute/path/file', badAllowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/absolute/path/file', badAllowed)).toBe(false);
+ });
+
+ it('handles null and undefined inputs gracefully', () => {
+ const allowed = ['/home/user/project'];
+
+ // Should return false, not crash
+ expect(isPathWithinAllowedDirectories(null as any, allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories(undefined as any, allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/path', null as any)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/path', undefined as any)).toBe(false);
+ });
+ });
+
+ describe('Unicode and special characters', () => {
+ it('handles unicode characters in paths', () => {
+ const allowed = ['/home/user/café'];
+
+ expect(isPathWithinAllowedDirectories('/home/user/café', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/café/file', allowed)).toBe(true);
+
+ // Different unicode representation won't match (not normalized)
+ const decomposed = '/home/user/cafe\u0301'; // e + combining accent
+ expect(isPathWithinAllowedDirectories(decomposed, allowed)).toBe(false);
+ });
+
+ it('handles paths with spaces correctly', () => {
+ const allowed = ['/home/user/my project'];
+
+ expect(isPathWithinAllowedDirectories('/home/user/my project', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/my project/file', allowed)).toBe(true);
+
+ // Partial matches should fail
+ expect(isPathWithinAllowedDirectories('/home/user/my', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/my proj', allowed)).toBe(false);
+ });
+ });
+
+ describe('Overlapping allowed directories', () => {
+ it('handles nested allowed directories correctly', () => {
+ const allowed = ['/home', '/home/user', '/home/user/project'];
+
+ // All paths under /home are allowed
+ expect(isPathWithinAllowedDirectories('/home/anything', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/anything', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/anything', allowed)).toBe(true);
+
+ // First match wins (most permissive)
+ expect(isPathWithinAllowedDirectories('/home/other/deep/path', allowed)).toBe(true);
+ });
+
+ it('handles root directory as allowed', () => {
+ const allowed = ['/'];
+
+ // Everything is allowed under root (dangerous configuration)
+ expect(isPathWithinAllowedDirectories('/', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/any/path', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/etc/passwd', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/secret', allowed)).toBe(true);
+
+ // But only on the same filesystem root
+ if (path.sep === '\\') {
+ expect(isPathWithinAllowedDirectories('D:\\other', ['/'])).toBe(false);
+ }
+ });
+ });
+
+ describe('Cross-platform behavior', () => {
+ it('handles Windows-style paths on Windows', () => {
+ if (path.sep === '\\') {
+ const allowed = ['C:\\Users\\project'];
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project\\src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project2', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('C:\\Users\\project_backup', allowed)).toBe(false);
+ }
+ });
+
+ it('handles Unix-style paths on Unix', () => {
+ if (path.sep === '/') {
+ const allowed = ['/home/user/project'];
+ expect(isPathWithinAllowedDirectories('/home/user/project', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project2', allowed)).toBe(false);
+ }
+ });
+ });
+
+ describe('Validation Tests - Path Traversal', () => {
+ it('blocks path traversal attempts', () => {
+ const allowed = ['/home/user/project'];
+
+ // Basic traversal attempts
+ expect(isPathWithinAllowedDirectories('/home/user/project/../../../etc/passwd', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project/../../other', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project/../project2', allowed)).toBe(false);
+
+ // Mixed traversal with valid segments
+ expect(isPathWithinAllowedDirectories('/home/user/project/src/../../project2', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project/./../../other', allowed)).toBe(false);
+
+ // Multiple traversal sequences
+ expect(isPathWithinAllowedDirectories('/home/user/project/../project/../../../etc', allowed)).toBe(false);
+ });
+
+ it('blocks traversal in allowed directories', () => {
+ const allowed = ['/home/user/project/../safe'];
+
+ // The allowed directory itself should be normalized and safe
+ expect(isPathWithinAllowedDirectories('/home/user/safe/file', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/file', allowed)).toBe(false);
+ });
+
+ it('handles complex traversal patterns', () => {
+ const allowed = ['/home/user/project'];
+
+ // Double dots in filenames (not traversal) - these normalize to paths within allowed dir
+ expect(isPathWithinAllowedDirectories('/home/user/project/..test', allowed)).toBe(true); // Not traversal
+ expect(isPathWithinAllowedDirectories('/home/user/project/test..', allowed)).toBe(true); // Not traversal
+ expect(isPathWithinAllowedDirectories('/home/user/project/te..st', allowed)).toBe(true); // Not traversal
+
+ // Actual traversal
+ expect(isPathWithinAllowedDirectories('/home/user/project/../test', allowed)).toBe(false); // Is traversal - goes to /home/user/test
+
+ // Edge case: /home/user/project/.. normalizes to /home/user (parent dir)
+ expect(isPathWithinAllowedDirectories('/home/user/project/..', allowed)).toBe(false); // Goes to parent
+ });
+ });
+
+ describe('Validation Tests - Null Bytes', () => {
+ it('rejects paths with null bytes', () => {
+ const allowed = ['/home/user/project'];
+
+ expect(isPathWithinAllowedDirectories('/home/user/project\x00/etc/passwd', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project/test\x00.txt', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('\x00/home/user/project', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project/\x00', allowed)).toBe(false);
+ });
+
+ it('rejects allowed directories with null bytes', () => {
+ const allowed = ['/home/user/project\x00'];
+
+ expect(isPathWithinAllowedDirectories('/home/user/project', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project/file', allowed)).toBe(false);
+ });
+ });
+
+ describe('Validation Tests - Special Characters', () => {
+ it('allows percent signs in filenames', () => {
+ const allowed = ['/home/user/project'];
+
+ // Percent is a valid filename character
+ expect(isPathWithinAllowedDirectories('/home/user/project/report_50%.pdf', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/Q1_25%_growth', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/%41', allowed)).toBe(true); // File named %41
+
+ // URL encoding is NOT decoded by path.normalize, so these are just odd filenames
+ expect(isPathWithinAllowedDirectories('/home/user/project/%2e%2e', allowed)).toBe(true); // File named "%2e%2e"
+ expect(isPathWithinAllowedDirectories('/home/user/project/file%20name', allowed)).toBe(true); // File with %20 in name
+ });
+
+ it('handles percent signs in allowed directories', () => {
+ const allowed = ['/home/user/project%20files'];
+
+ // This is a directory literally named "project%20files"
+ expect(isPathWithinAllowedDirectories('/home/user/project%20files/test', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project files/test', allowed)).toBe(false); // Different dir
+ });
+ });
+
+ describe('Path Normalization', () => {
+ it('normalizes paths before comparison', () => {
+ const allowed = ['/home/user/project'];
+
+ // Trailing slashes
+ expect(isPathWithinAllowedDirectories('/home/user/project/', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project//', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project///', allowed)).toBe(true);
+
+ // Current directory references
+ expect(isPathWithinAllowedDirectories('/home/user/project/./src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/./project/src', allowed)).toBe(true);
+
+ // Multiple slashes
+ expect(isPathWithinAllowedDirectories('/home/user/project//src//file', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home//user//project//src', allowed)).toBe(true);
+
+ // Should still block outside paths
+ expect(isPathWithinAllowedDirectories('/home/user//project2', allowed)).toBe(false);
+ });
+
+ it('handles mixed separators correctly', () => {
+ if (path.sep === '\\') {
+ const allowed = ['C:\\Users\\project'];
+
+ // Mixed separators should be normalized
+ expect(isPathWithinAllowedDirectories('C:/Users/project', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('C:\\Users/project\\src', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('C:/Users\\project/src', allowed)).toBe(true);
+ }
+ });
+ });
+
+ describe('Edge Cases', () => {
+ it('rejects non-string inputs safely', () => {
+ const allowed = ['/home/user/project'];
+
+ expect(isPathWithinAllowedDirectories(123 as any, allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories({} as any, allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories([] as any, allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories(null as any, allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories(undefined as any, allowed)).toBe(false);
+
+ // Non-string in allowed directories
+ expect(isPathWithinAllowedDirectories('/home/user/project', [123 as any])).toBe(false);
+ expect(isPathWithinAllowedDirectories('/home/user/project', [{} as any])).toBe(false);
+ });
+
+ it('handles very long paths', () => {
+ const allowed = ['/home/user/project'];
+
+ // Create a very long path that's still valid
+ const longSubPath = 'a/'.repeat(1000) + 'file.txt';
+ expect(isPathWithinAllowedDirectories(`/home/user/project/${longSubPath}`, allowed)).toBe(true);
+
+ // Very long path that escapes
+ const escapePath = 'a/'.repeat(1000) + '../'.repeat(1001) + 'etc/passwd';
+ expect(isPathWithinAllowedDirectories(`/home/user/project/${escapePath}`, allowed)).toBe(false);
+ });
+ });
+
+ describe('Additional Coverage', () => {
+ it('handles allowed directories with traversal that normalizes safely', () => {
+ // These allowed dirs contain traversal but normalize to valid paths
+ const allowed = ['/home/user/../user/project'];
+
+ // Should normalize to /home/user/project and work correctly
+ expect(isPathWithinAllowedDirectories('/home/user/project/file', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/other', allowed)).toBe(false);
+ });
+
+ it('handles symbolic dots in filenames', () => {
+ const allowed = ['/home/user/project'];
+
+ // Single and double dots as actual filenames (not traversal)
+ expect(isPathWithinAllowedDirectories('/home/user/project/.', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('/home/user/project/..', allowed)).toBe(false); // This normalizes to parent
+ expect(isPathWithinAllowedDirectories('/home/user/project/...', allowed)).toBe(true); // Three dots is a valid filename
+ expect(isPathWithinAllowedDirectories('/home/user/project/....', allowed)).toBe(true); // Four dots is a valid filename
+ });
+
+ it('handles UNC paths on Windows', () => {
+ if (path.sep === '\\') {
+ const allowed = ['\\\\server\\share\\project'];
+
+ expect(isPathWithinAllowedDirectories('\\\\server\\share\\project', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('\\\\server\\share\\project\\file', allowed)).toBe(true);
+ expect(isPathWithinAllowedDirectories('\\\\server\\share\\other', allowed)).toBe(false);
+ expect(isPathWithinAllowedDirectories('\\\\other\\share\\project', allowed)).toBe(false);
+ }
+ });
+ });
+
+ describe('Symlink Tests', () => {
+ let testDir: string;
+ let allowedDir: string;
+ let forbiddenDir: string;
+
+ beforeEach(async () => {
+ testDir = await fs.mkdtemp(path.join(os.tmpdir(), 'fs-error-test-'));
+ allowedDir = path.join(testDir, 'allowed');
+ forbiddenDir = path.join(testDir, 'forbidden');
+
+ await fs.mkdir(allowedDir, { recursive: true });
+ await fs.mkdir(forbiddenDir, { recursive: true });
+ });
+
+ afterEach(async () => {
+ await fs.rm(testDir, { recursive: true, force: true });
+ });
+
+ it('validates symlink handling', async () => {
+ // Test with symlinks
+ try {
+ const linkPath = path.join(allowedDir, 'bad-link');
+ const targetPath = path.join(forbiddenDir, 'target.txt');
+
+ await fs.writeFile(targetPath, 'content');
+ await fs.symlink(targetPath, linkPath);
+
+ // In real implementation, this would throw with the resolved path
+ const realPath = await fs.realpath(linkPath);
+ const allowed = [allowedDir];
+
+ // Symlink target should be outside allowed directory
+ expect(isPathWithinAllowedDirectories(realPath, allowed)).toBe(false);
+ } catch (error) {
+ // Skip if no symlink permissions
+ }
+ });
+
+ it('handles non-existent paths correctly', async () => {
+ const newFilePath = path.join(allowedDir, 'subdir', 'newfile.txt');
+
+ // Parent directory doesn't exist
+ try {
+ await fs.access(newFilePath);
+ } catch (error) {
+ expect((error as NodeJS.ErrnoException).code).toBe('ENOENT');
+ }
+
+ // After creating parent, validation should work
+ await fs.mkdir(path.dirname(newFilePath), { recursive: true });
+ const allowed = [allowedDir];
+ expect(isPathWithinAllowedDirectories(newFilePath, allowed)).toBe(true);
+ });
+
+ // Test path resolution consistency for symlinked files
+ it('validates symlinked files consistently between path and resolved forms', async () => {
+ try {
+ // Setup: Create target file in forbidden area
+ const targetFile = path.join(forbiddenDir, 'target.txt');
+ await fs.writeFile(targetFile, 'TARGET_CONTENT');
+
+ // Create symlink inside allowed directory pointing to forbidden file
+ const symlinkPath = path.join(allowedDir, 'link-to-target.txt');
+ await fs.symlink(targetFile, symlinkPath);
+
+ // The symlink path itself passes validation (looks like it's in allowed dir)
+ expect(isPathWithinAllowedDirectories(symlinkPath, [allowedDir])).toBe(true);
+
+ // But the resolved path should fail validation
+ const resolvedPath = await fs.realpath(symlinkPath);
+ expect(isPathWithinAllowedDirectories(resolvedPath, [allowedDir])).toBe(false);
+
+ // Verify the resolved path goes to the forbidden location (normalize both paths for macOS temp dirs)
+ expect(await fs.realpath(resolvedPath)).toBe(await fs.realpath(targetFile));
+ } catch (error) {
+ // Skip if no symlink permissions on the system
+ if ((error as NodeJS.ErrnoException).code !== 'EPERM') {
+ throw error;
+ }
+ }
+ });
+
+ // Test allowed directory resolution behavior
+ it('validates paths correctly when allowed directory is resolved from symlink', async () => {
+ try {
+ // Setup: Create the actual target directory with content
+ const actualTargetDir = path.join(testDir, 'actual-target');
+ await fs.mkdir(actualTargetDir, { recursive: true });
+ const targetFile = path.join(actualTargetDir, 'file.txt');
+ await fs.writeFile(targetFile, 'FILE_CONTENT');
+
+ // Setup: Create symlink directory that points to target
+ const symlinkDir = path.join(testDir, 'symlink-dir');
+ await fs.symlink(actualTargetDir, symlinkDir);
+
+ // Simulate resolved allowed directory (what the server startup should do)
+ const resolvedAllowedDir = await fs.realpath(symlinkDir);
+ const resolvedTargetDir = await fs.realpath(actualTargetDir);
+ expect(resolvedAllowedDir).toBe(resolvedTargetDir);
+
+ // Test 1: File access through original symlink path should pass validation with resolved allowed dir
+ const fileViaSymlink = path.join(symlinkDir, 'file.txt');
+ const resolvedFile = await fs.realpath(fileViaSymlink);
+ expect(isPathWithinAllowedDirectories(resolvedFile, [resolvedAllowedDir])).toBe(true);
+
+ // Test 2: File access through resolved path should also pass validation
+ const fileViaResolved = path.join(resolvedTargetDir, 'file.txt');
+ expect(isPathWithinAllowedDirectories(fileViaResolved, [resolvedAllowedDir])).toBe(true);
+
+ // Test 3: Demonstrate inconsistent behavior with unresolved allowed directories
+ // If allowed dirs were not resolved (storing symlink paths instead):
+ const unresolvedAllowedDirs = [symlinkDir];
+ // This validation would incorrectly fail for the same content:
+ expect(isPathWithinAllowedDirectories(resolvedFile, unresolvedAllowedDirs)).toBe(false);
+
+ } catch (error) {
+ // Skip if no symlink permissions on the system
+ if ((error as NodeJS.ErrnoException).code !== 'EPERM') {
+ throw error;
+ }
+ }
+ });
+
+ it('resolves nested symlink chains completely', async () => {
+ try {
+ // Setup: Create target file in forbidden area
+ const actualTarget = path.join(forbiddenDir, 'target-file.txt');
+ await fs.writeFile(actualTarget, 'FINAL_CONTENT');
+
+ // Create chain of symlinks: allowedFile -> link2 -> link1 -> actualTarget
+ const link1 = path.join(testDir, 'intermediate-link1');
+ const link2 = path.join(testDir, 'intermediate-link2');
+ const allowedFile = path.join(allowedDir, 'seemingly-safe-file');
+
+ await fs.symlink(actualTarget, link1);
+ await fs.symlink(link1, link2);
+ await fs.symlink(link2, allowedFile);
+
+ // The allowed file path passes basic validation
+ expect(isPathWithinAllowedDirectories(allowedFile, [allowedDir])).toBe(true);
+
+ // But complete resolution reveals the forbidden target
+ const fullyResolvedPath = await fs.realpath(allowedFile);
+ expect(isPathWithinAllowedDirectories(fullyResolvedPath, [allowedDir])).toBe(false);
+ expect(await fs.realpath(fullyResolvedPath)).toBe(await fs.realpath(actualTarget));
+
+ } catch (error) {
+ // Skip if no symlink permissions on the system
+ if ((error as NodeJS.ErrnoException).code !== 'EPERM') {
+ throw error;
+ }
+ }
+ });
+ });
+
+ describe('Path Validation Race Condition Tests', () => {
+ let testDir: string;
+ let allowedDir: string;
+ let forbiddenDir: string;
+ let targetFile: string;
+ let testPath: string;
+
+ beforeEach(async () => {
+ testDir = await fs.mkdtemp(path.join(os.tmpdir(), 'race-test-'));
+ allowedDir = path.join(testDir, 'allowed');
+ forbiddenDir = path.join(testDir, 'outside');
+ targetFile = path.join(forbiddenDir, 'target.txt');
+ testPath = path.join(allowedDir, 'test.txt');
+
+ await fs.mkdir(allowedDir, { recursive: true });
+ await fs.mkdir(forbiddenDir, { recursive: true });
+ await fs.writeFile(targetFile, 'ORIGINAL CONTENT', 'utf-8');
+ });
+
+ afterEach(async () => {
+ await fs.rm(testDir, { recursive: true, force: true });
+ });
+
+ it('validates non-existent file paths based on parent directory', async () => {
+ const allowed = [allowedDir];
+
+ expect(isPathWithinAllowedDirectories(testPath, allowed)).toBe(true);
+ await expect(fs.access(testPath)).rejects.toThrow();
+
+ const parentDir = path.dirname(testPath);
+ expect(isPathWithinAllowedDirectories(parentDir, allowed)).toBe(true);
+ });
+
+ it('demonstrates symlink race condition allows writing outside allowed directories', async () => {
+ const allowed = [allowedDir];
+
+ await expect(fs.access(testPath)).rejects.toThrow();
+ expect(isPathWithinAllowedDirectories(testPath, allowed)).toBe(true);
+
+ await fs.symlink(targetFile, testPath);
+ await fs.writeFile(testPath, 'MODIFIED CONTENT', 'utf-8');
+
+ const targetContent = await fs.readFile(targetFile, 'utf-8');
+ expect(targetContent).toBe('MODIFIED CONTENT');
+
+ const resolvedPath = await fs.realpath(testPath);
+ expect(isPathWithinAllowedDirectories(resolvedPath, allowed)).toBe(false);
+ });
+
+ it('shows timing differences between validation approaches', async () => {
+ const allowed = [allowedDir];
+
+ const validation1 = isPathWithinAllowedDirectories(testPath, allowed);
+ expect(validation1).toBe(true);
+
+ await fs.symlink(targetFile, testPath);
+
+ const resolvedPath = await fs.realpath(testPath);
+ const validation2 = isPathWithinAllowedDirectories(resolvedPath, allowed);
+ expect(validation2).toBe(false);
+
+ expect(validation1).not.toBe(validation2);
+ });
+
+ it('validates directory creation timing', async () => {
+ const allowed = [allowedDir];
+ const testDir = path.join(allowedDir, 'newdir');
+
+ expect(isPathWithinAllowedDirectories(testDir, allowed)).toBe(true);
+
+ await fs.symlink(forbiddenDir, testDir);
+
+ expect(isPathWithinAllowedDirectories(testDir, allowed)).toBe(true);
+
+ const resolved = await fs.realpath(testDir);
+ expect(isPathWithinAllowedDirectories(resolved, allowed)).toBe(false);
+ });
+
+ it('demonstrates exclusive file creation behavior', async () => {
+ const allowed = [allowedDir];
+
+ await fs.symlink(targetFile, testPath);
+
+ await expect(fs.open(testPath, 'wx')).rejects.toThrow(/EEXIST/);
+
+ await fs.writeFile(testPath, 'NEW CONTENT', 'utf-8');
+ const targetContent = await fs.readFile(targetFile, 'utf-8');
+ expect(targetContent).toBe('NEW CONTENT');
+ });
+
+ it('should use resolved parent paths for non-existent files', async () => {
+ const allowed = [allowedDir];
+
+ const symlinkDir = path.join(allowedDir, 'link');
+ await fs.symlink(forbiddenDir, symlinkDir);
+
+ const fileThroughSymlink = path.join(symlinkDir, 'newfile.txt');
+
+ expect(fileThroughSymlink.startsWith(allowedDir)).toBe(true);
+
+ const parentDir = path.dirname(fileThroughSymlink);
+ const resolvedParent = await fs.realpath(parentDir);
+ expect(isPathWithinAllowedDirectories(resolvedParent, allowed)).toBe(false);
+
+ const expectedSafePath = path.join(resolvedParent, path.basename(fileThroughSymlink));
+ expect(isPathWithinAllowedDirectories(expectedSafePath, allowed)).toBe(false);
+ });
+
+ it('demonstrates parent directory symlink traversal', async () => {
+ const allowed = [allowedDir];
+ const deepPath = path.join(allowedDir, 'sub1', 'sub2', 'file.txt');
+
+ expect(isPathWithinAllowedDirectories(deepPath, allowed)).toBe(true);
+
+ const sub1Path = path.join(allowedDir, 'sub1');
+ await fs.symlink(forbiddenDir, sub1Path);
+
+ await fs.mkdir(path.join(sub1Path, 'sub2'), { recursive: true });
+ await fs.writeFile(deepPath, 'CONTENT', 'utf-8');
+
+ const realPath = await fs.realpath(deepPath);
+ const realAllowedDir = await fs.realpath(allowedDir);
+ const realForbiddenDir = await fs.realpath(forbiddenDir);
+
+ expect(realPath.startsWith(realAllowedDir)).toBe(false);
+ expect(realPath.startsWith(realForbiddenDir)).toBe(true);
+ });
+
+ it('should prevent race condition between validatePath and file operation', async () => {
+ const allowed = [allowedDir];
+ const racePath = path.join(allowedDir, 'race-file.txt');
+ const targetFile = path.join(forbiddenDir, 'target.txt');
+
+ await fs.writeFile(targetFile, 'ORIGINAL CONTENT', 'utf-8');
+
+ // Path validation would pass (file doesn't exist, parent is in allowed dir)
+ expect(await fs.access(racePath).then(() => false).catch(() => true)).toBe(true);
+ expect(isPathWithinAllowedDirectories(racePath, allowed)).toBe(true);
+
+ // Race condition: symlink created after validation but before write
+ await fs.symlink(targetFile, racePath);
+
+ // With exclusive write flag, write should fail on symlink
+ await expect(
+ fs.writeFile(racePath, 'NEW CONTENT', { encoding: 'utf-8', flag: 'wx' })
+ ).rejects.toThrow(/EEXIST/);
+
+ // Verify content unchanged
+ const targetContent = await fs.readFile(targetFile, 'utf-8');
+ expect(targetContent).toBe('ORIGINAL CONTENT');
+
+ // The symlink exists but write was blocked
+ const actualWritePath = await fs.realpath(racePath);
+ expect(actualWritePath).toBe(await fs.realpath(targetFile));
+ expect(isPathWithinAllowedDirectories(actualWritePath, allowed)).toBe(false);
+ });
+
+ it('should allow overwrites to legitimate files within allowed directories', async () => {
+ const allowed = [allowedDir];
+ const legitFile = path.join(allowedDir, 'legit-file.txt');
+
+ // Create a legitimate file
+ await fs.writeFile(legitFile, 'ORIGINAL', 'utf-8');
+
+ // Opening with w should work for legitimate files
+ const fd = await fs.open(legitFile, 'w');
+ try {
+ await fd.write('UPDATED', 0, 'utf-8');
+ } finally {
+ await fd.close();
+ }
+
+ const content = await fs.readFile(legitFile, 'utf-8');
+ expect(content).toBe('UPDATED');
+ });
+
+ it('should handle symlinks that point within allowed directories', async () => {
+ const allowed = [allowedDir];
+ const targetFile = path.join(allowedDir, 'target.txt');
+ const symlinkPath = path.join(allowedDir, 'symlink.txt');
+
+ // Create target file within allowed directory
+ await fs.writeFile(targetFile, 'TARGET CONTENT', 'utf-8');
+
+ // Create symlink pointing to allowed file
+ await fs.symlink(targetFile, symlinkPath);
+
+ // Opening symlink with w follows it to the target
+ const fd = await fs.open(symlinkPath, 'w');
+ try {
+ await fd.write('UPDATED VIA SYMLINK', 0, 'utf-8');
+ } finally {
+ await fd.close();
+ }
+
+ // Both symlink and target should show updated content
+ const symlinkContent = await fs.readFile(symlinkPath, 'utf-8');
+ const targetContent = await fs.readFile(targetFile, 'utf-8');
+ expect(symlinkContent).toBe('UPDATED VIA SYMLINK');
+ expect(targetContent).toBe('UPDATED VIA SYMLINK');
+ });
+
+ it('should prevent overwriting files through symlinks pointing outside allowed directories', async () => {
+ const allowed = [allowedDir];
+ const legitFile = path.join(allowedDir, 'existing.txt');
+ const targetFile = path.join(forbiddenDir, 'target.txt');
+
+ // Create a legitimate file first
+ await fs.writeFile(legitFile, 'LEGIT CONTENT', 'utf-8');
+
+ // Create target file in forbidden directory
+ await fs.writeFile(targetFile, 'FORBIDDEN CONTENT', 'utf-8');
+
+ // Now replace the legitimate file with a symlink to forbidden location
+ await fs.unlink(legitFile);
+ await fs.symlink(targetFile, legitFile);
+
+ // Simulate the server's validation logic
+ const stats = await fs.lstat(legitFile);
+ expect(stats.isSymbolicLink()).toBe(true);
+
+ const realPath = await fs.realpath(legitFile);
+ expect(isPathWithinAllowedDirectories(realPath, allowed)).toBe(false);
+
+ // With atomic rename, symlinks are replaced not followed
+ // So this test now demonstrates the protection
+
+ // Verify content remains unchanged
+ const targetContent = await fs.readFile(targetFile, 'utf-8');
+ expect(targetContent).toBe('FORBIDDEN CONTENT');
+ });
+
+ it('demonstrates race condition in read operations', async () => {
+ const allowed = [allowedDir];
+ const legitFile = path.join(allowedDir, 'readable.txt');
+ const secretFile = path.join(forbiddenDir, 'secret.txt');
+
+ // Create legitimate file
+ await fs.writeFile(legitFile, 'PUBLIC CONTENT', 'utf-8');
+
+ // Create secret file in forbidden directory
+ await fs.writeFile(secretFile, 'SECRET CONTENT', 'utf-8');
+
+ // Step 1: validatePath would pass for legitimate file
+ expect(isPathWithinAllowedDirectories(legitFile, allowed)).toBe(true);
+
+ // Step 2: Race condition - replace file with symlink after validation
+ await fs.unlink(legitFile);
+ await fs.symlink(secretFile, legitFile);
+
+ // Step 3: Read operation follows symlink to forbidden location
+ const content = await fs.readFile(legitFile, 'utf-8');
+
+ // This shows the vulnerability - we read forbidden content
+ expect(content).toBe('SECRET CONTENT');
+ expect(isPathWithinAllowedDirectories(await fs.realpath(legitFile), allowed)).toBe(false);
+ });
+
+ it('verifies rename does not follow symlinks', async () => {
+ const allowed = [allowedDir];
+ const tempFile = path.join(allowedDir, 'temp.txt');
+ const targetSymlink = path.join(allowedDir, 'target-symlink.txt');
+ const forbiddenTarget = path.join(forbiddenDir, 'forbidden-target.txt');
+
+ // Create forbidden target
+ await fs.writeFile(forbiddenTarget, 'ORIGINAL CONTENT', 'utf-8');
+
+ // Create symlink pointing to forbidden location
+ await fs.symlink(forbiddenTarget, targetSymlink);
+
+ // Write temp file
+ await fs.writeFile(tempFile, 'NEW CONTENT', 'utf-8');
+
+ // Rename temp file to symlink path
+ await fs.rename(tempFile, targetSymlink);
+
+ // Check what happened
+ const symlinkExists = await fs.lstat(targetSymlink).then(() => true).catch(() => false);
+ const isSymlink = symlinkExists && (await fs.lstat(targetSymlink)).isSymbolicLink();
+ const targetContent = await fs.readFile(targetSymlink, 'utf-8');
+ const forbiddenContent = await fs.readFile(forbiddenTarget, 'utf-8');
+
+ // Rename should replace the symlink with a regular file
+ expect(isSymlink).toBe(false);
+ expect(targetContent).toBe('NEW CONTENT');
+ expect(forbiddenContent).toBe('ORIGINAL CONTENT'); // Unchanged
+ });
+ });
+});
diff --git a/src/filesystem/__tests__/roots-utils.test.ts b/src/filesystem/__tests__/roots-utils.test.ts
new file mode 100644
index 00000000..75821958
--- /dev/null
+++ b/src/filesystem/__tests__/roots-utils.test.ts
@@ -0,0 +1,84 @@
+import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
+import { getValidRootDirectories } from '../roots-utils.js';
+import { mkdtempSync, rmSync, mkdirSync, writeFileSync, realpathSync } from 'fs';
+import { tmpdir } from 'os';
+import { join } from 'path';
+import type { Root } from '@modelcontextprotocol/sdk/types.js';
+
+describe('getValidRootDirectories', () => {
+ let testDir1: string;
+ let testDir2: string;
+ let testDir3: string;
+ let testFile: string;
+
+ beforeEach(() => {
+ // Create test directories
+ testDir1 = realpathSync(mkdtempSync(join(tmpdir(), 'mcp-roots-test1-')));
+ testDir2 = realpathSync(mkdtempSync(join(tmpdir(), 'mcp-roots-test2-')));
+ testDir3 = realpathSync(mkdtempSync(join(tmpdir(), 'mcp-roots-test3-')));
+
+ // Create a test file (not a directory)
+ testFile = join(testDir1, 'test-file.txt');
+ writeFileSync(testFile, 'test content');
+ });
+
+ afterEach(() => {
+ // Cleanup
+ rmSync(testDir1, { recursive: true, force: true });
+ rmSync(testDir2, { recursive: true, force: true });
+ rmSync(testDir3, { recursive: true, force: true });
+ });
+
+ describe('valid directory processing', () => {
+ it('should process all URI formats and edge cases', async () => {
+ const roots = [
+ { uri: `file://${testDir1}`, name: 'File URI' },
+ { uri: testDir2, name: 'Plain path' },
+ { uri: testDir3 } // Plain path without name property
+ ];
+
+ const result = await getValidRootDirectories(roots);
+
+ expect(result).toContain(testDir1);
+ expect(result).toContain(testDir2);
+ expect(result).toContain(testDir3);
+ expect(result).toHaveLength(3);
+ });
+
+ it('should normalize complex paths', async () => {
+ const subDir = join(testDir1, 'subdir');
+ mkdirSync(subDir);
+
+ const roots = [
+ { uri: `file://${testDir1}/./subdir/../subdir`, name: 'Complex Path' }
+ ];
+
+ const result = await getValidRootDirectories(roots);
+
+ expect(result).toHaveLength(1);
+ expect(result[0]).toBe(subDir);
+ });
+ });
+
+ describe('error handling', () => {
+
+ it('should handle various error types', async () => {
+ const nonExistentDir = join(tmpdir(), 'non-existent-directory-12345');
+ const invalidPath = '\0invalid\0path'; // Null bytes cause different error types
+ const roots = [
+ { uri: `file://${testDir1}`, name: 'Valid Dir' },
+ { uri: `file://${nonExistentDir}`, name: 'Non-existent Dir' },
+ { uri: `file://${testFile}`, name: 'File Not Dir' },
+ { uri: `file://${invalidPath}`, name: 'Invalid Path' }
+ ];
+
+ const result = await getValidRootDirectories(roots);
+
+ expect(result).toContain(testDir1);
+ expect(result).not.toContain(nonExistentDir);
+ expect(result).not.toContain(testFile);
+ expect(result).not.toContain(invalidPath);
+ expect(result).toHaveLength(1);
+ });
+ });
+});
\ No newline at end of file
diff --git a/src/filesystem/index.ts b/src/filesystem/index.ts
index c544ff25..524c9c26 100644
--- a/src/filesystem/index.ts
+++ b/src/filesystem/index.ts
@@ -6,20 +6,28 @@ import {
CallToolRequestSchema,
ListToolsRequestSchema,
ToolSchema,
+ RootsListChangedNotificationSchema,
+ type Root,
} from "@modelcontextprotocol/sdk/types.js";
import fs from "fs/promises";
import path from "path";
import os from 'os';
+import { randomBytes } from 'crypto';
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
import { diffLines, createTwoFilesPatch } from 'diff';
import { minimatch } from 'minimatch';
+import { isPathWithinAllowedDirectories } from './path-validation.js';
+import { getValidRootDirectories } from './roots-utils.js';
// Command line argument parsing
const args = process.argv.slice(2);
if (args.length === 0) {
- console.error("Usage: mcp-server-filesystem [additional-directories...]");
- process.exit(1);
+ console.error("Usage: mcp-server-filesystem [allowed-directory] [additional-directories...]");
+ console.error("Note: Allowed directories can be provided via:");
+ console.error(" 1. Command-line arguments (shown above)");
+ console.error(" 2. MCP roots protocol (if client supports it)");
+ console.error("At least one directory must be provided by EITHER method for the server to operate.");
}
// Normalize all paths consistently
@@ -34,9 +42,21 @@ function expandHome(filepath: string): string {
return filepath;
}
-// Store allowed directories in normalized form
-const allowedDirectories = args.map(dir =>
- normalizePath(path.resolve(expandHome(dir)))
+// Store allowed directories in normalized and resolved form
+let allowedDirectories = await Promise.all(
+ args.map(async (dir) => {
+ const expanded = expandHome(dir);
+ const absolute = path.resolve(expanded);
+ try {
+ // Resolve symlinks in allowed directories during startup
+ const resolved = await fs.realpath(absolute);
+ return normalizePath(resolved);
+ } catch (error) {
+ // If we can't resolve (doesn't exist), use the normalized absolute path
+ // This allows configuring allowed dirs that will be created later
+ return normalizePath(absolute);
+ }
+ })
);
// Validate that all directories exist and are accessible
@@ -63,7 +83,7 @@ async function validatePath(requestedPath: string): Promise {
const normalizedRequested = normalizePath(absolute);
// Check if path is within allowed directories
- const isAllowed = allowedDirectories.some(dir => normalizedRequested.startsWith(dir));
+ const isAllowed = isPathWithinAllowedDirectories(normalizedRequested, allowedDirectories);
if (!isAllowed) {
throw new Error(`Access denied - path outside allowed directories: ${absolute} not in ${allowedDirectories.join(', ')}`);
}
@@ -72,31 +92,34 @@ async function validatePath(requestedPath: string): Promise {
try {
const realPath = await fs.realpath(absolute);
const normalizedReal = normalizePath(realPath);
- const isRealPathAllowed = allowedDirectories.some(dir => normalizedReal.startsWith(dir));
- if (!isRealPathAllowed) {
- throw new Error("Access denied - symlink target outside allowed directories");
+ if (!isPathWithinAllowedDirectories(normalizedReal, allowedDirectories)) {
+ throw new Error(`Access denied - symlink target outside allowed directories: ${realPath} not in ${allowedDirectories.join(', ')}`);
}
return realPath;
} catch (error) {
// For new files that don't exist yet, verify parent directory
- const parentDir = path.dirname(absolute);
- try {
- const realParentPath = await fs.realpath(parentDir);
- const normalizedParent = normalizePath(realParentPath);
- const isParentAllowed = allowedDirectories.some(dir => normalizedParent.startsWith(dir));
- if (!isParentAllowed) {
- throw new Error("Access denied - parent directory outside allowed directories");
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
+ const parentDir = path.dirname(absolute);
+ try {
+ const realParentPath = await fs.realpath(parentDir);
+ const normalizedParent = normalizePath(realParentPath);
+ if (!isPathWithinAllowedDirectories(normalizedParent, allowedDirectories)) {
+ throw new Error(`Access denied - parent directory outside allowed directories: ${realParentPath} not in ${allowedDirectories.join(', ')}`);
+ }
+ return absolute;
+ } catch {
+ throw new Error(`Parent directory does not exist: ${parentDir}`);
}
- return absolute;
- } catch {
- throw new Error(`Parent directory does not exist: ${parentDir}`);
}
+ throw error;
}
}
// Schema definitions
const ReadFileArgsSchema = z.object({
path: z.string(),
+ tail: z.number().optional().describe('If provided, returns only the last N lines of the file'),
+ head: z.number().optional().describe('If provided, returns only the first N lines of the file')
});
const ReadMultipleFilesArgsSchema = z.object({
@@ -127,6 +150,11 @@ const ListDirectoryArgsSchema = z.object({
path: z.string(),
});
+const ListDirectoryWithSizesArgsSchema = z.object({
+ path: z.string(),
+ sortBy: z.enum(['name', 'size']).optional().default('name').describe('Sort entries by name or size'),
+});
+
const DirectoryTreeArgsSchema = z.object({
path: z.string(),
});
@@ -324,12 +352,125 @@ async function applyFileEdits(
const formattedDiff = `${'`'.repeat(numBackticks)}diff\n${diff}${'`'.repeat(numBackticks)}\n\n`;
if (!dryRun) {
- await fs.writeFile(filePath, modifiedContent, 'utf-8');
+ // Security: Use atomic rename to prevent race conditions where symlinks
+ // could be created between validation and write. Rename operations
+ // replace the target file atomically and don't follow symlinks.
+ const tempPath = `${filePath}.${randomBytes(16).toString('hex')}.tmp`;
+ try {
+ await fs.writeFile(tempPath, modifiedContent, 'utf-8');
+ await fs.rename(tempPath, filePath);
+ } catch (error) {
+ try {
+ await fs.unlink(tempPath);
+ } catch {}
+ throw error;
+ }
}
return formattedDiff;
}
+// Helper functions
+function formatSize(bytes: number): string {
+ const units = ['B', 'KB', 'MB', 'GB', 'TB'];
+ if (bytes === 0) return '0 B';
+
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
+ if (i === 0) return `${bytes} ${units[i]}`;
+
+ return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${units[i]}`;
+}
+
+// Memory-efficient implementation to get the last N lines of a file
+async function tailFile(filePath: string, numLines: number): Promise {
+ const CHUNK_SIZE = 1024; // Read 1KB at a time
+ const stats = await fs.stat(filePath);
+ const fileSize = stats.size;
+
+ if (fileSize === 0) return '';
+
+ // Open file for reading
+ const fileHandle = await fs.open(filePath, 'r');
+ try {
+ const lines: string[] = [];
+ let position = fileSize;
+ let chunk = Buffer.alloc(CHUNK_SIZE);
+ let linesFound = 0;
+ let remainingText = '';
+
+ // Read chunks from the end of the file until we have enough lines
+ while (position > 0 && linesFound < numLines) {
+ const size = Math.min(CHUNK_SIZE, position);
+ position -= size;
+
+ const { bytesRead } = await fileHandle.read(chunk, 0, size, position);
+ if (!bytesRead) break;
+
+ // Get the chunk as a string and prepend any remaining text from previous iteration
+ const readData = chunk.slice(0, bytesRead).toString('utf-8');
+ const chunkText = readData + remainingText;
+
+ // Split by newlines and count
+ const chunkLines = normalizeLineEndings(chunkText).split('\n');
+
+ // If this isn't the end of the file, the first line is likely incomplete
+ // Save it to prepend to the next chunk
+ if (position > 0) {
+ remainingText = chunkLines[0];
+ chunkLines.shift(); // Remove the first (incomplete) line
+ }
+
+ // Add lines to our result (up to the number we need)
+ for (let i = chunkLines.length - 1; i >= 0 && linesFound < numLines; i--) {
+ lines.unshift(chunkLines[i]);
+ linesFound++;
+ }
+ }
+
+ return lines.join('\n');
+ } finally {
+ await fileHandle.close();
+ }
+}
+
+// New function to get the first N lines of a file
+async function headFile(filePath: string, numLines: number): Promise {
+ const fileHandle = await fs.open(filePath, 'r');
+ try {
+ const lines: string[] = [];
+ let buffer = '';
+ let bytesRead = 0;
+ const chunk = Buffer.alloc(1024); // 1KB buffer
+
+ // Read chunks and count lines until we have enough or reach EOF
+ while (lines.length < numLines) {
+ const result = await fileHandle.read(chunk, 0, chunk.length, bytesRead);
+ if (result.bytesRead === 0) break; // End of file
+ bytesRead += result.bytesRead;
+ buffer += chunk.slice(0, result.bytesRead).toString('utf-8');
+
+ const newLineIndex = buffer.lastIndexOf('\n');
+ if (newLineIndex !== -1) {
+ const completeLines = buffer.slice(0, newLineIndex).split('\n');
+ buffer = buffer.slice(newLineIndex + 1);
+ for (const line of completeLines) {
+ lines.push(line);
+ if (lines.length >= numLines) break;
+ }
+ }
+ }
+
+ // If there is leftover content and we still need lines, add it
+ if (buffer.length > 0 && lines.length < numLines) {
+ lines.push(buffer);
+ }
+
+ return lines.join('\n');
+ } finally {
+ await fileHandle.close();
+ }
+}
+
// Tool handlers
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
@@ -340,7 +481,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
"Read the complete contents of a file from the file system. " +
"Handles various text encodings and provides detailed error messages " +
"if the file cannot be read. Use this tool when you need to examine " +
- "the contents of a single file. Only works within allowed directories.",
+ "the contents of a single file. Use the 'head' parameter to read only " +
+ "the first N lines of a file, or the 'tail' parameter to read only " +
+ "the last N lines of a file. Only works within allowed directories.",
inputSchema: zodToJsonSchema(ReadFileArgsSchema) as ToolInput,
},
{
@@ -387,6 +530,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
"finding specific files within a directory. Only works within allowed directories.",
inputSchema: zodToJsonSchema(ListDirectoryArgsSchema) as ToolInput,
},
+ {
+ name: "list_directory_with_sizes",
+ description:
+ "Get a detailed listing of all files and directories in a specified path, including sizes. " +
+ "Results clearly distinguish between files and directories with [FILE] and [DIR] " +
+ "prefixes. This tool is useful for understanding directory structure and " +
+ "finding specific files within a directory. Only works within allowed directories.",
+ inputSchema: zodToJsonSchema(ListDirectoryWithSizesArgsSchema) as ToolInput,
+ },
{
name: "directory_tree",
description:
@@ -427,8 +579,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
{
name: "list_allowed_directories",
description:
- "Returns the list of directories that this server is allowed to access. " +
- "Use this to understand which directories are available before trying to access files.",
+ "Returns the list of root directories that this server is allowed to access. " +
+ "Use this to understand which directories are available before trying to access files. ",
inputSchema: {
type: "object",
properties: {},
@@ -451,6 +603,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
throw new Error(`Invalid arguments for read_file: ${parsed.error}`);
}
const validPath = await validatePath(parsed.data.path);
+
+ if (parsed.data.head && parsed.data.tail) {
+ throw new Error("Cannot specify both head and tail parameters simultaneously");
+ }
+
+ if (parsed.data.tail) {
+ // Use memory-efficient tail implementation for large files
+ const tailContent = await tailFile(validPath, parsed.data.tail);
+ return {
+ content: [{ type: "text", text: tailContent }],
+ };
+ }
+
+ if (parsed.data.head) {
+ // Use memory-efficient head implementation for large files
+ const headContent = await headFile(validPath, parsed.data.head);
+ return {
+ content: [{ type: "text", text: headContent }],
+ };
+ }
+
const content = await fs.readFile(validPath, "utf-8");
return {
content: [{ type: "text", text: content }],
@@ -485,7 +658,31 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
throw new Error(`Invalid arguments for write_file: ${parsed.error}`);
}
const validPath = await validatePath(parsed.data.path);
- await fs.writeFile(validPath, parsed.data.content, "utf-8");
+
+ try {
+ // Security: 'wx' flag ensures exclusive creation - fails if file/symlink exists,
+ // preventing writes through pre-existing symlinks
+ await fs.writeFile(validPath, parsed.data.content, { encoding: "utf-8", flag: 'wx' });
+ } catch (error) {
+ if ((error as NodeJS.ErrnoException).code === 'EEXIST') {
+ // Security: Use atomic rename to prevent race conditions where symlinks
+ // could be created between validation and write. Rename operations
+ // replace the target file atomically and don't follow symlinks.
+ const tempPath = `${validPath}.${randomBytes(16).toString('hex')}.tmp`;
+ try {
+ await fs.writeFile(tempPath, parsed.data.content, 'utf-8');
+ await fs.rename(tempPath, validPath);
+ } catch (renameError) {
+ try {
+ await fs.unlink(tempPath);
+ } catch {}
+ throw renameError;
+ }
+ } else {
+ throw error;
+ }
+ }
+
return {
content: [{ type: "text", text: `Successfully wrote to ${parsed.data.path}` }],
};
@@ -530,11 +727,77 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
}
- case "directory_tree": {
- const parsed = DirectoryTreeArgsSchema.safeParse(args);
- if (!parsed.success) {
- throw new Error(`Invalid arguments for directory_tree: ${parsed.error}`);
+ case "list_directory_with_sizes": {
+ const parsed = ListDirectoryWithSizesArgsSchema.safeParse(args);
+ if (!parsed.success) {
+ throw new Error(`Invalid arguments for list_directory_with_sizes: ${parsed.error}`);
+ }
+ const validPath = await validatePath(parsed.data.path);
+ const entries = await fs.readdir(validPath, { withFileTypes: true });
+
+ // Get detailed information for each entry
+ const detailedEntries = await Promise.all(
+ entries.map(async (entry) => {
+ const entryPath = path.join(validPath, entry.name);
+ try {
+ const stats = await fs.stat(entryPath);
+ return {
+ name: entry.name,
+ isDirectory: entry.isDirectory(),
+ size: stats.size,
+ mtime: stats.mtime
+ };
+ } catch (error) {
+ return {
+ name: entry.name,
+ isDirectory: entry.isDirectory(),
+ size: 0,
+ mtime: new Date(0)
+ };
}
+ })
+ );
+
+ // Sort entries based on sortBy parameter
+ const sortedEntries = [...detailedEntries].sort((a, b) => {
+ if (parsed.data.sortBy === 'size') {
+ return b.size - a.size; // Descending by size
+ }
+ // Default sort by name
+ return a.name.localeCompare(b.name);
+ });
+
+ // Format the output
+ const formattedEntries = sortedEntries.map(entry =>
+ `${entry.isDirectory ? "[DIR]" : "[FILE]"} ${entry.name.padEnd(30)} ${
+ entry.isDirectory ? "" : formatSize(entry.size).padStart(10)
+ }`
+ );
+
+ // Add summary
+ const totalFiles = detailedEntries.filter(e => !e.isDirectory).length;
+ const totalDirs = detailedEntries.filter(e => e.isDirectory).length;
+ const totalSize = detailedEntries.reduce((sum, entry) => sum + (entry.isDirectory ? 0 : entry.size), 0);
+
+ const summary = [
+ "",
+ `Total: ${totalFiles} files, ${totalDirs} directories`,
+ `Combined size: ${formatSize(totalSize)}`
+ ];
+
+ return {
+ content: [{
+ type: "text",
+ text: [...formattedEntries, ...summary].join("\n")
+ }],
+ };
+ }
+
+ case "directory_tree": {
+ const parsed = DirectoryTreeArgsSchema.safeParse(args);
+ if (!parsed.success) {
+ throw new Error(`Invalid arguments for directory_tree: ${parsed.error}`);
+ }
interface TreeEntry {
name: string;
@@ -633,12 +896,62 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
}
});
+// Updates allowed directories based on MCP client roots
+async function updateAllowedDirectoriesFromRoots(requestedRoots: Root[]) {
+ const validatedRootDirs = await getValidRootDirectories(requestedRoots);
+ if (validatedRootDirs.length > 0) {
+ allowedDirectories = [...validatedRootDirs];
+ console.error(`Updated allowed directories from MCP roots: ${validatedRootDirs.length} valid directories`);
+ } else {
+ console.error("No valid root directories provided by client");
+ }
+}
+
+// Handles dynamic roots updates during runtime, when client sends "roots/list_changed" notification, server fetches the updated roots and replaces all allowed directories with the new roots.
+server.setNotificationHandler(RootsListChangedNotificationSchema, async () => {
+ try {
+ // Request the updated roots list from the client
+ const response = await server.listRoots();
+ if (response && 'roots' in response) {
+ await updateAllowedDirectoriesFromRoots(response.roots);
+ }
+ } catch (error) {
+ console.error("Failed to request roots from client:", error instanceof Error ? error.message : String(error));
+ }
+});
+
+// Handles post-initialization setup, specifically checking for and fetching MCP roots.
+server.oninitialized = async () => {
+ const clientCapabilities = server.getClientCapabilities();
+
+ if (clientCapabilities?.roots) {
+ try {
+ const response = await server.listRoots();
+ if (response && 'roots' in response) {
+ await updateAllowedDirectoriesFromRoots(response.roots);
+ } else {
+ console.error("Client returned no roots set, keeping current settings");
+ }
+ } catch (error) {
+ console.error("Failed to request initial roots from client:", error instanceof Error ? error.message : String(error));
+ }
+ } else {
+ if (allowedDirectories.length > 0) {
+ console.error("Client does not support MCP Roots, using allowed directories set from server args:", allowedDirectories);
+ }else{
+ throw new Error(`Server cannot operate: No allowed directories available. Server was started without command-line directories and client either does not support MCP roots protocol or provided empty roots. Please either: 1) Start server with directory arguments, or 2) Use a client that supports MCP roots protocol and provides valid root directories.`);
+ }
+ }
+};
+
// Start server
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Secure MCP Filesystem Server running on stdio");
- console.error("Allowed directories:", allowedDirectories);
+ if (allowedDirectories.length === 0) {
+ console.error("Started without allowed directories - waiting for client to provide roots via MCP protocol");
+ }
}
runServer().catch((error) => {
diff --git a/src/filesystem/jest.config.cjs b/src/filesystem/jest.config.cjs
new file mode 100644
index 00000000..285141a7
--- /dev/null
+++ b/src/filesystem/jest.config.cjs
@@ -0,0 +1,23 @@
+/** @type {import('ts-jest').JestConfigWithTsJest} */
+module.exports = {
+ preset: 'ts-jest',
+ testEnvironment: 'node',
+ extensionsToTreatAsEsm: ['.ts'],
+ moduleNameMapper: {
+ '^(\\.{1,2}/.*)\\.js$': '$1',
+ },
+ transform: {
+ '^.+\\.tsx?$': [
+ 'ts-jest',
+ {
+ useESM: true,
+ },
+ ],
+ },
+ testMatch: ['**/__tests__/**/*.test.ts'],
+ collectCoverageFrom: [
+ '**/*.ts',
+ '!**/__tests__/**',
+ '!**/dist/**',
+ ],
+}
diff --git a/src/filesystem/package.json b/src/filesystem/package.json
index 6aca648f..482f0cce 100644
--- a/src/filesystem/package.json
+++ b/src/filesystem/package.json
@@ -16,20 +16,26 @@
"scripts": {
"build": "tsc && shx chmod +x dist/*.js",
"prepare": "npm run build",
- "watch": "tsc --watch"
+ "watch": "tsc --watch",
+ "test": "jest --config=jest.config.cjs --coverage"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "^1.12.3",
"diff": "^5.1.0",
"glob": "^10.3.10",
"minimatch": "^10.0.1",
"zod-to-json-schema": "^3.23.5"
},
"devDependencies": {
+ "@jest/globals": "^29.7.0",
"@types/diff": "^5.0.9",
+ "@types/jest": "^29.5.14",
"@types/minimatch": "^5.1.2",
"@types/node": "^22",
+ "jest": "^29.7.0",
"shx": "^0.3.4",
- "typescript": "^5.3.3"
+ "ts-jest": "^29.1.1",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.8.2"
}
}
\ No newline at end of file
diff --git a/src/filesystem/path-utils.ts b/src/filesystem/path-utils.ts
new file mode 100644
index 00000000..aca7f061
--- /dev/null
+++ b/src/filesystem/path-utils.ts
@@ -0,0 +1,104 @@
+import path from "path";
+import os from 'os';
+
+/**
+ * Converts WSL or Unix-style Windows paths to Windows format
+ * @param p The path to convert
+ * @returns Converted Windows path
+ */
+export function convertToWindowsPath(p: string): string {
+ // Handle WSL paths (/mnt/c/...)
+ if (p.startsWith('/mnt/')) {
+ const driveLetter = p.charAt(5).toUpperCase();
+ const pathPart = p.slice(6).replace(/\//g, '\\');
+ return `${driveLetter}:${pathPart}`;
+ }
+
+ // Handle Unix-style Windows paths (/c/...)
+ if (p.match(/^\/[a-zA-Z]\//)) {
+ const driveLetter = p.charAt(1).toUpperCase();
+ const pathPart = p.slice(2).replace(/\//g, '\\');
+ return `${driveLetter}:${pathPart}`;
+ }
+
+ // Handle standard Windows paths, ensuring backslashes
+ if (p.match(/^[a-zA-Z]:/)) {
+ return p.replace(/\//g, '\\');
+ }
+
+ // Leave non-Windows paths unchanged
+ return p;
+}
+
+/**
+ * Normalizes path by standardizing format while preserving OS-specific behavior
+ * @param p The path to normalize
+ * @returns Normalized path
+ */
+export function normalizePath(p: string): string {
+ // Remove any surrounding quotes and whitespace
+ p = p.trim().replace(/^["']|["']$/g, '');
+
+ // Check if this is a Unix path (starts with / but not a Windows or WSL path)
+ const isUnixPath = p.startsWith('/') &&
+ !p.match(/^\/mnt\/[a-z]\//i) &&
+ !p.match(/^\/[a-zA-Z]\//);
+
+ if (isUnixPath) {
+ // For Unix paths, just normalize without converting to Windows format
+ // Replace double slashes with single slashes and remove trailing slashes
+ return p.replace(/\/+/g, '/').replace(/\/+$/, '');
+ }
+
+ // Convert WSL or Unix-style Windows paths to Windows format
+ p = convertToWindowsPath(p);
+
+ // Handle double backslashes, preserving leading UNC \\
+ if (p.startsWith('\\\\')) {
+ // For UNC paths, first normalize any excessive leading backslashes to exactly \\
+ // Then normalize double backslashes in the rest of the path
+ let uncPath = p;
+ // Replace multiple leading backslashes with exactly two
+ uncPath = uncPath.replace(/^\\{2,}/, '\\\\');
+ // Now normalize any remaining double backslashes in the rest of the path
+ const restOfPath = uncPath.substring(2).replace(/\\\\/g, '\\');
+ p = '\\\\' + restOfPath;
+ } else {
+ // For non-UNC paths, normalize all double backslashes
+ p = p.replace(/\\\\/g, '\\');
+ }
+
+ // Use Node's path normalization, which handles . and .. segments
+ let normalized = path.normalize(p);
+
+ // Fix UNC paths after normalization (path.normalize can remove a leading backslash)
+ if (p.startsWith('\\\\') && !normalized.startsWith('\\\\')) {
+ normalized = '\\' + normalized;
+ }
+
+ // Handle Windows paths: convert slashes and ensure drive letter is capitalized
+ if (normalized.match(/^[a-zA-Z]:/)) {
+ let result = normalized.replace(/\//g, '\\');
+ // Capitalize drive letter if present
+ if (/^[a-z]:/.test(result)) {
+ result = result.charAt(0).toUpperCase() + result.slice(1);
+ }
+ return result;
+ }
+
+ // For all other paths (including relative paths), convert forward slashes to backslashes
+ // This ensures relative paths like "some/relative/path" become "some\\relative\\path"
+ return normalized.replace(/\//g, '\\');
+}
+
+/**
+ * Expands home directory tildes in paths
+ * @param filepath The path to expand
+ * @returns Expanded path
+ */
+export function expandHome(filepath: string): string {
+ if (filepath.startsWith('~/') || filepath === '~') {
+ return path.join(os.homedir(), filepath.slice(1));
+ }
+ return filepath;
+}
diff --git a/src/filesystem/path-validation.ts b/src/filesystem/path-validation.ts
new file mode 100644
index 00000000..ee0c97d7
--- /dev/null
+++ b/src/filesystem/path-validation.ts
@@ -0,0 +1,77 @@
+import path from 'path';
+
+/**
+ * Checks if an absolute path is within any of the allowed directories.
+ *
+ * @param absolutePath - The absolute path to check (will be normalized)
+ * @param allowedDirectories - Array of absolute allowed directory paths (will be normalized)
+ * @returns true if the path is within an allowed directory, false otherwise
+ * @throws Error if given relative paths after normalization
+ */
+export function isPathWithinAllowedDirectories(absolutePath: string, allowedDirectories: string[]): boolean {
+ // Type validation
+ if (typeof absolutePath !== 'string' || !Array.isArray(allowedDirectories)) {
+ return false;
+ }
+
+ // Reject empty inputs
+ if (!absolutePath || allowedDirectories.length === 0) {
+ return false;
+ }
+
+ // Reject null bytes (forbidden in paths)
+ if (absolutePath.includes('\x00')) {
+ return false;
+ }
+
+ // Normalize the input path
+ let normalizedPath: string;
+ try {
+ normalizedPath = path.resolve(path.normalize(absolutePath));
+ } catch {
+ return false;
+ }
+
+ // Verify it's absolute after normalization
+ if (!path.isAbsolute(normalizedPath)) {
+ throw new Error('Path must be absolute after normalization');
+ }
+
+ // Check against each allowed directory
+ return allowedDirectories.some(dir => {
+ if (typeof dir !== 'string' || !dir) {
+ return false;
+ }
+
+ // Reject null bytes in allowed dirs
+ if (dir.includes('\x00')) {
+ return false;
+ }
+
+ // Normalize the allowed directory
+ let normalizedDir: string;
+ try {
+ normalizedDir = path.resolve(path.normalize(dir));
+ } catch {
+ return false;
+ }
+
+ // Verify allowed directory is absolute after normalization
+ if (!path.isAbsolute(normalizedDir)) {
+ throw new Error('Allowed directories must be absolute paths after normalization');
+ }
+
+ // Check if normalizedPath is within normalizedDir
+ // Path is inside if it's the same or a subdirectory
+ if (normalizedPath === normalizedDir) {
+ return true;
+ }
+
+ // Special case for root directory to avoid double slash
+ if (normalizedDir === path.sep) {
+ return normalizedPath.startsWith(path.sep);
+ }
+
+ return normalizedPath.startsWith(normalizedDir + path.sep);
+ });
+}
\ No newline at end of file
diff --git a/src/filesystem/roots-utils.ts b/src/filesystem/roots-utils.ts
new file mode 100644
index 00000000..87329977
--- /dev/null
+++ b/src/filesystem/roots-utils.ts
@@ -0,0 +1,76 @@
+import { promises as fs, type Stats } from 'fs';
+import path from 'path';
+import os from 'os';
+import { normalizePath } from './path-utils.js';
+import type { Root } from '@modelcontextprotocol/sdk/types.js';
+
+/**
+ * Converts a root URI to a normalized directory path with basic security validation.
+ * @param rootUri - File URI (file://...) or plain directory path
+ * @returns Promise resolving to validated path or null if invalid
+ */
+async function parseRootUri(rootUri: string): Promise {
+ try {
+ const rawPath = rootUri.startsWith('file://') ? rootUri.slice(7) : rootUri;
+ const expandedPath = rawPath.startsWith('~/') || rawPath === '~'
+ ? path.join(os.homedir(), rawPath.slice(1))
+ : rawPath;
+ const absolutePath = path.resolve(expandedPath);
+ const resolvedPath = await fs.realpath(absolutePath);
+ return normalizePath(resolvedPath);
+ } catch {
+ return null; // Path doesn't exist or other error
+ }
+}
+
+/**
+ * Formats error message for directory validation failures.
+ * @param dir - Directory path that failed validation
+ * @param error - Error that occurred during validation
+ * @param reason - Specific reason for failure
+ * @returns Formatted error message
+ */
+function formatDirectoryError(dir: string, error?: unknown, reason?: string): string {
+ if (reason) {
+ return `Skipping ${reason}: ${dir}`;
+ }
+ const message = error instanceof Error ? error.message : String(error);
+ return `Skipping invalid directory: ${dir} due to error: ${message}`;
+}
+
+/**
+ * Resolves requested root directories from MCP root specifications.
+ *
+ * Converts root URI specifications (file:// URIs or plain paths) into normalized
+ * directory paths, validating that each path exists and is a directory.
+ * Includes symlink resolution for security.
+ *
+ * @param requestedRoots - Array of root specifications with URI and optional name
+ * @returns Promise resolving to array of validated directory paths
+ */
+export async function getValidRootDirectories(
+ requestedRoots: readonly Root[]
+): Promise {
+ const validatedDirectories: string[] = [];
+
+ for (const requestedRoot of requestedRoots) {
+ const resolvedPath = await parseRootUri(requestedRoot.uri);
+ if (!resolvedPath) {
+ console.error(formatDirectoryError(requestedRoot.uri, undefined, 'invalid path or inaccessible'));
+ continue;
+ }
+
+ try {
+ const stats: Stats = await fs.stat(resolvedPath);
+ if (stats.isDirectory()) {
+ validatedDirectories.push(resolvedPath);
+ } else {
+ console.error(formatDirectoryError(resolvedPath, undefined, 'non-directory root'));
+ }
+ } catch (error) {
+ console.error(formatDirectoryError(resolvedPath, error));
+ }
+ }
+
+ return validatedDirectories;
+}
\ No newline at end of file
diff --git a/src/gdrive/Dockerfile b/src/gdrive/Dockerfile
deleted file mode 100644
index 923ffa7e..00000000
--- a/src/gdrive/Dockerfile
+++ /dev/null
@@ -1,29 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-COPY src/gdrive /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
-
-FROM node:22-alpine AS release
-
-WORKDIR /app
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-COPY src/gdrive/replace_open.sh /replace_open.sh
-
-ENV NODE_ENV=production
-
-RUN npm ci --ignore-scripts --omit-dev
-
-RUN sh /replace_open.sh
-
-RUN rm /replace_open.sh
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/gdrive/README.md b/src/gdrive/README.md
deleted file mode 100644
index 2d153815..00000000
--- a/src/gdrive/README.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# Google Drive server
-
-This MCP server integrates with Google Drive to allow listing, reading, and searching over files.
-
-## Components
-
-### Tools
-
-- **search**
- - Search for files in Google Drive
- - Input: `query` (string): Search query
- - Returns file names and MIME types of matching files
-
-### Resources
-
-The server provides access to Google Drive files:
-
-- **Files** (`gdrive:///`)
- - Supports all file types
- - Google Workspace files are automatically exported:
- - Docs → Markdown
- - Sheets → CSV
- - Presentations → Plain text
- - Drawings → PNG
- - Other files are provided in their native format
-
-## Getting started
-
-1. [Create a new Google Cloud project](https://console.cloud.google.com/projectcreate)
-2. [Enable the Google Drive API](https://console.cloud.google.com/workspace-api/products)
-3. [Configure an OAuth consent screen](https://console.cloud.google.com/apis/credentials/consent) ("internal" is fine for testing)
-4. Add OAuth scope `https://www.googleapis.com/auth/drive.readonly`
-5. [Create an OAuth Client ID](https://console.cloud.google.com/apis/credentials/oauthclient) for application type "Desktop App"
-6. Download the JSON file of your client's OAuth keys
-7. Rename the key file to `gcp-oauth.keys.json` and place into the root of this repo (i.e. `servers/gcp-oauth.keys.json`)
-
-Make sure to build the server with either `npm run build` or `npm run watch`.
-
-### Authentication
-
-To authenticate and save credentials:
-
-1. Run the server with the `auth` argument: `node ./dist auth`
-2. This will open an authentication flow in your system browser
-3. Complete the authentication process
-4. Credentials will be saved in the root of this repo (i.e. `servers/.gdrive-server-credentials.json`)
-
-### Usage with Desktop App
-
-To integrate this server with the desktop app, add the following to your app's server configuration:
-
-#### Docker
-
-Authentication:
-
-Assuming you have completed setting up the OAuth application on Google Cloud, you can now auth the server with the following command, replacing `/path/to/gcp-oauth.keys.json` with the path to your OAuth keys file:
-
-```bash
-docker run -i --rm --mount type=bind,source=/path/to/gcp-oauth.keys.json,target=/gcp-oauth.keys.json -v mcp-gdrive:/gdrive-server -e GDRIVE_OAUTH_PATH=/gcp-oauth.keys.json -e "GDRIVE_CREDENTIALS_PATH=/gdrive-server/credentials.json" -p 3000:3000 mcp/gdrive auth
-```
-
-The command will print the URL to open in your browser. Open this URL in your browser and complete the authentication process. The credentials will be saved in the `mcp-gdrive` volume.
-
-Once authenticated, you can use the server in your app's server configuration:
-
-```json
-{
- "mcpServers": {
- "gdrive": {
- "command": "docker",
- "args": ["run", "-i", "--rm", "-v", "mcp-gdrive:/gdrive-server", "-e", "GDRIVE_CREDENTIALS_PATH=/gdrive-server/credentials.json", "mcp/gdrive"]
- }
- }
-}
-```
-
-#### NPX
-
-```json
-{
- "mcpServers": {
- "gdrive": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-gdrive"
- ]
- }
- }
-}
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/gdrive/index.ts b/src/gdrive/index.ts
deleted file mode 100644
index 1fa4dc89..00000000
--- a/src/gdrive/index.ts
+++ /dev/null
@@ -1,219 +0,0 @@
-#!/usr/bin/env node
-
-import { authenticate } from "@google-cloud/local-auth";
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListResourcesRequestSchema,
- ListToolsRequestSchema,
- ReadResourceRequestSchema,
-} from "@modelcontextprotocol/sdk/types.js";
-import fs from "fs";
-import { google } from "googleapis";
-import path from "path";
-import { fileURLToPath } from 'url';
-
-const drive = google.drive("v3");
-
-const server = new Server(
- {
- name: "example-servers/gdrive",
- version: "0.1.0",
- },
- {
- capabilities: {
- resources: {},
- tools: {},
- },
- },
-);
-
-server.setRequestHandler(ListResourcesRequestSchema, async (request) => {
- const pageSize = 10;
- const params: any = {
- pageSize,
- fields: "nextPageToken, files(id, name, mimeType)",
- };
-
- if (request.params?.cursor) {
- params.pageToken = request.params.cursor;
- }
-
- const res = await drive.files.list(params);
- const files = res.data.files!;
-
- return {
- resources: files.map((file) => ({
- uri: `gdrive:///${file.id}`,
- mimeType: file.mimeType,
- name: file.name,
- })),
- nextCursor: res.data.nextPageToken,
- };
-});
-
-server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
- const fileId = request.params.uri.replace("gdrive:///", "");
-
- // First get file metadata to check mime type
- const file = await drive.files.get({
- fileId,
- fields: "mimeType",
- });
-
- // For Google Docs/Sheets/etc we need to export
- if (file.data.mimeType?.startsWith("application/vnd.google-apps")) {
- let exportMimeType: string;
- switch (file.data.mimeType) {
- case "application/vnd.google-apps.document":
- exportMimeType = "text/markdown";
- break;
- case "application/vnd.google-apps.spreadsheet":
- exportMimeType = "text/csv";
- break;
- case "application/vnd.google-apps.presentation":
- exportMimeType = "text/plain";
- break;
- case "application/vnd.google-apps.drawing":
- exportMimeType = "image/png";
- break;
- default:
- exportMimeType = "text/plain";
- }
-
- const res = await drive.files.export(
- { fileId, mimeType: exportMimeType },
- { responseType: "text" },
- );
-
- return {
- contents: [
- {
- uri: request.params.uri,
- mimeType: exportMimeType,
- text: res.data,
- },
- ],
- };
- }
-
- // For regular files download content
- const res = await drive.files.get(
- { fileId, alt: "media" },
- { responseType: "arraybuffer" },
- );
- const mimeType = file.data.mimeType || "application/octet-stream";
- if (mimeType.startsWith("text/") || mimeType === "application/json") {
- return {
- contents: [
- {
- uri: request.params.uri,
- mimeType: mimeType,
- text: Buffer.from(res.data as ArrayBuffer).toString("utf-8"),
- },
- ],
- };
- } else {
- return {
- contents: [
- {
- uri: request.params.uri,
- mimeType: mimeType,
- blob: Buffer.from(res.data as ArrayBuffer).toString("base64"),
- },
- ],
- };
- }
-});
-
-server.setRequestHandler(ListToolsRequestSchema, async () => {
- return {
- tools: [
- {
- name: "search",
- description: "Search for files in Google Drive",
- inputSchema: {
- type: "object",
- properties: {
- query: {
- type: "string",
- description: "Search query",
- },
- },
- required: ["query"],
- },
- },
- ],
- };
-});
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- if (request.params.name === "search") {
- const userQuery = request.params.arguments?.query as string;
- const escapedQuery = userQuery.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
- const formattedQuery = `fullText contains '${escapedQuery}'`;
-
- const res = await drive.files.list({
- q: formattedQuery,
- pageSize: 10,
- fields: "files(id, name, mimeType, modifiedTime, size)",
- });
-
- const fileList = res.data.files
- ?.map((file: any) => `${file.name} (${file.mimeType})`)
- .join("\n");
- return {
- content: [
- {
- type: "text",
- text: `Found ${res.data.files?.length ?? 0} files:\n${fileList}`,
- },
- ],
- isError: false,
- };
- }
- throw new Error("Tool not found");
-});
-
-const credentialsPath = process.env.GDRIVE_CREDENTIALS_PATH || path.join(
- path.dirname(fileURLToPath(import.meta.url)),
- "../../../.gdrive-server-credentials.json",
-);
-
-async function authenticateAndSaveCredentials() {
- console.log("Launching auth flow…");
- const auth = await authenticate({
- keyfilePath: process.env.GDRIVE_OAUTH_PATH || path.join(
- path.dirname(fileURLToPath(import.meta.url)),
- "../../../gcp-oauth.keys.json",
- ),
- scopes: ["https://www.googleapis.com/auth/drive.readonly"],
- });
- fs.writeFileSync(credentialsPath, JSON.stringify(auth.credentials));
- console.log("Credentials saved. You can now run the server.");
-}
-
-async function loadCredentialsAndRunServer() {
- if (!fs.existsSync(credentialsPath)) {
- console.error(
- "Credentials not found. Please run with 'auth' argument first.",
- );
- process.exit(1);
- }
-
- const credentials = JSON.parse(fs.readFileSync(credentialsPath, "utf-8"));
- const auth = new google.auth.OAuth2();
- auth.setCredentials(credentials);
- google.options({ auth });
-
- console.error("Credentials loaded. Starting server.");
- const transport = new StdioServerTransport();
- await server.connect(transport);
-}
-
-if (process.argv[2] === "auth") {
- authenticateAndSaveCredentials().catch(console.error);
-} else {
- loadCredentialsAndRunServer().catch(console.error);
-}
diff --git a/src/gdrive/package.json b/src/gdrive/package.json
deleted file mode 100644
index a2d4be37..00000000
--- a/src/gdrive/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-gdrive",
- "version": "0.6.2",
- "description": "MCP server for interacting with Google Drive",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-gdrive": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@google-cloud/local-auth": "^3.0.1",
- "@modelcontextprotocol/sdk": "1.0.1",
- "googleapis": "^144.0.0"
- },
- "devDependencies": {
- "@types/node": "^22",
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/gdrive/replace_open.sh b/src/gdrive/replace_open.sh
deleted file mode 100644
index 6727854b..00000000
--- a/src/gdrive/replace_open.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#! /bin/bash
-
-# Basic script to replace opn(authorizeUrl, { wait: false }).then(cp => cp.unref()); with process.stdout.write(`Open this URL in your browser: ${authorizeUrl}`);
-
-sed -i 's/opn(authorizeUrl, { wait: false }).then(cp => cp.unref());/process.stderr.write(`Open this URL in your browser: ${authorizeUrl}\n`);/' node_modules/@google-cloud/local-auth/build/src/index.js
diff --git a/src/gdrive/tsconfig.json b/src/gdrive/tsconfig.json
deleted file mode 100644
index ec5da158..00000000
--- a/src/gdrive/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
-}
diff --git a/src/git/README.md b/src/git/README.md
index 827d58fa..a1294d8c 100644
--- a/src/git/README.md
+++ b/src/git/README.md
@@ -16,14 +16,16 @@ Please note that mcp-server-git is currently in early development. The functiona
2. `git_diff_unstaged`
- Shows changes in working directory not yet staged
- - Input:
+ - Inputs:
- `repo_path` (string): Path to Git repository
+ - `context_lines` (number, optional): Number of context lines to show (default: 3)
- Returns: Diff output of unstaged changes
3. `git_diff_staged`
- Shows changes that are staged for commit
- - Input:
+ - Inputs:
- `repo_path` (string): Path to Git repository
+ - `context_lines` (number, optional): Number of context lines to show (default: 3)
- Returns: Diff output of staged changes
4. `git_diff`
@@ -31,6 +33,7 @@ Please note that mcp-server-git is currently in early development. The functiona
- Inputs:
- `repo_path` (string): Path to Git repository
- `target` (string): Target branch or commit to compare with
+ - `context_lines` (number, optional): Number of context lines to show (default: 3)
- Returns: Diff output comparing current state with target
5. `git_commit`
@@ -85,6 +88,15 @@ Please note that mcp-server-git is currently in early development. The functiona
- `repo_path` (string): Path to directory to initialize git repo
- Returns: Confirmation of repository initialization
+13. `git_branch`
+ - List Git branches
+ - Inputs:
+ - `repo_path` (string): Path to the Git repository.
+ - `branch_type` (string): Whether to list local branches ('local'), remote branches ('remote') or all branches('all').
+ - `contains` (string, optional): The commit sha that branch should contain. Do not pass anything to this param if no commit sha is specified
+ - `not_contains` (string, optional): The commit sha that branch should NOT contain. Do not pass anything to this param if no commit sha is specified
+ - Returns: List of branches
+
## Installation
### Using uv (recommended)
@@ -153,6 +165,54 @@ Add this to your `claude_desktop_config.json`:
```
+### Usage with VS Code
+
+For quick installation, use one of the one-click install buttons below...
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=git&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-git%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=git&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-git%22%5D%7D&quality=insiders)
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=git&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22--rm%22%2C%22-i%22%2C%22--mount%22%2C%22type%3Dbind%2Csrc%3D%24%7BworkspaceFolder%7D%2Cdst%3D%2Fworkspace%22%2C%22mcp%2Fgit%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=git&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22--rm%22%2C%22-i%22%2C%22--mount%22%2C%22type%3Dbind%2Csrc%3D%24%7BworkspaceFolder%7D%2Cdst%3D%2Fworkspace%22%2C%22mcp%2Fgit%22%5D%7D&quality=insiders)
+
+For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open Settings (JSON)`.
+
+Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
+
+> Note that the `mcp` key is not needed in the `.vscode/mcp.json` file.
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "git": {
+ "command": "uvx",
+ "args": ["mcp-server-git"]
+ }
+ }
+ }
+}
+```
+
+For Docker installation:
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "git": {
+ "command": "docker",
+ "args": [
+ "run",
+ "--rm",
+ "-i",
+ "--mount", "type=bind,src=${workspaceFolder},dst=/workspace",
+ "mcp/git"
+ ]
+ }
+ }
+ }
+}
+```
+
### Usage with [Zed](https://github.com/zed-industries/zed)
Add to your Zed settings.json:
@@ -187,6 +247,24 @@ Add to your Zed settings.json:
```
+### Usage with [Zencoder](https://zencoder.ai)
+
+1. Go to the Zencoder menu (...)
+2. From the dropdown menu, select `Agent Tools`
+3. Click on the `Add Custom MCP`
+4. Add the name (i.e. git) and server configuration from below, and make sure to hit the `Install` button
+
+
+Using uvx
+
+```json
+{
+ "command": "uvx",
+ "args": ["mcp-server-git", "--repository", "path/to/git/repo"]
+}
+```
+
+
## Debugging
You can use the MCP inspector to debug the server. For uvx installations:
@@ -240,12 +318,13 @@ If you are doing local development, there are two ways to test your changes:
"mcpServers": {
"git": {
"command": "uv",
- "args": [
+ "args": [
"--directory",
"//mcp-servers/src/git",
"run",
"mcp-server-git"
]
+ }
}
}
```
diff --git a/src/git/pyproject.toml b/src/git/pyproject.toml
index f25b33d0..1869135c 100644
--- a/src/git/pyproject.toml
+++ b/src/git/pyproject.toml
@@ -36,4 +36,4 @@ dev-dependencies = ["pyright>=1.1.389", "ruff>=0.7.3", "pytest>=8.0.0"]
testpaths = ["tests"]
python_files = "test_*.py"
python_classes = "Test*"
-python_functions = "test_*"
\ No newline at end of file
+python_functions = "test_*"
diff --git a/src/git/src/mcp_server_git/py.typed b/src/git/src/mcp_server_git/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/src/git/src/mcp_server_git/server.py b/src/git/src/mcp_server_git/server.py
index c6a346cf..afb922f0 100644
--- a/src/git/src/mcp_server_git/server.py
+++ b/src/git/src/mcp_server_git/server.py
@@ -1,6 +1,6 @@
import logging
from pathlib import Path
-from typing import Sequence
+from typing import Sequence, Optional
from mcp.server import Server
from mcp.server.session import ServerSession
from mcp.server.stdio import stdio_server
@@ -13,20 +13,26 @@ from mcp.types import (
)
from enum import Enum
import git
-from pydantic import BaseModel
+from pydantic import BaseModel, Field
+
+# Default number of context lines to show in diff output
+DEFAULT_CONTEXT_LINES = 3
class GitStatus(BaseModel):
repo_path: str
class GitDiffUnstaged(BaseModel):
repo_path: str
+ context_lines: int = DEFAULT_CONTEXT_LINES
class GitDiffStaged(BaseModel):
repo_path: str
+ context_lines: int = DEFAULT_CONTEXT_LINES
class GitDiff(BaseModel):
repo_path: str
target: str
+ context_lines: int = DEFAULT_CONTEXT_LINES
class GitCommit(BaseModel):
repo_path: str
@@ -59,6 +65,24 @@ class GitShow(BaseModel):
class GitInit(BaseModel):
repo_path: str
+class GitBranch(BaseModel):
+ repo_path: str = Field(
+ ...,
+ description="The path to the Git repository.",
+ )
+ branch_type: str = Field(
+ ...,
+ description="Whether to list local branches ('local'), remote branches ('remote') or all branches('all').",
+ )
+ contains: Optional[str] = Field(
+ None,
+ description="The commit sha that branch should contain. Do not pass anything to this param if no commit sha is specified",
+ )
+ not_contains: Optional[str] = Field(
+ None,
+ description="The commit sha that branch should NOT contain. Do not pass anything to this param if no commit sha is specified",
+ )
+
class GitTools(str, Enum):
STATUS = "git_status"
DIFF_UNSTAGED = "git_diff_unstaged"
@@ -72,18 +96,19 @@ class GitTools(str, Enum):
CHECKOUT = "git_checkout"
SHOW = "git_show"
INIT = "git_init"
+ BRANCH = "git_branch"
def git_status(repo: git.Repo) -> str:
return repo.git.status()
-def git_diff_unstaged(repo: git.Repo) -> str:
- return repo.git.diff()
+def git_diff_unstaged(repo: git.Repo, context_lines: int = DEFAULT_CONTEXT_LINES) -> str:
+ return repo.git.diff(f"--unified={context_lines}")
-def git_diff_staged(repo: git.Repo) -> str:
- return repo.git.diff("--cached")
+def git_diff_staged(repo: git.Repo, context_lines: int = DEFAULT_CONTEXT_LINES) -> str:
+ return repo.git.diff(f"--unified={context_lines}", "--cached")
-def git_diff(repo: git.Repo, target: str) -> str:
- return repo.git.diff(target)
+def git_diff(repo: git.Repo, target: str, context_lines: int = DEFAULT_CONTEXT_LINES) -> str:
+ return repo.git.diff(f"--unified={context_lines}", target)
def git_commit(repo: git.Repo, message: str) -> str:
commit = repo.index.commit(message)
@@ -102,16 +127,16 @@ def git_log(repo: git.Repo, max_count: int = 10) -> list[str]:
log = []
for commit in commits:
log.append(
- f"Commit: {commit.hexsha}\n"
- f"Author: {commit.author}\n"
+ f"Commit: {commit.hexsha!r}\n"
+ f"Author: {commit.author!r}\n"
f"Date: {commit.authored_datetime}\n"
- f"Message: {commit.message}\n"
+ f"Message: {commit.message!r}\n"
)
return log
def git_create_branch(repo: git.Repo, branch_name: str, base_branch: str | None = None) -> str:
if base_branch:
- base = repo.refs[base_branch]
+ base = repo.references[base_branch]
else:
base = repo.active_branch
@@ -132,10 +157,10 @@ def git_init(repo_path: str) -> str:
def git_show(repo: git.Repo, revision: str) -> str:
commit = repo.commit(revision)
output = [
- f"Commit: {commit.hexsha}\n"
- f"Author: {commit.author}\n"
- f"Date: {commit.authored_datetime}\n"
- f"Message: {commit.message}\n"
+ f"Commit: {commit.hexsha!r}\n"
+ f"Author: {commit.author!r}\n"
+ f"Date: {commit.authored_datetime!r}\n"
+ f"Message: {commit.message!r}\n"
]
if commit.parents:
parent = commit.parents[0]
@@ -147,6 +172,34 @@ def git_show(repo: git.Repo, revision: str) -> str:
output.append(d.diff.decode('utf-8'))
return "".join(output)
+def git_branch(repo: git.Repo, branch_type: str, contains: str | None = None, not_contains: str | None = None) -> str:
+ match contains:
+ case None:
+ contains_sha = (None,)
+ case _:
+ contains_sha = ("--contains", contains)
+
+ match not_contains:
+ case None:
+ not_contains_sha = (None,)
+ case _:
+ not_contains_sha = ("--no-contains", not_contains)
+
+ match branch_type:
+ case 'local':
+ b_type = None
+ case 'remote':
+ b_type = "-r"
+ case 'all':
+ b_type = "-a"
+ case _:
+ return f"Invalid branch type: {branch_type}"
+
+ # None value will be auto deleted by GitPython
+ branch_info = repo.git.branch(b_type, *contains_sha, *not_contains_sha)
+
+ return branch_info
+
async def serve(repository: Path | None) -> None:
logger = logging.getLogger(__name__)
@@ -166,62 +219,67 @@ async def serve(repository: Path | None) -> None:
Tool(
name=GitTools.STATUS,
description="Shows the working tree status",
- inputSchema=GitStatus.schema(),
+ inputSchema=GitStatus.model_json_schema(),
),
Tool(
name=GitTools.DIFF_UNSTAGED,
description="Shows changes in the working directory that are not yet staged",
- inputSchema=GitDiffUnstaged.schema(),
+ inputSchema=GitDiffUnstaged.model_json_schema(),
),
Tool(
name=GitTools.DIFF_STAGED,
description="Shows changes that are staged for commit",
- inputSchema=GitDiffStaged.schema(),
+ inputSchema=GitDiffStaged.model_json_schema(),
),
Tool(
name=GitTools.DIFF,
description="Shows differences between branches or commits",
- inputSchema=GitDiff.schema(),
+ inputSchema=GitDiff.model_json_schema(),
),
Tool(
name=GitTools.COMMIT,
description="Records changes to the repository",
- inputSchema=GitCommit.schema(),
+ inputSchema=GitCommit.model_json_schema(),
),
Tool(
name=GitTools.ADD,
description="Adds file contents to the staging area",
- inputSchema=GitAdd.schema(),
+ inputSchema=GitAdd.model_json_schema(),
),
Tool(
name=GitTools.RESET,
description="Unstages all staged changes",
- inputSchema=GitReset.schema(),
+ inputSchema=GitReset.model_json_schema(),
),
Tool(
name=GitTools.LOG,
description="Shows the commit logs",
- inputSchema=GitLog.schema(),
+ inputSchema=GitLog.model_json_schema(),
),
Tool(
name=GitTools.CREATE_BRANCH,
description="Creates a new branch from an optional base branch",
- inputSchema=GitCreateBranch.schema(),
+ inputSchema=GitCreateBranch.model_json_schema(),
),
Tool(
name=GitTools.CHECKOUT,
description="Switches branches",
- inputSchema=GitCheckout.schema(),
+ inputSchema=GitCheckout.model_json_schema(),
),
Tool(
name=GitTools.SHOW,
description="Shows the contents of a commit",
- inputSchema=GitShow.schema(),
+ inputSchema=GitShow.model_json_schema(),
),
Tool(
name=GitTools.INIT,
description="Initialize a new Git repository",
- inputSchema=GitInit.schema(),
+ inputSchema=GitInit.model_json_schema(),
+ ),
+ Tool(
+ name=GitTools.BRANCH,
+ description="List Git branches",
+ inputSchema=GitBranch.model_json_schema(),
)
]
@@ -278,21 +336,21 @@ async def serve(repository: Path | None) -> None:
)]
case GitTools.DIFF_UNSTAGED:
- diff = git_diff_unstaged(repo)
+ diff = git_diff_unstaged(repo, arguments.get("context_lines", DEFAULT_CONTEXT_LINES))
return [TextContent(
type="text",
text=f"Unstaged changes:\n{diff}"
)]
case GitTools.DIFF_STAGED:
- diff = git_diff_staged(repo)
+ diff = git_diff_staged(repo, arguments.get("context_lines", DEFAULT_CONTEXT_LINES))
return [TextContent(
type="text",
text=f"Staged changes:\n{diff}"
)]
case GitTools.DIFF:
- diff = git_diff(repo, arguments["target"])
+ diff = git_diff(repo, arguments["target"], arguments.get("context_lines", DEFAULT_CONTEXT_LINES))
return [TextContent(
type="text",
text=f"Diff with {arguments['target']}:\n{diff}"
@@ -351,6 +409,18 @@ async def serve(repository: Path | None) -> None:
text=result
)]
+ case GitTools.BRANCH:
+ result = git_branch(
+ repo,
+ arguments.get("branch_type", 'local'),
+ arguments.get("contains", None),
+ arguments.get("not_contains", None),
+ )
+ return [TextContent(
+ type="text",
+ text=result
+ )]
+
case _:
raise ValueError(f"Unknown tool: {name}")
diff --git a/src/git/tests/test_server.py b/src/git/tests/test_server.py
index 0ec4d52c..911a90cf 100644
--- a/src/git/tests/test_server.py
+++ b/src/git/tests/test_server.py
@@ -1,7 +1,7 @@
import pytest
from pathlib import Path
import git
-from mcp_server_git.server import git_checkout
+from mcp_server_git.server import git_checkout, git_branch
import shutil
@pytest.fixture
@@ -27,4 +27,44 @@ def test_git_checkout_existing_branch(test_repository):
def test_git_checkout_nonexistent_branch(test_repository):
with pytest.raises(git.GitCommandError):
- git_checkout(test_repository, "nonexistent-branch")
\ No newline at end of file
+ git_checkout(test_repository, "nonexistent-branch")
+
+def test_git_branch_local(test_repository):
+ test_repository.git.branch("new-branch-local")
+ result = git_branch(test_repository, "local")
+ assert "new-branch-local" in result
+
+def test_git_branch_remote(test_repository):
+ # GitPython does not easily support creating remote branches without a remote.
+ # This test will check the behavior when 'remote' is specified without actual remotes.
+ result = git_branch(test_repository, "remote")
+ assert "" == result.strip() # Should be empty if no remote branches
+
+def test_git_branch_all(test_repository):
+ test_repository.git.branch("new-branch-all")
+ result = git_branch(test_repository, "all")
+ assert "new-branch-all" in result
+
+def test_git_branch_contains(test_repository):
+ # Create a new branch and commit to it
+ test_repository.git.checkout("-b", "feature-branch")
+ Path(test_repository.working_dir / Path("feature.txt")).write_text("feature content")
+ test_repository.index.add(["feature.txt"])
+ commit = test_repository.index.commit("feature commit")
+ test_repository.git.checkout("master")
+
+ result = git_branch(test_repository, "local", contains=commit.hexsha)
+ assert "feature-branch" in result
+ assert "master" not in result
+
+def test_git_branch_not_contains(test_repository):
+ # Create a new branch and commit to it
+ test_repository.git.checkout("-b", "another-feature-branch")
+ Path(test_repository.working_dir / Path("another_feature.txt")).write_text("another feature content")
+ test_repository.index.add(["another_feature.txt"])
+ commit = test_repository.index.commit("another feature commit")
+ test_repository.git.checkout("master")
+
+ result = git_branch(test_repository, "local", not_contains=commit.hexsha)
+ assert "another-feature-branch" not in result
+ assert "master" in result
diff --git a/src/github/Dockerfile b/src/github/Dockerfile
deleted file mode 100644
index a3ad36b8..00000000
--- a/src/github/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-# Must be entire project because `prepare` script is run during `npm install` and requires all files.
-COPY src/github /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-FROM node:22.12-alpine AS release
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-WORKDIR /app
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/github/README.md b/src/github/README.md
deleted file mode 100644
index a8e176f3..00000000
--- a/src/github/README.md
+++ /dev/null
@@ -1,372 +0,0 @@
-# GitHub MCP Server
-
-**Deprecation Notice:** Development for this project has been moved to GitHub in the http://github.com/github/github-mcp-server repo.
-
----
-
-MCP Server for the GitHub API, enabling file operations, repository management, search functionality, and more.
-
-### Features
-
-- **Automatic Branch Creation**: When creating/updating files or pushing changes, branches are automatically created if they don't exist
-- **Comprehensive Error Handling**: Clear error messages for common issues
-- **Git History Preservation**: Operations maintain proper Git history without force pushing
-- **Batch Operations**: Support for both single-file and multi-file operations
-- **Advanced Search**: Support for searching code, issues/PRs, and users
-
-
-## Tools
-
-1. `create_or_update_file`
- - Create or update a single file in a repository
- - Inputs:
- - `owner` (string): Repository owner (username or organization)
- - `repo` (string): Repository name
- - `path` (string): Path where to create/update the file
- - `content` (string): Content of the file
- - `message` (string): Commit message
- - `branch` (string): Branch to create/update the file in
- - `sha` (optional string): SHA of file being replaced (for updates)
- - Returns: File content and commit details
-
-2. `push_files`
- - Push multiple files in a single commit
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `branch` (string): Branch to push to
- - `files` (array): Files to push, each with `path` and `content`
- - `message` (string): Commit message
- - Returns: Updated branch reference
-
-3. `search_repositories`
- - Search for GitHub repositories
- - Inputs:
- - `query` (string): Search query
- - `page` (optional number): Page number for pagination
- - `perPage` (optional number): Results per page (max 100)
- - Returns: Repository search results
-
-4. `create_repository`
- - Create a new GitHub repository
- - Inputs:
- - `name` (string): Repository name
- - `description` (optional string): Repository description
- - `private` (optional boolean): Whether repo should be private
- - `autoInit` (optional boolean): Initialize with README
- - Returns: Created repository details
-
-5. `get_file_contents`
- - Get contents of a file or directory
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `path` (string): Path to file/directory
- - `branch` (optional string): Branch to get contents from
- - Returns: File/directory contents
-
-6. `create_issue`
- - Create a new issue
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `title` (string): Issue title
- - `body` (optional string): Issue description
- - `assignees` (optional string[]): Usernames to assign
- - `labels` (optional string[]): Labels to add
- - `milestone` (optional number): Milestone number
- - Returns: Created issue details
-
-7. `create_pull_request`
- - Create a new pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `title` (string): PR title
- - `body` (optional string): PR description
- - `head` (string): Branch containing changes
- - `base` (string): Branch to merge into
- - `draft` (optional boolean): Create as draft PR
- - `maintainer_can_modify` (optional boolean): Allow maintainer edits
- - Returns: Created pull request details
-
-8. `fork_repository`
- - Fork a repository
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `organization` (optional string): Organization to fork to
- - Returns: Forked repository details
-
-9. `create_branch`
- - Create a new branch
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `branch` (string): Name for new branch
- - `from_branch` (optional string): Source branch (defaults to repo default)
- - Returns: Created branch reference
-
-10. `list_issues`
- - List and filter repository issues
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `state` (optional string): Filter by state ('open', 'closed', 'all')
- - `labels` (optional string[]): Filter by labels
- - `sort` (optional string): Sort by ('created', 'updated', 'comments')
- - `direction` (optional string): Sort direction ('asc', 'desc')
- - `since` (optional string): Filter by date (ISO 8601 timestamp)
- - `page` (optional number): Page number
- - `per_page` (optional number): Results per page
- - Returns: Array of issue details
-
-11. `update_issue`
- - Update an existing issue
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `issue_number` (number): Issue number to update
- - `title` (optional string): New title
- - `body` (optional string): New description
- - `state` (optional string): New state ('open' or 'closed')
- - `labels` (optional string[]): New labels
- - `assignees` (optional string[]): New assignees
- - `milestone` (optional number): New milestone number
- - Returns: Updated issue details
-
-12. `add_issue_comment`
- - Add a comment to an issue
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `issue_number` (number): Issue number to comment on
- - `body` (string): Comment text
- - Returns: Created comment details
-
-13. `search_code`
- - Search for code across GitHub repositories
- - Inputs:
- - `q` (string): Search query using GitHub code search syntax
- - `sort` (optional string): Sort field ('indexed' only)
- - `order` (optional string): Sort order ('asc' or 'desc')
- - `per_page` (optional number): Results per page (max 100)
- - `page` (optional number): Page number
- - Returns: Code search results with repository context
-
-14. `search_issues`
- - Search for issues and pull requests
- - Inputs:
- - `q` (string): Search query using GitHub issues search syntax
- - `sort` (optional string): Sort field (comments, reactions, created, etc.)
- - `order` (optional string): Sort order ('asc' or 'desc')
- - `per_page` (optional number): Results per page (max 100)
- - `page` (optional number): Page number
- - Returns: Issue and pull request search results
-
-15. `search_users`
- - Search for GitHub users
- - Inputs:
- - `q` (string): Search query using GitHub users search syntax
- - `sort` (optional string): Sort field (followers, repositories, joined)
- - `order` (optional string): Sort order ('asc' or 'desc')
- - `per_page` (optional number): Results per page (max 100)
- - `page` (optional number): Page number
- - Returns: User search results
-
-16. `list_commits`
- - Gets commits of a branch in a repository
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `page` (optional string): page number
- - `per_page` (optional string): number of record per page
- - `sha` (optional string): branch name
- - Returns: List of commits
-
-17. `get_issue`
- - Gets the contents of an issue within a repository
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `issue_number` (number): Issue number to retrieve
- - Returns: Github Issue object & details
-
-18. `get_pull_request`
- - Get details of a specific pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - Returns: Pull request details including diff and review status
-
-19. `list_pull_requests`
- - List and filter repository pull requests
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `state` (optional string): Filter by state ('open', 'closed', 'all')
- - `head` (optional string): Filter by head user/org and branch
- - `base` (optional string): Filter by base branch
- - `sort` (optional string): Sort by ('created', 'updated', 'popularity', 'long-running')
- - `direction` (optional string): Sort direction ('asc', 'desc')
- - `per_page` (optional number): Results per page (max 100)
- - `page` (optional number): Page number
- - Returns: Array of pull request details
-
-20. `create_pull_request_review`
- - Create a review on a pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - `body` (string): Review comment text
- - `event` (string): Review action ('APPROVE', 'REQUEST_CHANGES', 'COMMENT')
- - `commit_id` (optional string): SHA of commit to review
- - `comments` (optional array): Line-specific comments, each with:
- - `path` (string): File path
- - `position` (number): Line position in diff
- - `body` (string): Comment text
- - Returns: Created review details
-
-21. `merge_pull_request`
- - Merge a pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - `commit_title` (optional string): Title for merge commit
- - `commit_message` (optional string): Extra detail for merge commit
- - `merge_method` (optional string): Merge method ('merge', 'squash', 'rebase')
- - Returns: Merge result details
-
-22. `get_pull_request_files`
- - Get the list of files changed in a pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - Returns: Array of changed files with patch and status details
-
-23. `get_pull_request_status`
- - Get the combined status of all status checks for a pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - Returns: Combined status check results and individual check details
-
-24. `update_pull_request_branch`
- - Update a pull request branch with the latest changes from the base branch (equivalent to GitHub's "Update branch" button)
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - `expected_head_sha` (optional string): The expected SHA of the pull request's HEAD ref
- - Returns: Success message when branch is updated
-
-25. `get_pull_request_comments`
- - Get the review comments on a pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - Returns: Array of pull request review comments with details like the comment text, author, and location in the diff
-
-26. `get_pull_request_reviews`
- - Get the reviews on a pull request
- - Inputs:
- - `owner` (string): Repository owner
- - `repo` (string): Repository name
- - `pull_number` (number): Pull request number
- - Returns: Array of pull request reviews with details like the review state (APPROVED, CHANGES_REQUESTED, etc.), reviewer, and review body
-
-## Search Query Syntax
-
-### Code Search
-- `language:javascript`: Search by programming language
-- `repo:owner/name`: Search in specific repository
-- `path:app/src`: Search in specific path
-- `extension:js`: Search by file extension
-- Example: `q: "import express" language:typescript path:src/`
-
-### Issues Search
-- `is:issue` or `is:pr`: Filter by type
-- `is:open` or `is:closed`: Filter by state
-- `label:bug`: Search by label
-- `author:username`: Search by author
-- Example: `q: "memory leak" is:issue is:open label:bug`
-
-### Users Search
-- `type:user` or `type:org`: Filter by account type
-- `followers:>1000`: Filter by followers
-- `location:London`: Search by location
-- Example: `q: "fullstack developer" location:London followers:>100`
-
-For detailed search syntax, see [GitHub's searching documentation](https://docs.github.com/en/search-github/searching-on-github).
-
-## Setup
-
-### Personal Access Token
-[Create a GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) with appropriate permissions:
- - Go to [Personal access tokens](https://github.com/settings/tokens) (in GitHub Settings > Developer settings)
- - Select which repositories you'd like this token to have access to (Public, All, or Select)
- - Create a token with the `repo` scope ("Full control of private repositories")
- - Alternatively, if working only with public repositories, select only the `public_repo` scope
- - Copy the generated token
-
-### Usage with Claude Desktop
-To use this with Claude Desktop, add the following to your `claude_desktop_config.json`:
-
-#### Docker
-```json
-{
- "mcpServers": {
- "github": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "-e",
- "GITHUB_PERSONAL_ACCESS_TOKEN",
- "mcp/github"
- ],
- "env": {
- "GITHUB_PERSONAL_ACCESS_TOKEN": ""
- }
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "github": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-github"
- ],
- "env": {
- "GITHUB_PERSONAL_ACCESS_TOKEN": ""
- }
- }
- }
-}
-```
-
-## Build
-
-Docker build:
-
-```bash
-docker build -t mcp/github -f src/github/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/github/common/errors.ts b/src/github/common/errors.ts
deleted file mode 100644
index 5b940f3b..00000000
--- a/src/github/common/errors.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-export class GitHubError extends Error {
- constructor(
- message: string,
- public readonly status: number,
- public readonly response: unknown
- ) {
- super(message);
- this.name = "GitHubError";
- }
-}
-
-export class GitHubValidationError extends GitHubError {
- constructor(message: string, status: number, response: unknown) {
- super(message, status, response);
- this.name = "GitHubValidationError";
- }
-}
-
-export class GitHubResourceNotFoundError extends GitHubError {
- constructor(resource: string) {
- super(`Resource not found: ${resource}`, 404, { message: `${resource} not found` });
- this.name = "GitHubResourceNotFoundError";
- }
-}
-
-export class GitHubAuthenticationError extends GitHubError {
- constructor(message = "Authentication failed") {
- super(message, 401, { message });
- this.name = "GitHubAuthenticationError";
- }
-}
-
-export class GitHubPermissionError extends GitHubError {
- constructor(message = "Insufficient permissions") {
- super(message, 403, { message });
- this.name = "GitHubPermissionError";
- }
-}
-
-export class GitHubRateLimitError extends GitHubError {
- constructor(
- message = "Rate limit exceeded",
- public readonly resetAt: Date
- ) {
- super(message, 429, { message, reset_at: resetAt.toISOString() });
- this.name = "GitHubRateLimitError";
- }
-}
-
-export class GitHubConflictError extends GitHubError {
- constructor(message: string) {
- super(message, 409, { message });
- this.name = "GitHubConflictError";
- }
-}
-
-export function isGitHubError(error: unknown): error is GitHubError {
- return error instanceof GitHubError;
-}
-
-export function createGitHubError(status: number, response: any): GitHubError {
- switch (status) {
- case 401:
- return new GitHubAuthenticationError(response?.message);
- case 403:
- return new GitHubPermissionError(response?.message);
- case 404:
- return new GitHubResourceNotFoundError(response?.message || "Resource");
- case 409:
- return new GitHubConflictError(response?.message || "Conflict occurred");
- case 422:
- return new GitHubValidationError(
- response?.message || "Validation failed",
- status,
- response
- );
- case 429:
- return new GitHubRateLimitError(
- response?.message,
- new Date(response?.reset_at || Date.now() + 60000)
- );
- default:
- return new GitHubError(
- response?.message || "GitHub API error",
- status,
- response
- );
- }
-}
\ No newline at end of file
diff --git a/src/github/common/types.ts b/src/github/common/types.ts
deleted file mode 100644
index 1ff9c7cc..00000000
--- a/src/github/common/types.ts
+++ /dev/null
@@ -1,259 +0,0 @@
-import { z } from "zod";
-
-// Base schemas for common types
-export const GitHubAuthorSchema = z.object({
- name: z.string(),
- email: z.string(),
- date: z.string(),
-});
-
-export const GitHubOwnerSchema = z.object({
- login: z.string(),
- id: z.number(),
- node_id: z.string(),
- avatar_url: z.string(),
- url: z.string(),
- html_url: z.string(),
- type: z.string(),
-});
-
-export const GitHubRepositorySchema = z.object({
- id: z.number(),
- node_id: z.string(),
- name: z.string(),
- full_name: z.string(),
- private: z.boolean(),
- owner: GitHubOwnerSchema,
- html_url: z.string(),
- description: z.string().nullable(),
- fork: z.boolean(),
- url: z.string(),
- created_at: z.string(),
- updated_at: z.string(),
- pushed_at: z.string(),
- git_url: z.string(),
- ssh_url: z.string(),
- clone_url: z.string(),
- default_branch: z.string(),
-});
-
-export const GithubFileContentLinks = z.object({
- self: z.string(),
- git: z.string().nullable(),
- html: z.string().nullable()
-});
-
-export const GitHubFileContentSchema = z.object({
- name: z.string(),
- path: z.string(),
- sha: z.string(),
- size: z.number(),
- url: z.string(),
- html_url: z.string(),
- git_url: z.string(),
- download_url: z.string(),
- type: z.string(),
- content: z.string().optional(),
- encoding: z.string().optional(),
- _links: GithubFileContentLinks
-});
-
-export const GitHubDirectoryContentSchema = z.object({
- type: z.string(),
- size: z.number(),
- name: z.string(),
- path: z.string(),
- sha: z.string(),
- url: z.string(),
- git_url: z.string(),
- html_url: z.string(),
- download_url: z.string().nullable(),
-});
-
-export const GitHubContentSchema = z.union([
- GitHubFileContentSchema,
- z.array(GitHubDirectoryContentSchema),
-]);
-
-export const GitHubTreeEntrySchema = z.object({
- path: z.string(),
- mode: z.enum(["100644", "100755", "040000", "160000", "120000"]),
- type: z.enum(["blob", "tree", "commit"]),
- size: z.number().optional(),
- sha: z.string(),
- url: z.string(),
-});
-
-export const GitHubTreeSchema = z.object({
- sha: z.string(),
- url: z.string(),
- tree: z.array(GitHubTreeEntrySchema),
- truncated: z.boolean(),
-});
-
-export const GitHubCommitSchema = z.object({
- sha: z.string(),
- node_id: z.string(),
- url: z.string(),
- author: GitHubAuthorSchema,
- committer: GitHubAuthorSchema,
- message: z.string(),
- tree: z.object({
- sha: z.string(),
- url: z.string(),
- }),
- parents: z.array(
- z.object({
- sha: z.string(),
- url: z.string(),
- })
- ),
-});
-
-export const GitHubListCommitsSchema = z.array(z.object({
- sha: z.string(),
- node_id: z.string(),
- commit: z.object({
- author: GitHubAuthorSchema,
- committer: GitHubAuthorSchema,
- message: z.string(),
- tree: z.object({
- sha: z.string(),
- url: z.string()
- }),
- url: z.string(),
- comment_count: z.number(),
- }),
- url: z.string(),
- html_url: z.string(),
- comments_url: z.string()
-}));
-
-export const GitHubReferenceSchema = z.object({
- ref: z.string(),
- node_id: z.string(),
- url: z.string(),
- object: z.object({
- sha: z.string(),
- type: z.string(),
- url: z.string(),
- }),
-});
-
-// User and assignee schemas
-export const GitHubIssueAssigneeSchema = z.object({
- login: z.string(),
- id: z.number(),
- avatar_url: z.string(),
- url: z.string(),
- html_url: z.string(),
-});
-
-// Issue-related schemas
-export const GitHubLabelSchema = z.object({
- id: z.number(),
- node_id: z.string(),
- url: z.string(),
- name: z.string(),
- color: z.string(),
- default: z.boolean(),
- description: z.string().nullable().optional(),
-});
-
-export const GitHubMilestoneSchema = z.object({
- url: z.string(),
- html_url: z.string(),
- labels_url: z.string(),
- id: z.number(),
- node_id: z.string(),
- number: z.number(),
- title: z.string(),
- description: z.string(),
- state: z.string(),
-});
-
-export const GitHubIssueSchema = z.object({
- url: z.string(),
- repository_url: z.string(),
- labels_url: z.string(),
- comments_url: z.string(),
- events_url: z.string(),
- html_url: z.string(),
- id: z.number(),
- node_id: z.string(),
- number: z.number(),
- title: z.string(),
- user: GitHubIssueAssigneeSchema,
- labels: z.array(GitHubLabelSchema),
- state: z.string(),
- locked: z.boolean(),
- assignee: GitHubIssueAssigneeSchema.nullable(),
- assignees: z.array(GitHubIssueAssigneeSchema),
- milestone: GitHubMilestoneSchema.nullable(),
- comments: z.number(),
- created_at: z.string(),
- updated_at: z.string(),
- closed_at: z.string().nullable(),
- body: z.string().nullable(),
-});
-
-// Search-related schemas
-export const GitHubSearchResponseSchema = z.object({
- total_count: z.number(),
- incomplete_results: z.boolean(),
- items: z.array(GitHubRepositorySchema),
-});
-
-// Pull request schemas
-export const GitHubPullRequestRefSchema = z.object({
- label: z.string(),
- ref: z.string(),
- sha: z.string(),
- user: GitHubIssueAssigneeSchema,
- repo: GitHubRepositorySchema,
-});
-
-export const GitHubPullRequestSchema = z.object({
- url: z.string(),
- id: z.number(),
- node_id: z.string(),
- html_url: z.string(),
- diff_url: z.string(),
- patch_url: z.string(),
- issue_url: z.string(),
- number: z.number(),
- state: z.string(),
- locked: z.boolean(),
- title: z.string(),
- user: GitHubIssueAssigneeSchema,
- body: z.string().nullable(),
- created_at: z.string(),
- updated_at: z.string(),
- closed_at: z.string().nullable(),
- merged_at: z.string().nullable(),
- merge_commit_sha: z.string().nullable(),
- assignee: GitHubIssueAssigneeSchema.nullable(),
- assignees: z.array(GitHubIssueAssigneeSchema),
- requested_reviewers: z.array(GitHubIssueAssigneeSchema),
- labels: z.array(GitHubLabelSchema),
- head: GitHubPullRequestRefSchema,
- base: GitHubPullRequestRefSchema,
-});
-
-// Export types
-export type GitHubAuthor = z.infer;
-export type GitHubRepository = z.infer;
-export type GitHubFileContent = z.infer;
-export type GitHubDirectoryContent = z.infer;
-export type GitHubContent = z.infer;
-export type GitHubTree = z.infer;
-export type GitHubCommit = z.infer;
-export type GitHubListCommits = z.infer;
-export type GitHubReference = z.infer;
-export type GitHubIssueAssignee = z.infer;
-export type GitHubLabel = z.infer;
-export type GitHubMilestone = z.infer;
-export type GitHubIssue = z.infer;
-export type GitHubSearchResponse = z.infer;
-export type GitHubPullRequest = z.infer;
-export type GitHubPullRequestRef = z.infer;
\ No newline at end of file
diff --git a/src/github/common/utils.ts b/src/github/common/utils.ts
deleted file mode 100644
index e85691a0..00000000
--- a/src/github/common/utils.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import { getUserAgent } from "universal-user-agent";
-import { createGitHubError } from "./errors.js";
-import { VERSION } from "./version.js";
-
-type RequestOptions = {
- method?: string;
- body?: unknown;
- headers?: Record;
-}
-
-async function parseResponseBody(response: Response): Promise {
- const contentType = response.headers.get("content-type");
- if (contentType?.includes("application/json")) {
- return response.json();
- }
- return response.text();
-}
-
-export function buildUrl(baseUrl: string, params: Record): string {
- const url = new URL(baseUrl);
- Object.entries(params).forEach(([key, value]) => {
- if (value !== undefined) {
- url.searchParams.append(key, value.toString());
- }
- });
- return url.toString();
-}
-
-const USER_AGENT = `modelcontextprotocol/servers/github/v${VERSION} ${getUserAgent()}`;
-
-export async function githubRequest(
- url: string,
- options: RequestOptions = {}
-): Promise {
- const headers: Record = {
- "Accept": "application/vnd.github.v3+json",
- "Content-Type": "application/json",
- "User-Agent": USER_AGENT,
- ...options.headers,
- };
-
- if (process.env.GITHUB_PERSONAL_ACCESS_TOKEN) {
- headers["Authorization"] = `Bearer ${process.env.GITHUB_PERSONAL_ACCESS_TOKEN}`;
- }
-
- const response = await fetch(url, {
- method: options.method || "GET",
- headers,
- body: options.body ? JSON.stringify(options.body) : undefined,
- });
-
- const responseBody = await parseResponseBody(response);
-
- if (!response.ok) {
- throw createGitHubError(response.status, responseBody);
- }
-
- return responseBody;
-}
-
-export function validateBranchName(branch: string): string {
- const sanitized = branch.trim();
- if (!sanitized) {
- throw new Error("Branch name cannot be empty");
- }
- if (sanitized.includes("..")) {
- throw new Error("Branch name cannot contain '..'");
- }
- if (/[\s~^:?*[\\\]]/.test(sanitized)) {
- throw new Error("Branch name contains invalid characters");
- }
- if (sanitized.startsWith("/") || sanitized.endsWith("/")) {
- throw new Error("Branch name cannot start or end with '/'");
- }
- if (sanitized.endsWith(".lock")) {
- throw new Error("Branch name cannot end with '.lock'");
- }
- return sanitized;
-}
-
-export function validateRepositoryName(name: string): string {
- const sanitized = name.trim().toLowerCase();
- if (!sanitized) {
- throw new Error("Repository name cannot be empty");
- }
- if (!/^[a-z0-9_.-]+$/.test(sanitized)) {
- throw new Error(
- "Repository name can only contain lowercase letters, numbers, hyphens, periods, and underscores"
- );
- }
- if (sanitized.startsWith(".") || sanitized.endsWith(".")) {
- throw new Error("Repository name cannot start or end with a period");
- }
- return sanitized;
-}
-
-export function validateOwnerName(owner: string): string {
- const sanitized = owner.trim().toLowerCase();
- if (!sanitized) {
- throw new Error("Owner name cannot be empty");
- }
- if (!/^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,38}$/.test(sanitized)) {
- throw new Error(
- "Owner name must start with a letter or number and can contain up to 39 characters"
- );
- }
- return sanitized;
-}
-
-export async function checkBranchExists(
- owner: string,
- repo: string,
- branch: string
-): Promise {
- try {
- await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/branches/${branch}`
- );
- return true;
- } catch (error) {
- if (error && typeof error === "object" && "status" in error && error.status === 404) {
- return false;
- }
- throw error;
- }
-}
-
-export async function checkUserExists(username: string): Promise {
- try {
- await githubRequest(`https://api.github.com/users/${username}`);
- return true;
- } catch (error) {
- if (error && typeof error === "object" && "status" in error && error.status === 404) {
- return false;
- }
- throw error;
- }
-}
\ No newline at end of file
diff --git a/src/github/common/version.ts b/src/github/common/version.ts
deleted file mode 100644
index 648f7c6b..00000000
--- a/src/github/common/version.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// If the format of this file changes, so it doesn't simply export a VERSION constant,
-// this will break .github/workflows/version-check.yml.
-export const VERSION = "0.6.2";
\ No newline at end of file
diff --git a/src/github/index.ts b/src/github/index.ts
deleted file mode 100644
index 0315a898..00000000
--- a/src/github/index.ts
+++ /dev/null
@@ -1,517 +0,0 @@
-#!/usr/bin/env node
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListToolsRequestSchema,
-} from "@modelcontextprotocol/sdk/types.js";
-import { z } from 'zod';
-import { zodToJsonSchema } from 'zod-to-json-schema';
-import fetch, { Request, Response } from 'node-fetch';
-
-import * as repository from './operations/repository.js';
-import * as files from './operations/files.js';
-import * as issues from './operations/issues.js';
-import * as pulls from './operations/pulls.js';
-import * as branches from './operations/branches.js';
-import * as search from './operations/search.js';
-import * as commits from './operations/commits.js';
-import {
- GitHubError,
- GitHubValidationError,
- GitHubResourceNotFoundError,
- GitHubAuthenticationError,
- GitHubPermissionError,
- GitHubRateLimitError,
- GitHubConflictError,
- isGitHubError,
-} from './common/errors.js';
-import { VERSION } from "./common/version.js";
-
-// If fetch doesn't exist in global scope, add it
-if (!globalThis.fetch) {
- globalThis.fetch = fetch as unknown as typeof global.fetch;
-}
-
-const server = new Server(
- {
- name: "github-mcp-server",
- version: VERSION,
- },
- {
- capabilities: {
- tools: {},
- },
- }
-);
-
-function formatGitHubError(error: GitHubError): string {
- let message = `GitHub API Error: ${error.message}`;
-
- if (error instanceof GitHubValidationError) {
- message = `Validation Error: ${error.message}`;
- if (error.response) {
- message += `\nDetails: ${JSON.stringify(error.response)}`;
- }
- } else if (error instanceof GitHubResourceNotFoundError) {
- message = `Not Found: ${error.message}`;
- } else if (error instanceof GitHubAuthenticationError) {
- message = `Authentication Failed: ${error.message}`;
- } else if (error instanceof GitHubPermissionError) {
- message = `Permission Denied: ${error.message}`;
- } else if (error instanceof GitHubRateLimitError) {
- message = `Rate Limit Exceeded: ${error.message}\nResets at: ${error.resetAt.toISOString()}`;
- } else if (error instanceof GitHubConflictError) {
- message = `Conflict: ${error.message}`;
- }
-
- return message;
-}
-
-server.setRequestHandler(ListToolsRequestSchema, async () => {
- return {
- tools: [
- {
- name: "create_or_update_file",
- description: "Create or update a single file in a GitHub repository",
- inputSchema: zodToJsonSchema(files.CreateOrUpdateFileSchema),
- },
- {
- name: "search_repositories",
- description: "Search for GitHub repositories",
- inputSchema: zodToJsonSchema(repository.SearchRepositoriesSchema),
- },
- {
- name: "create_repository",
- description: "Create a new GitHub repository in your account",
- inputSchema: zodToJsonSchema(repository.CreateRepositoryOptionsSchema),
- },
- {
- name: "get_file_contents",
- description: "Get the contents of a file or directory from a GitHub repository",
- inputSchema: zodToJsonSchema(files.GetFileContentsSchema),
- },
- {
- name: "push_files",
- description: "Push multiple files to a GitHub repository in a single commit",
- inputSchema: zodToJsonSchema(files.PushFilesSchema),
- },
- {
- name: "create_issue",
- description: "Create a new issue in a GitHub repository",
- inputSchema: zodToJsonSchema(issues.CreateIssueSchema),
- },
- {
- name: "create_pull_request",
- description: "Create a new pull request in a GitHub repository",
- inputSchema: zodToJsonSchema(pulls.CreatePullRequestSchema),
- },
- {
- name: "fork_repository",
- description: "Fork a GitHub repository to your account or specified organization",
- inputSchema: zodToJsonSchema(repository.ForkRepositorySchema),
- },
- {
- name: "create_branch",
- description: "Create a new branch in a GitHub repository",
- inputSchema: zodToJsonSchema(branches.CreateBranchSchema),
- },
- {
- name: "list_commits",
- description: "Get list of commits of a branch in a GitHub repository",
- inputSchema: zodToJsonSchema(commits.ListCommitsSchema)
- },
- {
- name: "list_issues",
- description: "List issues in a GitHub repository with filtering options",
- inputSchema: zodToJsonSchema(issues.ListIssuesOptionsSchema)
- },
- {
- name: "update_issue",
- description: "Update an existing issue in a GitHub repository",
- inputSchema: zodToJsonSchema(issues.UpdateIssueOptionsSchema)
- },
- {
- name: "add_issue_comment",
- description: "Add a comment to an existing issue",
- inputSchema: zodToJsonSchema(issues.IssueCommentSchema)
- },
- {
- name: "search_code",
- description: "Search for code across GitHub repositories",
- inputSchema: zodToJsonSchema(search.SearchCodeSchema),
- },
- {
- name: "search_issues",
- description: "Search for issues and pull requests across GitHub repositories",
- inputSchema: zodToJsonSchema(search.SearchIssuesSchema),
- },
- {
- name: "search_users",
- description: "Search for users on GitHub",
- inputSchema: zodToJsonSchema(search.SearchUsersSchema),
- },
- {
- name: "get_issue",
- description: "Get details of a specific issue in a GitHub repository.",
- inputSchema: zodToJsonSchema(issues.GetIssueSchema)
- },
- {
- name: "get_pull_request",
- description: "Get details of a specific pull request",
- inputSchema: zodToJsonSchema(pulls.GetPullRequestSchema)
- },
- {
- name: "list_pull_requests",
- description: "List and filter repository pull requests",
- inputSchema: zodToJsonSchema(pulls.ListPullRequestsSchema)
- },
- {
- name: "create_pull_request_review",
- description: "Create a review on a pull request",
- inputSchema: zodToJsonSchema(pulls.CreatePullRequestReviewSchema)
- },
- {
- name: "merge_pull_request",
- description: "Merge a pull request",
- inputSchema: zodToJsonSchema(pulls.MergePullRequestSchema)
- },
- {
- name: "get_pull_request_files",
- description: "Get the list of files changed in a pull request",
- inputSchema: zodToJsonSchema(pulls.GetPullRequestFilesSchema)
- },
- {
- name: "get_pull_request_status",
- description: "Get the combined status of all status checks for a pull request",
- inputSchema: zodToJsonSchema(pulls.GetPullRequestStatusSchema)
- },
- {
- name: "update_pull_request_branch",
- description: "Update a pull request branch with the latest changes from the base branch",
- inputSchema: zodToJsonSchema(pulls.UpdatePullRequestBranchSchema)
- },
- {
- name: "get_pull_request_comments",
- description: "Get the review comments on a pull request",
- inputSchema: zodToJsonSchema(pulls.GetPullRequestCommentsSchema)
- },
- {
- name: "get_pull_request_reviews",
- description: "Get the reviews on a pull request",
- inputSchema: zodToJsonSchema(pulls.GetPullRequestReviewsSchema)
- }
- ],
- };
-});
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- try {
- if (!request.params.arguments) {
- throw new Error("Arguments are required");
- }
-
- switch (request.params.name) {
- case "fork_repository": {
- const args = repository.ForkRepositorySchema.parse(request.params.arguments);
- const fork = await repository.forkRepository(args.owner, args.repo, args.organization);
- return {
- content: [{ type: "text", text: JSON.stringify(fork, null, 2) }],
- };
- }
-
- case "create_branch": {
- const args = branches.CreateBranchSchema.parse(request.params.arguments);
- const branch = await branches.createBranchFromRef(
- args.owner,
- args.repo,
- args.branch,
- args.from_branch
- );
- return {
- content: [{ type: "text", text: JSON.stringify(branch, null, 2) }],
- };
- }
-
- case "search_repositories": {
- const args = repository.SearchRepositoriesSchema.parse(request.params.arguments);
- const results = await repository.searchRepositories(
- args.query,
- args.page,
- args.perPage
- );
- return {
- content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
- };
- }
-
- case "create_repository": {
- const args = repository.CreateRepositoryOptionsSchema.parse(request.params.arguments);
- const result = await repository.createRepository(args);
- return {
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
- };
- }
-
- case "get_file_contents": {
- const args = files.GetFileContentsSchema.parse(request.params.arguments);
- const contents = await files.getFileContents(
- args.owner,
- args.repo,
- args.path,
- args.branch
- );
- return {
- content: [{ type: "text", text: JSON.stringify(contents, null, 2) }],
- };
- }
-
- case "create_or_update_file": {
- const args = files.CreateOrUpdateFileSchema.parse(request.params.arguments);
- const result = await files.createOrUpdateFile(
- args.owner,
- args.repo,
- args.path,
- args.content,
- args.message,
- args.branch,
- args.sha
- );
- return {
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
- };
- }
-
- case "push_files": {
- const args = files.PushFilesSchema.parse(request.params.arguments);
- const result = await files.pushFiles(
- args.owner,
- args.repo,
- args.branch,
- args.files,
- args.message
- );
- return {
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
- };
- }
-
- case "create_issue": {
- const args = issues.CreateIssueSchema.parse(request.params.arguments);
- const { owner, repo, ...options } = args;
-
- try {
- console.error(`[DEBUG] Attempting to create issue in ${owner}/${repo}`);
- console.error(`[DEBUG] Issue options:`, JSON.stringify(options, null, 2));
-
- const issue = await issues.createIssue(owner, repo, options);
-
- console.error(`[DEBUG] Issue created successfully`);
- return {
- content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
- };
- } catch (err) {
- // Type guard for Error objects
- const error = err instanceof Error ? err : new Error(String(err));
-
- console.error(`[ERROR] Failed to create issue:`, error);
-
- if (error instanceof GitHubResourceNotFoundError) {
- throw new Error(
- `Repository '${owner}/${repo}' not found. Please verify:\n` +
- `1. The repository exists\n` +
- `2. You have correct access permissions\n` +
- `3. The owner and repository names are spelled correctly`
- );
- }
-
- // Safely access error properties
- throw new Error(
- `Failed to create issue: ${error.message}${
- error.stack ? `\nStack: ${error.stack}` : ''
- }`
- );
- }
- }
-
- case "create_pull_request": {
- const args = pulls.CreatePullRequestSchema.parse(request.params.arguments);
- const pullRequest = await pulls.createPullRequest(args);
- return {
- content: [{ type: "text", text: JSON.stringify(pullRequest, null, 2) }],
- };
- }
-
- case "search_code": {
- const args = search.SearchCodeSchema.parse(request.params.arguments);
- const results = await search.searchCode(args);
- return {
- content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
- };
- }
-
- case "search_issues": {
- const args = search.SearchIssuesSchema.parse(request.params.arguments);
- const results = await search.searchIssues(args);
- return {
- content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
- };
- }
-
- case "search_users": {
- const args = search.SearchUsersSchema.parse(request.params.arguments);
- const results = await search.searchUsers(args);
- return {
- content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
- };
- }
-
- case "list_issues": {
- const args = issues.ListIssuesOptionsSchema.parse(request.params.arguments);
- const { owner, repo, ...options } = args;
- const result = await issues.listIssues(owner, repo, options);
- return {
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
- };
- }
-
- case "update_issue": {
- const args = issues.UpdateIssueOptionsSchema.parse(request.params.arguments);
- const { owner, repo, issue_number, ...options } = args;
- const result = await issues.updateIssue(owner, repo, issue_number, options);
- return {
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
- };
- }
-
- case "add_issue_comment": {
- const args = issues.IssueCommentSchema.parse(request.params.arguments);
- const { owner, repo, issue_number, body } = args;
- const result = await issues.addIssueComment(owner, repo, issue_number, body);
- return {
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
- };
- }
-
- case "list_commits": {
- const args = commits.ListCommitsSchema.parse(request.params.arguments);
- const results = await commits.listCommits(
- args.owner,
- args.repo,
- args.page,
- args.perPage,
- args.sha
- );
- return {
- content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
- };
- }
-
- case "get_issue": {
- const args = issues.GetIssueSchema.parse(request.params.arguments);
- const issue = await issues.getIssue(args.owner, args.repo, args.issue_number);
- return {
- content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
- };
- }
-
- case "get_pull_request": {
- const args = pulls.GetPullRequestSchema.parse(request.params.arguments);
- const pullRequest = await pulls.getPullRequest(args.owner, args.repo, args.pull_number);
- return {
- content: [{ type: "text", text: JSON.stringify(pullRequest, null, 2) }],
- };
- }
-
- case "list_pull_requests": {
- const args = pulls.ListPullRequestsSchema.parse(request.params.arguments);
- const { owner, repo, ...options } = args;
- const pullRequests = await pulls.listPullRequests(owner, repo, options);
- return {
- content: [{ type: "text", text: JSON.stringify(pullRequests, null, 2) }],
- };
- }
-
- case "create_pull_request_review": {
- const args = pulls.CreatePullRequestReviewSchema.parse(request.params.arguments);
- const { owner, repo, pull_number, ...options } = args;
- const review = await pulls.createPullRequestReview(owner, repo, pull_number, options);
- return {
- content: [{ type: "text", text: JSON.stringify(review, null, 2) }],
- };
- }
-
- case "merge_pull_request": {
- const args = pulls.MergePullRequestSchema.parse(request.params.arguments);
- const { owner, repo, pull_number, ...options } = args;
- const result = await pulls.mergePullRequest(owner, repo, pull_number, options);
- return {
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
- };
- }
-
- case "get_pull_request_files": {
- const args = pulls.GetPullRequestFilesSchema.parse(request.params.arguments);
- const files = await pulls.getPullRequestFiles(args.owner, args.repo, args.pull_number);
- return {
- content: [{ type: "text", text: JSON.stringify(files, null, 2) }],
- };
- }
-
- case "get_pull_request_status": {
- const args = pulls.GetPullRequestStatusSchema.parse(request.params.arguments);
- const status = await pulls.getPullRequestStatus(args.owner, args.repo, args.pull_number);
- return {
- content: [{ type: "text", text: JSON.stringify(status, null, 2) }],
- };
- }
-
- case "update_pull_request_branch": {
- const args = pulls.UpdatePullRequestBranchSchema.parse(request.params.arguments);
- const { owner, repo, pull_number, expected_head_sha } = args;
- await pulls.updatePullRequestBranch(owner, repo, pull_number, expected_head_sha);
- return {
- content: [{ type: "text", text: JSON.stringify({ success: true }, null, 2) }],
- };
- }
-
- case "get_pull_request_comments": {
- const args = pulls.GetPullRequestCommentsSchema.parse(request.params.arguments);
- const comments = await pulls.getPullRequestComments(args.owner, args.repo, args.pull_number);
- return {
- content: [{ type: "text", text: JSON.stringify(comments, null, 2) }],
- };
- }
-
- case "get_pull_request_reviews": {
- const args = pulls.GetPullRequestReviewsSchema.parse(request.params.arguments);
- const reviews = await pulls.getPullRequestReviews(args.owner, args.repo, args.pull_number);
- return {
- content: [{ type: "text", text: JSON.stringify(reviews, null, 2) }],
- };
- }
-
- default:
- throw new Error(`Unknown tool: ${request.params.name}`);
- }
- } catch (error) {
- if (error instanceof z.ZodError) {
- throw new Error(`Invalid input: ${JSON.stringify(error.errors)}`);
- }
- if (isGitHubError(error)) {
- throw new Error(formatGitHubError(error));
- }
- throw error;
- }
-});
-
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
- console.error("GitHub MCP Server running on stdio");
-}
-
-runServer().catch((error) => {
- console.error("Fatal error in main():", error);
- process.exit(1);
-});
\ No newline at end of file
diff --git a/src/github/operations/branches.ts b/src/github/operations/branches.ts
deleted file mode 100644
index 9b7033b5..00000000
--- a/src/github/operations/branches.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-import { z } from "zod";
-import { githubRequest } from "../common/utils.js";
-import { GitHubReferenceSchema } from "../common/types.js";
-
-// Schema definitions
-export const CreateBranchOptionsSchema = z.object({
- ref: z.string(),
- sha: z.string(),
-});
-
-export const CreateBranchSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- branch: z.string().describe("Name for the new branch"),
- from_branch: z.string().optional().describe("Optional: source branch to create from (defaults to the repository's default branch)"),
-});
-
-// Type exports
-export type CreateBranchOptions = z.infer;
-
-// Function implementations
-export async function getDefaultBranchSHA(owner: string, repo: string): Promise {
- try {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/refs/heads/main`
- );
- const data = GitHubReferenceSchema.parse(response);
- return data.object.sha;
- } catch (error) {
- const masterResponse = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/refs/heads/master`
- );
- if (!masterResponse) {
- throw new Error("Could not find default branch (tried 'main' and 'master')");
- }
- const data = GitHubReferenceSchema.parse(masterResponse);
- return data.object.sha;
- }
-}
-
-export async function createBranch(
- owner: string,
- repo: string,
- options: CreateBranchOptions
-): Promise> {
- const fullRef = `refs/heads/${options.ref}`;
-
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/refs`,
- {
- method: "POST",
- body: {
- ref: fullRef,
- sha: options.sha,
- },
- }
- );
-
- return GitHubReferenceSchema.parse(response);
-}
-
-export async function getBranchSHA(
- owner: string,
- repo: string,
- branch: string
-): Promise {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/refs/heads/${branch}`
- );
-
- const data = GitHubReferenceSchema.parse(response);
- return data.object.sha;
-}
-
-export async function createBranchFromRef(
- owner: string,
- repo: string,
- newBranch: string,
- fromBranch?: string
-): Promise> {
- let sha: string;
- if (fromBranch) {
- sha = await getBranchSHA(owner, repo, fromBranch);
- } else {
- sha = await getDefaultBranchSHA(owner, repo);
- }
-
- return createBranch(owner, repo, {
- ref: newBranch,
- sha,
- });
-}
-
-export async function updateBranch(
- owner: string,
- repo: string,
- branch: string,
- sha: string
-): Promise> {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/refs/heads/${branch}`,
- {
- method: "PATCH",
- body: {
- sha,
- force: true,
- },
- }
- );
-
- return GitHubReferenceSchema.parse(response);
-}
diff --git a/src/github/operations/commits.ts b/src/github/operations/commits.ts
deleted file mode 100644
index b10e1b5f..00000000
--- a/src/github/operations/commits.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { z } from "zod";
-import { githubRequest, buildUrl } from "../common/utils.js";
-
-export const ListCommitsSchema = z.object({
- owner: z.string(),
- repo: z.string(),
- sha: z.string().optional(),
- page: z.number().optional(),
- perPage: z.number().optional()
-});
-
-export async function listCommits(
- owner: string,
- repo: string,
- page?: number,
- perPage?: number,
- sha?: string
-) {
- return githubRequest(
- buildUrl(`https://api.github.com/repos/${owner}/${repo}/commits`, {
- page: page?.toString(),
- per_page: perPage?.toString(),
- sha
- })
- );
-}
\ No newline at end of file
diff --git a/src/github/operations/files.ts b/src/github/operations/files.ts
deleted file mode 100644
index 9517946e..00000000
--- a/src/github/operations/files.ts
+++ /dev/null
@@ -1,219 +0,0 @@
-import { z } from "zod";
-import { githubRequest } from "../common/utils.js";
-import {
- GitHubContentSchema,
- GitHubAuthorSchema,
- GitHubTreeSchema,
- GitHubCommitSchema,
- GitHubReferenceSchema,
- GitHubFileContentSchema,
-} from "../common/types.js";
-
-// Schema definitions
-export const FileOperationSchema = z.object({
- path: z.string(),
- content: z.string(),
-});
-
-export const CreateOrUpdateFileSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- path: z.string().describe("Path where to create/update the file"),
- content: z.string().describe("Content of the file"),
- message: z.string().describe("Commit message"),
- branch: z.string().describe("Branch to create/update the file in"),
- sha: z.string().optional().describe("SHA of the file being replaced (required when updating existing files)"),
-});
-
-export const GetFileContentsSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- path: z.string().describe("Path to the file or directory"),
- branch: z.string().optional().describe("Branch to get contents from"),
-});
-
-export const PushFilesSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- branch: z.string().describe("Branch to push to (e.g., 'main' or 'master')"),
- files: z.array(FileOperationSchema).describe("Array of files to push"),
- message: z.string().describe("Commit message"),
-});
-
-export const GitHubCreateUpdateFileResponseSchema = z.object({
- content: GitHubFileContentSchema.nullable(),
- commit: z.object({
- sha: z.string(),
- node_id: z.string(),
- url: z.string(),
- html_url: z.string(),
- author: GitHubAuthorSchema,
- committer: GitHubAuthorSchema,
- message: z.string(),
- tree: z.object({
- sha: z.string(),
- url: z.string(),
- }),
- parents: z.array(
- z.object({
- sha: z.string(),
- url: z.string(),
- html_url: z.string(),
- })
- ),
- }),
-});
-
-// Type exports
-export type FileOperation = z.infer;
-export type GitHubCreateUpdateFileResponse = z.infer;
-
-// Function implementations
-export async function getFileContents(
- owner: string,
- repo: string,
- path: string,
- branch?: string
-) {
- let url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
- if (branch) {
- url += `?ref=${branch}`;
- }
-
- const response = await githubRequest(url);
- const data = GitHubContentSchema.parse(response);
-
- // If it's a file, decode the content
- if (!Array.isArray(data) && data.content) {
- data.content = Buffer.from(data.content, "base64").toString("utf8");
- }
-
- return data;
-}
-
-export async function createOrUpdateFile(
- owner: string,
- repo: string,
- path: string,
- content: string,
- message: string,
- branch: string,
- sha?: string
-) {
- const encodedContent = Buffer.from(content).toString("base64");
-
- let currentSha = sha;
- if (!currentSha) {
- try {
- const existingFile = await getFileContents(owner, repo, path, branch);
- if (!Array.isArray(existingFile)) {
- currentSha = existingFile.sha;
- }
- } catch (error) {
- console.error("Note: File does not exist in branch, will create new file");
- }
- }
-
- const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;
- const body = {
- message,
- content: encodedContent,
- branch,
- ...(currentSha ? { sha: currentSha } : {}),
- };
-
- const response = await githubRequest(url, {
- method: "PUT",
- body,
- });
-
- return GitHubCreateUpdateFileResponseSchema.parse(response);
-}
-
-async function createTree(
- owner: string,
- repo: string,
- files: FileOperation[],
- baseTree?: string
-) {
- const tree = files.map((file) => ({
- path: file.path,
- mode: "100644" as const,
- type: "blob" as const,
- content: file.content,
- }));
-
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/trees`,
- {
- method: "POST",
- body: {
- tree,
- base_tree: baseTree,
- },
- }
- );
-
- return GitHubTreeSchema.parse(response);
-}
-
-async function createCommit(
- owner: string,
- repo: string,
- message: string,
- tree: string,
- parents: string[]
-) {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/commits`,
- {
- method: "POST",
- body: {
- message,
- tree,
- parents,
- },
- }
- );
-
- return GitHubCommitSchema.parse(response);
-}
-
-async function updateReference(
- owner: string,
- repo: string,
- ref: string,
- sha: string
-) {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/refs/${ref}`,
- {
- method: "PATCH",
- body: {
- sha,
- force: true,
- },
- }
- );
-
- return GitHubReferenceSchema.parse(response);
-}
-
-export async function pushFiles(
- owner: string,
- repo: string,
- branch: string,
- files: FileOperation[],
- message: string
-) {
- const refResponse = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/git/refs/heads/${branch}`
- );
-
- const ref = GitHubReferenceSchema.parse(refResponse);
- const commitSha = ref.object.sha;
-
- const tree = await createTree(owner, repo, files, commitSha);
- const commit = await createCommit(owner, repo, message, tree.sha, [commitSha]);
- return await updateReference(owner, repo, `heads/${branch}`, commit.sha);
-}
diff --git a/src/github/operations/issues.ts b/src/github/operations/issues.ts
deleted file mode 100644
index d2907bf7..00000000
--- a/src/github/operations/issues.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { z } from "zod";
-import { githubRequest, buildUrl } from "../common/utils.js";
-
-export const GetIssueSchema = z.object({
- owner: z.string(),
- repo: z.string(),
- issue_number: z.number(),
-});
-
-export const IssueCommentSchema = z.object({
- owner: z.string(),
- repo: z.string(),
- issue_number: z.number(),
- body: z.string(),
-});
-
-export const CreateIssueOptionsSchema = z.object({
- title: z.string(),
- body: z.string().optional(),
- assignees: z.array(z.string()).optional(),
- milestone: z.number().optional(),
- labels: z.array(z.string()).optional(),
-});
-
-export const CreateIssueSchema = z.object({
- owner: z.string(),
- repo: z.string(),
- ...CreateIssueOptionsSchema.shape,
-});
-
-export const ListIssuesOptionsSchema = z.object({
- owner: z.string(),
- repo: z.string(),
- direction: z.enum(["asc", "desc"]).optional(),
- labels: z.array(z.string()).optional(),
- page: z.number().optional(),
- per_page: z.number().optional(),
- since: z.string().optional(),
- sort: z.enum(["created", "updated", "comments"]).optional(),
- state: z.enum(["open", "closed", "all"]).optional(),
-});
-
-export const UpdateIssueOptionsSchema = z.object({
- owner: z.string(),
- repo: z.string(),
- issue_number: z.number(),
- title: z.string().optional(),
- body: z.string().optional(),
- assignees: z.array(z.string()).optional(),
- milestone: z.number().optional(),
- labels: z.array(z.string()).optional(),
- state: z.enum(["open", "closed"]).optional(),
-});
-
-export async function getIssue(owner: string, repo: string, issue_number: number) {
- return githubRequest(`https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}`);
-}
-
-export async function addIssueComment(
- owner: string,
- repo: string,
- issue_number: number,
- body: string
-) {
- return githubRequest(`https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}/comments`, {
- method: "POST",
- body: { body },
- });
-}
-
-export async function createIssue(
- owner: string,
- repo: string,
- options: z.infer
-) {
- return githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/issues`,
- {
- method: "POST",
- body: options,
- }
- );
-}
-
-export async function listIssues(
- owner: string,
- repo: string,
- options: Omit, "owner" | "repo">
-) {
- const urlParams: Record = {
- direction: options.direction,
- labels: options.labels?.join(","),
- page: options.page?.toString(),
- per_page: options.per_page?.toString(),
- since: options.since,
- sort: options.sort,
- state: options.state
- };
-
- return githubRequest(
- buildUrl(`https://api.github.com/repos/${owner}/${repo}/issues`, urlParams)
- );
-}
-
-export async function updateIssue(
- owner: string,
- repo: string,
- issue_number: number,
- options: Omit, "owner" | "repo" | "issue_number">
-) {
- return githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/issues/${issue_number}`,
- {
- method: "PATCH",
- body: options,
- }
- );
-}
\ No newline at end of file
diff --git a/src/github/operations/pulls.ts b/src/github/operations/pulls.ts
deleted file mode 100644
index 3628e707..00000000
--- a/src/github/operations/pulls.ts
+++ /dev/null
@@ -1,311 +0,0 @@
-import { z } from "zod";
-import { githubRequest } from "../common/utils.js";
-import {
- GitHubPullRequestSchema,
- GitHubIssueAssigneeSchema,
- GitHubRepositorySchema,
-} from "../common/types.js";
-
-// Schema definitions
-export const PullRequestFileSchema = z.object({
- sha: z.string(),
- filename: z.string(),
- status: z.enum(['added', 'removed', 'modified', 'renamed', 'copied', 'changed', 'unchanged']),
- additions: z.number(),
- deletions: z.number(),
- changes: z.number(),
- blob_url: z.string(),
- raw_url: z.string(),
- contents_url: z.string(),
- patch: z.string().optional()
-});
-
-export const StatusCheckSchema = z.object({
- url: z.string(),
- state: z.enum(['error', 'failure', 'pending', 'success']),
- description: z.string().nullable(),
- target_url: z.string().nullable(),
- context: z.string(),
- created_at: z.string(),
- updated_at: z.string()
-});
-
-export const CombinedStatusSchema = z.object({
- state: z.enum(['error', 'failure', 'pending', 'success']),
- statuses: z.array(StatusCheckSchema),
- sha: z.string(),
- total_count: z.number()
-});
-
-export const PullRequestCommentSchema = z.object({
- url: z.string(),
- id: z.number(),
- node_id: z.string(),
- pull_request_review_id: z.number().nullable(),
- diff_hunk: z.string(),
- path: z.string().nullable(),
- position: z.number().nullable(),
- original_position: z.number().nullable(),
- commit_id: z.string(),
- original_commit_id: z.string(),
- user: GitHubIssueAssigneeSchema,
- body: z.string(),
- created_at: z.string(),
- updated_at: z.string(),
- html_url: z.string(),
- pull_request_url: z.string(),
- author_association: z.string(),
- _links: z.object({
- self: z.object({ href: z.string() }),
- html: z.object({ href: z.string() }),
- pull_request: z.object({ href: z.string() })
- })
-});
-
-export const PullRequestReviewSchema = z.object({
- id: z.number(),
- node_id: z.string(),
- user: GitHubIssueAssigneeSchema,
- body: z.string().nullable(),
- state: z.enum(['APPROVED', 'CHANGES_REQUESTED', 'COMMENTED', 'DISMISSED', 'PENDING']),
- html_url: z.string(),
- pull_request_url: z.string(),
- commit_id: z.string(),
- submitted_at: z.string().nullable(),
- author_association: z.string()
-});
-
-// Input schemas
-export const CreatePullRequestSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- title: z.string().describe("Pull request title"),
- body: z.string().optional().describe("Pull request body/description"),
- head: z.string().describe("The name of the branch where your changes are implemented"),
- base: z.string().describe("The name of the branch you want the changes pulled into"),
- draft: z.boolean().optional().describe("Whether to create the pull request as a draft"),
- maintainer_can_modify: z.boolean().optional().describe("Whether maintainers can modify the pull request")
-});
-
-export const GetPullRequestSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number")
-});
-
-export const ListPullRequestsSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- state: z.enum(['open', 'closed', 'all']).optional().describe("State of the pull requests to return"),
- head: z.string().optional().describe("Filter by head user or head organization and branch name"),
- base: z.string().optional().describe("Filter by base branch name"),
- sort: z.enum(['created', 'updated', 'popularity', 'long-running']).optional().describe("What to sort results by"),
- direction: z.enum(['asc', 'desc']).optional().describe("The direction of the sort"),
- per_page: z.number().optional().describe("Results per page (max 100)"),
- page: z.number().optional().describe("Page number of the results")
-});
-
-export const CreatePullRequestReviewSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number"),
- commit_id: z.string().optional().describe("The SHA of the commit that needs a review"),
- body: z.string().describe("The body text of the review"),
- event: z.enum(['APPROVE', 'REQUEST_CHANGES', 'COMMENT']).describe("The review action to perform"),
- comments: z.array(
- z.union([
- z.object({
- path: z.string().describe("The relative path to the file being commented on"),
- position: z.number().describe("The position in the diff where you want to add a review comment"),
- body: z.string().describe("Text of the review comment")
- }),
- z.object({
- path: z.string().describe("The relative path to the file being commented on"),
- line: z.number().describe("The line number in the file where you want to add a review comment"),
- body: z.string().describe("Text of the review comment")
- })
- ])
- ).optional().describe("Comments to post as part of the review (specify either position or line, not both)")
-});
-
-export const MergePullRequestSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number"),
- commit_title: z.string().optional().describe("Title for the automatic commit message"),
- commit_message: z.string().optional().describe("Extra detail to append to automatic commit message"),
- merge_method: z.enum(['merge', 'squash', 'rebase']).optional().describe("Merge method to use")
-});
-
-export const GetPullRequestFilesSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number")
-});
-
-export const GetPullRequestStatusSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number")
-});
-
-export const UpdatePullRequestBranchSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number"),
- expected_head_sha: z.string().optional().describe("The expected SHA of the pull request's HEAD ref")
-});
-
-export const GetPullRequestCommentsSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number")
-});
-
-export const GetPullRequestReviewsSchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- pull_number: z.number().describe("Pull request number")
-});
-
-// Function implementations
-export async function createPullRequest(
- params: z.infer
-): Promise> {
- const { owner, repo, ...options } = CreatePullRequestSchema.parse(params);
-
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls`,
- {
- method: "POST",
- body: options,
- }
- );
-
- return GitHubPullRequestSchema.parse(response);
-}
-
-export async function getPullRequest(
- owner: string,
- repo: string,
- pullNumber: number
-): Promise> {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}`
- );
- return GitHubPullRequestSchema.parse(response);
-}
-
-export async function listPullRequests(
- owner: string,
- repo: string,
- options: Omit, 'owner' | 'repo'>
-): Promise[]> {
- const url = new URL(`https://api.github.com/repos/${owner}/${repo}/pulls`);
-
- if (options.state) url.searchParams.append('state', options.state);
- if (options.head) url.searchParams.append('head', options.head);
- if (options.base) url.searchParams.append('base', options.base);
- if (options.sort) url.searchParams.append('sort', options.sort);
- if (options.direction) url.searchParams.append('direction', options.direction);
- if (options.per_page) url.searchParams.append('per_page', options.per_page.toString());
- if (options.page) url.searchParams.append('page', options.page.toString());
-
- const response = await githubRequest(url.toString());
- return z.array(GitHubPullRequestSchema).parse(response);
-}
-
-export async function createPullRequestReview(
- owner: string,
- repo: string,
- pullNumber: number,
- options: Omit, 'owner' | 'repo' | 'pull_number'>
-): Promise> {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/reviews`,
- {
- method: 'POST',
- body: options,
- }
- );
- return PullRequestReviewSchema.parse(response);
-}
-
-export async function mergePullRequest(
- owner: string,
- repo: string,
- pullNumber: number,
- options: Omit, 'owner' | 'repo' | 'pull_number'>
-): Promise {
- return githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/merge`,
- {
- method: 'PUT',
- body: options,
- }
- );
-}
-
-export async function getPullRequestFiles(
- owner: string,
- repo: string,
- pullNumber: number
-): Promise[]> {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/files`
- );
- return z.array(PullRequestFileSchema).parse(response);
-}
-
-export async function updatePullRequestBranch(
- owner: string,
- repo: string,
- pullNumber: number,
- expectedHeadSha?: string
-): Promise {
- await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/update-branch`,
- {
- method: "PUT",
- body: expectedHeadSha ? { expected_head_sha: expectedHeadSha } : undefined,
- }
- );
-}
-
-export async function getPullRequestComments(
- owner: string,
- repo: string,
- pullNumber: number
-): Promise[]> {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/comments`
- );
- return z.array(PullRequestCommentSchema).parse(response);
-}
-
-export async function getPullRequestReviews(
- owner: string,
- repo: string,
- pullNumber: number
-): Promise[]> {
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/pulls/${pullNumber}/reviews`
- );
- return z.array(PullRequestReviewSchema).parse(response);
-}
-
-export async function getPullRequestStatus(
- owner: string,
- repo: string,
- pullNumber: number
-): Promise> {
- // First get the PR to get the head SHA
- const pr = await getPullRequest(owner, repo, pullNumber);
- const sha = pr.head.sha;
-
- // Then get the combined status for that SHA
- const response = await githubRequest(
- `https://api.github.com/repos/${owner}/${repo}/commits/${sha}/status`
- );
- return CombinedStatusSchema.parse(response);
-}
\ No newline at end of file
diff --git a/src/github/operations/repository.ts b/src/github/operations/repository.ts
deleted file mode 100644
index 4cf0ab9b..00000000
--- a/src/github/operations/repository.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { z } from "zod";
-import { githubRequest } from "../common/utils.js";
-import { GitHubRepositorySchema, GitHubSearchResponseSchema } from "../common/types.js";
-
-// Schema definitions
-export const CreateRepositoryOptionsSchema = z.object({
- name: z.string().describe("Repository name"),
- description: z.string().optional().describe("Repository description"),
- private: z.boolean().optional().describe("Whether the repository should be private"),
- autoInit: z.boolean().optional().describe("Initialize with README.md"),
-});
-
-export const SearchRepositoriesSchema = z.object({
- query: z.string().describe("Search query (see GitHub search syntax)"),
- page: z.number().optional().describe("Page number for pagination (default: 1)"),
- perPage: z.number().optional().describe("Number of results per page (default: 30, max: 100)"),
-});
-
-export const ForkRepositorySchema = z.object({
- owner: z.string().describe("Repository owner (username or organization)"),
- repo: z.string().describe("Repository name"),
- organization: z.string().optional().describe("Optional: organization to fork to (defaults to your personal account)"),
-});
-
-// Type exports
-export type CreateRepositoryOptions = z.infer;
-
-// Function implementations
-export async function createRepository(options: CreateRepositoryOptions) {
- const response = await githubRequest("https://api.github.com/user/repos", {
- method: "POST",
- body: options,
- });
- return GitHubRepositorySchema.parse(response);
-}
-
-export async function searchRepositories(
- query: string,
- page: number = 1,
- perPage: number = 30
-) {
- const url = new URL("https://api.github.com/search/repositories");
- url.searchParams.append("q", query);
- url.searchParams.append("page", page.toString());
- url.searchParams.append("per_page", perPage.toString());
-
- const response = await githubRequest(url.toString());
- return GitHubSearchResponseSchema.parse(response);
-}
-
-export async function forkRepository(
- owner: string,
- repo: string,
- organization?: string
-) {
- const url = organization
- ? `https://api.github.com/repos/${owner}/${repo}/forks?organization=${organization}`
- : `https://api.github.com/repos/${owner}/${repo}/forks`;
-
- const response = await githubRequest(url, { method: "POST" });
- return GitHubRepositorySchema.extend({
- parent: GitHubRepositorySchema,
- source: GitHubRepositorySchema,
- }).parse(response);
-}
diff --git a/src/github/operations/search.ts b/src/github/operations/search.ts
deleted file mode 100644
index 76faa729..00000000
--- a/src/github/operations/search.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { z } from "zod";
-import { githubRequest, buildUrl } from "../common/utils.js";
-
-export const SearchOptions = z.object({
- q: z.string(),
- order: z.enum(["asc", "desc"]).optional(),
- page: z.number().min(1).optional(),
- per_page: z.number().min(1).max(100).optional(),
-});
-
-export const SearchUsersOptions = SearchOptions.extend({
- sort: z.enum(["followers", "repositories", "joined"]).optional(),
-});
-
-export const SearchIssuesOptions = SearchOptions.extend({
- sort: z.enum([
- "comments",
- "reactions",
- "reactions-+1",
- "reactions--1",
- "reactions-smile",
- "reactions-thinking_face",
- "reactions-heart",
- "reactions-tada",
- "interactions",
- "created",
- "updated",
- ]).optional(),
-});
-
-export const SearchCodeSchema = SearchOptions;
-export const SearchUsersSchema = SearchUsersOptions;
-export const SearchIssuesSchema = SearchIssuesOptions;
-
-export async function searchCode(params: z.infer) {
- return githubRequest(buildUrl("https://api.github.com/search/code", params));
-}
-
-export async function searchIssues(params: z.infer) {
- return githubRequest(buildUrl("https://api.github.com/search/issues", params));
-}
-
-export async function searchUsers(params: z.infer) {
- return githubRequest(buildUrl("https://api.github.com/search/users", params));
-}
\ No newline at end of file
diff --git a/src/github/package.json b/src/github/package.json
deleted file mode 100644
index 29f5296b..00000000
--- a/src/github/package.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-github",
- "version": "0.6.2",
- "description": "MCP server for using the GitHub API",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-github": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1",
- "@types/node": "^22",
- "@types/node-fetch": "^2.6.12",
- "node-fetch": "^3.3.2",
- "universal-user-agent": "^7.0.2",
- "zod": "^3.22.4",
- "zod-to-json-schema": "^3.23.5"
- },
- "devDependencies": {
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
diff --git a/src/github/tsconfig.json b/src/github/tsconfig.json
deleted file mode 100644
index 4d33cae1..00000000
--- a/src/github/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
- }
-
\ No newline at end of file
diff --git a/src/gitlab/Dockerfile b/src/gitlab/Dockerfile
deleted file mode 100644
index e119288d..00000000
--- a/src/gitlab/Dockerfile
+++ /dev/null
@@ -1,24 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-COPY src/gitlab /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
-
-FROM node:22.12-alpine AS release
-
-WORKDIR /app
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/gitlab/README.md b/src/gitlab/README.md
deleted file mode 100644
index 4b3d6dc3..00000000
--- a/src/gitlab/README.md
+++ /dev/null
@@ -1,172 +0,0 @@
-# GitLab MCP Server
-
-MCP Server for the GitLab API, enabling project management, file operations, and more.
-
-### Features
-
-- **Automatic Branch Creation**: When creating/updating files or pushing changes, branches are automatically created if they don't exist
-- **Comprehensive Error Handling**: Clear error messages for common issues
-- **Git History Preservation**: Operations maintain proper Git history without force pushing
-- **Batch Operations**: Support for both single-file and multi-file operations
-
-
-## Tools
-
-1. `create_or_update_file`
- - Create or update a single file in a project
- - Inputs:
- - `project_id` (string): Project ID or URL-encoded path
- - `file_path` (string): Path where to create/update the file
- - `content` (string): Content of the file
- - `commit_message` (string): Commit message
- - `branch` (string): Branch to create/update the file in
- - `previous_path` (optional string): Path of the file to move/rename
- - Returns: File content and commit details
-
-2. `push_files`
- - Push multiple files in a single commit
- - Inputs:
- - `project_id` (string): Project ID or URL-encoded path
- - `branch` (string): Branch to push to
- - `files` (array): Files to push, each with `file_path` and `content`
- - `commit_message` (string): Commit message
- - Returns: Updated branch reference
-
-3. `search_repositories`
- - Search for GitLab projects
- - Inputs:
- - `search` (string): Search query
- - `page` (optional number): Page number for pagination
- - `per_page` (optional number): Results per page (default 20)
- - Returns: Project search results
-
-4. `create_repository`
- - Create a new GitLab project
- - Inputs:
- - `name` (string): Project name
- - `description` (optional string): Project description
- - `visibility` (optional string): 'private', 'internal', or 'public'
- - `initialize_with_readme` (optional boolean): Initialize with README
- - Returns: Created project details
-
-5. `get_file_contents`
- - Get contents of a file or directory
- - Inputs:
- - `project_id` (string): Project ID or URL-encoded path
- - `file_path` (string): Path to file/directory
- - `ref` (optional string): Branch/tag/commit to get contents from
- - Returns: File/directory contents
-
-6. `create_issue`
- - Create a new issue
- - Inputs:
- - `project_id` (string): Project ID or URL-encoded path
- - `title` (string): Issue title
- - `description` (optional string): Issue description
- - `assignee_ids` (optional number[]): User IDs to assign
- - `labels` (optional string[]): Labels to add
- - `milestone_id` (optional number): Milestone ID
- - Returns: Created issue details
-
-7. `create_merge_request`
- - Create a new merge request
- - Inputs:
- - `project_id` (string): Project ID or URL-encoded path
- - `title` (string): MR title
- - `description` (optional string): MR description
- - `source_branch` (string): Branch containing changes
- - `target_branch` (string): Branch to merge into
- - `draft` (optional boolean): Create as draft MR
- - `allow_collaboration` (optional boolean): Allow commits from upstream members
- - Returns: Created merge request details
-
-8. `fork_repository`
- - Fork a project
- - Inputs:
- - `project_id` (string): Project ID or URL-encoded path
- - `namespace` (optional string): Namespace to fork to
- - Returns: Forked project details
-
-9. `create_branch`
- - Create a new branch
- - Inputs:
- - `project_id` (string): Project ID or URL-encoded path
- - `branch` (string): Name for new branch
- - `ref` (optional string): Source branch/commit for new branch
- - Returns: Created branch reference
-
-## Setup
-
-### Personal Access Token
-[Create a GitLab Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) with appropriate permissions:
- - Go to User Settings > Access Tokens in GitLab
- - Select the required scopes:
- - `api` for full API access
- - `read_api` for read-only access
- - `read_repository` and `write_repository` for repository operations
- - Create the token and save it securely
-
-### Usage with Claude Desktop
-Add the following to your `claude_desktop_config.json`:
-
-#### Docker
-```json
-{
- "mcpServers": {
- "gitlab": {
- "command": "docker",
- "args": [
- "run",
- "--rm",
- "-i",
- "-e",
- "GITLAB_PERSONAL_ACCESS_TOKEN",
- "-e",
- "GITLAB_API_URL",
- "mcp/gitlab"
- ],
- "env": {
- "GITLAB_PERSONAL_ACCESS_TOKEN": "",
- "GITLAB_API_URL": "https://gitlab.com/api/v4" // Optional, for self-hosted instances
- }
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "gitlab": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-gitlab"
- ],
- "env": {
- "GITLAB_PERSONAL_ACCESS_TOKEN": "",
- "GITLAB_API_URL": "https://gitlab.com/api/v4" // Optional, for self-hosted instances
- }
- }
- }
-}
-```
-
-## Build
-
-Docker build:
-
-```bash
-docker build -t vonwig/gitlab:mcp -f src/gitlab/Dockerfile .
-```
-
-## Environment Variables
-
-- `GITLAB_PERSONAL_ACCESS_TOKEN`: Your GitLab personal access token (required)
-- `GITLAB_API_URL`: Base URL for GitLab API (optional, defaults to `https://gitlab.com/api/v4`)
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/gitlab/index.ts b/src/gitlab/index.ts
deleted file mode 100644
index 3c96461c..00000000
--- a/src/gitlab/index.ts
+++ /dev/null
@@ -1,534 +0,0 @@
-#!/usr/bin/env node
-
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListToolsRequestSchema,
-} from "@modelcontextprotocol/sdk/types.js";
-import fetch from "node-fetch";
-import { z } from 'zod';
-import { zodToJsonSchema } from 'zod-to-json-schema';
-import {
- GitLabForkSchema,
- GitLabReferenceSchema,
- GitLabRepositorySchema,
- GitLabIssueSchema,
- GitLabMergeRequestSchema,
- GitLabContentSchema,
- GitLabCreateUpdateFileResponseSchema,
- GitLabSearchResponseSchema,
- GitLabTreeSchema,
- GitLabCommitSchema,
- CreateRepositoryOptionsSchema,
- CreateIssueOptionsSchema,
- CreateMergeRequestOptionsSchema,
- CreateBranchOptionsSchema,
- CreateOrUpdateFileSchema,
- SearchRepositoriesSchema,
- CreateRepositorySchema,
- GetFileContentsSchema,
- PushFilesSchema,
- CreateIssueSchema,
- CreateMergeRequestSchema,
- ForkRepositorySchema,
- CreateBranchSchema,
- type GitLabFork,
- type GitLabReference,
- type GitLabRepository,
- type GitLabIssue,
- type GitLabMergeRequest,
- type GitLabContent,
- type GitLabCreateUpdateFileResponse,
- type GitLabSearchResponse,
- type GitLabTree,
- type GitLabCommit,
- type FileOperation,
-} from './schemas.js';
-
-const server = new Server({
- name: "gitlab-mcp-server",
- version: "0.5.1",
-}, {
- capabilities: {
- tools: {}
- }
-});
-
-const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
-const GITLAB_API_URL = process.env.GITLAB_API_URL || 'https://gitlab.com/api/v4';
-
-if (!GITLAB_PERSONAL_ACCESS_TOKEN) {
- console.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
- process.exit(1);
-}
-
-async function forkProject(
- projectId: string,
- namespace?: string
-): Promise {
- const url = `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/fork`;
- const queryParams = namespace ? `?namespace=${encodeURIComponent(namespace)}` : '';
-
- const response = await fetch(url + queryParams, {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- }
- });
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabForkSchema.parse(await response.json());
-}
-
-async function createBranch(
- projectId: string,
- options: z.infer
-): Promise {
- const response = await fetch(
- `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/branches`,
- {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- branch: options.name,
- ref: options.ref
- })
- }
- );
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabReferenceSchema.parse(await response.json());
-}
-
-async function getDefaultBranchRef(projectId: string): Promise {
- const response = await fetch(
- `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`,
- {
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`
- }
- }
- );
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- const project = GitLabRepositorySchema.parse(await response.json());
- return project.default_branch;
-}
-
-async function getFileContents(
- projectId: string,
- filePath: string,
- ref?: string
-): Promise {
- const encodedPath = encodeURIComponent(filePath);
- let url = `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`;
- if (ref) {
- url += `?ref=${encodeURIComponent(ref)}`;
- }
-
- const response = await fetch(url, {
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`
- }
- });
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- const data = GitLabContentSchema.parse(await response.json());
-
- if (!Array.isArray(data) && data.content) {
- data.content = Buffer.from(data.content, 'base64').toString('utf8');
- }
-
- return data;
-}
-
-async function createIssue(
- projectId: string,
- options: z.infer
-): Promise {
- const response = await fetch(
- `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`,
- {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- title: options.title,
- description: options.description,
- assignee_ids: options.assignee_ids,
- milestone_id: options.milestone_id,
- labels: options.labels?.join(',')
- })
- }
- );
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabIssueSchema.parse(await response.json());
-}
-
-async function createMergeRequest(
- projectId: string,
- options: z.infer
-): Promise {
- const response = await fetch(
- `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`,
- {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- title: options.title,
- description: options.description,
- source_branch: options.source_branch,
- target_branch: options.target_branch,
- allow_collaboration: options.allow_collaboration,
- draft: options.draft
- })
- }
- );
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabMergeRequestSchema.parse(await response.json());
-}
-
-async function createOrUpdateFile(
- projectId: string,
- filePath: string,
- content: string,
- commitMessage: string,
- branch: string,
- previousPath?: string
-): Promise {
- const encodedPath = encodeURIComponent(filePath);
- const url = `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`;
-
- const body = {
- branch,
- content,
- commit_message: commitMessage,
- ...(previousPath ? { previous_path: previousPath } : {})
- };
-
- // Check if file exists
- let method = "POST";
- try {
- await getFileContents(projectId, filePath, branch);
- method = "PUT";
- } catch (error) {
- // File doesn't exist, use POST
- }
-
- const response = await fetch(url, {
- method,
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- },
- body: JSON.stringify(body)
- });
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabCreateUpdateFileResponseSchema.parse(await response.json());
-}
-
-async function createTree(
- projectId: string,
- files: FileOperation[],
- ref?: string
-): Promise {
- const response = await fetch(
- `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/tree`,
- {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- files: files.map(file => ({
- file_path: file.path,
- content: file.content
- })),
- ...(ref ? { ref } : {})
- })
- }
- );
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabTreeSchema.parse(await response.json());
-}
-
-async function createCommit(
- projectId: string,
- message: string,
- branch: string,
- actions: FileOperation[]
-): Promise {
- const response = await fetch(
- `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits`,
- {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- branch,
- commit_message: message,
- actions: actions.map(action => ({
- action: "create",
- file_path: action.path,
- content: action.content
- }))
- })
- }
- );
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabCommitSchema.parse(await response.json());
-}
-
-async function searchProjects(
- query: string,
- page: number = 1,
- perPage: number = 20
-): Promise {
- const url = new URL(`${GITLAB_API_URL}/projects`);
- url.searchParams.append("search", query);
- url.searchParams.append("page", page.toString());
- url.searchParams.append("per_page", perPage.toString());
-
- const response = await fetch(url.toString(), {
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`
- }
- });
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- const projects = await response.json();
- return GitLabSearchResponseSchema.parse({
- count: parseInt(response.headers.get("X-Total") || "0"),
- items: projects
- });
-}
-
-async function createRepository(
- options: z.infer
-): Promise {
- const response = await fetch(`${GITLAB_API_URL}/projects`, {
- method: "POST",
- headers: {
- "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- name: options.name,
- description: options.description,
- visibility: options.visibility,
- initialize_with_readme: options.initialize_with_readme
- })
- });
-
- if (!response.ok) {
- throw new Error(`GitLab API error: ${response.statusText}`);
- }
-
- return GitLabRepositorySchema.parse(await response.json());
-}
-
-server.setRequestHandler(ListToolsRequestSchema, async () => {
- return {
- tools: [
- {
- name: "create_or_update_file",
- description: "Create or update a single file in a GitLab project",
- inputSchema: zodToJsonSchema(CreateOrUpdateFileSchema)
- },
- {
- name: "search_repositories",
- description: "Search for GitLab projects",
- inputSchema: zodToJsonSchema(SearchRepositoriesSchema)
- },
- {
- name: "create_repository",
- description: "Create a new GitLab project",
- inputSchema: zodToJsonSchema(CreateRepositorySchema)
- },
- {
- name: "get_file_contents",
- description: "Get the contents of a file or directory from a GitLab project",
- inputSchema: zodToJsonSchema(GetFileContentsSchema)
- },
- {
- name: "push_files",
- description: "Push multiple files to a GitLab project in a single commit",
- inputSchema: zodToJsonSchema(PushFilesSchema)
- },
- {
- name: "create_issue",
- description: "Create a new issue in a GitLab project",
- inputSchema: zodToJsonSchema(CreateIssueSchema)
- },
- {
- name: "create_merge_request",
- description: "Create a new merge request in a GitLab project",
- inputSchema: zodToJsonSchema(CreateMergeRequestSchema)
- },
- {
- name: "fork_repository",
- description: "Fork a GitLab project to your account or specified namespace",
- inputSchema: zodToJsonSchema(ForkRepositorySchema)
- },
- {
- name: "create_branch",
- description: "Create a new branch in a GitLab project",
- inputSchema: zodToJsonSchema(CreateBranchSchema)
- }
- ]
- };
-});
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- try {
- if (!request.params.arguments) {
- throw new Error("Arguments are required");
- }
-
- switch (request.params.name) {
- case "fork_repository": {
- const args = ForkRepositorySchema.parse(request.params.arguments);
- const fork = await forkProject(args.project_id, args.namespace);
- return { content: [{ type: "text", text: JSON.stringify(fork, null, 2) }] };
- }
-
- case "create_branch": {
- const args = CreateBranchSchema.parse(request.params.arguments);
- let ref = args.ref;
- if (!ref) {
- ref = await getDefaultBranchRef(args.project_id);
- }
-
- const branch = await createBranch(args.project_id, {
- name: args.branch,
- ref
- });
-
- return { content: [{ type: "text", text: JSON.stringify(branch, null, 2) }] };
- }
-
- case "search_repositories": {
- const args = SearchRepositoriesSchema.parse(request.params.arguments);
- const results = await searchProjects(args.search, args.page, args.per_page);
- return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
- }
-
- case "create_repository": {
- const args = CreateRepositorySchema.parse(request.params.arguments);
- const repository = await createRepository(args);
- return { content: [{ type: "text", text: JSON.stringify(repository, null, 2) }] };
- }
-
- case "get_file_contents": {
- const args = GetFileContentsSchema.parse(request.params.arguments);
- const contents = await getFileContents(args.project_id, args.file_path, args.ref);
- return { content: [{ type: "text", text: JSON.stringify(contents, null, 2) }] };
- }
-
- case "create_or_update_file": {
- const args = CreateOrUpdateFileSchema.parse(request.params.arguments);
- const result = await createOrUpdateFile(
- args.project_id,
- args.file_path,
- args.content,
- args.commit_message,
- args.branch,
- args.previous_path
- );
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
- }
-
- case "push_files": {
- const args = PushFilesSchema.parse(request.params.arguments);
- const result = await createCommit(
- args.project_id,
- args.commit_message,
- args.branch,
- args.files.map(f => ({ path: f.file_path, content: f.content }))
- );
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
- }
-
- case "create_issue": {
- const args = CreateIssueSchema.parse(request.params.arguments);
- const { project_id, ...options } = args;
- const issue = await createIssue(project_id, options);
- return { content: [{ type: "text", text: JSON.stringify(issue, null, 2) }] };
- }
-
- case "create_merge_request": {
- const args = CreateMergeRequestSchema.parse(request.params.arguments);
- const { project_id, ...options } = args;
- const mergeRequest = await createMergeRequest(project_id, options);
- return { content: [{ type: "text", text: JSON.stringify(mergeRequest, null, 2) }] };
- }
-
- default:
- throw new Error(`Unknown tool: ${request.params.name}`);
- }
- } catch (error) {
- if (error instanceof z.ZodError) {
- throw new Error(`Invalid arguments: ${error.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', ')}`);
- }
- throw error;
- }
-});
-
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
- console.error("GitLab MCP Server running on stdio");
-}
-
-runServer().catch((error) => {
- console.error("Fatal error in main():", error);
- process.exit(1);
-});
\ No newline at end of file
diff --git a/src/gitlab/package.json b/src/gitlab/package.json
deleted file mode 100644
index 1259e241..00000000
--- a/src/gitlab/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-gitlab",
- "version": "0.6.2",
- "description": "MCP server for using the GitLab API",
- "license": "MIT",
- "author": "GitLab, PBC (https://gitlab.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-gitlab": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1",
- "@types/node-fetch": "^2.6.12",
- "node-fetch": "^3.3.2",
- "zod-to-json-schema": "^3.23.5"
- },
- "devDependencies": {
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/gitlab/schemas.ts b/src/gitlab/schemas.ts
deleted file mode 100644
index af93380d..00000000
--- a/src/gitlab/schemas.ts
+++ /dev/null
@@ -1,325 +0,0 @@
-import { z } from 'zod';
-
-// Base schemas for common types
-export const GitLabAuthorSchema = z.object({
- name: z.string(),
- email: z.string(),
- date: z.string()
-});
-
-// Repository related schemas
-export const GitLabOwnerSchema = z.object({
- username: z.string(), // Changed from login to match GitLab API
- id: z.number(),
- avatar_url: z.string(),
- web_url: z.string(), // Changed from html_url to match GitLab API
- name: z.string(), // Added as GitLab includes full name
- state: z.string() // Added as GitLab includes user state
-});
-
-export const GitLabRepositorySchema = z.object({
- id: z.number(),
- name: z.string(),
- path_with_namespace: z.string(), // Changed from full_name to match GitLab API
- visibility: z.string(), // Changed from private to match GitLab API
- owner: GitLabOwnerSchema.optional(),
- web_url: z.string(), // Changed from html_url to match GitLab API
- description: z.string().nullable(),
- fork: z.boolean().optional(),
- ssh_url_to_repo: z.string(), // Changed from ssh_url to match GitLab API
- http_url_to_repo: z.string(), // Changed from clone_url to match GitLab API
- created_at: z.string(),
- last_activity_at: z.string(), // Changed from updated_at to match GitLab API
- default_branch: z.string()
-});
-
-// File content schemas
-export const GitLabFileContentSchema = z.object({
- file_name: z.string(), // Changed from name to match GitLab API
- file_path: z.string(), // Changed from path to match GitLab API
- size: z.number(),
- encoding: z.string(),
- content: z.string(),
- content_sha256: z.string(), // Changed from sha to match GitLab API
- ref: z.string(), // Added as GitLab requires branch reference
- blob_id: z.string(), // Added to match GitLab API
- last_commit_id: z.string() // Added to match GitLab API
-});
-
-export const GitLabDirectoryContentSchema = z.object({
- name: z.string(),
- path: z.string(),
- type: z.string(),
- mode: z.string(),
- id: z.string(), // Changed from sha to match GitLab API
- web_url: z.string() // Changed from html_url to match GitLab API
-});
-
-export const GitLabContentSchema = z.union([
- GitLabFileContentSchema,
- z.array(GitLabDirectoryContentSchema)
-]);
-
-// Operation schemas
-export const FileOperationSchema = z.object({
- path: z.string(),
- content: z.string()
-});
-
-// Tree and commit schemas
-export const GitLabTreeEntrySchema = z.object({
- id: z.string(), // Changed from sha to match GitLab API
- name: z.string(),
- type: z.enum(['blob', 'tree']),
- path: z.string(),
- mode: z.string()
-});
-
-export const GitLabTreeSchema = z.object({
- id: z.string(), // Changed from sha to match GitLab API
- tree: z.array(GitLabTreeEntrySchema)
-});
-
-export const GitLabCommitSchema = z.object({
- id: z.string(), // Changed from sha to match GitLab API
- short_id: z.string(), // Added to match GitLab API
- title: z.string(), // Changed from message to match GitLab API
- author_name: z.string(),
- author_email: z.string(),
- authored_date: z.string(),
- committer_name: z.string(),
- committer_email: z.string(),
- committed_date: z.string(),
- web_url: z.string(), // Changed from html_url to match GitLab API
- parent_ids: z.array(z.string()) // Changed from parents to match GitLab API
-});
-
-// Reference schema
-export const GitLabReferenceSchema = z.object({
- name: z.string(), // Changed from ref to match GitLab API
- commit: z.object({
- id: z.string(), // Changed from sha to match GitLab API
- web_url: z.string() // Changed from url to match GitLab API
- })
-});
-
-// Input schemas for operations
-export const CreateRepositoryOptionsSchema = z.object({
- name: z.string(),
- description: z.string().optional(),
- visibility: z.enum(['private', 'internal', 'public']).optional(), // Changed from private to match GitLab API
- initialize_with_readme: z.boolean().optional() // Changed from auto_init to match GitLab API
-});
-
-export const CreateIssueOptionsSchema = z.object({
- title: z.string(),
- description: z.string().optional(), // Changed from body to match GitLab API
- assignee_ids: z.array(z.number()).optional(), // Changed from assignees to match GitLab API
- milestone_id: z.number().optional(), // Changed from milestone to match GitLab API
- labels: z.array(z.string()).optional()
-});
-
-export const CreateMergeRequestOptionsSchema = z.object({ // Changed from CreatePullRequestOptionsSchema
- title: z.string(),
- description: z.string().optional(), // Changed from body to match GitLab API
- source_branch: z.string(), // Changed from head to match GitLab API
- target_branch: z.string(), // Changed from base to match GitLab API
- allow_collaboration: z.boolean().optional(), // Changed from maintainer_can_modify to match GitLab API
- draft: z.boolean().optional()
-});
-
-export const CreateBranchOptionsSchema = z.object({
- name: z.string(), // Changed from ref to match GitLab API
- ref: z.string() // The source branch/commit for the new branch
-});
-
-// Response schemas for operations
-export const GitLabCreateUpdateFileResponseSchema = z.object({
- file_path: z.string(),
- branch: z.string(),
- commit_id: z.string(), // Changed from sha to match GitLab API
- content: GitLabFileContentSchema.optional()
-});
-
-export const GitLabSearchResponseSchema = z.object({
- count: z.number(), // Changed from total_count to match GitLab API
- items: z.array(GitLabRepositorySchema)
-});
-
-// Fork related schemas
-export const GitLabForkParentSchema = z.object({
- name: z.string(),
- path_with_namespace: z.string(), // Changed from full_name to match GitLab API
- owner: z.object({
- username: z.string(), // Changed from login to match GitLab API
- id: z.number(),
- avatar_url: z.string()
- }),
- web_url: z.string() // Changed from html_url to match GitLab API
-});
-
-export const GitLabForkSchema = GitLabRepositorySchema.extend({
- forked_from_project: GitLabForkParentSchema // Changed from parent to match GitLab API
-});
-
-// Issue related schemas
-export const GitLabLabelSchema = z.object({
- id: z.number(),
- name: z.string(),
- color: z.string(),
- description: z.string().optional()
-});
-
-export const GitLabUserSchema = z.object({
- username: z.string(), // Changed from login to match GitLab API
- id: z.number(),
- name: z.string(),
- avatar_url: z.string(),
- web_url: z.string() // Changed from html_url to match GitLab API
-});
-
-export const GitLabMilestoneSchema = z.object({
- id: z.number(),
- iid: z.number(), // Added to match GitLab API
- title: z.string(),
- description: z.string(),
- state: z.string(),
- web_url: z.string() // Changed from html_url to match GitLab API
-});
-
-export const GitLabIssueSchema = z.object({
- id: z.number(),
- iid: z.number(), // Added to match GitLab API
- project_id: z.number(), // Added to match GitLab API
- title: z.string(),
- description: z.string(), // Changed from body to match GitLab API
- state: z.string(),
- author: GitLabUserSchema,
- assignees: z.array(GitLabUserSchema),
- labels: z.array(GitLabLabelSchema),
- milestone: GitLabMilestoneSchema.nullable(),
- created_at: z.string(),
- updated_at: z.string(),
- closed_at: z.string().nullable(),
- web_url: z.string() // Changed from html_url to match GitLab API
-});
-
-// Merge Request related schemas (equivalent to Pull Request)
-export const GitLabMergeRequestDiffRefSchema = z.object({
- base_sha: z.string(),
- head_sha: z.string(),
- start_sha: z.string()
-});
-
-export const GitLabMergeRequestSchema = z.object({
- id: z.number(),
- iid: z.number(), // Added to match GitLab API
- project_id: z.number(), // Added to match GitLab API
- title: z.string(),
- description: z.string(), // Changed from body to match GitLab API
- state: z.string(),
- merged: z.boolean().optional(),
- author: GitLabUserSchema,
- assignees: z.array(GitLabUserSchema),
- source_branch: z.string(), // Changed from head to match GitLab API
- target_branch: z.string(), // Changed from base to match GitLab API
- diff_refs: GitLabMergeRequestDiffRefSchema.nullable(),
- web_url: z.string(), // Changed from html_url to match GitLab API
- created_at: z.string(),
- updated_at: z.string(),
- merged_at: z.string().nullable(),
- closed_at: z.string().nullable(),
- merge_commit_sha: z.string().nullable()
-});
-
-// API Operation Parameter Schemas
-const ProjectParamsSchema = z.object({
- project_id: z.string().describe("Project ID or URL-encoded path") // Changed from owner/repo to match GitLab API
-});
-
-export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
- file_path: z.string().describe("Path where to create/update the file"),
- content: z.string().describe("Content of the file"),
- commit_message: z.string().describe("Commit message"),
- branch: z.string().describe("Branch to create/update the file in"),
- previous_path: z.string().optional()
- .describe("Path of the file to move/rename")
-});
-
-export const SearchRepositoriesSchema = z.object({
- search: z.string().describe("Search query"), // Changed from query to match GitLab API
- page: z.number().optional().describe("Page number for pagination (default: 1)"),
- per_page: z.number().optional().describe("Number of results per page (default: 20)")
-});
-
-export const CreateRepositorySchema = z.object({
- name: z.string().describe("Repository name"),
- description: z.string().optional().describe("Repository description"),
- visibility: z.enum(['private', 'internal', 'public']).optional()
- .describe("Repository visibility level"),
- initialize_with_readme: z.boolean().optional()
- .describe("Initialize with README.md")
-});
-
-export const GetFileContentsSchema = ProjectParamsSchema.extend({
- file_path: z.string().describe("Path to the file or directory"),
- ref: z.string().optional().describe("Branch/tag/commit to get contents from")
-});
-
-export const PushFilesSchema = ProjectParamsSchema.extend({
- branch: z.string().describe("Branch to push to"),
- files: z.array(z.object({
- file_path: z.string().describe("Path where to create the file"),
- content: z.string().describe("Content of the file")
- })).describe("Array of files to push"),
- commit_message: z.string().describe("Commit message")
-});
-
-export const CreateIssueSchema = ProjectParamsSchema.extend({
- title: z.string().describe("Issue title"),
- description: z.string().optional().describe("Issue description"),
- assignee_ids: z.array(z.number()).optional().describe("Array of user IDs to assign"),
- labels: z.array(z.string()).optional().describe("Array of label names"),
- milestone_id: z.number().optional().describe("Milestone ID to assign")
-});
-
-export const CreateMergeRequestSchema = ProjectParamsSchema.extend({
- title: z.string().describe("Merge request title"),
- description: z.string().optional().describe("Merge request description"),
- source_branch: z.string().describe("Branch containing changes"),
- target_branch: z.string().describe("Branch to merge into"),
- draft: z.boolean().optional().describe("Create as draft merge request"),
- allow_collaboration: z.boolean().optional()
- .describe("Allow commits from upstream members")
-});
-
-export const ForkRepositorySchema = ProjectParamsSchema.extend({
- namespace: z.string().optional()
- .describe("Namespace to fork to (full path)")
-});
-
-export const CreateBranchSchema = ProjectParamsSchema.extend({
- branch: z.string().describe("Name for the new branch"),
- ref: z.string().optional()
- .describe("Source branch/commit for new branch")
-});
-
-// Export types
-export type GitLabAuthor = z.infer;
-export type GitLabFork = z.infer;
-export type GitLabIssue = z.infer;
-export type GitLabMergeRequest = z.infer;
-export type GitLabRepository = z.infer;
-export type GitLabFileContent = z.infer;
-export type GitLabDirectoryContent = z.infer;
-export type GitLabContent = z.infer;
-export type FileOperation = z.infer;
-export type GitLabTree = z.infer;
-export type GitLabCommit = z.infer;
-export type GitLabReference = z.infer;
-export type CreateRepositoryOptions = z.infer;
-export type CreateIssueOptions = z.infer;
-export type CreateMergeRequestOptions = z.infer;
-export type CreateBranchOptions = z.infer;
-export type GitLabCreateUpdateFileResponse = z.infer;
-export type GitLabSearchResponse = z.infer;
\ No newline at end of file
diff --git a/src/gitlab/tsconfig.json b/src/gitlab/tsconfig.json
deleted file mode 100644
index 4d33cae1..00000000
--- a/src/gitlab/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
- }
-
\ No newline at end of file
diff --git a/src/google-maps/Dockerfile b/src/google-maps/Dockerfile
deleted file mode 100644
index 3808d7fc..00000000
--- a/src/google-maps/Dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-# Must be entire project because `prepare` script is run during `npm install` and requires all files.
-COPY src/google-maps /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
-
-FROM node:22-alpine AS release
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-WORKDIR /app
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/google-maps/README.md b/src/google-maps/README.md
deleted file mode 100644
index b91a0657..00000000
--- a/src/google-maps/README.md
+++ /dev/null
@@ -1,114 +0,0 @@
-# Google Maps MCP Server
-
-MCP Server for the Google Maps API.
-
-## Tools
-
-1. `maps_geocode`
- - Convert address to coordinates
- - Input: `address` (string)
- - Returns: location, formatted_address, place_id
-
-2. `maps_reverse_geocode`
- - Convert coordinates to address
- - Inputs:
- - `latitude` (number)
- - `longitude` (number)
- - Returns: formatted_address, place_id, address_components
-
-3. `maps_search_places`
- - Search for places using text query
- - Inputs:
- - `query` (string)
- - `location` (optional): { latitude: number, longitude: number }
- - `radius` (optional): number (meters, max 50000)
- - Returns: array of places with names, addresses, locations
-
-4. `maps_place_details`
- - Get detailed information about a place
- - Input: `place_id` (string)
- - Returns: name, address, contact info, ratings, reviews, opening hours
-
-5. `maps_distance_matrix`
- - Calculate distances and times between points
- - Inputs:
- - `origins` (string[])
- - `destinations` (string[])
- - `mode` (optional): "driving" | "walking" | "bicycling" | "transit"
- - Returns: distances and durations matrix
-
-6. `maps_elevation`
- - Get elevation data for locations
- - Input: `locations` (array of {latitude, longitude})
- - Returns: elevation data for each point
-
-7. `maps_directions`
- - Get directions between points
- - Inputs:
- - `origin` (string)
- - `destination` (string)
- - `mode` (optional): "driving" | "walking" | "bicycling" | "transit"
- - Returns: route details with steps, distance, duration
-
-## Setup
-
-### API Key
-Get a Google Maps API key by following the instructions [here](https://developers.google.com/maps/documentation/javascript/get-api-key#create-api-keys).
-
-### Usage with Claude Desktop
-
-Add the following to your `claude_desktop_config.json`:
-
-#### Docker
-
-```json
-{
- "mcpServers": {
- "google-maps": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "-e",
- "GOOGLE_MAPS_API_KEY",
- "mcp/google-maps"
- ],
- "env": {
- "GOOGLE_MAPS_API_KEY": ""
- }
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "google-maps": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-google-maps"
- ],
- "env": {
- "GOOGLE_MAPS_API_KEY": ""
- }
- }
- }
-}
-```
-
-## Build
-
-Docker build:
-
-```bash
-docker build -t mcp/google-maps -f src/google-maps/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/google-maps/index.ts b/src/google-maps/index.ts
deleted file mode 100644
index 00bf6eaa..00000000
--- a/src/google-maps/index.ts
+++ /dev/null
@@ -1,678 +0,0 @@
-#!/usr/bin/env node
-
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListToolsRequestSchema,
- Tool,
-} from "@modelcontextprotocol/sdk/types.js";
-import fetch from "node-fetch";
-
-// Response interfaces
-interface GoogleMapsResponse {
- status: string;
- error_message?: string;
-}
-
-interface GeocodeResponse extends GoogleMapsResponse {
- results: Array<{
- place_id: string;
- formatted_address: string;
- geometry: {
- location: {
- lat: number;
- lng: number;
- }
- };
- address_components: Array<{
- long_name: string;
- short_name: string;
- types: string[];
- }>;
- }>;
-}
-
-interface PlacesSearchResponse extends GoogleMapsResponse {
- results: Array<{
- name: string;
- place_id: string;
- formatted_address: string;
- geometry: {
- location: {
- lat: number;
- lng: number;
- }
- };
- rating?: number;
- types: string[];
- }>;
-}
-
-interface PlaceDetailsResponse extends GoogleMapsResponse {
- result: {
- name: string;
- place_id: string;
- formatted_address: string;
- formatted_phone_number?: string;
- website?: string;
- rating?: number;
- reviews?: Array<{
- author_name: string;
- rating: number;
- text: string;
- time: number;
- }>;
- opening_hours?: {
- weekday_text: string[];
- open_now: boolean;
- };
- geometry: {
- location: {
- lat: number;
- lng: number;
- }
- };
- };
-}
-
-interface DistanceMatrixResponse extends GoogleMapsResponse {
- origin_addresses: string[];
- destination_addresses: string[];
- rows: Array<{
- elements: Array<{
- status: string;
- duration: {
- text: string;
- value: number;
- };
- distance: {
- text: string;
- value: number;
- };
- }>;
- }>;
-}
-
-interface ElevationResponse extends GoogleMapsResponse {
- results: Array<{
- elevation: number;
- location: {
- lat: number;
- lng: number;
- };
- resolution: number;
- }>;
-}
-
-interface DirectionsResponse extends GoogleMapsResponse {
- routes: Array<{
- summary: string;
- legs: Array<{
- distance: {
- text: string;
- value: number;
- };
- duration: {
- text: string;
- value: number;
- };
- steps: Array<{
- html_instructions: string;
- distance: {
- text: string;
- value: number;
- };
- duration: {
- text: string;
- value: number;
- };
- travel_mode: string;
- }>;
- }>;
- }>;
-}
-
-function getApiKey(): string {
- const apiKey = process.env.GOOGLE_MAPS_API_KEY;
- if (!apiKey) {
- console.error("GOOGLE_MAPS_API_KEY environment variable is not set");
- process.exit(1);
- }
- return apiKey;
- }
-
-const GOOGLE_MAPS_API_KEY = getApiKey();
-
-// Tool definitions
-const GEOCODE_TOOL: Tool = {
- name: "maps_geocode",
- description: "Convert an address into geographic coordinates",
- inputSchema: {
- type: "object",
- properties: {
- address: {
- type: "string",
- description: "The address to geocode"
- }
- },
- required: ["address"]
- }
- };
-
-const REVERSE_GEOCODE_TOOL: Tool = {
- name: "maps_reverse_geocode",
- description: "Convert coordinates into an address",
- inputSchema: {
- type: "object",
- properties: {
- latitude: {
- type: "number",
- description: "Latitude coordinate"
- },
- longitude: {
- type: "number",
- description: "Longitude coordinate"
- }
- },
- required: ["latitude", "longitude"]
- }
-};
-
-const SEARCH_PLACES_TOOL: Tool = {
- name: "maps_search_places",
- description: "Search for places using Google Places API",
- inputSchema: {
- type: "object",
- properties: {
- query: {
- type: "string",
- description: "Search query"
- },
- location: {
- type: "object",
- properties: {
- latitude: { type: "number" },
- longitude: { type: "number" }
- },
- description: "Optional center point for the search"
- },
- radius: {
- type: "number",
- description: "Search radius in meters (max 50000)"
- }
- },
- required: ["query"]
- }
-};
-
-const PLACE_DETAILS_TOOL: Tool = {
- name: "maps_place_details",
- description: "Get detailed information about a specific place",
- inputSchema: {
- type: "object",
- properties: {
- place_id: {
- type: "string",
- description: "The place ID to get details for"
- }
- },
- required: ["place_id"]
- }
-};
-
-const DISTANCE_MATRIX_TOOL: Tool = {
- name: "maps_distance_matrix",
- description: "Calculate travel distance and time for multiple origins and destinations",
- inputSchema: {
- type: "object",
- properties: {
- origins: {
- type: "array",
- items: { type: "string" },
- description: "Array of origin addresses or coordinates"
- },
- destinations: {
- type: "array",
- items: { type: "string" },
- description: "Array of destination addresses or coordinates"
- },
- mode: {
- type: "string",
- description: "Travel mode (driving, walking, bicycling, transit)",
- enum: ["driving", "walking", "bicycling", "transit"]
- }
- },
- required: ["origins", "destinations"]
- }
-};
-
-const ELEVATION_TOOL: Tool = {
- name: "maps_elevation",
- description: "Get elevation data for locations on the earth",
- inputSchema: {
- type: "object",
- properties: {
- locations: {
- type: "array",
- items: {
- type: "object",
- properties: {
- latitude: { type: "number" },
- longitude: { type: "number" }
- },
- required: ["latitude", "longitude"]
- },
- description: "Array of locations to get elevation for"
- }
- },
- required: ["locations"]
- }
-};
-
-const DIRECTIONS_TOOL: Tool = {
- name: "maps_directions",
- description: "Get directions between two points",
- inputSchema: {
- type: "object",
- properties: {
- origin: {
- type: "string",
- description: "Starting point address or coordinates"
- },
- destination: {
- type: "string",
- description: "Ending point address or coordinates"
- },
- mode: {
- type: "string",
- description: "Travel mode (driving, walking, bicycling, transit)",
- enum: ["driving", "walking", "bicycling", "transit"]
- }
- },
- required: ["origin", "destination"]
- }
-};
-
-const MAPS_TOOLS = [
- GEOCODE_TOOL,
- REVERSE_GEOCODE_TOOL,
- SEARCH_PLACES_TOOL,
- PLACE_DETAILS_TOOL,
- DISTANCE_MATRIX_TOOL,
- ELEVATION_TOOL,
- DIRECTIONS_TOOL,
-] as const;
-
-// API handlers
-async function handleGeocode(address: string) {
- const url = new URL("https://maps.googleapis.com/maps/api/geocode/json");
- url.searchParams.append("address", address);
- url.searchParams.append("key", GOOGLE_MAPS_API_KEY);
-
- const response = await fetch(url.toString());
- const data = await response.json() as GeocodeResponse;
-
- if (data.status !== "OK") {
- return {
- content: [{
- type: "text",
- text: `Geocoding failed: ${data.error_message || data.status}`
- }],
- isError: true
- };
- }
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- location: data.results[0].geometry.location,
- formatted_address: data.results[0].formatted_address,
- place_id: data.results[0].place_id
- }, null, 2)
- }],
- isError: false
- };
-}
-
-async function handleReverseGeocode(latitude: number, longitude: number) {
- const url = new URL("https://maps.googleapis.com/maps/api/geocode/json");
- url.searchParams.append("latlng", `${latitude},${longitude}`);
- url.searchParams.append("key", GOOGLE_MAPS_API_KEY);
-
- const response = await fetch(url.toString());
- const data = await response.json() as GeocodeResponse;
-
- if (data.status !== "OK") {
- return {
- content: [{
- type: "text",
- text: `Reverse geocoding failed: ${data.error_message || data.status}`
- }],
- isError: true
- };
- }
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- formatted_address: data.results[0].formatted_address,
- place_id: data.results[0].place_id,
- address_components: data.results[0].address_components
- }, null, 2)
- }],
- isError: false
- };
-}
-
-async function handlePlaceSearch(
- query: string,
- location?: { latitude: number; longitude: number },
- radius?: number
-) {
- const url = new URL("https://maps.googleapis.com/maps/api/place/textsearch/json");
- url.searchParams.append("query", query);
- url.searchParams.append("key", GOOGLE_MAPS_API_KEY);
-
- if (location) {
- url.searchParams.append("location", `${location.latitude},${location.longitude}`);
- }
- if (radius) {
- url.searchParams.append("radius", radius.toString());
- }
-
- const response = await fetch(url.toString());
- const data = await response.json() as PlacesSearchResponse;
-
- if (data.status !== "OK") {
- return {
- content: [{
- type: "text",
- text: `Place search failed: ${data.error_message || data.status}`
- }],
- isError: true
- };
- }
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- places: data.results.map((place) => ({
- name: place.name,
- formatted_address: place.formatted_address,
- location: place.geometry.location,
- place_id: place.place_id,
- rating: place.rating,
- types: place.types
- }))
- }, null, 2)
- }],
- isError: false
- };
-}
-
-async function handlePlaceDetails(place_id: string) {
- const url = new URL("https://maps.googleapis.com/maps/api/place/details/json");
- url.searchParams.append("place_id", place_id);
- url.searchParams.append("key", GOOGLE_MAPS_API_KEY);
-
- const response = await fetch(url.toString());
- const data = await response.json() as PlaceDetailsResponse;
-
- if (data.status !== "OK") {
- return {
- content: [{
- type: "text",
- text: `Place details request failed: ${data.error_message || data.status}`
- }],
- isError: true
- };
- }
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- name: data.result.name,
- formatted_address: data.result.formatted_address,
- location: data.result.geometry.location,
- formatted_phone_number: data.result.formatted_phone_number,
- website: data.result.website,
- rating: data.result.rating,
- reviews: data.result.reviews,
- opening_hours: data.result.opening_hours
- }, null, 2)
- }],
- isError: false
- };
-}
-async function handleDistanceMatrix(
- origins: string[],
- destinations: string[],
- mode: "driving" | "walking" | "bicycling" | "transit" = "driving"
-) {
- const url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json");
- url.searchParams.append("origins", origins.join("|"));
- url.searchParams.append("destinations", destinations.join("|"));
- url.searchParams.append("mode", mode);
- url.searchParams.append("key", GOOGLE_MAPS_API_KEY);
-
- const response = await fetch(url.toString());
- const data = await response.json() as DistanceMatrixResponse;
-
- if (data.status !== "OK") {
- return {
- content: [{
- type: "text",
- text: `Distance matrix request failed: ${data.error_message || data.status}`
- }],
- isError: true
- };
- }
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- origin_addresses: data.origin_addresses,
- destination_addresses: data.destination_addresses,
- results: data.rows.map((row) => ({
- elements: row.elements.map((element) => ({
- status: element.status,
- duration: element.duration,
- distance: element.distance
- }))
- }))
- }, null, 2)
- }],
- isError: false
- };
-}
-
-async function handleElevation(locations: Array<{ latitude: number; longitude: number }>) {
- const url = new URL("https://maps.googleapis.com/maps/api/elevation/json");
- const locationString = locations
- .map((loc) => `${loc.latitude},${loc.longitude}`)
- .join("|");
- url.searchParams.append("locations", locationString);
- url.searchParams.append("key", GOOGLE_MAPS_API_KEY);
-
- const response = await fetch(url.toString());
- const data = await response.json() as ElevationResponse;
-
- if (data.status !== "OK") {
- return {
- content: [{
- type: "text",
- text: `Elevation request failed: ${data.error_message || data.status}`
- }],
- isError: true
- };
- }
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- results: data.results.map((result) => ({
- elevation: result.elevation,
- location: result.location,
- resolution: result.resolution
- }))
- }, null, 2)
- }],
- isError: false
- };
-}
-
-async function handleDirections(
- origin: string,
- destination: string,
- mode: "driving" | "walking" | "bicycling" | "transit" = "driving"
-) {
- const url = new URL("https://maps.googleapis.com/maps/api/directions/json");
- url.searchParams.append("origin", origin);
- url.searchParams.append("destination", destination);
- url.searchParams.append("mode", mode);
- url.searchParams.append("key", GOOGLE_MAPS_API_KEY);
-
- const response = await fetch(url.toString());
- const data = await response.json() as DirectionsResponse;
-
- if (data.status !== "OK") {
- return {
- content: [{
- type: "text",
- text: `Directions request failed: ${data.error_message || data.status}`
- }],
- isError: true
- };
- }
-
- return {
- content: [{
- type: "text",
- text: JSON.stringify({
- routes: data.routes.map((route) => ({
- summary: route.summary,
- distance: route.legs[0].distance,
- duration: route.legs[0].duration,
- steps: route.legs[0].steps.map((step) => ({
- instructions: step.html_instructions,
- distance: step.distance,
- duration: step.duration,
- travel_mode: step.travel_mode
- }))
- }))
- }, null, 2)
- }],
- isError: false
- };
-}
-
-// Server setup
-const server = new Server(
- {
- name: "mcp-server/google-maps",
- version: "0.1.0",
- },
- {
- capabilities: {
- tools: {},
- },
- },
-);
-
-// Set up request handlers
-server.setRequestHandler(ListToolsRequestSchema, async () => ({
- tools: MAPS_TOOLS,
-}));
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- try {
- switch (request.params.name) {
- case "maps_geocode": {
- const { address } = request.params.arguments as { address: string };
- return await handleGeocode(address);
- }
-
- case "maps_reverse_geocode": {
- const { latitude, longitude } = request.params.arguments as {
- latitude: number;
- longitude: number;
- };
- return await handleReverseGeocode(latitude, longitude);
- }
-
- case "maps_search_places": {
- const { query, location, radius } = request.params.arguments as {
- query: string;
- location?: { latitude: number; longitude: number };
- radius?: number;
- };
- return await handlePlaceSearch(query, location, radius);
- }
-
- case "maps_place_details": {
- const { place_id } = request.params.arguments as { place_id: string };
- return await handlePlaceDetails(place_id);
- }
-
- case "maps_distance_matrix": {
- const { origins, destinations, mode } = request.params.arguments as {
- origins: string[];
- destinations: string[];
- mode?: "driving" | "walking" | "bicycling" | "transit";
- };
- return await handleDistanceMatrix(origins, destinations, mode);
- }
-
- case "maps_elevation": {
- const { locations } = request.params.arguments as {
- locations: Array<{ latitude: number; longitude: number }>;
- };
- return await handleElevation(locations);
- }
-
- case "maps_directions": {
- const { origin, destination, mode } = request.params.arguments as {
- origin: string;
- destination: string;
- mode?: "driving" | "walking" | "bicycling" | "transit";
- };
- return await handleDirections(origin, destination, mode);
- }
-
- default:
- return {
- content: [{
- type: "text",
- text: `Unknown tool: ${request.params.name}`
- }],
- isError: true
- };
- }
- } catch (error) {
- return {
- content: [{
- type: "text",
- text: `Error: ${error instanceof Error ? error.message : String(error)}`
- }],
- isError: true
- };
- }
-});
-
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
- console.error("Google Maps MCP Server running on stdio");
-}
-
-runServer().catch((error) => {
- console.error("Fatal error running server:", error);
- process.exit(1);
-});
diff --git a/src/google-maps/package.json b/src/google-maps/package.json
deleted file mode 100644
index 5e4c04c4..00000000
--- a/src/google-maps/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-google-maps",
- "version": "0.6.2",
- "description": "MCP server for using the Google Maps API",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-google-maps": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1",
- "@types/node-fetch": "^2.6.12",
- "node-fetch": "^3.3.2"
- },
- "devDependencies": {
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/google-maps/tsconfig.json b/src/google-maps/tsconfig.json
deleted file mode 100644
index ec5da158..00000000
--- a/src/google-maps/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
-}
diff --git a/src/memory/README.md b/src/memory/README.md
index e5795cb5..5b18d841 100644
--- a/src/memory/README.md
+++ b/src/memory/README.md
@@ -1,4 +1,5 @@
# Knowledge Graph Memory Server
+
A basic implementation of persistent memory using a local knowledge graph. This lets Claude remember information about the user across chats.
## Core Concepts
@@ -181,6 +182,60 @@ The server can be configured using the following environment variables:
- `MEMORY_FILE_PATH`: Path to the memory storage JSON file (default: `memory.json` in the server directory)
+# VS Code Installation Instructions
+
+For quick installation, use one of the one-click installation buttons below:
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-memory%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-memory%22%5D%7D&quality=insiders)
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22-v%22%2C%22claude-memory%3A%2Fapp%2Fdist%22%2C%22--rm%22%2C%22mcp%2Fmemory%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22-v%22%2C%22claude-memory%3A%2Fapp%2Fdist%22%2C%22--rm%22%2C%22mcp%2Fmemory%22%5D%7D&quality=insiders)
+
+For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open Settings (JSON)`.
+
+Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
+
+> Note that the `mcp` key is not needed in the `.vscode/mcp.json` file.
+
+#### NPX
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "memory": {
+ "command": "npx",
+ "args": [
+ "-y",
+ "@modelcontextprotocol/server-memory"
+ ]
+ }
+ }
+ }
+}
+```
+
+#### Docker
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "memory": {
+ "command": "docker",
+ "args": [
+ "run",
+ "-i",
+ "-v",
+ "claude-memory:/app/dist",
+ "--rm",
+ "mcp/memory"
+ ]
+ }
+ }
+ }
+}
+```
+
### System Prompt
The prompt for utilizing memory depends on the use case. Changing the prompt will help the model determine the frequency and types of memories created.
@@ -210,7 +265,7 @@ Follow these steps for each interaction:
- If any new information was gathered during the interaction, update your memory as follows:
a) Create entities for recurring organizations, people, and significant events
b) Connect them to the current entities using relations
- b) Store facts about them as observations
+ c) Store facts about them as observations
```
## Building
diff --git a/src/memory/index.ts b/src/memory/index.ts
index 62f7aeb6..b7993a3a 100644
--- a/src/memory/index.ts
+++ b/src/memory/index.ts
@@ -189,7 +189,7 @@ const knowledgeGraphManager = new KnowledgeGraphManager();
// The server instance and tools exposed to Claude
const server = new Server({
name: "memory-server",
- version: "1.0.0",
+ version: "0.6.3",
}, {
capabilities: {
tools: {},
@@ -416,4 +416,4 @@ async function main() {
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
-});
\ No newline at end of file
+});
diff --git a/src/postgres/Dockerfile b/src/postgres/Dockerfile
deleted file mode 100644
index 59ef9cac..00000000
--- a/src/postgres/Dockerfile
+++ /dev/null
@@ -1,24 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-COPY src/postgres /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
-
-FROM node:22-alpine AS release
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-WORKDIR /app
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/postgres/README.md b/src/postgres/README.md
deleted file mode 100644
index aaace581..00000000
--- a/src/postgres/README.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# PostgreSQL
-
-A Model Context Protocol server that provides read-only access to PostgreSQL databases. This server enables LLMs to inspect database schemas and execute read-only queries.
-
-## Components
-
-### Tools
-
-- **query**
- - Execute read-only SQL queries against the connected database
- - Input: `sql` (string): The SQL query to execute
- - All queries are executed within a READ ONLY transaction
-
-### Resources
-
-The server provides schema information for each table in the database:
-
-- **Table Schemas** (`postgres:////schema`)
- - JSON schema information for each table
- - Includes column names and data types
- - Automatically discovered from database metadata
-
-## Usage with Claude Desktop
-
-To use this server with the Claude Desktop app, add the following configuration to the "mcpServers" section of your `claude_desktop_config.json`:
-
-### Docker
-
-* when running docker on macos, use host.docker.internal if the server is running on the host network (eg localhost)
-* username/password can be added to the postgresql url with `postgresql://user:password@host:port/db-name`
-
-```json
-{
- "mcpServers": {
- "postgres": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "mcp/postgres",
- "postgresql://host.docker.internal:5432/mydb"]
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "postgres": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-postgres",
- "postgresql://localhost/mydb"
- ]
- }
- }
-}
-```
-
-Replace `/mydb` with your database name.
-
-## Building
-
-Docker:
-
-```sh
-docker build -t mcp/postgres -f src/postgres/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/postgres/index.ts b/src/postgres/index.ts
deleted file mode 100644
index 24fabf3e..00000000
--- a/src/postgres/index.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/usr/bin/env node
-
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListResourcesRequestSchema,
- ListToolsRequestSchema,
- ReadResourceRequestSchema,
-} from "@modelcontextprotocol/sdk/types.js";
-import pg from "pg";
-
-const server = new Server(
- {
- name: "example-servers/postgres",
- version: "0.1.0",
- },
- {
- capabilities: {
- resources: {},
- tools: {},
- },
- },
-);
-
-const args = process.argv.slice(2);
-if (args.length === 0) {
- console.error("Please provide a database URL as a command-line argument");
- process.exit(1);
-}
-
-const databaseUrl = args[0];
-
-const resourceBaseUrl = new URL(databaseUrl);
-resourceBaseUrl.protocol = "postgres:";
-resourceBaseUrl.password = "";
-
-const pool = new pg.Pool({
- connectionString: databaseUrl,
-});
-
-const SCHEMA_PATH = "schema";
-
-server.setRequestHandler(ListResourcesRequestSchema, async () => {
- const client = await pool.connect();
- try {
- const result = await client.query(
- "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'",
- );
- return {
- resources: result.rows.map((row) => ({
- uri: new URL(`${row.table_name}/${SCHEMA_PATH}`, resourceBaseUrl).href,
- mimeType: "application/json",
- name: `"${row.table_name}" database schema`,
- })),
- };
- } finally {
- client.release();
- }
-});
-
-server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
- const resourceUrl = new URL(request.params.uri);
-
- const pathComponents = resourceUrl.pathname.split("/");
- const schema = pathComponents.pop();
- const tableName = pathComponents.pop();
-
- if (schema !== SCHEMA_PATH) {
- throw new Error("Invalid resource URI");
- }
-
- const client = await pool.connect();
- try {
- const result = await client.query(
- "SELECT column_name, data_type FROM information_schema.columns WHERE table_name = $1",
- [tableName],
- );
-
- return {
- contents: [
- {
- uri: request.params.uri,
- mimeType: "application/json",
- text: JSON.stringify(result.rows, null, 2),
- },
- ],
- };
- } finally {
- client.release();
- }
-});
-
-server.setRequestHandler(ListToolsRequestSchema, async () => {
- return {
- tools: [
- {
- name: "query",
- description: "Run a read-only SQL query",
- inputSchema: {
- type: "object",
- properties: {
- sql: { type: "string" },
- },
- },
- },
- ],
- };
-});
-
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- if (request.params.name === "query") {
- const sql = request.params.arguments?.sql as string;
-
- const client = await pool.connect();
- try {
- await client.query("BEGIN TRANSACTION READ ONLY");
- const result = await client.query(sql);
- return {
- content: [{ type: "text", text: JSON.stringify(result.rows, null, 2) }],
- isError: false,
- };
- } catch (error) {
- throw error;
- } finally {
- client
- .query("ROLLBACK")
- .catch((error) =>
- console.warn("Could not roll back transaction:", error),
- );
-
- client.release();
- }
- }
- throw new Error(`Unknown tool: ${request.params.name}`);
-});
-
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
-}
-
-runServer().catch(console.error);
diff --git a/src/postgres/package.json b/src/postgres/package.json
deleted file mode 100644
index 70fa0dbd..00000000
--- a/src/postgres/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-postgres",
- "version": "0.6.2",
- "description": "MCP server for interacting with PostgreSQL databases",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-postgres": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1",
- "pg": "^8.13.0"
- },
- "devDependencies": {
- "@types/pg": "^8.11.10",
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/postgres/tsconfig.json b/src/postgres/tsconfig.json
deleted file mode 100644
index ec5da158..00000000
--- a/src/postgres/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
-}
diff --git a/src/puppeteer/Dockerfile b/src/puppeteer/Dockerfile
deleted file mode 100644
index d0f58a3a..00000000
--- a/src/puppeteer/Dockerfile
+++ /dev/null
@@ -1,26 +0,0 @@
-FROM node:22-bookworm-slim
-
-ENV DEBIAN_FRONTEND noninteractive
-
-# for arm64 support we need to install chromium provided by debian
-# npm ERR! The chromium binary is not available for arm64.
-# https://github.com/puppeteer/puppeteer/issues/7740
-
-ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
-ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
-
-RUN apt-get update && \
- apt-get install -y wget gnupg && \
- apt-get install -y fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
- libgtk2.0-0 libnss3 libatk-bridge2.0-0 libdrm2 libxkbcommon0 libgbm1 libasound2 && \
- apt-get install -y chromium && \
- apt-get clean
-
-COPY src/puppeteer /project
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /project
-
-RUN npm install
-
-ENTRYPOINT ["node", "dist/index.js"]
\ No newline at end of file
diff --git a/src/puppeteer/README.md b/src/puppeteer/README.md
deleted file mode 100644
index 4eab314c..00000000
--- a/src/puppeteer/README.md
+++ /dev/null
@@ -1,143 +0,0 @@
-# Puppeteer
-
-A Model Context Protocol server that provides browser automation capabilities using Puppeteer. This server enables LLMs to interact with web pages, take screenshots, and execute JavaScript in a real browser environment.
-
-## Components
-
-### Tools
-
-- **puppeteer_navigate**
- - Navigate to any URL in the browser
- - Inputs:
- - `url` (string, required): URL to navigate to
- - `launchOptions` (object, optional): PuppeteerJS LaunchOptions. Default null. If changed and not null, browser restarts. Example: `{ headless: true, args: ['--user-data-dir="C:/Data"'] }`
- - `allowDangerous` (boolean, optional): Allow dangerous LaunchOptions that reduce security. When false, dangerous args like `--no-sandbox`, `--disable-web-security` will throw errors. Default false.
-
-- **puppeteer_screenshot**
- - Capture screenshots of the entire page or specific elements
- - Inputs:
- - `name` (string, required): Name for the screenshot
- - `selector` (string, optional): CSS selector for element to screenshot
- - `width` (number, optional, default: 800): Screenshot width
- - `height` (number, optional, default: 600): Screenshot height
-
-- **puppeteer_click**
- - Click elements on the page
- - Input: `selector` (string): CSS selector for element to click
-
-- **puppeteer_hover**
- - Hover elements on the page
- - Input: `selector` (string): CSS selector for element to hover
-
-- **puppeteer_fill**
- - Fill out input fields
- - Inputs:
- - `selector` (string): CSS selector for input field
- - `value` (string): Value to fill
-
-- **puppeteer_select**
- - Select an element with SELECT tag
- - Inputs:
- - `selector` (string): CSS selector for element to select
- - `value` (string): Value to select
-
-- **puppeteer_evaluate**
- - Execute JavaScript in the browser console
- - Input: `script` (string): JavaScript code to execute
-
-### Resources
-
-The server provides access to two types of resources:
-
-1. **Console Logs** (`console://logs`)
- - Browser console output in text format
- - Includes all console messages from the browser
-
-2. **Screenshots** (`screenshot://`)
- - PNG images of captured screenshots
- - Accessible via the screenshot name specified during capture
-
-## Key Features
-
-- Browser automation
-- Console log monitoring
-- Screenshot capabilities
-- JavaScript execution
-- Basic web interaction (navigation, clicking, form filling)
-- Customizable Puppeteer launch options
-
-## Configuration to use Puppeteer Server
-Here's the Claude Desktop configuration to use the Puppeter server:
-
-### Docker
-
-**NOTE** The docker implementation will use headless chromium, where as the NPX version will open a browser window.
-
-```json
-{
- "mcpServers": {
- "puppeteer": {
- "command": "docker",
- "args": ["run", "-i", "--rm", "--init", "-e", "DOCKER_CONTAINER=true", "mcp/puppeteer"]
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "puppeteer": {
- "command": "npx",
- "args": ["-y", "@modelcontextprotocol/server-puppeteer"]
- }
- }
-}
-```
-
-### Launch Options
-
-You can customize Puppeteer's browser behavior in two ways:
-
-1. **Environment Variable**: Set `PUPPETEER_LAUNCH_OPTIONS` with a JSON-encoded string in the MCP configuration's `env` parameter:
-
- ```json
- {
- "mcpServers": {
- "mcp-puppeteer": {
- "command": "npx",
- "args": ["-y", "@modelcontextprotocol/server-puppeteer"],
- "env": {
- "PUPPETEER_LAUNCH_OPTIONS": "{ \"headless\": false, \"executablePath\": \"C:/Program Files/Google/Chrome/Application/chrome.exe\", \"args\": [] }",
- "ALLOW_DANGEROUS": "true"
- }
- }
- }
- }
- ```
-
-2. **Tool Call Arguments**: Pass `launchOptions` and `allowDangerous` parameters to the `puppeteer_navigate` tool:
-
- ```json
- {
- "url": "https://example.com",
- "launchOptions": {
- "headless": false,
- "defaultViewport": {"width": 1280, "height": 720}
- }
- }
- ```
-
-## Build
-
-Docker build:
-
-```bash
-docker build -t mcp/puppeteer -f src/puppeteer/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
\ No newline at end of file
diff --git a/src/puppeteer/index.ts b/src/puppeteer/index.ts
deleted file mode 100644
index 1849c783..00000000
--- a/src/puppeteer/index.ts
+++ /dev/null
@@ -1,484 +0,0 @@
-#!/usr/bin/env node
-
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListResourcesRequestSchema,
- ListToolsRequestSchema,
- ReadResourceRequestSchema,
- CallToolResult,
- TextContent,
- ImageContent,
- Tool,
-} from "@modelcontextprotocol/sdk/types.js";
-import puppeteer, { Browser, Page } from "puppeteer";
-
-// Define the tools once to avoid repetition
-const TOOLS: Tool[] = [
- {
- name: "puppeteer_navigate",
- description: "Navigate to a URL",
- inputSchema: {
- type: "object",
- properties: {
- url: { type: "string", description: "URL to navigate to" },
- launchOptions: { type: "object", description: "PuppeteerJS LaunchOptions. Default null. If changed and not null, browser restarts. Example: { headless: true, args: ['--no-sandbox'] }" },
- allowDangerous: { type: "boolean", description: "Allow dangerous LaunchOptions that reduce security. When false, dangerous args like --no-sandbox will throw errors. Default false." },
- },
- required: ["url"],
- },
- },
- {
- name: "puppeteer_screenshot",
- description: "Take a screenshot of the current page or a specific element",
- inputSchema: {
- type: "object",
- properties: {
- name: { type: "string", description: "Name for the screenshot" },
- selector: { type: "string", description: "CSS selector for element to screenshot" },
- width: { type: "number", description: "Width in pixels (default: 800)" },
- height: { type: "number", description: "Height in pixels (default: 600)" },
- },
- required: ["name"],
- },
- },
- {
- name: "puppeteer_click",
- description: "Click an element on the page",
- inputSchema: {
- type: "object",
- properties: {
- selector: { type: "string", description: "CSS selector for element to click" },
- },
- required: ["selector"],
- },
- },
- {
- name: "puppeteer_fill",
- description: "Fill out an input field",
- inputSchema: {
- type: "object",
- properties: {
- selector: { type: "string", description: "CSS selector for input field" },
- value: { type: "string", description: "Value to fill" },
- },
- required: ["selector", "value"],
- },
- },
- {
- name: "puppeteer_select",
- description: "Select an element on the page with Select tag",
- inputSchema: {
- type: "object",
- properties: {
- selector: { type: "string", description: "CSS selector for element to select" },
- value: { type: "string", description: "Value to select" },
- },
- required: ["selector", "value"],
- },
- },
- {
- name: "puppeteer_hover",
- description: "Hover an element on the page",
- inputSchema: {
- type: "object",
- properties: {
- selector: { type: "string", description: "CSS selector for element to hover" },
- },
- required: ["selector"],
- },
- },
- {
- name: "puppeteer_evaluate",
- description: "Execute JavaScript in the browser console",
- inputSchema: {
- type: "object",
- properties: {
- script: { type: "string", description: "JavaScript code to execute" },
- },
- required: ["script"],
- },
- },
-];
-
-// Global state
-let browser: Browser | null;
-let page: Page | null;
-const consoleLogs: string[] = [];
-const screenshots = new Map();
-let previousLaunchOptions: any = null;
-
-async function ensureBrowser({ launchOptions, allowDangerous }: any) {
-
- const DANGEROUS_ARGS = [
- '--no-sandbox',
- '--disable-setuid-sandbox',
- '--single-process',
- '--disable-web-security',
- '--ignore-certificate-errors',
- '--disable-features=IsolateOrigins',
- '--disable-site-isolation-trials',
- '--allow-running-insecure-content'
- ];
-
- // Parse environment config safely
- let envConfig = {};
- try {
- envConfig = JSON.parse(process.env.PUPPETEER_LAUNCH_OPTIONS || '{}');
- } catch (error: any) {
- console.warn('Failed to parse PUPPETEER_LAUNCH_OPTIONS:', error?.message || error);
- }
-
- // Deep merge environment config with user-provided options
- const mergedConfig = deepMerge(envConfig, launchOptions || {});
-
- // Security validation for merged config
- if (mergedConfig?.args) {
- const dangerousArgs = mergedConfig.args?.filter?.((arg: string) => DANGEROUS_ARGS.some((dangerousArg: string) => arg.startsWith(dangerousArg)));
- if (dangerousArgs?.length > 0 && !(allowDangerous || (process.env.ALLOW_DANGEROUS === 'true'))) {
- throw new Error(`Dangerous browser arguments detected: ${dangerousArgs.join(', ')}. Fround from environment variable and tool call argument. ` +
- 'Set allowDangerous: true in the tool call arguments to override.');
- }
- }
-
- try {
- if ((browser && !browser.connected) ||
- (launchOptions && (JSON.stringify(launchOptions) != JSON.stringify(previousLaunchOptions)))) {
- await browser?.close();
- browser = null;
- }
- }
- catch (error) {
- browser = null;
- }
-
- previousLaunchOptions = launchOptions;
-
- if (!browser) {
- const npx_args = { headless: false }
- const docker_args = { headless: true, args: ["--no-sandbox", "--single-process", "--no-zygote"] }
- browser = await puppeteer.launch(deepMerge(
- process.env.DOCKER_CONTAINER ? docker_args : npx_args,
- mergedConfig
- ));
- const pages = await browser.pages();
- page = pages[0];
-
- page.on("console", (msg) => {
- const logEntry = `[${msg.type()}] ${msg.text()}`;
- consoleLogs.push(logEntry);
- server.notification({
- method: "notifications/resources/updated",
- params: { uri: "console://logs" },
- });
- });
- }
- return page!;
-}
-
-// Deep merge utility function
-function deepMerge(target: any, source: any): any {
- const output = Object.assign({}, target);
- if (typeof target !== 'object' || typeof source !== 'object') return source;
-
- for (const key of Object.keys(source)) {
- const targetVal = target[key];
- const sourceVal = source[key];
- if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {
- // Deduplicate args/ignoreDefaultArgs, prefer source values
- output[key] = [...new Set([
- ...(key === 'args' || key === 'ignoreDefaultArgs' ?
- targetVal.filter((arg: string) => !sourceVal.some((launchArg: string) => arg.startsWith('--') && launchArg.startsWith(arg.split('=')[0]))) :
- targetVal),
- ...sourceVal
- ])];
- } else if (sourceVal instanceof Object && key in target) {
- output[key] = deepMerge(targetVal, sourceVal);
- } else {
- output[key] = sourceVal;
- }
- }
- return output;
-}
-
-declare global {
- interface Window {
- mcpHelper: {
- logs: string[],
- originalConsole: Partial,
- }
- }
-}
-
-async function handleToolCall(name: string, args: any): Promise {
- const page = await ensureBrowser(args);
-
- switch (name) {
- case "puppeteer_navigate":
- await page.goto(args.url);
- return {
- content: [{
- type: "text",
- text: `Navigated to ${args.url}`,
- }],
- isError: false,
- };
-
- case "puppeteer_screenshot": {
- const width = args.width ?? 800;
- const height = args.height ?? 600;
- await page.setViewport({ width, height });
-
- const screenshot = await (args.selector ?
- (await page.$(args.selector))?.screenshot({ encoding: "base64" }) :
- page.screenshot({ encoding: "base64", fullPage: false }));
-
- if (!screenshot) {
- return {
- content: [{
- type: "text",
- text: args.selector ? `Element not found: ${args.selector}` : "Screenshot failed",
- }],
- isError: true,
- };
- }
-
- screenshots.set(args.name, screenshot as string);
- server.notification({
- method: "notifications/resources/list_changed",
- });
-
- return {
- content: [
- {
- type: "text",
- text: `Screenshot '${args.name}' taken at ${width}x${height}`,
- } as TextContent,
- {
- type: "image",
- data: screenshot,
- mimeType: "image/png",
- } as ImageContent,
- ],
- isError: false,
- };
- }
-
- case "puppeteer_click":
- try {
- await page.click(args.selector);
- return {
- content: [{
- type: "text",
- text: `Clicked: ${args.selector}`,
- }],
- isError: false,
- };
- } catch (error) {
- return {
- content: [{
- type: "text",
- text: `Failed to click ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- };
- }
-
- case "puppeteer_fill":
- try {
- await page.waitForSelector(args.selector);
- await page.type(args.selector, args.value);
- return {
- content: [{
- type: "text",
- text: `Filled ${args.selector} with: ${args.value}`,
- }],
- isError: false,
- };
- } catch (error) {
- return {
- content: [{
- type: "text",
- text: `Failed to fill ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- };
- }
-
- case "puppeteer_select":
- try {
- await page.waitForSelector(args.selector);
- await page.select(args.selector, args.value);
- return {
- content: [{
- type: "text",
- text: `Selected ${args.selector} with: ${args.value}`,
- }],
- isError: false,
- };
- } catch (error) {
- return {
- content: [{
- type: "text",
- text: `Failed to select ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- };
- }
-
- case "puppeteer_hover":
- try {
- await page.waitForSelector(args.selector);
- await page.hover(args.selector);
- return {
- content: [{
- type: "text",
- text: `Hovered ${args.selector}`,
- }],
- isError: false,
- };
- } catch (error) {
- return {
- content: [{
- type: "text",
- text: `Failed to hover ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- };
- }
-
- case "puppeteer_evaluate":
- try {
- await page.evaluate(() => {
- window.mcpHelper = {
- logs: [],
- originalConsole: { ...console },
- };
-
- ['log', 'info', 'warn', 'error'].forEach(method => {
- (console as any)[method] = (...args: any[]) => {
- window.mcpHelper.logs.push(`[${method}] ${args.join(' ')}`);
- (window.mcpHelper.originalConsole as any)[method](...args);
- };
- });
- });
-
- const result = await page.evaluate(args.script);
-
- const logs = await page.evaluate(() => {
- Object.assign(console, window.mcpHelper.originalConsole);
- const logs = window.mcpHelper.logs;
- delete (window as any).mcpHelper;
- return logs;
- });
-
- return {
- content: [
- {
- type: "text",
- text: `Execution result:\n${JSON.stringify(result, null, 2)}\n\nConsole output:\n${logs.join('\n')}`,
- },
- ],
- isError: false,
- };
- } catch (error) {
- return {
- content: [{
- type: "text",
- text: `Script execution failed: ${(error as Error).message}`,
- }],
- isError: true,
- };
- }
-
- default:
- return {
- content: [{
- type: "text",
- text: `Unknown tool: ${name}`,
- }],
- isError: true,
- };
- }
-}
-
-const server = new Server(
- {
- name: "example-servers/puppeteer",
- version: "0.1.0",
- },
- {
- capabilities: {
- resources: {},
- tools: {},
- },
- },
-);
-
-
-// Setup request handlers
-server.setRequestHandler(ListResourcesRequestSchema, async () => ({
- resources: [
- {
- uri: "console://logs",
- mimeType: "text/plain",
- name: "Browser console logs",
- },
- ...Array.from(screenshots.keys()).map(name => ({
- uri: `screenshot://${name}`,
- mimeType: "image/png",
- name: `Screenshot: ${name}`,
- })),
- ],
-}));
-
-server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
- const uri = request.params.uri.toString();
-
- if (uri === "console://logs") {
- return {
- contents: [{
- uri,
- mimeType: "text/plain",
- text: consoleLogs.join("\n"),
- }],
- };
- }
-
- if (uri.startsWith("screenshot://")) {
- const name = uri.split("://")[1];
- const screenshot = screenshots.get(name);
- if (screenshot) {
- return {
- contents: [{
- uri,
- mimeType: "image/png",
- blob: screenshot,
- }],
- };
- }
- }
-
- throw new Error(`Resource not found: ${uri}`);
-});
-
-server.setRequestHandler(ListToolsRequestSchema, async () => ({
- tools: TOOLS,
-}));
-
-server.setRequestHandler(CallToolRequestSchema, async (request) =>
- handleToolCall(request.params.name, request.params.arguments ?? {})
-);
-
-async function runServer() {
- const transport = new StdioServerTransport();
- await server.connect(transport);
-}
-
-runServer().catch(console.error);
-
-process.stdin.on("close", () => {
- console.error("Puppeteer MCP Server closed");
- server.close();
-});
\ No newline at end of file
diff --git a/src/puppeteer/package.json b/src/puppeteer/package.json
deleted file mode 100644
index 6ca49157..00000000
--- a/src/puppeteer/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-puppeteer",
- "version": "0.6.2",
- "description": "MCP server for browser automation using Puppeteer",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-puppeteer": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1",
- "puppeteer": "^23.4.0"
- },
- "devDependencies": {
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/puppeteer/tsconfig.json b/src/puppeteer/tsconfig.json
deleted file mode 100644
index ec5da158..00000000
--- a/src/puppeteer/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
-}
diff --git a/src/redis/Dockerfile b/src/redis/Dockerfile
deleted file mode 100644
index 24a2bb87..00000000
--- a/src/redis/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-FROM node:22.12-alpine as builder
-
-COPY src/redis /app
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-RUN npm run build
-
-FROM node:22-alpine AS release
-
-COPY --from=builder /app/build /app/build
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-WORKDIR /app
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "build/index.js"]
\ No newline at end of file
diff --git a/src/redis/README.md b/src/redis/README.md
deleted file mode 100644
index 992471dc..00000000
--- a/src/redis/README.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Redis
-
-A Model Context Protocol server that provides access to Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.
-
-## Prerequisites
-
-1. Redis server must be installed and running
- - [Download Redis](https://redis.io/download)
- - For Windows users: Use [Windows Subsystem for Linux (WSL)](https://redis.io/docs/getting-started/installation/install-redis-on-windows/) or [Memurai](https://www.memurai.com/) (Redis-compatible Windows server)
- - Default port: 6379
-
-## Common Issues & Solutions
-
-### Connection Errors
-
-**ECONNREFUSED**
- - **Cause**: Redis server is not running or unreachable
- - **Solution**:
- - Verify Redis is running: `redis-cli ping` should return "PONG"
- - Check Redis service status: `systemctl status redis` (Linux) or `brew services list` (macOS)
- - Ensure correct port (default 6379) is not blocked by firewall
- - Verify Redis URL format: `redis://hostname:port`
-
-### Server Behavior
-
-- The server implements exponential backoff with a maximum of 5 retries
-- Initial retry delay: 1 second, maximum delay: 30 seconds
-- Server will exit after max retries to prevent infinite reconnection loops
-
-## Components
-
-### Tools
-
-- **set**
- - Set a Redis key-value pair with optional expiration
- - Input:
- - `key` (string): Redis key
- - `value` (string): Value to store
- - `expireSeconds` (number, optional): Expiration time in seconds
-
-- **get**
- - Get value by key from Redis
- - Input: `key` (string): Redis key to retrieve
-
-- **delete**
- - Delete one or more keys from Redis
- - Input: `key` (string | string[]): Key or array of keys to delete
-
-- **list**
- - List Redis keys matching a pattern
- - Input: `pattern` (string, optional): Pattern to match keys (default: *)
-
-## Usage with Claude Desktop
-
-To use this server with the Claude Desktop app, add the following configuration to the "mcpServers" section of your `claude_desktop_config.json`:
-
-### Docker
-
-* when running docker on macos, use host.docker.internal if the server is running on the host network (eg localhost)
-* Redis URL can be specified as an argument, defaults to "redis://localhost:6379"
-
-```json
-{
- "mcpServers": {
- "redis": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "mcp/redis",
- "redis://host.docker.internal:6379"]
- }
- }
-}
-```
-
-### NPX
-
-```json
-{
- "mcpServers": {
- "redis": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-redis",
- "redis://localhost:6379"
- ]
- }
- }
-}
-```
-
-## Building
-
-Docker:
-
-```sh
-docker build -t mcp/redis -f src/redis/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/redis/package.json b/src/redis/package.json
deleted file mode 100644
index 33155265..00000000
--- a/src/redis/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-redis",
- "version": "0.1.0",
- "description": "MCP server for using Redis",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "redis": "./build/index.js"
- },
- "files": [
- "build"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x build/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "^1.7.0",
- "@types/node": "^22.10.2",
- "@types/redis": "^4.0.10",
- "redis": "^4.7.0"
- },
- "devDependencies": {
- "shx": "^0.3.4",
- "typescript": "^5.7.2"
- }
-}
diff --git a/src/redis/src/index.ts b/src/redis/src/index.ts
deleted file mode 100644
index 27ce91fa..00000000
--- a/src/redis/src/index.ts
+++ /dev/null
@@ -1,286 +0,0 @@
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequestSchema,
- ListToolsRequestSchema,
-} from "@modelcontextprotocol/sdk/types.js";
-import { z } from "zod";
-import { createClient } from 'redis';
-
-// Configuration
-const REDIS_URL = process.argv[2] || "redis://localhost:6379";
-const MAX_RETRIES = 5;
-const MIN_RETRY_DELAY = 1000; // 1 second
-const MAX_RETRY_DELAY = 30000; // 30 seconds
-
-// Create Redis client with retry strategy
-const redisClient = createClient({
- url: REDIS_URL,
- socket: {
- reconnectStrategy: (retries) => {
- if (retries >= MAX_RETRIES) {
- console.error(`Maximum retries (${MAX_RETRIES}) reached. Giving up.`);
- return new Error('Max retries reached');
- }
- const delay = Math.min(Math.pow(2, retries) * MIN_RETRY_DELAY, MAX_RETRY_DELAY);
- console.error(`Reconnection attempt ${retries + 1}/${MAX_RETRIES} in ${delay}ms`);
- return delay;
- }
- }
-});
-
-// Define Zod schemas for validation
-const SetArgumentsSchema = z.object({
- key: z.string(),
- value: z.string(),
- expireSeconds: z.number().optional(),
-});
-
-const GetArgumentsSchema = z.object({
- key: z.string(),
-});
-
-const DeleteArgumentsSchema = z.object({
- key: z.string().or(z.array(z.string())),
-});
-
-const ListArgumentsSchema = z.object({
- pattern: z.string().default("*"),
-});
-
-// Create server instance
-const server = new Server(
- {
- name: "redis",
- version: "0.0.1"
- },
- {
- capabilities: {
- tools: {}
- }
- }
-);
-
-// List available tools
-server.setRequestHandler(ListToolsRequestSchema, async () => {
- return {
- tools: [
- {
- name: "set",
- description: "Set a Redis key-value pair with optional expiration",
- inputSchema: {
- type: "object",
- properties: {
- key: {
- type: "string",
- description: "Redis key",
- },
- value: {
- type: "string",
- description: "Value to store",
- },
- expireSeconds: {
- type: "number",
- description: "Optional expiration time in seconds",
- },
- },
- required: ["key", "value"],
- },
- },
- {
- name: "get",
- description: "Get value by key from Redis",
- inputSchema: {
- type: "object",
- properties: {
- key: {
- type: "string",
- description: "Redis key to retrieve",
- },
- },
- required: ["key"],
- },
- },
- {
- name: "delete",
- description: "Delete one or more keys from Redis",
- inputSchema: {
- type: "object",
- properties: {
- key: {
- oneOf: [
- { type: "string" },
- { type: "array", items: { type: "string" } }
- ],
- description: "Key or array of keys to delete",
- },
- },
- required: ["key"],
- },
- },
- {
- name: "list",
- description: "List Redis keys matching a pattern",
- inputSchema: {
- type: "object",
- properties: {
- pattern: {
- type: "string",
- description: "Pattern to match keys (default: *)",
- },
- },
- },
- },
- ],
- };
-});
-
-// Handle tool execution
-server.setRequestHandler(CallToolRequestSchema, async (request) => {
- const { name, arguments: args } = request.params;
-
- try {
- if (name === "set") {
- const { key, value, expireSeconds } = SetArgumentsSchema.parse(args);
-
- if (expireSeconds) {
- await redisClient.setEx(key, expireSeconds, value);
- } else {
- await redisClient.set(key, value);
- }
-
- return {
- content: [
- {
- type: "text",
- text: `Successfully set key: ${key}`,
- },
- ],
- };
- } else if (name === "get") {
- const { key } = GetArgumentsSchema.parse(args);
- const value = await redisClient.get(key);
-
- if (value === null) {
- return {
- content: [
- {
- type: "text",
- text: `Key not found: ${key}`,
- },
- ],
- };
- }
-
- return {
- content: [
- {
- type: "text",
- text: `${value}`,
- },
- ],
- };
- } else if (name === "delete") {
- const { key } = DeleteArgumentsSchema.parse(args);
-
- if (Array.isArray(key)) {
- await redisClient.del(key);
- return {
- content: [
- {
- type: "text",
- text: `Successfully deleted ${key.length} keys`,
- },
- ],
- };
- } else {
- await redisClient.del(key);
- return {
- content: [
- {
- type: "text",
- text: `Successfully deleted key: ${key}`,
- },
- ],
- };
- }
- } else if (name === "list") {
- const { pattern } = ListArgumentsSchema.parse(args);
- const keys = await redisClient.keys(pattern);
-
- return {
- content: [
- {
- type: "text",
- text: keys.length > 0
- ? `Found keys:\n${keys.join('\n')}`
- : "No keys found matching pattern",
- },
- ],
- };
- } else {
- throw new Error(`Unknown tool: ${name}`);
- }
- } catch (error) {
- if (error instanceof z.ZodError) {
- throw new Error(
- `Invalid arguments: ${error.errors
- .map((e) => `${e.path.join(".")}: ${e.message}`)
- .join(", ")}`
- );
- }
- throw error;
- }
-});
-
-// Start the server
-async function main() {
- try {
- // Set up Redis event handlers
- redisClient.on('error', (err: Error) => {
- console.error('Redis Client Error:', err);
- });
-
- redisClient.on('connect', () => {
- console.error(`Connected to Redis at ${REDIS_URL}`);
- });
-
- redisClient.on('reconnecting', () => {
- console.error('Attempting to reconnect to Redis...');
- });
-
- redisClient.on('end', () => {
- console.error('Redis connection closed');
- });
-
- // Connect to Redis
- await redisClient.connect();
-
- // Set up MCP server
- const transport = new StdioServerTransport();
- await server.connect(transport);
- console.error("Redis MCP Server running on stdio");
- } catch (error) {
- console.error("Error during startup:", error);
- await cleanup();
- }
-}
-
-// Cleanup function
-async function cleanup() {
- try {
- await redisClient.quit();
- } catch (error) {
- console.error("Error during cleanup:", error);
- }
- process.exit(1);
-}
-
-// Handle process termination
-process.on('SIGINT', cleanup);
-process.on('SIGTERM', cleanup);
-
-main().catch((error) => {
- console.error("Fatal error in main():", error);
- cleanup();
-});
diff --git a/src/redis/tsconfig.json b/src/redis/tsconfig.json
deleted file mode 100644
index efcd96e7..00000000
--- a/src/redis/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2022",
- "module": "Node16",
- "moduleResolution": "Node16",
- "outDir": "./build",
- "rootDir": "./src",
- "strict": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true
- },
- "include": ["src/**/*"],
- "exclude": ["node_modules"]
- }
-
\ No newline at end of file
diff --git a/src/sentry/.python-version b/src/sentry/.python-version
deleted file mode 100644
index c8cfe395..00000000
--- a/src/sentry/.python-version
+++ /dev/null
@@ -1 +0,0 @@
-3.10
diff --git a/src/sentry/Dockerfile b/src/sentry/Dockerfile
deleted file mode 100644
index a706a15e..00000000
--- a/src/sentry/Dockerfile
+++ /dev/null
@@ -1,37 +0,0 @@
-# Use a Python image with uv pre-installed
-FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS uv
-
-# Install the project into `/app`
-WORKDIR /app
-
-# Enable bytecode compilation
-ENV UV_COMPILE_BYTECODE=1
-
-# Copy from the cache instead of linking since it's a mounted volume
-ENV UV_LINK_MODE=copy
-
-# Install the project's dependencies using the lockfile and settings
-RUN --mount=type=cache,target=/root/.cache/uv \
- --mount=type=bind,source=uv.lock,target=uv.lock \
- --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
- uv sync --frozen --no-install-project --no-dev --no-editable
-
-# Then, add the rest of the project source code and install it
-# Installing separately from its dependencies allows optimal layer caching
-ADD . /app
-RUN --mount=type=cache,target=/root/.cache/uv \
- uv sync --frozen --no-dev --no-editable
-
-FROM python:3.12-slim-bookworm
-
-WORKDIR /app
-
-COPY --from=uv /root/.local /root/.local
-COPY --from=uv --chown=app:app /app/.venv /app/.venv
-
-# Place executables in the environment at the front of the path
-ENV PATH="/app/.venv/bin:$PATH"
-
-# when running the container, add --db-path and a bind mount to the host's db file
-ENTRYPOINT ["mcp-server-sentry"]
-
diff --git a/src/sentry/README.md b/src/sentry/README.md
deleted file mode 100644
index 4f02bb58..00000000
--- a/src/sentry/README.md
+++ /dev/null
@@ -1,149 +0,0 @@
-# mcp-server-sentry: A Sentry MCP server
-
-## Overview
-
-A Model Context Protocol server for retrieving and analyzing issues from Sentry.io. This server provides tools to inspect error reports, stacktraces, and other debugging information from your Sentry account.
-
-### Tools
-
-1. `get_sentry_issue`
- - Retrieve and analyze a Sentry issue by ID or URL
- - Input:
- - `issue_id_or_url` (string): Sentry issue ID or URL to analyze
- - Returns: Issue details including:
- - Title
- - Issue ID
- - Status
- - Level
- - First seen timestamp
- - Last seen timestamp
- - Event count
- - Full stacktrace
-
-### Prompts
-
-1. `sentry-issue`
- - Retrieve issue details from Sentry
- - Input:
- - `issue_id_or_url` (string): Sentry issue ID or URL
- - Returns: Formatted issue details as conversation context
-
-## Installation
-
-### Using uv (recommended)
-
-When using [`uv`](https://docs.astral.sh/uv/) no specific installation is needed. We will
-use [`uvx`](https://docs.astral.sh/uv/guides/tools/) to directly run *mcp-server-sentry*.
-
-### Using PIP
-
-Alternatively you can install `mcp-server-sentry` via pip:
-
-```
-pip install mcp-server-sentry
-```
-
-After installation, you can run it as a script using:
-
-```
-python -m mcp_server_sentry
-```
-
-## Configuration
-
-### Usage with Claude Desktop
-
-Add this to your `claude_desktop_config.json`:
-
-
-Using uvx
-
-```json
-"mcpServers": {
- "sentry": {
- "command": "uvx",
- "args": ["mcp-server-sentry", "--auth-token", "YOUR_SENTRY_TOKEN"]
- }
-}
-```
-
-
-
-
-
-Using docker
-
-```json
-"mcpServers": {
- "sentry": {
- "command": "docker",
- "args": ["run", "-i", "--rm", "mcp/sentry", "--auth-token", "YOUR_SENTRY_TOKEN"]
- }
-}
-```
-
-
-
-
-Using pip installation
-
-```json
-"mcpServers": {
- "sentry": {
- "command": "python",
- "args": ["-m", "mcp_server_sentry", "--auth-token", "YOUR_SENTRY_TOKEN"]
- }
-}
-```
-
-
-### Usage with [Zed](https://github.com/zed-industries/zed)
-
-Add to your Zed settings.json:
-
-
-Using uvx
-
-```json
-"context_servers": [
- "mcp-server-sentry": {
- "command": {
- "path": "uvx",
- "args": ["mcp-server-sentry", "--auth-token", "YOUR_SENTRY_TOKEN"]
- }
- }
-],
-```
-
-
-
-Using pip installation
-
-```json
-"context_servers": {
- "mcp-server-sentry": {
- "command": "python",
- "args": ["-m", "mcp_server_sentry", "--auth-token", "YOUR_SENTRY_TOKEN"]
- }
-},
-```
-
-
-## Debugging
-
-You can use the MCP inspector to debug the server. For uvx installations:
-
-```
-npx @modelcontextprotocol/inspector uvx mcp-server-sentry --auth-token YOUR_SENTRY_TOKEN
-```
-
-Or if you've installed the package in a specific directory or are developing on it:
-
-```
-cd path/to/servers/src/sentry
-npx @modelcontextprotocol/inspector uv run mcp-server-sentry --auth-token YOUR_SENTRY_TOKEN
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/sentry/pyproject.toml b/src/sentry/pyproject.toml
deleted file mode 100644
index 0788ad80..00000000
--- a/src/sentry/pyproject.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[project]
-name = "mcp-server-sentry"
-version = "0.6.2"
-description = "MCP server for retrieving issues from sentry.io"
-readme = "README.md"
-requires-python = ">=3.10"
-dependencies = ["mcp>=1.0.0"]
-
-[build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
-
-[tool.uv]
-dev-dependencies = ["pyright>=1.1.389", "pytest>=8.3.3", "ruff>=0.8.0"]
-
-[project.scripts]
-mcp-server-sentry = "mcp_server_sentry:main"
diff --git a/src/sentry/src/mcp_server_sentry/__init__.py b/src/sentry/src/mcp_server_sentry/__init__.py
deleted file mode 100644
index 8fc09807..00000000
--- a/src/sentry/src/mcp_server_sentry/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from . import server
-import asyncio
-
-
-def main():
- """Main entry point for the package."""
- asyncio.run(server.main())
-
-
-# Optionally expose other important items at package level
-__all__ = ["main", "server"]
diff --git a/src/sentry/src/mcp_server_sentry/__main__.py b/src/sentry/src/mcp_server_sentry/__main__.py
deleted file mode 100644
index c9a93f1a..00000000
--- a/src/sentry/src/mcp_server_sentry/__main__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from mcp_server_sentry.server import main
-
-if __name__ == "__main__":
- main()
diff --git a/src/sentry/src/mcp_server_sentry/server.py b/src/sentry/src/mcp_server_sentry/server.py
deleted file mode 100644
index 9f885bbc..00000000
--- a/src/sentry/src/mcp_server_sentry/server.py
+++ /dev/null
@@ -1,285 +0,0 @@
-import asyncio
-from dataclasses import dataclass
-from urllib.parse import urlparse
-
-import click
-import httpx
-import mcp.types as types
-from mcp.server import NotificationOptions, Server
-from mcp.server.models import InitializationOptions
-from mcp.shared.exceptions import McpError
-import mcp.server.stdio
-
-SENTRY_API_BASE = "https://sentry.io/api/0/"
-MISSING_AUTH_TOKEN_MESSAGE = (
- """Sentry authentication token not found. Please specify your Sentry auth token."""
-)
-
-
-@dataclass
-class SentryIssueData:
- title: str
- issue_id: str
- status: str
- level: str
- first_seen: str
- last_seen: str
- count: int
- stacktrace: str
-
- def to_text(self) -> str:
- return f"""
-Sentry Issue: {self.title}
-Issue ID: {self.issue_id}
-Status: {self.status}
-Level: {self.level}
-First Seen: {self.first_seen}
-Last Seen: {self.last_seen}
-Event Count: {self.count}
-
-{self.stacktrace}
- """
-
- def to_prompt_result(self) -> types.GetPromptResult:
- return types.GetPromptResult(
- description=f"Sentry Issue: {self.title}",
- messages=[
- types.PromptMessage(
- role="user", content=types.TextContent(type="text", text=self.to_text())
- )
- ],
- )
-
- def to_tool_result(self) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
- return [types.TextContent(type="text", text=self.to_text())]
-
-
-class SentryError(Exception):
- pass
-
-
-def extract_issue_id(issue_id_or_url: str) -> str:
- """
- Extracts the Sentry issue ID from either a full URL or a standalone ID.
-
- This function validates the input and returns the numeric issue ID.
- It raises SentryError for invalid inputs, including empty strings,
- non-Sentry URLs, malformed paths, and non-numeric IDs.
- """
- if not issue_id_or_url:
- raise SentryError("Missing issue_id_or_url argument")
-
- if issue_id_or_url.startswith(("http://", "https://")):
- parsed_url = urlparse(issue_id_or_url)
- if not parsed_url.hostname or not parsed_url.hostname.endswith(".sentry.io"):
- raise SentryError("Invalid Sentry URL. Must be a URL ending with .sentry.io")
-
- path_parts = parsed_url.path.strip("/").split("/")
- if len(path_parts) < 2 or path_parts[0] != "issues":
- raise SentryError(
- "Invalid Sentry issue URL. Path must contain '/issues/{issue_id}'"
- )
-
- issue_id = path_parts[-1]
- else:
- issue_id = issue_id_or_url
-
- if not issue_id.isdigit():
- raise SentryError("Invalid Sentry issue ID. Must be a numeric value.")
-
- return issue_id
-
-
-def create_stacktrace(latest_event: dict) -> str:
- """
- Creates a formatted stacktrace string from the latest Sentry event.
-
- This function extracts exception information and stacktrace details from the
- provided event dictionary, formatting them into a human-readable string.
- It handles multiple exceptions and includes file, line number, and function
- information for each frame in the stacktrace.
-
- Args:
- latest_event (dict): A dictionary containing the latest Sentry event data.
-
- Returns:
- str: A formatted string containing the stacktrace information,
- or "No stacktrace found" if no relevant data is present.
- """
- stacktraces = []
- for entry in latest_event.get("entries", []):
- if entry["type"] != "exception":
- continue
-
- exception_data = entry["data"]["values"]
- for exception in exception_data:
- exception_type = exception.get("type", "Unknown")
- exception_value = exception.get("value", "")
- stacktrace = exception.get("stacktrace")
-
- stacktrace_text = f"Exception: {exception_type}: {exception_value}\n\n"
- if stacktrace:
- stacktrace_text += "Stacktrace:\n"
- for frame in stacktrace.get("frames", []):
- filename = frame.get("filename", "Unknown")
- lineno = frame.get("lineNo", "?")
- function = frame.get("function", "Unknown")
-
- stacktrace_text += f"{filename}:{lineno} in {function}\n"
-
- if "context" in frame:
- context = frame["context"]
- for ctx_line in context:
- stacktrace_text += f" {ctx_line[1]}\n"
-
- stacktrace_text += "\n"
-
- stacktraces.append(stacktrace_text)
-
- return "\n".join(stacktraces) if stacktraces else "No stacktrace found"
-
-
-async def handle_sentry_issue(
- http_client: httpx.AsyncClient, auth_token: str, issue_id_or_url: str
-) -> SentryIssueData:
- try:
- issue_id = extract_issue_id(issue_id_or_url)
-
- response = await http_client.get(
- f"issues/{issue_id}/", headers={"Authorization": f"Bearer {auth_token}"}
- )
- if response.status_code == 401:
- raise McpError(
- "Error: Unauthorized. Please check your MCP_SENTRY_AUTH_TOKEN token."
- )
- response.raise_for_status()
- issue_data = response.json()
-
- # Get issue hashes
- hashes_response = await http_client.get(
- f"issues/{issue_id}/hashes/",
- headers={"Authorization": f"Bearer {auth_token}"},
- )
- hashes_response.raise_for_status()
- hashes = hashes_response.json()
-
- if not hashes:
- raise McpError("No Sentry events found for this issue")
-
- latest_event = hashes[0]["latestEvent"]
- stacktrace = create_stacktrace(latest_event)
-
- return SentryIssueData(
- title=issue_data["title"],
- issue_id=issue_id,
- status=issue_data["status"],
- level=issue_data["level"],
- first_seen=issue_data["firstSeen"],
- last_seen=issue_data["lastSeen"],
- count=issue_data["count"],
- stacktrace=stacktrace
- )
-
- except SentryError as e:
- raise McpError(str(e))
- except httpx.HTTPStatusError as e:
- raise McpError(f"Error fetching Sentry issue: {str(e)}")
- except Exception as e:
- raise McpError(f"An error occurred: {str(e)}")
-
-
-async def serve(auth_token: str) -> Server:
- server = Server("sentry")
- http_client = httpx.AsyncClient(base_url=SENTRY_API_BASE)
-
- @server.list_prompts()
- async def handle_list_prompts() -> list[types.Prompt]:
- return [
- types.Prompt(
- name="sentry-issue",
- description="Retrieve a Sentry issue by ID or URL",
- arguments=[
- types.PromptArgument(
- name="issue_id_or_url",
- description="Sentry issue ID or URL",
- required=True,
- )
- ],
- )
- ]
-
- @server.get_prompt()
- async def handle_get_prompt(
- name: str, arguments: dict[str, str] | None
- ) -> types.GetPromptResult:
- if name != "sentry-issue":
- raise ValueError(f"Unknown prompt: {name}")
-
- issue_id_or_url = (arguments or {}).get("issue_id_or_url", "")
- issue_data = await handle_sentry_issue(http_client, auth_token, issue_id_or_url)
- return issue_data.to_prompt_result()
-
- @server.list_tools()
- async def handle_list_tools() -> list[types.Tool]:
- return [
- types.Tool(
- name="get_sentry_issue",
- description="""Retrieve and analyze a Sentry issue by ID or URL. Use this tool when you need to:
- - Investigate production errors and crashes
- - Access detailed stacktraces from Sentry
- - Analyze error patterns and frequencies
- - Get information about when issues first/last occurred
- - Review error counts and status""",
- inputSchema={
- "type": "object",
- "properties": {
- "issue_id_or_url": {
- "type": "string",
- "description": "Sentry issue ID or URL to analyze"
- }
- },
- "required": ["issue_id_or_url"]
- }
- )
- ]
-
- @server.call_tool()
- async def handle_call_tool(
- name: str, arguments: dict | None
- ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
- if name != "get_sentry_issue":
- raise ValueError(f"Unknown tool: {name}")
-
- if not arguments or "issue_id_or_url" not in arguments:
- raise ValueError("Missing issue_id_or_url argument")
-
- issue_data = await handle_sentry_issue(http_client, auth_token, arguments["issue_id_or_url"])
- return issue_data.to_tool_result()
-
- return server
-
-@click.command()
-@click.option(
- "--auth-token",
- envvar="SENTRY_TOKEN",
- required=True,
- help="Sentry authentication token",
-)
-def main(auth_token: str):
- async def _run():
- async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
- server = await serve(auth_token)
- await server.run(
- read_stream,
- write_stream,
- InitializationOptions(
- server_name="sentry",
- server_version="0.4.1",
- capabilities=server.get_capabilities(
- notification_options=NotificationOptions(),
- experimental_capabilities={},
- ),
- ),
- )
-
- asyncio.run(_run())
diff --git a/src/sentry/uv.lock b/src/sentry/uv.lock
deleted file mode 100644
index a9a8c1a6..00000000
--- a/src/sentry/uv.lock
+++ /dev/null
@@ -1,439 +0,0 @@
-version = 1
-requires-python = ">=3.10"
-
-[[package]]
-name = "annotated-types"
-version = "0.7.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
-]
-
-[[package]]
-name = "anyio"
-version = "4.6.2.post1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
- { name = "idna" },
- { name = "sniffio" },
- { name = "typing-extensions", marker = "python_full_version < '3.11'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 },
-]
-
-[[package]]
-name = "certifi"
-version = "2024.8.30"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 },
-]
-
-[[package]]
-name = "click"
-version = "8.1.7"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "colorama", marker = "platform_system == 'Windows'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 },
-]
-
-[[package]]
-name = "colorama"
-version = "0.4.6"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
-]
-
-[[package]]
-name = "exceptiongroup"
-version = "1.2.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
-]
-
-[[package]]
-name = "h11"
-version = "0.14.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
-]
-
-[[package]]
-name = "httpcore"
-version = "1.0.7"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "certifi" },
- { name = "h11" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
-]
-
-[[package]]
-name = "httpx"
-version = "0.28.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
- { name = "certifi" },
- { name = "httpcore" },
- { name = "idna" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/10/df/676b7cf674dd1bdc71a64ad393c89879f75e4a0ab8395165b498262ae106/httpx-0.28.0.tar.gz", hash = "sha256:0858d3bab51ba7e386637f22a61d8ccddaeec5f3fe4209da3a6168dbb91573e0", size = 141307 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551 },
-]
-
-[[package]]
-name = "httpx-sse"
-version = "0.4.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
-]
-
-[[package]]
-name = "idna"
-version = "3.10"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
-]
-
-[[package]]
-name = "iniconfig"
-version = "2.0.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 },
-]
-
-[[package]]
-name = "mcp"
-version = "1.0.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
- { name = "httpx" },
- { name = "httpx-sse" },
- { name = "pydantic" },
- { name = "sse-starlette" },
- { name = "starlette" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/97/de/a9ec0a1b6439f90ea59f89004bb2e7ec6890dfaeef809751d9e6577dca7e/mcp-1.0.0.tar.gz", hash = "sha256:dba51ce0b5c6a80e25576f606760c49a91ee90210fed805b530ca165d3bbc9b7", size = 82891 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/56/89/900c0c8445ec001d3725e475fc553b0feb2e8a51be018f3bb7de51e683db/mcp-1.0.0-py3-none-any.whl", hash = "sha256:bbe70ffa3341cd4da78b5eb504958355c68381fb29971471cea1e642a2af5b8a", size = 36361 },
-]
-
-[[package]]
-name = "mcp-server-sentry"
-version = "0.6.2"
-source = { editable = "." }
-dependencies = [
- { name = "mcp" },
-]
-
-[package.dev-dependencies]
-dev = [
- { name = "pyright" },
- { name = "pytest" },
- { name = "ruff" },
-]
-
-[package.metadata]
-requires-dist = [{ name = "mcp", specifier = ">=1.0.0" }]
-
-[package.metadata.requires-dev]
-dev = [
- { name = "pyright", specifier = ">=1.1.389" },
- { name = "pytest", specifier = ">=8.3.3" },
- { name = "ruff", specifier = ">=0.8.0" },
-]
-
-[[package]]
-name = "nodeenv"
-version = "1.9.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 },
-]
-
-[[package]]
-name = "packaging"
-version = "24.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
-]
-
-[[package]]
-name = "pluggy"
-version = "1.5.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 },
-]
-
-[[package]]
-name = "pydantic"
-version = "2.10.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "annotated-types" },
- { name = "pydantic-core" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/41/86/a03390cb12cf64e2a8df07c267f3eb8d5035e0f9a04bb20fb79403d2a00e/pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa", size = 785401 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364 },
-]
-
-[[package]]
-name = "pydantic-core"
-version = "2.27.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/a6/9f/7de1f19b6aea45aeb441838782d68352e71bfa98ee6fa048d5041991b33e/pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235", size = 412785 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/6e/ce/60fd96895c09738648c83f3f00f595c807cb6735c70d3306b548cc96dd49/pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a", size = 1897984 },
- { url = "https://files.pythonhosted.org/packages/fd/b9/84623d6b6be98cc209b06687d9bca5a7b966ffed008d15225dd0d20cce2e/pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b", size = 1807491 },
- { url = "https://files.pythonhosted.org/packages/01/72/59a70165eabbc93b1111d42df9ca016a4aa109409db04304829377947028/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278", size = 1831953 },
- { url = "https://files.pythonhosted.org/packages/7c/0c/24841136476adafd26f94b45bb718a78cb0500bd7b4f8d667b67c29d7b0d/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05", size = 1856071 },
- { url = "https://files.pythonhosted.org/packages/53/5e/c32957a09cceb2af10d7642df45d1e3dbd8596061f700eac93b801de53c0/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4", size = 2038439 },
- { url = "https://files.pythonhosted.org/packages/e4/8f/979ab3eccd118b638cd6d8f980fea8794f45018255a36044dea40fe579d4/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f", size = 2787416 },
- { url = "https://files.pythonhosted.org/packages/02/1d/00f2e4626565b3b6d3690dab4d4fe1a26edd6a20e53749eb21ca892ef2df/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08", size = 2134548 },
- { url = "https://files.pythonhosted.org/packages/9d/46/3112621204128b90898adc2e721a3cd6cf5626504178d6f32c33b5a43b79/pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6", size = 1989882 },
- { url = "https://files.pythonhosted.org/packages/49/ec/557dd4ff5287ffffdf16a31d08d723de6762bb1b691879dc4423392309bc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807", size = 1995829 },
- { url = "https://files.pythonhosted.org/packages/6e/b2/610dbeb74d8d43921a7234555e4c091cb050a2bdb8cfea86d07791ce01c5/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c", size = 2091257 },
- { url = "https://files.pythonhosted.org/packages/8c/7f/4bf8e9d26a9118521c80b229291fa9558a07cdd9a968ec2d5c1026f14fbc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206", size = 2143894 },
- { url = "https://files.pythonhosted.org/packages/1f/1c/875ac7139c958f4390f23656fe696d1acc8edf45fb81e4831960f12cd6e4/pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c", size = 1816081 },
- { url = "https://files.pythonhosted.org/packages/d7/41/55a117acaeda25ceae51030b518032934f251b1dac3704a53781383e3491/pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17", size = 1981109 },
- { url = "https://files.pythonhosted.org/packages/27/39/46fe47f2ad4746b478ba89c561cafe4428e02b3573df882334bd2964f9cb/pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8", size = 1895553 },
- { url = "https://files.pythonhosted.org/packages/1c/00/0804e84a78b7fdb394fff4c4f429815a10e5e0993e6ae0e0b27dd20379ee/pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330", size = 1807220 },
- { url = "https://files.pythonhosted.org/packages/01/de/df51b3bac9820d38371f5a261020f505025df732ce566c2a2e7970b84c8c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52", size = 1829727 },
- { url = "https://files.pythonhosted.org/packages/5f/d9/c01d19da8f9e9fbdb2bf99f8358d145a312590374d0dc9dd8dbe484a9cde/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4", size = 1854282 },
- { url = "https://files.pythonhosted.org/packages/5f/84/7db66eb12a0dc88c006abd6f3cbbf4232d26adfd827a28638c540d8f871d/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c", size = 2037437 },
- { url = "https://files.pythonhosted.org/packages/34/ac/a2537958db8299fbabed81167d58cc1506049dba4163433524e06a7d9f4c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de", size = 2780899 },
- { url = "https://files.pythonhosted.org/packages/4a/c1/3e38cd777ef832c4fdce11d204592e135ddeedb6c6f525478a53d1c7d3e5/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025", size = 2135022 },
- { url = "https://files.pythonhosted.org/packages/7a/69/b9952829f80fd555fe04340539d90e000a146f2a003d3fcd1e7077c06c71/pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e", size = 1987969 },
- { url = "https://files.pythonhosted.org/packages/05/72/257b5824d7988af43460c4e22b63932ed651fe98804cc2793068de7ec554/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919", size = 1994625 },
- { url = "https://files.pythonhosted.org/packages/73/c3/78ed6b7f3278a36589bcdd01243189ade7fc9b26852844938b4d7693895b/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c", size = 2090089 },
- { url = "https://files.pythonhosted.org/packages/8d/c8/b4139b2f78579960353c4cd987e035108c93a78371bb19ba0dc1ac3b3220/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc", size = 2142496 },
- { url = "https://files.pythonhosted.org/packages/3e/f8/171a03e97eb36c0b51981efe0f78460554a1d8311773d3d30e20c005164e/pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9", size = 1811758 },
- { url = "https://files.pythonhosted.org/packages/6a/fe/4e0e63c418c1c76e33974a05266e5633e879d4061f9533b1706a86f77d5b/pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5", size = 1980864 },
- { url = "https://files.pythonhosted.org/packages/50/fc/93f7238a514c155a8ec02fc7ac6376177d449848115e4519b853820436c5/pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89", size = 1864327 },
- { url = "https://files.pythonhosted.org/packages/be/51/2e9b3788feb2aebff2aa9dfbf060ec739b38c05c46847601134cc1fed2ea/pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f", size = 1895239 },
- { url = "https://files.pythonhosted.org/packages/7b/9e/f8063952e4a7d0127f5d1181addef9377505dcce3be224263b25c4f0bfd9/pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02", size = 1805070 },
- { url = "https://files.pythonhosted.org/packages/2c/9d/e1d6c4561d262b52e41b17a7ef8301e2ba80b61e32e94520271029feb5d8/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c", size = 1828096 },
- { url = "https://files.pythonhosted.org/packages/be/65/80ff46de4266560baa4332ae3181fffc4488ea7d37282da1a62d10ab89a4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac", size = 1857708 },
- { url = "https://files.pythonhosted.org/packages/d5/ca/3370074ad758b04d9562b12ecdb088597f4d9d13893a48a583fb47682cdf/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb", size = 2037751 },
- { url = "https://files.pythonhosted.org/packages/b1/e2/4ab72d93367194317b99d051947c071aef6e3eb95f7553eaa4208ecf9ba4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529", size = 2733863 },
- { url = "https://files.pythonhosted.org/packages/8a/c6/8ae0831bf77f356bb73127ce5a95fe115b10f820ea480abbd72d3cc7ccf3/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35", size = 2161161 },
- { url = "https://files.pythonhosted.org/packages/f1/f4/b2fe73241da2429400fc27ddeaa43e35562f96cf5b67499b2de52b528cad/pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089", size = 1993294 },
- { url = "https://files.pythonhosted.org/packages/77/29/4bb008823a7f4cc05828198153f9753b3bd4c104d93b8e0b1bfe4e187540/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381", size = 2001468 },
- { url = "https://files.pythonhosted.org/packages/f2/a9/0eaceeba41b9fad851a4107e0cf999a34ae8f0d0d1f829e2574f3d8897b0/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb", size = 2091413 },
- { url = "https://files.pythonhosted.org/packages/d8/36/eb8697729725bc610fd73940f0d860d791dc2ad557faaefcbb3edbd2b349/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae", size = 2154735 },
- { url = "https://files.pythonhosted.org/packages/52/e5/4f0fbd5c5995cc70d3afed1b5c754055bb67908f55b5cb8000f7112749bf/pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c", size = 1833633 },
- { url = "https://files.pythonhosted.org/packages/ee/f2/c61486eee27cae5ac781305658779b4a6b45f9cc9d02c90cb21b940e82cc/pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16", size = 1986973 },
- { url = "https://files.pythonhosted.org/packages/df/a6/e3f12ff25f250b02f7c51be89a294689d175ac76e1096c32bf278f29ca1e/pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e", size = 1883215 },
- { url = "https://files.pythonhosted.org/packages/0f/d6/91cb99a3c59d7b072bded9959fbeab0a9613d5a4935773c0801f1764c156/pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073", size = 1895033 },
- { url = "https://files.pythonhosted.org/packages/07/42/d35033f81a28b27dedcade9e967e8a40981a765795c9ebae2045bcef05d3/pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08", size = 1807542 },
- { url = "https://files.pythonhosted.org/packages/41/c2/491b59e222ec7e72236e512108ecad532c7f4391a14e971c963f624f7569/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf", size = 1827854 },
- { url = "https://files.pythonhosted.org/packages/e3/f3/363652651779113189cefdbbb619b7b07b7a67ebb6840325117cc8cc3460/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737", size = 1857389 },
- { url = "https://files.pythonhosted.org/packages/5f/97/be804aed6b479af5a945daec7538d8bf358d668bdadde4c7888a2506bdfb/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2", size = 2037934 },
- { url = "https://files.pythonhosted.org/packages/42/01/295f0bd4abf58902917e342ddfe5f76cf66ffabfc57c2e23c7681a1a1197/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107", size = 2735176 },
- { url = "https://files.pythonhosted.org/packages/9d/a0/cd8e9c940ead89cc37812a1a9f310fef59ba2f0b22b4e417d84ab09fa970/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51", size = 2160720 },
- { url = "https://files.pythonhosted.org/packages/73/ae/9d0980e286627e0aeca4c352a60bd760331622c12d576e5ea4441ac7e15e/pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a", size = 1992972 },
- { url = "https://files.pythonhosted.org/packages/bf/ba/ae4480bc0292d54b85cfb954e9d6bd226982949f8316338677d56541b85f/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc", size = 2001477 },
- { url = "https://files.pythonhosted.org/packages/55/b7/e26adf48c2f943092ce54ae14c3c08d0d221ad34ce80b18a50de8ed2cba8/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960", size = 2091186 },
- { url = "https://files.pythonhosted.org/packages/ba/cc/8491fff5b608b3862eb36e7d29d36a1af1c945463ca4c5040bf46cc73f40/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23", size = 2154429 },
- { url = "https://files.pythonhosted.org/packages/78/d8/c080592d80edd3441ab7f88f865f51dae94a157fc64283c680e9f32cf6da/pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05", size = 1833713 },
- { url = "https://files.pythonhosted.org/packages/83/84/5ab82a9ee2538ac95a66e51f6838d6aba6e0a03a42aa185ad2fe404a4e8f/pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337", size = 1987897 },
- { url = "https://files.pythonhosted.org/packages/df/c3/b15fb833926d91d982fde29c0624c9f225da743c7af801dace0d4e187e71/pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5", size = 1882983 },
- { url = "https://files.pythonhosted.org/packages/7c/60/e5eb2d462595ba1f622edbe7b1d19531e510c05c405f0b87c80c1e89d5b1/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6", size = 1894016 },
- { url = "https://files.pythonhosted.org/packages/61/20/da7059855225038c1c4326a840908cc7ca72c7198cb6addb8b92ec81c1d6/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676", size = 1771648 },
- { url = "https://files.pythonhosted.org/packages/8f/fc/5485cf0b0bb38da31d1d292160a4d123b5977841ddc1122c671a30b76cfd/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d", size = 1826929 },
- { url = "https://files.pythonhosted.org/packages/a1/ff/fb1284a210e13a5f34c639efc54d51da136074ffbe25ec0c279cf9fbb1c4/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c", size = 1980591 },
- { url = "https://files.pythonhosted.org/packages/f1/14/77c1887a182d05af74f6aeac7b740da3a74155d3093ccc7ee10b900cc6b5/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27", size = 1981326 },
- { url = "https://files.pythonhosted.org/packages/06/aa/6f1b2747f811a9c66b5ef39d7f02fbb200479784c75e98290d70004b1253/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f", size = 1989205 },
- { url = "https://files.pythonhosted.org/packages/7a/d2/8ce2b074d6835f3c88d85f6d8a399790043e9fdb3d0e43455e72d19df8cc/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed", size = 2079616 },
- { url = "https://files.pythonhosted.org/packages/65/71/af01033d4e58484c3db1e5d13e751ba5e3d6b87cc3368533df4c50932c8b/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f", size = 2133265 },
- { url = "https://files.pythonhosted.org/packages/33/72/f881b5e18fbb67cf2fb4ab253660de3c6899dbb2dba409d0b757e3559e3d/pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c", size = 2001864 },
-]
-
-[[package]]
-name = "pyright"
-version = "1.1.389"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "nodeenv" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 },
-]
-
-[[package]]
-name = "pytest"
-version = "8.3.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "colorama", marker = "sys_platform == 'win32'" },
- { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
- { name = "iniconfig" },
- { name = "packaging" },
- { name = "pluggy" },
- { name = "tomli", marker = "python_full_version < '3.11'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 },
-]
-
-[[package]]
-name = "ruff"
-version = "0.8.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/95/d0/8ff5b189d125f4260f2255d143bf2fa413b69c2610c405ace7a0a8ec81ec/ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f", size = 3313222 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a2/d6/1a6314e568db88acdbb5121ed53e2c52cebf3720d3437a76f82f923bf171/ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5", size = 10532605 },
- { url = "https://files.pythonhosted.org/packages/89/a8/a957a8812e31facffb6a26a30be0b5b4af000a6e30c7d43a22a5232a3398/ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087", size = 10278243 },
- { url = "https://files.pythonhosted.org/packages/a8/23/9db40fa19c453fabf94f7a35c61c58f20e8200b4734a20839515a19da790/ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209", size = 9917739 },
- { url = "https://files.pythonhosted.org/packages/e2/a0/6ee2d949835d5701d832fc5acd05c0bfdad5e89cfdd074a171411f5ccad5/ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871", size = 10779153 },
- { url = "https://files.pythonhosted.org/packages/7a/25/9c11dca9404ef1eb24833f780146236131a3c7941de394bc356912ef1041/ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1", size = 10304387 },
- { url = "https://files.pythonhosted.org/packages/c8/b9/84c323780db1b06feae603a707d82dbbd85955c8c917738571c65d7d5aff/ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5", size = 11360351 },
- { url = "https://files.pythonhosted.org/packages/6b/e1/9d4bbb2ace7aad14ded20e4674a48cda5b902aed7a1b14e6b028067060c4/ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d", size = 12022879 },
- { url = "https://files.pythonhosted.org/packages/75/28/752ff6120c0e7f9981bc4bc275d540c7f36db1379ba9db9142f69c88db21/ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26", size = 11610354 },
- { url = "https://files.pythonhosted.org/packages/ba/8c/967b61c2cc8ebd1df877607fbe462bc1e1220b4a30ae3352648aec8c24bd/ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1", size = 12813976 },
- { url = "https://files.pythonhosted.org/packages/7f/29/e059f945d6bd2d90213387b8c360187f2fefc989ddcee6bbf3c241329b92/ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c", size = 11154564 },
- { url = "https://files.pythonhosted.org/packages/55/47/cbd05e5a62f3fb4c072bc65c1e8fd709924cad1c7ec60a1000d1e4ee8307/ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa", size = 10760604 },
- { url = "https://files.pythonhosted.org/packages/bb/ee/4c3981c47147c72647a198a94202633130cfda0fc95cd863a553b6f65c6a/ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540", size = 10391071 },
- { url = "https://files.pythonhosted.org/packages/6b/e6/083eb61300214590b188616a8ac6ae1ef5730a0974240fb4bec9c17de78b/ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9", size = 10896657 },
- { url = "https://files.pythonhosted.org/packages/77/bd/aacdb8285d10f1b943dbeb818968efca35459afc29f66ae3bd4596fbf954/ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5", size = 11228362 },
- { url = "https://files.pythonhosted.org/packages/39/72/fcb7ad41947f38b4eaa702aca0a361af0e9c2bf671d7fd964480670c297e/ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790", size = 8803476 },
- { url = "https://files.pythonhosted.org/packages/e4/ea/cae9aeb0f4822c44651c8407baacdb2e5b4dcd7b31a84e1c5df33aa2cc20/ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6", size = 9614463 },
- { url = "https://files.pythonhosted.org/packages/eb/76/fbb4bd23dfb48fa7758d35b744413b650a9fd2ddd93bca77e30376864414/ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737", size = 8959621 },
-]
-
-[[package]]
-name = "sniffio"
-version = "1.3.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
-]
-
-[[package]]
-name = "sse-starlette"
-version = "2.1.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
- { name = "starlette" },
- { name = "uvicorn" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/72/fc/56ab9f116b2133521f532fce8d03194cf04dcac25f583cf3d839be4c0496/sse_starlette-2.1.3.tar.gz", hash = "sha256:9cd27eb35319e1414e3d2558ee7414487f9529ce3b3cf9b21434fd110e017169", size = 19678 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/52/aa/36b271bc4fa1d2796311ee7c7283a3a1c348bad426d37293609ca4300eef/sse_starlette-2.1.3-py3-none-any.whl", hash = "sha256:8ec846438b4665b9e8c560fcdea6bc8081a3abf7942faa95e5a744999d219772", size = 9383 },
-]
-
-[[package]]
-name = "starlette"
-version = "0.41.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225 },
-]
-
-[[package]]
-name = "tomli"
-version = "2.2.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 },
- { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 },
- { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 },
- { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 },
- { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 },
- { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 },
- { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 },
- { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 },
- { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 },
- { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 },
- { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 },
- { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 },
- { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 },
- { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 },
- { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 },
- { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 },
- { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 },
- { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 },
- { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 },
- { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 },
- { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 },
- { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 },
- { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 },
- { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 },
- { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 },
- { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 },
- { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 },
- { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 },
- { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 },
- { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 },
- { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 },
-]
-
-[[package]]
-name = "typing-extensions"
-version = "4.12.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
-]
-
-[[package]]
-name = "uvicorn"
-version = "0.32.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "click" },
- { name = "h11" },
- { name = "typing-extensions", marker = "python_full_version < '3.11'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/6a/3c/21dba3e7d76138725ef307e3d7ddd29b763119b3aa459d02cc05fefcff75/uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175", size = 77630 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/50/c1/2d27b0a15826c2b71dcf6e2f5402181ef85acf439617bb2f1453125ce1f3/uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e", size = 63828 },
-]
diff --git a/src/sequentialthinking/README.md b/src/sequentialthinking/README.md
index 3914d8ea..fd90b9b1 100644
--- a/src/sequentialthinking/README.md
+++ b/src/sequentialthinking/README.md
@@ -1,4 +1,3 @@
-
# Sequential Thinking MCP Server
An MCP server implementation that provides a tool for dynamic and reflective problem-solving through a structured thinking process.
@@ -78,6 +77,61 @@ Add this to your `claude_desktop_config.json`:
}
```
+To disable logging of thought information set env var: `DISABLE_THOUGHT_LOGGING` to `true`.
+Comment
+
+### Usage with VS Code
+
+For quick installation, click one of the installation buttons below...
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=sequentialthinking&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-sequential-thinking%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=sequentialthinking&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-sequential-thinking%22%5D%7D&quality=insiders)
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=sequentialthinking&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22--rm%22%2C%22-i%22%2C%22mcp%2Fsequentialthinking%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=sequentialthinking&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22--rm%22%2C%22-i%22%2C%22mcp%2Fsequentialthinking%22%5D%7D&quality=insiders)
+
+For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open Settings (JSON)`.
+
+Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
+
+> Note that the `mcp` key is not needed in the `.vscode/mcp.json` file.
+
+For NPX installation:
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "sequential-thinking": {
+ "command": "npx",
+ "args": [
+ "-y",
+ "@modelcontextprotocol/server-sequential-thinking"
+ ]
+ }
+ }
+ }
+}
+```
+
+For Docker installation:
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "sequential-thinking": {
+ "command": "docker",
+ "args": [
+ "run",
+ "--rm",
+ "-i",
+ "mcp/sequentialthinking"
+ ]
+ }
+ }
+ }
+}
+```
+
## Building
Docker:
diff --git a/src/sequentialthinking/index.ts b/src/sequentialthinking/index.ts
index c10301d7..bd486fdb 100644
--- a/src/sequentialthinking/index.ts
+++ b/src/sequentialthinking/index.ts
@@ -25,6 +25,11 @@ interface ThoughtData {
class SequentialThinkingServer {
private thoughtHistory: ThoughtData[] = [];
private branches: Record = {};
+ private disableThoughtLogging: boolean;
+
+ constructor() {
+ this.disableThoughtLogging = (process.env.DISABLE_THOUGHT_LOGGING || "").toLowerCase() === "true";
+ }
private validateThoughtData(input: unknown): ThoughtData {
const data = input as Record;
@@ -100,8 +105,10 @@ class SequentialThinkingServer {
this.branches[validatedInput.branchId].push(validatedInput);
}
- const formattedThought = this.formatThought(validatedInput);
- console.error(formattedThought);
+ if (!this.disableThoughtLogging) {
+ const formattedThought = this.formatThought(validatedInput);
+ console.error(formattedThought);
+ }
return {
content: [{
diff --git a/src/slack/Dockerfile b/src/slack/Dockerfile
deleted file mode 100644
index 1f7efa46..00000000
--- a/src/slack/Dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM node:22.12-alpine AS builder
-
-# Must be entire project because `prepare` script is run during `npm install` and requires all files.
-COPY src/slack /app
-COPY tsconfig.json /tsconfig.json
-
-WORKDIR /app
-
-RUN --mount=type=cache,target=/root/.npm npm install
-
-RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
-
-FROM node:22-alpine AS release
-
-COPY --from=builder /app/dist /app/dist
-COPY --from=builder /app/package.json /app/package.json
-COPY --from=builder /app/package-lock.json /app/package-lock.json
-
-ENV NODE_ENV=production
-
-WORKDIR /app
-
-RUN npm ci --ignore-scripts --omit-dev
-
-ENTRYPOINT ["node", "dist/index.js"]
diff --git a/src/slack/README.md b/src/slack/README.md
deleted file mode 100644
index 61bec01f..00000000
--- a/src/slack/README.md
+++ /dev/null
@@ -1,166 +0,0 @@
-# Slack MCP Server
-
-MCP Server for the Slack API, enabling Claude to interact with Slack workspaces.
-
-## Tools
-
-1. `slack_list_channels`
- - List public or pre-defined channels in the workspace
- - Optional inputs:
- - `limit` (number, default: 100, max: 200): Maximum number of channels to return
- - `cursor` (string): Pagination cursor for next page
- - Returns: List of channels with their IDs and information
-
-2. `slack_post_message`
- - Post a new message to a Slack channel
- - Required inputs:
- - `channel_id` (string): The ID of the channel to post to
- - `text` (string): The message text to post
- - Returns: Message posting confirmation and timestamp
-
-3. `slack_reply_to_thread`
- - Reply to a specific message thread
- - Required inputs:
- - `channel_id` (string): The channel containing the thread
- - `thread_ts` (string): Timestamp of the parent message
- - `text` (string): The reply text
- - Returns: Reply confirmation and timestamp
-
-4. `slack_add_reaction`
- - Add an emoji reaction to a message
- - Required inputs:
- - `channel_id` (string): The channel containing the message
- - `timestamp` (string): Message timestamp to react to
- - `reaction` (string): Emoji name without colons
- - Returns: Reaction confirmation
-
-5. `slack_get_channel_history`
- - Get recent messages from a channel
- - Required inputs:
- - `channel_id` (string): The channel ID
- - Optional inputs:
- - `limit` (number, default: 10): Number of messages to retrieve
- - Returns: List of messages with their content and metadata
-
-6. `slack_get_thread_replies`
- - Get all replies in a message thread
- - Required inputs:
- - `channel_id` (string): The channel containing the thread
- - `thread_ts` (string): Timestamp of the parent message
- - Returns: List of replies with their content and metadata
-
-
-7. `slack_get_users`
- - Get list of workspace users with basic profile information
- - Optional inputs:
- - `cursor` (string): Pagination cursor for next page
- - `limit` (number, default: 100, max: 200): Maximum users to return
- - Returns: List of users with their basic profiles
-
-8. `slack_get_user_profile`
- - Get detailed profile information for a specific user
- - Required inputs:
- - `user_id` (string): The user's ID
- - Returns: Detailed user profile information
-
-## Setup
-
-1. Create a Slack App:
- - Visit the [Slack Apps page](https://api.slack.com/apps)
- - Click "Create New App"
- - Choose "From scratch"
- - Name your app and select your workspace
-
-2. Configure Bot Token Scopes:
- Navigate to "OAuth & Permissions" and add these scopes:
- - `channels:history` - View messages and other content in public channels
- - `channels:read` - View basic channel information
- - `chat:write` - Send messages as the app
- - `reactions:write` - Add emoji reactions to messages
- - `users:read` - View users and their basic information
-
-4. Install App to Workspace:
- - Click "Install to Workspace" and authorize the app
- - Save the "Bot User OAuth Token" that starts with `xoxb-`
-
-5. Get your Team ID (starts with a `T`) by following [this guidance](https://slack.com/help/articles/221769328-Locate-your-Slack-URL-or-ID#find-your-workspace-or-org-id)
-
-### Usage with Claude Desktop
-
-Add the following to your `claude_desktop_config.json`:
-
-#### npx
-
-```json
-{
- "mcpServers": {
- "slack": {
- "command": "npx",
- "args": [
- "-y",
- "@modelcontextprotocol/server-slack"
- ],
- "env": {
- "SLACK_BOT_TOKEN": "xoxb-your-bot-token",
- "SLACK_TEAM_ID": "T01234567",
- "SLACK_CHANNEL_IDS": "C01234567, C76543210"
- }
- }
- }
-}
-```
-
-#### docker
-
-```json
-{
- "mcpServers": {
- "slack": {
- "command": "docker",
- "args": [
- "run",
- "-i",
- "--rm",
- "-e",
- "SLACK_BOT_TOKEN",
- "-e",
- "SLACK_TEAM_ID",
- "-e",
- "SLACK_CHANNEL_IDS",
- "mcp/slack"
- ],
- "env": {
- "SLACK_BOT_TOKEN": "xoxb-your-bot-token",
- "SLACK_TEAM_ID": "T01234567",
- "SLACK_CHANNEL_IDS": "C01234567, C76543210"
- }
- }
- }
-}
-```
-
-### Environment Variables
-
-1. `SLACK_BOT_TOKEN`: Required. The Bot User OAuth Token starting with `xoxb-`.
-2. `SLACK_TEAM_ID`: Required. Your Slack workspace ID starting with `T`.
-3. `SLACK_CHANNEL_IDS`: Optional. Comma-separated list of channel IDs to limit channel access (e.g., "C01234567, C76543210"). If not set, all public channels will be listed.
-
-### Troubleshooting
-
-If you encounter permission errors, verify that:
-1. All required scopes are added to your Slack app
-2. The app is properly installed to your workspace
-3. The tokens and workspace ID are correctly copied to your configuration
-4. The app has been added to the channels it needs to access
-
-## Build
-
-Docker build:
-
-```bash
-docker build -t mcp/slack -f src/slack/Dockerfile .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/slack/index.ts b/src/slack/index.ts
deleted file mode 100644
index f2135b36..00000000
--- a/src/slack/index.ts
+++ /dev/null
@@ -1,582 +0,0 @@
-#!/usr/bin/env node
-import { Server } from "@modelcontextprotocol/sdk/server/index.js";
-import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
-import {
- CallToolRequest,
- CallToolRequestSchema,
- ListToolsRequestSchema,
- Tool,
-} from "@modelcontextprotocol/sdk/types.js";
-
-// Type definitions for tool arguments
-interface ListChannelsArgs {
- limit?: number;
- cursor?: string;
-}
-
-interface PostMessageArgs {
- channel_id: string;
- text: string;
-}
-
-interface ReplyToThreadArgs {
- channel_id: string;
- thread_ts: string;
- text: string;
-}
-
-interface AddReactionArgs {
- channel_id: string;
- timestamp: string;
- reaction: string;
-}
-
-interface GetChannelHistoryArgs {
- channel_id: string;
- limit?: number;
-}
-
-interface GetThreadRepliesArgs {
- channel_id: string;
- thread_ts: string;
-}
-
-interface GetUsersArgs {
- cursor?: string;
- limit?: number;
-}
-
-interface GetUserProfileArgs {
- user_id: string;
-}
-
-// Tool definitions
-const listChannelsTool: Tool = {
- name: "slack_list_channels",
- description: "List public or pre-defined channels in the workspace with pagination",
- inputSchema: {
- type: "object",
- properties: {
- limit: {
- type: "number",
- description:
- "Maximum number of channels to return (default 100, max 200)",
- default: 100,
- },
- cursor: {
- type: "string",
- description: "Pagination cursor for next page of results",
- },
- },
- },
-};
-
-const postMessageTool: Tool = {
- name: "slack_post_message",
- description: "Post a new message to a Slack channel",
- inputSchema: {
- type: "object",
- properties: {
- channel_id: {
- type: "string",
- description: "The ID of the channel to post to",
- },
- text: {
- type: "string",
- description: "The message text to post",
- },
- },
- required: ["channel_id", "text"],
- },
-};
-
-const replyToThreadTool: Tool = {
- name: "slack_reply_to_thread",
- description: "Reply to a specific message thread in Slack",
- inputSchema: {
- type: "object",
- properties: {
- channel_id: {
- type: "string",
- description: "The ID of the channel containing the thread",
- },
- thread_ts: {
- type: "string",
- description: "The timestamp of the parent message in the format '1234567890.123456'. Timestamps in the format without the period can be converted by adding the period such that 6 numbers come after it.",
- },
- text: {
- type: "string",
- description: "The reply text",
- },
- },
- required: ["channel_id", "thread_ts", "text"],
- },
-};
-
-const addReactionTool: Tool = {
- name: "slack_add_reaction",
- description: "Add a reaction emoji to a message",
- inputSchema: {
- type: "object",
- properties: {
- channel_id: {
- type: "string",
- description: "The ID of the channel containing the message",
- },
- timestamp: {
- type: "string",
- description: "The timestamp of the message to react to",
- },
- reaction: {
- type: "string",
- description: "The name of the emoji reaction (without ::)",
- },
- },
- required: ["channel_id", "timestamp", "reaction"],
- },
-};
-
-const getChannelHistoryTool: Tool = {
- name: "slack_get_channel_history",
- description: "Get recent messages from a channel",
- inputSchema: {
- type: "object",
- properties: {
- channel_id: {
- type: "string",
- description: "The ID of the channel",
- },
- limit: {
- type: "number",
- description: "Number of messages to retrieve (default 10)",
- default: 10,
- },
- },
- required: ["channel_id"],
- },
-};
-
-const getThreadRepliesTool: Tool = {
- name: "slack_get_thread_replies",
- description: "Get all replies in a message thread",
- inputSchema: {
- type: "object",
- properties: {
- channel_id: {
- type: "string",
- description: "The ID of the channel containing the thread",
- },
- thread_ts: {
- type: "string",
- description: "The timestamp of the parent message in the format '1234567890.123456'. Timestamps in the format without the period can be converted by adding the period such that 6 numbers come after it.",
- },
- },
- required: ["channel_id", "thread_ts"],
- },
-};
-
-const getUsersTool: Tool = {
- name: "slack_get_users",
- description:
- "Get a list of all users in the workspace with their basic profile information",
- inputSchema: {
- type: "object",
- properties: {
- cursor: {
- type: "string",
- description: "Pagination cursor for next page of results",
- },
- limit: {
- type: "number",
- description: "Maximum number of users to return (default 100, max 200)",
- default: 100,
- },
- },
- },
-};
-
-const getUserProfileTool: Tool = {
- name: "slack_get_user_profile",
- description: "Get detailed profile information for a specific user",
- inputSchema: {
- type: "object",
- properties: {
- user_id: {
- type: "string",
- description: "The ID of the user",
- },
- },
- required: ["user_id"],
- },
-};
-
-class SlackClient {
- private botHeaders: { Authorization: string; "Content-Type": string };
-
- constructor(botToken: string) {
- this.botHeaders = {
- Authorization: `Bearer ${botToken}`,
- "Content-Type": "application/json",
- };
- }
-
- async getChannels(limit: number = 100, cursor?: string): Promise {
- const predefinedChannelIds = process.env.SLACK_CHANNEL_IDS;
- if (!predefinedChannelIds) {
- const params = new URLSearchParams({
- types: "public_channel",
- exclude_archived: "true",
- limit: Math.min(limit, 200).toString(),
- team_id: process.env.SLACK_TEAM_ID!,
- });
-
- if (cursor) {
- params.append("cursor", cursor);
- }
-
- const response = await fetch(
- `https://slack.com/api/conversations.list?${params}`,
- { headers: this.botHeaders },
- );
-
- return response.json();
- }
-
- const predefinedChannelIdsArray = predefinedChannelIds.split(",").map((id: string) => id.trim());
- const channels = [];
-
- for (const channelId of predefinedChannelIdsArray) {
- const params = new URLSearchParams({
- channel: channelId,
- });
-
- const response = await fetch(
- `https://slack.com/api/conversations.info?${params}`,
- { headers: this.botHeaders }
- );
- const data = await response.json();
-
- if (data.ok && data.channel && !data.channel.is_archived) {
- channels.push(data.channel);
- }
- }
-
- return {
- ok: true,
- channels: channels,
- response_metadata: { next_cursor: "" },
- };
- }
-
- async postMessage(channel_id: string, text: string): Promise {
- const response = await fetch("https://slack.com/api/chat.postMessage", {
- method: "POST",
- headers: this.botHeaders,
- body: JSON.stringify({
- channel: channel_id,
- text: text,
- }),
- });
-
- return response.json();
- }
-
- async postReply(
- channel_id: string,
- thread_ts: string,
- text: string,
- ): Promise {
- const response = await fetch("https://slack.com/api/chat.postMessage", {
- method: "POST",
- headers: this.botHeaders,
- body: JSON.stringify({
- channel: channel_id,
- thread_ts: thread_ts,
- text: text,
- }),
- });
-
- return response.json();
- }
-
- async addReaction(
- channel_id: string,
- timestamp: string,
- reaction: string,
- ): Promise {
- const response = await fetch("https://slack.com/api/reactions.add", {
- method: "POST",
- headers: this.botHeaders,
- body: JSON.stringify({
- channel: channel_id,
- timestamp: timestamp,
- name: reaction,
- }),
- });
-
- return response.json();
- }
-
- async getChannelHistory(
- channel_id: string,
- limit: number = 10,
- ): Promise {
- const params = new URLSearchParams({
- channel: channel_id,
- limit: limit.toString(),
- });
-
- const response = await fetch(
- `https://slack.com/api/conversations.history?${params}`,
- { headers: this.botHeaders },
- );
-
- return response.json();
- }
-
- async getThreadReplies(channel_id: string, thread_ts: string): Promise {
- const params = new URLSearchParams({
- channel: channel_id,
- ts: thread_ts,
- });
-
- const response = await fetch(
- `https://slack.com/api/conversations.replies?${params}`,
- { headers: this.botHeaders },
- );
-
- return response.json();
- }
-
- async getUsers(limit: number = 100, cursor?: string): Promise {
- const params = new URLSearchParams({
- limit: Math.min(limit, 200).toString(),
- team_id: process.env.SLACK_TEAM_ID!,
- });
-
- if (cursor) {
- params.append("cursor", cursor);
- }
-
- const response = await fetch(`https://slack.com/api/users.list?${params}`, {
- headers: this.botHeaders,
- });
-
- return response.json();
- }
-
- async getUserProfile(user_id: string): Promise {
- const params = new URLSearchParams({
- user: user_id,
- include_labels: "true",
- });
-
- const response = await fetch(
- `https://slack.com/api/users.profile.get?${params}`,
- { headers: this.botHeaders },
- );
-
- return response.json();
- }
-}
-
-async function main() {
- const botToken = process.env.SLACK_BOT_TOKEN;
- const teamId = process.env.SLACK_TEAM_ID;
-
- if (!botToken || !teamId) {
- console.error(
- "Please set SLACK_BOT_TOKEN and SLACK_TEAM_ID environment variables",
- );
- process.exit(1);
- }
-
- console.error("Starting Slack MCP Server...");
- const server = new Server(
- {
- name: "Slack MCP Server",
- version: "1.0.0",
- },
- {
- capabilities: {
- tools: {},
- },
- },
- );
-
- const slackClient = new SlackClient(botToken);
-
- server.setRequestHandler(
- CallToolRequestSchema,
- async (request: CallToolRequest) => {
- console.error("Received CallToolRequest:", request);
- try {
- if (!request.params.arguments) {
- throw new Error("No arguments provided");
- }
-
- switch (request.params.name) {
- case "slack_list_channels": {
- const args = request.params
- .arguments as unknown as ListChannelsArgs;
- const response = await slackClient.getChannels(
- args.limit,
- args.cursor,
- );
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- case "slack_post_message": {
- const args = request.params.arguments as unknown as PostMessageArgs;
- if (!args.channel_id || !args.text) {
- throw new Error(
- "Missing required arguments: channel_id and text",
- );
- }
- const response = await slackClient.postMessage(
- args.channel_id,
- args.text,
- );
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- case "slack_reply_to_thread": {
- const args = request.params
- .arguments as unknown as ReplyToThreadArgs;
- if (!args.channel_id || !args.thread_ts || !args.text) {
- throw new Error(
- "Missing required arguments: channel_id, thread_ts, and text",
- );
- }
- const response = await slackClient.postReply(
- args.channel_id,
- args.thread_ts,
- args.text,
- );
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- case "slack_add_reaction": {
- const args = request.params.arguments as unknown as AddReactionArgs;
- if (!args.channel_id || !args.timestamp || !args.reaction) {
- throw new Error(
- "Missing required arguments: channel_id, timestamp, and reaction",
- );
- }
- const response = await slackClient.addReaction(
- args.channel_id,
- args.timestamp,
- args.reaction,
- );
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- case "slack_get_channel_history": {
- const args = request.params
- .arguments as unknown as GetChannelHistoryArgs;
- if (!args.channel_id) {
- throw new Error("Missing required argument: channel_id");
- }
- const response = await slackClient.getChannelHistory(
- args.channel_id,
- args.limit,
- );
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- case "slack_get_thread_replies": {
- const args = request.params
- .arguments as unknown as GetThreadRepliesArgs;
- if (!args.channel_id || !args.thread_ts) {
- throw new Error(
- "Missing required arguments: channel_id and thread_ts",
- );
- }
- const response = await slackClient.getThreadReplies(
- args.channel_id,
- args.thread_ts,
- );
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- case "slack_get_users": {
- const args = request.params.arguments as unknown as GetUsersArgs;
- const response = await slackClient.getUsers(
- args.limit,
- args.cursor,
- );
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- case "slack_get_user_profile": {
- const args = request.params
- .arguments as unknown as GetUserProfileArgs;
- if (!args.user_id) {
- throw new Error("Missing required argument: user_id");
- }
- const response = await slackClient.getUserProfile(args.user_id);
- return {
- content: [{ type: "text", text: JSON.stringify(response) }],
- };
- }
-
- default:
- throw new Error(`Unknown tool: ${request.params.name}`);
- }
- } catch (error) {
- console.error("Error executing tool:", error);
- return {
- content: [
- {
- type: "text",
- text: JSON.stringify({
- error: error instanceof Error ? error.message : String(error),
- }),
- },
- ],
- };
- }
- },
- );
-
- server.setRequestHandler(ListToolsRequestSchema, async () => {
- console.error("Received ListToolsRequest");
- return {
- tools: [
- listChannelsTool,
- postMessageTool,
- replyToThreadTool,
- addReactionTool,
- getChannelHistoryTool,
- getThreadRepliesTool,
- getUsersTool,
- getUserProfileTool,
- ],
- };
- });
-
- const transport = new StdioServerTransport();
- console.error("Connecting server to transport...");
- await server.connect(transport);
-
- console.error("Slack MCP Server running on stdio");
-}
-
-main().catch((error) => {
- console.error("Fatal error in main():", error);
- process.exit(1);
-});
diff --git a/src/slack/package.json b/src/slack/package.json
deleted file mode 100644
index 337b9db0..00000000
--- a/src/slack/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-slack",
- "version": "0.6.2",
- "description": "MCP server for interacting with Slack",
- "license": "MIT",
- "author": "Anthropic, PBC (https://anthropic.com)",
- "homepage": "https://modelcontextprotocol.io",
- "bugs": "https://github.com/modelcontextprotocol/servers/issues",
- "type": "module",
- "bin": {
- "mcp-server-slack": "dist/index.js"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "build": "tsc && shx chmod +x dist/*.js",
- "prepare": "npm run build",
- "watch": "tsc --watch"
- },
- "dependencies": {
- "@modelcontextprotocol/sdk": "1.0.1"
- },
- "devDependencies": {
- "@types/node": "^22",
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
-}
\ No newline at end of file
diff --git a/src/slack/tsconfig.json b/src/slack/tsconfig.json
deleted file mode 100644
index 4d33cae1..00000000
--- a/src/slack/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "."
- },
- "include": [
- "./**/*.ts"
- ]
- }
-
\ No newline at end of file
diff --git a/src/sqlite/.python-version b/src/sqlite/.python-version
deleted file mode 100644
index c8cfe395..00000000
--- a/src/sqlite/.python-version
+++ /dev/null
@@ -1 +0,0 @@
-3.10
diff --git a/src/sqlite/Dockerfile b/src/sqlite/Dockerfile
deleted file mode 100644
index 2edc34b0..00000000
--- a/src/sqlite/Dockerfile
+++ /dev/null
@@ -1,37 +0,0 @@
-# Use a Python image with uv pre-installed
-FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS uv
-
-# Install the project into `/app`
-WORKDIR /app
-
-# Enable bytecode compilation
-ENV UV_COMPILE_BYTECODE=1
-
-# Copy from the cache instead of linking since it's a mounted volume
-ENV UV_LINK_MODE=copy
-
-# Install the project's dependencies using the lockfile and settings
-RUN --mount=type=cache,target=/root/.cache/uv \
- --mount=type=bind,source=uv.lock,target=uv.lock \
- --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
- uv sync --frozen --no-install-project --no-dev --no-editable
-
-# Then, add the rest of the project source code and install it
-# Installing separately from its dependencies allows optimal layer caching
-ADD . /app
-RUN --mount=type=cache,target=/root/.cache/uv \
- uv sync --frozen --no-dev --no-editable
-
-FROM python:3.12-slim-bookworm
-
-WORKDIR /app
-
-COPY --from=uv /root/.local /root/.local
-COPY --from=uv --chown=app:app /app/.venv /app/.venv
-
-# Place executables in the environment at the front of the path
-ENV PATH="/app/.venv/bin:$PATH"
-
-# when running the container, add --db-path and a bind mount to the host's db file
-ENTRYPOINT ["mcp-server-sqlite"]
-
diff --git a/src/sqlite/README.md b/src/sqlite/README.md
deleted file mode 100644
index e194c6bf..00000000
--- a/src/sqlite/README.md
+++ /dev/null
@@ -1,116 +0,0 @@
-# SQLite MCP Server
-
-## Overview
-A Model Context Protocol (MCP) server implementation that provides database interaction and business intelligence capabilities through SQLite. This server enables running SQL queries, analyzing business data, and automatically generating business insight memos.
-
-## Components
-
-### Resources
-The server exposes a single dynamic resource:
-- `memo://insights`: A continuously updated business insights memo that aggregates discovered insights during analysis
- - Auto-updates as new insights are discovered via the append-insight tool
-
-### Prompts
-The server provides a demonstration prompt:
-- `mcp-demo`: Interactive prompt that guides users through database operations
- - Required argument: `topic` - The business domain to analyze
- - Generates appropriate database schemas and sample data
- - Guides users through analysis and insight generation
- - Integrates with the business insights memo
-
-### Tools
-The server offers six core tools:
-
-#### Query Tools
-- `read_query`
- - Execute SELECT queries to read data from the database
- - Input:
- - `query` (string): The SELECT SQL query to execute
- - Returns: Query results as array of objects
-
-- `write_query`
- - Execute INSERT, UPDATE, or DELETE queries
- - Input:
- - `query` (string): The SQL modification query
- - Returns: `{ affected_rows: number }`
-
-- `create_table`
- - Create new tables in the database
- - Input:
- - `query` (string): CREATE TABLE SQL statement
- - Returns: Confirmation of table creation
-
-#### Schema Tools
-- `list_tables`
- - Get a list of all tables in the database
- - No input required
- - Returns: Array of table names
-
-- `describe-table`
- - View schema information for a specific table
- - Input:
- - `table_name` (string): Name of table to describe
- - Returns: Array of column definitions with names and types
-
-#### Analysis Tools
-- `append_insight`
- - Add new business insights to the memo resource
- - Input:
- - `insight` (string): Business insight discovered from data analysis
- - Returns: Confirmation of insight addition
- - Triggers update of memo://insights resource
-
-
-## Usage with Claude Desktop
-
-### uv
-
-```bash
-# Add the server to your claude_desktop_config.json
-"mcpServers": {
- "sqlite": {
- "command": "uv",
- "args": [
- "--directory",
- "parent_of_servers_repo/servers/src/sqlite",
- "run",
- "mcp-server-sqlite",
- "--db-path",
- "~/test.db"
- ]
- }
-}
-```
-
-### Docker
-
-```json
-# Add the server to your claude_desktop_config.json
-"mcpServers": {
- "sqlite": {
- "command": "docker",
- "args": [
- "run",
- "--rm",
- "-i",
- "-v",
- "mcp-test:/mcp",
- "mcp/sqlite",
- "--db-path",
- "/mcp/test.db"
- ]
- }
-}
-```
-
-## Building
-
-Docker:
-
-```bash
-docker build -t mcp/sqlite .
-```
-
-## License
-
-This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
diff --git a/src/sqlite/pyproject.toml b/src/sqlite/pyproject.toml
deleted file mode 100644
index 241ad0e2..00000000
--- a/src/sqlite/pyproject.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[project]
-name = "mcp-server-sqlite"
-version = "0.6.2"
-description = "A simple SQLite MCP server"
-readme = "README.md"
-requires-python = ">=3.10"
-dependencies = ["mcp>=1.0.0"]
-
-[build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
-
-[tool.uv]
-dev-dependencies = ["pyright>=1.1.389"]
-
-[project.scripts]
-mcp-server-sqlite = "mcp_server_sqlite:main"
diff --git a/src/sqlite/src/mcp_server_sqlite/__init__.py b/src/sqlite/src/mcp_server_sqlite/__init__.py
deleted file mode 100644
index 1dc9f008..00000000
--- a/src/sqlite/src/mcp_server_sqlite/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from . import server
-import asyncio
-import argparse
-
-
-def main():
- """Main entry point for the package."""
- parser = argparse.ArgumentParser(description='SQLite MCP Server')
- parser.add_argument('--db-path',
- default="./sqlite_mcp_server.db",
- help='Path to SQLite database file')
-
- args = parser.parse_args()
- asyncio.run(server.main(args.db_path))
-
-
-# Optionally expose other important items at package level
-__all__ = ["main", "server"]
diff --git a/src/sqlite/src/mcp_server_sqlite/server.py b/src/sqlite/src/mcp_server_sqlite/server.py
deleted file mode 100644
index 01452022..00000000
--- a/src/sqlite/src/mcp_server_sqlite/server.py
+++ /dev/null
@@ -1,382 +0,0 @@
-import os
-import sys
-import sqlite3
-import logging
-from contextlib import closing
-from pathlib import Path
-from mcp.server.models import InitializationOptions
-import mcp.types as types
-from mcp.server import NotificationOptions, Server
-import mcp.server.stdio
-from pydantic import AnyUrl
-from typing import Any
-
-# reconfigure UnicodeEncodeError prone default (i.e. windows-1252) to utf-8
-if sys.platform == "win32" and os.environ.get('PYTHONIOENCODING') is None:
- sys.stdin.reconfigure(encoding="utf-8")
- sys.stdout.reconfigure(encoding="utf-8")
- sys.stderr.reconfigure(encoding="utf-8")
-
-logger = logging.getLogger('mcp_sqlite_server')
-logger.info("Starting MCP SQLite Server")
-
-PROMPT_TEMPLATE = """
-The assistants goal is to walkthrough an informative demo of MCP. To demonstrate the Model Context Protocol (MCP) we will leverage this example server to interact with an SQLite database.
-It is important that you first explain to the user what is going on. The user has downloaded and installed the SQLite MCP Server and is now ready to use it.
-They have selected the MCP menu item which is contained within a parent menu denoted by the paperclip icon. Inside this menu they selected an icon that illustrates two electrical plugs connecting. This is the MCP menu.
-Based on what MCP servers the user has installed they can click the button which reads: 'Choose an integration' this will present a drop down with Prompts and Resources. The user has selected the prompt titled: 'mcp-demo'.
-This text file is that prompt. The goal of the following instructions is to walk the user through the process of using the 3 core aspects of an MCP server. These are: Prompts, Tools, and Resources.
-They have already used a prompt and provided a topic. The topic is: {topic}. The user is now ready to begin the demo.
-Here is some more information about mcp and this specific mcp server:
-
-Prompts:
-This server provides a pre-written prompt called "mcp-demo" that helps users create and analyze database scenarios. The prompt accepts a "topic" argument and guides users through creating tables, analyzing data, and generating insights. For example, if a user provides "retail sales" as the topic, the prompt will help create relevant database tables and guide the analysis process. Prompts basically serve as interactive templates that help structure the conversation with the LLM in a useful way.
-Resources:
-This server exposes one key resource: "memo://insights", which is a business insights memo that gets automatically updated throughout the analysis process. As users analyze the database and discover insights, the memo resource gets updated in real-time to reflect new findings. Resources act as living documents that provide context to the conversation.
-Tools:
-This server provides several SQL-related tools:
-"read_query": Executes SELECT queries to read data from the database
-"write_query": Executes INSERT, UPDATE, or DELETE queries to modify data
-"create_table": Creates new tables in the database
-"list_tables": Shows all existing tables
-"describe_table": Shows the schema for a specific table
-"append_insight": Adds a new business insight to the memo resource
-
-
-You are an AI assistant tasked with generating a comprehensive business scenario based on a given topic.
-Your goal is to create a narrative that involves a data-driven business problem, develop a database structure to support it, generate relevant queries, create a dashboard, and provide a final solution.
-
-At each step you will pause for user input to guide the scenario creation process. Overall ensure the scenario is engaging, informative, and demonstrates the capabilities of the SQLite MCP Server.
-You should guide the scenario to completion. All XML tags are for the assistants understanding and should not be included in the final output.
-
-1. The user has chosen the topic: {topic}.
-
-2. Create a business problem narrative:
-a. Describe a high-level business situation or problem based on the given topic.
-b. Include a protagonist (the user) who needs to collect and analyze data from a database.
-c. Add an external, potentially comedic reason why the data hasn't been prepared yet.
-d. Mention an approaching deadline and the need to use Claude (you) as a business tool to help.
-
-3. Setup the data:
-a. Instead of asking about the data that is required for the scenario, just go ahead and use the tools to create the data. Inform the user you are "Setting up the data".
-b. Design a set of table schemas that represent the data needed for the business problem.
-c. Include at least 2-3 tables with appropriate columns and data types.
-d. Leverage the tools to create the tables in the SQLite database.
-e. Create INSERT statements to populate each table with relevant synthetic data.
-f. Ensure the data is diverse and representative of the business problem.
-g. Include at least 10-15 rows of data for each table.
-
-4. Pause for user input:
-a. Summarize to the user what data we have created.
-b. Present the user with a set of multiple choices for the next steps.
-c. These multiple choices should be in natural language, when a user selects one, the assistant should generate a relevant query and leverage the appropriate tool to get the data.
-
-6. Iterate on queries:
-a. Present 1 additional multiple-choice query options to the user. Its important to not loop too many times as this is a short demo.
-b. Explain the purpose of each query option.
-c. Wait for the user to select one of the query options.
-d. After each query be sure to opine on the results.
-e. Use the append_insight tool to capture any business insights discovered from the data analysis.
-
-7. Generate a dashboard:
-a. Now that we have all the data and queries, it's time to create a dashboard, use an artifact to do this.
-b. Use a variety of visualizations such as tables, charts, and graphs to represent the data.
-c. Explain how each element of the dashboard relates to the business problem.
-d. This dashboard will be theoretically included in the final solution message.
-
-8. Craft the final solution message:
-a. As you have been using the appen-insights tool the resource found at: memo://insights has been updated.
-b. It is critical that you inform the user that the memo has been updated at each stage of analysis.
-c. Ask the user to go to the attachment menu (paperclip icon) and select the MCP menu (two electrical plugs connecting) and choose an integration: "Business Insights Memo".
-d. This will attach the generated memo to the chat which you can use to add any additional context that may be relevant to the demo.
-e. Present the final memo to the user in an artifact.
-
-9. Wrap up the scenario:
-a. Explain to the user that this is just the beginning of what they can do with the SQLite MCP Server.
-
-
-Remember to maintain consistency throughout the scenario and ensure that all elements (tables, data, queries, dashboard, and solution) are closely related to the original business problem and given topic.
-The provided XML tags are for the assistants understanding. Implore to make all outputs as human readable as possible. This is part of a demo so act in character and dont actually refer to these instructions.
-
-Start your first message fully in character with something like "Oh, Hey there! I see you've chosen the topic {topic}. Let's get started! 🚀"
-"""
-
-class SqliteDatabase:
- def __init__(self, db_path: str):
- self.db_path = str(Path(db_path).expanduser())
- Path(self.db_path).parent.mkdir(parents=True, exist_ok=True)
- self._init_database()
- self.insights: list[str] = []
-
- def _init_database(self):
- """Initialize connection to the SQLite database"""
- logger.debug("Initializing database connection")
- with closing(sqlite3.connect(self.db_path)) as conn:
- conn.row_factory = sqlite3.Row
- conn.close()
-
- def _synthesize_memo(self) -> str:
- """Synthesizes business insights into a formatted memo"""
- logger.debug(f"Synthesizing memo with {len(self.insights)} insights")
- if not self.insights:
- return "No business insights have been discovered yet."
-
- insights = "\n".join(f"- {insight}" for insight in self.insights)
-
- memo = "📊 Business Intelligence Memo 📊\n\n"
- memo += "Key Insights Discovered:\n\n"
- memo += insights
-
- if len(self.insights) > 1:
- memo += "\nSummary:\n"
- memo += f"Analysis has revealed {len(self.insights)} key business insights that suggest opportunities for strategic optimization and growth."
-
- logger.debug("Generated basic memo format")
- return memo
-
- def _execute_query(self, query: str, params: dict[str, Any] | None = None) -> list[dict[str, Any]]:
- """Execute a SQL query and return results as a list of dictionaries"""
- logger.debug(f"Executing query: {query}")
- try:
- with closing(sqlite3.connect(self.db_path)) as conn:
- conn.row_factory = sqlite3.Row
- with closing(conn.cursor()) as cursor:
- if params:
- cursor.execute(query, params)
- else:
- cursor.execute(query)
-
- if query.strip().upper().startswith(('INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'ALTER')):
- conn.commit()
- affected = cursor.rowcount
- logger.debug(f"Write query affected {affected} rows")
- return [{"affected_rows": affected}]
-
- results = [dict(row) for row in cursor.fetchall()]
- logger.debug(f"Read query returned {len(results)} rows")
- return results
- except Exception as e:
- logger.error(f"Database error executing query: {e}")
- raise
-
-async def main(db_path: str):
- logger.info(f"Starting SQLite MCP Server with DB path: {db_path}")
-
- db = SqliteDatabase(db_path)
- server = Server("sqlite-manager")
-
- # Register handlers
- logger.debug("Registering handlers")
-
- @server.list_resources()
- async def handle_list_resources() -> list[types.Resource]:
- logger.debug("Handling list_resources request")
- return [
- types.Resource(
- uri=AnyUrl("memo://insights"),
- name="Business Insights Memo",
- description="A living document of discovered business insights",
- mimeType="text/plain",
- )
- ]
-
- @server.read_resource()
- async def handle_read_resource(uri: AnyUrl) -> str:
- logger.debug(f"Handling read_resource request for URI: {uri}")
- if uri.scheme != "memo":
- logger.error(f"Unsupported URI scheme: {uri.scheme}")
- raise ValueError(f"Unsupported URI scheme: {uri.scheme}")
-
- path = str(uri).replace("memo://", "")
- if not path or path != "insights":
- logger.error(f"Unknown resource path: {path}")
- raise ValueError(f"Unknown resource path: {path}")
-
- return db._synthesize_memo()
-
- @server.list_prompts()
- async def handle_list_prompts() -> list[types.Prompt]:
- logger.debug("Handling list_prompts request")
- return [
- types.Prompt(
- name="mcp-demo",
- description="A prompt to seed the database with initial data and demonstrate what you can do with an SQLite MCP Server + Claude",
- arguments=[
- types.PromptArgument(
- name="topic",
- description="Topic to seed the database with initial data",
- required=True,
- )
- ],
- )
- ]
-
- @server.get_prompt()
- async def handle_get_prompt(name: str, arguments: dict[str, str] | None) -> types.GetPromptResult:
- logger.debug(f"Handling get_prompt request for {name} with args {arguments}")
- if name != "mcp-demo":
- logger.error(f"Unknown prompt: {name}")
- raise ValueError(f"Unknown prompt: {name}")
-
- if not arguments or "topic" not in arguments:
- logger.error("Missing required argument: topic")
- raise ValueError("Missing required argument: topic")
-
- topic = arguments["topic"]
- prompt = PROMPT_TEMPLATE.format(topic=topic)
-
- logger.debug(f"Generated prompt template for topic: {topic}")
- return types.GetPromptResult(
- description=f"Demo template for {topic}",
- messages=[
- types.PromptMessage(
- role="user",
- content=types.TextContent(type="text", text=prompt.strip()),
- )
- ],
- )
-
- @server.list_tools()
- async def handle_list_tools() -> list[types.Tool]:
- """List available tools"""
- return [
- types.Tool(
- name="read_query",
- description="Execute a SELECT query on the SQLite database",
- inputSchema={
- "type": "object",
- "properties": {
- "query": {"type": "string", "description": "SELECT SQL query to execute"},
- },
- "required": ["query"],
- },
- ),
- types.Tool(
- name="write_query",
- description="Execute an INSERT, UPDATE, or DELETE query on the SQLite database",
- inputSchema={
- "type": "object",
- "properties": {
- "query": {"type": "string", "description": "SQL query to execute"},
- },
- "required": ["query"],
- },
- ),
- types.Tool(
- name="create_table",
- description="Create a new table in the SQLite database",
- inputSchema={
- "type": "object",
- "properties": {
- "query": {"type": "string", "description": "CREATE TABLE SQL statement"},
- },
- "required": ["query"],
- },
- ),
- types.Tool(
- name="list_tables",
- description="List all tables in the SQLite database",
- inputSchema={
- "type": "object",
- "properties": {},
- },
- ),
- types.Tool(
- name="describe_table",
- description="Get the schema information for a specific table",
- inputSchema={
- "type": "object",
- "properties": {
- "table_name": {"type": "string", "description": "Name of the table to describe"},
- },
- "required": ["table_name"],
- },
- ),
- types.Tool(
- name="append_insight",
- description="Add a business insight to the memo",
- inputSchema={
- "type": "object",
- "properties": {
- "insight": {"type": "string", "description": "Business insight discovered from data analysis"},
- },
- "required": ["insight"],
- },
- ),
- ]
-
- @server.call_tool()
- async def handle_call_tool(
- name: str, arguments: dict[str, Any] | None
- ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
- """Handle tool execution requests"""
- try:
- if name == "list_tables":
- results = db._execute_query(
- "SELECT name FROM sqlite_master WHERE type='table'"
- )
- return [types.TextContent(type="text", text=str(results))]
-
- elif name == "describe_table":
- if not arguments or "table_name" not in arguments:
- raise ValueError("Missing table_name argument")
- results = db._execute_query(
- f"PRAGMA table_info({arguments['table_name']})"
- )
- return [types.TextContent(type="text", text=str(results))]
-
- elif name == "append_insight":
- if not arguments or "insight" not in arguments:
- raise ValueError("Missing insight argument")
-
- db.insights.append(arguments["insight"])
- _ = db._synthesize_memo()
-
- # Notify clients that the memo resource has changed
- await server.request_context.session.send_resource_updated(AnyUrl("memo://insights"))
-
- return [types.TextContent(type="text", text="Insight added to memo")]
-
- if not arguments:
- raise ValueError("Missing arguments")
-
- if name == "read_query":
- if not arguments["query"].strip().upper().startswith("SELECT"):
- raise ValueError("Only SELECT queries are allowed for read_query")
- results = db._execute_query(arguments["query"])
- return [types.TextContent(type="text", text=str(results))]
-
- elif name == "write_query":
- if arguments["query"].strip().upper().startswith("SELECT"):
- raise ValueError("SELECT queries are not allowed for write_query")
- results = db._execute_query(arguments["query"])
- return [types.TextContent(type="text", text=str(results))]
-
- elif name == "create_table":
- if not arguments["query"].strip().upper().startswith("CREATE TABLE"):
- raise ValueError("Only CREATE TABLE statements are allowed")
- db._execute_query(arguments["query"])
- return [types.TextContent(type="text", text="Table created successfully")]
-
- else:
- raise ValueError(f"Unknown tool: {name}")
-
- except sqlite3.Error as e:
- return [types.TextContent(type="text", text=f"Database error: {str(e)}")]
- except Exception as e:
- return [types.TextContent(type="text", text=f"Error: {str(e)}")]
-
- async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
- logger.info("Server running with stdio transport")
- await server.run(
- read_stream,
- write_stream,
- InitializationOptions(
- server_name="sqlite",
- server_version="0.1.0",
- capabilities=server.get_capabilities(
- notification_options=NotificationOptions(),
- experimental_capabilities={},
- ),
- ),
- )
diff --git a/src/sqlite/uv.lock b/src/sqlite/uv.lock
deleted file mode 100644
index 87ccbfbd..00000000
--- a/src/sqlite/uv.lock
+++ /dev/null
@@ -1,325 +0,0 @@
-version = 1
-requires-python = ">=3.10"
-
-[[package]]
-name = "annotated-types"
-version = "0.7.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
-]
-
-[[package]]
-name = "anyio"
-version = "4.6.2.post1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
- { name = "idna" },
- { name = "sniffio" },
- { name = "typing-extensions", marker = "python_full_version < '3.11'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 },
-]
-
-[[package]]
-name = "certifi"
-version = "2024.8.30"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 },
-]
-
-[[package]]
-name = "click"
-version = "8.1.7"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "colorama", marker = "platform_system == 'Windows'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 },
-]
-
-[[package]]
-name = "colorama"
-version = "0.4.6"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
-]
-
-[[package]]
-name = "exceptiongroup"
-version = "1.2.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
-]
-
-[[package]]
-name = "h11"
-version = "0.14.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
-]
-
-[[package]]
-name = "httpcore"
-version = "1.0.7"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "certifi" },
- { name = "h11" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
-]
-
-[[package]]
-name = "httpx"
-version = "0.28.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
- { name = "certifi" },
- { name = "httpcore" },
- { name = "idna" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/10/df/676b7cf674dd1bdc71a64ad393c89879f75e4a0ab8395165b498262ae106/httpx-0.28.0.tar.gz", hash = "sha256:0858d3bab51ba7e386637f22a61d8ccddaeec5f3fe4209da3a6168dbb91573e0", size = 141307 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551 },
-]
-
-[[package]]
-name = "httpx-sse"
-version = "0.4.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
-]
-
-[[package]]
-name = "idna"
-version = "3.10"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
-]
-
-[[package]]
-name = "mcp"
-version = "1.0.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
- { name = "httpx" },
- { name = "httpx-sse" },
- { name = "pydantic" },
- { name = "sse-starlette" },
- { name = "starlette" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/97/de/a9ec0a1b6439f90ea59f89004bb2e7ec6890dfaeef809751d9e6577dca7e/mcp-1.0.0.tar.gz", hash = "sha256:dba51ce0b5c6a80e25576f606760c49a91ee90210fed805b530ca165d3bbc9b7", size = 82891 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/56/89/900c0c8445ec001d3725e475fc553b0feb2e8a51be018f3bb7de51e683db/mcp-1.0.0-py3-none-any.whl", hash = "sha256:bbe70ffa3341cd4da78b5eb504958355c68381fb29971471cea1e642a2af5b8a", size = 36361 },
-]
-
-[[package]]
-name = "mcp-server-sqlite"
-version = "0.6.2"
-source = { editable = "." }
-dependencies = [
- { name = "mcp" },
-]
-
-[package.dev-dependencies]
-dev = [
- { name = "pyright" },
-]
-
-[package.metadata]
-requires-dist = [{ name = "mcp", specifier = ">=1.0.0" }]
-
-[package.metadata.requires-dev]
-dev = [{ name = "pyright", specifier = ">=1.1.389" }]
-
-[[package]]
-name = "nodeenv"
-version = "1.9.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 },
-]
-
-[[package]]
-name = "pydantic"
-version = "2.10.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "annotated-types" },
- { name = "pydantic-core" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/41/86/a03390cb12cf64e2a8df07c267f3eb8d5035e0f9a04bb20fb79403d2a00e/pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa", size = 785401 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364 },
-]
-
-[[package]]
-name = "pydantic-core"
-version = "2.27.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/a6/9f/7de1f19b6aea45aeb441838782d68352e71bfa98ee6fa048d5041991b33e/pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235", size = 412785 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/6e/ce/60fd96895c09738648c83f3f00f595c807cb6735c70d3306b548cc96dd49/pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a", size = 1897984 },
- { url = "https://files.pythonhosted.org/packages/fd/b9/84623d6b6be98cc209b06687d9bca5a7b966ffed008d15225dd0d20cce2e/pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b", size = 1807491 },
- { url = "https://files.pythonhosted.org/packages/01/72/59a70165eabbc93b1111d42df9ca016a4aa109409db04304829377947028/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278", size = 1831953 },
- { url = "https://files.pythonhosted.org/packages/7c/0c/24841136476adafd26f94b45bb718a78cb0500bd7b4f8d667b67c29d7b0d/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05", size = 1856071 },
- { url = "https://files.pythonhosted.org/packages/53/5e/c32957a09cceb2af10d7642df45d1e3dbd8596061f700eac93b801de53c0/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4", size = 2038439 },
- { url = "https://files.pythonhosted.org/packages/e4/8f/979ab3eccd118b638cd6d8f980fea8794f45018255a36044dea40fe579d4/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f", size = 2787416 },
- { url = "https://files.pythonhosted.org/packages/02/1d/00f2e4626565b3b6d3690dab4d4fe1a26edd6a20e53749eb21ca892ef2df/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08", size = 2134548 },
- { url = "https://files.pythonhosted.org/packages/9d/46/3112621204128b90898adc2e721a3cd6cf5626504178d6f32c33b5a43b79/pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6", size = 1989882 },
- { url = "https://files.pythonhosted.org/packages/49/ec/557dd4ff5287ffffdf16a31d08d723de6762bb1b691879dc4423392309bc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807", size = 1995829 },
- { url = "https://files.pythonhosted.org/packages/6e/b2/610dbeb74d8d43921a7234555e4c091cb050a2bdb8cfea86d07791ce01c5/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c", size = 2091257 },
- { url = "https://files.pythonhosted.org/packages/8c/7f/4bf8e9d26a9118521c80b229291fa9558a07cdd9a968ec2d5c1026f14fbc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206", size = 2143894 },
- { url = "https://files.pythonhosted.org/packages/1f/1c/875ac7139c958f4390f23656fe696d1acc8edf45fb81e4831960f12cd6e4/pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c", size = 1816081 },
- { url = "https://files.pythonhosted.org/packages/d7/41/55a117acaeda25ceae51030b518032934f251b1dac3704a53781383e3491/pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17", size = 1981109 },
- { url = "https://files.pythonhosted.org/packages/27/39/46fe47f2ad4746b478ba89c561cafe4428e02b3573df882334bd2964f9cb/pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8", size = 1895553 },
- { url = "https://files.pythonhosted.org/packages/1c/00/0804e84a78b7fdb394fff4c4f429815a10e5e0993e6ae0e0b27dd20379ee/pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330", size = 1807220 },
- { url = "https://files.pythonhosted.org/packages/01/de/df51b3bac9820d38371f5a261020f505025df732ce566c2a2e7970b84c8c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52", size = 1829727 },
- { url = "https://files.pythonhosted.org/packages/5f/d9/c01d19da8f9e9fbdb2bf99f8358d145a312590374d0dc9dd8dbe484a9cde/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4", size = 1854282 },
- { url = "https://files.pythonhosted.org/packages/5f/84/7db66eb12a0dc88c006abd6f3cbbf4232d26adfd827a28638c540d8f871d/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c", size = 2037437 },
- { url = "https://files.pythonhosted.org/packages/34/ac/a2537958db8299fbabed81167d58cc1506049dba4163433524e06a7d9f4c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de", size = 2780899 },
- { url = "https://files.pythonhosted.org/packages/4a/c1/3e38cd777ef832c4fdce11d204592e135ddeedb6c6f525478a53d1c7d3e5/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025", size = 2135022 },
- { url = "https://files.pythonhosted.org/packages/7a/69/b9952829f80fd555fe04340539d90e000a146f2a003d3fcd1e7077c06c71/pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e", size = 1987969 },
- { url = "https://files.pythonhosted.org/packages/05/72/257b5824d7988af43460c4e22b63932ed651fe98804cc2793068de7ec554/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919", size = 1994625 },
- { url = "https://files.pythonhosted.org/packages/73/c3/78ed6b7f3278a36589bcdd01243189ade7fc9b26852844938b4d7693895b/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c", size = 2090089 },
- { url = "https://files.pythonhosted.org/packages/8d/c8/b4139b2f78579960353c4cd987e035108c93a78371bb19ba0dc1ac3b3220/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc", size = 2142496 },
- { url = "https://files.pythonhosted.org/packages/3e/f8/171a03e97eb36c0b51981efe0f78460554a1d8311773d3d30e20c005164e/pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9", size = 1811758 },
- { url = "https://files.pythonhosted.org/packages/6a/fe/4e0e63c418c1c76e33974a05266e5633e879d4061f9533b1706a86f77d5b/pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5", size = 1980864 },
- { url = "https://files.pythonhosted.org/packages/50/fc/93f7238a514c155a8ec02fc7ac6376177d449848115e4519b853820436c5/pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89", size = 1864327 },
- { url = "https://files.pythonhosted.org/packages/be/51/2e9b3788feb2aebff2aa9dfbf060ec739b38c05c46847601134cc1fed2ea/pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f", size = 1895239 },
- { url = "https://files.pythonhosted.org/packages/7b/9e/f8063952e4a7d0127f5d1181addef9377505dcce3be224263b25c4f0bfd9/pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02", size = 1805070 },
- { url = "https://files.pythonhosted.org/packages/2c/9d/e1d6c4561d262b52e41b17a7ef8301e2ba80b61e32e94520271029feb5d8/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c", size = 1828096 },
- { url = "https://files.pythonhosted.org/packages/be/65/80ff46de4266560baa4332ae3181fffc4488ea7d37282da1a62d10ab89a4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac", size = 1857708 },
- { url = "https://files.pythonhosted.org/packages/d5/ca/3370074ad758b04d9562b12ecdb088597f4d9d13893a48a583fb47682cdf/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb", size = 2037751 },
- { url = "https://files.pythonhosted.org/packages/b1/e2/4ab72d93367194317b99d051947c071aef6e3eb95f7553eaa4208ecf9ba4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529", size = 2733863 },
- { url = "https://files.pythonhosted.org/packages/8a/c6/8ae0831bf77f356bb73127ce5a95fe115b10f820ea480abbd72d3cc7ccf3/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35", size = 2161161 },
- { url = "https://files.pythonhosted.org/packages/f1/f4/b2fe73241da2429400fc27ddeaa43e35562f96cf5b67499b2de52b528cad/pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089", size = 1993294 },
- { url = "https://files.pythonhosted.org/packages/77/29/4bb008823a7f4cc05828198153f9753b3bd4c104d93b8e0b1bfe4e187540/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381", size = 2001468 },
- { url = "https://files.pythonhosted.org/packages/f2/a9/0eaceeba41b9fad851a4107e0cf999a34ae8f0d0d1f829e2574f3d8897b0/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb", size = 2091413 },
- { url = "https://files.pythonhosted.org/packages/d8/36/eb8697729725bc610fd73940f0d860d791dc2ad557faaefcbb3edbd2b349/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae", size = 2154735 },
- { url = "https://files.pythonhosted.org/packages/52/e5/4f0fbd5c5995cc70d3afed1b5c754055bb67908f55b5cb8000f7112749bf/pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c", size = 1833633 },
- { url = "https://files.pythonhosted.org/packages/ee/f2/c61486eee27cae5ac781305658779b4a6b45f9cc9d02c90cb21b940e82cc/pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16", size = 1986973 },
- { url = "https://files.pythonhosted.org/packages/df/a6/e3f12ff25f250b02f7c51be89a294689d175ac76e1096c32bf278f29ca1e/pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e", size = 1883215 },
- { url = "https://files.pythonhosted.org/packages/0f/d6/91cb99a3c59d7b072bded9959fbeab0a9613d5a4935773c0801f1764c156/pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073", size = 1895033 },
- { url = "https://files.pythonhosted.org/packages/07/42/d35033f81a28b27dedcade9e967e8a40981a765795c9ebae2045bcef05d3/pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08", size = 1807542 },
- { url = "https://files.pythonhosted.org/packages/41/c2/491b59e222ec7e72236e512108ecad532c7f4391a14e971c963f624f7569/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf", size = 1827854 },
- { url = "https://files.pythonhosted.org/packages/e3/f3/363652651779113189cefdbbb619b7b07b7a67ebb6840325117cc8cc3460/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737", size = 1857389 },
- { url = "https://files.pythonhosted.org/packages/5f/97/be804aed6b479af5a945daec7538d8bf358d668bdadde4c7888a2506bdfb/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2", size = 2037934 },
- { url = "https://files.pythonhosted.org/packages/42/01/295f0bd4abf58902917e342ddfe5f76cf66ffabfc57c2e23c7681a1a1197/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107", size = 2735176 },
- { url = "https://files.pythonhosted.org/packages/9d/a0/cd8e9c940ead89cc37812a1a9f310fef59ba2f0b22b4e417d84ab09fa970/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51", size = 2160720 },
- { url = "https://files.pythonhosted.org/packages/73/ae/9d0980e286627e0aeca4c352a60bd760331622c12d576e5ea4441ac7e15e/pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a", size = 1992972 },
- { url = "https://files.pythonhosted.org/packages/bf/ba/ae4480bc0292d54b85cfb954e9d6bd226982949f8316338677d56541b85f/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc", size = 2001477 },
- { url = "https://files.pythonhosted.org/packages/55/b7/e26adf48c2f943092ce54ae14c3c08d0d221ad34ce80b18a50de8ed2cba8/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960", size = 2091186 },
- { url = "https://files.pythonhosted.org/packages/ba/cc/8491fff5b608b3862eb36e7d29d36a1af1c945463ca4c5040bf46cc73f40/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23", size = 2154429 },
- { url = "https://files.pythonhosted.org/packages/78/d8/c080592d80edd3441ab7f88f865f51dae94a157fc64283c680e9f32cf6da/pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05", size = 1833713 },
- { url = "https://files.pythonhosted.org/packages/83/84/5ab82a9ee2538ac95a66e51f6838d6aba6e0a03a42aa185ad2fe404a4e8f/pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337", size = 1987897 },
- { url = "https://files.pythonhosted.org/packages/df/c3/b15fb833926d91d982fde29c0624c9f225da743c7af801dace0d4e187e71/pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5", size = 1882983 },
- { url = "https://files.pythonhosted.org/packages/7c/60/e5eb2d462595ba1f622edbe7b1d19531e510c05c405f0b87c80c1e89d5b1/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6", size = 1894016 },
- { url = "https://files.pythonhosted.org/packages/61/20/da7059855225038c1c4326a840908cc7ca72c7198cb6addb8b92ec81c1d6/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676", size = 1771648 },
- { url = "https://files.pythonhosted.org/packages/8f/fc/5485cf0b0bb38da31d1d292160a4d123b5977841ddc1122c671a30b76cfd/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d", size = 1826929 },
- { url = "https://files.pythonhosted.org/packages/a1/ff/fb1284a210e13a5f34c639efc54d51da136074ffbe25ec0c279cf9fbb1c4/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c", size = 1980591 },
- { url = "https://files.pythonhosted.org/packages/f1/14/77c1887a182d05af74f6aeac7b740da3a74155d3093ccc7ee10b900cc6b5/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27", size = 1981326 },
- { url = "https://files.pythonhosted.org/packages/06/aa/6f1b2747f811a9c66b5ef39d7f02fbb200479784c75e98290d70004b1253/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f", size = 1989205 },
- { url = "https://files.pythonhosted.org/packages/7a/d2/8ce2b074d6835f3c88d85f6d8a399790043e9fdb3d0e43455e72d19df8cc/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed", size = 2079616 },
- { url = "https://files.pythonhosted.org/packages/65/71/af01033d4e58484c3db1e5d13e751ba5e3d6b87cc3368533df4c50932c8b/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f", size = 2133265 },
- { url = "https://files.pythonhosted.org/packages/33/72/f881b5e18fbb67cf2fb4ab253660de3c6899dbb2dba409d0b757e3559e3d/pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c", size = 2001864 },
-]
-
-[[package]]
-name = "pyright"
-version = "1.1.389"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "nodeenv" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 },
-]
-
-[[package]]
-name = "sniffio"
-version = "1.3.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
-]
-
-[[package]]
-name = "sse-starlette"
-version = "2.1.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
- { name = "starlette" },
- { name = "uvicorn" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/72/fc/56ab9f116b2133521f532fce8d03194cf04dcac25f583cf3d839be4c0496/sse_starlette-2.1.3.tar.gz", hash = "sha256:9cd27eb35319e1414e3d2558ee7414487f9529ce3b3cf9b21434fd110e017169", size = 19678 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/52/aa/36b271bc4fa1d2796311ee7c7283a3a1c348bad426d37293609ca4300eef/sse_starlette-2.1.3-py3-none-any.whl", hash = "sha256:8ec846438b4665b9e8c560fcdea6bc8081a3abf7942faa95e5a744999d219772", size = 9383 },
-]
-
-[[package]]
-name = "starlette"
-version = "0.41.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225 },
-]
-
-[[package]]
-name = "typing-extensions"
-version = "4.12.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
-]
-
-[[package]]
-name = "uvicorn"
-version = "0.32.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "click" },
- { name = "h11" },
- { name = "typing-extensions", marker = "python_full_version < '3.11'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/6a/3c/21dba3e7d76138725ef307e3d7ddd29b763119b3aa459d02cc05fefcff75/uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175", size = 77630 }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/50/c1/2d27b0a15826c2b71dcf6e2f5402181ef85acf439617bb2f1453125ce1f3/uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e", size = 63828 },
-]
diff --git a/src/time/README.md b/src/time/README.md
index eed504bb..01ce2f32 100644
--- a/src/time/README.md
+++ b/src/time/README.md
@@ -45,10 +45,12 @@ Add to your Claude settings:
Using uvx
```json
-"mcpServers": {
- "time": {
- "command": "uvx",
- "args": ["mcp-server-time"]
+{
+ "mcpServers": {
+ "time": {
+ "command": "uvx",
+ "args": ["mcp-server-time"]
+ }
}
}
```
@@ -58,10 +60,12 @@ Add to your Claude settings:
Using docker
```json
-"mcpServers": {
- "time": {
- "command": "docker",
- "args": ["run", "-i", "--rm", "mcp/time"]
+{
+ "mcpServers": {
+ "time": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm", "mcp/time"]
+ }
}
}
```
@@ -71,10 +75,12 @@ Add to your Claude settings:
Using pip installation
```json
-"mcpServers": {
- "time": {
- "command": "python",
- "args": ["-m", "mcp_server_time"]
+{
+ "mcpServers": {
+ "time": {
+ "command": "python",
+ "args": ["-m", "mcp_server_time"]
+ }
}
}
```
@@ -110,6 +116,72 @@ Add to your Zed settings.json:
```
+### Configure for VS Code
+
+For quick installation, use one of the one-click install buttons below...
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=time&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-time%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=time&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-time%22%5D%7D&quality=insiders)
+
+[](https://insiders.vscode.dev/redirect/mcp/install?name=time&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Ftime%22%5D%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=time&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22--rm%22%2C%22mcp%2Ftime%22%5D%7D&quality=insiders)
+
+For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
+
+Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
+
+> Note that the `mcp` key is needed when using the `mcp.json` file.
+
+
+Using uvx
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "time": {
+ "command": "uvx",
+ "args": ["mcp-server-time"]
+ }
+ }
+ }
+}
+```
+
+
+
+Using Docker
+
+```json
+{
+ "mcp": {
+ "servers": {
+ "time": {
+ "command": "docker",
+ "args": ["run", "-i", "--rm", "mcp/time"]
+ }
+ }
+ }
+}
+```
+
+
+### Configure for Zencoder
+
+1. Go to the Zencoder menu (...)
+2. From the dropdown menu, select `Agent Tools`
+3. Click on the `Add Custom MCP`
+4. Add the name and server configuration from below, and make sure to hit the `Install` button
+
+
+Using uvx
+
+```json
+{
+ "command": "uvx",
+ "args": ["mcp-server-time"]
+ }
+```
+
+
### Customization - System Timezone
By default, the server automatically detects your system's timezone. You can override this by adding the argument `--local-timezone` to the `args` list in the configuration.
diff --git a/src/time/pyproject.toml b/src/time/pyproject.toml
index 70924951..2b8c6ed2 100644
--- a/src/time/pyproject.toml
+++ b/src/time/pyproject.toml
@@ -20,6 +20,7 @@ dependencies = [
"mcp>=1.0.0",
"pydantic>=2.0.0",
"tzdata>=2024.2",
+ "tzlocal>=5.3.1"
]
[project.scripts]
diff --git a/src/time/src/mcp_server_time/server.py b/src/time/src/mcp_server_time/server.py
index 67c9024b..e3d353bd 100644
--- a/src/time/src/mcp_server_time/server.py
+++ b/src/time/src/mcp_server_time/server.py
@@ -4,6 +4,8 @@ import json
from typing import Sequence
from zoneinfo import ZoneInfo
+from tzlocal import get_localzone_name # ← returns "Europe/Paris", etc.
+
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent, ImageContent, EmbeddedResource
@@ -40,9 +42,9 @@ def get_local_tz(local_tz_override: str | None = None) -> ZoneInfo:
return ZoneInfo(local_tz_override)
# Get local timezone from datetime.now()
- tzinfo = datetime.now().astimezone(tz=None).tzinfo
- if tzinfo is not None:
- return ZoneInfo(str(tzinfo))
+ local_tzname = get_localzone_name()
+ if local_tzname is not None:
+ return ZoneInfo(local_tzname)
raise McpError("Could not determine local timezone - tzinfo is None")
diff --git a/src/time/uv.lock b/src/time/uv.lock
index a8d820ab..b6321e46 100644
--- a/src/time/uv.lock
+++ b/src/time/uv.lock
@@ -1,13 +1,14 @@
version = 1
+revision = 2
requires-python = ">=3.10"
[[package]]
name = "annotated-types"
version = "0.7.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
+sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload_time = "2024-05-20T21:33:25.928Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
+ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload_time = "2024-05-20T21:33:24.1Z" },
]
[[package]]
@@ -20,18 +21,18 @@ dependencies = [
{ name = "sniffio" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 }
+sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422, upload_time = "2024-10-14T14:31:44.021Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 },
+ { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377, upload_time = "2024-10-14T14:31:42.623Z" },
]
[[package]]
name = "certifi"
version = "2024.8.30"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 }
+sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507, upload_time = "2024-08-30T01:55:04.365Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 },
+ { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321, upload_time = "2024-08-30T01:55:02.591Z" },
]
[[package]]
@@ -39,29 +40,29 @@ name = "click"
version = "8.1.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "colorama", marker = "platform_system == 'Windows'" },
+ { name = "colorama", marker = "sys_platform == 'win32'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 }
+sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121, upload_time = "2023-08-17T17:29:11.868Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 },
+ { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941, upload_time = "2023-08-17T17:29:10.08Z" },
]
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
+sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload_time = "2022-10-25T02:36:22.414Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload_time = "2022-10-25T02:36:20.889Z" },
]
[[package]]
name = "exceptiongroup"
version = "1.2.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 }
+sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883, upload_time = "2024-07-12T22:26:00.161Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
+ { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453, upload_time = "2024-07-12T22:25:58.476Z" },
]
[[package]]
@@ -71,18 +72,18 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "python-dateutil" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/2c/ef/722b8d71ddf4d48f25f6d78aa2533d505bf3eec000a7cacb8ccc8de61f2f/freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9", size = 33697 }
+sdist = { url = "https://files.pythonhosted.org/packages/2c/ef/722b8d71ddf4d48f25f6d78aa2533d505bf3eec000a7cacb8ccc8de61f2f/freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9", size = 33697, upload_time = "2024-05-11T17:32:53.911Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/51/0b/0d7fee5919bccc1fdc1c2a7528b98f65c6f69b223a3fd8f809918c142c36/freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1", size = 17569 },
+ { url = "https://files.pythonhosted.org/packages/51/0b/0d7fee5919bccc1fdc1c2a7528b98f65c6f69b223a3fd8f809918c142c36/freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1", size = 17569, upload_time = "2024-05-11T17:32:51.715Z" },
]
[[package]]
name = "h11"
version = "0.14.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
+sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload_time = "2022-09-25T15:40:01.519Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
+ { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload_time = "2022-09-25T15:39:59.68Z" },
]
[[package]]
@@ -93,9 +94,9 @@ dependencies = [
{ name = "certifi" },
{ name = "h11" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
+sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196, upload_time = "2024-11-15T12:30:47.531Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
+ { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551, upload_time = "2024-11-15T12:30:45.782Z" },
]
[[package]]
@@ -108,36 +109,36 @@ dependencies = [
{ name = "httpcore" },
{ name = "idna" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/10/df/676b7cf674dd1bdc71a64ad393c89879f75e4a0ab8395165b498262ae106/httpx-0.28.0.tar.gz", hash = "sha256:0858d3bab51ba7e386637f22a61d8ccddaeec5f3fe4209da3a6168dbb91573e0", size = 141307 }
+sdist = { url = "https://files.pythonhosted.org/packages/10/df/676b7cf674dd1bdc71a64ad393c89879f75e4a0ab8395165b498262ae106/httpx-0.28.0.tar.gz", hash = "sha256:0858d3bab51ba7e386637f22a61d8ccddaeec5f3fe4209da3a6168dbb91573e0", size = 141307, upload_time = "2024-11-28T14:54:56.977Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551 },
+ { url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551, upload_time = "2024-11-28T14:54:55.141Z" },
]
[[package]]
name = "httpx-sse"
version = "0.4.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
+sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624, upload_time = "2023-12-22T08:01:21.083Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
+ { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819, upload_time = "2023-12-22T08:01:19.89Z" },
]
[[package]]
name = "idna"
version = "3.10"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
+sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload_time = "2024-09-15T18:07:39.745Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
+ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload_time = "2024-09-15T18:07:37.964Z" },
]
[[package]]
name = "iniconfig"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 }
+sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload_time = "2023-01-07T11:08:11.254Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 },
+ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload_time = "2023-01-07T11:08:09.864Z" },
]
[[package]]
@@ -152,9 +153,9 @@ dependencies = [
{ name = "sse-starlette" },
{ name = "starlette" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/97/de/a9ec0a1b6439f90ea59f89004bb2e7ec6890dfaeef809751d9e6577dca7e/mcp-1.0.0.tar.gz", hash = "sha256:dba51ce0b5c6a80e25576f606760c49a91ee90210fed805b530ca165d3bbc9b7", size = 82891 }
+sdist = { url = "https://files.pythonhosted.org/packages/97/de/a9ec0a1b6439f90ea59f89004bb2e7ec6890dfaeef809751d9e6577dca7e/mcp-1.0.0.tar.gz", hash = "sha256:dba51ce0b5c6a80e25576f606760c49a91ee90210fed805b530ca165d3bbc9b7", size = 82891, upload_time = "2024-11-25T14:27:35.616Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/56/89/900c0c8445ec001d3725e475fc553b0feb2e8a51be018f3bb7de51e683db/mcp-1.0.0-py3-none-any.whl", hash = "sha256:bbe70ffa3341cd4da78b5eb504958355c68381fb29971471cea1e642a2af5b8a", size = 36361 },
+ { url = "https://files.pythonhosted.org/packages/56/89/900c0c8445ec001d3725e475fc553b0feb2e8a51be018f3bb7de51e683db/mcp-1.0.0-py3-none-any.whl", hash = "sha256:bbe70ffa3341cd4da78b5eb504958355c68381fb29971471cea1e642a2af5b8a", size = 36361, upload_time = "2024-11-25T14:27:34.367Z" },
]
[[package]]
@@ -165,6 +166,7 @@ dependencies = [
{ name = "mcp" },
{ name = "pydantic" },
{ name = "tzdata" },
+ { name = "tzlocal" },
]
[package.dev-dependencies]
@@ -180,6 +182,7 @@ requires-dist = [
{ name = "mcp", specifier = ">=1.0.0" },
{ name = "pydantic", specifier = ">=2.0.0" },
{ name = "tzdata", specifier = ">=2024.2" },
+ { name = "tzlocal", specifier = ">=5.3.1" },
]
[package.metadata.requires-dev]
@@ -194,27 +197,27 @@ dev = [
name = "nodeenv"
version = "1.9.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 }
+sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload_time = "2024-06-04T18:44:11.171Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 },
+ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload_time = "2024-06-04T18:44:08.352Z" },
]
[[package]]
name = "packaging"
version = "24.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
+sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload_time = "2024-11-08T09:47:47.202Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
+ { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload_time = "2024-11-08T09:47:44.722Z" },
]
[[package]]
name = "pluggy"
version = "1.5.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 }
+sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload_time = "2024-04-20T21:34:42.531Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 },
+ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload_time = "2024-04-20T21:34:40.434Z" },
]
[[package]]
@@ -226,9 +229,9 @@ dependencies = [
{ name = "pydantic-core" },
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/41/86/a03390cb12cf64e2a8df07c267f3eb8d5035e0f9a04bb20fb79403d2a00e/pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa", size = 785401 }
+sdist = { url = "https://files.pythonhosted.org/packages/41/86/a03390cb12cf64e2a8df07c267f3eb8d5035e0f9a04bb20fb79403d2a00e/pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa", size = 785401, upload_time = "2024-11-26T13:02:29.793Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364 },
+ { url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364, upload_time = "2024-11-26T13:02:27.147Z" },
]
[[package]]
@@ -238,72 +241,72 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/a6/9f/7de1f19b6aea45aeb441838782d68352e71bfa98ee6fa048d5041991b33e/pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235", size = 412785 }
+sdist = { url = "https://files.pythonhosted.org/packages/a6/9f/7de1f19b6aea45aeb441838782d68352e71bfa98ee6fa048d5041991b33e/pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235", size = 412785, upload_time = "2024-11-22T00:24:49.865Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/6e/ce/60fd96895c09738648c83f3f00f595c807cb6735c70d3306b548cc96dd49/pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a", size = 1897984 },
- { url = "https://files.pythonhosted.org/packages/fd/b9/84623d6b6be98cc209b06687d9bca5a7b966ffed008d15225dd0d20cce2e/pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b", size = 1807491 },
- { url = "https://files.pythonhosted.org/packages/01/72/59a70165eabbc93b1111d42df9ca016a4aa109409db04304829377947028/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278", size = 1831953 },
- { url = "https://files.pythonhosted.org/packages/7c/0c/24841136476adafd26f94b45bb718a78cb0500bd7b4f8d667b67c29d7b0d/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05", size = 1856071 },
- { url = "https://files.pythonhosted.org/packages/53/5e/c32957a09cceb2af10d7642df45d1e3dbd8596061f700eac93b801de53c0/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4", size = 2038439 },
- { url = "https://files.pythonhosted.org/packages/e4/8f/979ab3eccd118b638cd6d8f980fea8794f45018255a36044dea40fe579d4/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f", size = 2787416 },
- { url = "https://files.pythonhosted.org/packages/02/1d/00f2e4626565b3b6d3690dab4d4fe1a26edd6a20e53749eb21ca892ef2df/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08", size = 2134548 },
- { url = "https://files.pythonhosted.org/packages/9d/46/3112621204128b90898adc2e721a3cd6cf5626504178d6f32c33b5a43b79/pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6", size = 1989882 },
- { url = "https://files.pythonhosted.org/packages/49/ec/557dd4ff5287ffffdf16a31d08d723de6762bb1b691879dc4423392309bc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807", size = 1995829 },
- { url = "https://files.pythonhosted.org/packages/6e/b2/610dbeb74d8d43921a7234555e4c091cb050a2bdb8cfea86d07791ce01c5/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c", size = 2091257 },
- { url = "https://files.pythonhosted.org/packages/8c/7f/4bf8e9d26a9118521c80b229291fa9558a07cdd9a968ec2d5c1026f14fbc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206", size = 2143894 },
- { url = "https://files.pythonhosted.org/packages/1f/1c/875ac7139c958f4390f23656fe696d1acc8edf45fb81e4831960f12cd6e4/pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c", size = 1816081 },
- { url = "https://files.pythonhosted.org/packages/d7/41/55a117acaeda25ceae51030b518032934f251b1dac3704a53781383e3491/pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17", size = 1981109 },
- { url = "https://files.pythonhosted.org/packages/27/39/46fe47f2ad4746b478ba89c561cafe4428e02b3573df882334bd2964f9cb/pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8", size = 1895553 },
- { url = "https://files.pythonhosted.org/packages/1c/00/0804e84a78b7fdb394fff4c4f429815a10e5e0993e6ae0e0b27dd20379ee/pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330", size = 1807220 },
- { url = "https://files.pythonhosted.org/packages/01/de/df51b3bac9820d38371f5a261020f505025df732ce566c2a2e7970b84c8c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52", size = 1829727 },
- { url = "https://files.pythonhosted.org/packages/5f/d9/c01d19da8f9e9fbdb2bf99f8358d145a312590374d0dc9dd8dbe484a9cde/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4", size = 1854282 },
- { url = "https://files.pythonhosted.org/packages/5f/84/7db66eb12a0dc88c006abd6f3cbbf4232d26adfd827a28638c540d8f871d/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c", size = 2037437 },
- { url = "https://files.pythonhosted.org/packages/34/ac/a2537958db8299fbabed81167d58cc1506049dba4163433524e06a7d9f4c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de", size = 2780899 },
- { url = "https://files.pythonhosted.org/packages/4a/c1/3e38cd777ef832c4fdce11d204592e135ddeedb6c6f525478a53d1c7d3e5/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025", size = 2135022 },
- { url = "https://files.pythonhosted.org/packages/7a/69/b9952829f80fd555fe04340539d90e000a146f2a003d3fcd1e7077c06c71/pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e", size = 1987969 },
- { url = "https://files.pythonhosted.org/packages/05/72/257b5824d7988af43460c4e22b63932ed651fe98804cc2793068de7ec554/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919", size = 1994625 },
- { url = "https://files.pythonhosted.org/packages/73/c3/78ed6b7f3278a36589bcdd01243189ade7fc9b26852844938b4d7693895b/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c", size = 2090089 },
- { url = "https://files.pythonhosted.org/packages/8d/c8/b4139b2f78579960353c4cd987e035108c93a78371bb19ba0dc1ac3b3220/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc", size = 2142496 },
- { url = "https://files.pythonhosted.org/packages/3e/f8/171a03e97eb36c0b51981efe0f78460554a1d8311773d3d30e20c005164e/pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9", size = 1811758 },
- { url = "https://files.pythonhosted.org/packages/6a/fe/4e0e63c418c1c76e33974a05266e5633e879d4061f9533b1706a86f77d5b/pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5", size = 1980864 },
- { url = "https://files.pythonhosted.org/packages/50/fc/93f7238a514c155a8ec02fc7ac6376177d449848115e4519b853820436c5/pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89", size = 1864327 },
- { url = "https://files.pythonhosted.org/packages/be/51/2e9b3788feb2aebff2aa9dfbf060ec739b38c05c46847601134cc1fed2ea/pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f", size = 1895239 },
- { url = "https://files.pythonhosted.org/packages/7b/9e/f8063952e4a7d0127f5d1181addef9377505dcce3be224263b25c4f0bfd9/pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02", size = 1805070 },
- { url = "https://files.pythonhosted.org/packages/2c/9d/e1d6c4561d262b52e41b17a7ef8301e2ba80b61e32e94520271029feb5d8/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c", size = 1828096 },
- { url = "https://files.pythonhosted.org/packages/be/65/80ff46de4266560baa4332ae3181fffc4488ea7d37282da1a62d10ab89a4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac", size = 1857708 },
- { url = "https://files.pythonhosted.org/packages/d5/ca/3370074ad758b04d9562b12ecdb088597f4d9d13893a48a583fb47682cdf/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb", size = 2037751 },
- { url = "https://files.pythonhosted.org/packages/b1/e2/4ab72d93367194317b99d051947c071aef6e3eb95f7553eaa4208ecf9ba4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529", size = 2733863 },
- { url = "https://files.pythonhosted.org/packages/8a/c6/8ae0831bf77f356bb73127ce5a95fe115b10f820ea480abbd72d3cc7ccf3/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35", size = 2161161 },
- { url = "https://files.pythonhosted.org/packages/f1/f4/b2fe73241da2429400fc27ddeaa43e35562f96cf5b67499b2de52b528cad/pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089", size = 1993294 },
- { url = "https://files.pythonhosted.org/packages/77/29/4bb008823a7f4cc05828198153f9753b3bd4c104d93b8e0b1bfe4e187540/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381", size = 2001468 },
- { url = "https://files.pythonhosted.org/packages/f2/a9/0eaceeba41b9fad851a4107e0cf999a34ae8f0d0d1f829e2574f3d8897b0/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb", size = 2091413 },
- { url = "https://files.pythonhosted.org/packages/d8/36/eb8697729725bc610fd73940f0d860d791dc2ad557faaefcbb3edbd2b349/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae", size = 2154735 },
- { url = "https://files.pythonhosted.org/packages/52/e5/4f0fbd5c5995cc70d3afed1b5c754055bb67908f55b5cb8000f7112749bf/pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c", size = 1833633 },
- { url = "https://files.pythonhosted.org/packages/ee/f2/c61486eee27cae5ac781305658779b4a6b45f9cc9d02c90cb21b940e82cc/pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16", size = 1986973 },
- { url = "https://files.pythonhosted.org/packages/df/a6/e3f12ff25f250b02f7c51be89a294689d175ac76e1096c32bf278f29ca1e/pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e", size = 1883215 },
- { url = "https://files.pythonhosted.org/packages/0f/d6/91cb99a3c59d7b072bded9959fbeab0a9613d5a4935773c0801f1764c156/pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073", size = 1895033 },
- { url = "https://files.pythonhosted.org/packages/07/42/d35033f81a28b27dedcade9e967e8a40981a765795c9ebae2045bcef05d3/pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08", size = 1807542 },
- { url = "https://files.pythonhosted.org/packages/41/c2/491b59e222ec7e72236e512108ecad532c7f4391a14e971c963f624f7569/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf", size = 1827854 },
- { url = "https://files.pythonhosted.org/packages/e3/f3/363652651779113189cefdbbb619b7b07b7a67ebb6840325117cc8cc3460/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737", size = 1857389 },
- { url = "https://files.pythonhosted.org/packages/5f/97/be804aed6b479af5a945daec7538d8bf358d668bdadde4c7888a2506bdfb/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2", size = 2037934 },
- { url = "https://files.pythonhosted.org/packages/42/01/295f0bd4abf58902917e342ddfe5f76cf66ffabfc57c2e23c7681a1a1197/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107", size = 2735176 },
- { url = "https://files.pythonhosted.org/packages/9d/a0/cd8e9c940ead89cc37812a1a9f310fef59ba2f0b22b4e417d84ab09fa970/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51", size = 2160720 },
- { url = "https://files.pythonhosted.org/packages/73/ae/9d0980e286627e0aeca4c352a60bd760331622c12d576e5ea4441ac7e15e/pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a", size = 1992972 },
- { url = "https://files.pythonhosted.org/packages/bf/ba/ae4480bc0292d54b85cfb954e9d6bd226982949f8316338677d56541b85f/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc", size = 2001477 },
- { url = "https://files.pythonhosted.org/packages/55/b7/e26adf48c2f943092ce54ae14c3c08d0d221ad34ce80b18a50de8ed2cba8/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960", size = 2091186 },
- { url = "https://files.pythonhosted.org/packages/ba/cc/8491fff5b608b3862eb36e7d29d36a1af1c945463ca4c5040bf46cc73f40/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23", size = 2154429 },
- { url = "https://files.pythonhosted.org/packages/78/d8/c080592d80edd3441ab7f88f865f51dae94a157fc64283c680e9f32cf6da/pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05", size = 1833713 },
- { url = "https://files.pythonhosted.org/packages/83/84/5ab82a9ee2538ac95a66e51f6838d6aba6e0a03a42aa185ad2fe404a4e8f/pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337", size = 1987897 },
- { url = "https://files.pythonhosted.org/packages/df/c3/b15fb833926d91d982fde29c0624c9f225da743c7af801dace0d4e187e71/pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5", size = 1882983 },
- { url = "https://files.pythonhosted.org/packages/7c/60/e5eb2d462595ba1f622edbe7b1d19531e510c05c405f0b87c80c1e89d5b1/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6", size = 1894016 },
- { url = "https://files.pythonhosted.org/packages/61/20/da7059855225038c1c4326a840908cc7ca72c7198cb6addb8b92ec81c1d6/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676", size = 1771648 },
- { url = "https://files.pythonhosted.org/packages/8f/fc/5485cf0b0bb38da31d1d292160a4d123b5977841ddc1122c671a30b76cfd/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d", size = 1826929 },
- { url = "https://files.pythonhosted.org/packages/a1/ff/fb1284a210e13a5f34c639efc54d51da136074ffbe25ec0c279cf9fbb1c4/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c", size = 1980591 },
- { url = "https://files.pythonhosted.org/packages/f1/14/77c1887a182d05af74f6aeac7b740da3a74155d3093ccc7ee10b900cc6b5/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27", size = 1981326 },
- { url = "https://files.pythonhosted.org/packages/06/aa/6f1b2747f811a9c66b5ef39d7f02fbb200479784c75e98290d70004b1253/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f", size = 1989205 },
- { url = "https://files.pythonhosted.org/packages/7a/d2/8ce2b074d6835f3c88d85f6d8a399790043e9fdb3d0e43455e72d19df8cc/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed", size = 2079616 },
- { url = "https://files.pythonhosted.org/packages/65/71/af01033d4e58484c3db1e5d13e751ba5e3d6b87cc3368533df4c50932c8b/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f", size = 2133265 },
- { url = "https://files.pythonhosted.org/packages/33/72/f881b5e18fbb67cf2fb4ab253660de3c6899dbb2dba409d0b757e3559e3d/pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c", size = 2001864 },
+ { url = "https://files.pythonhosted.org/packages/6e/ce/60fd96895c09738648c83f3f00f595c807cb6735c70d3306b548cc96dd49/pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a", size = 1897984, upload_time = "2024-11-22T00:21:25.431Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/b9/84623d6b6be98cc209b06687d9bca5a7b966ffed008d15225dd0d20cce2e/pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b", size = 1807491, upload_time = "2024-11-22T00:21:27.318Z" },
+ { url = "https://files.pythonhosted.org/packages/01/72/59a70165eabbc93b1111d42df9ca016a4aa109409db04304829377947028/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278", size = 1831953, upload_time = "2024-11-22T00:21:28.606Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/0c/24841136476adafd26f94b45bb718a78cb0500bd7b4f8d667b67c29d7b0d/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05", size = 1856071, upload_time = "2024-11-22T00:21:29.931Z" },
+ { url = "https://files.pythonhosted.org/packages/53/5e/c32957a09cceb2af10d7642df45d1e3dbd8596061f700eac93b801de53c0/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4", size = 2038439, upload_time = "2024-11-22T00:21:32.245Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/8f/979ab3eccd118b638cd6d8f980fea8794f45018255a36044dea40fe579d4/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f", size = 2787416, upload_time = "2024-11-22T00:21:33.708Z" },
+ { url = "https://files.pythonhosted.org/packages/02/1d/00f2e4626565b3b6d3690dab4d4fe1a26edd6a20e53749eb21ca892ef2df/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08", size = 2134548, upload_time = "2024-11-22T00:21:35.823Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/46/3112621204128b90898adc2e721a3cd6cf5626504178d6f32c33b5a43b79/pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6", size = 1989882, upload_time = "2024-11-22T00:21:37.872Z" },
+ { url = "https://files.pythonhosted.org/packages/49/ec/557dd4ff5287ffffdf16a31d08d723de6762bb1b691879dc4423392309bc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807", size = 1995829, upload_time = "2024-11-22T00:21:39.966Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/b2/610dbeb74d8d43921a7234555e4c091cb050a2bdb8cfea86d07791ce01c5/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c", size = 2091257, upload_time = "2024-11-22T00:21:41.99Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/7f/4bf8e9d26a9118521c80b229291fa9558a07cdd9a968ec2d5c1026f14fbc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206", size = 2143894, upload_time = "2024-11-22T00:21:44.193Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/1c/875ac7139c958f4390f23656fe696d1acc8edf45fb81e4831960f12cd6e4/pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c", size = 1816081, upload_time = "2024-11-22T00:21:45.468Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/41/55a117acaeda25ceae51030b518032934f251b1dac3704a53781383e3491/pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17", size = 1981109, upload_time = "2024-11-22T00:21:47.452Z" },
+ { url = "https://files.pythonhosted.org/packages/27/39/46fe47f2ad4746b478ba89c561cafe4428e02b3573df882334bd2964f9cb/pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8", size = 1895553, upload_time = "2024-11-22T00:21:48.859Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/00/0804e84a78b7fdb394fff4c4f429815a10e5e0993e6ae0e0b27dd20379ee/pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330", size = 1807220, upload_time = "2024-11-22T00:21:50.354Z" },
+ { url = "https://files.pythonhosted.org/packages/01/de/df51b3bac9820d38371f5a261020f505025df732ce566c2a2e7970b84c8c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52", size = 1829727, upload_time = "2024-11-22T00:21:51.722Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/d9/c01d19da8f9e9fbdb2bf99f8358d145a312590374d0dc9dd8dbe484a9cde/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4", size = 1854282, upload_time = "2024-11-22T00:21:53.098Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/84/7db66eb12a0dc88c006abd6f3cbbf4232d26adfd827a28638c540d8f871d/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c", size = 2037437, upload_time = "2024-11-22T00:21:55.185Z" },
+ { url = "https://files.pythonhosted.org/packages/34/ac/a2537958db8299fbabed81167d58cc1506049dba4163433524e06a7d9f4c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de", size = 2780899, upload_time = "2024-11-22T00:21:56.633Z" },
+ { url = "https://files.pythonhosted.org/packages/4a/c1/3e38cd777ef832c4fdce11d204592e135ddeedb6c6f525478a53d1c7d3e5/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025", size = 2135022, upload_time = "2024-11-22T00:21:59.154Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/69/b9952829f80fd555fe04340539d90e000a146f2a003d3fcd1e7077c06c71/pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e", size = 1987969, upload_time = "2024-11-22T00:22:01.325Z" },
+ { url = "https://files.pythonhosted.org/packages/05/72/257b5824d7988af43460c4e22b63932ed651fe98804cc2793068de7ec554/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919", size = 1994625, upload_time = "2024-11-22T00:22:03.447Z" },
+ { url = "https://files.pythonhosted.org/packages/73/c3/78ed6b7f3278a36589bcdd01243189ade7fc9b26852844938b4d7693895b/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c", size = 2090089, upload_time = "2024-11-22T00:22:04.941Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/c8/b4139b2f78579960353c4cd987e035108c93a78371bb19ba0dc1ac3b3220/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc", size = 2142496, upload_time = "2024-11-22T00:22:06.57Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/f8/171a03e97eb36c0b51981efe0f78460554a1d8311773d3d30e20c005164e/pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9", size = 1811758, upload_time = "2024-11-22T00:22:08.445Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/fe/4e0e63c418c1c76e33974a05266e5633e879d4061f9533b1706a86f77d5b/pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5", size = 1980864, upload_time = "2024-11-22T00:22:10Z" },
+ { url = "https://files.pythonhosted.org/packages/50/fc/93f7238a514c155a8ec02fc7ac6376177d449848115e4519b853820436c5/pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89", size = 1864327, upload_time = "2024-11-22T00:22:11.478Z" },
+ { url = "https://files.pythonhosted.org/packages/be/51/2e9b3788feb2aebff2aa9dfbf060ec739b38c05c46847601134cc1fed2ea/pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f", size = 1895239, upload_time = "2024-11-22T00:22:13.775Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/9e/f8063952e4a7d0127f5d1181addef9377505dcce3be224263b25c4f0bfd9/pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02", size = 1805070, upload_time = "2024-11-22T00:22:15.438Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/9d/e1d6c4561d262b52e41b17a7ef8301e2ba80b61e32e94520271029feb5d8/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c", size = 1828096, upload_time = "2024-11-22T00:22:17.892Z" },
+ { url = "https://files.pythonhosted.org/packages/be/65/80ff46de4266560baa4332ae3181fffc4488ea7d37282da1a62d10ab89a4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac", size = 1857708, upload_time = "2024-11-22T00:22:19.412Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/ca/3370074ad758b04d9562b12ecdb088597f4d9d13893a48a583fb47682cdf/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb", size = 2037751, upload_time = "2024-11-22T00:22:20.979Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/e2/4ab72d93367194317b99d051947c071aef6e3eb95f7553eaa4208ecf9ba4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529", size = 2733863, upload_time = "2024-11-22T00:22:22.951Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/c6/8ae0831bf77f356bb73127ce5a95fe115b10f820ea480abbd72d3cc7ccf3/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35", size = 2161161, upload_time = "2024-11-22T00:22:24.785Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/f4/b2fe73241da2429400fc27ddeaa43e35562f96cf5b67499b2de52b528cad/pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089", size = 1993294, upload_time = "2024-11-22T00:22:27.076Z" },
+ { url = "https://files.pythonhosted.org/packages/77/29/4bb008823a7f4cc05828198153f9753b3bd4c104d93b8e0b1bfe4e187540/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381", size = 2001468, upload_time = "2024-11-22T00:22:29.346Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/a9/0eaceeba41b9fad851a4107e0cf999a34ae8f0d0d1f829e2574f3d8897b0/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb", size = 2091413, upload_time = "2024-11-22T00:22:30.984Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/36/eb8697729725bc610fd73940f0d860d791dc2ad557faaefcbb3edbd2b349/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae", size = 2154735, upload_time = "2024-11-22T00:22:32.616Z" },
+ { url = "https://files.pythonhosted.org/packages/52/e5/4f0fbd5c5995cc70d3afed1b5c754055bb67908f55b5cb8000f7112749bf/pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c", size = 1833633, upload_time = "2024-11-22T00:22:35.027Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/f2/c61486eee27cae5ac781305658779b4a6b45f9cc9d02c90cb21b940e82cc/pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16", size = 1986973, upload_time = "2024-11-22T00:22:37.502Z" },
+ { url = "https://files.pythonhosted.org/packages/df/a6/e3f12ff25f250b02f7c51be89a294689d175ac76e1096c32bf278f29ca1e/pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e", size = 1883215, upload_time = "2024-11-22T00:22:39.186Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/d6/91cb99a3c59d7b072bded9959fbeab0a9613d5a4935773c0801f1764c156/pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073", size = 1895033, upload_time = "2024-11-22T00:22:41.087Z" },
+ { url = "https://files.pythonhosted.org/packages/07/42/d35033f81a28b27dedcade9e967e8a40981a765795c9ebae2045bcef05d3/pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08", size = 1807542, upload_time = "2024-11-22T00:22:43.341Z" },
+ { url = "https://files.pythonhosted.org/packages/41/c2/491b59e222ec7e72236e512108ecad532c7f4391a14e971c963f624f7569/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf", size = 1827854, upload_time = "2024-11-22T00:22:44.96Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/f3/363652651779113189cefdbbb619b7b07b7a67ebb6840325117cc8cc3460/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737", size = 1857389, upload_time = "2024-11-22T00:22:47.305Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/97/be804aed6b479af5a945daec7538d8bf358d668bdadde4c7888a2506bdfb/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2", size = 2037934, upload_time = "2024-11-22T00:22:49.093Z" },
+ { url = "https://files.pythonhosted.org/packages/42/01/295f0bd4abf58902917e342ddfe5f76cf66ffabfc57c2e23c7681a1a1197/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107", size = 2735176, upload_time = "2024-11-22T00:22:50.822Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/a0/cd8e9c940ead89cc37812a1a9f310fef59ba2f0b22b4e417d84ab09fa970/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51", size = 2160720, upload_time = "2024-11-22T00:22:52.638Z" },
+ { url = "https://files.pythonhosted.org/packages/73/ae/9d0980e286627e0aeca4c352a60bd760331622c12d576e5ea4441ac7e15e/pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a", size = 1992972, upload_time = "2024-11-22T00:22:54.31Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/ba/ae4480bc0292d54b85cfb954e9d6bd226982949f8316338677d56541b85f/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc", size = 2001477, upload_time = "2024-11-22T00:22:56.451Z" },
+ { url = "https://files.pythonhosted.org/packages/55/b7/e26adf48c2f943092ce54ae14c3c08d0d221ad34ce80b18a50de8ed2cba8/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960", size = 2091186, upload_time = "2024-11-22T00:22:58.226Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/cc/8491fff5b608b3862eb36e7d29d36a1af1c945463ca4c5040bf46cc73f40/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23", size = 2154429, upload_time = "2024-11-22T00:22:59.985Z" },
+ { url = "https://files.pythonhosted.org/packages/78/d8/c080592d80edd3441ab7f88f865f51dae94a157fc64283c680e9f32cf6da/pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05", size = 1833713, upload_time = "2024-11-22T00:23:01.715Z" },
+ { url = "https://files.pythonhosted.org/packages/83/84/5ab82a9ee2538ac95a66e51f6838d6aba6e0a03a42aa185ad2fe404a4e8f/pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337", size = 1987897, upload_time = "2024-11-22T00:23:03.497Z" },
+ { url = "https://files.pythonhosted.org/packages/df/c3/b15fb833926d91d982fde29c0624c9f225da743c7af801dace0d4e187e71/pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5", size = 1882983, upload_time = "2024-11-22T00:23:05.983Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/60/e5eb2d462595ba1f622edbe7b1d19531e510c05c405f0b87c80c1e89d5b1/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6", size = 1894016, upload_time = "2024-11-22T00:24:03.815Z" },
+ { url = "https://files.pythonhosted.org/packages/61/20/da7059855225038c1c4326a840908cc7ca72c7198cb6addb8b92ec81c1d6/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676", size = 1771648, upload_time = "2024-11-22T00:24:05.981Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/fc/5485cf0b0bb38da31d1d292160a4d123b5977841ddc1122c671a30b76cfd/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d", size = 1826929, upload_time = "2024-11-22T00:24:08.163Z" },
+ { url = "https://files.pythonhosted.org/packages/a1/ff/fb1284a210e13a5f34c639efc54d51da136074ffbe25ec0c279cf9fbb1c4/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c", size = 1980591, upload_time = "2024-11-22T00:24:10.291Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/14/77c1887a182d05af74f6aeac7b740da3a74155d3093ccc7ee10b900cc6b5/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27", size = 1981326, upload_time = "2024-11-22T00:24:13.169Z" },
+ { url = "https://files.pythonhosted.org/packages/06/aa/6f1b2747f811a9c66b5ef39d7f02fbb200479784c75e98290d70004b1253/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f", size = 1989205, upload_time = "2024-11-22T00:24:16.049Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/d2/8ce2b074d6835f3c88d85f6d8a399790043e9fdb3d0e43455e72d19df8cc/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed", size = 2079616, upload_time = "2024-11-22T00:24:19.099Z" },
+ { url = "https://files.pythonhosted.org/packages/65/71/af01033d4e58484c3db1e5d13e751ba5e3d6b87cc3368533df4c50932c8b/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f", size = 2133265, upload_time = "2024-11-22T00:24:21.397Z" },
+ { url = "https://files.pythonhosted.org/packages/33/72/f881b5e18fbb67cf2fb4ab253660de3c6899dbb2dba409d0b757e3559e3d/pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c", size = 2001864, upload_time = "2024-11-22T00:24:24.354Z" },
]
[[package]]
@@ -314,9 +317,9 @@ dependencies = [
{ name = "nodeenv" },
{ name = "typing-extensions" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 }
+sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940, upload_time = "2024-11-13T16:35:41.84Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 },
+ { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581, upload_time = "2024-11-13T16:35:40.689Z" },
]
[[package]]
@@ -331,9 +334,9 @@ dependencies = [
{ name = "pluggy" },
{ name = "tomli", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 }
+sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487, upload_time = "2024-09-10T10:52:15.003Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 },
+ { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341, upload_time = "2024-09-10T10:52:12.54Z" },
]
[[package]]
@@ -343,52 +346,52 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
+sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload_time = "2024-03-01T18:36:20.211Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
+ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload_time = "2024-03-01T18:36:18.57Z" },
]
[[package]]
name = "ruff"
version = "0.8.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/95/d0/8ff5b189d125f4260f2255d143bf2fa413b69c2610c405ace7a0a8ec81ec/ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f", size = 3313222 }
+sdist = { url = "https://files.pythonhosted.org/packages/95/d0/8ff5b189d125f4260f2255d143bf2fa413b69c2610c405ace7a0a8ec81ec/ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f", size = 3313222, upload_time = "2024-11-29T03:29:49.986Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/a2/d6/1a6314e568db88acdbb5121ed53e2c52cebf3720d3437a76f82f923bf171/ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5", size = 10532605 },
- { url = "https://files.pythonhosted.org/packages/89/a8/a957a8812e31facffb6a26a30be0b5b4af000a6e30c7d43a22a5232a3398/ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087", size = 10278243 },
- { url = "https://files.pythonhosted.org/packages/a8/23/9db40fa19c453fabf94f7a35c61c58f20e8200b4734a20839515a19da790/ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209", size = 9917739 },
- { url = "https://files.pythonhosted.org/packages/e2/a0/6ee2d949835d5701d832fc5acd05c0bfdad5e89cfdd074a171411f5ccad5/ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871", size = 10779153 },
- { url = "https://files.pythonhosted.org/packages/7a/25/9c11dca9404ef1eb24833f780146236131a3c7941de394bc356912ef1041/ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1", size = 10304387 },
- { url = "https://files.pythonhosted.org/packages/c8/b9/84c323780db1b06feae603a707d82dbbd85955c8c917738571c65d7d5aff/ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5", size = 11360351 },
- { url = "https://files.pythonhosted.org/packages/6b/e1/9d4bbb2ace7aad14ded20e4674a48cda5b902aed7a1b14e6b028067060c4/ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d", size = 12022879 },
- { url = "https://files.pythonhosted.org/packages/75/28/752ff6120c0e7f9981bc4bc275d540c7f36db1379ba9db9142f69c88db21/ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26", size = 11610354 },
- { url = "https://files.pythonhosted.org/packages/ba/8c/967b61c2cc8ebd1df877607fbe462bc1e1220b4a30ae3352648aec8c24bd/ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1", size = 12813976 },
- { url = "https://files.pythonhosted.org/packages/7f/29/e059f945d6bd2d90213387b8c360187f2fefc989ddcee6bbf3c241329b92/ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c", size = 11154564 },
- { url = "https://files.pythonhosted.org/packages/55/47/cbd05e5a62f3fb4c072bc65c1e8fd709924cad1c7ec60a1000d1e4ee8307/ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa", size = 10760604 },
- { url = "https://files.pythonhosted.org/packages/bb/ee/4c3981c47147c72647a198a94202633130cfda0fc95cd863a553b6f65c6a/ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540", size = 10391071 },
- { url = "https://files.pythonhosted.org/packages/6b/e6/083eb61300214590b188616a8ac6ae1ef5730a0974240fb4bec9c17de78b/ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9", size = 10896657 },
- { url = "https://files.pythonhosted.org/packages/77/bd/aacdb8285d10f1b943dbeb818968efca35459afc29f66ae3bd4596fbf954/ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5", size = 11228362 },
- { url = "https://files.pythonhosted.org/packages/39/72/fcb7ad41947f38b4eaa702aca0a361af0e9c2bf671d7fd964480670c297e/ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790", size = 8803476 },
- { url = "https://files.pythonhosted.org/packages/e4/ea/cae9aeb0f4822c44651c8407baacdb2e5b4dcd7b31a84e1c5df33aa2cc20/ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6", size = 9614463 },
- { url = "https://files.pythonhosted.org/packages/eb/76/fbb4bd23dfb48fa7758d35b744413b650a9fd2ddd93bca77e30376864414/ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737", size = 8959621 },
+ { url = "https://files.pythonhosted.org/packages/a2/d6/1a6314e568db88acdbb5121ed53e2c52cebf3720d3437a76f82f923bf171/ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5", size = 10532605, upload_time = "2024-11-29T03:28:41.978Z" },
+ { url = "https://files.pythonhosted.org/packages/89/a8/a957a8812e31facffb6a26a30be0b5b4af000a6e30c7d43a22a5232a3398/ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087", size = 10278243, upload_time = "2024-11-29T03:28:44.577Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/23/9db40fa19c453fabf94f7a35c61c58f20e8200b4734a20839515a19da790/ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209", size = 9917739, upload_time = "2024-11-29T03:28:53.895Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/a0/6ee2d949835d5701d832fc5acd05c0bfdad5e89cfdd074a171411f5ccad5/ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871", size = 10779153, upload_time = "2024-11-29T03:28:59.609Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/25/9c11dca9404ef1eb24833f780146236131a3c7941de394bc356912ef1041/ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1", size = 10304387, upload_time = "2024-11-29T03:29:02.512Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/b9/84c323780db1b06feae603a707d82dbbd85955c8c917738571c65d7d5aff/ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5", size = 11360351, upload_time = "2024-11-29T03:29:04.838Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/e1/9d4bbb2ace7aad14ded20e4674a48cda5b902aed7a1b14e6b028067060c4/ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d", size = 12022879, upload_time = "2024-11-29T03:29:07.202Z" },
+ { url = "https://files.pythonhosted.org/packages/75/28/752ff6120c0e7f9981bc4bc275d540c7f36db1379ba9db9142f69c88db21/ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26", size = 11610354, upload_time = "2024-11-29T03:29:09.533Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/8c/967b61c2cc8ebd1df877607fbe462bc1e1220b4a30ae3352648aec8c24bd/ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1", size = 12813976, upload_time = "2024-11-29T03:29:12.627Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/29/e059f945d6bd2d90213387b8c360187f2fefc989ddcee6bbf3c241329b92/ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c", size = 11154564, upload_time = "2024-11-29T03:29:16.594Z" },
+ { url = "https://files.pythonhosted.org/packages/55/47/cbd05e5a62f3fb4c072bc65c1e8fd709924cad1c7ec60a1000d1e4ee8307/ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa", size = 10760604, upload_time = "2024-11-29T03:29:24.553Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/ee/4c3981c47147c72647a198a94202633130cfda0fc95cd863a553b6f65c6a/ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540", size = 10391071, upload_time = "2024-11-29T03:29:29.533Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/e6/083eb61300214590b188616a8ac6ae1ef5730a0974240fb4bec9c17de78b/ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9", size = 10896657, upload_time = "2024-11-29T03:29:31.87Z" },
+ { url = "https://files.pythonhosted.org/packages/77/bd/aacdb8285d10f1b943dbeb818968efca35459afc29f66ae3bd4596fbf954/ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5", size = 11228362, upload_time = "2024-11-29T03:29:34.255Z" },
+ { url = "https://files.pythonhosted.org/packages/39/72/fcb7ad41947f38b4eaa702aca0a361af0e9c2bf671d7fd964480670c297e/ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790", size = 8803476, upload_time = "2024-11-29T03:29:36.483Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/ea/cae9aeb0f4822c44651c8407baacdb2e5b4dcd7b31a84e1c5df33aa2cc20/ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6", size = 9614463, upload_time = "2024-11-29T03:29:38.814Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/76/fbb4bd23dfb48fa7758d35b744413b650a9fd2ddd93bca77e30376864414/ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737", size = 8959621, upload_time = "2024-11-29T03:29:43.977Z" },
]
[[package]]
name = "six"
version = "1.16.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 }
+sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041, upload_time = "2021-05-05T14:18:18.379Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 },
+ { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053, upload_time = "2021-05-05T14:18:17.237Z" },
]
[[package]]
name = "sniffio"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload_time = "2024-02-25T23:20:04.057Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
+ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload_time = "2024-02-25T23:20:01.196Z" },
]
[[package]]
@@ -400,9 +403,9 @@ dependencies = [
{ name = "starlette" },
{ name = "uvicorn" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/72/fc/56ab9f116b2133521f532fce8d03194cf04dcac25f583cf3d839be4c0496/sse_starlette-2.1.3.tar.gz", hash = "sha256:9cd27eb35319e1414e3d2558ee7414487f9529ce3b3cf9b21434fd110e017169", size = 19678 }
+sdist = { url = "https://files.pythonhosted.org/packages/72/fc/56ab9f116b2133521f532fce8d03194cf04dcac25f583cf3d839be4c0496/sse_starlette-2.1.3.tar.gz", hash = "sha256:9cd27eb35319e1414e3d2558ee7414487f9529ce3b3cf9b21434fd110e017169", size = 19678, upload_time = "2024-08-01T08:52:50.248Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/52/aa/36b271bc4fa1d2796311ee7c7283a3a1c348bad426d37293609ca4300eef/sse_starlette-2.1.3-py3-none-any.whl", hash = "sha256:8ec846438b4665b9e8c560fcdea6bc8081a3abf7942faa95e5a744999d219772", size = 9383 },
+ { url = "https://files.pythonhosted.org/packages/52/aa/36b271bc4fa1d2796311ee7c7283a3a1c348bad426d37293609ca4300eef/sse_starlette-2.1.3-py3-none-any.whl", hash = "sha256:8ec846438b4665b9e8c560fcdea6bc8081a3abf7942faa95e5a744999d219772", size = 9383, upload_time = "2024-08-01T08:52:48.659Z" },
]
[[package]]
@@ -412,66 +415,78 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159 }
+sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159, upload_time = "2024-11-18T19:45:04.283Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225 },
+ { url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225, upload_time = "2024-11-18T19:45:02.027Z" },
]
[[package]]
name = "tomli"
version = "2.2.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 }
+sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload_time = "2024-11-27T22:38:36.873Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 },
- { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 },
- { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 },
- { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 },
- { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 },
- { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 },
- { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 },
- { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 },
- { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 },
- { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 },
- { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 },
- { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 },
- { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 },
- { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 },
- { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 },
- { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 },
- { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 },
- { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 },
- { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 },
- { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 },
- { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 },
- { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 },
- { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 },
- { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 },
- { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 },
- { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 },
- { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 },
- { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 },
- { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 },
- { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 },
- { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 },
+ { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload_time = "2024-11-27T22:37:54.956Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload_time = "2024-11-27T22:37:56.698Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload_time = "2024-11-27T22:37:57.63Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload_time = "2024-11-27T22:37:59.344Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload_time = "2024-11-27T22:38:00.429Z" },
+ { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload_time = "2024-11-27T22:38:02.094Z" },
+ { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload_time = "2024-11-27T22:38:03.206Z" },
+ { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload_time = "2024-11-27T22:38:04.217Z" },
+ { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload_time = "2024-11-27T22:38:05.908Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload_time = "2024-11-27T22:38:06.812Z" },
+ { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload_time = "2024-11-27T22:38:07.731Z" },
+ { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload_time = "2024-11-27T22:38:09.384Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload_time = "2024-11-27T22:38:10.329Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload_time = "2024-11-27T22:38:11.443Z" },
+ { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload_time = "2024-11-27T22:38:13.099Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload_time = "2024-11-27T22:38:14.766Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload_time = "2024-11-27T22:38:15.843Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload_time = "2024-11-27T22:38:17.645Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload_time = "2024-11-27T22:38:19.159Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload_time = "2024-11-27T22:38:20.064Z" },
+ { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload_time = "2024-11-27T22:38:21.659Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload_time = "2024-11-27T22:38:22.693Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload_time = "2024-11-27T22:38:24.367Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload_time = "2024-11-27T22:38:26.081Z" },
+ { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload_time = "2024-11-27T22:38:27.921Z" },
+ { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload_time = "2024-11-27T22:38:29.591Z" },
+ { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload_time = "2024-11-27T22:38:30.639Z" },
+ { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload_time = "2024-11-27T22:38:31.702Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload_time = "2024-11-27T22:38:32.837Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload_time = "2024-11-27T22:38:34.455Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload_time = "2024-11-27T22:38:35.385Z" },
]
[[package]]
name = "typing-extensions"
version = "4.12.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
+sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload_time = "2024-06-07T18:52:15.995Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
+ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload_time = "2024-06-07T18:52:13.582Z" },
]
[[package]]
name = "tzdata"
version = "2024.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e1/34/943888654477a574a86a98e9896bae89c7aa15078ec29f490fef2f1e5384/tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", size = 193282 }
+sdist = { url = "https://files.pythonhosted.org/packages/e1/34/943888654477a574a86a98e9896bae89c7aa15078ec29f490fef2f1e5384/tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", size = 193282, upload_time = "2024-09-23T18:56:46.89Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 },
+ { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586, upload_time = "2024-09-23T18:56:45.478Z" },
+]
+
+[[package]]
+name = "tzlocal"
+version = "5.3.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "tzdata", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/8b/2e/c14812d3d4d9cd1773c6be938f89e5735a1f11a9f184ac3639b93cef35d5/tzlocal-5.3.1.tar.gz", hash = "sha256:cceffc7edecefea1f595541dbd6e990cb1ea3d19bf01b2809f362a03dd7921fd", size = 30761, upload_time = "2025-03-05T21:17:41.549Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c2/14/e2a54fabd4f08cd7af1c07030603c3356b74da07f7cc056e600436edfa17/tzlocal-5.3.1-py3-none-any.whl", hash = "sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d", size = 18026, upload_time = "2025-03-05T21:17:39.857Z" },
]
[[package]]
@@ -483,7 +498,7 @@ dependencies = [
{ name = "h11" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/6a/3c/21dba3e7d76138725ef307e3d7ddd29b763119b3aa459d02cc05fefcff75/uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175", size = 77630 }
+sdist = { url = "https://files.pythonhosted.org/packages/6a/3c/21dba3e7d76138725ef307e3d7ddd29b763119b3aa459d02cc05fefcff75/uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175", size = 77630, upload_time = "2024-11-20T19:41:13.341Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/50/c1/2d27b0a15826c2b71dcf6e2f5402181ef85acf439617bb2f1453125ce1f3/uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e", size = 63828 },
+ { url = "https://files.pythonhosted.org/packages/50/c1/2d27b0a15826c2b71dcf6e2f5402181ef85acf439617bb2f1453125ce1f3/uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e", size = 63828, upload_time = "2024-11-20T19:41:11.244Z" },
]