Skip to content

Commit a007427

Browse files
authored
[pypi-mcp-server] feat: add the server (#69)
1 parent 73f4842 commit a007427

File tree

14 files changed

+1236
-0
lines changed

14 files changed

+1236
-0
lines changed

pypi-mcp-server/.actor/actor.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"actorSpecification": 1,
3+
"name": "pypi-query-mcp-server",
4+
"title": "PyPI Query MCP Server",
5+
"description": "An Apify Actor that proxies the pypi-query-mcp-server over Streamable HTTP with optional charging and tool whitelisting.",
6+
"version": "0.1",
7+
"buildTag": "latest",
8+
"usesStandbyMode": true,
9+
"meta": {
10+
"templateId": "python-mcp-server"
11+
},
12+
"dockerfile": "../Dockerfile",
13+
"webServerMcpPath": "/mcp"
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"apify-actor-start": {
3+
"eventTitle": "MCP server startup",
4+
"eventDescription": "Initial fee for starting the MCP Server Actor.",
5+
"eventPriceUsd": 0.10
6+
},
7+
"tool-call": {
8+
"eventTitle": "PyPI tool call",
9+
"eventDescription": "Flat fee for any PyPI Query MCP tool invocation.",
10+
"eventPriceUsd": 0.001
11+
}
12+
}

pypi-mcp-server/.gitignore

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
.mise.toml
2+
.nvim.lua
3+
storage
4+
5+
# The rest is copied from https://github.com/github/gitignore/blob/main/Python.gitignore
6+
7+
# Byte-compiled / optimized / DLL files
8+
__pycache__/
9+
*.py[cod]
10+
*$py.class
11+
12+
# C extensions
13+
*.so
14+
15+
# Distribution / packaging
16+
.Python
17+
build/
18+
develop-eggs/
19+
dist/
20+
downloads/
21+
eggs/
22+
.eggs/
23+
lib/
24+
lib64/
25+
parts/
26+
sdist/
27+
var/
28+
wheels/
29+
share/python-wheels/
30+
*.egg-info/
31+
.installed.cfg
32+
*.egg
33+
MANIFEST
34+
35+
# PyInstaller
36+
# Usually these files are written by a python script from a template
37+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
38+
*.manifest
39+
*.spec
40+
41+
# Installer logs
42+
pip-log.txt
43+
pip-delete-this-directory.txt
44+
45+
# Unit test / coverage reports
46+
htmlcov/
47+
.tox/
48+
.nox/
49+
.coverage
50+
.coverage.*
51+
.cache
52+
nosetests.xml
53+
coverage.xml
54+
*.cover
55+
*.py,cover
56+
.hypothesis/
57+
.pytest_cache/
58+
cover/
59+
60+
# Translations
61+
*.mo
62+
*.pot
63+
64+
# Django stuff:
65+
*.log
66+
local_settings.py
67+
db.sqlite3
68+
db.sqlite3-journal
69+
70+
# Flask stuff:
71+
instance/
72+
.webassets-cache
73+
74+
# Scrapy stuff:
75+
.scrapy
76+
77+
# Sphinx documentation
78+
docs/_build/
79+
80+
# PyBuilder
81+
.pybuilder/
82+
target/
83+
84+
# Jupyter Notebook
85+
.ipynb_checkpoints
86+
87+
# IPython
88+
profile_default/
89+
ipython_config.py
90+
91+
# pyenv
92+
# For a library or package, you might want to ignore these files since the code is
93+
# intended to run in multiple environments; otherwise, check them in:
94+
.python-version
95+
96+
# pdm
97+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
98+
#pdm.lock
99+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
100+
# in version control.
101+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
102+
.pdm.toml
103+
.pdm-python
104+
.pdm-build/
105+
106+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
107+
__pypackages__/
108+
109+
# Celery stuff
110+
celerybeat-schedule
111+
celerybeat.pid
112+
113+
# SageMath parsed files
114+
*.sage.py
115+
116+
# Environments
117+
.env
118+
.venv
119+
env/
120+
venv/
121+
ENV/
122+
env.bak/
123+
venv.bak/
124+
125+
# Spyder project settings
126+
.spyderproject
127+
.spyproject
128+
129+
# Rope project settings
130+
.ropeproject
131+
132+
# mkdocs documentation
133+
/site
134+
135+
# mypy
136+
.mypy_cache/
137+
.dmypy.json
138+
dmypy.json
139+
140+
# Pyre type checker
141+
.pyre/
142+
143+
# pytype static type analyzer
144+
.pytype/
145+
146+
# Cython debug symbols
147+
cython_debug/
148+
149+
# PyCharm
150+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
151+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
152+
# and can be added to the global gitignore or merged into this file. For a more nuclear
153+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
154+
.idea/
155+
156+
# Visual Studio Code
157+
# Ignores the folder created by VS Code when changing workspace settings, doing debugger
158+
# configuration, etc. Can be commented out to share Workspace Settings within a team
159+
.vscode
160+
161+
# Zed editor
162+
# Ignores the folder created when setting Project Settings in the Zed editor. Can be commented out
163+
# to share Project Settings within a team
164+
.zed
165+
166+
# Added by Apify CLI
167+
node_modules

