mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-09 15:58:30 +00:00
Rename the import package surfsense_mcp -> mcp_server and remove the src/ layer so the project mirrors the backend's shape (project folder != package name, e.g. surfsense_backend/app). Kills the redundant surfsense_mcp/src/surfsense_mcp nesting. Distribution name and console command (surfsense-mcp) are unchanged; only python -m and internal import paths move to mcp_server. Dockerfile CMD updated; no PYTHONPATH added since the editable install already makes the package importable.
58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
"""Entry point: load settings from the environment and run the MCP server.
|
|
|
|
Two transports share one build:
|
|
- ``stdio`` (default): Cursor/Claude launch one process per user; the key comes
|
|
from the environment, so it is required here.
|
|
- ``streamable-http``: one process serves many users, each passing their own key
|
|
per request; the key is enforced by the transport's auth middleware instead.
|
|
|
|
For stdio, stdout is the protocol channel, so every log line goes to stderr.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
from mcp.server.fastmcp import FastMCP
|
|
|
|
from .config import Settings
|
|
from .server import build_server
|
|
|
|
|
|
def main() -> None:
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
stream=sys.stderr,
|
|
format="%(levelname)s %(name)s: %(message)s",
|
|
)
|
|
settings = Settings.from_env()
|
|
transport = os.environ.get("SURFSENSE_MCP_TRANSPORT", "stdio").strip() or "stdio"
|
|
mcp, _client = build_server(settings)
|
|
|
|
if transport in ("streamable-http", "http"):
|
|
_run_http(mcp, settings)
|
|
return
|
|
|
|
if transport == "stdio" and not settings.api_key:
|
|
raise SystemExit(
|
|
"SURFSENSE_API_KEY is required for stdio transport. Create an API "
|
|
"key in SurfSense (Settings -> API) and pass it via the "
|
|
"SURFSENSE_API_KEY environment variable."
|
|
)
|
|
mcp.run(transport=transport)
|
|
|
|
|
|
def _run_http(mcp: FastMCP, settings: Settings) -> None:
|
|
"""Serve the streamable-http app directly, so the per-request identity
|
|
middleware wraps the SDK's MCP endpoint."""
|
|
import uvicorn
|
|
|
|
from .core.transport import build_http_app
|
|
|
|
uvicorn.run(build_http_app(mcp), host=settings.host, port=settings.port)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|