falaw.bridges.mcp#
MCP bridge: expose every falaw tool as an MCP tool.
Like bridges/skill.py, this is a thin adapter over
falaw.registry.list_tools() — adding a new falaw tool automatically adds
an MCP tool, no edit here. Built on fastmcp (the federation’s MCP library;
see lookbook/mcp.py for the canonical pattern).
Two entry points:
register_tools()— add falaw’s tools to an existingFastMCPserver. This is what an aggregating server (reelee’s MCP server, which composes falaw + nw + artful + lacing) calls.build_mcp_server()— build a standaloneFastMCPserver exposing just falaw.serve()runs it over stdio.
The server’s instructions reach the model before any tool call, so they are
behaviour-driving text and are guarded like code:
unresolved_tool_references() reports every tool name or name_* family
a piece of prose names that the registry does not hold. An aggregating server
should run it over its own composed preamble too.
fastmcp is an optional dependency: pip install falaw[mcp].
Module Attributes
Tag marking a tool that makes no vendor call — docs/registry upkeep only. |
|
Snapshot of |
Functions
|
Build a standalone |
Names of the falaw tools that spend money — the metering SSOT. |
|
|
Register every falaw |
|
Run the standalone falaw MCP server. |
|
Tool names and |
- falaw.bridges.mcp.COSTED_TOOLS = ('animate_face', 'apply_note_to_beat', 'apply_note_to_scene', 'cast_character', 'cast_voice', 'composite_character_in_environment', 'edit_image', 'establish_environment', 'generate_audio', 'generate_image', 'generate_image_with_refs', 'image_to_video', 'lipsync', 'llm_complete', 'parse_screenplay', 'remove_background', 'render_beat', 'render_scene', 'render_shot', 'storyboard_shot', 'talking_avatar_from_text', 'text_to_speech', 'text_to_video', 'upscale_image', 'voice_clone')#
Snapshot of
costed_tools()for consumers that want a constant. Prefer the function when tools may be registered after import.
- falaw.bridges.mcp.FREE_TAG = 'maintenance'#
Tag marking a tool that makes no vendor call — docs/registry upkeep only. Everything else reaches fal.ai or an LLM and therefore spends money.
- falaw.bridges.mcp.build_mcp_server(*, name='falaw', tools=None)[source]#
Build a standalone
FastMCPserver exposing every falaw tool.Raises
ImportErrorwith an install hint iffastmcpis missing.
- falaw.bridges.mcp.costed_tools()[source]#
Names of the falaw tools that spend money — the metering SSOT.
Every genre package in the federation exposes this so an aggregating connector can gate spend from one source of truth per package (
braidio.mcp.COSTED_TOOLS,muvid.mcp.COSTED_TOOLS). falaw had none, so its 24 money-spending tools — the raw fal.ai operations, includingtext_to_videoandrender_scene— reached an aggregating connector completely unmetered (thorwhalen/reelee#265).Derived from the registry, not hand-listed, matching this module’s existing contract that adding a falaw tool needs no edit here. The consequence is the safe one: a newly-registered tool is **costed by default** and must be explicitly tagged
FREE_TAGto be exempt. Forgetting the tag over-meters a free tool (annoying); the inverse would let a new money-spender through a credit cap (a billing hole).
- falaw.bridges.mcp.register_tools(server, *, tools=None, prefix='')[source]#
Register every falaw
ToolSpeconserver(aFastMCP).- Parameters:
server (
Any) – Afastmcp.FastMCPinstance (or anything with a compatible.tool(fn, *, name, description, tags)method).tools (
Optional[Iterable[ToolSpec]]) – The tools to register; defaults to the whole falaw registry.prefix (
str) – Optional name prefix (e.g."falaw_") so an aggregating server can namespace falaw’s tools away from another package’s.
- Return type:
- Returns:
The MCP tool names registered (in registry order).
- falaw.bridges.mcp.serve(*, transport='stdio', **kwargs)[source]#
Run the standalone falaw MCP server.
stdio is the default transport — what Claude Desktop and the Anthropic SDK expect when launching an MCP server as a subprocess.
- Return type:
- falaw.bridges.mcp.unresolved_tool_references(text, *, tool_names=None)[source]#
Tool names and
name_*families named intextthat do not exist.Behaviour-driving prose — the server
instructions, a tool description, an aggregating connector’s composed preamble — names tools, and a call-site sweep cannot see prose. Nothing derives one from the other, so nothing failed when_INSTRUCTIONSspent months telling every model to “use theplan_*tools to inspect cost before spending” while the registry held no such tool (thorwhalen/falaw#47). This is the check that now fails instead.- Parameters:
text (
str) – The prose to scan.tool_names (
Optional[Iterable[str]]) – The names that count as existing; defaults to the falaw registry. An aggregating server that registered falaw under a prefix should pass whatregister_tools()returned, sofalaw_generate_imageresolves.
- Return type:
- Returns:
The unresolved references, deduplicated, in order of first appearance.
>>> unresolved_tool_references("Use the refresh_* tools.") () >>> unresolved_tool_references("Use the plan_* tools to inspect cost.") ('plan_*',)