File size: 2,020 Bytes
24b5ffb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""MCP server exposing the built-in tools over the Model Context Protocol.

This is the *server* half of the optional MCP transport (ADR-0017).  It wraps the
same in-process tool functions (`src/tools/builtins.py`) as MCP tools using the
official SDK's FastMCP, so a tool's behaviour is identical whether an agent
reaches it in-process or over MCP.  ``oracle`` is exposed first; adding a tool is
one `@mcp.tool` decorator that delegates to the shared implementation.

Run as a stdio server::

    python -m src.tools.mcp_server

The capability check still lives on the *client* side, behind the registry
(ADR-0012): this server is pure transport and trusts the registry to have already
authorised the call.  ``mcp`` is a top-level import here because this module is
only ever imported when the server is being run — the package and the app import
cleanly without it (see ``src/tools/mcp_client.py`` for the lazy client side).
"""
from __future__ import annotations

from mcp.server.fastmcp import FastMCP

from src.tools.builtins import oracle as _oracle

#: Stable server name advertised to clients; also used by the client config gate.
SERVER_NAME = "multi-agent-land-tools"


def build_server() -> FastMCP:
    """Construct the FastMCP server with every exposed built-in tool registered.

    Return types are annotated as ``dict[str, str]`` so FastMCP emits structured
    content the client can read back without re-parsing prose; the client also
    tolerates plain text JSON for robustness.
    """
    mcp = FastMCP(SERVER_NAME)

    @mcp.tool(
        name="oracle",
        description="Draw a single cryptic omen for the current scene. Params: {seed: str}.",
    )
    def oracle(seed: str = "") -> dict[str, str]:
        """Deterministic omen — delegates to the shared in-process implementation."""
        return _oracle(seed=seed)

    return mcp


def main() -> None:
    """Entry point: serve the tools over stdio JSON-RPC."""
    build_server().run("stdio")


if __name__ == "__main__":
    main()