py2mcp.serve#
Serve a py2mcp FastMCP server over stdio, as a packaged integration launches it.
py2mcp.mk_mcp_server() / py2mcp.mk_mcp_from_refs() build a server
object but deliberately leave running it to the caller (the only run hint in
main is a comment). This module adds the thin “actually serve it over stdio”
layer plus a small JSON-config loader, so a one-click bundle (e.g. a Claude
Desktop .mcpb Desktop Extension) can point its manifest.json at:
python -m py2mcp --config ${__dirname}/server/py2mcp_config.json
and get a live MCP server. The config is just {"name": ..., "refs": [...]}
where each ref is a 'module:function' string resolved by
py2mcp.util.import_object().
stdio note: an MCP stdio server speaks newline-delimited JSON-RPC on
stdout, so nothing else may be written there. FastMCP’s run handles this;
keep application logging on stderr.
Main entry points:
serve_stdio: build from refs and run over stdio (blocking)resolve_server_config: merge a config file with explicit refs and nameload_server_config: read and check the JSON configmain: thepython -m py2mcpcommand line
>>> from py2mcp.serve import resolve_server_config
>>> resolve_server_config(refs=['os.path:basename'])
(['os.path:basename'], 'py2mcp Server')
Module Attributes
Default server name when neither a config nor |
Functions
|
Load a server config JSON of the form |
|
CLI: |
|
Merge a config file and explicit |
|
Build an MCP server from |
- py2mcp.serve.DFLT_SERVER_NAME = 'py2mcp Server'#
Default server name when neither a config nor
--namesupplies one.
- py2mcp.serve.load_server_config(path)[source]#
Load a server config JSON of the form
{"name": str, "refs": [str, ...]}.Only the shape is checked here; the refs are resolved later, when the server is built. An actionable error beats a server that starts with no tools.
- Parameters:
- Return type:
- Returns:
The parsed JSON object, untouched, with at least a
refslist.- Raises:
ValueError – The file is not valid JSON, or is not a JSON object carrying a
refslist.OSError – The file cannot be read.
Examples
>>> import json, tempfile >>> from pathlib import Path >>> path = Path(tempfile.mkdtemp()) / 'py2mcp_config.json' >>> _ = path.write_text(json.dumps({'name': 'My Tools', 'refs': ['os.path:basename']})) >>> load_server_config(path) {'name': 'My Tools', 'refs': ['os.path:basename']} >>> _ = path.write_text(json.dumps({'name': 'no refs here'})) >>> load_server_config(path) Traceback (most recent call last): ... ValueError: py2mcp server config '...py2mcp_config.json' must be a JSON object with a "refs" list, ...
See also
resolve_server_config(): merge the config with command-line refs.
- py2mcp.serve.main(argv=None)[source]#
CLI:
python -m py2mcp --config cfg.json(or--ref mod:func ...).py2mcp usage <dir>is the one subcommand: it summarizes a usage log written bypy2mcp.usage.UsageLogger(seepy2mcp.usage.main()) and is dispatched on the first word so the flag-only serving form above is unchanged.- Return type:
- py2mcp.serve.resolve_server_config(*, config=None, refs=(), name=None)[source]#
Merge a config file and explicit
refs/nameinto(refs, name).Refs from
--refare appended after any from the config file; an explicitnamewins over the config’s. Pure (no I/O beyond readingconfig), so it is unit-testable without standing up a server.- Parameters:
config (
Union[str,Path,None]) – Path of a JSON config as read byload_server_config(), orNonefor no config file.refs (
Iterable[str]) – Extra'module:function'references, appended after the config’s.name (
Optional[str]) – Server name; overrides the config’sname. When neither is given,DFLT_SERVER_NAME.
- Return type:
- Returns:
The merged list of references and the server name.
- Raises:
ValueError – Neither the config nor
refssupplies any reference, or the config file is malformed (seeload_server_config()).
Examples
>>> resolve_server_config(refs=['os.path:basename'], name='Paths') (['os.path:basename'], 'Paths')
With a config file, its refs come first and its name is the fallback:
>>> import json, tempfile >>> from pathlib import Path >>> path = Path(tempfile.mkdtemp()) / 'py2mcp_config.json' >>> _ = path.write_text(json.dumps({'name': 'My Tools', 'refs': ['os.path:basename']})) >>> resolve_server_config(config=path, refs=['os.path:dirname']) (['os.path:basename', 'os.path:dirname'], 'My Tools') >>> resolve_server_config(config=path, name='Override') (['os.path:basename'], 'Override')
- py2mcp.serve.serve_stdio(refs, *, name='py2mcp Server', input_trans=None, middleware=None, instructions=None, prompts=None, resources=None)[source]#
Build an MCP server from
'module:function'refs and run it over stdio.Blocks, serving the MCP protocol on stdin/stdout until the host disconnects. Thin wrapper over
py2mcp.mk_mcp_from_refs()+FastMCP.runso that packaged integrations have one command to launch. No example here: the call does not return while the server runs.- Parameters:
refs (
Iterable[str]) –'module:function'references, one per tool.name (
str) – Server name.input_trans (
Optional[Callable[[dict],dict]]) – Forwarded topy2mcp.mk_mcp_from_refs().middleware (
Optional[Any]) – A single FastMCP middleware or a list, forwarded for cross-cutting concerns; logging/metering is as useful on the local stdio path as on the remote one.instructions (
Optional[str]) – The server’s model-facing description.prompts (
Union[Callable,Iterable[Callable],None]) – Forwarded topy2mcp.mk_mcp_from_refs().resources (
Optional[Mapping[str,Callable]]) – Forwarded topy2mcp.mk_mcp_from_refs().
- Return type:
See also
py2mcp.http.serve_http(): the same over Streamable HTTP.main(): the command line that calls this.