diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index f6d5e1a8..5fbe8a15 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -3,8 +3,8 @@
## Description
## Server Details
-
-- Server:
+
+- Server:
- Changes to:
## Motivation and Context
@@ -18,7 +18,6 @@
## Types of changes
-- [ ] New MCP Server
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
@@ -27,7 +26,7 @@
## Checklist
- [ ] I have read the [MCP Protocol Documentation](https://modelcontextprotocol.io)
-- [ ] My server follows MCP security best practices
+- [ ] My changes follows MCP security best practices
- [ ] I have updated the server's README accordingly
- [ ] I have tested this with an LLM client
- [ ] My code follows the repository's style guidelines
diff --git a/.github/workflows/typescript.yml b/.github/workflows/typescript.yml
index 325f2ee7..7d55e744 100644
--- a/.github/workflows/typescript.yml
+++ b/.github/workflows/typescript.yml
@@ -74,6 +74,6 @@ jobs:
- name: Publish package
working-directory: src/${{ matrix.package }}
- run: npm publish # --provenance
+ run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 88a0e03b..8c6e176a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,12 +5,16 @@ Thank you for your interest in contributing to the Model Context Protocol (MCP)
## Types of Contributions
### 1. New Servers
-Adding a new server is a valuable way to contribute. Before creating a new server:
+
+The repository contains reference implementations, as well as a list of community servers.
+We generally don't accept new servers into the repository. We do accept pull requests to the [README.md](./README.md)
+adding a reference to your servers.
- Check the [modelcontextprotocol.io](https://modelcontextprotocol.io) documentation
- Ensure your server doesn't duplicate existing functionality
- Consider whether your server would be generally useful to others
- Follow [security best practices](https://modelcontextprotocol.io/docs/concepts/transports#security-considerations) from the MCP documentation
+- Create a PR adding a link to your server to the [README.md](./README.md).
### 2. Improvements to Existing Servers
Enhancements to existing servers are welcome! This includes:
@@ -88,7 +92,7 @@ Documentation improvements are always welcome:
## Community
-- Participate in [GitHub Discussions](https://github.com/modelcontextprotocol/servers/discussions)
+- Participate in [GitHub Discussions](https://github.com/orgs/modelcontextprotocol/discussions)
- Follow the [Code of Conduct](CODE_OF_CONDUCT.md)
## Questions?
@@ -96,4 +100,4 @@ Documentation improvements are always welcome:
- Check the [documentation](https://modelcontextprotocol.io)
- Ask in GitHub Discussions
-Thank you for contributing to MCP Servers!
\ No newline at end of file
+Thank you for contributing to MCP Servers!
diff --git a/README.md b/README.md
index 503a83f8..1c735776 100644
--- a/README.md
+++ b/README.md
@@ -1,37 +1,81 @@
-# MCP servers
+# Model Context Protocol servers
-A collection of reference implementations and community-contributed servers for the [Model Context Protocol](https://modelcontextprotocol.io/) (MCP). This repository showcases 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.
+This repository is a collection of *reference implementations* for the [Model Context Protocol](https://modelcontextprotocol.io/) (MCP), as well as references
+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).
-## 🌟 Featured Servers
+## 🌟 Reference Servers
+These servers aim to demonstrate MCP features and the Typescript and Python SDK.
+
+- **[Brave Search](src/brave-search)** - Web and local search using Brave's Search API
+- **[Fetch](src/fetch)** - Web content fetching and conversion for efficient LLM usage
- **[Filesystem](src/filesystem)** - Secure file operations with configurable access controls
- **[GitHub](src/github)** - Repository management, file operations, and GitHub API integration
- **[GitLab](src/gitlab)** - GitLab API, enabling project management
- **[Git](src/git)** - Tools to read, search, and manipulate Git repositories
- **[Google Drive](src/gdrive)** - File access and search capabilities for Google Drive
-- **[PostgreSQL](src/postgres)** - Read-only database access with schema inspection
-- **[Sqlite](src/sqlite)** - Database interaction and business intelligence capabilities
-- **[Slack](src/slack)** - Channel management and messaging capabilities
-- **[Sentry](src/sentry)** - Retrieving and analyzing issues from Sentry.io
-- **[Memory](src/memory)** - Knowledge graph-based persistent memory system
-- **[Puppeteer](src/puppeteer)** - Browser automation and web scraping
-- **[Brave Search](src/brave-search)** - Web and local search using Brave's Search API
- **[Google Maps](src/google-maps)** - Location services, directions, and place details
-- **[Fetch](src/fetch)** - Web content fetching and conversion for efficient LLM usage
+- **[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
+- **[Sentry](src/sentry)** - Retrieving and analyzing issues from Sentry.io
+- **[Slack](src/slack)** - Channel management and messaging capabilities
+- **[Sqlite](src/sqlite)** - Database interaction and business intelligence capabilities
+
+## 🤝 Third-Party Servers
+
+### 🎖️ Official Integrations
+
+Official integrations are maintained by companies building production ready MCP servers for their platforms.
+
+-
**[Cloudflare](https://github.com/cloudflare/mcp-server-cloudflare)** - Deploy, configure & interrogate your resources on the Cloudflare developer platform (e.g. Workers/KV/R2/D1)
+- **[Raygun](https://github.com/MindscapeHQ/mcp-server-raygun)** - Interact with your crash reporting and real using monitoring data on your Raygun account
+-
**[E2B](https://github.com/e2b-dev/mcp-server)** - Run code in secure sandboxes hosted by [E2B](https://e2b.dev)
+- **[Neon](https://github.com/neondatabase/mcp-server-neon)** - Interact with the Neon serverless Postgres platform
+-
**[Tinybird](https://github.com/tinybirdco/mcp-tinybird)** - Interact with Tinybird serverless ClickHouse platform
+-
[Search1API](https://github.com/fatwang2/search1api-mcp) - One API for Search, Crawling, and Sitemaps
+-
**[Qdrant](https://github.com/qdrant/mcp-server-qdrant/)** - Implement semantic memory layer on top of the Qdrant vector search engine
+
+### 🌎 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.
+
+- **[MCP Installer](https://github.com/anaisbetts/mcp-installer)** - This server is a server that installs other MCP servers for you.
+- **[Spotify MCP](https://github.com/varunneal/spotify-mcp)** - This MCP allows an LLM to play and use Spotify.
+- **[Inoyu](https://github.com/sergehuber/inoyu-mcp-unomi-server)** - Interact with an Apache Unomi CDP customer data platform to retrieve and update customer profiles
+- **[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
+- **[Todoist](https://github.com/abhiz123/todoist-mcp-server)** - Interact with Todoist to manage your tasks.
+- **[Playwright MCP](https://github.com/executeautomation/mcp-playwright)** - This MCP Server will help you run browser automation and webscraping using Playwright
+- **[AWS](https://github.com/rishikavikondala/mcp-server-aws)** - Perform operations on your AWS resources using an LLM
+- **[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/)
+- **[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.
+
+## 📚 Resources
+
+Additional resources on MCP.
+
+- **[Awesome MCP Servers by punkpeye](https://github.com/punkpeye/awesome-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)** - A curated list of MCP servers by **[wong2](https://github.com/wong2)**
+- **[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)**
+- **[mcp-get](https://mcp-get.com)** - Command line tool for installing and managing MCP servers by **[Michael Latman](https://github.com/michaellatman)**
## 🚀 Getting Started
### Using MCP Servers in this Repository
-Typescript-based servers in this repository can be used directly with `npx`.
+Typescript-based servers in this repository can be used directly with `npx`.
For example, this will start the [Memory](src/memory) server:
```sh
npx -y @modelcontextprotocol/server-memory
```
-Python-based servers in this repository can be used directly with [`uvx`](https://docs.astral.sh/uv/concepts/tools/) or [`pip`](https://pypi.org/project/pip/). `uvx` is recommended for ease of use and setup.
+Python-based servers in this repository can be used directly with [`uvx`](https://docs.astral.sh/uv/concepts/tools/) or [`pip`](https://pypi.org/project/pip/). `uvx` is recommended for ease of use and setup.
For example, this will start the [Git](src/git) server:
```sh
diff --git a/package-lock.json b/package-lock.json
index 3079d7c6..c73f44ee 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,24 +1,26 @@
{
"name": "@modelcontextprotocol/servers",
- "version": "0.5.1",
+ "version": "0.6.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@modelcontextprotocol/servers",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"workspaces": [
"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": "*"
}
},
@@ -167,6 +169,10 @@
"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
@@ -203,6 +209,10 @@
"resolved": "src/puppeteer",
"link": true
},
+ "node_modules/@modelcontextprotocol/server-sequential-thinking": {
+ "resolved": "src/sequentialthinking",
+ "link": true
+ },
"node_modules/@modelcontextprotocol/server-slack": {
"resolved": "src/slack",
"link": true
@@ -381,6 +391,21 @@
"@types/send": "*"
}
},
+ "node_modules/@types/yargs": {
+ "version": "17.0.33",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+ "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "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",
@@ -491,6 +516,16 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
+ "node_modules/axios": {
+ "version": "1.7.8",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz",
+ "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/b4a": {
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
@@ -569,6 +604,14 @@
"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",
@@ -614,6 +657,17 @@
"node": ">= 0.8"
}
},
+ "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",
@@ -660,6 +714,20 @@
"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"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -694,6 +762,17 @@
"node": ">=6"
}
},
+ "node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "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",
@@ -841,6 +920,38 @@
"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"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -857,6 +968,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "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",
@@ -901,6 +1023,17 @@
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz",
"integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg=="
},
+ "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==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -1045,6 +1178,67 @@
"node": ">= 0.6"
}
},
+ "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==",
+ "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"
+ },
+ "engines": {
+ "node": "^14.18.0 || ^16.14.0 || >=18.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "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.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
@@ -1184,6 +1378,25 @@
"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"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/foreground-child": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
@@ -1589,6 +1802,14 @@
"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",
@@ -1721,6 +1942,37 @@
"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"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -1833,6 +2085,11 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
+ "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",
@@ -1857,6 +2114,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "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=="
+ },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -1895,6 +2157,17 @@
"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",
@@ -1989,6 +2262,31 @@
}
}
},
+ "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_modules/object-inspect": {
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
@@ -2025,6 +2323,20 @@
"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==",
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "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",
@@ -2609,6 +2921,107 @@
"node": ">=4"
}
},
+ "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",
@@ -2954,6 +3367,17 @@
"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==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -2999,6 +3423,17 @@
"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"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -3077,6 +3512,14 @@
"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/url-template": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
@@ -3280,10 +3723,10 @@
},
"src/brave-search": {
"name": "@modelcontextprotocol/server-brave-search",
- "version": "0.5.2",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0"
+ "@modelcontextprotocol/sdk": "1.0.1"
},
"bin": {
"mcp-server-brave-search": "dist/index.js"
@@ -3294,6 +3737,16 @@
"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/brave-search/node_modules/@types/node": {
"version": "20.17.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz",
@@ -3324,12 +3777,82 @@
"typescript": "^5.6.2"
}
},
- "src/everything": {
- "name": "@modelcontextprotocol/server-everything",
- "version": "0.5.1",
+ "src/everart": {
+ "name": "@modelcontextprotocol/server-everart",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "0.5.0",
+ "everart": "^1.0.0",
+ "node-fetch": "^3.3.2",
+ "open": "^9.1.0"
+ },
+ "bin": {
+ "mcp-server-everart": "dist/index.js"
+ },
+ "devDependencies": {
+ "@types/node": "^20.11.0",
+ "shx": "^0.3.4",
+ "typescript": "^5.3.3"
+ }
+ },
+ "src/everart/node_modules/@types/node": {
+ "version": "20.17.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.9.tgz",
+ "integrity": "sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~6.19.2"
+ }
+ },
+ "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",
"express": "^4.21.1",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.23.5"
@@ -3343,12 +3866,22 @@
"typescript": "^5.6.2"
}
},
+ "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==",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "raw-body": "^3.0.0",
+ "zod": "^3.23.8"
+ }
+ },
"src/filesystem": {
"name": "@modelcontextprotocol/server-filesystem",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"glob": "^10.3.10",
"zod-to-json-schema": "^3.23.5"
},
@@ -3361,6 +3894,16 @@
"typescript": "^5.3.3"
}
},
+ "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==",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "raw-body": "^3.0.0",
+ "zod": "^3.23.8"
+ }
+ },
"src/filesystem/node_modules/@types/node": {
"version": "20.17.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz",
@@ -3417,11 +3960,11 @@
},
"src/gdrive": {
"name": "@modelcontextprotocol/server-gdrive",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
"@google-cloud/local-auth": "^3.0.1",
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"googleapis": "^144.0.0"
},
"bin": {
@@ -3433,6 +3976,16 @@
"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/gdrive/node_modules/@types/node": {
"version": "22.9.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz",
@@ -3444,10 +3997,10 @@
},
"src/github": {
"name": "@modelcontextprotocol/server-github",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"@types/node-fetch": "^2.6.12",
"node-fetch": "^3.3.2",
"zod-to-json-schema": "^3.23.5"
@@ -3461,9 +4014,9 @@
}
},
"src/github/node_modules/@modelcontextprotocol/sdk": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz",
- "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==",
+ "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",
@@ -3496,10 +4049,11 @@
}
},
"src/gitlab": {
- "version": "0.5.1",
+ "name": "@modelcontextprotocol/server-gitlab",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"@types/node-fetch": "^2.6.12",
"node-fetch": "^3.3.2",
"zod-to-json-schema": "^3.23.5"
@@ -3513,9 +4067,9 @@
}
},
"src/gitlab/node_modules/@modelcontextprotocol/sdk": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz",
- "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==",
+ "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",
@@ -3549,10 +4103,10 @@
},
"src/google-maps": {
"name": "@modelcontextprotocol/server-google-maps",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"@types/node-fetch": "^2.6.12",
"node-fetch": "^3.3.2"
},
@@ -3565,10 +4119,9 @@
}
},
"src/google-maps/node_modules/@modelcontextprotocol/sdk": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz",
- "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==",
- "license": "MIT",
+ "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",
@@ -3602,10 +4155,10 @@
},
"src/memory": {
"name": "@modelcontextprotocol/server-memory",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0"
+ "@modelcontextprotocol/sdk": "1.0.1"
},
"bin": {
"mcp-server-memory": "dist/index.js"
@@ -3616,6 +4169,16 @@
"typescript": "^5.6.2"
}
},
+ "src/memory/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/memory/node_modules/@types/node": {
"version": "22.9.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz",
@@ -3627,10 +4190,10 @@
},
"src/postgres": {
"name": "@modelcontextprotocol/server-postgres",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"pg": "^8.13.0"
},
"bin": {
@@ -3643,10 +4206,9 @@
}
},
"src/postgres/node_modules/@modelcontextprotocol/sdk": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz",
- "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==",
- "license": "MIT",
+ "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",
@@ -3655,10 +4217,10 @@
},
"src/puppeteer": {
"name": "@modelcontextprotocol/server-puppeteer",
- "version": "0.5.1",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"puppeteer": "^23.4.0"
},
"bin": {
@@ -3669,12 +4231,50 @@
"typescript": "^5.6.2"
}
},
- "src/slack": {
- "name": "@modelcontextprotocol/server-slack",
- "version": "0.5.1",
+ "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/sequentialthinking": {
+ "name": "@modelcontextprotocol/server-sequential-thinking",
+ "version": "0.6.2",
"license": "MIT",
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0"
+ "@modelcontextprotocol/sdk": "0.5.0",
+ "chalk": "^5.3.0",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "mcp-server-sequential-thinking": "dist/index.js"
+ },
+ "devDependencies": {
+ "@types/node": "^20.11.0",
+ "@types/yargs": "^17.0.32",
+ "shx": "^0.3.4",
+ "typescript": "^5.3.3"
+ }
+ },
+ "src/sequentialthinking/node_modules/@types/node": {
+ "version": "20.17.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.9.tgz",
+ "integrity": "sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~6.19.2"
+ }
+ },
+ "src/slack": {
+ "name": "@modelcontextprotocol/server-slack",
+ "version": "0.6.2",
+ "license": "MIT",
+ "dependencies": {
+ "@modelcontextprotocol/sdk": "1.0.1"
},
"bin": {
"mcp-server-slack": "dist/index.js"
@@ -3686,10 +4286,9 @@
}
},
"src/slack/node_modules/@modelcontextprotocol/sdk": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz",
- "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==",
- "license": "MIT",
+ "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",
diff --git a/package.json b/package.json
index 19240a5e..0203ca98 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "@modelcontextprotocol/servers",
"private": true,
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "Model Context Protocol servers",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -26,6 +26,8 @@
"@modelcontextprotocol/server-slack": "*",
"@modelcontextprotocol/server-brave-search": "*",
"@modelcontextprotocol/server-memory": "*",
- "@modelcontextprotocol/server-filesystem": "*"
+ "@modelcontextprotocol/server-filesystem": "*",
+ "@modelcontextprotocol/server-everart": "*",
+ "@modelcontextprotocol/server-sequential-thinking": "*"
}
-}
+}
\ No newline at end of file
diff --git a/src/brave-search/package.json b/src/brave-search/package.json
index 3e68d358..70ce9d00 100644
--- a/src/brave-search/package.json
+++ b/src/brave-search/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-brave-search",
- "version": "0.5.2",
+ "version": "0.6.2",
"description": "MCP server for Brave Search API integration",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,11 +19,11 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0"
+ "@modelcontextprotocol/sdk": "1.0.1"
},
"devDependencies": {
"@types/node": "^20.10.0",
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/everart/README.md b/src/everart/README.md
new file mode 100644
index 00000000..545f5dfa
--- /dev/null
+++ b/src/everart/README.md
@@ -0,0 +1,73 @@
+# 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:
+```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.
+```
diff --git a/src/everart/index.ts b/src/everart/index.ts
new file mode 100644
index 00000000..bfdb2277
--- /dev/null
+++ b/src/everart/index.ts
@@ -0,0 +1,160 @@
+#!/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
new file mode 100644
index 00000000..189ca650
--- /dev/null
+++ b/src/everart/package.json
@@ -0,0 +1,32 @@
+{
+ "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": "^20.11.0",
+ "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
new file mode 100644
index 00000000..ec5da158
--- /dev/null
+++ b/src/everart/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./dist",
+ "rootDir": "."
+ },
+ "include": [
+ "./**/*.ts"
+ ]
+}
diff --git a/src/everything/package.json b/src/everything/package.json
index 29df070b..0344f2f1 100644
--- a/src/everything/package.json
+++ b/src/everything/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-everything",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server that exercises all the features of the MCP protocol",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,7 +19,7 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"express": "^4.21.1",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.23.5"
@@ -29,4 +29,4 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/fetch/README.md b/src/fetch/README.md
index ffdd01b0..bc8f0f61 100644
--- a/src/fetch/README.md
+++ b/src/fetch/README.md
@@ -2,20 +2,27 @@
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.
-Presently the server only supports fetching HTML content.
+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
- `fetch` - Fetches a URL from the internet and extracts its contents as markdown.
+ - `url` (string, required): URL to fetch
+ - `max_length` (integer, optional): Maximum number of characters to return (default: 5000)
+ - `start_index` (integer, optional): Start content from this character index (default: 0)
+ - `raw` (boolean, optional): Get raw content without markdown conversion (default: false)
### Prompts
- **fetch**
- Fetch a URL and extract its contents as markdown
- - Argument: `url` (string, required): URL to fetch
+ - Arguments:
+ - `url` (string, required): URL to fetch
## Installation
+Optionally: Install node.js, this will cause the fetch server to use a different HTML simplifier that is more robust.
+
### Using uv (recommended)
When using [`uv`](https://docs.astral.sh/uv/) no specific installation is needed. We will
@@ -67,36 +74,6 @@ Add to your Claude settings:
```
-### Configure for Zed
-
-Add to your Zed settings.json:
-
-
-Using uvx
-
-```json
-"context_servers": [
- "mcp-server-fetch": {
- "command": "uvx",
- "args": ["mcp-server-fetch"]
- }
-],
-```
-
-
-
-Using pip installation
-
-```json
-"context_servers": {
- "mcp-server-fetch": {
- "command": "python",
- "args": ["-m", "mcp_server_fetch"]
- }
-},
-```
-
-
### Customization - robots.txt
By default, the server will obey a websites robots.txt file if the request came from the model (via a tool), but not if
@@ -105,7 +82,7 @@ the request was user initiated (via a prompt). This can be disabled by adding th
### Customization - User-agent
-By default, depending on if the request came from the model (via a tool), or was user initiated (via a prompt), the
+By default, depending on if the request came from the model (via a tool), or was user initiated (via a prompt), the
server will use either the user-agent
```
ModelContextProtocol/1.0 (Autonomous; +https://github.com/modelcontextprotocol/servers)
diff --git a/src/fetch/pyproject.toml b/src/fetch/pyproject.toml
index 25eac8d8..1d43cae8 100644
--- a/src/fetch/pyproject.toml
+++ b/src/fetch/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "mcp-server-fetch"
-version = "0.1.2"
+version = "0.6.2"
description = "A Model Context Protocol server providing tools to fetch and convert web content for usage by LLMs"
readme = "README.md"
requires-python = ">=3.10"
diff --git a/src/fetch/src/mcp_server_fetch/server.py b/src/fetch/src/mcp_server_fetch/server.py
index 63cae6fa..6e831ff6 100644
--- a/src/fetch/src/mcp_server_fetch/server.py
+++ b/src/fetch/src/mcp_server_fetch/server.py
@@ -1,4 +1,4 @@
-from typing import Optional
+from typing import Annotated, Tuple
from urllib.parse import urlparse, urlunparse
import markdownify
@@ -17,24 +17,42 @@ from mcp.types import (
INTERNAL_ERROR,
)
from protego import Protego
-from pydantic import BaseModel, Field
+from pydantic import BaseModel, Field, AnyUrl
DEFAULT_USER_AGENT_AUTONOMOUS = "ModelContextProtocol/1.0 (Autonomous; +https://github.com/modelcontextprotocol/servers)"
DEFAULT_USER_AGENT_MANUAL = "ModelContextProtocol/1.0 (User-Specified; +https://github.com/modelcontextprotocol/servers)"
-def extract_content(html: str) -> str:
- ret = readabilipy.simple_json.simple_json_from_html_string(html)
- if not ret["plain_content"]:
+def extract_content_from_html(html: str) -> str:
+ """Extract and convert HTML content to Markdown format.
+
+ Args:
+ html: Raw HTML content to process
+
+ Returns:
+ Simplified markdown version of the content
+ """
+ ret = readabilipy.simple_json.simple_json_from_html_string(
+ html, use_readability=True
+ )
+ if not ret["content"]:
return "Page failed to be simplified from HTML"
content = markdownify.markdownify(
- ret["plain_content"],
+ ret["content"],
heading_style=markdownify.ATX,
)
return content
def get_robots_txt_url(url: str) -> str:
+ """Get the robots.txt URL for a given website URL.
+
+ Args:
+ url: Website URL to get robots.txt for
+
+ Returns:
+ URL of the robots.txt file
+ """
# Parse the URL into components
parsed = urlparse(url)
@@ -44,10 +62,10 @@ def get_robots_txt_url(url: str) -> str:
return robots_url
-async def check_may_autonomously_fetch_url(url: str, user_agent: str):
+async def check_may_autonomously_fetch_url(url: str, user_agent: str) -> None:
"""
Check if the URL can be fetched by the user agent according to the robots.txt file.
- Raises an McpError if not.
+ Raises a McpError if not.
"""
from httpx import AsyncClient, HTTPError
@@ -56,7 +74,9 @@ async def check_may_autonomously_fetch_url(url: str, user_agent: str):
async with AsyncClient() as client:
try:
response = await client.get(
- robot_txt_url, headers={"User-Agent": user_agent}
+ robot_txt_url,
+ follow_redirects=True,
+ headers={"User-Agent": user_agent},
)
except HTTPError:
raise McpError(
@@ -75,7 +95,7 @@ async def check_may_autonomously_fetch_url(url: str, user_agent: str):
line for line in robot_txt.splitlines() if not line.strip().startswith("#")
)
robot_parser = Protego.parse(processed_robot_txt)
- if not robot_parser.can_fetch(url, user_agent):
+ if not robot_parser.can_fetch(str(url), user_agent):
raise McpError(
INTERNAL_ERROR,
f"The sites robots.txt ({robot_txt_url}), specifies that autonomous fetching of this page is not allowed, "
@@ -87,34 +107,85 @@ async def check_may_autonomously_fetch_url(url: str, user_agent: str):
)
-async def fetch_url(url: str, user_agent: str) -> str:
+async def fetch_url(
+ url: str, user_agent: str, force_raw: bool = False
+) -> Tuple[str, str]:
+ """
+ Fetch the URL and return the content in a form ready for the LLM, as well as a prefix string with status information.
+ """
from httpx import AsyncClient, HTTPError
async with AsyncClient() as client:
try:
response = await client.get(
- url, follow_redirects=True, headers={"User-Agent": user_agent}
+ url,
+ follow_redirects=True,
+ headers={"User-Agent": user_agent},
+ timeout=30,
)
- except HTTPError:
- raise McpError(INTERNAL_ERROR, f"Failed to fetch {url}")
+ except HTTPError as e:
+ raise McpError(INTERNAL_ERROR, f"Failed to fetch {url}: {e!r}")
if response.status_code >= 400:
raise McpError(
INTERNAL_ERROR,
f"Failed to fetch {url} - status code {response.status_code}",
)
- page_html = response.text
+ page_raw = response.text
- return extract_content(page_html)
+ content_type = response.headers.get("content-type", "")
+ is_page_html = (
+ " None:
+ """Run the fetch MCP server.
+
+ Args:
+ custom_user_agent: Optional custom User-Agent string to use for requests
+ ignore_robots_txt: Whether to ignore robots.txt restrictions
+ """
server = Server("mcp-fetch")
user_agent_autonomous = custom_user_agent or DEFAULT_USER_AGENT_AUTONOMOUS
user_agent_manual = custom_user_agent or DEFAULT_USER_AGENT_MANUAL
@@ -124,7 +195,7 @@ async def serve(
return [
Tool(
name="fetch",
- description="""Fetches a URL from the internet and extracts its contents as markdown.
+ description="""Fetches a URL from the internet and optionally extracts its contents as markdown.
Although originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.""",
inputSchema=Fetch.model_json_schema(),
@@ -147,15 +218,25 @@ Although originally you did not have internet access, and were advised to refuse
@server.call_tool()
async def call_tool(name, arguments: dict) -> list[TextContent]:
- url = arguments.get("url")
+ try:
+ args = Fetch(**arguments)
+ except ValueError as e:
+ raise McpError(INVALID_PARAMS, str(e))
+
+ url = str(args.url)
if not url:
raise McpError(INVALID_PARAMS, "URL is required")
if not ignore_robots_txt:
await check_may_autonomously_fetch_url(url, user_agent_autonomous)
- content = await fetch_url(url, user_agent_autonomous)
- return [TextContent(type="text", text=f"Contents of {url}:\n{content}")]
+ content, prefix = await fetch_url(
+ url, user_agent_autonomous, force_raw=args.raw
+ )
+ if len(content) > args.max_length:
+ content = content[args.start_index : args.start_index + args.max_length]
+ content += f"\n\nContent truncated. Call the fetch tool with a start_index of {args.start_index + args.max_length} to get more content."
+ return [TextContent(type="text", text=f"{prefix}Contents of {url}:\n{content}")]
@server.get_prompt()
async def get_prompt(name: str, arguments: dict | None) -> GetPromptResult:
@@ -165,7 +246,7 @@ Although originally you did not have internet access, and were advised to refuse
url = arguments["url"]
try:
- content = await fetch_url(url, user_agent_manual)
+ content, prefix = await fetch_url(url, user_agent_manual)
# TODO: after SDK bug is addressed, don't catch the exception
except McpError as e:
return GetPromptResult(
@@ -181,7 +262,7 @@ Although originally you did not have internet access, and were advised to refuse
description=f"Contents of {url}",
messages=[
PromptMessage(
- role="user", content=TextContent(type="text", text=content)
+ role="user", content=TextContent(type="text", text=prefix + content)
)
],
)
diff --git a/src/fetch/uv.lock b/src/fetch/uv.lock
index baa06662..bb114910 100644
--- a/src/fetch/uv.lock
+++ b/src/fetch/uv.lock
@@ -182,18 +182,17 @@ wheels = [
[[package]]
name = "httpx"
-version = "0.27.2"
+version = "0.28.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "certifi" },
{ name = "httpcore" },
{ name = "idna" },
- { name = "sniffio" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 }
+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/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 },
+ { url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551 },
]
[[package]]
@@ -298,15 +297,15 @@ wheels = [
[[package]]
name = "markdownify"
-version = "0.13.1"
+version = "0.14.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "beautifulsoup4" },
{ name = "six" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/19/5a/bd1b685ee9efbfb0b22774a30188dfb4048c64e8a6c80a65a7f207af4ea1/markdownify-0.13.1.tar.gz", hash = "sha256:ab257f9e6bd4075118828a28c9d02f8a4bfeb7421f558834aa79b2dfeb32a098", size = 13609 }
+sdist = { url = "https://files.pythonhosted.org/packages/1b/75/483a4bcca436fe88d02dc7686c372631d833848951b368700bdc0c770bb7/markdownify-0.14.1.tar.gz", hash = "sha256:a62a7a216947ed0b8dafb95b99b2ef4a0edd1e18d5653c656f68f03db2bfb2f1", size = 14332 }
wheels = [
- { url = "https://files.pythonhosted.org/packages/6c/e9/6e2757a670b8c48bc48eff1c20cb9d71f1476e844038bdbdb76f17e6a12b/markdownify-0.13.1-py3-none-any.whl", hash = "sha256:1d181d43d20902bcc69d7be85b5316ed174d0dda72ff56e14ae4c95a4a407d22", size = 10800 },
+ { url = "https://files.pythonhosted.org/packages/65/0b/74cec93a7b05edf4fc3ea1c899fe8a37f041d7b9d303c75abf7a162924e0/markdownify-0.14.1-py3-none-any.whl", hash = "sha256:4c46a6c0c12c6005ddcd49b45a5a890398b002ef51380cd319db62df5e09bc2a", size = 11530 },
]
[[package]]
@@ -328,7 +327,7 @@ wheels = [
[[package]]
name = "mcp-server-fetch"
-version = "0.1.2"
+version = "0.6.2"
source = { editable = "." }
dependencies = [
{ name = "markdownify" },
@@ -381,16 +380,16 @@ wheels = [
[[package]]
name = "pydantic"
-version = "2.10.1"
+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/c4/bd/7fc610993f616d2398958d0028d15eaf53bde5f80cb2edb7aa4f1feaf3a7/pydantic-2.10.1.tar.gz", hash = "sha256:a4daca2dc0aa429555e0656d6bf94873a7dc5f54ee42b1f5873d666fb3f35560", size = 783717 }
+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/e0/fc/fda48d347bd50a788dd2a0f318a52160f911b86fc2d8b4c86f4d7c9bceea/pydantic-2.10.1-py3-none-any.whl", hash = "sha256:a8d20db84de64cf4a7d59e899c2caf0fe9d660c7cfc482528e7020d7dd189a7e", size = 455329 },
+ { url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364 },
]
[[package]]
@@ -582,27 +581,27 @@ wheels = [
[[package]]
name = "ruff"
-version = "0.8.0"
+version = "0.8.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/b2/d6/a2373f3ba7180ddb44420d2a9d1f1510e1a4d162b3d27282bedcb09c8da9/ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44", size = 3276537 }
+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/ec/77/e889ee3ce7fd8baa3ed1b77a03b9fb8ec1be68be1418261522fd6a5405e0/ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea", size = 10518283 },
- { url = "https://files.pythonhosted.org/packages/da/c8/0a47de01edf19fb22f5f9b7964f46a68d0bdff20144d134556ffd1ba9154/ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b", size = 10317691 },
- { url = "https://files.pythonhosted.org/packages/41/17/9885e4a0eeae07abd2a4ebabc3246f556719f24efa477ba2739146c4635a/ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a", size = 9940999 },
- { url = "https://files.pythonhosted.org/packages/3e/cd/46b6f7043597eb318b5f5482c8ae8f5491cccce771e85f59d23106f2d179/ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99", size = 10772437 },
- { url = "https://files.pythonhosted.org/packages/5d/87/afc95aeb8bc78b1d8a3461717a4419c05aa8aa943d4c9cbd441630f85584/ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c", size = 10299156 },
- { url = "https://files.pythonhosted.org/packages/65/fa/04c647bb809c4d65e8eae1ed1c654d9481b21dd942e743cd33511687b9f9/ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9", size = 11325819 },
- { url = "https://files.pythonhosted.org/packages/90/26/7dad6e7d833d391a8a1afe4ee70ca6f36c4a297d3cca83ef10e83e9aacf3/ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362", size = 12023927 },
- { url = "https://files.pythonhosted.org/packages/24/a0/be5296dda6428ba8a13bda8d09fbc0e14c810b485478733886e61597ae2b/ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df", size = 11589702 },
- { url = "https://files.pythonhosted.org/packages/26/3f/7602eb11d2886db545834182a9dbe500b8211fcbc9b4064bf9d358bbbbb4/ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3", size = 12782936 },
- { url = "https://files.pythonhosted.org/packages/4c/5d/083181bdec4ec92a431c1291d3fff65eef3ded630a4b55eb735000ef5f3b/ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c", size = 11138488 },
- { url = "https://files.pythonhosted.org/packages/b7/23/c12cdef58413cee2436d6a177aa06f7a366ebbca916cf10820706f632459/ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2", size = 10744474 },
- { url = "https://files.pythonhosted.org/packages/29/61/a12f3b81520083cd7c5caa24ba61bb99fd1060256482eff0ef04cc5ccd1b/ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70", size = 10369029 },
- { url = "https://files.pythonhosted.org/packages/08/2a/c013f4f3e4a54596c369cee74c24870ed1d534f31a35504908b1fc97017a/ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd", size = 10867481 },
- { url = "https://files.pythonhosted.org/packages/d5/f7/685b1e1d42a3e94ceb25eab23c70bdd8c0ab66a43121ef83fe6db5a58756/ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426", size = 11237117 },
- { url = "https://files.pythonhosted.org/packages/03/20/401132c0908e8837625e3b7e32df9962e7cd681a4df1e16a10e2a5b4ecda/ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468", size = 8783511 },
- { url = "https://files.pythonhosted.org/packages/1d/5c/4d800fca7854f62ad77f2c0d99b4b585f03e2d87a6ec1ecea85543a14a3c/ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f", size = 9559876 },
- { url = "https://files.pythonhosted.org/packages/5b/bc/cc8a6a5ca4960b226dc15dd8fb511dd11f2014ff89d325c0b9b9faa9871f/ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6", size = 8939733 },
+ { 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]]
diff --git a/src/filesystem/package.json b/src/filesystem/package.json
index 581ad818..e6e2f43d 100644
--- a/src/filesystem/package.json
+++ b/src/filesystem/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-filesystem",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for filesystem access",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,7 +19,7 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"glob": "^10.3.10",
"zod-to-json-schema": "^3.23.5"
},
@@ -28,4 +28,4 @@
"shx": "^0.3.4",
"typescript": "^5.3.3"
}
-}
+}
\ No newline at end of file
diff --git a/src/gdrive/package.json b/src/gdrive/package.json
index 5b16edae..26e2bfe5 100644
--- a/src/gdrive/package.json
+++ b/src/gdrive/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-gdrive",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for interacting with Google Drive",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -20,7 +20,7 @@
},
"dependencies": {
"@google-cloud/local-auth": "^3.0.1",
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"googleapis": "^144.0.0"
},
"devDependencies": {
@@ -28,4 +28,4 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/git/README.md b/src/git/README.md
index 49f45324..caf01294 100644
--- a/src/git/README.md
+++ b/src/git/README.md
@@ -53,6 +53,13 @@ Please note that mcp-server-git is currently in early development. The functiona
- `max_count` (number, optional): Maximum number of commits to show (default: 10)
- Returns: Array of commit entries with hash, author, date, and message
+8. `git_create_branch`
+ - Creates a new branch
+ - Inputs:
+ - `repo_path` (string): Path to Git repository
+ - `branch_name` (string): Name of the new branch
+ - `start_point` (string, optional): Starting point for the new branch
+ - Returns: Confirmation of branch creation
## Installation
@@ -117,8 +124,10 @@ Add to your Zed settings.json:
```json
"context_servers": [
"mcp-server-git": {
- "command": "uvx",
- "args": ["mcp-server-git"]
+ "command": {
+ "path": "uvx",
+ "args": ["mcp-server-git"]
+ }
}
],
```
@@ -130,8 +139,10 @@ Add to your Zed settings.json:
```json
"context_servers": {
"mcp-server-git": {
- "command": "python",
- "args": ["-m", "mcp_server_git"]
+ "command": {
+ "path": "python",
+ "args": ["-m", "mcp_server_git"]
+ }
}
},
```
@@ -152,6 +163,29 @@ cd path/to/servers/src/git
npx @modelcontextprotocol/inspector uv run mcp-server-git
```
+Running `tail -n 20 -f ~/Library/Logs/Claude/mcp*.log` will show the logs from the server and may
+help you debug any issues.
+
+## Development
+
+If you are doing local development, there are two ways to test your changes:
+
+1. Run the MCP inspector to test your changes. See [Debugging](#debugging) for run instructions.
+
+2. Test using the Claude desktop app. Add the following to your `claude_desktop_config.json`:
+
+```json
+"git": {
+ "command": "uv",
+ "args": [
+ "--directory",
+ "//mcp-servers/src/git",
+ "run",
+ "mcp-server-git"
+ ]
+}
+```
+
## 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/git/pyproject.toml b/src/git/pyproject.toml
index 92e19c78..373529c0 100644
--- a/src/git/pyproject.toml
+++ b/src/git/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "mcp-server-git"
-version = "0.5.1"
+version = "0.6.2"
description = "A Model Context Protocol server providing tools to read, search, and manipulate Git repositories programmatically via LLMs"
readme = "README.md"
requires-python = ">=3.10"
@@ -18,7 +18,7 @@ classifiers = [
dependencies = [
"click>=8.1.7",
"gitpython>=3.1.43",
- "mcp>=0.6.0",
+ "mcp>=1.0.0",
"pydantic>=2.0.0",
]
diff --git a/src/git/src/mcp_server_git/server.py b/src/git/src/mcp_server_git/server.py
index fe1e3f59..02fae584 100644
--- a/src/git/src/mcp_server_git/server.py
+++ b/src/git/src/mcp_server_git/server.py
@@ -39,6 +39,11 @@ class GitLog(BaseModel):
repo_path: str
max_count: int = 10
+class GitCreateBranch(BaseModel):
+ repo_path: str
+ branch_name: str
+ base_branch: str | None = None
+
class GitTools(str, Enum):
STATUS = "git_status"
DIFF_UNSTAGED = "git_diff_unstaged"
@@ -47,6 +52,7 @@ class GitTools(str, Enum):
ADD = "git_add"
RESET = "git_reset"
LOG = "git_log"
+ CREATE_BRANCH = "git_create_branch"
def git_status(repo: git.Repo) -> str:
return repo.git.status()
@@ -81,6 +87,15 @@ def git_log(repo: git.Repo, max_count: int = 10) -> list[str]:
)
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]
+ else:
+ base = repo.active_branch
+
+ repo.create_head(branch_name, base)
+ return f"Created branch '{branch_name}' from '{base.name}'"
+
async def serve(repository: Path | None) -> None:
logger = logging.getLogger(__name__)
@@ -132,6 +147,11 @@ async def serve(repository: Path | None) -> None:
description="Shows the commit logs",
inputSchema=GitLog.schema(),
),
+ Tool(
+ name=GitTools.CREATE_BRANCH,
+ description="Creates a new branch from an optional base branch",
+ inputSchema=GitCreateBranch.schema(),
+ ),
]
async def list_repos() -> Sequence[str]:
@@ -218,6 +238,17 @@ async def serve(repository: Path | None) -> None:
text="Commit history:\n" + "\n".join(log)
)]
+ case GitTools.CREATE_BRANCH:
+ result = git_create_branch(
+ repo,
+ arguments["branch_name"],
+ arguments.get("base_branch")
+ )
+ return [TextContent(
+ type="text",
+ text=result
+ )]
+
case _:
raise ValueError(f"Unknown tool: {name}")
diff --git a/src/git/uv.lock b/src/git/uv.lock
index 3411aa00..4b585e9a 100644
--- a/src/git/uv.lock
+++ b/src/git/uv.lock
@@ -146,7 +146,7 @@ wheels = [
[[package]]
name = "mcp"
-version = "0.9.1"
+version = "1.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@@ -156,14 +156,14 @@ dependencies = [
{ name = "sse-starlette" },
{ name = "starlette" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/e7/1c/932818470ffd49c33509110c835101a8dc4c9cdd06028b9f647fb3dde237/mcp-0.9.1.tar.gz", hash = "sha256:e8509a37c2ab546095788ed170e0fb4d7ce0cf5a3ee56b6449c78af27321a425", size = 78218 }
+sdist = { url = "https://files.pythonhosted.org/packages/77/f2/067b1fc114e8d3ae4af02fc4f4ed8971a2c4900362d976fabe0f4e9a3418/mcp-1.1.0.tar.gz", hash = "sha256:e3c8d6df93a4de90230ea944dd667730744a3cd91a4cc0ee66a5acd53419e100", size = 83802 }
wheels = [
- { url = "https://files.pythonhosted.org/packages/b3/a0/2ee813d456b57a726d583868417d1ad900fbe12ee3c8cd866e3e804ca486/mcp-0.9.1-py3-none-any.whl", hash = "sha256:7f640fcfb0be486aa510594df309920ae1d375cdca1f8aff21db3a96d837f303", size = 31562 },
+ { url = "https://files.pythonhosted.org/packages/b9/3e/aef19ac08a6f9a347c086c4e628c2f7329659828cbe92ffd524ec2aac833/mcp-1.1.0-py3-none-any.whl", hash = "sha256:44aa4d2e541f0924d6c344aa7f96b427a6ee1df2fab70b5f9ae2f8777b3f05f2", size = 36576 },
]
[[package]]
name = "mcp-server-git"
-version = "0.4.1"
+version = "0.6.2"
source = { editable = "." }
dependencies = [
{ name = "click" },
@@ -182,7 +182,7 @@ dev = [
requires-dist = [
{ name = "click", specifier = ">=8.1.7" },
{ name = "gitpython", specifier = ">=3.1.43" },
- { name = "mcp", specifier = ">=0.6.0" },
+ { name = "mcp", specifier = ">=1.0.0" },
{ name = "pydantic", specifier = ">=2.0.0" },
]
diff --git a/src/github/index.ts b/src/github/index.ts
index bddd9f46..2d73dee4 100644
--- a/src/github/index.ts
+++ b/src/github/index.ts
@@ -632,161 +632,186 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
};
});
-server.setRequestHandler(
- CallToolRequestSchema,
- async (request: CallToolRequest) => {
- try {
- if (!request.params.arguments) {
- throw new Error("Arguments are required");
+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 forkRepository(
+ args.owner,
+ args.repo,
+ args.organization
+ );
+ return {
+ content: [{ type: "text", text: JSON.stringify(fork, null, 2) }],
+ };
}
- switch (request.params.name) {
- case "fork_repository": {
- const args = ForkRepositorySchema.parse(request.params.arguments);
- const fork = await forkRepository(
- args.owner,
- args.repo,
- args.organization
- );
- return { toolResult: fork };
- }
-
- case "create_branch": {
- const args = CreateBranchSchema.parse(request.params.arguments);
- let sha: string;
- if (args.from_branch) {
- const response = await fetch(
- `https://api.github.com/repos/${args.owner}/${args.repo}/git/refs/heads/${args.from_branch}`,
- {
- headers: {
- Authorization: `token ${GITHUB_PERSONAL_ACCESS_TOKEN}`,
- Accept: "application/vnd.github.v3+json",
- "User-Agent": "github-mcp-server",
- },
- }
- );
-
- if (!response.ok) {
- throw new Error(`Source branch '${args.from_branch}' not found`);
+ case "create_branch": {
+ const args = CreateBranchSchema.parse(request.params.arguments);
+ let sha: string;
+ if (args.from_branch) {
+ const response = await fetch(
+ `https://api.github.com/repos/${args.owner}/${args.repo}/git/refs/heads/${args.from_branch}`,
+ {
+ headers: {
+ Authorization: `token ${GITHUB_PERSONAL_ACCESS_TOKEN}`,
+ Accept: "application/vnd.github.v3+json",
+ "User-Agent": "github-mcp-server",
+ },
}
+ );
- const data = GitHubReferenceSchema.parse(await response.json());
- sha = data.object.sha;
- } else {
- sha = await getDefaultBranchSHA(args.owner, args.repo);
+ if (!response.ok) {
+ throw new Error(`Source branch '${args.from_branch}' not found`);
}
- const branch = await createBranch(args.owner, args.repo, {
- ref: args.branch,
- sha,
- });
-
- return { toolResult: branch };
+ const data = GitHubReferenceSchema.parse(await response.json());
+ sha = data.object.sha;
+ } else {
+ sha = await getDefaultBranchSHA(args.owner, args.repo);
}
- case "search_repositories": {
- const args = SearchRepositoriesSchema.parse(request.params.arguments);
- const results = await searchRepositories(
- args.query,
- args.page,
- args.perPage
- );
- return { toolResult: results };
- }
+ const branch = await createBranch(args.owner, args.repo, {
+ ref: args.branch,
+ sha,
+ });
- case "create_repository": {
- const args = CreateRepositorySchema.parse(request.params.arguments);
- const repository = await createRepository(args);
- return { toolResult: repository };
- }
-
- case "get_file_contents": {
- const args = GetFileContentsSchema.parse(request.params.arguments);
- const contents = await getFileContents(
- args.owner,
- args.repo,
- args.path,
- args.branch
- );
- return { toolResult: contents };
- }
-
- case "create_or_update_file": {
- const args = CreateOrUpdateFileSchema.parse(request.params.arguments);
- const result = await createOrUpdateFile(
- args.owner,
- args.repo,
- args.path,
- args.content,
- args.message,
- args.branch,
- args.sha
- );
- return { toolResult: result };
- }
-
- case "push_files": {
- const args = PushFilesSchema.parse(request.params.arguments);
- const result = await pushFiles(
- args.owner,
- args.repo,
- args.branch,
- args.files,
- args.message
- );
- return { toolResult: result };
- }
-
- case "create_issue": {
- const args = CreateIssueSchema.parse(request.params.arguments);
- const { owner, repo, ...options } = args;
- const issue = await createIssue(owner, repo, options);
- return { toolResult: issue };
- }
-
- case "create_pull_request": {
- const args = CreatePullRequestSchema.parse(request.params.arguments);
- const { owner, repo, ...options } = args;
- const pullRequest = await createPullRequest(owner, repo, options);
- return { toolResult: pullRequest };
- }
-
- case "search_code": {
- const args = SearchCodeSchema.parse(request.params.arguments);
- const results = await searchCode(args);
- return { toolResult: results };
- }
-
- case "search_issues": {
- const args = SearchIssuesSchema.parse(request.params.arguments);
- const results = await searchIssues(args);
- return { toolResult: results };
- }
-
- case "search_users": {
- const args = SearchUsersSchema.parse(request.params.arguments);
- const results = await searchUsers(args);
- return { toolResult: results };
- }
-
- default:
- throw new Error(`Unknown tool: ${request.params.name}`);
+ return {
+ content: [{ type: "text", text: JSON.stringify(branch, null, 2) }],
+ };
}
- } catch (error) {
- if (error instanceof z.ZodError) {
- throw new Error(
- `Invalid arguments: ${error.errors
- .map(
- (e: z.ZodError["errors"][number]) =>
- `${e.path.join(".")}: ${e.message}`
- )
- .join(", ")}`
+
+ case "search_repositories": {
+ const args = SearchRepositoriesSchema.parse(request.params.arguments);
+ const results = await searchRepositories(
+ args.query,
+ args.page,
+ args.perPage
);
+ return {
+ content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
+ };
}
- throw error;
+
+ 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.owner,
+ args.repo,
+ args.path,
+ args.branch
+ );
+ 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.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 = PushFilesSchema.parse(request.params.arguments);
+ const result = await 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 = CreateIssueSchema.parse(request.params.arguments);
+ const { owner, repo, ...options } = args;
+ const issue = await createIssue(owner, repo, options);
+ return {
+ content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
+ };
+ }
+
+ case "create_pull_request": {
+ const args = CreatePullRequestSchema.parse(request.params.arguments);
+ const { owner, repo, ...options } = args;
+ const pullRequest = await createPullRequest(owner, repo, options);
+ return {
+ content: [
+ { type: "text", text: JSON.stringify(pullRequest, null, 2) },
+ ],
+ };
+ }
+
+ case "search_code": {
+ const args = SearchCodeSchema.parse(request.params.arguments);
+ const results = await searchCode(args);
+ return {
+ content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
+ };
+ }
+
+ case "search_issues": {
+ const args = SearchIssuesSchema.parse(request.params.arguments);
+ const results = await searchIssues(args);
+ return {
+ content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
+ };
+ }
+
+ case "search_users": {
+ const args = SearchUsersSchema.parse(request.params.arguments);
+ const results = await searchUsers(args);
+ return {
+ content: [{ type: "text", text: JSON.stringify(results, 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: z.ZodError["errors"][number]) =>
+ `${e.path.join(".")}: ${e.message}`
+ )
+ .join(", ")}`
+ );
+ }
+ throw error;
}
-);
+});
async function runServer() {
const transport = new StdioServerTransport();
diff --git a/src/github/package-lock.json b/src/github/package-lock.json
deleted file mode 100644
index fc0d3962..00000000
--- a/src/github/package-lock.json
+++ /dev/null
@@ -1,551 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-github",
- "version": "0.2.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "@modelcontextprotocol/server-github",
- "version": "0.2.0",
- "license": "MIT",
- "dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
- "@types/node-fetch": "^2.6.12",
- "node-fetch": "^3.3.2"
- },
- "bin": {
- "mcp-server-github": "dist/index.js"
- },
- "devDependencies": {
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
- },
- "node_modules/@modelcontextprotocol/sdk": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz",
- "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
- "node_modules/@types/node": {
- "version": "22.9.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz",
- "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==",
- "dependencies": {
- "undici-types": "~6.19.8"
- }
- },
- "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==",
- "dependencies": {
- "@types/node": "*",
- "form-data": "^4.0.0"
- }
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
- },
- "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==",
- "dev": true
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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==",
- "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",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "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"
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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"
- }
- ],
- "dependencies": {
- "node-domexception": "^1.0.0",
- "web-streams-polyfill": "^3.0.3"
- },
- "engines": {
- "node": "^12.20 || >= 14.13"
- }
- },
- "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==",
- "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==",
- "dependencies": {
- "fetch-blob": "^3.1.2"
- },
- "engines": {
- "node": ">=12.20.0"
- }
- },
- "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/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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==",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "dev": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "node_modules/interpret": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
- "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
- "dev": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.15.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
- "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
- "dev": true,
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "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==",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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"
- }
- ],
- "engines": {
- "node": ">=10.5.0"
- }
- },
- "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"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
- },
- "node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/rechoir": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
- "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
- "dev": true,
- "dependencies": {
- "resolve": "^1.1.6"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
- "dev": true,
- "dependencies": {
- "is-core-module": "^2.13.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
- },
- "node_modules/shelljs": {
- "version": "0.8.5",
- "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
- "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
- "dev": true,
- "dependencies": {
- "glob": "^7.0.0",
- "interpret": "^1.0.0",
- "rechoir": "^0.6.2"
- },
- "bin": {
- "shjs": "bin/shjs"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/shx": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz",
- "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==",
- "dev": true,
- "dependencies": {
- "minimist": "^1.2.3",
- "shelljs": "^0.8.5"
- },
- "bin": {
- "shx": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/typescript": {
- "version": "5.6.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
- "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
- "dev": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/undici-types": {
- "version": "6.19.8",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
- "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "engines": {
- "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==",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
- },
- "node_modules/zod": {
- "version": "3.23.8",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
- "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/src/github/package.json b/src/github/package.json
index e15e486d..0fc2aaeb 100644
--- a/src/github/package.json
+++ b/src/github/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-github",
- "version": "0.6.0",
+ "version": "0.6.2",
"description": "MCP server for using the GitHub API",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,7 +19,7 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"@types/node": "^20.11.0",
"@types/node-fetch": "^2.6.12",
"node-fetch": "^3.3.2",
@@ -30,4 +30,4 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/gitlab/index.ts b/src/gitlab/index.ts
index e246af4d..3c96461c 100644
--- a/src/gitlab/index.ts
+++ b/src/gitlab/index.ts
@@ -437,7 +437,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
case "fork_repository": {
const args = ForkRepositorySchema.parse(request.params.arguments);
const fork = await forkProject(args.project_id, args.namespace);
- return { toolResult: fork };
+ return { content: [{ type: "text", text: JSON.stringify(fork, null, 2) }] };
}
case "create_branch": {
@@ -452,25 +452,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
ref
});
- return { toolResult: branch };
+ 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 { toolResult: results };
+ 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 { toolResult: repository };
+ 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 { toolResult: contents };
+ return { content: [{ type: "text", text: JSON.stringify(contents, null, 2) }] };
}
case "create_or_update_file": {
@@ -483,7 +483,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
args.branch,
args.previous_path
);
- return { toolResult: result };
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
}
case "push_files": {
@@ -494,21 +494,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
args.branch,
args.files.map(f => ({ path: f.file_path, content: f.content }))
);
- return { toolResult: result };
+ 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 { toolResult: issue };
+ 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 { toolResult: mergeRequest };
+ return { content: [{ type: "text", text: JSON.stringify(mergeRequest, null, 2) }] };
}
default:
diff --git a/src/gitlab/package-lock.json b/src/gitlab/package-lock.json
deleted file mode 100644
index 9cb28696..00000000
--- a/src/gitlab/package-lock.json
+++ /dev/null
@@ -1,551 +0,0 @@
-{
- "name": "@modelcontextprotocol/server-gitlab",
- "version": "0.5.1",
- "lockfileVersion": 1,
- "requires": true,
- "packages": {
- "": {
- "name": "@modelcontextprotocol/server-gitlab",
- "version": "0.5.1",
- "license": "MIT",
- "dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
- "@types/node-fetch": "^2.6.12",
- "node-fetch": "^3.3.2"
- },
- "bin": {
- "mcp-server-gitlab": "dist/index.js"
- },
- "devDependencies": {
- "shx": "^0.3.4",
- "typescript": "^5.6.2"
- }
- },
- "node_modules/@modelcontextprotocol/sdk": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz",
- "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==",
- "dependencies": {
- "content-type": "^1.0.5",
- "raw-body": "^3.0.0",
- "zod": "^3.23.8"
- }
- },
- "node_modules/@types/node": {
- "version": "22.9.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz",
- "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==",
- "dependencies": {
- "undici-types": "~6.19.8"
- }
- },
- "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==",
- "dependencies": {
- "@types/node": "*",
- "form-data": "^4.0.0"
- }
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
- },
- "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==",
- "dev": true
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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==",
- "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",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "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"
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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"
- }
- ],
- "dependencies": {
- "node-domexception": "^1.0.0",
- "web-streams-polyfill": "^3.0.3"
- },
- "engines": {
- "node": "^12.20 || >= 14.13"
- }
- },
- "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==",
- "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==",
- "dependencies": {
- "fetch-blob": "^3.1.2"
- },
- "engines": {
- "node": ">=12.20.0"
- }
- },
- "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/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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==",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "dev": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "node_modules/interpret": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
- "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
- "dev": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.15.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
- "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
- "dev": true,
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "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==",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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"
- }
- ],
- "engines": {
- "node": ">=10.5.0"
- }
- },
- "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"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
- },
- "node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/rechoir": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
- "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
- "dev": true,
- "dependencies": {
- "resolve": "^1.1.6"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
- "dev": true,
- "dependencies": {
- "is-core-module": "^2.13.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
- },
- "node_modules/shelljs": {
- "version": "0.8.5",
- "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
- "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
- "dev": true,
- "dependencies": {
- "glob": "^7.0.0",
- "interpret": "^1.0.0",
- "rechoir": "^0.6.2"
- },
- "bin": {
- "shjs": "bin/shjs"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/shx": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz",
- "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==",
- "dev": true,
- "dependencies": {
- "minimist": "^1.2.3",
- "shelljs": "^0.8.5"
- },
- "bin": {
- "shx": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/typescript": {
- "version": "5.6.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
- "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
- "dev": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/undici-types": {
- "version": "6.19.8",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
- "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "engines": {
- "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==",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
- },
- "node_modules/zod": {
- "version": "3.23.8",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
- "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/src/gitlab/package.json b/src/gitlab/package.json
index e4b35fff..1259e241 100644
--- a/src/gitlab/package.json
+++ b/src/gitlab/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-gitlab",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for using the GitLab API",
"license": "MIT",
"author": "GitLab, PBC (https://gitlab.com)",
@@ -19,7 +19,7 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"@types/node-fetch": "^2.6.12",
"node-fetch": "^3.3.2",
"zod-to-json-schema": "^3.23.5"
@@ -28,4 +28,4 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/google-maps/index.ts b/src/google-maps/index.ts
index 937b39af..00bf6eaa 100644
--- a/src/google-maps/index.ts
+++ b/src/google-maps/index.ts
@@ -141,7 +141,7 @@ function getApiKey(): string {
}
return apiKey;
}
-
+
const GOOGLE_MAPS_API_KEY = getApiKey();
// Tool definitions
@@ -151,28 +151,28 @@ const GEOCODE_TOOL: Tool = {
inputSchema: {
type: "object",
properties: {
- address: {
- type: "string",
- description: "The address to geocode"
+ 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"
+ latitude: {
+ type: "number",
+ description: "Latitude coordinate"
},
- longitude: {
- type: "number",
- description: "Longitude coordinate"
+ longitude: {
+ type: "number",
+ description: "Longitude coordinate"
}
},
required: ["latitude", "longitude"]
@@ -185,9 +185,9 @@ const SEARCH_PLACES_TOOL: Tool = {
inputSchema: {
type: "object",
properties: {
- query: {
- type: "string",
- description: "Search query"
+ query: {
+ type: "string",
+ description: "Search query"
},
location: {
type: "object",
@@ -225,7 +225,7 @@ const DISTANCE_MATRIX_TOOL: Tool = {
name: "maps_distance_matrix",
description: "Calculate travel distance and time for multiple origins and destinations",
inputSchema: {
- type: "object",
+ type: "object",
properties: {
origins: {
type: "array",
@@ -233,7 +233,7 @@ const DISTANCE_MATRIX_TOOL: Tool = {
description: "Array of origin addresses or coordinates"
},
destinations: {
- type: "array",
+ type: "array",
items: { type: "string" },
description: "Array of destination addresses or coordinates"
},
@@ -276,13 +276,13 @@ const DIRECTIONS_TOOL: Tool = {
inputSchema: {
type: "object",
properties: {
- origin: {
- type: "string",
- description: "Starting point address or coordinates"
+ origin: {
+ type: "string",
+ description: "Starting point address or coordinates"
},
- destination: {
- type: "string",
- description: "Ending point address or coordinates"
+ destination: {
+ type: "string",
+ description: "Ending point address or coordinates"
},
mode: {
type: "string",
@@ -315,28 +315,24 @@ async function handleGeocode(address: string) {
if (data.status !== "OK") {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Geocoding failed: ${data.error_message || data.status}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Geocoding failed: ${data.error_message || data.status}`
+ }],
+ isError: true
};
}
return {
- toolResult: {
- 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
- }
+ 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
};
}
@@ -350,28 +346,24 @@ async function handleReverseGeocode(latitude: number, longitude: number) {
if (data.status !== "OK") {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Reverse geocoding failed: ${data.error_message || data.status}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Reverse geocoding failed: ${data.error_message || data.status}`
+ }],
+ isError: true
};
}
return {
- toolResult: {
- 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
- }
+ 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
};
}
@@ -396,33 +388,29 @@ async function handlePlaceSearch(
if (data.status !== "OK") {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Place search failed: ${data.error_message || data.status}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Place search failed: ${data.error_message || data.status}`
+ }],
+ isError: true
};
}
return {
- toolResult: {
- 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
- }
+ 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
};
}
@@ -436,33 +424,29 @@ async function handlePlaceDetails(place_id: string) {
if (data.status !== "OK") {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Place details request failed: ${data.error_message || data.status}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Place details request failed: ${data.error_message || data.status}`
+ }],
+ isError: true
};
}
return {
- toolResult: {
- 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
- }
+ 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(
@@ -481,34 +465,30 @@ async function handleDistanceMatrix(
if (data.status !== "OK") {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Distance matrix request failed: ${data.error_message || data.status}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Distance matrix request failed: ${data.error_message || data.status}`
+ }],
+ isError: true
};
}
return {
- toolResult: {
- 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
- }))
+ 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
- }
+ }))
+ }, null, 2)
+ }],
+ isError: false
};
}
@@ -525,30 +505,26 @@ async function handleElevation(locations: Array<{ latitude: number; longitude: n
if (data.status !== "OK") {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Elevation request failed: ${data.error_message || data.status}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Elevation request failed: ${data.error_message || data.status}`
+ }],
+ isError: true
};
}
return {
- toolResult: {
- content: [{
- type: "text",
- text: JSON.stringify({
- results: data.results.map((result) => ({
- elevation: result.elevation,
- location: result.location,
- resolution: result.resolution
- }))
- }, null, 2)
- }],
- isError: false
- }
+ content: [{
+ type: "text",
+ text: JSON.stringify({
+ results: data.results.map((result) => ({
+ elevation: result.elevation,
+ location: result.location,
+ resolution: result.resolution
+ }))
+ }, null, 2)
+ }],
+ isError: false
};
}
@@ -568,36 +544,32 @@ async function handleDirections(
if (data.status !== "OK") {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Directions request failed: ${data.error_message || data.status}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Directions request failed: ${data.error_message || data.status}`
+ }],
+ isError: true
};
}
return {
- toolResult: {
- 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
- }))
+ 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
- }
+ }))
+ }, null, 2)
+ }],
+ isError: false
};
}
@@ -626,7 +598,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
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;
@@ -634,7 +606,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
return await handleReverseGeocode(latitude, longitude);
}
-
+
case "maps_search_places": {
const { query, location, radius } = request.params.arguments as {
query: string;
@@ -643,12 +615,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
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[];
@@ -657,14 +629,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
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;
@@ -673,27 +645,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
return await handleDirections(origin, destination, mode);
}
-
+
default:
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Unknown tool: ${request.params.name}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Unknown tool: ${request.params.name}`
+ }],
+ isError: true
};
}
} catch (error) {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Error: ${error instanceof Error ? error.message : String(error)}`
- }],
- isError: true
- }
+ content: [{
+ type: "text",
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
+ }],
+ isError: true
};
}
});
@@ -707,4 +675,4 @@ async function runServer() {
runServer().catch((error) => {
console.error("Fatal error running server:", error);
process.exit(1);
-});
\ No newline at end of file
+});
diff --git a/src/google-maps/package.json b/src/google-maps/package.json
index dedf73cf..5e4c04c4 100644
--- a/src/google-maps/package.json
+++ b/src/google-maps/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-google-maps",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for using the Google Maps API",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,7 +19,7 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"@types/node-fetch": "^2.6.12",
"node-fetch": "^3.3.2"
},
@@ -27,4 +27,4 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/memory/index.ts b/src/memory/index.ts
index ad3937ce..0117c920 100644
--- a/src/memory/index.ts
+++ b/src/memory/index.ts
@@ -377,26 +377,26 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
switch (name) {
case "create_entities":
- return { toolResult: await knowledgeGraphManager.createEntities(args.entities as Entity[]) };
+ return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.createEntities(args.entities as Entity[]), null, 2) }] };
case "create_relations":
- return { toolResult: await knowledgeGraphManager.createRelations(args.relations as Relation[]) };
+ return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.createRelations(args.relations as Relation[]), null, 2) }] };
case "add_observations":
- return { toolResult: await knowledgeGraphManager.addObservations(args.observations as { entityName: string; contents: string[] }[]) };
+ return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.addObservations(args.observations as { entityName: string; contents: string[] }[]), null, 2) }] };
case "delete_entities":
await knowledgeGraphManager.deleteEntities(args.entityNames as string[]);
- return { toolResult: "Entities deleted successfully" };
+ return { content: [{ type: "text", text: "Entities deleted successfully" }] };
case "delete_observations":
await knowledgeGraphManager.deleteObservations(args.deletions as { entityName: string; observations: string[] }[]);
- return { toolResult: "Observations deleted successfully" };
+ return { content: [{ type: "text", text: "Observations deleted successfully" }] };
case "delete_relations":
await knowledgeGraphManager.deleteRelations(args.relations as Relation[]);
- return { toolResult: "Relations deleted successfully" };
+ return { content: [{ type: "text", text: "Relations deleted successfully" }] };
case "read_graph":
- return { toolResult: await knowledgeGraphManager.readGraph() };
+ return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.readGraph(), null, 2) }] };
case "search_nodes":
- return { toolResult: await knowledgeGraphManager.searchNodes(args.query as string) };
+ return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.searchNodes(args.query as string), null, 2) }] };
case "open_nodes":
- return { toolResult: await knowledgeGraphManager.openNodes(args.names as string[]) };
+ return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.openNodes(args.names as string[]), null, 2) }] };
default:
throw new Error(`Unknown tool: ${name}`);
}
diff --git a/src/memory/package.json b/src/memory/package.json
index 32bb098d..49cbc92e 100644
--- a/src/memory/package.json
+++ b/src/memory/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-memory",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for enabling memory for Claude through a knowledge graph",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,11 +19,11 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0"
+ "@modelcontextprotocol/sdk": "1.0.1"
},
"devDependencies": {
"@types/node": "^22.9.3",
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/postgres/package.json b/src/postgres/package.json
index 243d2de2..70fa0dbd 100644
--- a/src/postgres/package.json
+++ b/src/postgres/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-postgres",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for interacting with PostgreSQL databases",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,7 +19,7 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0",
+ "@modelcontextprotocol/sdk": "1.0.1",
"pg": "^8.13.0"
},
"devDependencies": {
@@ -27,4 +27,4 @@
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/puppeteer/index.ts b/src/puppeteer/index.ts
index d3aa2a30..d8da6cae 100644
--- a/src/puppeteer/index.ts
+++ b/src/puppeteer/index.ts
@@ -124,20 +124,18 @@ async function ensureBrowser() {
return page!;
}
-async function handleToolCall(name: string, args: any): Promise<{ toolResult: CallToolResult }> {
+async function handleToolCall(name: string, args: any): Promise {
const page = await ensureBrowser();
switch (name) {
case "puppeteer_navigate":
await page.goto(args.url);
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Navigated to ${args.url}`,
- }],
- isError: false,
- },
+ content: [{
+ type: "text",
+ text: `Navigated to ${args.url}`,
+ }],
+ isError: false,
};
case "puppeteer_screenshot": {
@@ -151,13 +149,11 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
if (!screenshot) {
return {
- toolResult: {
- content: [{
- type: "text",
- text: args.selector ? `Element not found: ${args.selector}` : "Screenshot failed",
- }],
- isError: true,
- },
+ content: [{
+ type: "text",
+ text: args.selector ? `Element not found: ${args.selector}` : "Screenshot failed",
+ }],
+ isError: true,
};
}
@@ -167,20 +163,18 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
});
return {
- toolResult: {
- 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,
- },
+ 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,
};
}
@@ -188,23 +182,19 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
try {
await page.click(args.selector);
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Clicked: ${args.selector}`,
- }],
- isError: false,
- },
+ content: [{
+ type: "text",
+ text: `Clicked: ${args.selector}`,
+ }],
+ isError: false,
};
} catch (error) {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Failed to click ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- },
+ content: [{
+ type: "text",
+ text: `Failed to click ${args.selector}: ${(error as Error).message}`,
+ }],
+ isError: true,
};
}
@@ -213,23 +203,19 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
await page.waitForSelector(args.selector);
await page.type(args.selector, args.value);
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Filled ${args.selector} with: ${args.value}`,
- }],
- isError: false,
- },
+ content: [{
+ type: "text",
+ text: `Filled ${args.selector} with: ${args.value}`,
+ }],
+ isError: false,
};
} catch (error) {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Failed to fill ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- },
+ content: [{
+ type: "text",
+ text: `Failed to fill ${args.selector}: ${(error as Error).message}`,
+ }],
+ isError: true,
};
}
@@ -238,23 +224,19 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
await page.waitForSelector(args.selector);
await page.select(args.selector, args.value);
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Selected ${args.selector} with: ${args.value}`,
- }],
- isError: false,
- },
+ content: [{
+ type: "text",
+ text: `Selected ${args.selector} with: ${args.value}`,
+ }],
+ isError: false,
};
} catch (error) {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Failed to select ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- },
+ content: [{
+ type: "text",
+ text: `Failed to select ${args.selector}: ${(error as Error).message}`,
+ }],
+ isError: true,
};
}
@@ -263,23 +245,19 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
await page.waitForSelector(args.selector);
await page.hover(args.selector);
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Hovered ${args.selector}`,
- }],
- isError: false,
- },
+ content: [{
+ type: "text",
+ text: `Hovered ${args.selector}`,
+ }],
+ isError: false,
};
} catch (error) {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Failed to hover ${args.selector}: ${(error as Error).message}`,
- }],
- isError: true,
- },
+ content: [{
+ type: "text",
+ text: `Failed to hover ${args.selector}: ${(error as Error).message}`,
+ }],
+ isError: true,
};
}
@@ -307,37 +285,31 @@ async function handleToolCall(name: string, args: any): Promise<{ toolResult: Ca
}, args.script);
return {
- toolResult: {
- content: [
- {
- type: "text",
- text: `Execution result:\n${JSON.stringify(result.result, null, 2)}\n\nConsole output:\n${result.logs.join('\n')}`,
- },
- ],
- isError: false,
- },
+ content: [
+ {
+ type: "text",
+ text: `Execution result:\n${JSON.stringify(result.result, null, 2)}\n\nConsole output:\n${result.logs.join('\n')}`,
+ },
+ ],
+ isError: false,
};
} catch (error) {
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Script execution failed: ${(error as Error).message}`,
- }],
- isError: true,
- },
+ content: [{
+ type: "text",
+ text: `Script execution failed: ${(error as Error).message}`,
+ }],
+ isError: true,
};
}
default:
return {
- toolResult: {
- content: [{
- type: "text",
- text: `Unknown tool: ${name}`,
- }],
- isError: true,
- },
+ content: [{
+ type: "text",
+ text: `Unknown tool: ${name}`,
+ }],
+ isError: true,
};
}
}
diff --git a/src/puppeteer/package.json b/src/puppeteer/package.json
index b6f9d8cc..6ca49157 100644
--- a/src/puppeteer/package.json
+++ b/src/puppeteer/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-puppeteer",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for browser automation using Puppeteer",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,11 +19,11 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.5.0",
+ "@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/sentry/README.md b/src/sentry/README.md
index 78e8f72b..34a1feb5 100644
--- a/src/sentry/README.md
+++ b/src/sentry/README.md
@@ -91,8 +91,10 @@ Add to your Zed settings.json:
```json
"context_servers": [
"mcp-server-sentry": {
- "command": "uvx",
- "args": ["mcp-server-sentry", "--auth-token", "YOUR_SENTRY_TOKEN"]
+ "command": {
+ "path": "uvx",
+ "args": ["mcp-server-sentry", "--auth-token", "YOUR_SENTRY_TOKEN"]
+ }
}
],
```
diff --git a/src/sentry/pyproject.toml b/src/sentry/pyproject.toml
index ff8ed0ba..0788ad80 100644
--- a/src/sentry/pyproject.toml
+++ b/src/sentry/pyproject.toml
@@ -1,10 +1,10 @@
[project]
name = "mcp-server-sentry"
-version = "0.5.1"
+version = "0.6.2"
description = "MCP server for retrieving issues from sentry.io"
readme = "README.md"
requires-python = ">=3.10"
-dependencies = ["mcp>=0.9.1"]
+dependencies = ["mcp>=1.0.0"]
[build-system]
requires = ["hatchling"]
diff --git a/src/sentry/src/mcp_server_sentry/__main__.py b/src/sentry/src/mcp_server_sentry/__main__.py
new file mode 100644
index 00000000..c9a93f1a
--- /dev/null
+++ b/src/sentry/src/mcp_server_sentry/__main__.py
@@ -0,0 +1,4 @@
+from mcp_server_sentry.server import main
+
+if __name__ == "__main__":
+ main()
diff --git a/src/sentry/uv.lock b/src/sentry/uv.lock
index 4e1b8b5f..a9a8c1a6 100644
--- a/src/sentry/uv.lock
+++ b/src/sentry/uv.lock
@@ -88,18 +88,17 @@ wheels = [
[[package]]
name = "httpx"
-version = "0.27.2"
+version = "0.28.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "certifi" },
{ name = "httpcore" },
{ name = "idna" },
- { name = "sniffio" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 }
+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/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 },
+ { url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551 },
]
[[package]]
@@ -131,7 +130,7 @@ wheels = [
[[package]]
name = "mcp"
-version = "0.9.1"
+version = "1.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@@ -141,14 +140,14 @@ dependencies = [
{ name = "sse-starlette" },
{ name = "starlette" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/e7/1c/932818470ffd49c33509110c835101a8dc4c9cdd06028b9f647fb3dde237/mcp-0.9.1.tar.gz", hash = "sha256:e8509a37c2ab546095788ed170e0fb4d7ce0cf5a3ee56b6449c78af27321a425", size = 78218 }
+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/b3/a0/2ee813d456b57a726d583868417d1ad900fbe12ee3c8cd866e3e804ca486/mcp-0.9.1-py3-none-any.whl", hash = "sha256:7f640fcfb0be486aa510594df309920ae1d375cdca1f8aff21db3a96d837f303", size = 31562 },
+ { 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.4.1"
+version = "0.6.2"
source = { editable = "." }
dependencies = [
{ name = "mcp" },
@@ -162,7 +161,7 @@ dev = [
]
[package.metadata]
-requires-dist = [{ name = "mcp", specifier = ">=0.9.1" }]
+requires-dist = [{ name = "mcp", specifier = ">=1.0.0" }]
[package.metadata.requires-dev]
dev = [
@@ -200,16 +199,16 @@ wheels = [
[[package]]
name = "pydantic"
-version = "2.10.1"
+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/c4/bd/7fc610993f616d2398958d0028d15eaf53bde5f80cb2edb7aa4f1feaf3a7/pydantic-2.10.1.tar.gz", hash = "sha256:a4daca2dc0aa429555e0656d6bf94873a7dc5f54ee42b1f5873d666fb3f35560", size = 783717 }
+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/e0/fc/fda48d347bd50a788dd2a0f318a52160f911b86fc2d8b4c86f4d7c9bceea/pydantic-2.10.1-py3-none-any.whl", hash = "sha256:a8d20db84de64cf4a7d59e899c2caf0fe9d660c7cfc482528e7020d7dd189a7e", size = 455329 },
+ { url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364 },
]
[[package]]
@@ -319,27 +318,27 @@ wheels = [
[[package]]
name = "ruff"
-version = "0.8.0"
+version = "0.8.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/b2/d6/a2373f3ba7180ddb44420d2a9d1f1510e1a4d162b3d27282bedcb09c8da9/ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44", size = 3276537 }
+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/ec/77/e889ee3ce7fd8baa3ed1b77a03b9fb8ec1be68be1418261522fd6a5405e0/ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea", size = 10518283 },
- { url = "https://files.pythonhosted.org/packages/da/c8/0a47de01edf19fb22f5f9b7964f46a68d0bdff20144d134556ffd1ba9154/ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b", size = 10317691 },
- { url = "https://files.pythonhosted.org/packages/41/17/9885e4a0eeae07abd2a4ebabc3246f556719f24efa477ba2739146c4635a/ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a", size = 9940999 },
- { url = "https://files.pythonhosted.org/packages/3e/cd/46b6f7043597eb318b5f5482c8ae8f5491cccce771e85f59d23106f2d179/ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99", size = 10772437 },
- { url = "https://files.pythonhosted.org/packages/5d/87/afc95aeb8bc78b1d8a3461717a4419c05aa8aa943d4c9cbd441630f85584/ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c", size = 10299156 },
- { url = "https://files.pythonhosted.org/packages/65/fa/04c647bb809c4d65e8eae1ed1c654d9481b21dd942e743cd33511687b9f9/ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9", size = 11325819 },
- { url = "https://files.pythonhosted.org/packages/90/26/7dad6e7d833d391a8a1afe4ee70ca6f36c4a297d3cca83ef10e83e9aacf3/ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362", size = 12023927 },
- { url = "https://files.pythonhosted.org/packages/24/a0/be5296dda6428ba8a13bda8d09fbc0e14c810b485478733886e61597ae2b/ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df", size = 11589702 },
- { url = "https://files.pythonhosted.org/packages/26/3f/7602eb11d2886db545834182a9dbe500b8211fcbc9b4064bf9d358bbbbb4/ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3", size = 12782936 },
- { url = "https://files.pythonhosted.org/packages/4c/5d/083181bdec4ec92a431c1291d3fff65eef3ded630a4b55eb735000ef5f3b/ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c", size = 11138488 },
- { url = "https://files.pythonhosted.org/packages/b7/23/c12cdef58413cee2436d6a177aa06f7a366ebbca916cf10820706f632459/ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2", size = 10744474 },
- { url = "https://files.pythonhosted.org/packages/29/61/a12f3b81520083cd7c5caa24ba61bb99fd1060256482eff0ef04cc5ccd1b/ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70", size = 10369029 },
- { url = "https://files.pythonhosted.org/packages/08/2a/c013f4f3e4a54596c369cee74c24870ed1d534f31a35504908b1fc97017a/ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd", size = 10867481 },
- { url = "https://files.pythonhosted.org/packages/d5/f7/685b1e1d42a3e94ceb25eab23c70bdd8c0ab66a43121ef83fe6db5a58756/ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426", size = 11237117 },
- { url = "https://files.pythonhosted.org/packages/03/20/401132c0908e8837625e3b7e32df9962e7cd681a4df1e16a10e2a5b4ecda/ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468", size = 8783511 },
- { url = "https://files.pythonhosted.org/packages/1d/5c/4d800fca7854f62ad77f2c0d99b4b585f03e2d87a6ec1ecea85543a14a3c/ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f", size = 9559876 },
- { url = "https://files.pythonhosted.org/packages/5b/bc/cc8a6a5ca4960b226dc15dd8fb511dd11f2014ff89d325c0b9b9faa9871f/ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6", size = 8939733 },
+ { 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]]
@@ -379,11 +378,41 @@ wheels = [
[[package]]
name = "tomli"
-version = "2.1.0"
+version = "2.2.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/1e/e4/1b6cbcc82d8832dd0ce34767d5c560df8a3547ad8cbc427f34601415930a/tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8", size = 16622 }
+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/de/f7/4da0ffe1892122c9ea096c57f64c2753ae5dd3ce85488802d11b0992cc6d/tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391", size = 13750 },
+ { 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]]
diff --git a/src/sequentialthinking/README.md b/src/sequentialthinking/README.md
new file mode 100644
index 00000000..0b299c3f
--- /dev/null
+++ b/src/sequentialthinking/README.md
@@ -0,0 +1,63 @@
+
+# Sequential Thinking MCP Server
+
+An MCP server implementation that provides a tool for dynamic and reflective problem-solving through a structured thinking process.
+
+## Features
+
+- Break down complex problems into manageable steps
+- Revise and refine thoughts as understanding deepens
+- Branch into alternative paths of reasoning
+- Adjust the total number of thoughts dynamically
+- Generate and verify solution hypotheses
+
+## Tool
+
+### sequential_thinking
+
+Facilitates a detailed, step-by-step thinking process for problem-solving and analysis.
+
+**Inputs:**
+- `thought` (string): The current thinking step
+- `nextThoughtNeeded` (boolean): Whether another thought step is needed
+- `thoughtNumber` (integer): Current thought number
+- `totalThoughts` (integer): Estimated total thoughts needed
+- `isRevision` (boolean, optional): Whether this revises previous thinking
+- `revisesThought` (integer, optional): Which thought is being reconsidered
+- `branchFromThought` (integer, optional): Branching point thought number
+- `branchId` (string, optional): Branch identifier
+- `needsMoreThoughts` (boolean, optional): If more thoughts are needed
+
+## Usage
+
+The Sequential Thinking tool is designed for:
+- Breaking down complex problems into steps
+- Planning and design with room for revision
+- Analysis that might need course correction
+- Problems where the full scope might not be clear initially
+- Tasks that need to maintain context over multiple steps
+- Situations where irrelevant information needs to be filtered out
+
+## Configuration
+
+### Usage with Claude Desktop
+
+Add this to your `claude_desktop_config.json`:
+
+```json
+{
+ "mcpServers": {
+ "sequential-thinking": {
+ "command": "npx",
+ "args": [
+ "-y",
+ "@modelcontextprotocol/server-sequential-thinking"
+ ]
+ }
+ }
+}
+```
+
+## 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/sequentialthinking/index.ts b/src/sequentialthinking/index.ts
new file mode 100644
index 00000000..c10301d7
--- /dev/null
+++ b/src/sequentialthinking/index.ts
@@ -0,0 +1,278 @@
+#!/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";
+// Fixed chalk import for ESM
+import chalk from 'chalk';
+
+interface ThoughtData {
+ thought: string;
+ thoughtNumber: number;
+ totalThoughts: number;
+ isRevision?: boolean;
+ revisesThought?: number;
+ branchFromThought?: number;
+ branchId?: string;
+ needsMoreThoughts?: boolean;
+ nextThoughtNeeded: boolean;
+}
+
+class SequentialThinkingServer {
+ private thoughtHistory: ThoughtData[] = [];
+ private branches: Record = {};
+
+ private validateThoughtData(input: unknown): ThoughtData {
+ const data = input as Record;
+
+ if (!data.thought || typeof data.thought !== 'string') {
+ throw new Error('Invalid thought: must be a string');
+ }
+ if (!data.thoughtNumber || typeof data.thoughtNumber !== 'number') {
+ throw new Error('Invalid thoughtNumber: must be a number');
+ }
+ if (!data.totalThoughts || typeof data.totalThoughts !== 'number') {
+ throw new Error('Invalid totalThoughts: must be a number');
+ }
+ if (typeof data.nextThoughtNeeded !== 'boolean') {
+ throw new Error('Invalid nextThoughtNeeded: must be a boolean');
+ }
+
+ return {
+ thought: data.thought,
+ thoughtNumber: data.thoughtNumber,
+ totalThoughts: data.totalThoughts,
+ nextThoughtNeeded: data.nextThoughtNeeded,
+ isRevision: data.isRevision as boolean | undefined,
+ revisesThought: data.revisesThought as number | undefined,
+ branchFromThought: data.branchFromThought as number | undefined,
+ branchId: data.branchId as string | undefined,
+ needsMoreThoughts: data.needsMoreThoughts as boolean | undefined,
+ };
+ }
+
+ private formatThought(thoughtData: ThoughtData): string {
+ const { thoughtNumber, totalThoughts, thought, isRevision, revisesThought, branchFromThought, branchId } = thoughtData;
+
+ let prefix = '';
+ let context = '';
+
+ if (isRevision) {
+ prefix = chalk.yellow('🔄 Revision');
+ context = ` (revising thought ${revisesThought})`;
+ } else if (branchFromThought) {
+ prefix = chalk.green('🌿 Branch');
+ context = ` (from thought ${branchFromThought}, ID: ${branchId})`;
+ } else {
+ prefix = chalk.blue('💭 Thought');
+ context = '';
+ }
+
+ const header = `${prefix} ${thoughtNumber}/${totalThoughts}${context}`;
+ const border = '─'.repeat(Math.max(header.length, thought.length) + 4);
+
+ return `
+┌${border}┐
+│ ${header} │
+├${border}┤
+│ ${thought.padEnd(border.length - 2)} │
+└${border}┘`;
+ }
+
+ public processThought(input: unknown): { content: Array<{ type: string; text: string }>; isError?: boolean } {
+ try {
+ const validatedInput = this.validateThoughtData(input);
+
+ if (validatedInput.thoughtNumber > validatedInput.totalThoughts) {
+ validatedInput.totalThoughts = validatedInput.thoughtNumber;
+ }
+
+ this.thoughtHistory.push(validatedInput);
+
+ if (validatedInput.branchFromThought && validatedInput.branchId) {
+ if (!this.branches[validatedInput.branchId]) {
+ this.branches[validatedInput.branchId] = [];
+ }
+ this.branches[validatedInput.branchId].push(validatedInput);
+ }
+
+ const formattedThought = this.formatThought(validatedInput);
+ console.error(formattedThought);
+
+ return {
+ content: [{
+ type: "text",
+ text: JSON.stringify({
+ thoughtNumber: validatedInput.thoughtNumber,
+ totalThoughts: validatedInput.totalThoughts,
+ nextThoughtNeeded: validatedInput.nextThoughtNeeded,
+ branches: Object.keys(this.branches),
+ thoughtHistoryLength: this.thoughtHistory.length
+ }, null, 2)
+ }]
+ };
+ } catch (error) {
+ return {
+ content: [{
+ type: "text",
+ text: JSON.stringify({
+ error: error instanceof Error ? error.message : String(error),
+ status: 'failed'
+ }, null, 2)
+ }],
+ isError: true
+ };
+ }
+ }
+}
+
+const SEQUENTIAL_THINKING_TOOL: Tool = {
+ name: "sequentialthinking",
+ description: `A detailed tool for dynamic and reflective problem-solving through thoughts.
+This tool helps analyze problems through a flexible thinking process that can adapt and evolve.
+Each thought can build on, question, or revise previous insights as understanding deepens.
+
+When to use this tool:
+- Breaking down complex problems into steps
+- Planning and design with room for revision
+- Analysis that might need course correction
+- Problems where the full scope might not be clear initially
+- Problems that require a multi-step solution
+- Tasks that need to maintain context over multiple steps
+- Situations where irrelevant information needs to be filtered out
+
+Key features:
+- You can adjust total_thoughts up or down as you progress
+- You can question or revise previous thoughts
+- You can add more thoughts even after reaching what seemed like the end
+- You can express uncertainty and explore alternative approaches
+- Not every thought needs to build linearly - you can branch or backtrack
+- Generates a solution hypothesis
+- Verifies the hypothesis based on the Chain of Thought steps
+- Repeats the process until satisfied
+- Provides a correct answer
+
+Parameters explained:
+- thought: Your current thinking step, which can include:
+* Regular analytical steps
+* Revisions of previous thoughts
+* Questions about previous decisions
+* Realizations about needing more analysis
+* Changes in approach
+* Hypothesis generation
+* Hypothesis verification
+- next_thought_needed: True if you need more thinking, even if at what seemed like the end
+- thought_number: Current number in sequence (can go beyond initial total if needed)
+- total_thoughts: Current estimate of thoughts needed (can be adjusted up/down)
+- is_revision: A boolean indicating if this thought revises previous thinking
+- revises_thought: If is_revision is true, which thought number is being reconsidered
+- branch_from_thought: If branching, which thought number is the branching point
+- branch_id: Identifier for the current branch (if any)
+- needs_more_thoughts: If reaching end but realizing more thoughts needed
+
+You should:
+1. Start with an initial estimate of needed thoughts, but be ready to adjust
+2. Feel free to question or revise previous thoughts
+3. Don't hesitate to add more thoughts if needed, even at the "end"
+4. Express uncertainty when present
+5. Mark thoughts that revise previous thinking or branch into new paths
+6. Ignore information that is irrelevant to the current step
+7. Generate a solution hypothesis when appropriate
+8. Verify the hypothesis based on the Chain of Thought steps
+9. Repeat the process until satisfied with the solution
+10. Provide a single, ideally correct answer as the final output
+11. Only set next_thought_needed to false when truly done and a satisfactory answer is reached`,
+ inputSchema: {
+ type: "object",
+ properties: {
+ thought: {
+ type: "string",
+ description: "Your current thinking step"
+ },
+ nextThoughtNeeded: {
+ type: "boolean",
+ description: "Whether another thought step is needed"
+ },
+ thoughtNumber: {
+ type: "integer",
+ description: "Current thought number",
+ minimum: 1
+ },
+ totalThoughts: {
+ type: "integer",
+ description: "Estimated total thoughts needed",
+ minimum: 1
+ },
+ isRevision: {
+ type: "boolean",
+ description: "Whether this revises previous thinking"
+ },
+ revisesThought: {
+ type: "integer",
+ description: "Which thought is being reconsidered",
+ minimum: 1
+ },
+ branchFromThought: {
+ type: "integer",
+ description: "Branching point thought number",
+ minimum: 1
+ },
+ branchId: {
+ type: "string",
+ description: "Branch identifier"
+ },
+ needsMoreThoughts: {
+ type: "boolean",
+ description: "If more thoughts are needed"
+ }
+ },
+ required: ["thought", "nextThoughtNeeded", "thoughtNumber", "totalThoughts"]
+ }
+};
+
+const server = new Server(
+ {
+ name: "sequential-thinking-server",
+ version: "0.2.0",
+ },
+ {
+ capabilities: {
+ tools: {},
+ },
+ }
+);
+
+const thinkingServer = new SequentialThinkingServer();
+
+server.setRequestHandler(ListToolsRequestSchema, async () => ({
+ tools: [SEQUENTIAL_THINKING_TOOL],
+}));
+
+server.setRequestHandler(CallToolRequestSchema, async (request) => {
+ if (request.params.name === "sequentialthinking") {
+ return thinkingServer.processThought(request.params.arguments);
+ }
+
+ return {
+ content: [{
+ type: "text",
+ text: `Unknown tool: ${request.params.name}`
+ }],
+ isError: true
+ };
+});
+
+async function runServer() {
+ const transport = new StdioServerTransport();
+ await server.connect(transport);
+ console.error("Sequential Thinking MCP Server running on stdio");
+}
+
+runServer().catch((error) => {
+ console.error("Fatal error running server:", error);
+ process.exit(1);
+});
diff --git a/src/sequentialthinking/package.json b/src/sequentialthinking/package.json
new file mode 100644
index 00000000..d696695e
--- /dev/null
+++ b/src/sequentialthinking/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "@modelcontextprotocol/server-sequential-thinking",
+ "version": "0.6.2",
+ "description": "MCP server for sequential thinking and problem solving",
+ "license": "MIT",
+ "author": "Anthropic, PBC (https://anthropic.com)",
+ "homepage": "https://modelcontextprotocol.io",
+ "bugs": "https://github.com/modelcontextprotocol/servers/issues",
+ "type": "module",
+ "bin": {
+ "mcp-server-sequential-thinking": "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",
+ "chalk": "^5.3.0",
+ "yargs": "^17.7.2"
+ },
+ "devDependencies": {
+ "@types/node": "^20.11.0",
+ "@types/yargs": "^17.0.32",
+ "shx": "^0.3.4",
+ "typescript": "^5.3.3"
+ }
+}
\ No newline at end of file
diff --git a/src/sequentialthinking/tsconfig.json b/src/sequentialthinking/tsconfig.json
new file mode 100644
index 00000000..2ce5843e
--- /dev/null
+++ b/src/sequentialthinking/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./dist",
+ "rootDir": ".",
+ "moduleResolution": "NodeNext",
+ "module": "NodeNext"
+ },
+ "include": ["./**/*.ts"]
+}
diff --git a/src/slack/package.json b/src/slack/package.json
index 8c8dcdee..10e18594 100644
--- a/src/slack/package.json
+++ b/src/slack/package.json
@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/server-slack",
- "version": "0.5.1",
+ "version": "0.6.2",
"description": "MCP server for interacting with Slack",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -19,11 +19,11 @@
"watch": "tsc --watch"
},
"dependencies": {
- "@modelcontextprotocol/sdk": "0.6.0"
+ "@modelcontextprotocol/sdk": "1.0.1"
},
"devDependencies": {
"@types/node": "^22.9.3",
"shx": "^0.3.4",
"typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/src/sqlite/pyproject.toml b/src/sqlite/pyproject.toml
index 62d0c306..241ad0e2 100644
--- a/src/sqlite/pyproject.toml
+++ b/src/sqlite/pyproject.toml
@@ -1,10 +1,10 @@
[project]
name = "mcp-server-sqlite"
-version = "0.5.1"
+version = "0.6.2"
description = "A simple SQLite MCP server"
readme = "README.md"
requires-python = ">=3.10"
-dependencies = ["mcp>=0.9.1"]
+dependencies = ["mcp>=1.0.0"]
[build-system]
requires = ["hatchling"]
diff --git a/src/sqlite/uv.lock b/src/sqlite/uv.lock
index 369d3c0a..87ccbfbd 100644
--- a/src/sqlite/uv.lock
+++ b/src/sqlite/uv.lock
@@ -88,18 +88,17 @@ wheels = [
[[package]]
name = "httpx"
-version = "0.27.2"
+version = "0.28.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
{ name = "certifi" },
{ name = "httpcore" },
{ name = "idna" },
- { name = "sniffio" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 }
+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/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 },
+ { url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551 },
]
[[package]]
@@ -122,7 +121,7 @@ wheels = [
[[package]]
name = "mcp"
-version = "0.9.1"
+version = "1.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
@@ -132,14 +131,14 @@ dependencies = [
{ name = "sse-starlette" },
{ name = "starlette" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/e7/1c/932818470ffd49c33509110c835101a8dc4c9cdd06028b9f647fb3dde237/mcp-0.9.1.tar.gz", hash = "sha256:e8509a37c2ab546095788ed170e0fb4d7ce0cf5a3ee56b6449c78af27321a425", size = 78218 }
+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/b3/a0/2ee813d456b57a726d583868417d1ad900fbe12ee3c8cd866e3e804ca486/mcp-0.9.1-py3-none-any.whl", hash = "sha256:7f640fcfb0be486aa510594df309920ae1d375cdca1f8aff21db3a96d837f303", size = 31562 },
+ { 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.5.1"
+version = "0.6.2"
source = { editable = "." }
dependencies = [
{ name = "mcp" },
@@ -151,7 +150,7 @@ dev = [
]
[package.metadata]
-requires-dist = [{ name = "mcp", specifier = ">=0.9.1" }]
+requires-dist = [{ name = "mcp", specifier = ">=1.0.0" }]
[package.metadata.requires-dev]
dev = [{ name = "pyright", specifier = ">=1.1.389" }]
@@ -167,16 +166,16 @@ wheels = [
[[package]]
name = "pydantic"
-version = "2.10.1"
+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/c4/bd/7fc610993f616d2398958d0028d15eaf53bde5f80cb2edb7aa4f1feaf3a7/pydantic-2.10.1.tar.gz", hash = "sha256:a4daca2dc0aa429555e0656d6bf94873a7dc5f54ee42b1f5873d666fb3f35560", size = 783717 }
+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/e0/fc/fda48d347bd50a788dd2a0f318a52160f911b86fc2d8b4c86f4d7c9bceea/pydantic-2.10.1-py3-none-any.whl", hash = "sha256:a8d20db84de64cf4a7d59e899c2caf0fe9d660c7cfc482528e7020d7dd189a7e", size = 455329 },
+ { url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364 },
]
[[package]]
diff --git a/src/time/.python-version b/src/time/.python-version
new file mode 100644
index 00000000..c8cfe395
--- /dev/null
+++ b/src/time/.python-version
@@ -0,0 +1 @@
+3.10
diff --git a/src/time/README.md b/src/time/README.md
new file mode 100644
index 00000000..8f80e415
--- /dev/null
+++ b/src/time/README.md
@@ -0,0 +1,193 @@
+# Time MCP Server
+
+A Model Context Protocol server that provides time and timezone conversion capabilities. This server enables LLMs to get current time information and perform timezone conversions using IANA timezone names, with automatic system timezone detection.
+
+### Available Tools
+
+- `get_current_time` - Get current time in a specific timezone or system timezone.
+ - Required arguments:
+ - `timezone` (string): IANA timezone name (e.g., 'America/New_York', 'Europe/London')
+
+- `convert_time` - Convert time between timezones.
+ - Required arguments:
+ - `source_timezone` (string): Source IANA timezone name
+ - `time` (string): Time in 24-hour format (HH:MM)
+ - `target_timezone` (string): Target IANA timezone name
+
+## 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-time*.
+
+### Using PIP
+
+Alternatively you can install `mcp-server-time` via pip:
+
+```bash
+pip install mcp-server-time
+```
+
+After installation, you can run it as a script using:
+
+```bash
+python -m mcp_server_time
+```
+
+## Configuration
+
+### Configure for Claude.app
+
+Add to your Claude settings:
+
+
+Using uvx
+
+```json
+"mcpServers": {
+ "time": {
+ "command": "uvx",
+ "args": ["mcp-server-time"]
+ }
+}
+```
+
+
+
+Using pip installation
+
+```json
+"mcpServers": {
+ "time": {
+ "command": "python",
+ "args": ["-m", "mcp_server_time"]
+ }
+}
+```
+
+
+### Configure for Zed
+
+Add to your Zed settings.json:
+
+
+Using uvx
+
+```json
+"context_servers": [
+ "mcp-server-time": {
+ "command": "uvx",
+ "args": ["mcp-server-time"]
+ }
+],
+```
+
+
+
+Using pip installation
+
+```json
+"context_servers": {
+ "mcp-server-time": {
+ "command": "python",
+ "args": ["-m", "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.
+
+Example:
+```json
+{
+ "command": "python",
+ "args": ["-m", "mcp_server_time", "--local-timezone=America/New_York"]
+}
+```
+
+## Example Interactions
+
+1. Get current time:
+```json
+{
+ "name": "get_current_time",
+ "arguments": {
+ "timezone": "Europe/Warsaw"
+ }
+}
+```
+Response:
+```json
+{
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T13:00:00+01:00",
+ "is_dst": false
+}
+```
+
+2. Convert time between timezones:
+```json
+{
+ "name": "convert_time",
+ "arguments": {
+ "source_timezone": "America/New_York",
+ "time": "16:30",
+ "target_timezone": "Asia/Tokyo"
+ }
+}
+```
+Response:
+```json
+{
+ "source": {
+ "timezone": "America/New_York",
+ "datetime": "2024-01-01T12:30:00-05:00",
+ "is_dst": false
+ },
+ "target": {
+ "timezone": "Asia/Tokyo",
+ "datetime": "2024-01-01T12:30:00+09:00",
+ "is_dst": false
+ },
+ "time_difference": "+13.0h",
+}
+```
+
+## Debugging
+
+You can use the MCP inspector to debug the server. For uvx installations:
+
+```bash
+npx @modelcontextprotocol/inspector uvx mcp-server-time
+```
+
+Or if you've installed the package in a specific directory or are developing on it:
+
+```bash
+cd path/to/servers/src/time
+npx @modelcontextprotocol/inspector uv run mcp-server-time
+```
+
+## Examples of Questions for Claude
+
+1. "What time is it now?" (will use system timezone)
+2. "What time is it in Tokyo?"
+3. "When it's 4 PM in New York, what time is it in London?"
+4. "Convert 9:30 AM Tokyo time to New York time"
+
+## Contributing
+
+We encourage contributions to help expand and improve mcp-server-time. Whether you want to add new time-related tools, enhance existing functionality, or improve documentation, your input is valuable.
+
+For examples of other MCP servers and implementation patterns, see:
+https://github.com/modelcontextprotocol/servers
+
+Pull requests are welcome! Feel free to contribute new ideas, bug fixes, or enhancements to make mcp-server-time even more powerful and useful.
+
+## License
+
+mcp-server-time 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/time/pyproject.toml b/src/time/pyproject.toml
new file mode 100644
index 00000000..70924951
--- /dev/null
+++ b/src/time/pyproject.toml
@@ -0,0 +1,38 @@
+[project]
+name = "mcp-server-time"
+version = "0.6.2"
+description = "A Model Context Protocol server providing tools for time queries and timezone conversions for LLMs"
+readme = "README.md"
+requires-python = ">=3.10"
+authors = [
+ { name = "Mariusz 'maledorak' Korzekwa", email = "mariusz@korzekwa.dev" },
+]
+keywords = ["time", "timezone", "mcp", "llm"]
+license = { text = "MIT" }
+classifiers = [
+ "Development Status :: 4 - Beta",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.10",
+]
+dependencies = [
+ "mcp>=1.0.0",
+ "pydantic>=2.0.0",
+ "tzdata>=2024.2",
+]
+
+[project.scripts]
+mcp-server-time = "mcp_server_time:main"
+
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[tool.uv]
+dev-dependencies = [
+ "freezegun>=1.5.1",
+ "pyright>=1.1.389",
+ "pytest>=8.3.3",
+ "ruff>=0.8.1",
+]
diff --git a/src/time/src/mcp_server_time/__init__.py b/src/time/src/mcp_server_time/__init__.py
new file mode 100644
index 00000000..cce7ccc9
--- /dev/null
+++ b/src/time/src/mcp_server_time/__init__.py
@@ -0,0 +1,19 @@
+from .server import serve
+
+
+def main():
+ """MCP Time Server - Time and timezone conversion functionality for MCP"""
+ import argparse
+ import asyncio
+
+ parser = argparse.ArgumentParser(
+ description="give a model the ability to handle time queries and timezone conversions"
+ )
+ parser.add_argument("--local-timezone", type=str, help="Override local timezone")
+
+ args = parser.parse_args()
+ asyncio.run(serve(args.local_timezone))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/time/src/mcp_server_time/__main__.py b/src/time/src/mcp_server_time/__main__.py
new file mode 100644
index 00000000..27adff28
--- /dev/null
+++ b/src/time/src/mcp_server_time/__main__.py
@@ -0,0 +1,3 @@
+from mcp_server_time import main
+
+main()
diff --git a/src/time/src/mcp_server_time/server.py b/src/time/src/mcp_server_time/server.py
new file mode 100644
index 00000000..67c9024b
--- /dev/null
+++ b/src/time/src/mcp_server_time/server.py
@@ -0,0 +1,201 @@
+from datetime import datetime, timedelta
+from enum import Enum
+import json
+from typing import Sequence
+
+from zoneinfo import ZoneInfo
+from mcp.server import Server
+from mcp.server.stdio import stdio_server
+from mcp.types import Tool, TextContent, ImageContent, EmbeddedResource
+from mcp.shared.exceptions import McpError
+
+from pydantic import BaseModel
+
+
+class TimeTools(str, Enum):
+ GET_CURRENT_TIME = "get_current_time"
+ CONVERT_TIME = "convert_time"
+
+
+class TimeResult(BaseModel):
+ timezone: str
+ datetime: str
+ is_dst: bool
+
+
+class TimeConversionResult(BaseModel):
+ source: TimeResult
+ target: TimeResult
+ time_difference: str
+
+
+class TimeConversionInput(BaseModel):
+ source_tz: str
+ time: str
+ target_tz_list: list[str]
+
+
+def get_local_tz(local_tz_override: str | None = None) -> ZoneInfo:
+ if local_tz_override:
+ 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))
+ raise McpError("Could not determine local timezone - tzinfo is None")
+
+
+def get_zoneinfo(timezone_name: str) -> ZoneInfo:
+ try:
+ return ZoneInfo(timezone_name)
+ except Exception as e:
+ raise McpError(f"Invalid timezone: {str(e)}")
+
+
+class TimeServer:
+ def get_current_time(self, timezone_name: str) -> TimeResult:
+ """Get current time in specified timezone"""
+ timezone = get_zoneinfo(timezone_name)
+ current_time = datetime.now(timezone)
+
+ return TimeResult(
+ timezone=timezone_name,
+ datetime=current_time.isoformat(timespec="seconds"),
+ is_dst=bool(current_time.dst()),
+ )
+
+ def convert_time(
+ self, source_tz: str, time_str: str, target_tz: str
+ ) -> TimeConversionResult:
+ """Convert time between timezones"""
+ source_timezone = get_zoneinfo(source_tz)
+ target_timezone = get_zoneinfo(target_tz)
+
+ try:
+ parsed_time = datetime.strptime(time_str, "%H:%M").time()
+ except ValueError:
+ raise ValueError("Invalid time format. Expected HH:MM [24-hour format]")
+
+ now = datetime.now(source_timezone)
+ source_time = datetime(
+ now.year,
+ now.month,
+ now.day,
+ parsed_time.hour,
+ parsed_time.minute,
+ tzinfo=source_timezone,
+ )
+
+ target_time = source_time.astimezone(target_timezone)
+ source_offset = source_time.utcoffset() or timedelta()
+ target_offset = target_time.utcoffset() or timedelta()
+ hours_difference = (target_offset - source_offset).total_seconds() / 3600
+
+ if hours_difference.is_integer():
+ time_diff_str = f"{hours_difference:+.1f}h"
+ else:
+ # For fractional hours like Nepal's UTC+5:45
+ time_diff_str = f"{hours_difference:+.2f}".rstrip("0").rstrip(".") + "h"
+
+ return TimeConversionResult(
+ source=TimeResult(
+ timezone=source_tz,
+ datetime=source_time.isoformat(timespec="seconds"),
+ is_dst=bool(source_time.dst()),
+ ),
+ target=TimeResult(
+ timezone=target_tz,
+ datetime=target_time.isoformat(timespec="seconds"),
+ is_dst=bool(target_time.dst()),
+ ),
+ time_difference=time_diff_str,
+ )
+
+
+async def serve(local_timezone: str | None = None) -> None:
+ server = Server("mcp-time")
+ time_server = TimeServer()
+ local_tz = str(get_local_tz(local_timezone))
+
+ @server.list_tools()
+ async def list_tools() -> list[Tool]:
+ """List available time tools."""
+ return [
+ Tool(
+ name=TimeTools.GET_CURRENT_TIME.value,
+ description="Get current time in a specific timezones",
+ inputSchema={
+ "type": "object",
+ "properties": {
+ "timezone": {
+ "type": "string",
+ "description": f"IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use '{local_tz}' as local timezone if no timezone provided by the user.",
+ }
+ },
+ "required": ["timezone"],
+ },
+ ),
+ Tool(
+ name=TimeTools.CONVERT_TIME.value,
+ description="Convert time between timezones",
+ inputSchema={
+ "type": "object",
+ "properties": {
+ "source_timezone": {
+ "type": "string",
+ "description": f"Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use '{local_tz}' as local timezone if no source timezone provided by the user.",
+ },
+ "time": {
+ "type": "string",
+ "description": "Time to convert in 24-hour format (HH:MM)",
+ },
+ "target_timezone": {
+ "type": "string",
+ "description": f"Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use '{local_tz}' as local timezone if no target timezone provided by the user.",
+ },
+ },
+ "required": ["source_timezone", "time", "target_timezone"],
+ },
+ ),
+ ]
+
+ @server.call_tool()
+ async def call_tool(
+ name: str, arguments: dict
+ ) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
+ """Handle tool calls for time queries."""
+ try:
+ match name:
+ case TimeTools.GET_CURRENT_TIME.value:
+ timezone = arguments.get("timezone")
+ if not timezone:
+ raise ValueError("Missing required argument: timezone")
+
+ result = time_server.get_current_time(timezone)
+
+ case TimeTools.CONVERT_TIME.value:
+ if not all(
+ k in arguments
+ for k in ["source_timezone", "time", "target_timezone"]
+ ):
+ raise ValueError("Missing required arguments")
+
+ result = time_server.convert_time(
+ arguments["source_timezone"],
+ arguments["time"],
+ arguments["target_timezone"],
+ )
+ case _:
+ raise ValueError(f"Unknown tool: {name}")
+
+ return [
+ TextContent(type="text", text=json.dumps(result.model_dump(), indent=2))
+ ]
+
+ except Exception as e:
+ raise ValueError(f"Error processing mcp-server-time query: {str(e)}")
+
+ options = server.create_initialization_options()
+ async with stdio_server() as (read_stream, write_stream):
+ await server.run(read_stream, write_stream, options)
diff --git a/src/time/test/time_server_test.py b/src/time/test/time_server_test.py
new file mode 100644
index 00000000..8129fb5b
--- /dev/null
+++ b/src/time/test/time_server_test.py
@@ -0,0 +1,460 @@
+
+from freezegun import freeze_time
+from mcp.shared.exceptions import McpError
+import pytest
+
+from mcp_server_time.server import TimeServer
+
+
+@pytest.mark.parametrize(
+ "test_time,timezone,expected",
+ [
+ # UTC+1 non-DST
+ (
+ "2024-01-01 12:00:00+00:00",
+ "Europe/Warsaw",
+ {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T13:00:00+01:00",
+ "is_dst": False,
+ },
+ ),
+ # UTC non-DST
+ (
+ "2024-01-01 12:00:00+00:00",
+ "Europe/London",
+ {
+ "timezone": "Europe/London",
+ "datetime": "2024-01-01T12:00:00+00:00",
+ "is_dst": False,
+ },
+ ),
+ # UTC-5 non-DST
+ (
+ "2024-01-01 12:00:00-00:00",
+ "America/New_York",
+ {
+ "timezone": "America/New_York",
+ "datetime": "2024-01-01T07:00:00-05:00",
+ "is_dst": False,
+ },
+ ),
+ # UTC+1 DST
+ (
+ "2024-03-31 12:00:00+00:00",
+ "Europe/Warsaw",
+ {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-03-31T14:00:00+02:00",
+ "is_dst": True,
+ },
+ ),
+ # UTC DST
+ (
+ "2024-03-31 12:00:00+00:00",
+ "Europe/London",
+ {
+ "timezone": "Europe/London",
+ "datetime": "2024-03-31T13:00:00+01:00",
+ "is_dst": True,
+ },
+ ),
+ # UTC-5 DST
+ (
+ "2024-03-31 12:00:00-00:00",
+ "America/New_York",
+ {
+ "timezone": "America/New_York",
+ "datetime": "2024-03-31T08:00:00-04:00",
+ "is_dst": True,
+ },
+ ),
+ ],
+)
+def test_get_current_time(test_time, timezone, expected):
+ with freeze_time(test_time):
+ time_server = TimeServer()
+ result = time_server.get_current_time(timezone)
+ assert result.timezone == expected["timezone"]
+ assert result.datetime == expected["datetime"]
+ assert result.is_dst == expected["is_dst"]
+
+
+def test_get_current_time_with_invalid_timezone():
+ time_server = TimeServer()
+ with pytest.raises(
+ McpError,
+ match=r"Invalid timezone: 'No time zone found with key Invalid/Timezone'",
+ ):
+ time_server.get_current_time("Invalid/Timezone")
+
+
+@pytest.mark.parametrize(
+ "source_tz,time_str,target_tz,expected_error",
+ [
+ (
+ "invalid_tz",
+ "12:00",
+ "Europe/London",
+ "Invalid timezone: 'No time zone found with key invalid_tz'",
+ ),
+ (
+ "Europe/Warsaw",
+ "12:00",
+ "invalid_tz",
+ "Invalid timezone: 'No time zone found with key invalid_tz'",
+ ),
+ (
+ "Europe/Warsaw",
+ "25:00",
+ "Europe/London",
+ "Invalid time format. Expected HH:MM [24-hour format]",
+ ),
+ ],
+)
+def test_convert_time_errors(source_tz, time_str, target_tz, expected_error):
+ time_server = TimeServer()
+ with pytest.raises((McpError, ValueError), match=expected_error):
+ time_server.convert_time(source_tz, time_str, target_tz)
+
+
+@pytest.mark.parametrize(
+ "test_time,source_tz,time_str,target_tz,expected",
+ [
+ # Basic case: Standard time conversion between Warsaw and London (1 hour difference)
+ # Warsaw is UTC+1, London is UTC+0
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Europe/London",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Europe/London",
+ "datetime": "2024-01-01T11:00:00+00:00",
+ "is_dst": False,
+ },
+ "time_difference": "-1.0h",
+ },
+ ),
+ # Reverse case of above: London to Warsaw conversion
+ # Shows how time difference is positive when going east
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Europe/London",
+ "12:00",
+ "Europe/Warsaw",
+ {
+ "source": {
+ "timezone": "Europe/London",
+ "datetime": "2024-01-01T12:00:00+00:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T13:00:00+01:00",
+ "is_dst": False,
+ },
+ "time_difference": "+1.0h",
+ },
+ ),
+ # Edge case: Different DST periods between Europe and USA
+ # Europe ends DST on Oct 27, while USA waits until Nov 3
+ # This creates a one-week period where Europe is in standard time but USA still observes DST
+ (
+ "2024-10-28 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "America/New_York",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-10-28T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "America/New_York",
+ "datetime": "2024-10-28T07:00:00-04:00",
+ "is_dst": True,
+ },
+ "time_difference": "-5.0h",
+ },
+ ),
+ # Follow-up to previous case: After both regions end DST
+ # Shows how time difference increases by 1 hour when USA also ends DST
+ (
+ "2024-11-04 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "America/New_York",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-11-04T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "America/New_York",
+ "datetime": "2024-11-04T06:00:00-05:00",
+ "is_dst": False,
+ },
+ "time_difference": "-6.0h",
+ },
+ ),
+ # Edge case: Nepal's unusual UTC+5:45 offset
+ # One of the few time zones using 45-minute offset
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Asia/Kathmandu",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Asia/Kathmandu",
+ "datetime": "2024-01-01T16:45:00+05:45",
+ "is_dst": False,
+ },
+ "time_difference": "+4.75h",
+ },
+ ),
+ # Reverse case for Nepal
+ # Demonstrates how 45-minute offset works in opposite direction
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Asia/Kathmandu",
+ "12:00",
+ "Europe/Warsaw",
+ {
+ "source": {
+ "timezone": "Asia/Kathmandu",
+ "datetime": "2024-01-01T12:00:00+05:45",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T07:15:00+01:00",
+ "is_dst": False,
+ },
+ "time_difference": "-4.75h",
+ },
+ ),
+ # Edge case: Lord Howe Island's unique DST rules
+ # One of the few places using 30-minute DST shift
+ # During summer (DST), they use UTC+11
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Australia/Lord_Howe",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Australia/Lord_Howe",
+ "datetime": "2024-01-01T22:00:00+11:00",
+ "is_dst": True,
+ },
+ "time_difference": "+10.0h",
+ },
+ ),
+ # Second Lord Howe Island case: During their standard time
+ # Shows transition to UTC+10:30 after DST ends
+ (
+ "2024-04-07 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Australia/Lord_Howe",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-04-07T12:00:00+02:00",
+ "is_dst": True,
+ },
+ "target": {
+ "timezone": "Australia/Lord_Howe",
+ "datetime": "2024-04-07T20:30:00+10:30",
+ "is_dst": False,
+ },
+ "time_difference": "+8.5h",
+ },
+ ),
+ # Edge case: Date line crossing with Samoa
+ # Demonstrates how a single time conversion can result in a date change
+ # Samoa is UTC+13, creating almost a full day difference with Warsaw
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Europe/Warsaw",
+ "23:00",
+ "Pacific/Apia",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T23:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Pacific/Apia",
+ "datetime": "2024-01-02T11:00:00+13:00",
+ "is_dst": False,
+ },
+ "time_difference": "+12.0h",
+ },
+ ),
+ # Edge case: Iran's unusual half-hour offset
+ # Demonstrates conversion with Iran's UTC+3:30 timezone
+ (
+ "2024-03-21 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Asia/Tehran",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-03-21T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Asia/Tehran",
+ "datetime": "2024-03-21T14:30:00+03:30",
+ "is_dst": False,
+ },
+ "time_difference": "+2.5h",
+ },
+ ),
+ # Edge case: Venezuela's unusual -4:30 offset (historical)
+ # In 2016, Venezuela moved from -4:30 to -4:00
+ # Useful for testing historical dates
+ (
+ "2016-04-30 00:00:00+00:00", # Just before the change
+ "Europe/Warsaw",
+ "12:00",
+ "America/Caracas",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2016-04-30T12:00:00+02:00",
+ "is_dst": True,
+ },
+ "target": {
+ "timezone": "America/Caracas",
+ "datetime": "2016-04-30T05:30:00-04:30",
+ "is_dst": False,
+ },
+ "time_difference": "-6.5h",
+ },
+ ),
+ # Edge case: Israel's variable DST
+ # Israel's DST changes don't follow a fixed pattern
+ # They often change dates year-to-year based on Hebrew calendar
+ (
+ "2024-10-27 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Asia/Jerusalem",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-10-27T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Asia/Jerusalem",
+ "datetime": "2024-10-27T13:00:00+02:00",
+ "is_dst": False,
+ },
+ "time_difference": "+1.0h",
+ },
+ ),
+ # Edge case: Antarctica/Troll station
+ # Only timezone that uses UTC+0 in winter and UTC+2 in summer
+ # One of the few zones with exactly 2 hours DST difference
+ (
+ "2024-03-31 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Antarctica/Troll",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-03-31T12:00:00+02:00",
+ "is_dst": True,
+ },
+ "target": {
+ "timezone": "Antarctica/Troll",
+ "datetime": "2024-03-31T12:00:00+02:00",
+ "is_dst": True,
+ },
+ "time_difference": "+0.0h",
+ },
+ ),
+ # Edge case: Kiribati date line anomaly
+ # After skipping Dec 31, 1994, eastern Kiribati is UTC+14
+ # The furthest forward timezone in the world
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Europe/Warsaw",
+ "23:00",
+ "Pacific/Kiritimati",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T23:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Pacific/Kiritimati",
+ "datetime": "2024-01-02T12:00:00+14:00",
+ "is_dst": False,
+ },
+ "time_difference": "+13.0h",
+ },
+ ),
+ # Edge case: Chatham Islands, New Zealand
+ # Uses unusual 45-minute offset AND observes DST
+ # UTC+12:45 in standard time, UTC+13:45 in DST
+ (
+ "2024-01-01 00:00:00+00:00",
+ "Europe/Warsaw",
+ "12:00",
+ "Pacific/Chatham",
+ {
+ "source": {
+ "timezone": "Europe/Warsaw",
+ "datetime": "2024-01-01T12:00:00+01:00",
+ "is_dst": False,
+ },
+ "target": {
+ "timezone": "Pacific/Chatham",
+ "datetime": "2024-01-02T00:45:00+13:45",
+ "is_dst": True,
+ },
+ "time_difference": "+12.75h",
+ },
+ ),
+ ],
+)
+def test_convert_time(test_time, source_tz, time_str, target_tz, expected):
+ with freeze_time(test_time):
+ time_server = TimeServer()
+ result = time_server.convert_time(source_tz, time_str, target_tz)
+
+ assert result.source.timezone == expected["source"]["timezone"]
+ assert result.target.timezone == expected["target"]["timezone"]
+ assert result.source.datetime == expected["source"]["datetime"]
+ assert result.target.datetime == expected["target"]["datetime"]
+ assert result.source.is_dst == expected["source"]["is_dst"]
+ assert result.target.is_dst == expected["target"]["is_dst"]
+ assert result.time_difference == expected["time_difference"]
diff --git a/src/time/uv.lock b/src/time/uv.lock
new file mode 100644
index 00000000..a8d820ab
--- /dev/null
+++ b/src/time/uv.lock
@@ -0,0 +1,489 @@
+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 = "freezegun"
+version = "1.5.1"
+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 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/51/0b/0d7fee5919bccc1fdc1c2a7528b98f65c6f69b223a3fd8f809918c142c36/freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1", size = 17569 },
+]
+
+[[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-time"
+version = "0.6.2"
+source = { editable = "." }
+dependencies = [
+ { name = "mcp" },
+ { name = "pydantic" },
+ { name = "tzdata" },
+]
+
+[package.dev-dependencies]
+dev = [
+ { name = "freezegun" },
+ { name = "pyright" },
+ { name = "pytest" },
+ { name = "ruff" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "mcp", specifier = ">=1.0.0" },
+ { name = "pydantic", specifier = ">=2.0.0" },
+ { name = "tzdata", specifier = ">=2024.2" },
+]
+
+[package.metadata.requires-dev]
+dev = [
+ { name = "freezegun", specifier = ">=1.5.1" },
+ { name = "pyright", specifier = ">=1.1.389" },
+ { name = "pytest", specifier = ">=8.3.3" },
+ { name = "ruff", specifier = ">=0.8.1" },
+]
+
+[[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 = "python-dateutil"
+version = "2.9.0.post0"
+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 }
+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 },
+]
+
+[[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 = "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 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 },
+]
+
+[[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 = "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 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 },
+]
+
+[[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 },
+]