From d144a53b25df9f1b16f7ad3650768010123fcd02 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 21 Nov 2024 20:52:40 +0000 Subject: [PATCH 1/7] Add CI workflow for Python build + publish --- .github/workflows/python.yml | 80 +++++++++++++++++++ .../workflows/{main.yml => typescript.yml} | 2 + 2 files changed, 82 insertions(+) create mode 100644 .github/workflows/python.yml rename .github/workflows/{main.yml => typescript.yml} (97%) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 00000000..1833be08 --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,80 @@ +name: Python + +on: + push: + branches: + - main + pull_request: + release: + types: [published] + +jobs: + detect-packages: + runs-on: ubuntu-latest + outputs: + packages: ${{ steps.find-packages.outputs.packages }} + steps: + - uses: actions/checkout@v4 + + - name: Find Python packages + id: find-packages + run: | + PACKAGES=$(find src -name pyproject.toml -exec dirname {} \; | jq -R -s -c 'split("\n")[:-1]') + echo "packages=$PACKAGES" >> $GITHUB_OUTPUT + + build: + needs: [detect-packages] + strategy: + matrix: + package: ${{ fromJson(needs.detect-packages.outputs.packages) }} + name: Build ${{ matrix.package }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v3 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version-file: "${{ matrix.package }}/.python-version" + + - name: Install dependencies + working-directory: ${{ matrix.package }} + run: uv sync --frozen --all-extras --dev + + - name: Run pyright + working-directory: ${{ matrix.package }} + run: uv run --frozen pyright + + - name: Build package + working-directory: ${{ matrix.package }} + run: uv build + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: dist-${{ matrix.package }} + path: ${{ matrix.package }}/dist/ + + publish: + needs: [build, detect-packages] + strategy: + matrix: + package: ${{ fromJson(needs.detect-packages.outputs.packages) }} + name: Publish ${{ matrix.package }} + runs-on: ubuntu-latest + environment: release + permissions: + id-token: write # Required for trusted publishing + + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: dist-${{ matrix.package }} + path: dist/ + + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/main.yml b/.github/workflows/typescript.yml similarity index 97% rename from .github/workflows/main.yml rename to .github/workflows/typescript.yml index 7b85236b..07229176 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/typescript.yml @@ -1,3 +1,5 @@ +name: TypeScript + on: push: branches: From d68341d9853c9cf932cc46ba886aed27bf8a82ad Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 21 Nov 2024 20:52:56 +0000 Subject: [PATCH 2/7] Tweak Python server package names --- src/git/pyproject.toml | 2 +- src/sqlite/pyproject.toml | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/git/pyproject.toml b/src/git/pyproject.toml index 3fc2ae8c..86dad110 100644 --- a/src/git/pyproject.toml +++ b/src/git/pyproject.toml @@ -1,5 +1,5 @@ [project] -name = "mcp-git" +name = "mcp-server-git" version = "0.2.0" description = "A Model Context Protocol server providing tools to read, search, and manipulate Git repositories programmatically via LLMs" readme = "README.md" diff --git a/src/sqlite/pyproject.toml b/src/sqlite/pyproject.toml index b0b1b2b6..8cba887c 100644 --- a/src/sqlite/pyproject.toml +++ b/src/sqlite/pyproject.toml @@ -1,16 +1,14 @@ [project] -name = "sqlite" +name = "mcp-server-sqlite" version = "0.1.0" description = "A simple SQLite MCP server" readme = "README.md" requires-python = ">=3.11" -dependencies = [ - "mcp>=0.9.1", -] +dependencies = ["mcp>=0.9.1"] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project.scripts] -sqlite = "sqlite:main" \ No newline at end of file +sqlite = "sqlite:main" From 06cb2759b8a12903345956ae99431ab87a561b00 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 21 Nov 2024 21:07:25 +0000 Subject: [PATCH 3/7] Fix package and executable names, re-sync `uv` --- src/git/pyproject.toml | 2 +- src/git/src/mcp_git/__main__.py | 5 ----- .../{mcp_git => mcp_server_git}/__init__.py | 0 src/git/src/mcp_server_git/__main__.py | 5 +++++ src/git/uv.lock | 2 +- src/sqlite/pyproject.toml | 2 +- .../{sqlite => mcp_server_sqlite}/__init__.py | 0 .../{sqlite => mcp_server_sqlite}/server.py | 0 src/sqlite/uv.lock | 22 +++++++++---------- 9 files changed, 19 insertions(+), 19 deletions(-) delete mode 100644 src/git/src/mcp_git/__main__.py rename src/git/src/{mcp_git => mcp_server_git}/__init__.py (100%) create mode 100644 src/git/src/mcp_server_git/__main__.py rename src/sqlite/src/{sqlite => mcp_server_sqlite}/__init__.py (100%) rename src/sqlite/src/{sqlite => mcp_server_sqlite}/server.py (100%) diff --git a/src/git/pyproject.toml b/src/git/pyproject.toml index 86dad110..4abc81af 100644 --- a/src/git/pyproject.toml +++ b/src/git/pyproject.toml @@ -23,7 +23,7 @@ dependencies = [ ] [project.scripts] -mcp-git = "mcp_git:main" +mcp-server-git = "mcp_server_git:main" [build-system] requires = ["hatchling"] diff --git a/src/git/src/mcp_git/__main__.py b/src/git/src/mcp_git/__main__.py deleted file mode 100644 index 7182e6f7..00000000 --- a/src/git/src/mcp_git/__main__.py +++ /dev/null @@ -1,5 +0,0 @@ -# __main__.py - -from mcp_git import main - -main() diff --git a/src/git/src/mcp_git/__init__.py b/src/git/src/mcp_server_git/__init__.py similarity index 100% rename from src/git/src/mcp_git/__init__.py rename to src/git/src/mcp_server_git/__init__.py diff --git a/src/git/src/mcp_server_git/__main__.py b/src/git/src/mcp_server_git/__main__.py new file mode 100644 index 00000000..beda6b0e --- /dev/null +++ b/src/git/src/mcp_server_git/__main__.py @@ -0,0 +1,5 @@ +# __main__.py + +from mcp_server_git import main + +main() diff --git a/src/git/uv.lock b/src/git/uv.lock index f994f688..191ed15f 100644 --- a/src/git/uv.lock +++ b/src/git/uv.lock @@ -166,7 +166,7 @@ wheels = [ ] [[package]] -name = "mcp-git" +name = "mcp-server-git" version = "0.2.0" source = { editable = "." } dependencies = [ diff --git a/src/sqlite/pyproject.toml b/src/sqlite/pyproject.toml index 8cba887c..1730db4b 100644 --- a/src/sqlite/pyproject.toml +++ b/src/sqlite/pyproject.toml @@ -11,4 +11,4 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project.scripts] -sqlite = "sqlite:main" +mcp-server-sqlite = "mcp_server_sqlite:main" diff --git a/src/sqlite/src/sqlite/__init__.py b/src/sqlite/src/mcp_server_sqlite/__init__.py similarity index 100% rename from src/sqlite/src/sqlite/__init__.py rename to src/sqlite/src/mcp_server_sqlite/__init__.py diff --git a/src/sqlite/src/sqlite/server.py b/src/sqlite/src/mcp_server_sqlite/server.py similarity index 100% rename from src/sqlite/src/sqlite/server.py rename to src/sqlite/src/mcp_server_sqlite/server.py diff --git a/src/sqlite/uv.lock b/src/sqlite/uv.lock index fc36f073..d9c68db8 100644 --- a/src/sqlite/uv.lock +++ b/src/sqlite/uv.lock @@ -126,6 +126,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/a0/2ee813d456b57a726d583868417d1ad900fbe12ee3c8cd866e3e804ca486/mcp-0.9.1-py3-none-any.whl", hash = "sha256:7f640fcfb0be486aa510594df309920ae1d375cdca1f8aff21db3a96d837f303", size = 31562 }, ] +[[package]] +name = "mcp-server-sqlite" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "mcp" }, +] + +[package.metadata] +requires-dist = [{ name = "mcp", specifier = ">=0.9.1" }] + [[package]] name = "pydantic" version = "2.10.0" @@ -202,17 +213,6 @@ 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 = "sqlite" -version = "0.1.0" -source = { editable = "." } -dependencies = [ - { name = "mcp" }, -] - -[package.metadata] -requires-dist = [{ name = "mcp", specifier = ">=0.9.1" }] - [[package]] name = "sse-starlette" version = "2.1.3" From 6d4bbf5982807fe1628a04924ac154a840de683e Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 21 Nov 2024 21:08:36 +0000 Subject: [PATCH 4/7] Fix type error --- src/sqlite/src/mcp_server_sqlite/server.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sqlite/src/mcp_server_sqlite/server.py b/src/sqlite/src/mcp_server_sqlite/server.py index 8836cf45..14db5674 100644 --- a/src/sqlite/src/mcp_server_sqlite/server.py +++ b/src/sqlite/src/mcp_server_sqlite/server.py @@ -5,8 +5,9 @@ from pathlib import Path from mcp.server.models import InitializationOptions import mcp.types as types -from mcp.server import NotificationOptions, Server, AnyUrl +from mcp.server import NotificationOptions, Server import mcp.server.stdio +from pydantic import AnyUrl # Set up logging to file log_file = Path('mcp_server.log') @@ -332,7 +333,7 @@ async def handle_call_tool( memo = self._synthesize_memo() # Notify clients that the memo resource has changed - await self.request_context.session.send_resource_updated("memo://insights") + await self.request_context.session.send_resource_updated(AnyUrl("memo://insights")) return [types.TextContent(type="text", text="Insight added to memo")] if not arguments: From 46dde5252c1d57f6060c668915afe110a396876a Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 21 Nov 2024 21:40:29 +0000 Subject: [PATCH 5/7] Add pyright in dev --- src/git/pyproject.toml | 5 ++++- src/git/uv.lock | 28 +++++++++++++++++++++++++++- src/sqlite/pyproject.toml | 5 +++++ src/sqlite/uv.lock | 30 ++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/git/pyproject.toml b/src/git/pyproject.toml index 4abc81af..1f3f4773 100644 --- a/src/git/pyproject.toml +++ b/src/git/pyproject.toml @@ -30,4 +30,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.uv] -dev-dependencies = ["ruff>=0.7.3"] +dev-dependencies = [ + "pyright>=1.1.389", + "ruff>=0.7.3", +] diff --git a/src/git/uv.lock b/src/git/uv.lock index 191ed15f..f35f8157 100644 --- a/src/git/uv.lock +++ b/src/git/uv.lock @@ -178,6 +178,7 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pyright" }, { name = "ruff" }, ] @@ -190,7 +191,19 @@ requires-dist = [ ] [package.metadata.requires-dev] -dev = [{ name = "ruff", specifier = ">=0.7.3" }] +dev = [ + { name = "pyright", specifier = ">=1.1.389" }, + { name = "ruff", specifier = ">=0.7.3" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] [[package]] name = "pydantic" @@ -273,6 +286,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, ] +[[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 = "ruff" version = "0.7.4" diff --git a/src/sqlite/pyproject.toml b/src/sqlite/pyproject.toml index 1730db4b..068e038c 100644 --- a/src/sqlite/pyproject.toml +++ b/src/sqlite/pyproject.toml @@ -10,5 +10,10 @@ dependencies = ["mcp>=0.9.1"] requires = ["hatchling"] build-backend = "hatchling.build" +[tool.uv] +dev-dependencies = [ + "pyright>=1.1.389", +] + [project.scripts] mcp-server-sqlite = "mcp_server_sqlite:main" diff --git a/src/sqlite/uv.lock b/src/sqlite/uv.lock index d9c68db8..b290984a 100644 --- a/src/sqlite/uv.lock +++ b/src/sqlite/uv.lock @@ -134,9 +134,26 @@ dependencies = [ { name = "mcp" }, ] +[package.dev-dependencies] +dev = [ + { name = "pyright" }, +] + [package.metadata] requires-dist = [{ name = "mcp", specifier = ">=0.9.1" }] +[package.metadata.requires-dev] +dev = [{ name = "pyright", specifier = ">=1.1.389" }] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + [[package]] name = "pydantic" version = "2.10.0" @@ -204,6 +221,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/18/e5744a132b81f98b9f92e15f33f03229a1d254ce7af942b1422ec2ac656f/pydantic_core-2.27.0-cp313-none-win_arm64.whl", hash = "sha256:6f4a53af9e81d757756508b57cae1cf28293f0f31b9fa2bfcb416cc7fb230f9d", size = 1877469 }, ] +[[package]] +name = "pyright" +version = "1.1.389" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 }, +] + [[package]] name = "sniffio" version = "1.3.1" From 4f871840e5d206076f58573922e95062296ae5dd Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 21 Nov 2024 21:43:14 +0000 Subject: [PATCH 6/7] Fix invalid artifact names --- .github/workflows/python.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 1833be08..51c61702 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -18,8 +18,9 @@ jobs: - name: Find Python packages id: find-packages + working-directory: src run: | - PACKAGES=$(find src -name pyproject.toml -exec dirname {} \; | jq -R -s -c 'split("\n")[:-1]') + PACKAGES=$(find . -name pyproject.toml -exec dirname {} \; | sed 's/^\.\///' | jq -R -s -c 'split("\n")[:-1]') echo "packages=$PACKAGES" >> $GITHUB_OUTPUT build: @@ -38,25 +39,25 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version-file: "${{ matrix.package }}/.python-version" + python-version-file: "src/${{ matrix.package }}/.python-version" - name: Install dependencies - working-directory: ${{ matrix.package }} + working-directory: src/${{ matrix.package }} run: uv sync --frozen --all-extras --dev - name: Run pyright - working-directory: ${{ matrix.package }} + working-directory: src/${{ matrix.package }} run: uv run --frozen pyright - name: Build package - working-directory: ${{ matrix.package }} + working-directory: src/${{ matrix.package }} run: uv build - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: dist-${{ matrix.package }} - path: ${{ matrix.package }}/dist/ + path: src/${{ matrix.package }}/dist/ publish: needs: [build, detect-packages] @@ -67,7 +68,7 @@ jobs: runs-on: ubuntu-latest environment: release permissions: - id-token: write # Required for trusted publishing + id-token: write # Required for trusted publishing steps: - name: Download artifacts From aac117f7b3f20ee6a7b56a053e509544ee1f40c8 Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 21 Nov 2024 21:56:42 +0000 Subject: [PATCH 7/7] Only publish on release --- .github/workflows/python.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 51c61702..a1edc0c9 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -60,12 +60,15 @@ jobs: path: src/${{ matrix.package }}/dist/ publish: + runs-on: ubuntu-latest needs: [build, detect-packages] + if: github.event_name == 'release' + strategy: matrix: package: ${{ fromJson(needs.detect-packages.outputs.packages) }} name: Publish ${{ matrix.package }} - runs-on: ubuntu-latest + environment: release permissions: id-token: write # Required for trusted publishing