Reframe the README around two transports and add a local stdio quickstart with uvx/pip and Claude Desktop / Claude Code wiring. New docs: local-quickstart.md and packaging.md (uv build/publish). Document resource-type-aware authorization and classified gitea_request in security.md; stdio env vars + audit-log fallback in configuration.md; local install in deployment.md; core+adapters in architecture.md. Add the missing root AGENTS.md contract, update CLAUDE.md with the core/adapter layout, fail-closed invariants, and the branching flow (HEAD -> feature -> dev -> main). Update roadmap/todo and .env.example. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.5 KiB
Packaging & publishing
AegisGitea-MCP is distributed as a single Python package, aegis-gitea-mcp,
built with uv and published to the self-hosted
Gitea package registry.
Distribution layout
One package, two console scripts, one optional extra:
| Console script | Entry point | Requires |
|---|---|---|
aegis-gitea-mcp |
aegis_gitea_mcp.stdio_app:main |
core only |
aegis-gitea-mcp-server |
aegis_gitea_mcp.server_entry:main |
[server] extra |
- Core (default install):
httpx,pydantic,pydantic-settings,PyYAML,python-dotenv,structlog,mcp. Enough to run the local stdio server. [server]extra:fastapi,uvicorn[standard],PyJWT[crypto],python-multipart. The public HTTP/OAuth server.
The aegis-gitea-mcp-server entry point degrades gracefully: invoked without
the web stack it prints install 'aegis-gitea-mcp[server]' instead of a
ModuleNotFoundError traceback.
Build locally
uv build
# -> dist/aegis_gitea_mcp-<version>-py3-none-any.whl
# -> dist/aegis_gitea_mcp-<version>.tar.gz
Smoke-test the local stdio server from the built wheel:
GITEA_URL=https://git.hiddenden.cafe GITEA_TOKEN=<pat> \
uvx --from ./dist/aegis_gitea_mcp-*.whl aegis-gitea-mcp
Install from the Gitea registry
uv pip install \
--index-url https://git.hiddenden.cafe/api/packages/Hiddenden/pypi/simple \
aegis-gitea-mcp
(With pip, use --index-url the same way.)
Cutting a release
Releases are tag-driven. The publish workflow
(.gitea/workflows/publish.yml) triggers on a v* tag, runs lint + tests
first, builds with uv, and publishes to the Gitea PyPI registry.
-
Bump
versioninpyproject.toml(e.g.0.2.0). -
Open a PR into
dev, mergedevintomain. -
Tag the release commit and push the tag:
git tag v0.2.0 git push origin v0.2.0 -
The workflow publishes the wheel + sdist and attaches them to the run.
Required CI secrets
The publish job uses Gitea Actions secrets — never hardcode credentials:
| Secret | Purpose |
|---|---|
GITEA_PACKAGE_USER |
Gitea username that owns the package |
GITEA_PACKAGE_TOKEN |
least-privilege PAT with write:package |
If either secret is absent the job fails loudly rather than publishing anonymously.
Publishing to public PyPI is intentionally not configured. A second, separately-gated
uv publishstep would be required and is left as a commented stub in the workflow.