MCP tools: Content Relations
MCP tools: Content Relations
Six MCP tools manage the relation graph. They are available when app.Relations(store) is wired — the server checks App.RelationStore() != nil at startup and registers the tools only when a store is present. No additional server option is required.
For the underlying concepts — RelationKindDef, edge_class, the three-layer model — see Content Relations.
assert_relation
Creates an asserted edge between two content items. Each call inserts a new edge record with a unique ID — calling assert_relation twice with the same endpoints and kind creates two distinct edges. Use get_relations first to check whether an edge already exists before asserting.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
source_type | string | yes | Content type of the dependent item (e.g. "post") |
source_id | string | yes | ID of the dependent item |
target_type | string | yes | Content type of the referenced item |
target_id | string | yes | ID of the referenced item |
relation_kind | string | yes | type_name of a registered kind (e.g. "cites") |
confidence | float | no | Confidence score, for weighted kinds |
attributes | object | no | Arbitrary edge metadata |
Returns the created or updated RelationEdge record.
When to use vs. Go API — Use assert_relation when an operator or agent is manually establishing a relation from outside the application's save path. For relations that should be maintained automatically whenever a content item is saved, call store.RecomputeAsserted from a save-path hook in Go instead.
propose_relation
Creates an inferred edge — an agent-proposed relation pending human review. The edge is immediately visible in the graph with edge_class = "inferred" but is not treated as authoritative until promoted via assert_relation.
Parameters — same as assert_relation, with the addition of:
| Parameter | Type | Required | Description |
|---|---|---|---|
created_by_job | string | no | Agent job ID, for audit trail |
Returns the created RelationEdge with edge_class = "inferred".
Asserted vs. inferred workflow
Agent calls propose_relation
→ edge created with edge_class = "inferred"
Editor reviews (via get_relations, filtering edge_class)
→ accepts: calls assert_relation with same endpoints and kind
(promotes to edge_class = "asserted")
→ rejects: calls store.Delete or a future delete_relation tool
Rules can also promote inferred edges automatically — for example, any edge with confidence above 0.9 could be asserted by a nightly job without human review.
get_relations
Queries edges by source or target, with optional kind and edge_class filters.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
source_type | string | no* | Content type of the source item |
source_id | string | no* | ID of the source item |
target_type | string | no* | Content type of the target item |
target_id | string | no* | ID of the target item |
relation_kind | string | no | Filter by kind; omit for all kinds |
edge_class | string | no | "asserted" or "inferred"; omit for both |
*At least one of source_id or target_id must be provided.
Returns an array of RelationEdge records.
When to use vs. Go API — Use get_relations for interactive inspection and agent-driven graph queries. For application logic that needs edges on the hot path (e.g. inside a request handler), call store.GetBySource or store.GetByTarget directly in Go.
preview_impact
Returns all source-side dependents of a target item without firing any signals. Use this before an archive or delete action to show an editor how many items depend on the target.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
target_type | string | yes | Content type of the item being evaluated |
target_id | string | yes | ID of the item being evaluated |
Returns an array of RelationEdge records for all active edges pointing at the target — the same set that would receive AfterRelationCascade if the target were archived or deleted.
When to use — Always call preview_impact before archiving or deleting an item that other content may reference. The result tells an editor "if you archive this, X items will be notified via AfterRelationCascade."
preview_impact only reads — it does not change any state or fire any signals.
upsert_relation_kind
Registers a new relation kind or updates an existing one. Safe to call on every boot; idempotent on type_name.
Parameters
| Parameter | Type | Required | Description | ||
|---|---|---|---|---|---|
type_name | string | yes | Unique snake_case identifier | ||
label | string | no | Human-readable label | ||
mode | string | yes | "derived" \ | "asserted" \ | "inferable" |
directional | bool | no | Default true | ||
weighted | bool | no | Default false | ||
type_pairs | string | no | JSON array of {source_type, target_type} objects | ||
attributes | object | no | Arbitrary metadata |
Returns the registered RelationKindDef.
When to use vs. Go API — Prefer registering kinds in Go at boot time via store.UpsertKind, so the kind registry is always consistent on startup. Use upsert_relation_kind for interactive registration during development or when adding kinds dynamically at runtime without a code deploy.
list_relation_kinds
Returns all registered relation kinds.
Parameters — none.
Returns an array of RelationKindDef records.
Use this to inspect the kind registry — for example, before calling assert_relation or propose_relation to confirm the kind name.