SurfSense/plugins/remote/mcp_server/access.py
Anish Sarkar 8d85b6f544 feat(plugins): serve SurfSense's plugins from one host, a paid one behind the license
plugins/remote/host mounts each plugin folder's MCP server at /<id>/mcp and
answers /health; without proprietary/ it serves only the Apache-2.0 plugins.
A plugin's access hook runs before its server sees a request, and
proprietary/license_check applies contract 2 with Keygen's validate-key: a
five-minute cache, a day's grace while Keygen is down, and 401, 403 or 503
otherwise. The check is license_check/, since license/ beside LICENSE is one
path on macOS and Windows. CI checks plugins/remote/ on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:40:00 +05:30

23 lines
580 B
Python

"""What a plugin requires of a request before its server sees it, such as a license.
A plugin's `server.py` names one as `access`; a plugin without one is open to every request.
"""
from dataclasses import dataclass
from typing import Protocol
from starlette.datastructures import Headers
@dataclass(frozen=True)
class Refusal:
"""An HTTP status and the `reason` the app shows the user."""
status: int
reason: str
class Access(Protocol):
async def refusal(self, headers: Headers) -> Refusal | None:
"""None lets the request through."""
...