Skip to content

Commit 27fc753

Browse files
feat: add mcp_server() helper with built-in server info and credential resolution (#9)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent ec40125 commit 27fc753

File tree

7 files changed

+879
-88
lines changed

7 files changed

+879
-88
lines changed

README.md

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ Unofficial extension library for FastMCP 2.0 with patterns, practices, and utili
44

55
## Features
66

7+
- MCP Server Factory: `mcp_server()` helper that creates FastMCP instances with built-in server info resources, MCP asset discovery (optional), and credential resolution.
78
- MCP Annotation Constants: Standard annotation hints (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) following the FastMCP 2.2.7+ specification
8-
- Deferred Registration Decorators: `@mcp_tool`, `@mcp_prompt`, `@mcp_resource` decorators for organizing tools by domain with automatic domain detection
9-
- Registration Utilities: Functions to register tools, prompts, and resources with a FastMCP app, filtered by domain
10-
- Tool Testing Utilities: Helpers for testing MCP tools directly with JSON arguments (stdio and HTTP transports)
11-
- Tool List Measurement: Utilities for measuring tool list size to track context truncation issues
12-
- Prompt Helpers: Generic `get_prompt_text` helper for agents that cannot access prompt assets directly
9+
- Deferred Registration Decorators: `@mcp_tool`, `@mcp_prompt`, `@mcp_resource` decorators for organizing tools by domain with automatic domain detection.
10+
- Registration Utilities: Functions to register tools, prompts, and resources with a FastMCP app, filtered by domain.
11+
- Tool Testing Utilities: Helpers for testing MCP tools directly with JSON arguments (stdio and HTTP transports).
12+
- Tool List Measurement: Utilities for measuring tool list size to track context truncation issues.
13+
- Prompt Helpers: Generic `get_prompt_text` helper for agents that cannot access prompt assets directly.
1314

1415
## Installation
1516

@@ -25,6 +26,37 @@ uv add fastmcp-extensions
2526

2627
## Quick Start
2728

29+
### Using the MCP Server Factory
30+
31+
The `mcp_server` function creates a FastMCP instance with built-in server info resources and optional credential resolution:
32+
33+
```python
34+
from fastmcp_extensions import mcp_server, MCPServerConfigArg
35+
36+
app = mcp_server(
37+
name="my-mcp-server",
38+
package_name="my-package",
39+
advertised_properties={
40+
"docs_url": "https://github.com/org/repo",
41+
"release_history_url": "https://github.com/org/repo/releases",
42+
},
43+
server_config_args=[
44+
MCPServerConfigArg(
45+
name="api_key",
46+
http_header_key="X-API-Key",
47+
env_var="MY_API_KEY",
48+
required=True,
49+
sensitive=True,
50+
),
51+
],
52+
)
53+
54+
# Server info resource is automatically registered at {name}://server/info
55+
# Get credentials from HTTP headers or environment variables
56+
from fastmcp_extensions import get_mcp_config
57+
api_key = get_mcp_config(app, "api_key")
58+
```
59+
2860
### Using Annotation Constants
2961

3062
```python
@@ -132,10 +164,16 @@ cmd = "python bin/measure_mcp_tool_list.py"
132164

133165
## API Reference
134166

167+
### Server Factory
168+
169+
- `mcp_server` - Create a FastMCP instance with built-in server info resource and auto-registration of decorated tools and assets.
170+
- `MCPServerConfigArg` - Configuration for credential resolution and other server settings.
171+
- `get_mcp_config` - Get a credential from HTTP headers or environment variables.
172+
135173
### Annotations
136174

137175
| Constant | Description | FastMCP Default |
138-
|----------|-------------|-----------------|
176+
| -------- | ----------- | --------------- |
139177
| `READ_ONLY_HINT` | Tool only reads data | `False` |
140178
| `DESTRUCTIVE_HINT` | Tool modifies/deletes data | `True` |
141179
| `IDEMPOTENT_HINT` | Repeated calls have same effect | `False` |

src/fastmcp_extensions/__init__.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818
READ_ONLY_HINT,
1919
)
2020
from fastmcp_extensions.decorators import (
21-
clear_registrations,
22-
get_registered_prompts,
23-
get_registered_resources,
24-
get_registered_tools,
2521
mcp_prompt,
2622
mcp_resource,
2723
mcp_tool,
@@ -33,20 +29,26 @@
3329
register_mcp_resources,
3430
register_mcp_tools,
3531
)
32+
from fastmcp_extensions.server import (
33+
MCPServerConfig,
34+
MCPServerConfigArg,
35+
get_mcp_config,
36+
mcp_server,
37+
)
3638

3739
__all__ = [
3840
"DESTRUCTIVE_HINT",
3941
"IDEMPOTENT_HINT",
4042
"OPEN_WORLD_HINT",
4143
"READ_ONLY_HINT",
44+
"MCPServerConfig",
45+
"MCPServerConfigArg",
4246
"PromptDef",
4347
"ResourceDef",
44-
"clear_registrations",
45-
"get_registered_prompts",
46-
"get_registered_resources",
47-
"get_registered_tools",
48+
"get_mcp_config",
4849
"mcp_prompt",
4950
"mcp_resource",
51+
"mcp_server",
5052
"mcp_tool",
5153
"register_mcp_prompts",
5254
"register_mcp_resources",

src/fastmcp_extensions/decorators.py

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -186,34 +186,7 @@ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
186186
return decorator
187187

188188

189-
def get_registered_tools() -> list[tuple[Callable[..., Any], dict[str, Any]]]:
190-
"""Get all registered tools.
191-
192-
Returns:
193-
List of (function, annotations) tuples for all registered tools.
194-
"""
195-
return _REGISTERED_TOOLS.copy()
196-
197-
198-
def get_registered_prompts() -> list[tuple[Callable[..., Any], dict[str, Any]]]:
199-
"""Get all registered prompts.
200-
201-
Returns:
202-
List of (function, annotations) tuples for all registered prompts.
203-
"""
204-
return _REGISTERED_PROMPTS.copy()
205-
206-
207-
def get_registered_resources() -> list[tuple[Callable[..., Any], dict[str, Any]]]:
208-
"""Get all registered resources.
209-
210-
Returns:
211-
List of (function, annotations) tuples for all registered resources.
212-
"""
213-
return _REGISTERED_RESOURCES.copy()
214-
215-
216-
def clear_registrations() -> None:
189+
def _clear_registrations() -> None:
217190
"""Clear all registered tools, prompts, and resources.
218191
219192
This is primarily useful for testing.

src/fastmcp_extensions/registration.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -191,30 +191,3 @@ def _register_fn(
191191
resource_list=_REGISTERED_RESOURCES,
192192
register_fn=_register_fn,
193193
)
194-
195-
196-
def get_registered_tools() -> list[tuple[Callable[..., Any], dict[str, Any]]]:
197-
"""Get all registered tools.
198-
199-
Returns:
200-
List of (function, annotations) tuples for all registered tools.
201-
"""
202-
return _REGISTERED_TOOLS.copy()
203-
204-
205-
def get_registered_prompts() -> list[tuple[Callable[..., Any], dict[str, Any]]]:
206-
"""Get all registered prompts.
207-
208-
Returns:
209-
List of (function, annotations) tuples for all registered prompts.
210-
"""
211-
return _REGISTERED_PROMPTS.copy()
212-
213-
214-
def get_registered_resources() -> list[tuple[Callable[..., Any], dict[str, Any]]]:
215-
"""Get all registered resources.
216-
217-
Returns:
218-
List of (function, annotations) tuples for all registered resources.
219-
"""
220-
return _REGISTERED_RESOURCES.copy()

0 commit comments

Comments
 (0)