Troubleshooting¶
This guide covers common issues you may encounter when setting up or running drf-mcp-docs, organized by symptom.
First Steps: Run the Diagnostic Command¶
Before diving into specific issues, run the built-in configuration checker:
This command validates your settings, checks adapter availability, and attempts schema generation. It catches the majority of configuration problems and provides actionable error messages.
Example output:
drf-mcp-docs configuration check
===================================
--- Settings ---
OK: TRANSPORT = 'streamable-http'
OK: DEFAULT_CODE_LANGUAGE = 'javascript'
OK: DEFAULT_HTTP_CLIENT = 'fetch'
OK: CACHE_TTL = None (no expiry)
OK: SCHEMA_PATH_PREFIX = '/api/'
OK: MCP_ENDPOINT = '/mcp/'
OK: EXCLUDE_PATHS = []
--- Adapters ---
SpectacularAdapter: available
YasgAdapter: not available
DRFBuiltinAdapter: available
OK: Active adapter: SpectacularAdapter (auto-detected)
--- Schema Generation ---
OK: Schema generated successfully
OK: 12 endpoint(s) after path filtering
OK: 5 schema definition(s) found
===================================
All checks passed. 0 warning(s).
Tip
Include checkmcpconfig output when filing bug reports — it provides the context needed to diagnose most issues.
Installation & Adapter Detection¶
"No schema adapter available"¶
Symptom: RuntimeError at startup:
RuntimeError: No schema adapter available. Install drf-spectacular, drf-yasg,
or ensure DRF's built-in schema generation is configured.
Cause: None of the three supported schema generators could be detected.
Solution: Install a schema generator. drf-spectacular is recommended:
Or with drf-yasg:
If you want to use DRF's built-in generator (limited output), make sure djangorestframework is installed and that inflection and uritemplate are available (they are required by DRF's schema generator).
drf-spectacular installed but not detected¶
Symptom: checkmcpconfig shows SpectacularAdapter: not available even though drf-spectacular is installed. The server falls back to DRFBuiltinAdapter.
Cause: drf-spectacular requires DEFAULT_SCHEMA_CLASS to be set in your REST_FRAMEWORK settings. The adapter checks both that the package is installed and that the schema class is configured.
Solution: Add to your settings.py:
Also ensure 'drf_spectacular' is in your INSTALLED_APPS.
"Could not import module '...' for adapter"¶
Symptom: ImportError when using a custom SCHEMA_ADAPTER setting:
ImportError: Could not import module 'myapp.adapters' for adapter.
Check your DRF_MCP_DOCS['SCHEMA_ADAPTER'] setting: 'myapp.adapters.MyAdapter'
Cause: The module path in SCHEMA_ADAPTER is incorrect, or the module is not on sys.path.
Solution: Verify the dotted path. The format is 'module.path.ClassName':
Check that the module is importable: python -c "from myapp.adapters import MyCustomAdapter".
"Module '...' has no class '...'"¶
Symptom: ImportError about a missing class name.
Cause: The module exists but the class name portion of SCHEMA_ADAPTER is misspelled.
Solution: Check the class name spelling. The part after the last . is the class name:
# Wrong — class name typo
'SCHEMA_ADAPTER': 'myapp.adapters.MyCustomAdaptor'
# Correct
'SCHEMA_ADAPTER': 'myapp.adapters.MyCustomAdapter'
Schema Generation Issues¶
Empty schema (0 endpoints)¶
Symptom: AI agent says "no endpoints found", or checkmcpconfig shows 0 endpoint(s) after path filtering.
Possible causes and solutions:
1. No DRF views registered
Your ROOT_URLCONF doesn't include any DRF router URLs. Verify your URL configuration:
# urls.py
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from myapp.views import MyViewSet
router = DefaultRouter()
router.register(r'items', MyViewSet)
urlpatterns = [
path('api/', include(router.urls)),
]
2. SCHEMA_PATH_PREFIX doesn't match your URLs
The default prefix is /api/. If your URLs use a different prefix (e.g., /v1/ or no prefix), endpoints will be filtered out.
# If your URLs are under /v1/
DRF_MCP_DOCS = {
'SCHEMA_PATH_PREFIX': '/v1/',
}
# To include all endpoints regardless of prefix
DRF_MCP_DOCS = {
'SCHEMA_PATH_PREFIX': '',
}
3. EXCLUDE_PATHS is too broad
Check that your exclusion patterns aren't removing all endpoints:
# This would exclude everything under /api/
DRF_MCP_DOCS = {
'EXCLUDE_PATHS': ['/api/'], # Too broad!
}
Tip
Run python manage.py checkmcpconfig — it reports both the raw endpoint count and the count after filtering, making it easy to spot when filtering is the problem.
"Path filtering reduced N endpoints to 0"¶
Symptom: checkmcpconfig warning showing that path filtering removed all endpoints.
Cause: Your SCHEMA_PATH_PREFIX or EXCLUDE_PATHS settings don't match your actual URL structure.
Solution: Check what paths your API actually uses. The checkmcpconfig output shows the raw count before filtering. Adjust SCHEMA_PATH_PREFIX to match, or set it to '' to disable prefix filtering.
Empty or generic examples for endpoints¶
Symptom: get_request_example returns placeholder values like "string" or 0 instead of realistic examples.
Cause: The schema generator doesn't provide enough field detail. This is common with DRF's built-in adapter, which has limited serializer introspection. It can also happen with circular $ref references (the resolver has a depth limit of 10).
Solution: Switch to drf-spectacular for richer schemas. With drf-spectacular, you can also add explicit examples using @extend_schema:
from drf_spectacular.utils import extend_schema, OpenApiExample
class MyViewSet(viewsets.ModelViewSet):
@extend_schema(
examples=[
OpenApiExample('Create item', value={'name': 'Widget', 'price': 9.99})
]
)
def create(self, request, *args, **kwargs):
...
ASGI Integration Issues¶
"RuntimeError: Task group is not initialized"¶
Symptom: Every request to the MCP endpoint returns a 500 error with:
Cause: ASGI lifespan events are not being forwarded to the mount_mcp wrapper. The MCP server uses the ASGI lifespan protocol to initialize its internal task group — without it, all MCP requests fail.
Solution: Make sure your ASGI application forwards lifespan scope to mount_mcp. If you have a custom ASGI wrapper, it must include the lifespan case:
# asgi.py
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django_app = get_asgi_application()
from drf_mcp_docs.urls import mount_mcp
django_app = mount_mcp(django_app)
async def application(scope, receive, send):
if scope["type"] == "http":
await django_app(scope, receive, send)
elif scope["type"] == "websocket":
await websocket_app(scope, receive, send)
elif scope["type"] == "lifespan":
# Required: forward lifespan events to mount_mcp
await django_app(scope, receive, send)
Warning
A common mistake is routing only http and websocket scopes while dropping lifespan. If you use mount_mcp(), lifespan forwarding is mandatory.
MCP endpoint returns 404 or Django handles it¶
Symptom: Requests to /mcp/ are handled by Django instead of the MCP server, returning a 404 or an unexpected response.
Cause: A Django URL pattern matches the MCP endpoint path before mount_mcp can intercept it, or the MCP_ENDPOINT path doesn't match what the client is requesting.
Solution:
mount_mcp()checks the path before passing to Django, so this usually means the path configuration is wrong. Verify yourMCP_ENDPOINTsetting matches what you're requesting.- If using a custom mount path, ensure it's consistent:
# settings.py
DRF_MCP_DOCS = {
'MCP_ENDPOINT': '/docs-mcp/',
}
# asgi.py — path parameter overrides the setting
application = mount_mcp(django_app, path="/docs-mcp/")
WSGI project trying to use mount_mcp¶
Symptom: mount_mcp doesn't work or produces errors when running under WSGI (e.g., gunicorn myproject.wsgi).
Cause: mount_mcp creates an ASGI application. It cannot be used with WSGI servers.
Solution: Use one of these alternatives:
# Option A: stdio transport (recommended for WSGI projects)
python manage.py runmcpserver --transport stdio
# Option B: standalone HTTP server on a separate port
python manage.py runmcpserver --transport streamable-http --port 8100
# Option C: migrate to ASGI
pip install uvicorn
uvicorn myproject.asgi:application --host 0.0.0.0 --port 8000
See ASGI Integration for details on each option.
Connection & Transport Issues¶
stdio: AI tool fails to start the MCP server¶
Symptom: Your AI tool (Claude Code, Cursor, VS Code) reports "command not found", "No module named django", or similar errors when trying to start the MCP server.
Cause: The AI tool is using the wrong Python interpreter or working directory.
Solution: Use absolute paths in your MCP configuration:
{
"mcpServers": {
"my-api": {
"command": "/path/to/venv/bin/python",
"args": ["manage.py", "runmcpserver", "--transport", "stdio"],
"cwd": "/absolute/path/to/your/django/project"
}
}
}
Warning
The most common mistake is not pointing to the virtual environment's Python. If you use a venv, always use its full path (e.g., /home/user/myproject/.venv/bin/python).
Verify manually first:
streamable-http: "Address already in use"¶
Symptom: OSError: [Errno 98] Address already in use when starting runmcpserver.
Cause: Another process is already listening on that port.
Solution:
# Use a different port
python manage.py runmcpserver --transport streamable-http --port 8200
# Or find and stop the process using the port
lsof -i :8100
kill <PID>
streamable-http: Connection refused¶
Symptom: MCP client reports "connection refused" or times out.
Cause: The server isn't running, the URL is wrong, or a firewall is blocking the connection.
Solution:
- Verify the server is running:
python manage.py runmcpserver --transport streamable-http --port 8100 - Check the URL in your MCP client config matches (default:
http://localhost:8100/mcp/) - For remote connections, ensure the firewall allows traffic on the port and the server binds to
0.0.0.0(not justlocalhost)
AI tool connects but gets empty data¶
Symptom: The MCP server responds, but resources and tools return no endpoints or schemas.
Cause: Schema generation succeeded but produced 0 endpoints. This is a schema generation issue, not a connection issue.
Solution: See Empty schema (0 endpoints) above. Run python manage.py checkmcpconfig to diagnose.
Configuration Issues¶
Unknown setting warning¶
Symptom: checkmcpconfig warns about an unknown setting, possibly with a suggestion:
Cause: Typo in your DRF_MCP_DOCS dictionary key.
Solution: Fix the key name. See Configuration for the full list of valid settings.
Invalid setting values¶
Symptom: checkmcpconfig reports errors about setting values.
Common mistakes and fixes:
| Setting | Invalid | Valid |
|---|---|---|
TRANSPORT | 'http' | 'stdio' or 'streamable-http' |
DEFAULT_CODE_LANGUAGE | 'ts' | 'javascript', 'typescript', or 'python' |
DEFAULT_HTTP_CLIENT | 'curl' | 'fetch', 'axios', 'ky', 'requests', or 'httpx' |
CACHE_TTL | -1 or '300' | None or a positive number (e.g., 300) |
SCHEMA_PATH_PREFIX | 'api/' | '/api/' (must start with /) |
MCP_ENDPOINT | 'mcp/' | '/mcp/' (must start with /) |
EXCLUDE_PATHS | '/admin/' | ['/admin/'] (must be a list) |
Language/client mismatch warning¶
Symptom: checkmcpconfig warns:
Cause: The default HTTP client doesn't match the default code language (e.g., fetch is a JavaScript client but the language is set to Python).
Solution: This is a warning, not an error — the code generator will auto-correct. To silence it, set a matching pair:
# Python with requests
DRF_MCP_DOCS = {
'DEFAULT_CODE_LANGUAGE': 'python',
'DEFAULT_HTTP_CLIENT': 'requests',
}
# TypeScript with axios
DRF_MCP_DOCS = {
'DEFAULT_CODE_LANGUAGE': 'typescript',
'DEFAULT_HTTP_CLIENT': 'axios',
}
Cache & Performance¶
Stale schema data after model or view changes¶
Symptom: The MCP server still shows old endpoints, fields, or schemas after you've made changes to your models, serializers, or views.
Cause: In production (DEBUG=False), CACHE_SCHEMA defaults to True and the schema is cached indefinitely (unless CACHE_TTL is set).
Solutions:
Option 1: Set a TTL for automatic refresh
Option 2: Invalidate programmatically
from drf_mcp_docs import invalidate_schema_cache
# Call after deploying new code, or in a signal handler
invalidate_schema_cache()
Option 3: Restart the server
The simplest approach — the cache is in-process memory and is cleared on restart.
Schema rebuilds on every request in development¶
Symptom: Logs show the schema being rebuilt on every MCP request, making responses slower.
Cause: When DEBUG=True, CACHE_SCHEMA defaults to False, so the schema is regenerated on every request. This is the intended behavior for development — you always see your latest changes.
Solution: This is expected. If schema generation is slow, you can enable caching in development:
Just remember to restart the server or call invalidate_schema_cache() when you make API changes.
Debugging with Logs¶
Enable detailed logging to see what drf-mcp-docs is doing internally:
# settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'drf_mcp_docs': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}
This enables debug output from all drf-mcp-docs modules:
drf_mcp_docs.adapters— Adapter probing, selection, and schema generation timingdrf_mcp_docs.server.instance— Cache hits/misses, schema processor creation, path filteringdrf_mcp_docs.server.tools— Tool inputs and endpoint lookupsdrf_mcp_docs.schema.processor— Schema processing,$refresolution, depth limit warningsdrf_mcp_docs.urls— ASGI lifespan events and request routingdrf_mcp_docs.settings— Resolved settings values
Getting Help¶
If the troubleshooting steps above don't resolve your issue:
- Run
python manage.py checkmcpconfigand note the output - Enable debug logging (see above) and reproduce the issue
- Open an issue at github.com/Abdulkhalek-1/drf-mcp-docs/issues with:
- The
checkmcpconfigoutput - Relevant log output
- Your Python, Django, and DRF versions
- Which schema generator you're using
- The