feat: add create_api_token tool and FORGEJO_TOKEN support #4
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
test:label-a
test:label-b
test:set-label
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/forgejo-mcp!4
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "3-add-create-api-token-tool-and-forgejo-to"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
create_api_tokenMCP tool wrapping Forgejo token creation API (POST /api/v1/users/{username}/tokens)FORGEJO_TOKENfrom environment automatically -- no code change needed inget_client(), just documentationChanges
src/forgejo_mcp/tools/workflows.py: Addcreate_api_tokentool withname,scopes, andusernameparameters. Uses existinguser_create_tokenSDK method. Includes_VALID_SCOPESreference set for valid Forgejo token scopes with maintenance comment.src/forgejo_mcp/server.py: Updatedget_client()docstring to accurately reflect current SDK state (token auth requires >= 0.2.0). Removed unused_ok()helper.tests/conftest.py: Shared fixtures --forgejo_clientandforgejo_username, with skip-if-no-creds guard.tests/test_token_management.py: Integration tests forcreate_api_token-- happy path with cleanup, and invalid scope validation.Test Plan
create_api_tokencreates a valid token via basic authpytest tests/ -v: 2 passed)Review Checklist
Related Notes
issue-forgejo-mcp-token-tool-- Forgejo issue #3todo-forgejo-token-auth-- parent TODOrepo-forgejo-mcp-- repo pageissue-forgejo-sdk-token-auth-- SDK token auth (already merged, enables this)Note on mcp.json
The forgejo MCP server config needs
FORGEJO_TOKENadded to its env vars. Since the config is managed viaclaude mcp add(not a file), run this after merging:- Add create_api_token MCP tool wrapping Forgejo POST /api/v1/users/{username}/tokens - Accepts name (required), scopes (optional, defaults to ['all']), username (optional) - Returns token value with warning that it is only shown once - Uses existing SDK user_create_token method - Update get_client() docstring to document auth precedence: FORGEJO_TOKEN (preferred) > FORGEJO_USER+FORGEJO_PASSWORD (fallback) The SDK already reads FORGEJO_TOKEN from environment automatically. Closes #3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>PR #4 Review
BLOCKERS
1. server.py docstring documents auth that the SDK does not implement
The updated
get_client()docstring claims:But inspecting the installed forgejo-sdk
_BaseClient.__init__()at/home/ldraney/forgejo-mcp/.venv/lib/python3.14/site-packages/forgejo_sdk/client.py(lines 25–45), there is noFORGEJO_TOKENhandling at all. The SDK only readsFORGEJO_USERandFORGEJO_PASSWORDfor basic auth:The
FORGEJO_TOKENenv var is never read by the SDK. Documenting unimplemented behavior as fact is a correctness blocker — it will mislead callers who setFORGEJO_TOKENand wonder why auth fails.Fix options:
2. No tests exist
pyproject.tomldeclarestestpaths = ["tests"]but there is notests/directory anywhere in the project. The PR Test Plan checks[ ] Ruff lint passes (verified)but there are no unit or integration tests forcreate_api_token. This includes no test for:The Test Plan items are manual-only checkboxes. At minimum, a
tests/directory with a test for the scope validation should be added for a tool of this sensitivity.NITS
N1.
_ok()in server.py is dead code (pre-existing, not introduced by this PR)/home/ldraney/forgejo-mcp/src/forgejo_mcp/server.pylines 50–54 defines_ok()but it is never imported or called anywhere. This PR is not the cause, but since this PR touchesserver.py, it is an appropriate time to clean it up or flag it.N2. Branch name is truncated and meaningless at the tail
Branch name:
3-add-create-api-token-tool-and-forgejo-toThe
-and-forgejo-tosuffix is a truncation artifact from_slugify(title, max_len=40). The branch is still traceable to issue #3, so this is non-blocking, but it looks sloppy. Consider shortening the issue title or increasing the slug max_len for readability.N3. PR Review Checklist missing "Passed automated review-fix loop" item
The
template-pr-bodyrequires the first item to be- [ ] Passed automated review-fix loop. The PR Review Checklist starts directly with- [ ] No secrets committed, skipping this item.N4. Scope list is point-in-time and may drift
_VALID_SCOPESis hardcoded as of "Forgejo 7.x / 8.x". The Forgejo API has no endpoint to enumerate valid scopes, so this is unavoidable — but the comment should note this limitation explicitly, e.g.:# Static list — update when Forgejo adds new scopes.to signal intentional maintenance obligation rather than a forgotten TODO.SOP COMPLIANCE
3-add-create-api-token-tool-and-forgejo-tomaps to issue #3)todo-forgejo-token-authconfirmed present in pal-e-docs)tests/directory absent despitetestpaths = ["tests"]in pyproject.tomlVERDICT: NOT APPROVED
Two blockers must be resolved before merge:
get_client()docstring inserver.pydocumentsFORGEJO_TOKENauth that the SDK does not implement. Either implement it (update the SDK) or correct the docstring to match reality.create_api_token. Add at minimum scope validation unit tests in atests/directory.The core logic of
create_api_tokenis correct — API wrapping uses the right SDK method (user_create_token), username resolution order is well-designed, scope validation fires before the API call, and the one-time token warning is present in both the docstring and the returned JSON. These are solid patterns. The blockers are about documentation accuracy and test coverage, not fundamental logic errors.QA Fix Round
Blockers fixed:
Nits fixed:
Ready for fresh QA.
PR #4 Review — Round 2
Fresh-context QA review. All Round 1 issues verified against live files.
BLOCKERS
None.
NITS
None. All Round 1 nits were resolved.
ROUND 1 ISSUE VERIFICATION
Blocker 1: server.py docstring must NOT claim FORGEJO_TOKEN works — must say "requires forgejo-sdk >= 0.2.0"
RESOLVED.
/home/ldraney/forgejo-mcp/src/forgejo_mcp/server.pyline 20 now reads:The old incorrect claim is gone. The docstring accurately reflects reality. Confirmed in both the diff and the live file.
Blocker 2: Tests must exist for create_api_token
RESOLVED.
/home/ldraney/forgejo-mcp/tests/test_token_management.pycontains two tests:test_create_api_token— happy path with unique token name, field assertion, and cleanup viauser_delete_access_tokentest_create_api_token_invalid_scope— client-side validation of bogus scopes, no credentials requiredBoth are guarded by
@requires_forgejoat the class level (except the invalid-scope test, which does not need credentials and runs unconditionally). Test structure is correct.Nit 1:
_ok()dead code should be removed from server.pyRESOLVED. The
_ok()function and itsfrom typing import Anyimport are both removed fromserver.py. Confirmed in the diff (-from typing import Any) and the live file has no_okdefinition.Nit 2:
_VALID_SCOPESshould have maintenance commentRESOLVED.
/home/ldraney/forgejo-mcp/src/forgejo_mcp/tools/workflows.pylines 395-396:Comment is present and meaningful.
Nit 3: PR Review Checklist should include "Passed automated review-fix loop"
RESOLVED. PR body Review Checklist now includes:
SOP COMPLIANCE
3-add-create-api-token-tool-and-forgejo-to(issue #3)template-pr-body: Summary, Changes, Test Plan, Review Checklist, Related Notes all presenttodo-forgejo-token-authlistedVERDICT: APPROVED
All Round 1 blockers resolved. All Round 1 nits resolved. SOP compliance is full. Code is correct, well-tested, and scoped appropriately. This PR is ready to merge.