pypi-mcp-server/Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# First, specify the base Docker image.
2+
# You can see the Docker images from Apify at https://hub.docker.com/r/apify/.
3+
# You can also use any other image from Docker Hub.
4+
FROM apify/actor-python:3.13
5+
6+
USER myuser
7+
8+
# Second, copy just requirements.txt into the Actor image,
9+
# since it should be the only file that affects the dependency installation in the next step,
10+
# in order to speed up the build.
11+
COPY --chown=myuser:myuser requirements.txt ./
12+
13+
# Install the packages specified in requirements.txt,
14+
# print the installed Python version, pip version,
15+
# and all installed packages with their versions for debugging.
16+
RUN echo "Python version:" \
17+
&& python --version \
18+
&& echo "Pip version:" \
19+
&& pip --version \
20+
&& echo "Installing dependencies:" \
21+
&& pip install -r requirements.txt \
22+
&& echo "All installed Python packages:" \
23+
&& pip freeze
24+
25+
# Next, copy the remaining files and directories with the source code.
26+
# Since we do this after installing the dependencies, quick builds will be really fast
27+
# for most source file changes.
28+
COPY --chown=myuser:myuser . ./
29+
30+
# Use compileall to ensure the runnability of the Actor Python code.
31+
RUN python3 -m compileall -q src/
32+
33+
# Specify how to launch the source code of your Actor.
34+
# By default, the "python3 -m ." command is run.
35+
CMD ["python3", "-m", "src"]

