Return modules that have a typed compatibility relationship with the given module. Both edge directions are returned and tagged via the per-match `direction` field — so a single call answers both "what is X a R for?" and "what is a R for X?".
`relationship` is OPTIONAL. Omit it to get EVERY edge touching the module across all relationship kinds — the bare "what pairs with / relates to X?" question — with each match self-describing via its own `relationship`. Pass a relationship to restrict to that one kind. Prefer the relationship-less call when you don't already know which kind exists; reach for the typed form only when the question names a specific role ("what clocks X?").
Use this for two question shapes:
1. Patch-time compatibility — "what could I use as a clock source for X?" (returns matches with direction='inbound'), or "what does X clock?" (direction='outbound').
2. Catalog comparison — "what's an alternative to X?" (symmetric), "what does X replace?" (outbound) / "what replaces X?" (inbound), "is there an expander for X?" (inbound).
The vocabulary describes the edge as stored (from = role-bearer, to = target):
Patch-time:
- clock-source-for — A clocks B
- cv-source-for — A produces CV that B consumes
- modulator-for — A is a modulator suitable for B (LFO, S&H, random)
- audio-source-for — A is an audio source for B (typically a VCO into a VCF)
- quantizer-for — A quantizes for B
- trigger-source-for — A produces triggers that B consumes
- envelope-target-for — A is something B's envelope output is designed to drive
Catalog:
- replaces — A is the newer successor to B (Morphagene replaces Phonogene)
- alternative-to — symmetric: A and B occupy similar design space with different character
- expander-for — A is an expander module for the host module B
Direction tag on each match:
- outbound: queried module is the FROM side (role-bearer). Match is what the queried module does as R.
- inbound: queried module is the TO side. Match is the R-for the queried module.
- symmetric: only for alternative-to.
Args:
- module_id (string, required): "<manufacturer-slug>/<module-slug>"
- relationship (string, optional): one of the values above. Omit for all edges.
- limit (number): default 50, max 200
Returns:
{
"module": { id, name },
"relationship": <relationship> | null, // null when none was passed (all-edges query)
"matches": [{ id, name, manufacturer, notes, source_id, direction, relationship }]
}
If the module is unknown, returns an error. If no relationships have been recorded in either direction, returns matches=[]. The `notes` field describes the edge in the canonical A→B direction; combined with `direction` the caller can read it correctly either way.