Skip to content

Extension ports

Five typed protocols keep the SDK open. An implementation ships in its own distribution and declares an entry point; nothing in the SDK changes.

Port Module Entry-point group Reference implementation
SourceAdapter ports.source_adapter agent_connector_sdk.source_adapters mcp_tool
ArtifactKind ports.artifact_kind agent_connector_sdk.artifact_kinds tools, skills, prompts, resources
Transport ports.transport agent_connector_sdk.transports mcp
Sink ports.sink agent_connector_sdk.sinks epistemic_graph
WriteBackPort ports.writeback generated connector binding GovernedWriteBack + fixture transport

SourceAdapter

Method Contract
describe() capabilities, without I/O
discover(session) verify the live source contract; required before extraction
extract(session, checkpoint) one page and the provider checkpoint that resumes after it
reconcile(session, known_ids) ids missing from the source and unknown to the sink

The mcp_tool adapter extracts through a connector's MCP tool as a preset describes it (pagination, a since-watermark), requires the pinned tool_schema_sha256, and rejects records that do not match the preset. The watermark advances only when a sweep is exhausted.

pagination Parameters Next page
none none
cursor cursor_param; cursor_path or cursor_record_field; optional more_path the token, until it is absent or repeats
page page_param, page_size_param, page_size, start_page; page_kind number (the spelling page is rejected) the next page index, until a page is shorter than page_size
offset page_param (the offset), page_size_param, page_size; page_kind offset the offset plus the records returned, until a page is shorter than page_size

A page_kind that does not apply to the mode is rejected. A preset with an empty id_field is rejected: a sweep without record identity, such as a SQL table sweep, belongs to a data-platform source adapter.

The package validator requires the current fingerprint algorithm and rejects a tool_schema_sha256 derived from an empty input schema. The pin binds both input and output schemas. An action selected by a preset must appear in the action argument's JSON Schema enum (or its single-value const form). Certify from the server's tools/list with connector-certify.

ArtifactKind

Prompt packs read both prompts/list and prompts/get through the same MCP session. Each prompt entry retains its listing definition, the argument contract, and the complete ordered MCP result, including roles, typed multimodal content, resource references and response metadata. The capture records that it is a rendered prompt with no supplied arguments; it does not claim to be a template or a system prompt. Changed message content changes the pack digest.

Pack provisioning has no configured prompt-argument input. A prompt with required arguments fails closed before retrieval; no values are invented. Optional arguments are omitted so the server may apply its defaults. Empty, incomplete or malformed results are rejected. Aggregate prompt capture uses the existing 16 MiB response-byte limit and fails before a pack can be acknowledged.

Sink

Method Contract
submit(batch) commit a record batch; the receipt is returned only after commit
source_status(connector, stream) read EG's sole durable checkpoint and live-set authority
import_pack(pack) import a content pack keyed by its digest
readiness() whether this sink can commit right now, without side effects -- returns a SinkReadiness(ready, reason); reason is set whenever ready is False and must never carry a credential or other secret value

The connector-sync runner's /health/ready (see Connector sync "Health") calls readiness() directly, bounded by a short timeout, so a sink implementation must answer it without a side effect and should not assume it is ever skipped. epistemic_graph requires a verified client and a live ConnectorPack authority resolver at construction; the testing kit's InMemorySink always reports ready.

SourceIngestionRequest is imported from epistemic_graph.generated.source_ingestion; the SDK does not define an alias, parallel DTO, or digest. Its generated canonical_digest() binds raw records, provenance, exact per-record mapping references, provider checkpoint, and expected previous checkpoint. The runner sends it through generated send_source_ingest with a stable idempotency key and advances the checkpoint only from the matching generated receipt. EG compare-and-swaps the expected position atomically with the commit.

A mapping reference names one exact mapping the connector declares at connector://resources: connector:<connector>#mappings/<key>. A relation reference is connector:<connector>#relations/<resource>/<relation>. The shorter connector:<connector> form is a convenience only for a declaration holding exactly one mapping. Package validation fails closed when the short form is ambiguous or an explicit fragment names no declared key. Other reference schemes are rejected at the EG boundary.

Lifecycle mode is explicit on every page. full is a non-authoritative load, delta may carry provider-declared withdrawals, and reconcile carries the complete authoritative live-id and relationship sets so EG derives removals atomically. Empty authoritative full/reconcile commits require a non-empty descriptor approval and the verified server's source:reconcile-empty scope; the SDK cannot grant that capability. Provider content hashes are optional and are echoed, never invented. An unchanged empty delta is not submitted as a fake checkpoint advance.

SourceIngest is the one durable operation; SQL batches and pre-mapped change envelopes are not substitutes. EG resolves the manifest mapping, admits raw evidence, deduplicates, writes provenance/outbox state, and advances the checkpoint before returning SourceIngestionReceipt. The SDK verifies that the receipt's batch digest, mode, and accepted checkpoint bind the submitted request.

Runner ports

The connector-sync runner adds two runtime ports, described in Connector sync: ConnectorRegistry (ports.connector_registry) and ChangeSource (ports.change_source). Source checkpoint and live-set state are read directly from EG's generated SourceIngestStatus contract and are never persisted by the SDK.

WriteBackPort

WriteBackPort is the D18 source-I/O boundary. It reads the current source version, produces a side-effect-free field diff, rejects an optimistic conflict before mutation, verifies an exact durable authorization decision, applies under an idempotency key, and reconciles every possible effect before retry. The only authorization modes are proposal_approval, standing_policy, and manual_trigger; a mode or reference supplied by a caller grants nothing by itself.

Write-back sequence

GovernedWriteBack reads the source's current state (read_current), compares the base version and field scope, then has AuthorizationVerifier verify the exact digest/mode/ref/policy before calling the WriteBackTransport's compare-and-apply with an idempotency key. When acknowledgement is certain, the transport returns a source observation directly. When the effect is only possible (an ambiguous response), the transport reports the outcome as uncertain and GovernedWriteBack reconciles using the key and source version, which resolves to applied, no-effect, or still-uncertain. Either way, the final source observations go back to EG's change set for durable receipts.

The canonical models come from epistemic_graph.generated.write_back. SourceChangeSet.canonical_digest() and .patch_digest() implement EG's framed MessagePack digest contract; the SDK neither reconstructs those schemas nor implements a parallel digest. EG alone creates and persists WriteBackReceipt and ReconciliationReceipt. No live vendor write-back is enabled by the reference in-memory transport.

Activation

load_extension(group, name, policy=...) loads an extension only when the activation policy certifies its exact group, name, distribution and version. There is no permissive default. sdk_reference_extensions() certifies the implementations this SDK version ships. Two distributions declaring the same name in a group is an error.

Contract ownership

Source ingestion, ConnectorPack, and WriteBack request/result models come directly from epistemic_graph.generated. The SDK owns only connector authoring, capture, transport, and extraction shapes; it defines no parallel EG DTO or digest.

Current-plan values

agent_connector_sdk.current_plan exports CurrentPlanRequest, PlanItem, CurrentPlanSnapshot and CurrentPlanRead. The request selects only a run ID. Snapshots carry a nonnegative revision, UTC observation and expiry, and ordered immutable items. An available read contains a snapshot, which can have no items. An unavailable read has no snapshot. All models reject unknown fields and coercion. Use model_validate_json for JSON input and model_dump_json for output.

The models validate shape and the timestamp interval. They do not establish caller authority, run ownership, current freshness or a live lease. The serving owner must verify those conditions before returning an available read.