Skip to content

[DOC] Document FastMCP limitations with parameterized resources #11

@ivnvxd

Description

@ivnvxd

Document FastMCP Resource Limitations

Before Implementation

⚠️ CRITICAL: Verify this limitation still exists with latest MCP libraries

  1. Check Current MCP Library Versions

    • Review latest FastMCP library version and changelog
    • Check MCP Python SDK recent updates and releases
    • Test behavior with latest versions
    • Verify if parameterized resource discovery has been fixed
  2. Test Current Behavior

    • Test list_resources() with current FastMCP version
    • Verify parameterized resources still don't appear
    • Check if recent updates changed template registration
    • Test with multiple MCP clients to confirm behavior
  3. Review Recent Changes

    • Check FastMCP GitHub releases and issues
    • Look for resource discovery improvements
    • Review MCP protocol specification updates
    • Check if workarounds are still needed

Potential Status Update

Note: FastMCP and MCP libraries have been recently updated. This limitation may have been resolved in newer versions.

Current Problem (Verify if still exists)

# User tries to list resources
resources = list_resources()
# Returns: [] (empty array) - VERIFY THIS BEHAVIOR

# But resources ARE implemented:
read_resource("odoo://res.partner/record/10")  # Test if this still works

Investigation Required

Before documenting, confirm:

  1. Does list_resources() still return empty with latest libraries?
  2. Do parameterized resources still work when called directly?
  3. Have there been protocol changes that affect this?
  4. Are there new recommended patterns for resource discovery?

Root Cause (If still valid)

FastMCP registers parameterized resources (those with {model}, {record_id}, etc.) as templates, not concrete resources. The MCP protocol's list_resources() only shows concrete resources, not templates.

Documentation Requirements (If limitation still exists)

1. Update Library Dependencies First

# Before documenting, update to latest versions
pip install --upgrade fastmcp mcp
# Or check pyproject.toml for latest compatible versions

2. Add to README.md (If still needed)

## Important: Resource Discovery Behavior

Due to FastMCP's template system, parameterized resources (like `odoo://{model}/record/{id}`) 
may not appear in the standard `list_resources()` call.

**Version Note**: This behavior may vary depending on FastMCP version. 
Check latest documentation for current behavior.

**To discover available resources**, use the `list_resource_templates` tool:

```text
# May return empty (check with current version)
resources = list_resources()

# Reliable alternative
templates = list_resource_templates()
# Returns all 5 resource templates with documentation

Recommendation: Use tools instead of resources for maximum compatibility.


### 2. Create FastMCP Limitations Guide

Create `docs/fastmcp-limitations.md`:

```markdown
# FastMCP Limitations and Workarounds

## Parameterized Resources

### The Issue

FastMCP resources that use parameters in their URIs are registered as templates:

```python
@app.resource("odoo://{model}/record/{record_id}")
async def get_record(model: str, record_id: str) -> str:
    # This becomes a template, not a concrete resource

These templates:

  • ✅ Work correctly when called with actual values
  • ❌ Don't appear in list_resources()
  • ❌ May not work with all MCP clients

Why This Happens

  1. FastMCP registers parameterized paths as templates
  2. MCP protocol expects concrete resources in listings
  3. There's no standard way to communicate templates to clients

Workarounds

Option 1: Use Tools (Recommended)

Tools are always discoverable and work with all clients:

# Instead of resource:
read_resource("odoo://res.partner/search?limit=10")

# Use tool:
search_records(model="res.partner", limit=10)

Option 2: Use list_resource_templates Tool

We provide a tool to discover resource templates:

templates = list_resource_templates()
# Returns:
{
    "templates": [
        {
            "uri_template": "odoo://{model}/record/{record_id}",
            "description": "Retrieve a specific record",
            "parameters": {...},
            "example": "odoo://res.partner/record/10"
        },
        ...
    ]
}

Option 3: Register Concrete Resources

For critical models, consider registering concrete resources:

# In addition to template
@app.resource("odoo://res.partner/record/{record_id}")
async def get_partner(record_id: str) -> str:
    return await get_record("res.partner", record_id)

Other FastMCP Limitations

1. Query Parameter Handling

FastMCP may not properly parse query parameters in decorated paths:

# This might not work as expected:
@app.resource("odoo://{model}/search?limit={limit}")

# Better approach:
@app.resource("odoo://{model}/search")
async def search(model: str, **kwargs) -> str:
    limit = kwargs.get('limit', 100)

2. Complex URI Patterns

FastMCP has limited support for complex URI patterns:

# May not work:
@app.resource("odoo://{model}/record/{id}/related/{relation}")

# Workaround: Use simpler patterns and parse manually
@app.resource("odoo://{model}/related")
async def get_related(model: str, **kwargs) -> str:
    # Parse additional parameters from kwargs

Best Practices

  1. Prefer Tools Over Resources

    • Tools are more reliable
    • Better client compatibility
    • Easier to discover and document
  2. Document Resource URIs

    • Provide clear examples
    • Use list_resource_templates tool
    • Include in API documentation
  3. Test with Multiple Clients

    • Not all MCP clients handle templates the same way
    • Verify resources work with your target clients
  4. Consider Concrete Resources

    • For frequently used models
    • When client compatibility is critical
    • As a fallback option

### 3. Update API Documentation

Add section to API docs:

```markdown
## Resource Discovery

