Skip to content

v0.9.2: Merge upstream (MCP, token manager, home redesign)

Choose a tag to compare

@emichaud emichaud released this 16 Jun 03:55

Merges 54 commits from django-smallstack v0.9.2 into the Tabler-themed downstream, with theme integration so the new pages render cleanly inside the Tabler chrome.

What's New from Upstream

Model Context Protocol (MCP) server — apps/mcp/

  • Full JSON-RPC dispatch with OAuth 2.0 (PKCE, Dynamic Client Registration, authorize / token / revoke endpoints, metadata discovery)
  • @tool decorator + auto-discovery (autodiscovers views.py and mcp_tools.py in every app)
  • CRUDView factory — enable_mcp = True on a CRUDView derives list/get/create/update/delete tools automatically
  • Per-action and per-model description maps, mcp_singular/mcp_plural for consistent tool naming
  • mcp_doctor diagnostics command and mcp_smoke end-to-end test command
  • /smallstack/mcp/ admin dashboard with Health, Tools registry browser, Activity (RequestLog filtered by /mcp path), self-test runner
  • 55-test suite covering dispatch, factory, OAuth, PKCE, tenancy, X-Forwarded-Proto, session-login rejection
  • Dashboard widget on /smallstack/

Token Manager — apps/tokenmgr/

  • Self-service UI for the existing APIToken model. Any user can mint a read-only token; staff can mint at any access level for any user
  • List page with search + filter dropdowns (active/user/token type/access level) and inline revoke
  • Mint and "reveal once" pages
  • Dashboard widget with active/revoked counts
  • 37 tests covering the permissions matrix
  • MCP OAuth consent page deep-links to tokenmgr for self-service management of granted tokens

Other

  • Home page redesigned as an editorial product page (templates/website/home.html rewritten; content extracted to apps/smallstack/templates/smallstack/pages/home_content.html)
  • Pagination fix — page_range_display attached on every list-pagination path
  • OpenAPI 3.0.3 spec validated on every test run
  • api-smoke and mcp-smoke end-to-end commands
  • Heartbeat migration 0006 adjusting epoch options
  • apps/smallstack/api.py exposes serialize/search/filter helpers as public API
  • usermanager.views cleaned up: @staff_member_required replaces @login_required + @user_passes_test

Tabler Integration

Two Tabler-specific commits sit on top of the merge to make the new pages render cleanly in the Tabler chrome:

  • CSS variable aliases — Map SmallStack-style var(--primary), var(--card-bg), var(--body-fg), var(--body-quiet-color), var(--body-bg), var(--border), var(--hairline-color), var(--input-border), var(--code-bg), var(--message-warning-bg), var(--delete-button-bg), var(--font-monospace), var(--radius-sm), var(--control-height) to their --tblr-* equivalents in both light and dark modes. Upstream templates render correctly without per-template rewrites.
  • Ported SmallStack layout + form classes that the new MCP and tokenmgr pages depend on:
    • .page-header-bleed, .page-header-with-actions, .page-header-content, .page-subtitle (the tinted bleed header)
    • .crud-form .crud-field/label/help/error/actions, .has-error (form-rendering scaffolding)
    • .list-toolbar, .list-toolbar-search, .list-toolbar-filter, .list-toolbar-overflow-toggle/-panel, .list-toolbar-count, .list-toolbar-clear (search + filter dropdown toolbar)
  • pyproject.toml — skip @pytest.mark.starter_content tests by default (the marker is documented as "safe to skip in downstream projects" — they assert upstream home-page copy that doesn't apply to our Tabler dashboard home)

Verified visually at /smallstack/mcp/health/, /smallstack/mcp/tools/, /smallstack/tokens/, and /smallstack/tokens/create/ in both light and dark themes with the amber accent.

Stats

  • 708 tests passing, 26 starter_content tests deselected (intentional), 73% coverage
  • 2 new Django apps registered (apps.mcp, apps.tokenmgr); apps.preview retained alongside
  • 2 new migrations applied (heartbeat.0006, mcp_server.0001)

Upgrade

git pull origin main
make setup    # uv sync + migrate + create_dev_superuser

🤖 Co-Authored-By: Claude Opus 4.7 (1M context)