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 manifest mapping reference names one exact mapping: manifest:<connector>#schema_mappings/<key>. The shorter manifest:<connector> form is a convenience only for a manifest containing exactly one schema_mappings entry. 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.

sequenceDiagram
    participant EG as EG change set
    participant SDK as GovernedWriteBack
    participant Auth as AuthorizationVerifier
    participant Source as WriteBackTransport
    SDK->>Source: read_current
    SDK->>SDK: compare base version and field scope
    SDK->>Auth: verify exact digest/mode/ref/policy
    SDK->>Source: compare-and-apply(idempotency key)
    alt acknowledgement certain
        Source-->>SDK: source observation
    else possible effect
        Source--xSDK: outcome uncertain
        SDK->>Source: reconcile key + source version
        Source-->>SDK: applied / no effect / still uncertain
    end
    SDK-->>EG: source observations 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.