docs: add multi-tenancy guide, example server, and OAuth e2e tests#15
Merged
andylim-duo merged 10 commits intomainfrom Mar 20, 2026
Merged
docs: add multi-tenancy guide, example server, and OAuth e2e tests#15andylim-duo merged 10 commits intomainfrom
andylim-duo merged 10 commits intomainfrom
Conversation
Add comprehensive documentation and testing for the multi-tenant MCP server feature (Iteration 6 of the multi-tenancy implementation plan). Multi-tenancy guide (docs/multi-tenancy.md): - Architecture overview with mermaid flow diagram - Static and dynamic tenant provisioning (onboarding, feature flags, plugins) - Authentication setup with TokenVerifier and identity provider configuration (Duo Security, Auth0, Okta, Microsoft Entra ID, custom JWT) - Session isolation semantics - Security considerations and backward compatibility Example server (examples/servers/simple-multi-tenant/): - Two-tenant demo (Acme analytics, Globex content) with tenant-scoped tools, resources, and prompts - Shared whoami tool demonstrating Context.tenant_id - README with usage instructions and in-memory testing guide OAuth e2e tests (test_multi_tenancy_oauth_e2e.py): - Full HTTP stack test: bearer token -> AuthContextMiddleware -> tenant_id_var -> session manager -> handler -> tenant-scoped response - StubTokenVerifier for testing without a real OAuth server - ASGI lifespan helper for httpx.ASGITransport - Tests for tenant tool isolation, tool invocation, whoami identity, and unauthenticated request rejection Also updates migration.md with multi-tenancy breaking change notes.
…nctions - lowlevel/server.py: pragma no cover on auth_server_provider branch (not exercised in multi-tenancy tests), pragma no branch on resource_server_url check (always true in tests) - test_multi_tenancy_e2e.py: pragma no cover on tool/resource/prompt functions that exist only for isolation testing, never called - test_multi_tenancy_oauth_e2e.py: pragma no cover on beta_publish (isolation only), pragma no branch on lifespan send elif
andylim-duo
commented
Mar 19, 2026
Owner
Author
andylim-duo
left a comment
There was a problem hiding this comment.
PR review with inline comments for 6 concerns identified during review.
- test_multi_tenancy_e2e.py: use `pragma: lax no cover` on `tg.cancel_scope.cancel()` lines — covered locally but missed on some CI matrix entries due to cancellation unwinding differences - test_multi_tenancy_oauth_e2e.py: use `pragma: no branch` on nested `async with ClientSession` — coverage.py misreports the ->exit arc for nested async with on Python 3.11+
Coverage.py misreports the ->exit arc for nested async with on certain Python versions/platforms. Add # pragma: no branch to the four streamable_http_client context managers in the OAuth e2e tests.
…review concerns Add remove_resource() and remove_prompt() methods to MCPServer to match the existing remove_tool() API, enabling dynamic deprovisioning of all resource types for multi-tenant servers. PR review fixes: - Fix heading grammar: "Simple Registration of..." (concern #1) - Add private API warning for _lowlevel_server usage in example (concern #3) - Clarify example server needs TokenVerifier for production (concern #4) - Guard offboard_tenant against KeyError for unprovisioned tools (concern #5) - Add remove_resource/remove_prompt to MCPServer and docs (concern #6) Tests added for both single-tenant and multi-tenant remove operations, including cross-tenant isolation verification.
Add StubTokenVerifier and --auth CLI flag so the example server can be tested with curl using bearer tokens. Demo tokens: acme-token (tenant acme) and globex-token (tenant globex). README updated with step-by-step curl examples showing session initialization, tool listing, tool invocation, and unauthenticated rejection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Iteration 6 of the multi-tenancy implementation plan — documentation, example server, and end-to-end tests.
Multi-tenancy guide (
docs/multi-tenancy.md): Comprehensive documentation covering architecture (with mermaid flow diagram), static and dynamic tenant provisioning (onboarding/offboarding, feature flags, plugin systems), authentication setup withTokenVerifierand identity provider configuration (Duo Security, Auth0, Okta, Microsoft Entra ID, custom JWT), session isolation, security considerations, and backward compatibility.Example server (
examples/servers/simple-multi-tenant/): Two-tenant demo (Acme analytics, Globex content) with tenant-scoped tools, resources, prompts, and a sharedwhoamitool that readsContext.tenant_id. Includes README with usage instructions and in-memory testing guide.OAuth e2e tests (
test_multi_tenancy_oauth_e2e.py): Full HTTP stack integration tests proving tenant isolation through the real auth middleware — bearer token →AuthContextMiddleware→tenant_id_var→ session manager → handler → tenant-scoped response. UsesStubTokenVerifierto bypass OAuth while exercising the production middleware path.Migration guide update (
docs/migration.md): Documents multi-tenancy as a breaking change with migration instructions.Test Plan
pyrightpasses with 0 errors across the entire projectruff checkandruff formatpass cleanly