Connector SDK
The Connector SDK is one shape for everything that plugs into Fibric: SaaS APIs, hardware gateways, and AI operators all ship as connectors, declared with defineConnector(), built from tool() definitions, authenticated by declaration. You write the honest call to the target system; the runtime supplies per-tenant credentials, rate-limited HTTP, idempotency, and tracing, and the governed executor stands in front of every side effect. This page is the map of the Build section.
Philosophy
Two design decisions explain everything else in the SDK.
Capability, then connector. Operators never name vendors. An operator requires orders.hold; configuration binds that capability to whichever connector provides it. Your connector's job is to provide capabilities well, and the reward is that any operator asking for them works against your connector without either side knowing the other exists. Swapping Kustomer for Zendesk under a running operator is a binding change, not a rewrite, and that indirection is a platform tenet, not a convention.
Everything is MCP. A connector is an MCP server: its tools are MCP tools, its events feed the envelope stream, and the kernel speaks the same protocol to a helpdesk, a BACnet gateway, and an operator pack. The kernel hardcodes no integration. What Fibric adds on top of the protocol is the governance: a deterministic executor that evaluates every side-effecting call against a fail-closed trust policy, serializes per entity, dedupes on idempotency keys, and writes a receipt.
No retry helpers, no credential storage, no policy hooks. Retries and rate limits belong to the runtime's HTTP client, secrets to the tenant's secret store, policy to the executor. A connector that reimplements any of these is harder to review and no safer. Keep the handler to one honest call.
Install
The SDK is a TypeScript package. It has no runtime dependencies of its own; the helpers return plain data the platform reads.
npm install @fibric/connector-sdk
# scaffold a connector project with fixtures and CI wiring
fibric init my-connector --template connector
The three exports
The whole public surface of @fibric/connector-sdk is three exports and their types. Everything on the following pages is detail on these.
| Export | Takes | Returns | Job |
|---|---|---|---|
defineConnector() | ConnectorDef | ConnectorDef | Declares the connector: id, version, category, auth, tools, events, probe. The def is the whole contract; the platform reads it to register capabilities and publish the listing. |
tool() | ToolDef | ToolDef | Declares one capability: an optional input validator, the sideEffecting flag that decides its execution path, and the handler. |
oauth2(), apiKey(), none() | options | AuthSchema | Declares how credentials are obtained. Shape only; the runtime resolves the material per tenant from the secret store at call time. |
The division of labor between your code and the runtime is fixed, and it is worth internalizing before writing a handler:
| Concern | Owner |
|---|---|
| The call to the target system | Your handler |
| Argument validation | Your input function (Zod in practice) |
| Credentials, storage and injection | Runtime (tenant secret store, ctx.http) |
| Rate limiting and retries | Runtime (ctx.http) |
| Policy, single-flight, idempotency dedup | Deterministic executor |
| Receipts and tracing | Kernel |
The Build section
The section is ordered the way a connector gets built: declare it, wire its tools and auth, package it if it is an operator, test it, publish it.
The full ConnectorDef reference: every field with its type from source, the ConnectorCtx, a complete worked helpdesk connector, and the register-to-act lifecycle.
Tools & authThe tool() helper: input validation, what sideEffecting really does, idempotency wiring, every auth kind, secret handling rules, and sandbox vs live credentials.
Operator packsPackaging operators: the prompt contract, capability requirements, guardrail defaults, pricing metadata, and how packs version and appear in the marketplace.
Testing connectorsThe fibric dev harness, the envelope fixture format, asserting on proposed plans without executing, trust-tier simulation, and a GitHub Actions recipe.
Publishing to the marketplaceListing metadata field by field, the early-access review process, pricing your listing, and the proposed to early-access to live lifecycle.
End to end in one file
A compact but complete connector: one read, one governed write, one event stream, a probe. Everything the marketplace, the executor, and the dev harness need is in this def.
import { defineConnector, tool, apiKey } from '@fibric/connector-sdk';
export default defineConnector({
id: 'cn-brightdesk',
version: '1.0.0',
category: 'comms',
auth: apiKey(), // shape only; the runtime holds the key
tools: {
'conversation.read': tool({
input: (a) => ({ conversation_id: String((a as any).conversation_id) }),
handler: (ctx, args) => {
ctx.log('read', { id: args.conversation_id });
return { id: args.conversation_id, status: 'open' };
},
}),
'note.write': tool({
sideEffecting: true, // executor + trust policy + idempotency
input: (a) => {
const x = a as { conversation_id?: unknown; body?: unknown };
if (typeof x.conversation_id !== 'string' || typeof x.body !== 'string')
throw new Error('conversation_id and body: string required');
return { conversation_id: x.conversation_id, body: x.body };
},
handler: async (ctx, args) => ({ ok: true }),
}),
},
events: {
'conversation.created': { kind: 'webhook', topic: 'conversations' },
},
probe: () => ({ status: 'ok' }),
});
From here: fibric dev runs it against the local kernel, fibric dev replay pushes recorded envelopes through it, and fibric publish submits it for review. The read is callable by any operator sensing state; the write is reachable only through a validated ExecutionPlan, which is the entire point.
The same shape for hardware
Nothing in the SDK is SaaS-specific, and the marketplace's building-systems catalog is built from the same def shape as the helpdesk example above. A BACnet gateway connector differs from Brightdesk in exactly three ways: category hardware, an auth kind suited to the endpoint (basic or mtls, declared as a literal AuthSchema since only the three common kinds have helpers), and events that are poll rather than webhook, because a building does not call you back.
export default defineConnector({
id: 'cn-acme-bms',
version: '0.4.0',
category: 'hardware',
auth: { kind: 'basic' }, // no helper needed; the shape is the API
tools: {
'hvac.zone.read': tool({ handler: readZone }),
'hvac.setpoint': tool({ sideEffecting: true, input: SetpointArgs, handler: writeSetpoint }),
},
events: {
'hvac.zone.fault': { kind: 'poll' }, // pull, not push
},
probe: (ctx) => ({ status: 'ok', metric: { label: 'zones online', value: 48 } }),
});
Everything downstream is identical: a proposed hvac.setpoint passes the same trust evaluation, holds the same per-zone single-flight lock, and leaves the same receipt as a proposed note.write. That a thermostat write and a helpdesk note flow through identical machinery is the point of the envelope, and of the SDK.
Keep going
- defineConnector(): start here for the full API surface.
- Connectors: the concept page, if you want the why before the how.
- Governance & trust: what happens to a side-effecting call after it leaves your handler.
- CLI reference:
init,dev,connectors test, andpublishin full.