### Why list_resources() Returns Empty

The Odoo MCP server implements resources using FastMCP's template syntax:
- `odoo://{model}/record/{record_id}`
- `odoo://{model}/search`
- etc.

These parameterized resources work correctly but don't appear in `list_resources()`.

### How to Discover Resources

1. **Use list_resource_templates tool**:
   ```python
   result = call_tool("list_resource_templates", {})
   print(result["templates"])  # Shows all 5 resource types
  1. Check documentation: All resources are documented in the README

  2. Use tools instead: More reliable and discoverable

    # Get available tools
    tools = list_tools()
    # Returns: search_records, get_record, list_models, etc.

Resource Compatibility Matrix

Resource Type Direct Access Via MCP Client Recommended Alternative
record/{id} ✅ Works ⚠️ May fail get_record tool
search ✅ Works ❌ Fails search_records tool
browse ✅ Works ❌ Fails search_records tool
count ✅ Works ⚠️ May work search_records tool
fields ✅ Works ⚠️ May work get_record with fields

### 4. Add to Troubleshooting Guide

```markdown
## Troubleshooting Resources

### "Unknown resource" Errors

**Symptom**: Resources return "Unknown resource" when accessed through MCP clients.

**Cause**: FastMCP parameterized resources aren't recognized by some MCP clients.

**Solutions**:

1. **Use tools instead**:
   ```python
   # Replace this:
   read_resource("odoo://res.partner/record/10")
   
   # With this:
   get_record(model="res.partner", record_id=10)
  1. Access directly (if your client supports it):

    # Some clients can handle direct URIs
    response = await session.read_resource("odoo://res.partner/record/10")
  2. Check client compatibility:

    • Claude Desktop App: Use tools only
    • Custom clients: May support resources
    • Test your specific client

Empty Resource List

Symptom: list_resources() returns []

This is expected behavior. Use list_resource_templates() instead:

templates = call_tool("list_resource_templates", {})
for template in templates["templates"]:
    print(f"{template['uri_template']}: {template['description']}")

## Success Criteria

**Phase 1: Investigation**
- [ ] Latest FastMCP and MCP library versions tested
- [ ] Current resource discovery behavior confirmed
- [ ] Library changelog reviewed for relevant changes
- [ ] Multiple MCP clients tested for compatibility

**Phase 2: Documentation (If needed)**
- [ ] Users understand current resource discovery behavior
- [ ] Version-specific guidance provided
- [ ] Clear recommendation on tools vs resources
- [ ] Workarounds documented if still needed
- [ ] Migration guide if behavior changed

**Phase 3: Validation**
- [ ] Documentation tested with actual users
- [ ] No confusion about resource availability
- [ ] Proper guidance for different MCP client versions

## Impact

**If limitation still exists**: Prevents user confusion about "missing" resources and provides clear guidance.

**If limitation was fixed**: Updates users about new capabilities and how to leverage improved resource discovery.

## Next Steps

1. **First**: Test with latest MCP library versions
2. **Then**: Document current behavior (may be different than expected)
3. **Finally**: Provide version-appropriate guidance to users

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions