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, refresh токени и индикатори за ресурс. Приложението изпраща човека към /settings/security, той избира какво може да прави и кои от неговите екипи достига, а браузърът се връща към приложението с код. Неговият access токен важи един час и се подновява; връзката живее 90 дни.
Агент от командния ред не контролира браузър и не може да държи callback URL, затова се сдвоява чрез device authorization grant (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) и назовава този origin като сървър за удостоверяване; метаданните му на /.well-known/oauth-authorization-server (RFC 8414) назовават крайните точки за регистрация, упълномощаване, токен и отмяна. Тази верига е всичко, от което клиентът се нуждае, след като има адреса. За да намери адреса по домейн, агентът чете /.well-known/ai-catalog.json, който посочва Server Card на /mcp/server-card (MCP Server Cards, SEP-2127). Крайните точки на device grant са изброени в документа за защитения ресурс под x-nessie-device-authorization.
Внедряването може да отговаря и на втори, по-кратък адрес: https://nessie.works/mcp на Nessie Cloud се препраща към API, а клиент, дошъл по този път, получава обратно този адрес като ресурс, докато входът остава при API. Пренасочване не би работило, защото клиентът отказва метаданни, които назовават друг адрес, освен този, който му е бил даден. Операторът изброява тези origin-и в NESSIE_MCP_ALIAS_ORIGINS.
Обхвати и инструменти
Обхватите са умишлено груби — обхват, който никой не може да обясни, никой не го задава правилно. Връзка, която достига повече от един екип, ги изброява с nessie_team_list, а всеки следващ инструмент тогава назовава своя teamId.
| Обхват | Достига |
|---|---|
boards_read | Проекти, табла и задачи, с техните коментари, файлове, етикети, типове и чеклисти |
boards_write | Създаване, редактиране и преместване на задачи и всичко към тях |
documents_read | Пространства за знание, документи и електронни таблици |
documents_write | Изготвяне и редактиране на тях и искане за публикуване на документ |
clients_read | Входящата кутия на клиентите, контакти, списъци с контакти, бюлетини и формуляри за контакт |
clients_write | Бележки, поемане, възлагане и затваряне на разговори, списъци с контакти и подготовка на бюлетини |
clients_send | Всичко, което получава клиент: отговор, първи имейл или текстово съобщение. Никога не се отмята, освен ако човекът сам не я отметне |
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, импортите и настройката на канали остават за човек в браузъра.
- Превключвателят за свързване е настройка на ниво организация. Настройки за екип или лични изключения днес не може да зададе нито екип, нито човек.