---
title: "Конектори"
description: "Како конектори и везе омогућавају агентима ограничен приступ спољним алатима."
---

Конектор повезује пројекат са спољним алатом или услугом. Агент га позива као алат. Beeuni посредује у сваком позиву, тако да окружење за извршавање никада не садржи акредитив конектора.

Већину конектора дефинишете у `beeuni.yaml`. Погледајте [референцу манифеста](/docs/sr/project/manifest) за сва поља. Beeuni дефинише конекторе канала и рачунара када повежете платформу за ћаскање или машину.

<a id="browse-and-add-a-connector"></a>

## Прегледајте и додајте конектор

Отворите **Connectors** да бисте прегледали управљани каталог. Подразумевана листа садржи скупове алата управљаних од стране добављача, који се могу повезати аутентификацијом којом управља добављач или омогућеном конфигурацијом прилагођене аутентификације. Није потребно да већ имате везу у пројекту. Скуп алата који захтева непроверену конфигурацију прилагођеног OAuth-а остаје скривен док се та конфигурација не може проверити.

За директне изворе омогућите **Connectors API Discover** у заставицама функција пројекта, а затим на истој страници изаберите **API / MCP**. Омогућавање заставице не замењује подразумевани управљани каталог. Директни каталог групише објављене OpenAPI, MCP, GraphQL, Postman и друге API површине. Изаберите картицу, па објављену површину и попуните образац за повезивање. Површине које садрже само документацију отварају документацију добављача; не приказују се као шаблони спремни за повезивање. Користите **Add → Manual** за сирови API или шему која није у каталогу. Директно откривање ради и без конфигурисаног управљаног добављача.

<a id="connectors-connections-and-accounts"></a>

## Конектори, везе и налози

