Skip to content

feat: add MCP client examples (no-auth, slack-identity, DCR, external-auth)#66

Draft
zimeg wants to merge 26 commits into
mainfrom
feat/mcp-client-examples
Draft

feat: add MCP client examples (no-auth, slack-identity, DCR, external-auth)#66
zimeg wants to merge 26 commits into
mainfrom
feat/mcp-client-examples

Conversation

@zimeg

@zimeg zimeg commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

  • No Auth (Dice Game): Full Bolt + MCP server with roll_dice tool, structured content, and a custom dice roller UI resource. No user-level auth required.
  • Slack Identity (Profile Card): Full Bolt + MCP server using _meta.slack context to look up user profiles via OAuth. Demonstrates installation flow with install button fallback.
  • DCR Auth: Manifest-only example for Dynamic Client Registration auth flow.
  • External Auth: Manifest-only example for external OAuth provider auth flow.

Architecture

All code examples use Starlette to compose Bolt (via SlackRequestHandler) and MCP (via FastMCP.streamable_http_app()) in a single ASGI process. A SlackSignatureMiddleware verifies request signatures before forwarding to the MCP handler.

Also included

  • CI test matrix expanded with both MCP examples (fail-fast: false)
  • Dependabot entries for both MCP example directories
  • Root README updated with AI/MCP examples section
  • Full mypy + ruff + pytest passing for all examples

Test plan

  • pytest -v passes for no-auth (3 tests)
  • pytest -v passes for slack-identity (4 tests)
  • ruff check + ruff format --check passes for both
  • mypy ./**/*.py passes for both
  • Manual testing with slack run against a dev workspace
  • Verify CI passes on this PR

🤖 Generated with Claude Code

zimeg and others added 14 commits June 15, 2026 23:11
Add manifests, READMEs, requirements, and static files for all four
MCP client examples (no-auth, slack-identity, DCR, external-auth).

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Force-add .env.example files that are excluded by the .env* gitignore
pattern to provide template environment configuration.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Fix body-consuming bug in SlackSignatureMiddleware that prevented
the downstream MCP handler from reading the request body. Add
replay_receive to make the body available after signature verification.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Add 4 integration tests for profile card MCP server
- Add mcp:connect to OAuth scopes to match manifest
- Add MCP examples to CI test matrix with fail-fast: false
- Add dependabot entries for both MCP example directories
- Update root README with AI/MCP examples section
- Make mypy conditional in CI (only if installed)

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Add mypy>=2.1.0 to both MCP example requirements
- Use ToolAnnotations object instead of dict literal
- Handle None case for model_extra in slack-identity
- Remove conditional mypy in CI (all examples have it now)

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Use Route instead of Mount to serve /mcp directly (eliminates 307
  redirect that Slack's MCP client does not follow on POST)
- Add _meta.ui.csp with esm.sh domains to dice resource (unblocks
  script loading in sandboxed iframe)
- Document --host-header=rewrite for ngrok (satisfies DNS-rebinding
  protection allowlist)
- Reorder app.py sections to mirror JS examples (MCP first, Bolt second)
- Clean up test files (inline MCP_PATH, move helpers to bottom)

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
- Add docstrings mirroring JS examples, remove section comments
- Inline bolt_handler, rename tests to match JS equivalents
- Replace httpx with httpx2, sort requirements alphabetically
- Use os.environ[] instead of fallback empty string for signing secret

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
@zimeg zimeg self-assigned this Jun 16, 2026
@zimeg zimeg added the enhancement New feature or request label Jun 16, 2026
zimeg and others added 12 commits June 16, 2026 14:44
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant