MCP и поврзани алатки
Поврзете го Nessie со MCP сервери и спарете надворешен агент, за да работи во Nessie во ваше име.
Што е MCP
Model Context Protocol е мала, отворена конвенција за опишување алатки на јазичен модел и за нивно повикување. Серверот ја објавува својата способност — список на именувани алатки, секоја со JSON-шема за своите аргументи — а клиентот го открива списокот и ги повикува во име на моделот. Намерно е едноставна: вредноста е во тоа што една интеграција, напишана еднаш, работи со секој модел и со секој производ што го зборува тој протокол.
Nessie е на двете страни
Тоа вреди да се каже прецизно, бидејќи двете половини лесно се мешаат, а живеат на намерно различни патеки.
- Излезно. Nessie е MCP клиент. Ги поврзувате серверите што ги води некој друг, а алатките што тие ги изложуваат стануваат алатки што вашите агенти можат да ги користат. Површината за управување е
/api/mcp/*. - Влезно. Nessie е исто така MCP сервер. Агент што работи некаде другаде — Claude Code или Codex на компјутерот на програмерот — може да пристапи до вашите табли и документи. Таа крајна точка е
POST /mcp, намерно надвор од/api, за двете спротивни значења да не бидат еден сегмент на патеката едно до друго.
Поврзување MCP-сервер со Nessie
Записи во каталогот и инстанци
Има два објекти, и разликата е важна:
- Запис во каталогот е дефиницијата на еден сервер — неговото име, неговиот транспорт, како се автентицира. Се пишува еднаш и може да се сподели.
- Инстанца е тој запис инсталиран на едно ниво, со акредитивите што до него допираат. Инсталирањето на истиот запис за два различни тима создава две инстанци.
Повеќето луѓе никогаш не ги допираат директно. Влезот во администраторскиот интерфејс е продавницата на апликации на /admin/apps: таа го прелистува истиот каталог со скриени деталите за поврзување, а Поврзи на некој оглас создава инстанца. Операторите што сакаат суровите објекти ги користат /api/mcp/catalog и /api/mcp/instances.
Ако еден сервер сè уште не е во каталогот, POST /api/mcp/discover прима URL и враќа што самиот сервер вели за себе, а POST /api/mcp/library/import повлекува запис од јавната библиотека на сервери. Прво поврзување може да се создаде директно од URL-то и со POST /api/apps/custom.
Транспорти
Nessie се поврзува со далечинските сервери преку HTTP. Работат два транспорти: streamable HTTP (тековниот MCP транспорт) и постариот HTTP+SSE транспорт. Изберете http, освен ако серверот не нуди само sse.
Транспортот stdio е одбиен за конектори што ги пишувате вие. stdio значи дека MCP-серверот е локален процес што го стартува домаќинот, а извршувањето на произволни програми внатре во серверот на Nessie не е нешто што операторот смислено може да го прегледа. Серверите што се објавени само како пакет за локално извршување се исфрлени од увозите од библиотеката из истата причина. Вредноста ws постои во полето за протокол и не е имплементирана — врската што ја користи паѓа кога Nessie ќе се обиде да ја отвори.
Како Nessie се автентицира кај серверот
Записот во каталогот декларира еден од пет методи: none, api_key, bearer, basic или oauth2.
api_key е вметнување на заглавие, а записот вели кое заглавие и каков префикс — па Authorization: Bearer …, X-API-Key: … и X-Auth-Token: Token … се ист метод, конфигуриран поинаку. Самиот клуч се внесува еднаш со POST /api/mcp/instances/:instanceId/secret и никогаш повеќе не е читлив; ниеден одговор од рутите на инстанците не носи референца на акредитив.
oauth2 има две форми. Сервер со фиксни крајни точки ги има во својот запис во каталогот. Сервер што објавува стандардни метаподатоци не бара ништо конфигурирано: Nessie ги чита документите за заштитениот ресурс и за авторизациониот сервер и си создава клиент преку динамичка регистрација на клиент или преку документот со метаподатоци за идентификаторот на клиентот, што го објавува на својата well-known патека. Во двата случаја ракувањето е POST /api/mcp/instances/:instanceId/oauth/start, по што провајдерот ја пренасочува назад на GET /api/mcp/oauth/callback. Токенот на состојбата се користи еднаш, се чува во базата и важи десет минути, а PKCE секогаш се користи.
Едно правило ги изненадува луѓето: дури ни сопственик на организација не може да прикачи личен или OAuth-токен на некој друг. Споделен акредитив е можен само за запис со API-клуч што е валидиран како таков; сè друго се одбива. Акредитивот што припаѓа на некој човек останува акредитив што припаѓа на тој човек.
Каде се чуваат акредитивите
Тајните на конекторите и пакетите OAuth-токени се чуваат во вашата сопствена Postgres база, во AES-256-GCM обвивки по намена, под независимо верзираниот прстен за шифрирање на распоредувањето, и се адресираат само преку непрозирни референци secret_*. Намерно не се во надворешниот трезор за тајни што ги чува останатите тајни на Nessie. Продукциско распоредување што не ја конфигурирало шифрираната продавница одбива да се стартува, наместо да заврши OAuth-ракување што потоа би го изгубило.
Каде допира една врска
Инстанцата е инсталирана на еден од шест опсези: system, organization, project, team, channel или user. Тој опсег е тврда граница за тоа кои извршувања можат да ја користат, а грантовите можат само да го стеснат, никогаш да го прошират — па конектор што сте го инсталирале со сопствената сметка не може тивко да стане конектор за целата организација.
Кој смее каде да инсталира следи иста форма: сопствениците и администраторите на организацијата управуваат со инсталации на секој опсег; секој друг инсталира конектори на својот личен опсег user и може да ги види заедничките инсталации до кои има пристап.
Давање алатка на агент
Поврзувањето на сервер не ги дава неговите алатки никому. Кога се инсталира инстанца, Nessie ја проверува и ја проектира секоја алатка што ја објавува во регистарот на алатки, а тоа е она што администраторскиот интерфејс го прикажува на /admin/advanced/tools — вградени алатки, MCP-алатки, алатки од пакети и алатки за извршување во еден список, секоја со својот извор и статус.
Проектирана алатка има еден од три статуси: active, pending_review или disabled. Алатките од заедничка инсталација стигнуваат како pending_review и мора да се одобрат на таа страница пред агент да ги види; алатките од сопствената инсталација на ниво user се активни веднаш, бидејќи единствената изложена личност сте вие. Прегледот се повторува и не е еднократна церемонија: ако подоцнежна проверка открие дека описот или шемата на алатката се променети, таа се враќа на pending_review и не се нуди додека некој не ја погледне промената.
Кои агенти потоа можат да ја повикаат активната алатка, се одлучува на два начина:
- Врската создадена преку продавницата на апликации бара изричит грант. Агентот ја добива алатката само кога грант ја именува, а грантот се проверува наспроти тековниот отпечаток на алатката, па измената на алатката бара нова одлука.
- Инаку алатката е вклучена стандардно за агентите во досегот на нејзиниот опсег, а поединечните агенти се исклучуваат на панелот со деталите за алатката.
Грантот именува точно еден субјект — улога или агент, никогаш двете — и одбивањето секогаш ја победува дозволата. За врска на ниво user прашањето воопшто не се јавува: секој агент со кој разговара тој човек може да ја користи, а единствено експлицитното исклучување ја задржува.
Нешто што лесно се бара на погрешно место: /settings/accounts во администраторскиот интерфејс се поврзани сметки — Slack, поштенски сандачиња, претплати за модели и OAuth-врските кон Linear, Jira, GitHub и Trello што стојат зад надворешните табли. MCP-конекторите се на /admin/apps, а алатките што тие ги создаваат се на /admin/advanced/tools.
Порти за одобрување на повиците на алатки
Некои повици на алатки застануваат и чекаат човек. Кога тоа ќе се случи, извршувањето не паѓа: повикот се замрзнува — името на алатката, хеш од нејзините аргументи и доволно состојба за продолжување — и се појавува барање за одобрување на /api/approvals, што некој треба да го одговори. Продолжувањето е идемпотентно, па дуплирано одобрување не може да го изврши повикот два пати. Лицето што одлучува ја гледа ограничената резиме-верзија на она што се бара; точните аргументи и потеклото на извршувањето остануваат на серверот.
Постојат два различни портали, и се конфигурираат поинаку.
- Структурни порти се својство на одредени вградени алатки и не се конфигурабилни. Испраќањето пошта од сопственото поштенско сандаче на агентот или од поврзано, испраќањето Gmail-нацрт, исклучувањето на поштенска сметка, создавањето, менувањето или откажувањето на календарски настан и дејство во прелистувач што би пишувало на сајт на кој прелистувачот не е најавен, сите се порти на овој начин. Добиваат прозорец од 24 часа за одговор, наместо вообичаените 30 минути.
- Порти на политика доаѓаат од правила на политиката за парот
tool/invoke. Правилото што дозволува повик може да носиrequiresApproval, и без проверено одобрување проценката ја враќаAPPROVAL_REQUIREDнаместо да извршува. Правилата се проценуваат најпрво одбивање и се подредени по опсег.
Кој административен екран пишува правило на политиката requiresApproval за алатка — моделот на податоци и спроведувањето се и двете на место, но не можевме да го потврдиме екранот што го пишува таквото правило.
Поврзување на надворешен агент со Nessie
Другата насока. Nessie работи со свој MCP-сервер на POST /mcp, преку streamable HTTP, и е без состојба: секој повик носи сопствен акредитив и сам го разрешува својот актер, па нема сесија за која да се врзе клиент за една реплика. ChatGPT, Claude, Claude Code, Codex или агент на нечиј лаптоп може да работи со вашите табли, документи и клиенти од алатката што тој човек веќе ја користи. Чекор по чекор за секоја апликација е во Поврзување ChatGPT, Claude и други AI апликации.
Што всушност е спарен акредитив
Ова е делот што треба правилно да се разбере, бидејќи очигледниот ментален модел — API-клуч со придружени дозволи — е погрешен.
Спарениот акредитив никогаш не е идентитет. Тој именува човек, а секој повик на алатка се извршува како тој човек, преку истите сервисни функции што ги повикуваат HTTP-рутите. Агентот затоа не може да стигне до ништо што личноста што му го позајмила не би можела да стигне до него со кликање. Опсезите секогаш само ја стеснуваат таа доброта; нема опсег што ја проширува.
Живоста се чита повторно на секој повик, никогаш не се верува од токенот: отповикување, истекување, верзијата на токенот на корисникот, членството во организацијата и тековната улога. Деградација, деактивација или „одјавете ме насекаде“ стигнуваат на следниот повик на агентот, а не на истекувањето на акредитивот.
Токенот е непрозирен, со префикс nag1_, се чува само како SHA-256 хеш и важи 90 дена. Се одбива со специфичен 403 на која било рута освен MCP-крајната точка — да се претстави на друго место не е делумен успех што треба да се обиде повторно, и тоа е она што ја спречува „му позајмив на агентот моите табли“ да значи „му позајмив мојата сметка“.
Два начини за поврзување
Апликација што може да отвори прелистувач — ChatGPT, Claude, Claude Code, Codex — го користи MCP-профилот за авторизација: OAuth 2.1 со PKCE (S256), динамичка регистрација на клиент на POST /mcp/oauth/register, токени за освежување и индикатори на ресурси. Апликацијата ја испраќа личноста на /settings/security, таа избира што смее да прави и до кои од нејзините тимови има пристап, а прелистувачот се враќа во апликацијата со код. Нејзиниот токен за пристап важи еден час и се освежува; врската трае 90 дена.
Агент од командна линија не контролира прелистувач и не може да држи повратен URL, па наместо тоа се спарува со грантот за уред (RFC 8628).
- Агентот вика
POST /mcp/auth/deviceсоclientNameиscopesшто ги сака. Добива назадdevice_code, кратокuser_code,verification_uriиverification_uri_completeсо кодот веќе во барањето, плус интервалот на прашањеintervalиexpires_in. Го печати URI-то. - Некој човек го отвора тој URI додека е најавен, на
/settings/security. Гледа кој агент бара, во чие име би работел, до кога и точно што би можел да прави — и избира Дозволи или Не дозволувај. - Агентот прашува на
POST /mcp/auth/tokenсоdeviceCode, почитувајќиauthorization_pending,slow_down,expired_tokenиaccess_denied. При успех добива{ access_token, token_type, scope, expires_at }.
Во двата случаја има човечки чекор, бидејќи акредитивот ги наследува правата на човекот, па човекот мора да избере да му ги позајми. Ништо тука не создава пристап од ниоткаде. Поврзувањето може да се исклучи за целата организација на /admin/security?tab=programs, а тој одговор се проверува кога некој дозволува врска, а не кога агент ќе почне една.
Откривање
Неавтентициран POST /mcp одговара со 401 и заглавие WWW-Authenticate што упатува на /.well-known/oauth-protected-resource (RFC 9728), кое го именува овој извор како авторизационен сервер; неговите метаподатоци на /.well-known/oauth-authorization-server (RFC 8414) ги именуваат крајните точки за регистрација, авторизација, токен и отповикување. Тој синџир е сè што му треба на клиентот откако ќе ја добие адресата. За да ја најде адресата од домен, агентот го чита /.well-known/ai-catalog.json, кој го именува Server Card на /mcp/server-card (MCP Server Cards, SEP-2127). Крајните точки на грантот за уред се наведени во документот за заштитениот ресурс под x-nessie-device-authorization.
Едно распоредување може да одговара и на втора, пократка адреса: https://nessie.works/mcp на Nessie Cloud се проксира до API-то, а клиент што дошол по тој пат ја добива таа адреса назад како ресурс, додека најавата останува на API-то. Пренасочување не би помогнало, бидејќи клиентот одбива метаподатоци што именуваат која било адреса освен онаа што му била дадена. Операторот ги наведува овие извори во NESSIE_MCP_ALIAS_ORIGINS.
Опсези и алатки
Опсезите се намерно грубо поставени — опсег што никој не може да го објасни никој не го поставува точно. Врската што допира повеќе тимови ги наведува со nessie_team_list, а секоја друга алатка потоа го именува својот teamId.
| Опсег | Допира до |
|---|---|
boards_read | Проекти, табли и задачи, со нивните коментари, датотеки, ознаки, типови и списоци за проверка |
boards_write | Создавање, уредување и поместување задачи и сè што е на нив |
documents_read | Простори на знаење, документи и табели |
documents_write | Нацрт и уредување на нив, и барање за објавување на документ |
clients_read | Пораките од клиентите, контактите, листите на контакти, билтените и формуларите за контакт |
clients_write | Белешки, преземање, доделување и затворање разговори, листи на контакти и подготвување билтени |
clients_send | Сè што клиентот прима: одговор, прва е-пошта или SMS. Никогаш не е означено, освен ако личноста не го означи |
website_tools | Алатките на страниците од регистрираната веб-страница на вашиот тим, управувани во хостиран прелистувач што можете да го контролирате. Никогаш не е означено, освен ако личноста не го означи |
Повик без опсегот што му е потребен се враќа како резултат на алатка што го именува опсегот што треба да се побара, а не како грешка во транспортот, па моделот може да каже нешто корисно наместо да повторува во ѕид.
Нема посебно семејство алатки за надворешни следачи. Табла е табла, без оглед дали нејзините задачи потекнуваат од Nessie или се пренесени од Linear, Jira, GitHub или Trello, па едно множество алатки ги покрива двете, а секоја задача вели од каде е. Разликата е во пишувањето: табла пренесена од извор само за читање одбива запис со зборови, велејќи му на агентот дека задачата ја поседува другиот систем и дека повторувањето нема да помогне.
Објавувањето документ е одобрување, никогаш опсег
Агентите подготвуваат нацрти; човек објавува. Тоа правило за агентите на Nessie се спроведува со одбивање на агент-актер директно — но спарениот акредитив се разрешува како човек, па тоа одбивање не може да го фати. Портата мора да биде на друго место.
Затоа nessie_doc_publish не објавува. Отвора барање за одобрување knowledge.page.publish — истото што го отвора и агент на Nessie — и враќа { status: "awaiting_approval", approvalId }. Повторното прашање го враќа истото барање, наместо да отвори второ. Одлуката се носи на истиот начин како секоја друга одлука за објавување во Nessie: од човек, за тој документ, во моментот кога постои.
Намерно нема опсег за објавување. Имаше еден — ознака при спарувањето што вели дека агентот може да објавува — и беше повлечен. Еднаш и за деведесет дена одлучуваше прашање што производот го поставува по документ секаде другаде, и одлучуваше пред документот да постои, па личноста што ја означила не можеше да знае што се согласува да објави. nessie_doc_publish бара documents_write, бидејќи прашањето не е бесплатно — ја чита страницата и ја става одлуката пред некого — но тој опсег не дава ништо за објавувањето.
Два идентитети се запишуваат на барањето, и разликата е носечка. Барателот е акредитивот, никогаш човекот во чие име дејствува. Бараниот одобрувач е тој човек, и само тој може да одговори. Ако барањето го именува личноста како барател, правилото што спречува некој да го одобри сопственото барање би ја дисквалификувало единствената личност што има право да одлучува.
Гледање и отповикување на спарените врски
Спарените агенти на една личност се наведени на /settings/security, со ознака и контрола за отповикување за секој. Сопственик или администратор на организација ги гледа сите акредитиви во организацијата на /admin/security?tab=programs — како се викаат, што смеат да прават, дали се живи и чија сметка ја позајмуваат — и може да отповика кој било. Личниот список останува само за самиот корисник: список на живи акредитиви е список на упориште, а не општо читање.
Промените направени преку акредитив се припишуваат на човекот што го позајмил и го носат идентификаторот на акредитивот во метаподатоците на дневникот, па дневникот може да го разликува уредувањето на личноста од она што агентот го направил за неа.
Што уште не е достапно
Експлицитно, бидејќи јазот помеѓу можностите на протоколот и онаа на даден сервер е местото каде документацијата обично лаже:
- Разговорите, каналите, извршувањата и управувањето со агенти не се изложени преку MCP.
- Програмата подготвува билтен, а човек го испраќа: ништо не испраќа, не закажува и не брише кампања, а самата е-порака се пишува во дизајнерот.
- Поврзувањето и спојувањето контакти, промените на шемата на CRM-от, увозите и поставувањето канали остануваат кај човек во прелистувачот.
- Прекинувачот за поврзување е поставка на ниво организација. Поставки на ниво тим и лични надзапишувања денес не може да ги постави ниту тим, ниту личност.