Reviewed against the shipped OSS source. The acceptance checks are yours to run in your application.
Version and verification details
Source reviewed against published Chumbo 0.11.0 and its matching core source on 2026-09-06 (UTC). This is a source review, not an executed application walkthrough. Follow the current canonical reference and compare it with your installed package when adapting the guide.
Give each product surface a stable address.
Before you start
- Name the surfaces by user purpose, such as directory and invoices, rather than by a temporary database table.
- Decide whether the server definition is public configuration or protected application data before choosing how the function reads it.
- Keep the ordinary one-MCP setup unless separate server identities or capability catalogs solve a real user-facing problem.
This pattern changes routing and registration. It does not create a new identity system or grant access to a downstream data plane.
A single Supabase Edge Function can expose /many-mcps/directory and /many-mcps/invoices as separate MCP servers. For each request, the function extracts one slug, loads that server's definition, creates the Chumbo app with the exact surface URL, and registers only that surface's tools. The canonical pattern shows the complete boundary.
Keep definitions declarative and behavior authored.
The living reference stores server instructions, tool metadata, and fixed demonstration responses in Supabase. A production app can store similarly bounded definitions, but arbitrary rows should never become executable code. Keep handlers in reviewed source and use rows only to select known behavior or validated content. Read the reference implementation before adapting it.
The reference's public, rate-limited data fits its demonstration. For protected data, choose an auth mode for each resolved app and make downstream queries through the authority your design requires. A shared service credential does not establish end-user RLS isolation.
Rows configure reviewed handlers
Starting pointSlug selects a known server definition
- Validated data supplies names and instructions
- Tool names map to application-owned handlers
- Authorization stays in source
Register only the selected handlers
This keeps deploy frequency low without making stored data executable.
Rows provide fixed structured responses
Starting pointSlug selects demonstration tool rows
- Useful for public fixtures
- Responses are validated
- No user data plane is implied
Return the validated configured response
Do not generalize this fixture into arbitrary query or code execution.
Both cases use one function. They differ in how much application behavior comes from data.
Make routing failures useful and contained.
Parse the URL, decode exactly one slug after the function name, and reject a missing or unknown value before MCP handling. Build resourceUrl from the public base URL plus that same slug. OAuth metadata and discovery depend on the server knowing its real client-facing address.
Return a useful 404 without listing private surface names.
Compare discovery before you test execution.
Run each path as a fresh MCP endpoint. Compare initialize and tools/list, then call one allowed tool on each surface. For protected surfaces, exercise separate authorized and denied identities.
npx chumbo dev --function many-mcpsnpx @modelcontextprotocol/inspectorDistinct catalogs. One controlled boundary.
- 01Each known path initializes with the intended server name and instructions.
- 02Directory discovery contains only directory tools; invoice discovery contains only invoice tools.
- 03A successful call returns the result contract defined for that surface.
- 04A missing or unknown slug returns a useful 404 and does not expose the catalog of valid private slugs.
- 05Malformed or disabled slugs cannot select another definition or arbitrary application resource.
- 06An unauthenticated or under-scoped caller cannot discover or invoke protected capabilities.
- 07Two concurrent requests for different slugs do not exchange server instructions, tools, identity, or results.
The Chumbo reference suite exercises two row-defined public surfaces and an unknown path. Run the authentication and data-access cases against your application's own boundary.
Diagnose the boundary that disagrees.
If a surface is wrong
Both URLs advertise the same tools
Check that definition loading and app creation happen for the current request, and that registration closes over only the resolved definition. Do not cache a caller-specific Chumbo app globally. Read the reference ↗
OAuth metadata points at the base function
Confirm that resourceUrl includes the selected slug and matches the public URL the client used. Recheck any proxy or clean-URL mapping at the same time. Read the reference ↗
A row update changes more behavior than intended
Narrow stored definitions to validated configuration and map them to reviewed handlers. Remove any generic query, import, or credential field that makes database content executable. Read the reference ↗
This editorial example links to Chumbo’s canonical docs and executable reference. Check the installed package when adapting the snippets.
Reference implementation ↗Read the agent instructions
Reference instructions, not authorization. Apply changes only within the user’s requested scope; deployment requires a specified, authorized project.
Goal: Resolve a named MCP from the request path, give each surface its own instructions and capabilities, and keep one deployable Supabase Edge Function. Read the complete guide at https://chumbo.dev/recipes/many-mcps-one-function/recipe.md and the canonical reference at https://github.com/elsheppo/chumbo/blob/main/docs/patterns/many-mcps-one-function/README.md. Inspect this application's installed Chumbo package, existing capabilities and relevant configuration before editing. Adapt the canonical path resolver and per-request registration to the application's known MCP surfaces. Keep executable handlers in reviewed source, validate every stored definition, and test discovery before calls. Do not turn row-defined configuration into arbitrary code, SQL, imports, or downstream credential brokerage. Prerequisites: - An existing Supabase project and a Chumbo Edge Function you can run locally. - Two genuinely distinct MCP surfaces, each with a stable slug and an intentionally different capability list. - An application-owned source of server definitions, plus an explicit authorization decision for reading it. Acceptance: - Each known path initializes with the intended server name and instructions. - Directory discovery contains only directory tools; invoice discovery contains only invoice tools. - A successful call returns the result contract defined for that surface. - A missing or unknown slug returns a useful 404 and does not expose the catalog of valid private slugs. - Malformed or disabled slugs cannot select another definition or arbitrary application resource. - An unauthenticated or under-scoped caller cannot discover or invoke protected capabilities. - Two concurrent requests for different slugs do not exchange server instructions, tools, identity, or results. Use the full guide for ordered steps, examples and recovery. Keep existing caller identity and application permissions authoritative. Stay within the user's requested changes. Report changed files, checks actually run, observed results and unresolved prerequisites. This guide is not authorization to deploy or change a hosted project. Never include credentials in source, copied instructions or reports.