feat: add mcp_server() helper with built-in server info and credential resolution#9
Merged
Aaron ("AJ") Steers (aaronsteers) merged 19 commits intomainfrom Jan 19, 2026
Conversation
…l resolution - Add mcp_server() factory function that creates FastMCP instances with: - Automatic server info resource registration (version, git SHA, fastmcp version) - HTTP header credential resolution with env var fallback - Support for advertised properties (package_name, docs_url, etc.) - Optional auto_discover_assets parameter - Add MCPServerConfigArg dataclass for credential configuration - Add MCPServerConfig dataclass to store server configuration - Add resolve_config() function for credential resolution - Add comprehensive tests for all new functionality - Update README with documentation for new features Closes #6 Co-Authored-By: AJ Steers <aj@airbyte.io>
Contributor
Original prompt from AJ Steers |
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
🎉 Thanks for opening this pull request! Your contribution is appreciated. Here are some helpful commands you can use: Quick Commands
Available Poe TasksYou can run any of these tasks using the slash command: Core Tasks
Quick Fixes
Build & Install
Other Commands
The CI will automatically run tests when you push commits. Happy coding! 🚀 |
Co-Authored-By: AJ Steers <aj@airbyte.io>
… default support Based on PR feedback: - Rename 'header' field to 'http_header_key' for clarity - Make http_header_key and env_var optional (nullable) - Add 'default' field that can be a string or callable - Update resolution logic to handle nullable fields and defaults - Add tests for new default value functionality - Update README documentation Co-Authored-By: AJ Steers <aj@airbyte.io>
- Rename _discover_domains_from_modules() to _discover_mcp_module_names() - Update docstrings to use 'MCP modules' instead of 'domains' - Update advertised_properties key from 'domains' to 'mcp_modules' Co-Authored-By: AJ Steers <aj@airbyte.io>
…module discovery Based on PR feedback: - Move package_name from advertised_properties to a top-level parameter - Implement _discover_mcp_module_names() to auto-discover sibling modules - Update README feature description and examples - Update API reference documentation Co-Authored-By: AJ Steers <aj@airbyte.io>
Per PR feedback, use 'x_' prefix to distinguish grafted-in property from the class's own private properties. This avoids name collisions if FastMCP adds similar functionality in the future. Co-Authored-By: AJ Steers <aj@airbyte.io>
This allows transforming resolved values before returning them. Useful for parsing values like 'Bearer <token>' from Authorization headers. The normalize_fn receives the raw value and returns the normalized value, or None if the value should be treated as not found (triggering fallback to the next resolution source). Co-Authored-By: AJ Steers <aj@airbyte.io>
…ions Co-Authored-By: AJ Steers <aj@airbyte.io>
- resolve_config now accepts either a Context object (preferred for MCP tools) or a FastMCP app instance directly - When using Context, the function accesses the app via ctx.fastmcp - This enables session-aware resolution of HTTP headers - Added example usage in docstring Co-Authored-By: AJ Steers <aj@airbyte.io>
Per PR feedback, added comprehensive module docstring with: - Key components section with backtick cross-links - Basic usage example - Credential resolution example with MCPServerConfigArg - MCP module auto-discovery example - See Also section linking to main components Co-Authored-By: AJ Steers <aj@airbyte.io>
…ger.devin.ai/proxy/github.com/airbytehq/fastmcp-extensions into devin/1768688145-mcp-server-helper
Per PR feedback, changed from indented blocks (::) to dedented code blocks (```py) for better readability in documentation. Co-Authored-By: AJ Steers <aj@airbyte.io>
Per PR feedback: - Changed from RST-style underlines to markdown ## headers - See Also section already uses bulleted markdown list Co-Authored-By: AJ Steers <aj@airbyte.io>
Per PR feedback, the See Also section is redundant since the components are already linked in the Key Components section above. Co-Authored-By: AJ Steers <aj@airbyte.io>
Per user feedback, 'get' is more accurate since the value may already be resolved/cached, and 'mcp' in the name makes it clearer what we're doing. Changes: - Renamed public function resolve_config -> get_mcp_config - Renamed internal method MCPServerConfig.resolve_config -> get_config - Updated all test function names and calls - Updated module docstring examples - Updated README examples and API reference - Updated __init__.py exports Co-Authored-By: AJ Steers <aj@airbyte.io>
3 tasks
Per user feedback, these functions are internal implementation details now that mcp_server() handles registration automatically. Changes: - Deleted get_registered_tools, get_registered_prompts, get_registered_resources - Renamed clear_registrations to _clear_registrations - Removed exports from __init__.py - Updated tests to use private _REGISTERED_* lists directly Co-Authored-By: AJ Steers <aj@airbyte.io>
4 tasks
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
Adds a new
mcp_server()factory function that creates FastMCP instances with common patterns built-in:{name}://server/inforesource with package version, git SHA, FastMCP version, and custom advertised propertiesMCPServerConfigArgallows defining credentials that resolve from HTTP headers first, then fall back to environment variables, then to default valuesauto_discover_assetsparameter discovers sibling non-private modules in the caller's packageExample usage:
Updates since last revision
Based on PR feedback:
resolve_configtoget_mcp_config("get" is more accurate since values may be cached, and "mcp" prefix makes the purpose clearer)get_registered_tools,get_registered_prompts,get_registered_resourcesprivate (internal implementation details now thatmcp_server()handles registration)clear_registrationsprivate (_clear_registrations) - only used for testingnormalize_fnparameter toMCPServerConfigArgfor transforming resolved valuesget_mcp_configto accept eitherContextorFastMCPfor session-aware resolution_mcp_server_configtox_mcp_server_configto distinguish from FastMCP's private propertiespackage_nameto a top-level parameter_discover_mcp_module_names()usinginspectandpkgutilhttp_header_keyandenv_varoptional/nullabledefaultfield (string or callable)Review & Testing Checklist for Human
_discover_mcp_module_names()with a real package - The implementation uses stack inspection (inspect.currentframe()) which can be fragile. Verify it works correctly when called from a real MCP server package.normalize_fnbehavior - Verify that returningNonefrom normalize_fn triggers fallback to next source, and that exceptions propagate correctly without leaking sensitive values.get_mcp_configwith Context - Verify session-aware resolution works when passing aContextobject from an MCP tool function.sensitiveattribute behavior -MCPServerConfigArg.sensitiveis defined but not used for masking. Confirm this is intentional for future use.Suggested test plan:
mcp_server(auto_discover_assets=True)_discover_mcp_module_names()returns the expected module list{name}://server/inforesourceNotes
Closes #6
Link to Devin run: https://app.devin.ai/sessions/2df3046f40894f978f822b81ecd774ab
Requested by: Aaron ("AJ") Steers (@aaronsteers)