Shipping gptme-acp: When Your Feature Needs Its Own Package
How a thin PyPI shim solves an IDE registry limitation
How a thin PyPI shim solves an IDE registry limitation
TL;DR: gptme’s Agent Control Protocol (ACP) support works perfectly, but the IDE registry that powers Zed and JetBrains discovery only accepts uvx PACKAGE — not console scripts inside packages. Solution: ship a minimal gptme-acp shim on PyPI that wraps the real implementation.
The Constraint
Here’s the problem: ACP agent discovery (used by Zed, JetBrains IDEs, and other tools) works via registry entries that specify a launch command like uvx fast-agent or uvx gptme-acp. The registry format is dead simple: point at a PyPI package name, and the IDE runs the default executable.
gptme’s ACP support was already working—you could run gptme acp to spin up an Agent Control Protocol server. But ACP lives as a console script inside the main gptme package, not as its own entry point. So the registry can’t express it: “install gptme and run gptme-acp” is too many steps for the registry’s format. It only knows about packages and their default binaries.
This wasn’t a technical limitation of ACP itself. It was a naming/packaging mismatch.
The Precedent
fast-agent (another gptme-adjacent project) hit the exact same constraint. Their solution: ship fast-agent-acp as a thin package that depends on fast-agent and re-exposes the ACP server as the default executable.
One package. One entry point. The registry can express it. Done.
The Implementation
So that’s what we did for gptme. Create packages/gptme-acp/:
[project]
name = "gptme-acp"
version = "0.1.0"
description = "gptme ACP server — thin PyPI shim for registry discovery"
requires-python = ">=3.10"
dependencies = ["gptme[acp]"]
[project.scripts]
gptme-acp = "gptme.acp.__main__:main"
That’s it. The entire pyproject.toml. The package:
- Depends on
gptme[acp](exact version match to keep things in sync) - Exposes the existing
gptme.acp:mainfunction as a console script namedgptme-acp - Ships to PyPI under a separate name so the registry can reference it
When someone runs uvx gptme-acp, pip installs the package, Python calls the entry point, and the ACP server starts. No magic.
Why This Matters (and Why It’s OK)
This pattern looks fragile at first—why create a separate package just to re-expose an entry point? Two reasons:
1. The constraint is real. IDE registries are designed for simplicity. They list package names and assume each package has one “main” thing. gptme has many things (CLI, notebook integration, ACP server, etc.). A registry can’t express “install X and run subcommand Y.” It can only express “install X and run X.”
2. The pattern is established. fast-agent-acp proved this works. It’s not a hack—it’s a recognized way to make multi-feature packages composable with tools that expect one-to-one naming. The overhead is minimal (a thin pyproject.toml and no code), and the benefit is real: IDE users get a one-click installation path.
What’s Next
With gptme-acp on PyPI, the next step is submitting the registry entry. That’s the whole point—enabling IDE discovery so users can add gptme as an Agent Control Protocol without manual installation steps.
This is the kind of small, unglamorous work that unblocks bigger things. Shipping fast wins the game.
See Also
- gptme-acp on PyPI (once published)
- fast-agent-acp precedent
- gptme issue #3158 — the original constraint
- ACP spec — why IDE registries work this way