Cavi MCP Core
Shared plumbing for the CAVI MCP servers (blender-mcp, substance-mcp, houdini-mcp, adobe-mcp): one server type, one failure contract, one schema compaction, one bounded process runner, bounded file reads and an operation journal.
Install
uv add cavi-mcp-core
Requires Python 3.11+ and the MCP Python SDK 2.
Server
from cavi_mcp_core.server import READ_ONLY, Server
mcp = Server("my-mcp", package="my-mcp", instructions="Inspect before editing.")
@mcp.tool(annotations=READ_ONLY)
async def status() -> dict:
return {"ready": True}
Server extends mcp.server.mcpserver.MCPServer:
packagesets the reported server version from that distribution's metadata.- Tool schemas are compacted (
compact=Falsekeeps the SDK's schemas). ValueError,RuntimeErrorandOSErrorraised by a tool reach the caller with their text; any other exception is logged on the server and reported without details. Passanticipated=()to leave tool errors to the SDK.- Every tool error, including an unknown tool name, returns one structured result:
{"error": {"version": 1, "code": "INVALID_ARGUMENT", "operation": "status",
"outcome": "rejected", "retry_safe": false, "next_action": "inspect_inputs"}}
outcome is rejected only for invalid arguments, missing inputs and unknown tools;
anything else is unknown, and retry_safe is always false. Raise
contracts.OperationRejected(message, code) or contracts.OperationUnknown(message, code)
to report a specific code. Override Server.failure to name a different recovery tool
for unknown outcomes.
need(value, name, action) and reject_foreign(action, given, allowed) validate
action-style arguments. READ_ONLY, WRITES and DESTRUCTIVE are the tool annotations.
Contracts
contracts.Result is a strict pydantic model whose unset optional fields stay off the
wire. contracts.VariantResult accepts one of several declared field sets (shapes)
without a discriminator field.
Schemas
schema.compact_schema(schema, output=False) returns a copy without titles or
additionalProperties: true, with equivalent union forms shortened, and validates the same
values; output=True also drops defaults, which are documentation only in a response.
schema.validate_variant and schema.variant_schema back VariantResult.
Processes
proc.run(args, timeout) runs a command with bounded output and one deadline. On a
timeout or a cancellation it stops the whole process group (process tree on Windows) and
returns once the process exits. proc.run_sync is the blocking form and
proc.diagnostics(result) formats what a failed run printed.
Applications
apps.find_directory, apps.find_app and apps.find_executable locate an installed
application in one order: an environment override, which is final, then the default
location the caller passes, then PATH. apps.bundle(name, identifier, pattern, env)
finds a macOS application by its bundle identifier: the override in env when set, else
the newest matching bundle under /Applications; it raises AppUnavailable or
AppMismatch with a stable error_code. apps.version reads a bundle's version without
running it, apps.running asks whether an executable has a process, and
apps.processes lists the processes of one executable on macOS.
Files and journals
files.inside(workspace, path) resolves a path inside an existing workspace and refuses
.., escapes through symbolic links and the workspace root. files.read_bytes,
files.load_json and files.digest read bounded regular files and refuse a file that
changes while it is read; files.parse_json refuses NaN and Infinity.
journal.write_json replaces a JSON file atomically, durably and readable only by its
owner. journal.completion reads the completion receipt of one operation,
journal.archive records how an interrupted operation was resolved, and
journal.fingerprint hashes canonical JSON.
Development
uv sync --locked --dev
uv run --locked python -m unittest discover -s tests
uv run --locked ruff check .
License
MIT
Metadata
Release files for cavi-mcp-core 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cavi_mcp_core-0.1.1.tar.gz | 30.3 kB | With provenance | Details for cavi_mcp_core-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cavi_mcp_core-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for cavi_mcp_core-0.1.1-py3-none-any.whl |
Total release size: 49.7 kB
Release files / cavi_mcp_core-0.1.1.tar.gz
| Download URL | cavi_mcp_core-0.1.1.tar.gz |
|---|---|
| Size | 30.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f9080e60ed9a10fec7278c043a4914adee0dd968106e579a40ffece432b41519
|
|
BLAKE2b-256 checksum How to use checksums |
029c7df9320729f7ec3027eeaf093f276fba1a9636ff999aa27e5ece9d8dab2d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / cavi_mcp_core-0.1.1-py3-none-any.whl
| Download URL | cavi_mcp_core-0.1.1-py3-none-any.whl |
|---|---|
| Size | 19.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8b8ccbec012227e1e4efdad928d5f0beb1e01e16040ba6c3315fb5f123a4bf11
|
|
BLAKE2b-256 checksum How to use checksums |
9fd76f70749d787383fe0b06bedf55b335ff33d32818b648df5821539cf6b47a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logSecurity for cavi-mcp-core 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for cavi_mcp_core-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.