Skip to main content

liberrex-mcp-server (Python)

Publish a platform's tools on the Liberrex MCP mesh, so that Liberrex AI, Animatoria, the ERP and any other platform of the ecosystem can call them. It follows the shared mesh conventions: peer keys, per-call user identity, permissions, write control and [code] errors. The package also ships the Liberrex AI platform server (liberrex-mcp-server): agents, copilot and sales intelligence (next best action, next best product…) as tools.

  • Python ≥ 3.10, built on the official mcp SDK v2. Stateless Streamable HTTP (any instance answers any call) or stdio.
  • Pair it with liberrex-mcp-client on the calling side.
  • TypeScript equivalent: @liberrex/mcp-server.
pip install liberrex-mcp-server

Publish your platform's tools

from typing import Optional
from liberrex_mcp_server import PeerRegistry, PlatformError, PlatformServer, ToolContext

server = PlatformServer("erp", title="Acme ERP", peers=PeerRegistry.from_env())

@server.tool(permission="invoices.read", category="finance")
def overdue_invoices(ctx: ToolContext, customer: Optional[str] = None, limit: int = 20) -> dict:
    """Overdue invoices the user can see, oldest first."""
    user = ctx.require_identity()            # who the call acts for: user_id, tenant_id, roles, locale
    rows = invoices.overdue(tenant=user.tenant_id, user=user.user_id, customer=customer, limit=limit)
    if rows is None:
        raise PlatformError("not_found", "Unknown customer")      # → "[not_found] Unknown customer"
    return {"items": rows}

@server.tool(permission="invoices.write", write=True)
async def send_reminder(ctx: ToolContext, invoice_id: str) -> dict:
    """Send a payment reminder."""
    ...

Then serve it:

app.mount("/mcp", server.asgi())       # FastAPI / Starlette; the endpoint answers at /mcp/
server.run_http(port=8765)             # standalone, at /mcp
server.run_stdio()                     # local desktop clients

The SDK checks these before your function runs:

check refusal
The Authorization: Bearer key is a valid (not expired) key of a configured peer HTTP 401 [unauthorized]
At most rate_per_minute × 10 HTTP requests per minute from that peer (flood guard) HTTP 429 + Retry-After
At most rate_per_minute tool calls per minute from that peer [rate_limited]
The identity's tenant is one the peer may act in [tenant_not_allowed]
The identity's roles, capped by the peer's roles, include the tool's permission [forbidden] / [identity_required]
write=True tools only for peers with writes [writes_disabled]
At most 4 platform hops [too_many_hops]
Any other exception: logged, and not leaked to the caller [internal_error] <tool> failed

Sync functions run in a worker thread, so they may block, for example on a database call. Use ctx.forward_meta() when a tool calls another platform: the same person and trace go along, with hops + 1.

Already integrated with the Liberrex copilot?

Publish every tool you declared with liberrex_copilot in one line. The schemas, permission checks and error codes stay the same:

from liberrex_mcp_server.copilot import publish_copilot
publish_copilot(server, copilot, user=lambda identity: load_user_with_roles(identity))

This is how Animatoria publishes its 43 tools at /mcp. The user callback lets your platform compute the user's roles itself, rather than trust the roles the caller sends.

Tools that already have a JSON Schema

server.raw_tool("lookup", description="…", input_schema={"type": "object", "properties": {...}},
                handler=lambda ctx, arguments: ...)

Peers (who may call)

liberrex-mcp-server new-key liberrex-ai     # prints a key for the caller and the sha256 entry for you
LIBERREX_MCP_PEERS='{"liberrex-ai": {"keys": [{"key": "sha256:…", "expires": "2027-01-31"}, "sha256:…"],
                                     "tenants": "*", "writes": false, "rate_per_minute": 300},
                     "erp": {"key": "sha256:…", "tenants": ["acme"], "roles": ["invoices.read"]}}'
LIBERREX_MCP_PEERS_FILE=/etc/erp/mcp-peers.json    # or: the same JSON in a file, re-read when it changes
field meaning default
key / keys sha256:<64 hex> (preferred) or the raw key (24 characters at least); or {"key", "expires": "YYYY-MM-DD"}: valid until the end of that UTC day required
tenants "*" or the tenant ids the peer may act in "*"
writes may call write=True tools false
roles ceiling: the identity's roles are intersected with it none
rate_per_minute tool calls per minute (1 to 10,000), per process; HTTP requests are capped at 10× that 120

