> Source: https://wexa.ai/docs/connectors/provision-connector

# provision-connector

[Can be held for approval](/docs/sdks-and-apis/how-every-tool-call-works#lifecycle-and-governance)

Provision a credential-free connector in this project, which creates one skill per action it supports. Idempotent: provisioning one that already exists returns the existing connector and creates nothing. Needs the `fabric:skill.write` grant.

The shape of `result` for `provision-connector` is not recorded here: it was not captured against a live deployment. Call it once and read what comes back rather than assuming a shape.

**Provision a connector**

**Wexa MCP server**

```bash
curl -sS -X POST https://fabric.wexa.ai/mcp/$FABRIC_PROJECT_ID \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "Mcp-Session-Id: $MCP_SESSION_ID" \
  -H "content-type: application/json" -H "accept: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"provision-connector","arguments":{"category":"duckduckgo"}}}'
```

**REST API**

```bash
curl -sS https://fabric.wexa.ai/v1/provision-connector \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "content-type: application/json" \
  -d '{"category":"duckduckgo"}'
```

**TypeScript SDK**

```ts
import { Fabric } from '@wexa-fabric/sdk'

const fabric = new Fabric()
const result = await fabric.provisionConnector({ category: 'duckduckgo' })
```

**Python SDK**

```python
from wexa import Fabric

fabric = Fabric()
out = fabric.provision_connector(category="duckduckgo")
```

## Parameters

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `category` | one of 23 | Required | The connector to provision, such as `duckduckgo`, `hackernews` or `tables`. Only a connector that needs no credentials is accepted: `ask_a_website`, `bouncer`, `connector_catalog`, `content_creator`, `coworker_long_term_memory`, `coworker_trigger`, `duckduckgo`, `file_generator`, `hackernews`, `http`, `knowledge_base`, `master`, `nanobanana`, `parallel_ai`, `pdf_generator`, `pdf_handler`, `recall_ai`, `restful`, `runware`, `state_manager`, `tables`, `voice` or `wexa_api`. An empty value, or one that is not on this list, is refused with the list of what can be provisioned, and so is a connector with no enabled actions. One that needs credentials (an API key or OAuth) must be connected from the console. |

**More details**

Provisioning is the only verb: not create, connect, add or install. It does more than one thing, and one name keeps that visible. It creates one skill for each action the connector supports, and it is the only way skills come into a new project. The skill identifiers are minted at provisioning time, so read them back with [`list-skills`](/docs/connectors/list-skills) and never predict them. Reference those identifiers when you define an agent, or a [process flow](/docs/automation/create-process-flow) that names agents. A skill is a capability an agent may use, and an action is a single operation a skill performs.

Calling it twice is safe: it is neither an error nor a duplicate. A repeat returns the existing connector, and the response says so in a `note`.

Provisioning makes a source reachable and does not copy anything. Contents arrive through [ingestion](/docs/context/ingestion), as a separate step afterwards.

The set that can be provisioned moves as connectors are added, so read it from the tool rather than memorizing it. A connector with no enabled actions is refused, because provisioning it would leave the project with a connector that has no skills. A connector that needs an API key or OAuth authorization is a console step, because the credential has to be entered somewhere that is not a tool call. WhatsApp is linked by scanning a QR code on the phone, so no credential passes through a tool call: call [`connect-whatsapp`](/docs/connectors/connect-whatsapp), scan the code, then call [`complete-whatsapp-connection`](/docs/connectors/complete-whatsapp-connection).

In the console: open **Connect**, then **Connectors**, and select a project in the context bar, because connectors are project-scoped. Select **Add Connector**, which opens the marketplace where MCP servers and regular connectors sit together. Choose the connector and fill in its form. Pick an **Access scope**: Organization, Department, Project or Individual. The options depend on your role, and a role with one option sees it as a fixed note. Select **Save**. A connector that needs you to sign in shows a sign-in button in its place. Anyone who can reach the Connectors page can do this for the project they selected, except a compliance officer, who has read-only access.

A connector is the platform's link to an external system on a project's behalf, such as a search service, a document handler, a database or a business application. It makes that system reachable to agents and to [ingestion](/docs/context/ingestion), which brings its data into the project. It is not a repository connection: a project's link to a source-code repository is established by the code-sync client rather than provisioned, mints no skills and produces the code graph (see [code sync](/docs/context/code-sync)). It is not an MCP connection either: a link Wexa holds to a third-party MCP server, chosen from a marketplace so its tools become available inside Wexa, is a different mechanism, and neither is the Wexa MCP server, which is one of the surfaces Wexa itself is exposed over. And it is not, by itself, data in your project: bringing a source's contents into the [context graph](/docs/context/context-graph) and the [data catalog](/docs/context/create-ontology) is ingestion.

To read a source live without copying it, [`connector-read`](/docs/context/connector-read) runs a governed, read-only query against the source system. It suits large warehouse and database sources, where ingesting the rows would mean maintaining a stale copy. Writes are rejected: a write or modify action is blocked, and one whose read-only status is not established is refused. Rows default to 100, with a hard cap of 10000, and it needs the `fabric:query.read` grant. A declined read is an explicit governance refusal, never an empty result: see [policy and approvals](/docs/governance/policy-and-approvals). It is for rows, not structure: read which tables exist from the context graph with [`query-context`](/docs/context/query-context). Assets that arrived as crawled metadata carry no connector identifier and cannot be read live, so filter on the live-readable flag first. `provision-connector` and `connector-read` are turned on separately, so a deployment can have one and not the other. The missing one is absent from the tool list rather than present and failing.

Marked consequential: it changes the project, so it is audited in full and a policy rule may hold it for a person to approve.

Every tool call works the same way: [How every tool call works](/docs/sdks-and-apis/how-every-tool-call-works).