Конектор је пакет за досезање који види агент: дефинисана могућност (које радње, како доћи до услуге). То није улога и не поседује Beeuni дозволе: агент може да досегне конектор само ако се његов slug налази у додели из манифеста и ако одлука улоге дозвољава позив. Погледајте [Један речник, два повезивања](/docs/sr/accounts#one-vocabulary-two-bindings). Конектор садржи:

- slug јединствен за пројекат
- назив за приказ
- апликацију добављача
- смернице конектора

Веза је један **налог** — један овлашћени идентитет — за конектор: акредитив, OAuth додела или API кључ. Конектор може да садржи више налога истовремено. Сваки налог користи смернице конектора. `owner_type` сваког налога одређује ко може да обави позив као тај налог:

- `project` — **дељени** налог. Доступан свима којима је конектор додељен, било да су људи или сервисни налози (агент, окидач).
- `member` — **приватни** налог, чији је власник један члан пројекта (`owner_id`). Доступан само том члану и само у **приватној** сесији. Сервисни налог (агент или окидач који делује без надзора) никада не може да делује као приватни налог члана.

Више конектора може да упућује на исту апликацију добављача. Користите засебне конекторе када једној апликацији требају различите смернице.

<a id="add-an-account"></a>

### Додајте налог

Отворите конектор у **Customize → Connectors**. Картица **Accounts** приказује све налоге које можете да користите или којима можете да управљате, на једној листи. На свакој картици је наведено ко може да користи налог: **Only you**, **Everyone in project** или групе и особе са којима је дељен.

Изаберите **Add account**, дајте назив налогу и изаберите **Who can use it**:

- **Only you** — приватни налог. Сваки члан може да га дода.
- **Everyone in the project** — дељени налог.
- **Specific people or groups** — дељени налог, ограничен на особе, групе и агенте које изаберете.

За обе дељене опције потребно је `project.connector.connections.manage`. За **Specific people or groups**, Beeuni уписује доделе пре него што овластите налог, тако да налог никада нема акредитив док је доступан целом пројекту. Назив налога мора бити нов: одбија се назив који већ користи налог истог власника.

Када је агенту потребан налог, у ћаскању приказује картицу **Connect**. Картица отвара исти дијалог, са унапред попуњеним називом који је предложио агент и унапред изабраном публиком коју је затражио. Beeuni креира нови налог, никада поново не овлашћује постојећи и саопштава агенту назив новог налога како би могао да обавља позиве као тај налог.

<a id="choose-who-can-use-a-shared-account"></a>

### Изаберите ко може да користи дељени налог

Дељени налог може да користи свако у пројекту док не ограничите приступ. На картици налога изаберите **Share**. Дијалог је исти дијалог **Grant access** који се користи за агенте. У њему се приказује ко сада може да користи налог, а ви додајете:

- **Everyone in the project** — подразумевано.
- **Groups** — сваког члана сваке групе.
- **People** — по једног члана. Изаберите само себе да налог задржите за себе.
- **Agents** — сваку сесију тог агента, укључујући окидаче и дељене сесије. Свако ко може да покрене агента може преко њега да користи налог.

Ништа се не мења док не изаберете **Save**. Уклањањем последње групе или особе налог поново постаје доступан свима; дијалог приказује исход пре него што сачувате.

На ограничен налог примењују се правила за приватне налоге, с тим што публика замењује власника:

- Особа из публике може да га користи, и то само у приватној сесији.
- Агент из публике може да га користи у свим својим сесијама.
- Ниједан други агент, нити окидач било ког другог агента, не може да га користи.
- Сесија повезана са тим налогом не може да се дели, осим ако се налог дели са самим агентом те сесије.
- Само особа може да промени ко може да користи налог. Агентска сесија добија `403`.

Особа ван публике не види налог. Особа која управља везама пројекта и даље га види, са ознаком **Not shared with you**, како би могла да промени ко може да га користи.

<a id="share-your-own-private-account"></a>

### Делите сопствени приватни налог

И ваш налог **Only you** има дугме **Share**. Дељењем га претварате у дељени налог за особе и групе које изаберете (остајете међу њима, осим ако сами себе не уклоните) или за све у пројекту. Од тада је то дељени налог: и особе које управљају везама пројекта могу њиме да управљају.

- За дељење је потребно `project.connector.connections.manage`, исто право које је потребно за додавање дељеног налога. Без њега је дугме онемогућено и приказује разлог.
- Beeuni прво уписује доделе, а затим једним ажурирањем претвара налог у дељени, тако да у међувремену никада није доступан целом пројекту.
- Дељени налог истог назива на конектору спречава дељење (`409`): прво промените назив једног од њих.

```text
POST /projects/{projectId}/connections/{connectionId}/share
     {"principals": [{"principal_type": "group", "principal_id": "<group-id>"}]}
```

Празна листа `principals` дели налог са свима. Из CLI-ја:
`beeuni connectors connections share <connection-id> --group <group-id>`
(такође `--user <email|id>`, може да се понавља, или `--everyone`).

Сваки унос публике је једна додела објекта `connection` у складишту додела:

```text
POST   /accounts/{accountId}/iam/assignments
       {"principal_type": "group", "principal_id": "<group-id>",
        "role_key": "agent-user", "scope_type": "project", "scope_id": "<project-id>",
        "object_type": "connection", "object_id": "<connection-id>"}
DELETE /accounts/{accountId}/iam/assignments/{assignmentId}
```

Из CLI-ја се исти уписи обављају овако:

```bash
beeuni access grant --group <group-id> --connection <connection-id>
beeuni access grant --everyone --connection <connection-id>
beeuni access revoke <assignment-id>
beeuni connectors connections ls   # the WHO CAN USE column
```

- `principal_type` је `user`, `group` или `project` (сви у пројекту; `principal_id` је ID пројекта).
- За доделу или опозив потребно је `project.connector.connections.manage`.
- Само дељени налог може да се ограничи помоћу ових додела. За приватни налог или ID који није веза у овом пројекту добија се одговор `404`; уместо тога, поделите сопствени приватни налог помоћу горе наведеног пута `share`.
- `GET /projects/{projectId}/connections` враћа доделе сваког дељеног налога у `shared_with`, а `usable: false` на налогу који позивалац види само ради управљања њиме. Бирач сесије нуди само употребљиве налоге.

<a id="which-identity-an-account-acts-as"></a>

### Као који идентитет налог делује

`label` naloga je naziv izabran pre autorizacije. Ne govori vam kojom prijavom je nalog povezan. To pokazuje `connected_as`: imejl, prijavu ili prikazano ime koje dobavljač prijavi za autorizovani nalog.

- Beeuni ga čita kada se završi `composio` autorizacija: prvo prikazano ime povezanog naloga, a zatim alat „ko sam ja“ u paketu alata (Gmail, Google Calendar, Google Drive, Linear, GitHub, Slack, Notion, Outlook, Microsoft Teams, HubSpot, Jira, Asana, Figma, Airtable, Salesforce, Trello, Dropbox, Calendly). Google Docs i Google Sheets nemaju takav alat, pa njihovo `connected_as` ostaje `null`.
- Nalog koji još ima podrazumevanu oznaku (`Private connection`, `Project connection` ili naziv konektora) dobija oznaku koja odgovara tom identitetu. Oznaka koju je neko izabrao nikada se ne menja.
- Stranica za povezivanje prikazuje „Povezano kao …“ čim se nalog pojavi, pa se odmah vidi ako je deljeni nalog autorizovan ličnom prijavom.
- `connected_as` je prikazan za svaku vezu (`GET /projects/{projectId}/connections`), na listi naloga, u `beeuni connectors accounts <slug>` i `beeuni connectors connections ls` (kolona `CONNECTED AS`) i u redovima naloga u **Customize → Connectors**.

<a id="rename-an-account"></a>

### Promena naziva naloga

Promenite naziv nalога без поновне ауторизације:

```text
PUT /projects/{projectId}/connections/{connectionId}/label   {"label": "Support inbox"}
beeuni connectors connections rename <connection-id> Support inbox
```

На контролној табли отворите конектор, па изаберите **⋯ → Rename** у реду налога. Мења се само ознака. Ауторизовани налог, његов власник, подразумевана заставица и стање код добављача остају непромењени. Важе иста ограничења као за прекид везе: ваш лични налог или `project.connector.connections.manage` за дељени налог.

Промена назива се одбија са `400` за `me`, `project` или ознаку у облику UUID-а, јер `--account` разрешава те вредности пре ознака. Промена се одбија са `409` ако други налог истог власника већ има ту ознаку, без обзира на велика и мала слова.

<a id="connect-a-different-account"></a>

### Повезивање другог налога

Линк за повезивање са слотом који већ има активан налог не покреће поновну ауторизацију. Добављач поново користи тај налог, а страница за повезивање приказује **Већ повезано**. Да бисте користили другу пријаву, додајте нови налог у конектор, поставите га као подразумевани, па прекините везу са старим.

Позив у коме није наведен налог прво разрешава подразумевани лични налог позиваоца, а затим подразумевани дељени налог пројекта. Резултат сваког позива показује којим налогом је извршен (`account: { connection_id, label,
owner_type }`), па се у транскрипту увек види идентитет коришћен за позив алата. Листу налога којима се конектор може позвати, са подразумеваним налогом на првом месту, добићете помоћу `GET /connectors/projects/{projectId}/connectors/{slug}/accounts`.

> **Warning**
>
> `authorization_strategy` (`project` | `user`) је био MODE на нивоу конектора који је искључивао међусобну употребу налога у власништву пројекта и налога у власништву чланова — конектор са стратегијом `user` није могао да понуди дељени налог, па није имао ток повезивања ни на једном месту где би услужни налог могао да га користи. Застарео је: манифест и `PUT .../authorization-strategy` га и даље прихватају и одговарају без грешке, али га више ништа не чита. `owner_type` за сваку везу сада представља цело правило приступа.

<a id="providers"></a>

## Добављачи

Конектор користи један тип добављача:

- **composio** — управљани OAuth за подржане SaaS апликације
- **pipedream** — стари управљани OAuth, задржан само за повратак на претходну верзију
- **openapi**, **postman**, **graphql**, **http** — директни API конектори
- **mcp** — удаљени MCP сервер преко HTTP-а или SSE-а
- **channel** — веза са платформом за ћаскање
- **computer** — повезани рачунар сваког члана представља један налог

Више о управљаним токовима добављача потражите у одељцима [Slack и канали](/docs/sr/connect/slack) и [Рачунари](/docs/sr/connect/computers).

<a id="apps-that-need-your-own-oauth-app"></a>

### Доступност апликација

Каталог конектора приказује апликације које су тренутно доступне за повезивање. Неке захтевају додатно подешавање аутентификације и могу се појавити тек када се оно заврши.

## Аутентификација и смернице

Веза се аутентификује помоћу:

- OAuth-а преко `pipedream`-а, инсталације канала или изворног OAuth2 одобрења
- API кључа или токена унетог преко контролне табле

Beeuni шифрује податке везе и разрешава их на серверу за сваки позив алата. Агент захтева радњу. Beeuni додаје акредитив, проверава одобрење агента и смернице за конектор и везу, позива спољни API и враћа резултат.

Смернице конектора припадају конектору. Веза не може да их надјача. Заштитна правила пројекта имају предност у односу на смернице за конектор и везу.

Подразумевано се за неподударајућу радњу конектора не тражи одобрење. Подесите `policy.default_mode: risk` да бисте захтевали одобрење за неподударајуће радње писања и деструктивне радње. Подесите `sensitive: true` да би `require_approval` постало подразумевано за неподударајуће радње конектора, укључујући читања. Експлицитна правила пројекта или везе са конектором и даље имају предност.

<a id="approve-one-governed-call"></a>

### Одобравање једног позива који подлеже смерницама

`require_approval` креира једну одлуку за један позив конектора. Конектор враћа `202 pending_approval` са `approval_url`, `approval_summary` и `execution_id`. Не држи HTTP захтев отвореним.

Поделите `approval_url` са било којим чланом тима. URL идентификује захтев, али не даје овлашћење. За ову страницу потребно је да корисник буде пријављен на Beeuni налог. Beeuni затим проверава да ли тај налог има приступ пројекту и овлашћење за одобравање радњи у њему.

На страници за одобравање приказани су редиговани параметри које ће конектор примити. Позивалац може да дода `approval_context` (у CLI-ју: `--reason`) како би описао ефекат. Користите ово када су параметри само референце: `gmail.send_draft` прима ID нацрта, па агент наводи примаоца, тему и садржај. Страница приказује овај текст као опис агента, а не као проверену информацију. Параметри и даље представљају доказ. Beeuni никада не шаље `approval_context` добављачу.

Одобрите или одбијте позив једном. По жељи додајте поруку уз одлуку. Порука се заједно са одлуком враћа агенту, па одбијање може да садржи упутства шта да уради уместо тога.

Сваки позив на чекању приказан је и у одељку **Review → Needs you** за пројекат. Отворите **Review** у бочној траци; број приказује колико ставки чека на вас. Позив се отвара у истом приказу за одобравање као и линк за одобравање, па пре одлуке можете да видите конектор, параметре и опис агента.

Када позив потиче из Slack или Teams сесије, Beeuni објављује картицу за одобрење у тој нити. Картица приказује опис агента, параметре и опције **Approve** / **Deny**. У Slack-у, **Reply…** отвара поље за поруку агенту; у Teams-у је поље за поруку директно на картици. Одлуку може да донесе само менаџер пројекта или особа која је покренула сесију. Одлука донета било где (у нити, у Beeuni-ју или на страници за одобрење) замењује дугмад на картици исходом, а агент наставља рад у истој нити. Beeuni шаље одлуку назад у сесију путем трајног повратног позива. Одобрење важи само за тачан сажетак захтева. Ако се промени прималац, предмет, тело, канал, URL или други параметар, потребна је нова одлука.

Отворите панел **Audit** сесије да бисте користили исти приказ параметара. Историјски уноси су само за читање. Не постоји опција за одобрење целе сесије. Користите изричиту смерницу `always_run` само када радња конектора мора да се извршава без надзора.

<a id="connect-with-oauth"></a>

## Повезивање помоћу OAuth-а

1. **Отворите страницу Connectors пројекта**

    Отворите пројекат. Изаберите **Connectors**, а затим апликацију.

2. **Изаберите опсег налога**

    Изаберите **Project** за дељени налог, доступан свима којима је додељен конектор. Изаберите **User** за приватни налог, чији сте власник и коме можете да приступите само ви, и то само у приватној сесији.

3. **Довршите ауторизацију**

    Довршите OAuth поступак. Beeuni чува повезани налог као везу.

<a id="connect-an-mcp-server-that-uses-oauth-21"></a>

## Повезивање MCP сервера који користи OAuth 2.1

Beeuni имплементира спецификацију за MCP ауторизацију. Отворите конектор, изаберите **Add credential**, а затим картицу **OAuth 2.0**. Beeuni испитује сервер и чита његове метаподатке:

1. Неауторизовано испитивање враћа `401` са
   `WWW-Authenticate: Bearer resource_metadata="…"`.
2. Beeuni чита метаподатке заштићеног ресурса (RFC 9728) на тој URL адреси или на
   `/.well-known/oauth-protected-resource`.
3. Beeuni чита метаподатке сервера за ауторизацију (RFC 8414 или OpenID Connect discovery) за први сервер за ауторизацију који ресурс наведе.

Када тај сервер оглашава `registration_endpoint`, Beeuni се региструје као OAuth клијент (RFC 7591) и приказује једно дугме: **Connect &lt;server&gt;**. Не морате да правите апликацију нити да копирате ID клијента или тајну. Beeuni затим покреће Authorization Code with PKCE (S256) и повезује токен са сервером помоћу параметра `resource` (RFC 8707).

Региструјте овај URI за преусмеравање ако сервер захтева да га унесете унапред:

```text
https://api.beeuni.ai/v1/connectors/oauth2/callback
```

Када сервер објављује крајње тачке, али не и `registration_endpoint`, Beeuni унапред попуњава URL адресу за ауторизацију, URL адресу токена и опсеге. Унесите ID клијента апликације коју направите код тог добављача. Ако сервер не објављује метаподатке, унесите сва поља.

Beeuni одржава MCP сесију: покреће `initialize` и
`notifications/initialized` на захтев, а затим у каснијим позивима шаље `Mcp-Session-Id`. Сервер који одговара без сесије неће видети руковање.

Beeuni повезује сваку везу са сервером за ауторизацију који ју је издао. Када повратни позив садржи параметар `iss` (RFC 9207), Beeuni га одбија ако се не подудара са забележеним издаваоцем — код који је издао други сервер одбија се пре него што буде искоришћен.

<a id="authorize-from-the-cli"></a>

### Ауторизација из CLI-ја

Контролна табла је један од начина покретања овог поступка, али не и једини. Декларишите конектор у `beeuni.yaml`, а затим га ауторизујте из терминала или сесије агента:

```yaml
connectors:
  - slug: read-ai
    name: Read AI
    provider: mcp
    url: 'https://api.read.ai/mcp'
    auth:
      type: bearer
```

```text
beeuni connectors authorize read-ai --json
```

Команда креира везу, покреће ланац откривања, региструје Beeuni као клијента ако сервер подржава RFC 7591 и враћа URL адресу коју треба одобрити:

```json
{
  "connection_id": "7b1a16b2-...",
  "registered": true,
  "scopes": ["openid", "offline_access", "mcp:execute", "meeting:read"],
  "authorization_url": "https://authn.read.ai/oauth2/auth?response_type=code&...",
  "expires_at": "2026-08-19T14:48:26.345Z"
}
```

Агент враћа `authorization_url` особи са којом ради. Када она одобри, агент потврђује:

```text
beeuni connectors authorize read-ai --status
```

Команда завршава са ненултим излазним кодом док је статус `error`. Користите `--scope` да бисте сузили тражене дозволе. Користите `--client-id` и `--client-secret` за сервер који не подржава динамичку регистрацију клијента.

Beeuni поново преузима каталог алата конектора чим се ауторизација доврши, па конектор излази из стања `error` без ручне синхронизације.

<a id="connect-a-direct-api-with-oauth2"></a>

## Повезивање директног API-ја помоћу OAuth2-а

Директни конектори подржавају:

- client credentials
- authorization code with PKCE
- device authorization
- динамичку регистрацију клијента (RFC 7591)

За client credentials унесите URL адресу токена, ID клијента, опсеге и тајну клијента. Можете користити `client_secret_basic`, `client_secret_post`,
`client_secret_jwt` или `private_key_jwt` за аутентификацију на крајњој тачки токена.

За authorization code унесите URL адресу за ауторизацију и URL адресу токена. За device authorization унесите URL адресу за ауторизацију уређаја и URL адресу токена. URL адреса за откривање RFC 8414 може да обезбеди ове крајње тачке.

Beeuni шифрује конфигурацију OAuth2-а и токене. Освежава приступне токене пре истека и чува сваки ротирани токен за освежавање. Опозив везе блокира следећи позив конектора.

За Microsoft Graph користите:

```text
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
https://graph.microsoft.com/.default
```

За директне SharePoint REST позиве користите опсег ресурса SharePoint:

```text
https://{tenant}.sharepoint.com/.default
```

<a id="connect-with-an-api-key"></a>

## Повезивање помоћу API кључа

1. **Декларишите конектор**

    ```yaml
    connectors:
      - slug: stripe-read
        name: Stripe read access
        provider: openapi
        spec: 'https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json'
        auth:
          type: bearer
        policies:
          - match: 'get_*'
            action: always_run
          - match: '*'
            action: block
    ```

    Манифест и даље прихвата кључ `authorization_strategy` ради компатибилности са старијим верзијама. Beeuni га игнорише: власника (дељени или приватни) подесите за сваку везу посебно, када додате њене акредитиве.

2. **Обједините захтев за измену**

    Beeuni чита манифест из подразумеване гране. Конектор постаје активан након обједињавања захтева за измену.

3. **Додајте везу**

    Отворите конектор и подесите његове акредитиве. Beeuni чува вредност шифровану. Не уписује је у манифест.

<a id="grant-an-agent-access"></a>

## Додела приступа агенту

Додајте ознаку конектора у поље `connectors` агента:

```yaml
agents:
  release-bot:
    connectors: [stripe-read]
```

Изоставите `connectors` да би агент добио `none`. Обједините измену да би ступила на снагу.

`connectors_required` је застарео. Манифест га и даље прихвата, али га ништа не чита: сесија се никада не одбија приликом креирања зато што конектор нема употребљив налог. Одбијање креирања сесије због недостајућег конектора у пракси није било могуће — конектор који је доступан само приватно није имао дељени налог који би се могао понудити, па позивалац није могао да отклони узрок одбијања. Провера се сада врши при **позиву** конектора: агент коме је додељен `stripe-read` може одмах да започне рад, а одбија се само позив за који је конектор заиста потребан (погледајте [Када је позив одбијен](#when-a-call-is-denied)) — уз упутство како да се проблем реши.

<a id="select-an-account"></a>

## Избор налога

Постоје два независна начина да изаберете налог за позив — закачите један за целу сесију или наведите један у појединачном позиву.

<a id="pin-a-session-wide-default"></a>

### Подешавање подразумеваног налога за целу сесију

Сесија може да замени подразумевани налог конектора за сваки позив који упути:

```json
{
  "connector_bindings": {
    "stripe-read": {
      "connection_id": "00000000-0000-4000-8000-000000000000"
    }
  }
}
```

Кључ везе је ознака конектора. Вредност је налог (веза) ком позивалац у овој сесији има право да приступи.

Користите `GET /projects/{projectId}/sessions/{sessionId}/scope` да бисте прочитали ефективну везу. Користите `PUT` на истој путањи да бисте је заменили. Замена важи за следећи позив алата, без поновног покретања сесије.

<a id="name-an-account-on-one-call"></a>

### Навођење налога у појединачном позиву

Помоћу следеће команде наведите налоге за које може да се позове конектор — подразумевани први:

```text
GET /connectors/projects/{projectId}/connectors/{slug}/accounts
```

```json
{
  "connector": "stripe-read",
  "accounts": [
    { "connection_id": "...", "label": "Shared workspace", "owner_type": "project", "is_default": true, "connected_as": "billing@example.com" },
    { "connection_id": "...", "label": "My Stripe", "owner_type": "member", "is_default": false, "connected_as": null }
  ]
}
```

Затим наведите један налог у позиву, према ИД-у везе или називу (без разлике између великих и малих слова), или
помоћу две селекторске речи `me` (ваш подразумевани приватни налог) и
`project` (подразумевани заједнички налог пројекта):

```text
beeuni connectors call stripe-read get_balance '{}' --account me
beeuni connectors call stripe-read get_balance '{}' --account "Shared workspace"
```

Позив у ком није наведен налог најпре се разрешава на подразумевани приватни налог позиваоца, а затим на подразумевани заједнички налог пројекта — исто као и пре него што је конектор могао да има више налога. Наведени налог који није могуће разрешити бива **одбијен**; никада се не преусмерава неприметно на други налог (погледајте [Када је позив одбијен](#when-a-call-is-denied)). Резултат сваког успешног позива наводи са ког налога је извршен: `account: { connection_id, label,
owner_type }`.

<a id="use-a-connector-in-a-session"></a>

## Коришћење конектора у сесији

У оквиру сесије користите Connector CLI:

```text
beeuni connectors ls
beeuni connectors accounts stripe-read
beeuni connectors call stripe-read <action> '<json-args>' [--account <id|label|me|project>]
```

`connectors` приказује конекторе у домету. `accounts` приказује налоге које овај позивалац може да користи `stripe-read` као — прво подразумевани, а затим заједнички пре приватног у оквиру сваке групе. `call` покреће једну радњу, као именовани `--account` или, ако није наведен, користи исто подразумевано разрешавање као пре него што је конектор могао да има више налога.

<a id="large-results"></a>

### Велики резултати

Позив за листање или претрагу може да врати више података него што модел може да прочита: излаз алата већи од ~50 KB се скраћује. Сачувајте резултат у датотеку и обрадите га помоћу кода:

```text
beeuni connectors call linear graphql.issues '{"first":250}' --out /workspace/output/issues.json
# → { "ok": true, "account": …, "saved_to": "/workspace/output/issues.json",
#     "bytes": 93037, "shape": { "issues": { "nodes": "array(250) of {id,title,…}",
#     "pageInfo": { "hasNextPage": true, "endCursor": "…" } } } }
jq '.data.issues.nodes[] | {id, title}' /workspace/output/issues.json
```

`--out` уписује цео JSON резултат и креира надређене директоријуме. Стандардни излаз садржи омотач позива без `data`, као и `saved_to`, `bytes` и `shape`: преглед структуре `data` (кључеви, дужине низова и сваки `pageInfo`). Излазни код остаје непромењен.

<a id="attach-files"></a>

### Прилагање датотека

Позив никада не садржи бајтове датотеке у аргументима. Прво припремите датотеку, а затим у аргументе унесите њену референцу. Гејтвеј чита бајтове на серверској страни и уписује их у захтев.

```text
beeuni connectors call microsoft-graph.sendmail @mail.json \
  --attach /workspace/artifacts/report.pdf
```

`--attach` припрема датотеку и додаје референцу у низ прилога радње. Низ се налази у улазној шеми радње: `attachments` за Email канал, `body.message.attachments` за Microsoft Graph `sendMail`. Ако је шема неуобичајена, наведите назив помоћу `--attach-path body.message.attachments`.
Велике JSON аргументе сместите у датотеку (`@mail.json`) или проследите преко stdin-а (`-`).

Да бисте сами поставили датотеку, прво је припремите:

```text
beeuni connectors upload /workspace/artifacts/report.pdf --connector microsoft-graph
# → { "attachment_id": "…", "ref": { "$beeuni_attachment": "…" }, … }
```

Ставите `ref` било где у аргументе. Гејтвеј га замењује на основу позиције:

| Позиција `ref` | Замењује се са |
| --- | --- |
| Елемент низа прилога чије су ставке објекти | Ставка прилога добављача. Шема ставке одређује облик: Microsoft Graph `fileAttachment` (`name` + `contentBytes` или `@odata.type`), Postmark (`Name` + `Content`), Mailjet (`Filename` + `Base64Content`), SendGrid и Resend (`filename` + `content`), Brevo (`name` + `content`). Сваки други облик ставке се одбија уз `attachment_item_shape_unknown`. |
| Текстуално поље, нпр. `contentBytes` или `content` GitHub датотеке | Base64 кодирани садржај датотеке. |
| `attachments[]` Email канала | Потписани URL за преузимање за добављача Email услуге. |

Правила:

- Датотеке морају да потичу из `/workspace/output`, `/workspace/artifacts`,
  `/workspace/reports` или `/workspace/deliverables`. Симболичке и чврсте везе
  се одбијају. Прво копирајте датотеку на ту локацију.
- Један позив може да садржи највише 20 датотека и укупно 25 MiB. Узводни API може
  да постави нижи лимит: документација за Microsoft Graph наводи 3 MB као највећу датотеку која може да се приложи у један захтев `sendMail`.
- Припремљена датотека је приватна за сесију у којој је припремљена, користи се једном и
  брише се након 24 часа. Неуспешан позив ослобађа је за поновни покушај.
- Евиденција ревизије, преглед одобрења и модел виде само референцу, никада бајтове. Ако узводна грешка садржи датотеку, из ње се уклања Base64.
- Управљани конектори не прихватају припремљене датотеке
  (`connector_attachments_unsupported`).

MCP сервер нуди исти ток рада: `call` прима `attachment_files` (и опционо `attachment_path`), а `upload_attachment` враћа `ref`. Одговарајући SDK позив је `connectors.uploadAttachment(bytes, { filename, contentType,
connector })`, which returns `ref`.

<a id="call-results"></a>

### Резултати позива

`POST /connectors/projects/{projectId}/call` враћа један JSON објекат. Ова поља су иста за сва повезивања (OpenAPI, HTTP, MCP, GraphQL, `composio`,
`pipedream`, computers):

| Поље | Код | Вредност |
| --- | --- | --- |
| `data` | 200 | Неизмењен сирови одговор узводног система. |
| `output` | 200 | Садржај без омотача повезивања: `composio` `data.result`, MCP `result.structuredContent ?? result.content`, GraphQL `data.data`. Изостаје када је једнак `data` (OpenAPI, HTTP, Postman, channel, `pipedream` и computer позиви), па тело садржи садржај само једном: читајте `output ?? data`. SDK га попуњава. |
| `binding` | 200, 500, 429, 503 | Повезивање које је извршило позив: `openapi`, `http`, `mcp`, `graphql`, `composio`, `pipedream`, `pipedream_proxy`, `postman`, `tunnel`. `null` код грешке пре него што је радња разрешена. |
| `upstream_status` | 200, 500, 429, 503 | HTTP статус узводног система. `null` када нема одговора узводног система (истек времена, одбијен захтев, computer). `composio` и `pipedream` пријављују грешку добављача у оквиру статуса 200, па Beeuni за њу поставља `502` (`400` за одбијен Linear упит, `429` за ограничење броја захтева). |
| `upstream_error` | 200 | Присутно када је узводни систем пријавио грешку у оквиру одговора 2xx: резултат MCP алата са `isError: true` или грешком JSON-RPC-а, или GraphQL `errors` без података. Позив се и даље рачуна као извршен: `ok` остаје `true`. |
| `retry_after_seconds` | 429, 503 | Узводни `Retry-After`, у секундама, ако га је послао. Одговор садржи и заглавље `Retry-After`. |

HTTP статус неуспелог позива:

- Узводни `429` враћа `429`. Узводни `503` враћа `503`. Сачекајте
  `retry_after_seconds` (или смањите учесталост захтева) па поновите позив.
- Остале грешке узводног сервиса враћају `500`, са узроком у `reason`.

- Узводни одговор већи од 64 MiB враћа `500` са `reason: "upstream_response_too_large: …"`. Beeuni престаје да чита
  када достигне лимит. Затражите мању страницу или примените филтер.
- Ако узводни систем не одговори у року, враћа се `500` са
  `reason: "upstream_timeout: …"`. Рок је подразумевано 60 секунди.
  Подесите временско ограничење клијента на вредност већу од тога да би гејтвеј увек први одговорио.

Позив конектора није идемпотентан. Beeuni не уклања дупликате поновљених
позива. Након `upstream_timeout` или прекида на страни клијента, позив је можда извршен
на узводном систему: проверите његов ефекат пре него што поновите упис (послати имејл, креирани запис).

<a id="typed-calls-from-code"></a>

### Типизовани позиви из кода

`beeuni connectors types` генерише TypeScript датотеку декларација за сваку
радњу коју можете да позовете. Тип аргумената сваке радње одређује њена улазна шема,
а тип резултата — излазна шема. Тип резултата описује поље `output` позива.

```sh
beeuni connectors types --out src/beeuni-connectors.d.ts
beeuni connectors types --connector linear,github --out src/beeuni-connectors.d.ts
```

Укључите датотеку у свој `tsconfig.json`. Затим позив упутите преко `callAction`:

```ts
import { createBeeuni } from '@beeuni/sdk';

const connectors = createBeeuni({ backendUrl, getToken }).project(projectId).connectors;
const result = await connectors.callAction('linear', 'list_issues', { team: 'CORE' });
if (result.ok) console.log(result.output?.issues.length);
```

Ручица конектора чита исту датотеку, а `run` враћа типизовани излаз
или баца типизовану грешку (погледајте „Конектори из кода“):

```ts
const issues = await createBeeuni({ backendUrl, getToken })
  .project(projectId)
  .connector('linear')
  .run('list_issues', { team: 'CORE' });
```

`callAction(slug, action, args, options)` шаље исти захтев као
`call('<slug>.<action>', args, options)` и враћа исти резултат. Разликују се само типови: недостајући или непознат аргумент је грешка при компајлирању, а
`output` има генерисани тип. Радња која није у датотеци прихвата било који објекат и враћа `output: unknown`.

- OpenAPI, HTTP, MCP и GraphQL конектори објављују излазну шему ако је њихов извор дефинише. GraphQL резултат је типизиран као објекат.
- Управљани конектори не објављују излазну шему. Њихов резултат је `unknown`. CLI им додељује називе након што упише датотеку.
- Сваки унос `$defs` постаје један именовани тип (`BeeuniConnectorDef<n>_<name>`), па рекурзивна шема остаје коначна. Шема која не може да се компајлира (унија која садржи саму себе) или чији типови премашују 256 KB за једну радњу постаје `unknown`.
- Поново покрените команду након што додате конектор или када се синхронизује нова верзија.
- Каталог враћа излазне шеме само на захтев:
  `GET /connectors/projects/{projectId}/catalog?include_output_schemas=true`
  додаје `outputSchema` свакој радњи (`null` када ниједна није сачувана).

<a id="when-a-call-is-denied"></a>

### Када је позив одбијен

На одбијени позив добија се одговор `{ ok: false, status: "denied", reason, hint }`. `reason` је стабилан код; `hint` говори шта треба урадити.

| `reason` | HTTP | Значење | Такође у телу |
| --- | --- | --- | --- |
| `connector_not_assigned` | 403 | Дозвола за `connectors:` агента који је у току у `beeuni.yaml` не обухвата овај конектор. | `agent`, `granted` (листа или `"all"`), `manifest_revision` и `manifest_commit` (манифест из ког потиче дозвола). |
| `connector_not_connected` | 403 | Нема употребљивог налога за овај позив. Конектор уопште нема налог за овог позиваоца (нема сачуваних акредитива или апликација никада није одобрена — `beeuni connectors ls` приказује је као `needs_auth`), или је `--account` навео налог који није могао да се разреши. | `connect_url` — хостована веза за одобравање налога, када позивалац може да је генерише — када ништа није повезано. `requested_account` и `available_accounts` — назив који није могао да се разреши и називи који су могли — када је `--account` навео налог. |
| `connector_disabled` | 403 | Конектор је декларисан, али је онемогућен. | — |
| `connector_not_found` | 404 | У пројекту није декларисан конектор са овим slug-ом. | — |
| `action_not_found` | 404 | Конектор нема такву радњу. | — |

`connect_url` је целокупно решење за неповезан конектор: сесија се никада не одбија унапред због тога (погледајте [Одобравање приступа агенту](#grant-an-agent-access)), па само одбијање садржи решење. Агент приказује везу дословно; веб транскрипт је приказује као дугме „Повежи“ које се активира једним кликом. Веза подразумевано одобрава приватни налог за особу која је отвори — повезивање дељеног налога је изричит избор (`beeuni connectors connect stripe-read --owner project`, уз услов `project.connector.write`).

Конектор канала који је направио сесију (Slack, Teams, имејл) увек може да се позива из те сесије, без обзира на то шта дозвола агента наводи, тако да агент увек може да одговори у нити из које је позван.

Дозвола сесије прати `beeuni.yaml`: промена у `connectors:` агента који је у току (укључујући `beeuni connectors add --apply`) примењује се при следећем позиву. Дозвола бележи из ког манифестног блоба и комита потиче; читање које би је заменило из истог блоба потврђује се претходним другим читањем, а читање из старијег комита је никада не замењује.

Slack и Microsoft Teams повезују се са контролне табле на исти начин као OAuth апликације. Повезивање Slack-а уписује конектор `channel` у `beeuni.yaml` за вас. Погледајте [Slack и канали](/docs/sr/connect/slack).
