Connector — адаптер между внутренней архитектурой AI-системы и конкретной внешней системой: Gmail, Slack, CRM, Google Drive, Notion, database, ERP, GitHub, календарь, файловое хранилище или proprietary API.
№01 MCP стандартизирует, как capabilities/data могут экспонироваться AI-клиенту; №54 реализует конкретный adapter/auth/API mapping к внешней системе. №12 Tools — callable operations; connector объединяет операции одного provider/system и скрывает vendor details. №51 Permissions & Secrets владеет identity/scopes/credentials; connector использует credential_ref, но не становится secret manager. №55 Data Ingestion & Sync владеет recurring pull/push/change-tracking pipelines; connector только умеет читать/писать конкретный источник. №42 Events владеет semantics событий; connector может принять webhook и нормализовать его. №65 Model Gateway — отдельная abstraction для model providers, не business connectors.
Prerequisites: №01 MCP, №12 Tools & Function Calling, №42 Events, №46 Observability, №48 Policies, №50 Contracts, №51 Permissions & Secrets, №52 Security. Forward references: №55 Ingestion & Sync, №57 Queues/Workers, №59 Broker, №61 Provenance, №63 Retry/Circuit Breakers, №64 Rate Limits/Budgets.
REQUEST-TIME: YES — direct read/write tool calls. CONTROL PLANE: YES — connector registry, auth status, scopes, versions, health, mappings. DATA PLANE: YES — external objects/results/events. OFFLINE: YES — contract tests, schema drift checks, credential audits, sync validation.
Success: canonical request deterministically maps to provider action and canonical result. Retryable: timeout, 5xx, selected throttling. Permanent: invalid scope, revoked auth, unsupported object, deterministic 4xx, mapping error. Idempotency: write calls use provider idempotency or local operation key. Persist: connector_id, tenant, credential_ref, external IDs, cursor/page token where needed, mapping version. Trace: logical capability + provider operation + sanitized response metadata.
№54 не владеет long-running synchronization, queue infrastructure, connector credentials lifecycle, global policy, business workflow, provenance system или generic MCP protocol. Она владеет THE ADAPTER BETWEEN A STABLE INTERNAL CAPABILITY AND A SPECIFIC EXTERNAL SYSTEM.
create_draft(), read_document(), create_issue().
Это узкая callable capability.
GmailConnector содержит read/search/draft/send mapping, auth context, provider IDs, pagination, errors.
Один из способов стандартизированно представить tools/resources клиенту. MCP не отменяет provider adapter.
connector_id, provider, tenant, environment, status, capability list.
Получает scoped credential через №51; raw secret не хранится в agent logic.
create_draft → конкретный endpoint/request semantics.
Provider-specific response превращается в stable internal model.
Page token, offset, next link скрыты за canonical iterator/result contract.
429/401/vendor-specific codes → TRANSIENT/RATE_LIMITED/PERMISSION/etc.
Retry-after, backoff, quotas, request budget, circuit hooks.
provider object IDs ↔ canonical resource refs.
Logical call, provider method, status, latency, sanitized metadata.
Нужна capability:
search_messages(query, folder, limit)
Canonical contract.
Преобразует query, folders, limits, auth, pagination, provider syntax.
Возвращает canonical objects.
Gmail / Outlook / custom mail API со своими endpoints, IDs, fields, errors.
{
"contract": "message.v1",
"message_ref": "msg://tenant_A/...",
"connector_id": "mail:brand_A",
"external_id": "provider-id",
"thread_ref": "thread://...",
"sender": {
"address": "...",
"display_name": "..."
},
"recipients": [...],
"subject": "...",
"body_ref": "artifact://...",
"received_at": "...",
"labels": ["inbox"],
"provenance": {
"provider": "gmail"
}
}Canonical model должен покрывать shared semantics ваших use cases.
Provider-specific поля можно хранить отдельно:
provider_metadata;Не пытайтесь сразу создать «идеальную универсальную CRM/email/storage ontology».
credential_ref, scopes и auth status. Refresh token/password/private key не должны гулять через model context или Tool arguments.{
"connector_id": "mail:brand_A",
"provider": "gmail",
"tenant_id": "brand_A",
"status": "READY",
"environment": "prod",
"credential_ref": "secret://...",
"capabilities": {
"messages.search": true,
"messages.read": true,
"drafts.create": true,
"messages.send": false
},
"scopes": [
"mail.read",
"draft.create"
],
"adapter_version": "2.3.1"
}Router/Tool Engine может заранее знать:
Это не Agent Registry №44: там регистрируются agents; здесь — external integrations.
Каждый call имеет explicit limit / page size / result budget.
Возвращать canonical next_cursor, внутри которого connector хранит/provider page token semantics.
Agent/workflow решает, нужно ли продолжать, исходя из coverage/budget.
| Operation class | Examples | Default controls |
|---|---|---|
| Read-only | Search, read object, list metadata. | Tenant/scope check, bounded results, provenance. |
| Draft / reversible write | Create draft, update internal note. | Permission + policy + idempotency + readback. |
| External side effect | Send email, publish, create customer-facing object. | Strong policy, exact payload, approval where required, idempotency, readback. |
| Destructive / privileged | Delete, change roles, admin configuration. | Usually separate narrow capability; high-risk gate/HITL. |
connector.execute(method, url, body) доступным модели. Это превращает narrow integration в raw API tunnel.doc://tenant_A/123, msg://tenant_A/456.
Внутри mapping хранится provider + connector + external_id.
Одинаковый external_id может существовать в разных tenants/connectors. Migration provider A→B не должна ломать весь внутренний graph.
canonical_ref ↓ connector_id + tenant_id + object_type ↓ external_id ↓ provider API Never: external_id alone → global access
| Provider symptom | Canonical class | Typical action |
|---|---|---|
| 401 token expired | AUTH_EXPIRED / RETRYABLE_AFTER_REFRESH | Refresh/re-resolve credential once, then retry bounded. |
| 403 missing scope | PERMISSION_DENIED | Do not retry unchanged; reconnect/consent/admin path. |
| 404 missing object | NOT_FOUND | Caller decides clarify/fallback/terminal. |
| 409 version conflict | CONFLICT | Reload current object/state before retry. |
| 429 | RATE_LIMITED | Respect Retry-After/backoff/budget. |
| 5xx / timeout | TRANSIENT | Bounded retry/circuit breaker. |
| Vendor field/schema changed | ADAPTER_MAPPING_ERROR | Fail safely; alert/regression test; connector update. |
Retry-After, per-user quota, batch size, request limits.
Возвращает RATE_LIMITED + retry metadata и может применять bounded backoff.
№64 позже отвечает за cross-provider quotas/budgets/admission control.
Каждый connector имеет version/build/hash.
Явно фиксировать provider API/version where applicable.
Canonical capability schema version развивается отдельно.
Provider change ideally чинится в connector, а не в agent prompts.
Provider content остаётся untrusted/provenanced data.
Raw credential stays inside trusted client/runtime.
External object ID validated against connector/tenant context.
Write side effect проходит policy/permission/approval before provider call.
messages.search / drafts.create / crm.contact.read.
connector_id, tenant, provider, adapter version.
sanitized endpoint/method/status, request id.
network + provider + adapter time.
attempt count/backoff/rate-limit state.
items returned/written, pagination cursor, bytes where useful.
credential_ref/version/scope outcome, never raw token.
Link to task/tool/event/workflow trace.
Canonical request → expected vendor request; vendor response/error → canonical result/error.
Recorded/fixture schemas detect provider response drift and pagination/error behavior.
Auth, scopes, read/write, idempotency, webhooks, rate limits against non-prod account.
Wrong tenant/object/scope/expired auth is denied predictably.
Timeout/429/5xx do not create duplicate writes.
Every provider-specific production failure becomes permanent fixture/test.
«Прочитай страницу объектов», «получи item», «создай draft», «нормализуй webhook».
Он знает provider API.
«Обойди весь dataset», «сохрани checkpoint», «догоняй изменения», «deduplicate/upsert/delete stale records».
Он использует connector как source adapter.
Successful connector calls by capability/provider.
p50/p95 provider+adapter latency by operation.
Share of calls throttled and retry-after distribution.
Expired/revoked/missing-scope rate.
Vendor response/schema changes causing adapter failures.
Duplicate writes after retries. Target: zero.
% desired operations implemented and tested per connector.
Provider changes detected before user-facing failure.
connectors/ ├── registry.py ├── base.py ├── errors.py ├── models.py ├── gmail/ │ ├── client.py │ ├── mapping.py │ ├── tools.py │ └── tests/ ├── drive/ │ ├── client.py │ ├── mapping.py │ ├── tools.py │ └── tests/ └── fixtures/ Connector: id provider tenant credential_ref capabilities adapter_version Tool Engine: capability -> connector -> provider API
Не писать собственную «Zapier-платформу», пока не появится реальная потребность в десятках heterogeneous connectors.
| Вопрос | Ответ |
|---|---|
| Стоит ли реализовывать? | Только для реально нужных external systems. |
| Separate Component? | NO по архитектурному плану. Connector — adapter family внутри Tool / Action Engine. |
| Минимум 80% ценности? | Stable capability contract, auth bridge, normalization, canonical errors, pagination, tenant binding, idempotency, tests. |
| Когда overkill? | Строить generic integration DSL, visual mapper и hundreds-provider framework до появления нескольких реальных integrations. |
| Trigger? | Нужно читать/писать конкретную внешнюю систему, скрывая vendor API details от agent/core. |
| Как измерить uplift? | Integration defect rate, provider drift isolation, success/latency, auth failures, duplicate writes, time to add capability. |
| Можно ли rule/tool/code вместо LLM-agent? | Да. Connector — deterministic code adapter. LLM может формировать intent, но не должен выполнять protocol mapping. |
Agent works with stable capabilities, not endpoints/query syntax.
Mapping/auth/pagination/errors inside; business workflow outside.
Model sees connector/capability metadata, not raw auth material.
External IDs always scoped by tenant+connector+object type.
Orchestrator reacts to typed failure classes, not vendor strings.
Unavailable operations должны быть видны до call.
Retry must not duplicate external side effect.
Recurring ingestion/checkpoints belong to №55.
API changes should mostly result in connector changes, not core rewrites.
USER / AGENT / WORKFLOW
↓
INTERNAL CAPABILITY
messages.search
draft.create
document.read
issue.create
↓
TOOL CONTRACT
↓
POLICY + PERMISSION
↓
CONNECTOR REGISTRY
↓
SELECT:
connector_id + tenant + provider
↓
CONNECTOR ADAPTER
├─ credential_ref
├─ auth/token handling
├─ vendor request mapping
├─ pagination
├─ external ID mapping
├─ rate-limit handling
├─ error normalization
└─ response normalization
↓
EXTERNAL API / SAAS / DB / STORAGE
↓
CANONICAL RESULT / CANONICAL ERROR
↓
PROVENANCE + TRACE
↓
AGENT / WORKFLOW
FOR RECURRING DATA MOVEMENT:
CONNECTOR
↓
№55 DATA INGESTION & SYNC
↓
checkpoints / incremental updates / backfill / dedupe
CORE PRINCIPLE:
A CONNECTOR SHOULD MAKE
THE EXTERNAL SYSTEM LOOK BORING.
THE AGENT SHOULD THINK:
"READ DOCUMENT"
NOT:
"CALL PROVIDER X ENDPOINT Y
WITH VERSION Z AND PAGE TOKEN Q".
A. Related ECC ideas. Context-as-cache, scoped memory, lifecycle hooks, selective capabilities, feature flags, deterministic enforcement, provider-neutral adapters and eval-gated learning are applied only where relevant to №54 Connectors.
B–E. Existing boundary and placement. The existing conceptual boundary, class PRODUCTION, default CONDITIONAL and owner Tool / Action Engine remain authoritative. Runtime/control/data/offline placement is unchanged; durable state stays outside model context.
F–H. Hooks and contracts. Use bounded PRE_MODEL/POST_MODEL, PRE_TOOL/POST_TOOL, CHECKPOINT and TASK_COMPLETED events as applicable. Illustrative fields and canonical contracts are defined in NEW_CONTRACTS_SPEC.md; no universal schema is implied.
I–J. Security and evaluation. Host-side schema, permission, secret, budget, idempotency and audit checks take precedence over LLM output. Optional mechanisms require a feature flag and WITH/WITHOUT ablation; measure quality, acceptance, correction, latency, cost, escalations and severe errors.
K–L. Task profiles and cross-references. A TaskProfile selects the relevant skill, tool/context slice, memory scope and enforcement profile independently from FAST/STANDARD/DEEP. See cross-reference map, hook spec and ablation plan. Provider adapters remain outside the core.