Provides containerized deployment and execution environment for the MCP server with Docker Compose orchestration
Manages git submodules for schema and example discovery, enabling version-controlled access to synesthetic schemas
Uses Mermaid diagrams for system architecture documentation and visualization of component relationships
Integrates pytest testing framework for validation, diffing, backend operations, and transport testing
Built as a Python-based MCP adapter with JSON-RPC transport, schema validation, and backend API integration capabilities
Optionally integrates Ruff for Python code formatting and linting during development
version: v0.2.7 owner: delk73 lastReviewed: 2025-09-12
Synesthetic MCP
Minimal, deterministic MCP-style adapter exposing schemas, examples, validation, diff, and an optional backend-populate tool.
System Context
Features
Schema and example discovery
JSON Schema validation (Draft 2020-12)
Batch validation via
validate_many
withMCP_MAX_BATCH
(default 100)RFC6902 diff (add/remove/replace only)
Backend population (optional via
SYN_BACKEND_URL
)Canonical STDIO JSON-RPC loop with optional Unix-domain socket transport (
MCP_ENDPOINT=socket
) and TCP transport (MCP_ENDPOINT=tcp
,MCP_HOST
,MCP_PORT
)Per-request 1 MiB payload guard enforced before parsing across STDIO, socket, and TCP transports
Deprecated
validate
alias remains available but logs a warning; prefervalidate_asset
Strict asset contract: top-level
$schema
is required and legacyschema
/$schemaRef
keys are rejected (v0.2.8)
Quickstart
Install deps:
pip install -r requirements.txt && pip install -e .
Initialize schemas/examples:
git submodule update --init --recursive
.Serve via Compose:
docker compose up serve
(runs the transport, logsmcp:ready mode=<endpoint>
with ISO-8601 timestamps, and exposes/tmp/mcp.ready
for health checks).Or run the helper:
./up.sh
builds the image and starts the serve service in the background; follow withdocker compose logs -f serve
if you want to tail logs.Validate an asset locally:
python -m mcp --validate libs/synesthetic-schemas/examples/SynestheticAsset_Example1.json
.
Structure
Development
Python >= 3.11
Install deps (minimal):
pip install -r requirements.txt
Minimal deps:
jsonschema
,httpx
,pytest
Optional extras:
referencing
(enhanced JSON Schema refs; import is optional)Dev (optional):
ruff
,mypy
Import check:
python -c "import mcp; print(mcp.__version__)"
Run tests:
pytest -q
Runtimes:
python -m mcp
(STDIO by default; setMCP_ENDPOINT=socket
for the Unix-domain socket server orMCP_ENDPOINT=tcp
for TCP. Logsmcp:ready mode=<endpoint>
with ISO-8601 timestamps on readiness).python -m mcp.stdio_main
(invoke the STDIO loop directly when embedding).
Dependencies
Runtime:
jsonschema
,httpx
Tests:
pytest
Dev (optional):
ruff
,mypy
Extras (optional):
referencing
(ref handling performance/behavior)
Environment
Variable | Default | Behaviour |
|
| Transport selector.
runs over stdin/stdout;
enables the Unix-domain socket server;
binds a TCP listener. |
|
| File touched on startup with
and removed on shutdown; Compose health checks test for its presence. Override when sandboxed. |
|
| Socket path when
. The server unlinks the file on shutdown. |
|
| Octal file mode applied to the socket on startup. Increase only when the socket must be shared. |
|
| TCP bind address when
. Use
for local development. |
|
| TCP port when
. Set to
to request an ephemeral port (logged on startup). |
|
when present | Overrides schema directory; required when submodule absent. Startup fails if the directory is missing. |
|
when present | Overrides examples directory; discovery falls back to submodule if unset. |
| unset | Enables backend POSTs; missing keeps populate disabled (
). |
|
| Custom path for backend POST requests. |
|
| Maximum batch size for
; oversized batches return
. |
.env.example
captures these defaults for quick copying into local shells or Compose.
Environment Discovery
SYN_SCHEMAS_DIR
andSYN_EXAMPLES_DIR
override paths when set.Otherwise, schemas/examples are loaded from the
libs/synesthetic-schemas
submodule.If neither is available, listings are empty and get operations return not found (no fixture fallback).
Submodule (SSOT)
Authoritative schemas/examples live at libs/synesthetic-schemas
(git submodule).
Order of discovery used by the adapter:
SYN_SCHEMAS_DIR
andSYN_EXAMPLES_DIR
if setlibs/synesthetic-schemas/jsonschema
andlibs/synesthetic-schemas/examples
if presentIf neither exists, listings are empty and get operations return not found
Initialize the submodule:
Schema Aliases (Nested Assets)
synesthetic-asset
→ canonical schema (flat).nested-synesthetic-asset
→ alias for assets with components inlined.All component types may be embedded (shader, tone, haptic, control, modulation, rule bundle).
Alias validation loads the canonical
synesthetic-asset
schema.Examples
SynestheticAsset_Example*.json
are treated asnested-synesthetic-asset
.Assets MUST declare their validating schema via top-level
$schema
; legacyschema
or$schemaRef
keys are rejected.Tests use the nested alias; submodule is the single source of truth.
Error Model
Validation failed:
{ ok:false, reason:'validation_failed', errors:[{ path, msg }] }
Backend error:
{ ok:false, reason:'backend_error', status, detail }
Unsupported tool/resource:
{ ok:false, reason:'unsupported', detail }
Network errors map to backend_error with
status:503
and a briefdetail
.Payload too large (>1 MiB on STDIO/socket/TCP):
{ ok:false, reason:'validation_failed', errors:[{ path:'', msg:'payload_too_large' }] }
CLI Usage
Exit code
0
: validation succeeded.Exit code
1
: validation failed (payload includesreason: validation_failed
).Exit code
2
: input errors (file missing, unreadable, or invalid JSON).
Docker
Build and run tests in a container:
Notes:
docker-compose.yml
passes through env if set; there are no defaults to fixtures. The adapter’s own discovery logic picks the right source.No backend service is started by compose; backend calls are disabled unless
SYN_BACKEND_URL
is set.
Serving Locally
docker compose up serve
builds the image, startspython -m mcp
, waits for/tmp/mcp.ready
, and keeps logs attached../up.sh
builds the image and starts theserve
service in detached mode; rundocker compose logs -f serve
to follow output after startup.STDIO remains the default; set
MCP_ENDPOINT=socket
to listen on the Unix-domain socket path, orMCP_ENDPOINT=tcp
(optionally withMCP_HOST
/MCP_PORT
) to expose a TCP listener.Requests above 1 MiB (UTF-8 bytes) are rejected before parsing with
payload_too_large
on STDIO, socket, and TCP (seetests/test_stdio.py
,tests/test_socket.py
, andtests/test_tcp.py
).
Spec
See docs/mcp_spec.md
for deterministic IO contracts and limits.
Status
✅ Spec pinned in docs/mcp_spec.md
✅ Minimal implementation with tests
Validating it
Quick host check with
Paste this request:
You should get a JSON response with available schemas.
Labs connection env (pointing to the MCP container via TCP):
Run Labs against it:
This server cannot be installed
remote-capable server
The server can be hosted and run remotely because it primarily relies on remote services or has no dependency on the local environment.
Enables validation, diff generation, and backend population for Synesthetic assets using schema-compliant resources and tools. Serves as an MCP adapter that enforces schema compliance and integrates with the Synesthetic asset generation pipeline.