pypi-mcp-server/README.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
## PyPI Query MCP Server
2+
3+
A Model Context Protocol (MCP) server that lets AI agents explore and analyze Python packages from PyPI (and private indexes). It’s deployed as an Apify Actor and proxies the excellent open-source **pypi-query-mcp-server** over Streamable HTTP, with optional per-tool charging and a configurable whitelist.
4+
5+
**About this MCP Server:** To understand how to connect to and utilize this MCP server, please refer to the official Model Context Protocol documentation at [mcp.apify.com](https://mcp.apify.com).
6+
7+
---
8+
9+
## Connection URL
10+
11+
MCP clients can connect to this server at:
12+
13+
```text
14+
https://mcp-servers--pypi-query-mcp-server.apify.actor/mcp
15+
```
16+
17+
---
18+
19+
## Client Configuration
20+
21+
Add this to your MCP client configuration:
22+
23+
```json
24+
{
25+
"mcpServers": {
26+
"pypi-query": {
27+
"url": "https://mcp-servers--pypi-query-mcp-server.apify.actor/mcp",
28+
"headers": {
29+
"Authorization": "Bearer YOUR_APIFY_TOKEN"
30+
}
31+
}
32+
}
33+
}
34+
```
35+
36+
**Note:** Replace `YOUR_APIFY_TOKEN` with your Apify API token (find it in the [Apify Console](https://console.apify.com/account/integrations)).
37+
38+
---
39+
40+
## 🚩 Claim this MCP server
41+
42+
All credit to the original authors of **pypi-query-mcp-server**: <https://github.com/loonghao/pypi-query-mcp-server>
43+
To claim this server on Apify, please email [[email protected]](mailto:[email protected]).
44+
45+
---
46+
47+
## What this server does
48+
49+
- Proxies the **PyPI Query MCP Server** to HTTP so any MCP client can connect.
50+
- Supports **per-tool charging** (via Apify’s `Actor.charge`) and a **tool whitelist**.
51+
- Passes through environment variables for public mirrors and **private package indexes**.
52+
- Runs reliably in **Apify Standby** with an `/mcp` endpoint and a small helper HTML page at `/`.
53+
54+
---
55+
56+
## Features
57+
58+
- Look up package info, versions, dependencies, and compatibility.
59+
- Resolve dependency trees and detect conflicts.
60+
- Gather download stats, trends, and top packages.
61+
- Analyze package quality and security (if enabled upstream).
62+
- Plan upgrades, migrations, and environment updates.
63+
64+
---
65+
66+
## Available Tools
67+
68+
This server exposes the PyPI tools provided by the upstream server (whitelisted by default). Tool identifiers:
69+
70+
- `get_package_info`
71+
- `get_package_versions`
72+
- `get_package_dependencies`
73+
- `check_package_python_compatibility`
74+
- `get_package_compatible_python_versions`
75+
- `resolve_dependencies`
76+
- `download_package`
77+
- `get_download_statistics`
78+
- `get_download_trends`
79+
- `get_top_downloaded_packages`
80+
- `analyze_package_quality`
81+
- `compare_packages`
82+
- `suggest_alternatives`
83+
- `resolve_dependency_conflicts`
84+
- `plan_version_upgrade`
85+
- `audit_security_risks`
86+
- `plan_package_migration`
87+
- `generate_migration_checklist`
88+
- `analyze_environment_dependencies`
89+
- `check_outdated_packages`
90+
- `generate_update_plan`
91+
- `analyze_daily_trends`
92+
- `find_trending_packages`
93+
- `track_package_updates`
94+
95+
> Note: The exact set may evolve with upstream releases. This proxy can be configured to allow all tools or only a curated subset.
96+
97+
---
98+
99+
## Environment Variables
100+
101+
The proxy launches the upstream server via `uvx` (stdio) and forwards these environment variables:
102+
103+
- Public indexes & mirrors
104+
- `PYPI_INDEX_URL` (default: `https://pypi.org/pypi`)
105+
- `PYPI_INDEX_URLS`, `PYPI_EXTRA_INDEX_URLS` (comma-separated)
106+
- Caching & logging
107+
- `PYPI_CACHE_TTL` (default: `3600`)
108+
- `PYPI_LOG_LEVEL` (default: `INFO`)
109+
- Networking
110+
- `PYPI_REQUEST_TIMEOUT` (default: `30`)
111+
- Private repository support (optional)
112+
- `PYPI_PRIVATE_PYPI_URL`
113+
- `PYPI_PRIVATE_PYPI_USERNAME`
114+
- `PYPI_PRIVATE_PYPI_PASSWORD`
115+
- Advanced (optional)
116+
- `PYPI_DEPENDENCY_MAX_DEPTH` (default: `5`)
117+
- `PYPI_DEPENDENCY_MAX_CONCURRENT` (default: `10`)
118+
- `PYPI_ENABLE_SECURITY_ANALYSIS` (`true`|`false`, default: `false`)
119+
120+
Set these in your Apify Actor (Secrets / Environment) as needed.
121+
122+
---
123+
124+
## Usage Examples
125+
126+
Ask your MCP client to:
127+
128+
- “Get info for `requests`.” → `get_package_info`
129+
- “Show versions for `pydantic`.” → `get_package_versions`
130+
- “Resolve dependencies for `fastapi==0.115.0`.” → `resolve_dependencies`
131+
- “Are `httpx 0.27` and Python 3.12 compatible?” → `check_package_python_compatibility`
132+
- “Top downloads last week” → `get_top_downloaded_packages`
133+
- “Compare `requests` vs `httpx`” → `compare_packages`
134+
135+
---
136+
137+
## Pricing / Charging (optional)
138+
139+
This server can charge per MCP operation. Defaults are defined in code (`src/const.py`) and can be tuned per tool (e.g., heavier “resolve” or “download” operations can cost more). If you don’t want charging, remove or relax the whitelist and omit charging hooks.
140+
141+
---
142+
143+
## Local development & debugging
144+
145+
- This Actor only serves in **STANDBY** on Apify. When running locally you can still start it, but the HTTP `/mcp` endpoint is designed for Standby on the platform.
146+
- The server logs a ready-to-copy MCP JSON snippet with the endpoint URL at startup.
147+
148+
---
149+
150+
## References
151+
152+
To learn more:
153+
154+
- [Apify SDK for Python](https://docs.apify.com/sdk/python)
155+
- [Apify Platform](https://docs.apify.com/platform)
156+
- [Apify MCP Server](https://docs.apify.com/platform/integrations/mcp)
157+
- [Model Context Protocol docs](https://mcp.apify.com)
158+
- [Webinar: Building and Monetizing MCP Servers on Apify](https://www.youtube.com/watch?v=w3AH3jIrXXo)
159+
- [Join the Apify developer community on Discord](https://discord.com/invite/jyEM2PRvMU)
160+
161+
---
162+
163+
**Attribution:** Built as a proxy over the open-source **pypi-query-mcp-server**.

0 commit comments

Comments
 (0)