Keep only hashes on the server, give each caller its own key, and grant writes only where needed. Rotate with an overlap: add the new hash to keys, give the caller the new key, then remove the old hash (or let its expires pass). python -m liberrex_mcp_server.keys <peer> also prints a key and its hash.

With LIBERREX_MCP_PEERS_FILE (FilePeerRegistry), the file is re-read when its mtime changes (checked at most every 2 s): revoke a caller without a restart. Invalid at startup → PeerConfigError; invalid later → logged, the previous peers stay; missing → no caller is accepted.

Audit

Every tool call (ok / refused / error) and every refused HTTP request (unauthorized, rate_limited) produces one event for PlatformServer(..., audit=fn) (default: a JSON line on the liberrex_mcp_server.audit logger; None: off): at, platform, event, tool, write, peer, user, tenant, trace_id, origin, hops, status, code, duration_ms (and client for HTTP events). Tool arguments are never included. The fields are the same in the TypeScript server; see MCP_MESH.md §6.

The Liberrex AI platform server

liberrex-mcp-server --check                     # credentials, peers, tools
liberrex-mcp-server --transport http --port 8765   # the mesh endpoint at /mcp (needs LIBERREX_MCP_PEERS)
liberrex-mcp-server                              # stdio for Claude Desktop / Cursor (acts as LIBERREX_USER_ID)
Variable Meaning
LIBERREX_API_URL Liberrex API (default https://ai-api.liberrex.com)
LIBERREX_API_KEY Developer API key key_id:secret: agents, conversations, usage (company-wide tools)
LIBERREX_SECRET_KEY Embedded copilot key lxsk_…: copilot and surfaces, for the identity of each call
LIBERREX_SURFACES next_best_action=nba-queue,next_best_product=nbp-queue: modes of sales_recommendations
LIBERREX_MCP_PEERS / LIBERREX_MCP_PEERS_FILE Platforms allowed to call (see above)
LIBERREX_USER_ID, LIBERREX_TENANT_ID, LIBERREX_USER_ROLES, LIBERREX_LOCALE stdio only: the user a desktop client acts as
LIBERREX_MCP_READ_ONLY 1 leaves out confirm_action, create_action_batch and end_conversation

The 20 tools are:

Group Tools
Agents whoami, list_agents, get_agent, ask_agent, list_copilot_agents, start_agent_group, ask_agent_group, get_agent_group, list_conversations, get_conversation, end_conversation, get_usage
Copilot copilot_ask, copilot_list_threads, copilot_get_thread
Sales intelligence sales_recommendations, render_surface, suggest_field, run_surface_action, create_action_batch, confirm_action, cancel_action, record_feedback
Billing get_copilot_usage

Each calling user gets their own copilot session, minted for the user.id and tenant.id the calling platform sends. Recommendations are therefore computed from that user's own data, under their own roles.

Development

python3.12 -m venv .venv && .venv/bin/pip install -e ".[dev]" -e ../../mcp-client/python -e ../../python
.venv/bin/pytest      # 39 tests, including server ↔ client end to end over HTTP

Metadata

Release files for liberrex-mcp-server 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for liberrex-mcp-server 0.1.0
File Size Uploaded
liberrex_mcp_server-0.1.0.tar.gz 44.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for liberrex-mcp-server 0.1.0
File Interpreter ABI Platform
liberrex_mcp_server-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 82.1 kB

Release files / liberrex_mcp_server-0.1.0.tar.gz

Download URL liberrex_mcp_server-0.1.0.tar.gz
Size 44.2 kB
Tags Source
SHA-256 checksum
How to use checksums
37ce874f0877631e6d00e35f09dea4f8990ec8bec1201428d20eee73766dde51
BLAKE2b-256 checksum
How to use checksums
3366003a127a88ac0799f26d5d9a155929a67e693eec4d4bc02d14894fa4b6e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release files / liberrex_mcp_server-0.1.0-py3-none-any.whl

Download URL liberrex_mcp_server-0.1.0-py3-none-any.whl
Size 37.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
058a375acef8f69b430ea896da404f547762841b820f1971996e4cb555032518
BLAKE2b-256 checksum
How to use checksums
d0aa732b189452877f77aa10c883e41f1b865f6f8a443aa080209b61f1ad7f12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page