Your support encourages me to keep creating/supporting my open-source projects. If you found value in this project, you can buy me a coffee to keep me inspired.
PyPI Query MCP Server queries the Python Package Index ā package metadata, version lists, dependency trees, Python compatibility checks, download statistics, and trending packages ā through the Model Context Protocol. Built on the upstream loonghao/pypi-query-mcp-serverā (MIT-licensed) and packaged here under GPL-3.0; this image is independently maintained and is not affiliated with the upstream project. The container uses mcp-proxyā as the stdio<->HTTP/SSE bridge (replacing supergateway in stateful mode by default).
⨠Multi-Architecture Support - Native support for x86-64 and ARM64
š Multiple Transport Protocols - StreamableHTTP and SSE via mcp-proxy
š Secure by Design - Alpine-based with minimal attack surface
ā” High Performance - ZSTD compression for faster deployments
šÆ Production Ready - Stable releases with comprehensive testing
š§ Easy Configuration - Simple environment variable setup
| Architecture | Tag Prefix | Status |
|---|---|---|
| x86-64 | amd64-<version> | ā Stable |
| ARM64 | arm64v8-<version> | ā Stable |
š” Multi-arch images automatically select the correct architecture for your system.
| Tag | Stability | Description | Use Case |
|---|---|---|---|
stable | āāā | Most stable release | Recommended for production |
latest | āāā | Latest stable release | Stay current with stable features |
0.6.5 | āāā | Specific version | Version pinning for consistency |
beta | ā ļø | Beta releases | Testing only |
š CRITICAL: Do NOT expose this container directly to the internet without proper security measures (reverse proxy, SSL/TLS, authentication, firewall rules).
services:
pypi-query-mcp-server:
image: mekayelanik/pypi-query-mcp-server:stable
container_name: pypi-query-mcp-server
restart: unless-stopped
ports:
- "8055:8055"
volumes:
- pypi-query-mcp-cache:/home/node/.cache # Persist cache for future embedding support
environment:
- PORT=8055
- INTERNAL_PORT=38056
- PUID=1000
- PGID=1000
- TZ=Asia/Dhaka
- NODE_ENV=production
- PROTOCOL=HTTP
- ENABLE_HTTPS=false
- HTTP_VERSION_MODE=auto
# Optional: require Bearer token auth at HAProxy layer
# - API_KEY=replace-with-strong-secret
hostname: pypi-query-mcp-server
domainname: local
volumes:
pypi-query-mcp-cache:
driver: local
Deploy:
docker compose up -d
docker compose logs -f pypi-query-mcp-server
docker volume create pypi-query-mcp-cache
docker run -d \
--name=pypi-query-mcp-server \
--restart=unless-stopped \
-p 8055:8055 \
-v pypi-query-mcp-cache:/home/node/.cache \
-e PORT=8055 \
-e INTERNAL_PORT=38056 \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Dhaka \
-e NODE_ENV=production \
-e PROTOCOL=HTTP \
-e ENABLE_HTTPS=false \
-e HTTP_VERSION_MODE=auto \
mekayelanik/pypi-query-mcp-server:stable
| Protocol | Endpoint | Description |
|---|---|---|
| SHTTP | http://host-ip:8055/mcp | Streamable HTTP (default; exposed simultaneously) |
| SSE | http://host-ip:8055/sse | Server-Sent Events (exposed simultaneously) |
| Health | http://host-ip:8055/healthz | Health check (answered by HAProxy, sub-millisecond) |
When HTTPS is enabled (ENABLE_HTTPS=true), use TLS endpoints:
| Protocol | Endpoint |
|---|---|
| SHTTP | https://host-ip:8055/mcp |
| SSE | https://host-ip:8055/sse |
WebSocket transport was dropped in the migration to
mcp-proxy. SettingPROTOCOL=WSwill now fail at startup with a clear message. UseSHTTPorSSEinstead.ā ļø Security Warning: The container now defaults to HTTP (
ENABLE_HTTPS=false) for easier local setup. UseENABLE_HTTPS=truefor production, public networks, or any untrusted environment.ā±ļø ARM Devices: Allow 30-60 seconds for initialization before accessing endpoints.
| Variable | Default | Description |
|---|---|---|
PORT | 8055 | External HAProxy port |
INTERNAL_PORT | 38056 | Internal mcp-proxy port (loopback) |
PUID | 1000 | User ID for file permissions |
PGID | 1000 | Group ID for file permissions |
TZ | Asia/Dhaka | Container timezone (TZ databaseā ) |
NODE_ENV | production | Node.js environment |
PROTOCOL | SHTTP | Default transport protocol |
API_KEY | (empty) | Enables Bearer token auth (Authorization: Bearer <API_KEY>) |
CORS | (empty) | Comma-separated CORS origins, supports * |
ENABLE_HTTPS | false | Enables TLS termination in HAProxy |
TLS_CERT_PATH | /etc/haproxy/certs/server.crt | TLS cert path |
TLS_KEY_PATH | /etc/haproxy/certs/server.key | TLS private key path |
TLS_PEM_PATH | /etc/haproxy/certs/server.pem | Combined PEM file used by HAProxy |
TLS_CN | localhost | CN for auto-generated certificate |
TLS_SAN | DNS:<TLS_CN> | SAN for auto-generated certificate |
TLS_DAYS | 365 | Auto-generated cert validity period |
TLS_MIN_VERSION | TLSv1.3 | Minimum TLS protocol (TLSv1.2 or TLSv1.3) |
HTTP_VERSION_MODE | auto | auto, all, h1, h2, h3, h1+h2 |
RATE_LIMIT | 0 | Max requests per RATE_LIMIT_PERIOD per IP (0 = disabled) |
RATE_LIMIT_PERIOD | 10s | Sliding window for rate limiting (e.g., 10s, 1m, 1h) |
MAX_CONNECTIONS_PER_IP | 0 | Max concurrent connections per IP (0 = disabled) |
IP_ALLOWLIST | (empty) | Comma-separated IPs/CIDRs to allow (all others blocked) |
IP_BLOCKLIST | (empty) | Comma-separated IPs/CIDRs to block |
DEBUG_MODE | (empty) | Enables debug hold mode when set truthy |
ENABLE_HTTPS=true and cert files are missing, the container auto-generates a self-signed certificate.TLS_CERT_PATH and TLS_KEY_PATH exist, they are merged into TLS_PEM_PATH and used directly.HTTP_VERSION_MODE=h3 (or auto) enables HTTP/3 only when HAProxy build includes QUIC; otherwise it safely falls back.API_KEY to enforce authentication at reverse proxy level.Authorization: Bearer <API_KEY>.RATE_LIMIT=100 to allow 100 requests per RATE_LIMIT_PERIOD (default 10s) per IP. Exceeding the limit returns HTTP 429 with a Retry-After header.MAX_CONNECTIONS_PER_IP=50 to cap concurrent connections per IP. Exceeding returns HTTP 429.IP_BLOCKLIST=192.0.2.0/24,198.51.100.5 to block specific IPs/CIDRs. Blocked IPs receive HTTP 403.IP_ALLOWLIST=10.0.0.0/8,192.168.1.0/24 to allow only listed IPs/CIDRs. All others receive HTTP 403. Localhost is always allowed.mcp-proxy runs the PyPI Query backend as a single long-lived stdio child and multiplexes all client sessions through it via JSON-RPC ids. This caps the expected memory footprint; the knobs below cap the worst case:
MCP_PROXY_STATELESS=false (default) ā share one backend child across all sessions. Recommended for almost every deployment. Flip to true only when you genuinely need per-request isolation (and accept the per-request transport-instance cost).PQMS_MAX_MEM_MB=1024 ā caps the virtual-memory size of the pypi-query child via prlimit --as. A runaway backend gets OOM-killed by the kernel before it exhausts the host. The recommended starting value is 1 GiB.HAPROXY_FRONTEND_MAXCONN=64 + HAPROXY_SERVER_MAXCONN=16 ā bound concurrent connections at the HAProxy layer so a burst cannot saturate the upstream stdio bridge./healthz is answered directly by HAProxy with a local 200 ā Docker's container healthcheck no longer depends on upstream MCP readiness.Find your IDs and set them to avoid permission issues:
id username
# uid=1000(user) gid=1000(group)
- TZ=Asia/Dhaka # Bangladesh
- TZ=America/New_York # US Eastern
- TZ=Europe/London # UK
- TZ=UTC # Universal Time
| Client | SHTTP | SSE | Recommended |
|---|---|---|---|
| VS Code (Cline/Roo-Cline) | ā | ā | SHTTP |
| Claude Desktop | ā | ā | SHTTP |
| Claude CLI | ā | ā | SHTTP |
| Codex CLI | ā | ā | SHTTP |
| Codeium (Windsurf) | ā | ā | SHTTP |
| Cursor | ā | ā | SHTTP |
WebSocket transport was dropped in the migration to
mcp-proxy.
Configure in .vscode/settings.json:
{
"mcp.servers": {
"pypi-query-mcp-server": {
"url": "http://host-ip:8055/mcp",
"transport": "http"
}
}
}
Configuration:
claude mcp add-json github '{"type":"http","url":"http://localhost:8055/mcp","headers":{"Authorization":"Bearer <YOUR_API_KEY>"}}'
claude mcp add-json github '{"type":"http","url":"http://localhost:8055/mcp"}'
Configure in ~/.codex/config.json:
{
"mcpServers": {
"pypi-query-mcp-server": {
"transport": "http",
"url": "http://host-ip:8055/mcp"
}
}
}
Configure in .codeium/mcp_settings.json:
{
"mcpServers": {
"pypi-query-mcp-server": {
"transport": "http",
"url": "http://host-ip:8055/mcp"
}
}
}
Configure in ~/.cursor/mcp.json:
{
"mcpServers": {
"pypi-query-mcp-server": {
"transport": "http",
"url": "http://host-ip:8055/mcp"
}
}
}
Verify with MCP Inspectorā :
npm install -g @modelcontextprotocol/inspector
mcp-inspector http://host-ip:8055/mcp
| Network Mode | Complexity | Performance | Use Case |
|---|---|---|---|
| Bridge | ā Easy | āāā Good | Default, isolated |
| Host | āā Moderate | āāāā Excellent | Direct host access |
| MACVLAN | āāā Advanced | āāāā Excellent | Dedicated IP |
services:
pypi-query-mcp-server:
image: mekayelanik/pypi-query-mcp-server:stable
ports:
- "8055:8055"
Benefits: Container isolation, easy setup, works everywhere
Access: http://localhost:8055/mcp
services:
pypi-query-mcp-server:
image: mekayelanik/pypi-query-mcp-server:stable
network_mode: host
Benefits: Maximum performance, no NAT overhead, no port mapping needed
Considerations: Linux only, shares host network namespace
Access: http://localhost:8055/mcp
services:
pypi-query-mcp-server:
image: mekayelanik/pypi-query-mcp-server:stable
mac_address: "AB:BC:CD:DE:EF:01"
networks:
macvlan-net:
ipv4_address: 192.168.1.100
networks:
macvlan-net:
driver: macvlan
driver_opts:
parent: eth0
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
Benefits: Dedicated IP, direct LAN access
Considerations: Linux only, requires additional setup
Access: http://192.168.1.100:8055/mcp
docker compose pull
docker compose up -d
docker image prune -f
docker pull mekayelanik/pypi-query-mcp-server:stable
docker stop pypi-query-mcp-server && docker rm pypi-query-mcp-server
# Run your original docker run command
docker image prune -f
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower \
--run-once \
pypi-query-mcp-server
# Check Docker version
docker --version
# Verify port availability
sudo netstat -tulpn | grep 8055
# Check logs
docker logs pypi-query-mcp-server
# Get your IDs
id $USER
# Update configuration with correct PUID/PGID
# Fix volume permissions if needed
sudo chown -R 1000:1000 /path/to/volume
# Test connectivity
curl http://localhost:8055/mcp
curl http://host-ip:8055/mcp
curl -k https://localhost:8055/mcp
curl -k https://host-ip:8055/mcp
# Check firewall
sudo ufw status
# Verify container
docker inspect pypi-query-mcp-server | grep IPAddress
docker logs -f pypi-query-mcp-serverdocker stats pypi-query-mcp-serverWhen reporting issues, include:
# System info
docker --version && uname -a
# Container logs
docker logs pypi-query-mcp-server --tail 200 > logs.txt
# Container config
docker inspect pypi-query-mcp-server > inspect.json
Your support encourages me to keep creating/supporting my open-source projects. If you found value in this project, you can buy me a coffee to keep me inspired.
Docker Image Issues:
PyPI Query MCP Server Issues:
We welcome contributions:
GPL License. See LICENSEā for details.
PyPI Query MCP Server server has its own license - see Main repoā .
Content type
Image
Digest
sha256:fa56bd047ā¦
Size
62 MB
Last updated
about 1 month ago
docker pull mekayelanik/pypi-query-mcp-server