From conport
Use when managing agent identity, persistent memory, and structured domains in multi-agent systems. Must run agent_init at session start. Agent Intent-API v4 — you express intent (remember / recall / create_kind / event), ConPort handles storage.
How this skill is triggered — by the user, by Claude, or both
Slash command
/conport:conport-agentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> ConPort is your **single memory + knowledge system**. You work with
ConPort is your single memory + knowledge system. You work with intent commands — say what you want kept or found; ConPort decides where it lives, how it connects, and how to retrieve it. You never pick storage primitives.
Without
agent_init— no context. Withoutrecall— you answer blindly.
This skill carries the always-on discipline — bootstrap, recall-before-act, the core verbs, the structure decision, visibility, and the never-store rule. Deep, situational reference (the full intent-API semantics, the edge-type vocabulary and edge grounding, typed refs, and the aux operations) lives in the live docs — see the Live docs section. Fetch the relevant page before acting on one of those topics; don't act from memory.
Tool names below are short forms. Prepend the prefix for your environment:
mcp__conport__CONPORT_AGENT_UUID env var (preferred), orPAPERCLIP_AGENT_ID, HERMES_AGENT_ID,
OPENCLAW_AGENT_ID), oragent_init({ uuid: "<resolved_uuid>", name: "<display name>" })Response shape:
bootstrap_state 'new' or 'continuing'
identity your identity statements (private)
principles your rules / safety rails (private)
broadcast_facts collective always-load knowledge — facts AND crystallized skills
recent_self_changes YOUR own identity/principle/skill writes from the last 7 days
collections [{key, members, field_hints, status_vocab}] — your structured domains
mature_communities skill-promotion candidates (dense, stable clusters)
pending_extraction {buffer_size, message_ids} when un-consolidated messages ≥ 10 — informational; the backend distills the buffer on its own
summary human-readable status line
recent_self_changes is your short-term memory of what you changed about
yourself. Read it every session before you touch your own skills, config, or
loops — it is the record of "I rewrote X yesterday, here's why". A surface that
looks empty or wrong is not a blank slate; it is a prompt to check this list and
recall before you rebuild.
new → empty; write your first identity + principles via remember.
continuing → identity + principles + broadcast_facts are your baseline;
use recall for the rest. pending_extraction is informational — the backend
consolidates the buffer itself; you don't act on it. Glance at collections so
you reuse existing structured domains (don't reinvent them).
Updates: act on the signal, never hand-compare versions. Pass your
skill_id / skill_version / client_type to agent_init; if it returns
skill_update_available, an update exists — install it. If it's absent, you're
current. Your memory provider plugin is one installable unit with its own
version line — never compare its number against unrelated skill numbers, or a
skill version against a plugin release number. They're independent. Eyeballing "my 8.x looks higher than the 12.x
release, so I'm ahead" is the exact mistake this signal prevents.
Your memory is read-first, not a write-only journal. You write diligently;
the failure mode is acting without reading. Before you act on a conclusion about
the world OR about yourself, recall first.
The hard rule — never rebuild from a blank-looking surface. When your own
skill, file, config, or state looks empty, wrong, or missing, that is a
recall query — NOT a signal to fix it from scratch. You may have changed it
yourself recently and simply not be looking at the record.
# WRONG — destroys your own recent work
"my main skill is empty → I'll rebuild it"
# RIGHT — recover the record first
recall("research loop skill", scope={meta_types:["skill"]}) # what did I author?
# + read recent_self_changes from agent_init
# only AFTER that, if it's genuinely gone, rebuild
This applies hardest on diagnose turns — "what happened", "разберись",
"why this error", "fix this". The first move is recall of the relevant area
recent_self_changes, THEN inspect the live state. A live surface and
your memory of changing it are two sources; reconcile them, don't trust the
live one blindly and overwrite the other.Record what you change about yourself. When you edit your own skill, cron,
loop, or config, immediately remember it so future-you can recall it:
remember("2026-06-04 rewrote research-loop: switched topic/source split, "
"cron now nightly — reason: old approach buried sources under topics",
meta_type="skill", visibility="broadcast")
A self-change you don't record is a change you will later mistake for a bug.
These writes surface in next session's recent_self_changes and broadcast
anchors — that is how you avoid re-deciding what you already decided.
This is your everyday surface. Express intent; storage is ConPort's job.
| Verb | What it does |
|---|---|
remember(content) | Knowledge (default fact/observation): log an episode of what was said — the backend distills it into claims. |
remember(content, meta_type=identity|principle|skill) | Self-model: a direct, anchored write of who you are — not an episode, not consolidated. |
remember(kind, name, fields) | Keep the current state of a structured item. |
recall(query, intent?, scope?, include_candidate?, budget?) | Find anything relevant — returns a graph-augmented packet: facts grouped by entity with status/provenance/conflicts, plus flat_results for compat. |
create_kind(name, fields, statuses) | Declare a structured domain, once (like a table). |
get_kind(name) | Read a domain's form before writing items. |
event(kind, name, note, fields?) | Log a change/what-happened on an item (its timeline). |
link(from_node_id, to_node_id, edge_type) | Assert a connection between two memories you already have. |
meta_type routes the free path: knowledge vs self-model.
Knowledge — remember(content) with the default meta_type (fact /
observation). Your job here is to record what happened: log the observation,
chat_turn the dialogue message. The backend consolidates those episodes into
candidate claims on its own — asynchronously, after the fact. You do NOT
build the graph, hand-extract claims, or paste pre-built walls of facts. The
call logs an episode — it returns an episode marker (episode_logged,
consolidation: scheduled), not a node id — so the fact becomes a candidate
claim once consolidation runs, not the instant you call. Your visibility
(default shared) is carried onto the resulting claims.
Self-model — remember(content, meta_type=identity|principle|skill).
These are your declarations about yourself, not facts to distil. They bypass
the episode/consolidation pipeline and land directly as a node, preserving
meta_type / visibility / edges / relevant_until, and load as
agent_init bootstrap anchors. This is the path the Record what you change
about yourself example above uses (meta_type="skill"). It writes the node
immediately — recall it the same session.
The structured-item path — remember(kind, name, fields) → a workspace item —
is unchanged; everything in The structure decision below still applies to it.
Connecting memories. ConPort auto-links every new memory to its nearest
existing ones by meaning — you get a connected graph for free. On the
knowledge path you never hand-build edges: consolidation builds the
predicate edges between distilled claims (an edges=… argument there is ignored
gracefully). You assert a connection yourself only on the self-model
(identity/principle/skill) direct-write path, or between two
structured/workspace memories — when the relationship is one ConPort wouldn't
infer from similarity ("derived from", "competing view", "supersedes"), via
remember(content, meta_type=…, edges=[…]) or
link(from_node_id, to_node_id, edge_type). The edge-type vocabulary is a
fixed, curated set of 12 (6 structural + 6 domain) — pick the closest; an
unrecognized type returns invalid_edge_type. Malformed edges come back as
structured edge_errors, never a silent drop. → Deep detail (the full
vocabulary, edge properties grounding, why ground edges, typed refs between
items): live docs agents/edges-and-refs.
Recall returns a packet, not a flat list. recall(query) seeds by relevance,
walks one adaptive graph hop, and assembles a deterministic, token-bounded
packet: facts grouped by the entity they describe, each fact carrying
status, confidence, tentative, provenance (source-episode snippets) and
conflicts. Read it by entity, then by status: active = trusted,
tentative (a candidate claim) = provisional — treat with caution, conflicts
= competing claims with both sides kept — reconcile, provenance = the episodes
the fact was drawn from. A flat_results list rides along for callers that
haven't adopted the packet. include_candidate (default true; set false to
drop tentative claims) and budget (default 1500 token budget) tune it.
Superseded nodes are excluded by default (pass scope.include_superseded=true to
audit history); intent and relevant_until are optional refinements. → Deep
detail: live docs agents/recall-packet, agents/recall-before-act,
agents/intent-api.
The deciding rule. Can the links between entities be derived mechanically
from the item's own fields? If yes → projectional mode: write a flat record,
mark field roles, ignore the graph (the projector derives edges). If the links
require your judgment and accrete over time across sessions → graph mode:
assert edges explicitly with link.
Three anti-blob rules:
Don't serialize structure into prose. If a piece of knowledge has
distinct facets (a source, a conclusion, a link to a question), it is a
node with edges — not a string stuffed into a body field. Only genuinely
facet-less text belongs in body.
Timeline is not the graph. A raw measurement or event belongs in the
item's timeline via event. A judgment distilled from measurements (a
score, a rating, a trend assessment) is an attribute set by you on the
item — not a separate node per measurement.
conclusion and open_question are first-class node kinds, not fields
of a topic. If they were fields, the topic→question→topic recursion that
lets research accrete over time cannot form.
→ Deep detail (field-role table, kind list, edge types, the research recursion,
worked examples): live docs agents/modes.
Free thought / observation / principle → remember(content).
remember("the user prefers a warm, dry climate")
A thing you'll filter / compare / update over time, and there'll be more like it (cities you score, series you rate, research topics) → a kind:
create_kind("series", fields=[title, rating, imdb, tags, verdict], statuses=[watching, watched, wishlist, dropped]) — once.get_kind("series") — use the real fields + a valid status, don't invent them.remember(kind="series", name="Severance", fields={rating: 2, status: "dropped", verdict: "weak"})
event:event(kind="series", name="Severance", note="rewatched the finale, still a 2")
Rules that keep domains clean (skip them and you fragment — serial +
watchlist + interests for one thing, the same item filed twice):
series, not serial/shows). Check
agent_init.collections / get_kind first; reuse, don't reinvent.
remember(kind=…) into an undeclared kind fails with unknown_kind —
create_kind first.status field. Enumerate them exhaustively with
entity_list("series", attrs_filter={status:"wishlist"}) (exact, every match);
recall(..., scope={kind:"series"}) is a fuzzy/ranked slice, not the complete set.event.create_kind("source", …, refs={topic:"topic"}). The ref field is
validated on write (unknown_ref if the target doesn't exist). → Deep detail
(single vs multi refs, get_referrers): live docs agents/edges-and-refs.entity_delete(kind, name) — fix it, don't leave a duplicate.status is validated against the kind's statuses; unknown fields are accepted
(the schema grows). recall finds items by content; events are an item's
timeline (read with event_query, not recall).
remember)| Visibility | Who sees it | Use |
|---|---|---|
private | Only you | Identity, principles, scratch. Identity/principle are forced private. |
shared | All your owner's agents | Default for facts/observations. |
broadcast | All, always loaded | Crystallized skills, core user facts. |
remember("...", visibility="broadcast") # default 'shared'
"API key starts with 0a73…" · Good: "API key is in $API_KEY env var"Beyond the core verbs, named operations for specific needs. Reach for these when
you need them; fetch the live-docs agents/aux-operations page for the full
semantics before acting — the error shapes and provenance rules matter.
agent_feedback(agent_uuid, title, body) — file a bug report, friction
note, or suggestion. Writes a row to your feedback journal which the ConPort
maintainer reads and triages. Use when you hit a bug, limitation, or have a
concrete suggestion about the agent API. Returns {"id": <int>, "status": "open"}. This is NOT for storing your own memory (remember is for that).agent_feedback_list(status?, limit?) — read the open feedback journal
(status defaults to 'open').chat_turn(role, text) — record each message of a live dialogue. The
backend consolidates the buffer into facts on its own; extraction_signal: true (buffer ≥ 10) in the response is informational — you don't act on it.extract_thread / extract_into — DEPRECATED no-ops, do not call.
Manual extraction is retired: the backend distills logged episodes
(remember / chat_turn) into facts with provenance and edges automatically.
These tools remain on the surface for compatibility but do nothing and return a
deprecation notice. Just log; never hand-extract.entity_list(kind, attrs_filter?, limit?) — enumerate the actual members
of a kind (exact, exhaustive, owner-scoped). The right verb for "give me ALL
items of kind X" — not get_kind (form + count only), not
recall(scope={kind}) (fuzzy slice), not get_referrers (inverse refs).event_query(entity_id, …) — read an item's timeline (events aren't in recall).entity_delete(kind, name) — soft-delete an item; events survive, re-remember resurrects.get_referrers(kind, name) — items that reference this one by their declared ref.graph_stats() — size/shape of YOUR recall corpus (incl. superseded_count).node_forget(node_id) — forget your own noise node (irreversible from the agent surface; prefer supersedes-consolidation when a replacement exists).node_mute(node_id) / node_unmute(node_id) — per-viewer hide (reversible; someone else's shared/broadcast noise).promote_skill(community_id, content) — crystallize a mature_community into a broadcast skill node.run_start(skill_name, params?) → run_finish(run_id, status, outputs?) — wrap a multi-step skill execution.If a write returns error: "mcp_payload_contaminated", a literal MCP tool-call
fragment (<parameter …>, <invoke …>, </invoke>, <function_calls>,
antml:*) leaked into a string field — a client XML glitch. The response lists
the contaminated fields. Recovery: re-issue with them cleaned. The bad write
did not land.
agent_init done? bootstrap_state checked?collections — reusing existing domains, not reinventing?recent_self_changes before touching your own skills/config?recall BEFORE answering?recall + recent_self_changes BEFORE inspecting/rebuilding?remembered it as a self-change?create_kind once + get_kind before writing items?remember(kind,…); what-happened → event; never list-as-item?fact/observation) → remember(content) (logs an episode; backend distills it into claims — not an instant fact)?remember(content, meta_type=identity\|principle\|skill) (direct anchored write, preserves meta_type/visibility/edges — not consolidated)?extract_thread / extract_into are retired no-ops)?mature_communities → reviewed, promote or skip?The deep, situational reference lives at https://conport.app/agents and is
the single source of truth. Before acting on a deep topic, fetch the relevant
page. Index: https://conport.app/agents/llms.txt. (No web fetch? Use the
conport-agent docs <topic> CLI.)
| Topic | Page |
|---|---|
| Intent API v4 (full bootstrap + verbs + structure semantics) | agents/intent-api |
| The recall packet (shape + how to read status/tentative/conflicts/provenance) | agents/recall-packet |
Recall-before-act (deep) + visibility + relevant_until + intent | agents/recall-before-act |
| Edges, the 12-type vocabulary, edge grounding, typed refs | agents/edges-and-refs |
Aux operations (chat intake, extract_into, enumeration, lifecycle, runs) | agents/aux-operations |
| Workspace graph modes (field-role table, kind list, edge types, worked examples) | agents/modes |
v15.21.0 | Thinned skill — always-on discipline here, deep reference routed to live docs at conport.app/agents | recall-before-act gate (never rebuild a blank-looking surface) + self-change recording + recent_self_changes anchor | Intent API (v4): 6 verbs (create_kind, get_kind, remember, link, event, recall) + typed refs + aux ops (chat_turn, entity_list, entity_delete, event_query, graph_stats, node_forget, node_mute, node_unmute, promote_skill, run_start/finish) + feedback/feedback_list (file + read agent bug/friction reports in a local journal the maintainer triages) | Agent expresses intent; ConPort owns storage | remember routes by meta_type: knowledge (fact/observation) logs an episode → backend consolidates into claims asynchronously; self-model (identity/principle/skill) writes a direct anchored node (preserves meta_type/visibility/edges, loads as agent_init anchor); extract_thread/extract_into retired no-ops | recall returns a graph-augmented packet — facts grouped by entity with status/confidence/tentative/provenance/conflicts (1-hop graph traversal, relevance-primary ranking, token-budgeted), flat_results for compat; spans cognition + structured items, superseded excluded by default; relevant_until validity horizon; 12 edge types (6 structural + 6 domain) with optional grounding properties | workspace↔graph two modes (field_roles projection + explicit entity-edge graph mode + workspace-graph/topic-state/project-record reads)
npx claudepluginhub shaurgon/conport-plugin --plugin conportCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.