feat(mcp): migrate server to FastMCP with native tool-search#28
Merged
Conversation
Ooscaar
force-pushed
the
feat/mcp-tool-search
branch
3 times, most recently
from
July 10, 2026 15:04
392b575 to
b2a483c
Compare
Migrate the MCP server from the bundled mcp.server.fastmcp to the standalone FastMCP package and collapse the generated tool catalog behind FastMCP's BM25 tool-search transform, so clients see a small always-visible core plus search_tools/call_tool instead of the full catalog. - server.py: FastMCP + BM25SearchTransform(always_visible=core tools); _get_client() reads the request AccessToken (get_access_token) with ContextVar/env fallback for STDIO. - Pin a 49-tool always-visible core (51 with search_tools/call_tool, out of 481 registered): the 20 hand-written ergonomic tools plus the generated tools central to profile work — posting, scheduling queue, pre-publish validation, account health, cross-platform analytics basics, and post engagement. The messaging/ads/connect suites (~430 tools) stay behind search. - auth.py: ZernioTokenVerifier(TokenVerifier) + RemoteAuthProvider — bearer validated against the Zernio API (accepts API keys and OAuth tokens), with RFC 9728 protected-resource metadata and the 401 challenge served automatically. - http_server.py: mcp.http_app(stateless_http=True) + Origin-guard ASGI middleware. Streamable HTTP is the primary transport; the legacy SSE transport (GET /sse + POST /messages/) is deprecated but kept for backwards compatibility — its routes are grafted from the same FastMCP instance (http_app(transport="sse")), so tools and auth are identical. - Remove routes.py (superseded by FastMCP-native auth/routes). - Keep the pre-FastMCP discovery path working: /.well-known/oauth-protected- resource now 308-redirects to the canonical path-inserted document FastMCP serves at /.well-known/oauth-protected-resource/mcp. - Update docs (MCP.md, HTTP_DEPLOYMENT.md) to the new transport, auth model, and tool-search behaviour; document MCP_PUBLIC_URL and MCP_ALLOWED_ORIGINS. - Remove code superseded by FastMCP (extract_late_api_key, WWW_AUTHENTICATE_BEARER) and fix stale comments/docstrings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ooscaar
force-pushed
the
feat/mcp-tool-search
branch
from
July 10, 2026 16:00
b2a483c to
e1cdc1e
Compare
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.
Why
Connecting the MCP server to an AI client surfaces the full generated tool catalog (480+ tools) at once. Large tool lists inflate context and some MCP clients cap or truncate them, so not every tool reliably shows up. This keeps a curated, always-visible core of the tools central to profile work and makes the rest of the catalog reachable on demand through search.
What
mcp.server.fastmcpto the standalone FastMCP framework.search_tools/call_tool, out of 481 registered): the 20 hand-written ergonomic tools plus the generated tools central to profile work — posting, scheduling queue, pre-publish validation, account health, cross-platform analytics basics, and post engagement. The messaging/ads/connect suites (~430 tools) sit behindsearch_tools/call_tool. Every underlying tool stays directly callable, so nothing is lost.401WWW-Authenticatechallenge are served automatically. The pre-FastMCP discovery path (/.well-known/oauth-protected-resource) 308-redirects to the canonical path-inserted document, so clients holding the old URL keep working. Verified against the zernio.com authorization-server code that the changedresourceidentifier (…/mcp) is a no-op for token issuance and validation.GET /sse+POST /messages/) is deprecated but kept for backwards compatibility — production still receives SSE connections; its routes are grafted from the same FastMCP instance so tools and auth are identical.docs/MCP.mdanddocs/HTTP_DEPLOYMENT.mdto the new transport, auth model, and tool-search behaviour; documentMCP_PUBLIC_URLandMCP_ALLOWED_ORIGINS.Verification
mcp-server-dev-5f19.up.railway.app): health, 401/403 gates on/mcpand/sse, all three discovery docs, legacy 308 redirect; real client session exercised pinned tools,search_tools, andcall_toolend-to-end.developwith a minimaluv.lockdelta (fastmcp + transitive deps only).Follow-ups
Platformenum gap (sms/phoneaccounts crashaccounts_list/_resolve_account— surfaced during live testing, present in production today).🤖 Generated with Claude Code