Skip to content

Remote MCP endpoint returns 404 because Docker image likely omits MCP dependencies #2

Description

@paulieb89

Summary

The deployed remote MCP endpoint at https://property-shared.fly.dev/mcp is returning 404 when invoked by ChatGPT/MCP tooling.

This does not appear to be a /mcp vs /sse path issue. The repo and FastMCP defaults both indicate /mcp is the correct Streamable HTTP endpoint.

Observed behavior

Attempting to call the deployed MCP tool endpoint fails with:

MCP SSE probe returned 404 from fly.dev
url: https://property-shared.fly.dev/mcp
status_code: 404

Relevant repo findings

README advertises /mcp

README.md says:

Remote server deployed at `https://property-shared.fly.dev/mcp` (Streamable HTTP).

FastAPI app expects to mount MCP at /mcp

app/main.py contains:

from property_mcp.server import mcp as mcp_server
_mcp_app = mcp_server.http_app(path="/mcp")

and then adds middleware to route /mcp and /mcp/* directly, avoiding Starlette's trailing-slash 307 redirect.

ImportError is silently swallowed

_setup_mcp() currently does:

try:
    from property_mcp.server import mcp as mcp_server
    _mcp_app = mcp_server.http_app(path="/mcp")
except ImportError:
    pass

If property_mcp or fastmcp is missing in the deployed image, _mcp_app remains None, the MCP middleware is not installed, and /mcp returns 404.

Docker image appears to omit MCP dependencies/package

Dockerfile installs only the API extra:

RUN uv sync --frozen --no-dev --extra api

and copies only:

COPY app ./app
COPY property_core ./property_core

But app/main.py imports property_mcp.server, and pyproject.toml does not list property_mcp in the packaged folders. fastmcp[apps]==3.2.4 is under the apps extra, not the api extra.

Likely root cause

The Fly deployment starts the FastAPI app successfully, but the optional MCP setup fails due to missing MCP dependencies/package. Because the ImportError is swallowed, the deployment appears healthy while /mcp is never registered.

Proposed fix

  1. Ensure the deploy image installs the MCP dependencies, for example:
RUN uv sync --frozen --no-dev --extra api --extra apps
  1. Ensure the MCP package is actually present in the image. Either copy the package:
COPY property_mcp ./property_mcp

or add the correct published MCP package dependency to the deployed extras.

  1. Log or fail loudly when MCP is expected but unavailable:
def _setup_mcp() -> None:
    global _mcp_app
    try:
        from property_mcp.server import mcp as mcp_server

        _mcp_app = mcp_server.http_app(
            path="/mcp",
            transport="streamable-http",
            stateless_http=True,
        )
    except ImportError as exc:
        import logging
        logging.getLogger(__name__).exception("MCP disabled: %s", exc)
  1. Optional: add a lightweight smoke test/check for /mcp after deployment, so this class of failure is caught before publishing the endpoint.

Notes

fly.toml sets:

FASTMCP_STATELESS_HTTP = "true"

So Streamable HTTP on /mcp is the appropriate target. Classic SSE at /sse is probably not the right endpoint for this deployment mode.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions