# Showboat Demo — Forgejo wiki via forgejo-mcp End-to-end proof of the whole wiki surface in one sitting: six tools + the `forgejo://…/wiki/…` resource template, including the agent-discovery payoff (a bare URI in a prompt resolves to page content with no tool call). ## Prerequisites - `forgejo-mcp` built from this change and configured against a Forgejo/Codeberg instance. - A token with **repo write** scope; the target repo has **Wiki enabled** in settings. - A throwaway repo, referred to below as `/`. > Replace `/` throughout. Outputs shown are the *expected shape*; task 6.2 > replaces them with real captured output. --- ## 1. Create a page ```jsonc // tool: create_wiki_page { "owner": "", "repo": "", "title": "Home", "content": "# Welcome\n\nThis wiki is driven by forgejo-mcp.\n" } ``` → Page created. Content is sent base64-encoded under the hood; the caller only ever sees plain markdown. ```jsonc { "title": "Home", "page_name": "Home", "commit_sha": "a1b2c3…" } ``` ## 2. List pages (bounded) ```jsonc // tool: list_wiki_pages { "owner": "", "repo": "", "page": 1, "limit": 50 } ``` ```jsonc { "pages": [ { "title": "Home", "page_name": "Home", "sub_url": "Home" } ], "page": 1, "has_next": false } ``` ## 3. Read via the tool (decoded + total_lines) ```jsonc // tool: get_wiki_page { "owner": "", "repo": "", "page_name": "Home" } ``` ```jsonc { "title": "Home", "commit_sha": "a1b2c3…", "total_lines": 4, "content": "# Welcome\n\nThis wiki is driven by forgejo-mcp.\n" } ``` > `total_lines` is 4, not 3: the body ends in `\n`, and the shared `sliceLines` split > (`strings.Split(content, "\n")`) counts the trailing newline as a final empty line. ## 4. Read via the resource URI — the money shot Hand an agent a prompt containing only the bare URI: ``` Summarize forgejo://repo///wiki/Home ``` The result is **one `resources/read` call instead of a `get_wiki_page` tool call**, returning: - `application/json`: `{ owner, repo, page_name, title, commit_sha, recent_revisions: [...] }` - `text/markdown` sidecar: the decoded page body. A client that auto-resolves resource URIs issues that `resources/read` transparently; clients that do not (the common case today — auto-resolution of a bare URI embedded in chat text is not yet universal across Claude Code/Desktop, Codex, Cursor) issue it explicitly. Either way the wiki page becomes first-class, URI-addressable context — the discoverability win — without over-claiming that every client resolves it with zero prompting. ## 5. Edit the page ```jsonc // tool: update_wiki_page { "owner": "", "repo": "", "page_name": "Home", "content": "# Welcome\n\nThis wiki is driven by forgejo-mcp.\n\n## Links\n\n- See `list_wiki_pages`.\n" } ``` → New commit. `title` omitted ⇒ page keeps its name. ## 6. Revision history (bounded) ```jsonc // tool: get_wiki_revisions { "owner": "", "repo": "", "page_name": "Home", "page": 1, "limit": 30 } ``` ```jsonc { "revisions": [ { "sha": "d4e5f6…", "author": "you", "message": "Update wiki page 'Home'" }, { "sha": "a1b2c3…", "author": "you", "message": "Create wiki page 'Home'" } ], "page": 1, "has_next": false } ``` ## 7. Bounded read of a long page (resumability) ```jsonc // tool: get_wiki_page { "owner": "", "repo": "", "page_name": "Home", "start_line": 1, "end_line": 5 } ``` ```jsonc { "title": "Home", "total_lines": 8, "start_line": 1, "end_line": 5, "content": "# Welcome\n\nThis wiki is driven by forgejo-mcp.\n\n## Links" } ``` `total_lines: 8` > `end_line: 5` ⇒ the caller knows to request lines 6–8 next. (The edited body ends in `\n`, so the split counts a trailing empty 8th line; the same `sliceLines` routine and count as `get_file_content`.) ## 8. Cleanup ```jsonc // tool: delete_wiki_page { "owner": "", "repo": "", "page_name": "Home" } ``` → a `2xx` (canonically `204 No Content`) reported as success. `list_wiki_pages` now returns an empty list. --- ## What this proves - All six tools work against a stock instance with **no `forgejo-sdk` wiki dependency**. - Content round-trips correctly through base64 (caller never sees encoding). - Every data-proportional response is **bounded and resumable** (`page`/`limit`/`has_next`, `start_line`/`end_line`/`total_lines`). - A wiki page is **discoverable by URI** for agents and humans alike.