Przejdź do treści

MCP — narzędzia, których nikt tutaj nie musi pisać

Serwery Model Context Protocol to odpowiedź tej platformy na „nie da się napisać konektora do wszystkiego”.

Organizacja wskazuje serwer, jego narzędzia pojawiają się w Builderze i po naszej stronie nie zmienia się żaden kod.

Wszystko w katalogu capability to kod, który napisaliśmy i trzymamy na 100% pokrycia. Wszystko tutaj to URL, który ktoś wkleił.

To nie są alternatywy

Capability to właściwy kształt dla czegoś, co platforma musi zagwarantować — strażnika budżetu, sandboksa, retrievalu, który cytuje swoje źródła.

MCP to właściwy kształt dla kilkudziesięciu produktów SaaS, z których firma akurat korzysta, gdzie jedyną liczącą się gwarancją jest „narzędzia są tymi, które opublikował dostawca”.

Połączenie

Jeden wiersz wskazujący zdalny serwer. Transport — streamable HTTP albo server-sent events — jest wnioskowany z URL-a, więc serwer obsługujący wyłącznie SSE, taki jak Atlassian, działa obok serwera na streamable HTTP i nie ma tu niczego do konfigurowania.

name Zarazem prefiks narzędzi. Zobacz Kolizje nazw
url Sprawdzany pod kątem SSRF, zanim w ogóle wyślemy do niego żądanie
auth_token Zapieczętowany w vaulcie, nigdy nie zwracany przez żaden endpoint
allowed_tools Lista dozwolonych albo null, czyli „wszystko, co serwer oferuje”. Powiązanie zawęża ją dalej — zobacz niżej
is_enabled Wyłączenie bez utraty poświadczenia
include_instructions Dodaje własne instrukcje serwera z initialize do instrukcji agenta. Domyślnie wyłączone - to tekst operatora serwera, czytany jak instrukcje agenta - włączane w oknie Edit połączenia
last_status Co pokazało ostatnie odpytanie i kiedy

Adres, do którego ten deployment nie może sięgać, zostaje odrzucony — i odmowa to mówi

URL, który rozwiązuje się na adres loopback, prywatny, link-local albo współdzielony CGNAT, taki, który nie rozwiązuje się wcale, taki, który niesie poświadczenia w userinfo, taki na schemacie innym niż http/https albo po prostu źle sformułowany, wraca jako 400 wskazujące url jako pole, które zawiniło — przy tworzeniu, przy edycji i przy starcie flow OAuth, zarówno osobistego, jak i na poziomie organizacji.

Poza tym wskazuje host, nigdy URL: URL niesie klucz w query stringu, a zdanie wyjaśniające odmowę jest napisane w tym repozytorium, a nie jest tym, co parser URL-i miał do powiedzenia o wysłanym przez ciebie tekście.

Kiedyś było to 500 bez szczegółów i traceback w logu, co czyta się jak awaria platformy, a nie jak adres do poprawienia (#861) — self-hosting i wklejenie URL-a z localhost to przypadek zwyczajny, nie egzotyczny.

Operator może pozwolić połączeniu sięgać do serwera we własnej sieci wdrożenia, na przykład do usługi compose albo serwera w VPN-ie lub tailnecie. W tym celu wpisuje jego host do MCP_ALLOWED_HOSTS. Host z listy pomija tylko sprawdzenie adresu. URL nadal musi mieć http albo https.

Do serwera z listy można też logować się przez OAuth. Taki serwer często sam prowadzi logowanie, więc jego wykrywanie, rejestracja klienta i żądania tokenów mogą sięgać do hostów z listy, i do żadnego innego adresu prywatnego. Każde żądanie nadal jest przypięte do adresu, który sprawdzono, a nazwa z listy, która odpowiada adresem loopback, link-local albo adresem metadanych chmury, jest odrzucana. Logowanie do serwera publicznego nigdy nie sięga do hosta z listy, nawet gdy jego metadane go wskazują.

Każde konto we wdrożeniu może wtedy sięgnąć do każdego portu tego hosta. Wpisuj więc tylko serwer, który sprawdza token, i nigdy localhost ani usługi tego stacku, takiej jak app, db czy redis. Lista jest czytana przy zapisie połączenia oraz przy każdym logowaniu i odświeżeniu tokenu. Usunięcie hosta nie rozłącza zapisanego połączenia, ale połączenie OAuth do niego przestaje odnawiać token.

Osobiste albo dla całej organizacji

Dwa rodzaje, i o tę różnicę właśnie chodzi. Okno połączenia pyta o to jednym wyborem, prostymi słowami: Jedno wspólne konto - konfigurowane raz, zwykle przez administratora na koncie serwisowym, i używane przez każdego agenta - albo Moje własne konto, używane przez Ciebie i przez agentów ustawionych tak, by działali w imieniu każdej osoby. Serwer z katalogu, do którego ludzie się logują (Notion, Linear, Gmail), zaleca konto każdej osoby; serwer na klucz zaleca wspólne.

Osobiste (MCP servers → You) obejmuje jednego członka i jest osiągalne przez jego własnego asystenta oraz przez agenta powiązanego z własnym kontem każdej osoby, gdy to ona z nim rozmawia.

Jego poświadczenie jest zapieczętowane dla członka, a nie dla organizacji — połączenie osobiste żadnej nie ma, a jego właściciel może należeć do kilku, więc przypisanie go do tej, która była aktywna w chwili dodawania, sprawiłoby, że token stałby się nieczytelny w momencie przełączenia.

Organizacyjne obejmuje organizację, jest bramkowane przez mcp:manage i jest jedynym rodzajem, który spec opublikowanego agenta może wskazać po id.

Serwer organizacji może należeć do działu. W sekcji Kto może z tego korzystać dialog podłączania proponuje Wszyscy - domyślnie - albo Wybrane osoby, znajdowane przez wpisywanie; serwer staje się wtedy prywatny i udostępniony każdej z nich na poziomie use. Oni i osoba, która go podłączyła, widzą go i mogą go podpiąć; właściciele i administratorzy widzą każdy serwer. Przycisk Kto może z niego korzystać przy serwerze zmienia to później. Agent, który już go używa, działa dalej dla każdego, kto może go uruchomić: ten wybór decyduje, kto może serwer wybrać, a nie kto dostaje przez niego odpowiedzi, dlatego Builder oznacza go w sekcji skąd pochodzi wiedza agenta.

Opublikowany agent, który sięgałby po różne narzędzia zależnie od tego, czyja sesja go zbudowała, nie dałby się ani przejrzeć, ani przemyśleć — i to jest cały powód tego ograniczenia. Osobiste połączenie i tak dociera do agenta, jedną drogą: powiązanie z własnym kontem każdej osoby wskazuje usługę, a ten, kto rozmawia z agentem, dostarcza do niej własne połączenie.

GET  /api/v1/me/mcp-connections     personal
GET  /api/v1/mcp-connections        organization, requires mcp:manage; each server
                                    narrowed to groups only for them
POST /api/v1/mcp-connections/{id}/test   probe it, list its tools, store the status
GET  /api/v1/mcp-connections/{id}/sharing   who it is narrowed to, and the same
                                            grant routes as an agent's

Dwie nazwy, i odpowiadają na różne pytania

Połączenie niesie nazwę i prefiks narzędzi, a ograniczony jest tylko ten drugi. Prefiks to małe litery, cyfry i myślniki, unikalny wśród serwerów organizacji, bo tyle może unieść nazwa narzędzia i to właśnie czyta model, zanim którekolwiek wywoła. Nazwa jest dowolnym tekstem, jest opcjonalna i to ją widzi człowiek.

Ten podział zaczyna się opłacać w chwili, gdy organizacja podłącza jedną usługę dwa razy. Dwa konta Notion muszą być notion i notion-2, a żadne z nich nie mówi, do którego workspace'u sięga; Marketing workspace i Engineering handbook już tak.

Prefiks nigdy nie znika

Gdziekolwiek pokazywana jest nazwa, obok pokazywany jest prefiks. Wywołania narzędzi w runie są zapisywane pod prefiksem, więc nazwa, która by go zastąpiła, zostawiłaby pytanie „dlaczego to wywołało notion-2_search” bez odpowiedzi na stronie, która nazywa konto. Wyczyść nazwę, a połączenie znów czyta się jako swój prefiks — dokładnie tak, jak robiło, zanim nazwę ustawiłeś.

Spec wskazuje połączenia organizacji w mcp_servers, po jednym wpisie na powiązanie. Usunięcie połączenia, które agent wciąż wskazuje, odbiera agentowi ten serwer, a nie runowi.

Które narzędzia i kto o tym decyduje

Dwie listy dozwolonych i żadna nie unieważnia drugiej.

Na połączeniu allowed_tools to decyzja jednego administratora dla wszystkich z nim powiązanych — narzędzia, po które ta organizacja w ogóle godzi się sięgać na tym serwerze. Na powiązaniu zawęża się ona dalej, osobno dla każdego agenta. Dzięki temu jeden serwer może obsłużyć agenta tylko do odczytu i agenta edytującego, bez podłączania go dwa razy.

Przecinają się w czasie runu. Agent nie sięgnie po narzędzie, które połączenie wyklucza — także po takie, które wykluczono już po opublikowaniu agenta: powiązanie traci to narzędzie, a nie agent serwer. Null po którejkolwiek stronie oznacza brak zawężenia z tej strony, więc powiązanie, które nie wymienia niczego, dostaje to, na co pozwala połączenie — czyli to, co robiło każde powiązanie, zanim to istniało.

Builder wypisuje narzędzia serwera z jego ostatniego udanego odpytania, zapisanego na połączeniu. Odpytanie wydzwania do zewnętrznej firmy i jest bramkowane przez connections:manage; autor agenta ma agents:edit i potrzebuje listy, z której wybiera, więc lista jest odczytywana, a nie pobierana.

Połączenie, którego nikt jeszcze nie odpytał, nie ma katalogu do zaoferowania — lista wyboru mówi to wprost i kieruje na stronę serwerów, bo tam sprawdza się połączenie. Powiązanie, które już wymienia narzędzia, pokazuje właśnie je, więc to, z czym jest związane, pozostaje widoczne i wciąż można je zawęzić.

Które wywołania czekają na człowieka

Każde powiązanie ma politykę approval dla narzędzi swojego serwera. Domyślna, none, przepuszcza każde wywołanie, tak jak narzędzia capability działają, dopóki ktoś nie obejmie ich bramką. writes wstrzymuje każde narzędzie, którego serwer nie oznaczył jako tylko do odczytu (readOnlyHint w MCP), aż człowiek zatwierdzi wywołanie: karta pokazuje dokładne argumenty, a wykonywane są te zatwierdzone. all wstrzymuje każde wywołanie. Wskazówka „tylko do odczytu” to deklaracja samego serwera, więc writes jest tak ścisłe, jak serwer jest uczciwy — dla serwera, którego nie kontrolujesz, wybierz all.

Własny szablon Architekta prosi o writes dla serwera platformy, więc nie tworzy niczego bez osoby, w której imieniu działa. Powiązanie każdego agenta z tym serwerem trzyma co najmniej writes, także przy none: jego narzędzia działają z uprawnieniami osoby, która pyta, również administratora. Dwa odczyty czekają jak zmiany: read_conversation udostępnia całą wcześniejszą rozmowę, a get_project instrukcje wybranego projektu. Przeczytana strona nie może po cichu wywołać żadnego z tych ujawnień.

W Builderze ustawienia serwera mówią to osobno dla grup: Odczyt i Zmiany działają bez pytania albo najpierw pytają.

Przez czyje konto mówi powiązanie

Powiązanie jest jednego z dwóch rodzajów, a Builder pyta, którego, w ustawieniach serwera, które pokazują też Twoje własne konta w tej usłudze.

Konto organizacji (account: organization) wskazuje jedno z połączeń organizacji i odpowiada za wszystkich, na każdej powierzchni. To ustawienie domyślne i to wobec niego przegląda się agenta.

Własne konto każdej osoby (account: personal) wskazuje zamiast tego usługę z katalogu — catalog_key: notion — i żadnego połączenia. Kto rozmawia z agentem, podłącza swój własny Notion w MCP servers → You, a agent mówi do Notion jako on: w dashboardzie, w wiadomości prywatnej i w kanale tak samo. Ślad audytowy po stronie Notion mówi wtedy, kto co zrobił — czego współdzielone konto serwisowe nigdy nie potrafi.

Kontem jest autor tej wiadomości, nigdy autor wątku. Ania pyta na #ops i dostaje odpowiedź ze swojego Notion; Bartek zadaje to samo pytanie w tym samym wątku i dostaje swoją albo słyszy, że ma podłączyć konto. Wątek nie jest granicą, którą czyjekolwiek poświadczenia powinny przekraczać — gdyby pierwsza osoba, która się podłączy, odpowiadała za wszystkich po niej, podpięcie Notion w kanale oddawałoby go kanałowi.

Gdzie nikt nie rozmawia, narzędzi nie ma — i agent to mówi

Klucz API, osadzony widget, harmonogram, trigger i nadawca z kanału, który nie powiązał swojego konta czatu, nie mają konta, przez które mogliby mówić. Run idzie dalej bez tego serwera, z nietkniętymi pozostałymi powiązaniami, a do jego instrukcji dokładany jest jeden wiersz mówiący, której usługi brakuje i dlaczego — więc gdy ktoś poprosi o Notion, agent odpowie linkiem, który go podłącza (/mcp-servers?connect=notion), albo zdaniem „najpierw wyślij /link do tego bota”, gdy brakującym elementem jest konto czatu.

Czat w dashboardzie pyta wtedy, gdy agent potrzebuje usługi, nie wcześniej. Usługa, której osoba nie podłączyła albo musi autoryzować ponownie, trafia do modelu jako connect_account: gdy pytanie wymaga Notion, run zatrzymuje się na karcie z przyciskiem podłączenia, a po podłączeniu konta ten sam run idzie dalej z narzędziami Notion. Pominięty, idzie dalej bez nich. Kontrolki czatu wypisują też osobiste usługi agenta wraz z ich statusem, więc nowy członek widzi, co podłączyć, jeszcze zanim zapyta. Zobacz stronę konsoli.

Prefiksem narzędzi osobistego powiązania jest klucz katalogowy, niezależnie od tego, jak każdy nazwał swoje połączenie, więc agent przedstawia wszystkim notion_search. allowed_tools na powiązaniu to sufit ustawiony przez administratora; własne połączenie danej osoby może zawęzić dalej, a jedno z drugim się przecina.

Trzy rzeczy, których publikacja odmawia

Osobiste powiązanie z kluczem, którego katalog nie ma — nic nigdy nie dopasowałoby do niego połączenia członka. Dwa osobiste powiązania z jedną usługą — te same narzędzia dwa razy pod jedną nazwą. I osobiste powiązanie, którego klucz jest zarazem nazwą połączenia organizacji powiązanego z tym samym agentem, co postawiłoby dwa serwery pod jednym prefiksem; Pydantic AI odrzuca zduplikowane nazwy narzędzi i tura się przerywa.

Kolizja, która dociera do runa, zostaje zawężona, a nie utracona

Publikacja to punkt w czasie, a nazwę połączenia można później edytować, więc agent opublikowany przed tym sprawdzeniem albo taki, którego połączenie przemianowano na kolidującą nazwę, wciąż może dotrzeć do runa z dwoma serwerami pod jednym prefiksem. Taki run zatrzymuje pierwszy z nich, który odpowie na odpytanie, resztę odrzuca i mówi modelowi, który serwer jest w tej turze niedostępny — a gdy oba noszą jedną nazwę, przez które powiązanie mówi — zamiast gubić to w wierszu logu, którego nikt nie czyta. Naprawą po stronie autora jest przemianowanie jednego z dwóch połączeń.

Agent może powiązać usługę na oba sposoby — firmowe Notion z podręcznikiem i własne Notion każdej osoby — o ile połączenie organizacji nie nosi nazwy klucza katalogowego, bo to ten prefiks dostaje własne konto każdej osoby.

Kilka kont jednego serwera

Jeden agent może naraz czytać firmową skrzynkę i info@. Do osoby, która ma kilka własnych kont w jednej usłudze, agent sięga przez każde z nich: konto oznaczone przez nią jako główne w MCP servers → You (a bez tego to podłączone jako pierwsze) zachowuje zwykły prefiks, outlook_send, a każde kolejne dokłada swoją etykietę, outlook_info_send (dwie etykiety, które w nazwie narzędzia brzmią tak samo, Sales US i Sales-US, rozróżnia krótki identyfikator konta przy drugiej). Które to konta, decyduje osoba tym, co podłączy - powiązanie tego nie zawęża.

Konta organizacji wiążą się obok siebie tak samo: każde jej połączenie z serwerem to osobne powiązanie pod własną nazwą i z własnymi narzędziami. W Builderze ustawienia serwera wypisują powiązane konta z przyciskiem Add another account. Gdy run sięga do jednej usługi przez więcej niż jedno konto, jeden wiersz jego instrukcji wymienia każde konto obok jego prefiksu i każe modelowi dopytać, gdy nie wiadomo, o które konto chodzi.

Drugie konto w serwisie musi mieć nazwę: jego etykieta odróżnia oba konta w każdym wyborze i zatwierdzeniu, więc formularz prosi o nią przed połączeniem, a API odrzuca nienazwane drugie konto na polu label.

Zatwierdzenie mówi potem, które konto działa. Wywołanie przez połączenie z etykietą albo przez jedno z kilku kont w tym samym serwisie niesie nazwę tego konta: czat, Activity i dashboard pokazują ją obok akcji, wiadomość w Slacku lub Telegramie pyta o zgodę „to send in Gmail as Work”, a e-mail z prośbą o zatwierdzenie podaje ją po nazwie narzędzia. Jedno konto bez etykiety nie ma od czego się odróżniać, więc nic nie jest dodawane.

Uwierzytelnianie

Trzy tryby — i to jedyne, co naprawdę różni serwery między sobą.

Przeważnie publiczne serwery z dokumentacją — serwer dokumentacji Cloudflare nie potrzebuje żadnych poświadczeń.

Token bearer wklejony raz i zapieczętowany.

Każdy wpis w katalogu niesie własną podpowiedź, skąd go wziąć, bo ogólne instrukcje są głównym powodem, dla którego konfiguracja tokena się nie udaje.

PATCH z auth_token: "" go czyści.

Większość serwerów biznesowych — Notion, Linear, Atlassian, Asana — zwraca 401 z nagłówkiem WWW-Authenticate wskazującym metadane protected-resource z RFC 9728, i stamtąd rusza flow.

  1. Wykrycie — odpytaj serwer, ustal jego authorization server, pobierz metadane RFC 8414.
  2. Rejestracja — dynamiczna rejestracja klienta wg RFC 7591. Serwer, który nie publikuje endpointu rejestracji — tak jest u HubSpota — odmawia w tym miejscu i jedyna droga dalej to klient zarejestrowany u providera ręcznie: dialog podłączania przyjmuje jego client ID i secret w sekcji Własny klient i pokazuje redirect URL, który provider musi mieć wpisany dokładnie w tej postaci.
  3. Zgoda — URL autoryzacji z PKCE, ze state i wskaźnikiem zasobu wg RFC 8707; przeglądarka idzie pod ten adres.
  4. Wymiana — callback wymienia kod na tokeny, po czym przekierowuje przeglądarkę z powrotem na stronę MCP servers, która mówi, czy się udało. To jedyne miejsce, w którym można przekazać wynik: człowiek patrzy na stronę, na którą sam nie wszedł.
  5. Odświeżenie — gdy access token wygaśnie.
sequenceDiagram
    participant O as An operator
    participant P as AgenticOS
    participant S as The MCP server
    participant A as Its authorization server
    P->>S: connect
    S-->>P: 401 + WWW-Authenticate (RFC 9728)
    P->>S: fetch protected-resource metadata
    P->>A: fetch RFC 8414 metadata, then register (RFC 7591)
    P-->>O: a PKCE consent URL
    O->>A: consents in a browser
    A-->>P: callback with the code
    P->>A: exchange for tokens, refresh later
    P-->>O: back to the MCP servers page, with the outcome

Sprawdzany jest każdy URL w tym flow, nie tylko ten, który wpisałeś

Discovery oznacza, że większość adresów, pod które dzwonimy, wybiera zdalny serwer

Kiedyś wystarczyło podłączyć jeden wrogi serwer: nazwa mogła odpowiedzieć adresem publicznym na sprawdzenie i prywatnym na żądanie, które po nim szło (#860).

Adres, który przeszedł sprawdzenie, jest teraz adresem, z którym nawiązywane jest połączenie.

Żądanie idzie na rozwiązany adres IP, z oryginalnym hostem w nagłówku Host i w TLS SNI, więc certyfikat wciąż jest weryfikowany wobec nazwy i nic nie rozwiązuje jej po raz drugi.

Ta druga połowa ma tu większe znaczenie niż gdziekolwiek indziej w produkcie. Adres, który wpisuje operator, to dopiero pierwszy przeskok — authorization server, token endpoint, registration endpoint i każde przekierowanie po nich są wskazywane przez własne dokumenty discovery zdalnego serwera. Nikt w twojej organizacji nie musiał być atakującym.

Przekierowania są podążane po jednym przeskoku, z limitem pięciu, każde z własnym sprawdzeniem. 302 na nowy host jest rozwiązywane od nowa, a nie brane na wiarę.

Gdy nazwa odpowiada kilkoma adresami, każdy z nich jest sprawdzany i zachowywany, a po adresie, który odrzuci połączenie, idzie następny — to samo, co zwykły klient dostaje z resolvera, bez pytania DNS po raz drugi. Nazwa odpowiadająca jednym adresem publicznym i jednym prywatnym zostaje odrzucona w całości, a nie zawężona do swojej publicznej połowy.

Zostają dwa brzegi, oba wąskie i oba celowe:

  • URL zgody jest sprawdzany, a potem przekazywany czyjejś przeglądarce, która rozwiązuje go sama. Nie ma tu czego przypinać.
  • Własny URL połączenia jest sprawdzany przy zapisie i rozwiązywany ponownie, gdy agent działa — wpisuje go operator, więc przestawienie go wymaga bycia operatorem. Host z MCP_ALLOWED_HOSTS pomija sprawdzenie adresu, a żądania OAuth połączenia, którego własny host jest na liście, mogą sięgać do hostów z listy, przypięte jak każdy inny krok.

Nic, co wybiera model, w ogóle nie dociera do tego sprawdzenia — i nie powinno: URL wybrany przez agenta należy do safe_download z Pydantic AI.

Za proxy wyjściowym łączy się proxy

HTTP_PROXY i HTTPS_PROXY są respektowane, bo deployment wymuszający proxy wyjściowe straciłby inaczej MCP OAuth w całości — a takie proxy samo w sobie jest kontrolą ruchu wychodzącego.

Na tej ścieżce przypiętym adresem jest to, o co proxy jest proszone, żeby osiągnąć (CONNECT 93.184.216.34:443 albo linia żądania w formie absolutnej dla zwykłego HTTP), a nie to, z czym łączy się ten proces, więc gwarancja kończy się na proxy. TLS wciąż jest end to end, więc certyfikat wciąż jest weryfikowany wobec oryginalnej nazwy.

Proxy z polityką odrzucającą goły adres odrzuci te żądania; wiersz logu zapisywany, gdy proxy jest skonfigurowane, jest po to, by ta awaria dała się odczytać.

Gdy krok się nie powiedzie

Krok, który się nie powiedzie, mówi, który krok się poddał i jakiej klasy rzecz podniosła wyjątek, nigdy tego, co napisał klient po drugiej stronie.

httpx2 wstawia w swój komunikat żądanie, które zawiodło, a te dwa żądania to rejestracja klienta i przyznanie tokena — więc zacytowanie go przeniosłoby do przeglądarki token endpoint, osiągany z poświadczeniami. Błąd pydantica nad nieczytelną odpowiedzią z tokenami odbija payload, który odrzucił, czyli właśnie tokeny. Jedno i drugie zostaje w logu serwera, bo tam operator i tak zagląda.

Dokument discovery wskazujący URL, którego w ogóle nie da się zażądać, to odpowiedź tego samego rodzaju: 400 mówiące, który endpoint był bezużyteczny i że jest źle sformułowany.

To odmowa odrębna od „ten serwer skierował flow na zablokowany adres”. Jedna mówi, że serwer wycelował nas tam, gdzie ten deployment nie pójdzie, druga — że zapisał adres, którego nic nie wybierze; zgłoszenie jednej jako drugiej byłoby pewnym siebie twierdzeniem o tym, po czyjej stronie leży wina.

Bezużyteczna podpowiedź WWW-Authenticate kończy tego kandydata w discovery, a nie całe flow, bo idące po nim URI well-known wywodzą się z URL-a wpisanego przez operatora i mogą jak najbardziej odpowiedzieć.

Do #889 było to 500 z pustym ciałem: httpx2.InvalidURL nie dziedziczy po httpx2.HTTPError, więc żaden z catchów w tym flow go nie widział — i żadne sprawdzenie tutaj widzieć nie mogło, bo URL zostaje odrzucony w trakcie budowania żądania, ponad sprawdzeniem SSRF i ponad klientem z przypiętym adresem. To, czego parser nie umiał odczytać (Invalid port: 'client_secret=…'), jest własnym tekstem zdalnego serwera i zostaje w logu razem z resztą.

Połączenie OAuth organizacji wciąż jest czyjąś zgodą

POST /mcp-connections/oauth/start tworzy połączenie, którego właścicielem jest organizacja — i po to właśnie jest współdzielone konto serwisowe. Ale zgoda u providera pozostaje zgodą osoby, która ją wyraziła: odebranie jej tam dostępu zatrzymuje działanie serwera organizacji do czasu ponownej autoryzacji.

Wyrażaj zgodę z konta, które kontroluje organizacja.

Trzy zasady dotyczące tokenów

Token nigdy nie podąża za przeniesionym URL-em. Edycja URL-a połączenia kasuje jego payload OAuth, oczekujące flow i odwzorowane scope'y — tak samo w połączeniach osobistych, jak i organizacji — więc połączenie czyta się jako „wymaga ponownej autoryzacji”, zamiast wysyłać token wydany dla jednego hosta do innego.

W wierszu organizacji jest to zarazem granica między administratorami: posiadacz mcp:manage, który przestawia połączenie autoryzowane przez innego, nie może sprawić, żeby platforma dostarczyła ten token na nowy host.

Wyłączone połączenie nie wydaje tokenów nigdzie. Ścieżka narzędzi agenta je pomija i portale triggerów też — wywołujący, który zachował connection_id triggera, nie będzie dalej wyliczał repozytoriów ani rejestrował hooków poświadczeniem, które administrator wyłączył.

Usunięcie połączenia zwalnia to, co przez nie zarejestrowano. Każdy trigger zdarzeniowy, którego webhook u providera zarejestrowano automatycznie tokenem tego konta, ma ten hook wyrejestrowany — best-effort, dopóki token jeszcze istnieje — i wraca do ręcznego dostarczania. URL i sekret triggera nadal obowiązują, więc ręczne skierowanie na niego providera dalej działa.

Flow podłączania w portalu GitHuba jest też świadome aktualizacji w drugą stronę: organizacja, która podłączyła wpis katalogowy GitHuba jako zwykłe połączenie z tokenem bearer, zanim istniało flow OAuth, dostaje ten sam wiersz autoryzowany ponownie w miejscu — odnajdywany po swoim kluczu katalogowym, niezależnie od nazwy — zamiast odmowy albo duplikatu, a token bearer działa dalej, dopóki nie wyląduje nowa zgoda.

Co dzieje się w turze

Każdy serwer jest odpytywany krótką wymianą tools/list, zanim tura się zacznie, a odpytania biegną równolegle. Serwer ma 3 sekundy na przyjęcie połączenia i 10 sekund na całą wymianę, bo serwer, który sprawdza token każdego żądania u swojego dostawcy tożsamości, bywa wolny, choć działa. Serwer, który odpowiedział na odpytanie w ciągu ostatnich dwóch minut, z tym samym poświadczeniem, nie jest odpytywany ponownie: kolejna tura rozmowy dołącza go od razu. Jeśli w międzyczasie przestał odpowiadać, ta tura idzie dalej bez jego narzędzi, a następna odpytuje go znowu.

Nazwa narzędzia trafia do modelu jako prefiks połączony z własną nazwą serwera - a dostawcy odrzucają nazwę dłuższą niż 64 znaki albo zawierającą coś poza literami, cyframi, _ i -, odrzucając całe zapytanie. Taka nazwa jest dopasowywana: odrzucane znaki są zamieniane, koniec ucinany i dopisywanych jest osiem cyfr szesnastkowych skrótu, więc dwie długie nazwy pozostają dwoma narzędziami. Serwer jest nadal wywoływany pod prawdziwą nazwą.

Nieosiągalny serwer zostaje pominięty z ostrzeżeniem, a nie podnosi wyjątku

Pydantic AI wchodzi w każdy toolset przy starcie runa, więc martwy serwer przerwałby inaczej całą turę: jeden wygasły token na jednym połączeniu położyłby każdego agenta, który go wskazuje, łącznie z tymi, które nigdy go nie potrzebowały.

Model odpowiada wtedy bez tych narzędzi i wie o tym: instrukcje tury wymieniają serwer, mówią, że nie odpowiedział albo odrzucił połączenie, i każą modelowi powiedzieć, że nie dało się z nim połączyć, zamiast zgłaszać pusty wynik. Dotyczy to także serwera, który odpowiedział chwilę wcześniej i zawodzi, gdy tura się łączy. Słusznie w turze czatu, niesłusznie, jeśli założyłeś, że narzędzie jest tam zawsze.

To świadomy kompromis. Dowiadujesz się o tym przez endpoint /test i last_status, a ślad audytowy zapisuje, co faktycznie się wykonało.

Podłączenie serwera z poziomu Buildera

Zakładka MCP servers agenta wypisuje cały katalog, nie tylko to, co ma poświadczenia. Serwer bez nich nie jest checkboksem — nie ma id połączenia, które spec mógłby przechować — więc karta otwiera dialog podłączenia na miejscu.

Serwer na token albo w ogóle bez poświadczeń podłącza się bez opuszczania strony, a nowe połączenie jest zaznaczane dla agenta, gdy tylko powstanie. Podłączenie sprawdza serwer, a jego narzędzia pojawiają się od razu z tego sprawdzenia, więc wybór serwera, podłączenie go i wybór tego, co agent może wywołać, to jedna ścieżka. Nieudane sprawdzenie mówi w komunikacie, dlaczego, a połączenie zostaje do poprawy.

OAuth otwiera kartę

Ekran zgody należy do providera, więc nie ma gdzie zostać — jest za to sposób, by nie stracić agenta, którego edytowałeś. Dokończ w karcie, która się otworzy, i wróć; serwer pojawi się na liście, gdy będzie autoryzowany.

Jeden serwer podłączony kilka razy

Organizacja może podłączyć ten sam serwer więcej niż raz — Notion z dostępem tylko do odczytu do jednego workspace'u, drugi ograniczony do jednej bazy, trzeci z poświadczeniem administratora. To wspierany kształt, a nie obejście: nazwy są unikalne w obrębie organizacji, a nie w obrębie wpisu katalogowego, a nazwa jest prefiksem narzędzi, więc model widzi notion_readonly_search i notion_admin_search jako różne narzędzia.

Powiąż to, które agent ma mieć, albo kilka obok siebie — zobacz kilka kont jednego serwera. Builder pokazuje jedną kartę na serwer, a jego konta wypisuje w ustawieniach serwera, każde pod etykietą i nazwą.

Cała różnica tkwi w nazwie

notion i notion-2 nikomu nic nie mówią. Nazwij połączenie od tego, do czego może sięgać — notion-handbook, notion-admin — bo to ten ciąg znaków czyta model, gdy decyduje, które narzędzie wywołać.

Kolizje nazw

Narzędzia dostają prefiks z nazwy połączenia

github-work staje się github_work_*, bo dwa serwery udostępniające tę samą nazwę narzędzia sprawiają, że Pydantic AI podnosi wyjątek na duplikatach, co przerywa turę.

Lista dozwolonych filtruje przed nadaniem prefiksu, więc porównuje z nazwami bez prefiksu, wybranymi w UI.

Dwa połączenia, których nazwy sprowadzają się do tego samego prefiksu, są deduplikowane — wygrywa pierwsze, z ostrzeżeniem nazywającym przegranego. Serwery zarządzane przez deployment są układane jako pierwsze, więc wygrywają z połączeniem użytkownika, które trafiło na tę samą nazwę.

Stan, użycie i wywołania

Karta serwera na stronie MCP servers mówi, kiedy któreś z jego kont nie odpowiedziało przy ostatnim sprawdzeniu, a lista jego kont mówi, które i co zwróciło; kto zarządza serwerami MCP, może sprawdzić go tam ponownie. Konto OAuth, którego logowania nie udało się odnowić, jest pokazywane jako wymagające autoryzacji, a nie nieosiągalne, z przyciskiem Autoryzuj, by zalogować się ponownie.

Co piętnaście minut wdrożenie sprawdza każdy serwer organizacji, a każdy run sprawdza przed turą serwery, do których podpięty jest jego agent. Gdy serwer przestaje odpowiadać, administratorzy i właściciele agentów, którzy z niego korzystają, dostają jedno powiadomienie Serwer MCP nie odpowiada na tę awarię, niezależnie od tego, ile sprawdzeń czy runów to wykryje, oraz Serwer MCP znów odpowiada, gdy wróci. Kolejna awaria znów wywołuje alert. Oba przychodzą w aplikacji i e-mailem, a każdy może wyłączyć dowolne z nich w Ustawienia → Powiadomienia. Własne połączenie członka nie wysyła żadnego, a logowanie do odnowienia nie jest liczone jako awaria.

Na stronie MCP każde konto organizacji wymienia agentów, którzy są do niego podpięci, a O co pytały agenty pokazuje ostatnie wywołania jego narzędzi: które narzędzie, który agent, jak poszło i w którym runie. Treść pytań i odpowiedzi nie jest pokazywana - zostaje w rozmowie. Każde wywołanie zapisuje połączenie, które je obsłużyło, więc własne połączenie członka o tej samej nazwie nie trafia na listę, a wywołania sprzed tej zmiany nie są pokazywane wcale. API: used_by w GET /api/v1/mcp-connections i GET /api/v1/mcp-connections/{id}/calls.

Dodaj do agenta wpina konto w wersję roboczą wybranego agenta, a podłączenie konta kluczem lub zakończenie logowania proponuje to samo.

Katalog

Lista wyboru, która startuje pusta i prosi o URL, to lista, z której nikt nie korzysta, więc popularne serwery są dostarczane z metadanymi potrzebnymi do ich podłączenia: URL-em, sposobem uwierzytelniania i tym, co powiedzieć osobie wklejającej poświadczenie.

To lista utrzymywana ręcznie, nie lustro publicznego rejestru. Każdy wpis jest małą obietnicą — że ktoś zajrzał do serwera, że flow uwierzytelniania działa, że opis jest uczciwy — a odbity rejestr takiej obietnicy złożyć nie może.

Co naprawdę dałoby lustrzane odbicie rejestru

Oficjalny rejestr został przeczytany w całości w sierpniu 2026: 20 100 rekordów, z czego 7127 to bieżąca wersja aktywnego serwera, a 5824 niosą hostowany endpoint HTTPS, w sumie na 5141 różnych hostach. Tak więc „tysiące serwerów”, którymi rejestr się chwali, to fakt.

Po zestawieniu z tym katalogiem cztery z tych hostów należały do firmy, którą większość czytelników by rozpoznała, i tutaj ich brakowało — CircleCI, New Relic, Statsig i Lusha, wszystkie cztery są już na liście. Reszta z nieobjętych hostów to serwery jednoprojektowe, proxy na workers.dev, narzędzia SEO i gry: alfabetycznie pierwsze z brzegu to wyszukiwarka cen gruntów, narzędzie do przetargów dla wykonawców i węgierski serwis wyceny okien.

Warto trzymać oba te fakty naraz. Katalogowi nie brakuje wpisów dlatego, że nikt nie szukał; ma taką długość, jaką ma, bo ręcznie sprawdzona lista rzeczy, z których firma naprawdę korzysta, zbiega się w okolicach setki.

Rejestr jest na tej samej liście i w bazie danych

Lustro jest więc dostarczane razem z nim, a /mcp to jedna lista ich wszystkich — najpierw wyselekcjonowany katalog, potem odbity rejestr, stronicowane: ponad 4700 serwerów, tyle, ile pokazuje galeria. Nie wyselekcjonowana siatka z wyszukiwarką sięgającą dalej: jedna lista, jeden pager, jeden licznik.

To wymagało tabeli. mcp_registry_servers jest wspólna dla całego deploymentu i nie ma organization_id — i to jest cały powód, dla którego jest tabelą, a nie pięcioma tysiącami wierszy na tenanta; galeria skilli rozstrzygnęła sąsiednie pytanie odwrotnie, a różnica polega na tym, że katalog nie jest danymi tenanta. Wypełnia ją agenticos cmd mcp-registry-sync, z dołączonego snapshotu albo, z --fetch, z żywego rejestru.

Trzymane w bazie danych, bo pliku nie da się stronicować. Mając tysiące wpisów w pamięci, dałoby się odpowiedzieć na „serwery pasujące do »linear«”, ale nie na „czwartą stronę ich wszystkich” bez wczytania całości i pokrojenia jej. Wraz z tym do SQL-a przeniosło się rankowanie, z tego samego powodu: rankowanie strony to rankowanie tego, co akurat się na niej znalazło. Trzy pasma — serwer nazywający się Linear, potem nazwy, które to tylko zawierają, potem opisy, które o tym wspominają — wewnątrz pasma najpierw krótsza nazwa, więc Stripe bije Sweden Payments (Stripe).

To jedna lista z faktem dopisanym do niektórych wierszy, a nie dwie listy. Wiersz z rejestru niesie plakietkę Registry tam, gdzie wyselekcjonowany niesie swój rodzaj uwierzytelniania, bo tę różnicę warto znać, zanim ktoś wklei poświadczenie: nikt tutaj tego nie przejrzał, opis pochodzi od wydawcy, a podpowiedzi o tokenie nie ma — rejestr nie ma takiego pola do odbicia.

Z rozmiaru wynikają trzy rzeczy i każda z nich jest powodem, dla którego jest to wyszukiwanie, a nie wyliczanka:

  • Stronicowane przez serwer, nie filtrowane przez przeglądarkę. Pięćdziesiąt na stronę, a zapytanie, kategoria i strona to wszystko żądania. Granica strony wypada w środku złączenia — 99 wyselekcjonowanych wierszy przy rozmiarze strony 50 — więc arytmetyka mieszka w mcp_listing.page, z testem na tej granicy, bo pomyłka o jeden pomija tam serwer albo pokazuje go dwa razy na liście, na której nikt by nie zauważył którego.
  • Kategoria sięga też lustra. Rejestr nie ma kategorii, więc każdy wpis dostaje ją przy synchronizacji z własnej nazwy i opisu, przez policzenie słów, po których rozpoznaje się każdą kategorię; wpis, który nie wymienia żadnego z nich, trafia do other, zamiast być zgadywany pod nagłówek. Filtr Sign-in pyta o to, czego serwer chce - OAuth, tokenu, niczego - a dla odbitego wpisu jest to to, co ustaliło sprawdzenie katalogu.
  • Żadnego wbudowanego logo. Konsola wstawia inline favikonę dla każdego wyselekcjonowanego hosta, żeby plakietka renderowała się offline; po 1,9 KB każda, zrobienie tego dla lustra dałoby 10,5 MB base64 w module, który ładuje przeglądarka. Wiersze z rejestru spadają do serwisu favikon działającego w czasie żądania — po to właśnie został napisany.
  • Snapshot, nie proxy. Instalacja nie może przestać działać dlatego, że czyjś rejestr leży, a nazwa, która wczoraj się rozwiązywała, a dziś nie rozwiązuje się do niczego, jest gorsza niż taka, której nigdy nie było.

    make platform-bootstrap go ładuje, więc nowy deployment ma go bez czytania tego przez kogokolwiek. agenticos cmd mcp-registry-sync go odświeża, a --fetch czyta żywy rejestr zamiast dołączonego snapshotu. Na deploymencie starszym niż ta tabela listą jest wyselekcjonowana setka, dopóki nie przebiegnie synchronizacja — czyli to, czym była przed tym wszystkim, więc nic się nie cofa, zanim ktoś się tym zajmie.

Serwer, którego nie ma na żadnej z list, i tak jest osiągalny: Custom server przyjmuje dowolny URL i w ogóle nie potrzebuje wpisu w katalogu.

Cztery z nich to gatewaye, a to inna obietnica

Composio, Pipedream, Activepieces i Smithery nie są API jednego produktu — każdy z nich jest endpointem do setek albo tysięcy innych, z poświadczeniami trzymanymi po ich stronie. Wpis katalogowy ręczy więc za gateway, a to, po co agent faktycznie może sięgnąć, rozstrzyga się w konsoli tego gatewaya, u tego, kto go tam skonfigurował.

Warto o tym wiedzieć, zanim porówna się rozmiary katalogów z dostawcą reklamującym tysiące integracji: ta liczba to prawie zawsze jeden endpoint tego rodzaju, a nie tysiące serwerów, które ktoś przejrzał. Oba kształty są użyteczne i nie są tym samym twierdzeniem.

Jak katalog jest utrzymywany

Obietnica się starzeje. Oficjalny referencyjny serwer Postgresa został w 2025 roku zarchiwizowany i usunięty z modelcontextprotocol/servers, a ten katalog dalej do niego linkował, więc jedyne, co wpis oferował czytelnikowi, to 404. W październiku 2026 Linear odszedł od /sse, Pipedrive przeniósł się na nowy host, a dwanaście wpisów kuratorowanych miało hostowany serwer, którego nikt nie zapisał. Dlatego każdy wymieniony serwer jest teraz wywoływany - tak, jak wywołuje go pierwsze połączenie - jedną komendą:

uv run agenticos cmd mcp-catalog-check --report catalog-check.md

Wysyła ona każdemu serwerowi handshake MCP bez poświadczeń i zapisuje, co się stało: odpowiedział i wylistował swoje narzędzia (open, z liczbą tych, które tylko czytają), odmówił i publikuje metadane OAuth (sign in), odmówił bez tych metadanych (token) albo w ogóle nie odpowiedział jak serwer MCP (unreachable, broken lub refused dla adresu wewnątrz sieci). Dwa wpisy rejestru pod jednym adresem to jeden serwer i zostaje krótsza nazwa. Nic nigdzie się nie loguje: czy narzędzia działają po połączeniu, sprawdza test samego połączenia.

To, co ustalono, widać na kartach. Serwer, który odpowiedział, mówi Checked z datą i liczbą narzędzi tam, gdzie je wylistował. Serwer kuratorowany, który nie odpowiedział, mówi to na czerwono i zostaje na liście, bo ktoś go wybrał; odbity wpis, który nie odpowiedział albo powtarza inny, nie jest już oferowany. Wpis kuratorowany, który obiecuje OAuth, a nie opublikował do tego metadanych, nie jest oznaczony jako sprawdzony, bo jego Connect to przycisk, który by zawiódł.

Sprawdzenie uruchamia się przed każdym wydaniem z --snapshot, które zapisuje app/core/catalog/mcp_checks.json; make platform-bootstrap je wczytuje, więc nowe wdrożenie zaczyna od tego, na czym sprawdzono wydanie. Uruchom komendę na wdrożeniu, żeby sprawdzić ponownie; jego własne wyniki mają pierwszeństwo przed dołączonymi. --source catalog sprawdza samą listę kuratorowaną w około dziesięć sekund; cały rejestr zajmuje kilka minut. Raport wymienia każdy wpis kuratorowany z tym, co deklaruje, co ustalono i dlaczego któryś nie przeszedł.

(self-hosted) poniżej oznacza, że wpis opisuje serwer, ale URL podajesz ty: albo dlatego, że działa on na twojej własnej infrastrukturze, albo dlatego, że dostawca wydaje endpoint osobno dla każdego konta.

Programowanie

Serwer Uwierzytelnianie URL
GitHub token https://api.githubcopilot.com/mcp/
Cloudflare docs none https://docs.mcp.cloudflare.com/mcp
GitLab token self-hosted
Postman token https://mcp.postman.com/mcp
Vercel oauth https://mcp.vercel.com/
Netlify oauth https://mcp.netlify.com/mcp
Railway token https://mcp.railway.app/mcp
Replit oauth https://mcp.replit.com/server/mcp
Hugging Face token https://huggingface.co/mcp
Buildkite oauth https://mcp.buildkite.com/mcp
Semgrep token https://mcp.semgrep.ai/mcp
Clerk oauth https://mcp.clerk.com/mcp
WorkOS oauth https://mcp.workos.com/mcp
Render token https://mcp.render.com/mcp
CircleCI oauth https://mcp.circleci.com/v1/mcp

Zarządzanie projektami

Serwer Uwierzytelnianie URL
Linear oauth https://mcp.linear.app/mcp
Jira & Confluence oauth https://mcp.atlassian.com/v1/sse
Asana oauth https://mcp.asana.com/sse
ClickUp oauth https://mcp.clickup.com/mcp
Trello oauth https://mcp.trello.com/v1
Todoist oauth https://ai.todoist.net/mcp
monday.com oauth https://mcp.monday.com/mcp

Dane i analityka

Serwer Uwierzytelnianie URL
PostgreSQL token self-hosted
Supabase token https://mcp.supabase.com/mcp
Elasticsearch token self-hosted
Airtable token https://mcp.airtable.com/mcp
Snowflake token self-hosted
Databricks token self-hosted
Google BigQuery oauth self-hosted
PostHog token https://mcp.posthog.com/mcp
Mixpanel token https://mcp.mixpanel.com/mcp
Google Analytics 4 token self-hosted
Neon oauth https://mcp.neon.tech/mcp
Amplitude token https://mcp.amplitude.com/mcp
Firecrawl token https://mcp.firecrawl.dev/mcp
Exa token https://mcp.exa.ai/mcp
Tavily token https://mcp.tavily.com/mcp
Bright Data token https://mcp.brightdata.com/mcp
Qdrant none https://mcp.qdrant.tech/mcp
Statsig token https://api.statsig.com/v1/mcp

Komunikacja, wsparcie, wiedza

Serwer Uwierzytelnianie URL
Slack oauth https://mcp.slack.com/mcp
Microsoft Work IQ oauth https://workiq.svc.cloud.microsoft/mcp
Outlook Mail (Work IQ) oauth https://agent365.svc.cloud.microsoft/agents/servers/mcp_MailTools
Microsoft Teams (Work IQ) oauth https://agent365.svc.cloud.microsoft/agents/servers/mcp_TeamsServer
Zoom oauth self-hosted
Intercom oauth https://mcp.intercom.com/sse
Notion oauth https://mcp.notion.com/mcp
GitBook token https://mcp.gitbook.com/mcp
Sanity token https://mcp.sanity.io/mcp
DeepWiki none https://mcp.deepwiki.com/mcp
Supermemory token https://mcp.supermemory.ai/mcp
Contentful token https://mcp.contentful.com/mcp
Storyblok token https://mcp.storyblok.com/mcp
Vapi token https://mcp.vapi.ai/mcp

Finanse, sprzedaż, handel

Serwer Uwierzytelnianie URL
Stripe token https://mcp.stripe.com
PayPal oauth https://mcp.paypal.com/sse
Xero oauth https://mcp.xero.com/mcp
HubSpot oauth https://mcp.hubspot.com/
Shopify oauth self-hosted
Attio oauth https://mcp.attio.com/mcp
Pipedrive oauth https://mcp.pipedrive.ai/mcp
Lusha oauth https://mcp.lusha.com

Obserwowalność

Serwer Uwierzytelnianie URL
Sentry oauth https://mcp.sentry.dev/mcp
Grafana token https://mcp.grafana.com/mcp
PagerDuty oauth https://mcp.pagerduty.com/mcp
Datadog token https://mcp.datadoghq.com/api/unstable/mcp-server/mcp
Pydantic Logfire token https://logfire-us.pydantic.dev/mcp
LangSmith token https://api.smith.langchain.com/mcp
Honeycomb token https://mcp.honeycomb.io/mcp
New Relic token https://mcp.newrelic.com/mcp

Marketing i design

Serwer Uwierzytelnianie URL
Mailchimp oauth https://ai-inc.mailchimp.com/claude/mcp/v2
Resend token https://mcp.resend.com/mcp
Webflow oauth https://mcp.webflow.com/mcp
Wix oauth https://mcp.wix.com/mcp
WordPress.com oauth https://public-api.wordpress.com/wpcom/v2/mcp/v1
Semrush oauth https://mcp.semrush.com/v1/mcp
Meta Ads oauth https://mcp.facebook.com/ads
Google Ads token self-hosted
Similarweb token https://mcp.similarweb.com/mcp
Figma oauth https://mcp.figma.com/mcp
Miro oauth https://mcp.miro.com/mcp
Lucid oauth https://mcp.lucid.app/mcp
Excalidraw none https://mcp.excalidraw.com/mcp
Canva oauth https://mcp.canva.com/mcp
Klaviyo oauth https://mcp.klaviyo.com/mcp

Automatyzacja, przechowywanie, produktywność, media

Serwer Uwierzytelnianie URL
Zapier oauth https://mcp.zapier.com/api/mcp/mcp
Make token self-hosted
n8n token self-hosted
Box oauth https://mcp.box.com/mcp
Dropbox oauth https://mcp.dropbox.com/mcp
Calendly oauth https://mcp.calendly.com/
Typeform oauth https://api.typeform.com/mcp
SurveyMonkey oauth https://mcp.surveymonkey.com/mcp
DeepL oauth https://mcp.deepl.com/v1/mcp
ElevenLabs oauth https://api.elevenlabs.io/v1/mcp
Fireflies token https://mcp.fireflies.ai/mcp
Egnyte oauth https://mcp-server.egnyte.com/mcp
Apify token https://mcp.apify.com
Tally token https://api.tally.so/mcp
Pipedream oauth https://mcp.pipedream.net/v2
Composio token self-hosted
Activepieces token https://mcp.activepieces.com/mcp
Cal.com token https://mcp.cal.com/mcp
Outlook Calendar (Work IQ) oauth https://agent365.svc.cloud.microsoft/agents/servers/mcp_CalendarTools
Word (Work IQ) oauth https://agent365.svc.cloud.microsoft/agents/servers/mcp_WordServer
SharePoint (Work IQ) oauth https://agent365.svc.cloud.microsoft/agents/servers/mcp_SharePointRemoteServer
OneDrive (Work IQ) oauth https://agent365.svc.cloud.microsoft/agents/servers/mcp_OneDriveRemoteServer

Wszystko inne

Smithery — token — https://mcp.smithery.ai/mcp. Gateway do rejestru: serwery osiągane przez niego to te, które dane konto zainstalowało na Smithery, więc to, co agent może zrobić, rozstrzyga się tam, a nie tutaj.

Custom server — dowolny serwer MCP osiągalny po URL-u. Jego narzędzia są odczytywane przy podłączeniu i nic o nim nie musi być wcześniej w katalogu. Katalog oszczędza komuś szukania URL-a; nie jest bramką.

Wpisanie adresu własnego serwera pyta go, czy ludzie mogą się do niego logować: to samo wykrywanie, które wykonuje przepływ OAuth (RFC 9728, potem RFC 8414), bez rejestrowania czegokolwiek, przez POST /api/v1/me/mcp-connections/probe. Jeśli mogą, OAuth zostaje wybrany za Ciebie, a połączenie otwiera logowanie; jeśli serwer sam nie rejestruje aplikacji, okno prosi o identyfikator i sekret klienta utworzone u dostawcy; jeśli nie publikuje metadanych OAuth, zostaje token albo brak poświadczeń.

Aby dodać wpis do listy, zobacz Dodawanie serwera do katalogu MCP.

Microsoft 365 i Outlook

Microsoft publikuje własne serwery MCP dla Microsoft 365, a katalog je wymienia: Work IQ - jeden endpoint do poczty, spotkań, czatów i plików - oraz osobne serwery Mail, Calendar, Teams, SharePoint, OneDrive i Word. Każdy wymaga licencji Microsoft 365 Copilot i aplikacji zarejestrowanej w Microsoft Entra: dodaj uprawnienie Work IQ danego serwera (dla poczty WorkIQ-MailServer) oraz przekierowujący URL tej konsoli, który pokazuje okno połączenia, a przy łączeniu wpisz client ID aplikacji.

Entra nie rejestruje klienta na miejscu, więc client ID nie jest opcjonalny. Microsoft oznacza serwery per aplikacja jako utrzymywane dla zgodności i kieruje nowe projekty do Work IQ.

Outlook jest też dostępny przez zewnętrzne usługi MCP. Dołączony rejestr zawiera wpisy MintMCP dla poczty i kalendarza:

Wpis w rejestrze URL serwera
com.mintmcp/outlook-email https://outlook-email.mintmcp.com/mcp
com.mintmcp/outlook-calendar https://outlook-calendar.mintmcp.com/mcp

Znajdź wpis w katalogu MCP lub dodaj jego URL jako własny serwer. Skorzystaj z instrukcji dostawcy, skonfiguruj konto i autoryzację, a następnie przetestuj połączenie i wybierz narzędzia agenta. Dostępność, uprawnienia i ewentualne opłaty zależą od dostawcy. Wpis w rejestrze nie oznacza testu całej integracji z AgenticOS. Przed włączeniem narzędzi zapisu sprawdź opisane poniżej tryby zatwierdzania.

AgenticOS jako serwer MCP

Wszystko powyżej to platforma wołająca inne serwery. Sama też jest serwerem: /mcp na hoście API mówi MCP przez streamable HTTP, więc Claude Code, Claude Desktop albo dowolny klient MCP może obsługiwać organizację — listować i tworzyć agentów, uruchamiać ich, czytać runy i ich koszt, zasilać i przeszukiwać bazy wiedzy, zapraszać członków.

Serwer jest zbudowany na FastMCP: obsługuje protokół i endpointy OAuth 2.1, a AgenticOS dostarcza narzędzia i każdą decyzję stojącą za logowaniem.

Klient loguje się przez przeglądarkę: rejestruje się, otwiera w konsoli stronę zgody, na której wybierasz organizację i to, co może robić, i dostaje token ważny godzinę, który sam się odnawia. Nigdzie nie wklejasz klucza.

Rejestracja nie wymaga poświadczeń, więc jest limitowana per adres jak logowanie, a klient, z którym nikt nie dokończył logowania, znika po dobie.

W konsoli Ustawienia → Klienci MCP pokazuje adres tego serwera i dokładne polecenie albo konfigurację dla Claude Code, Codexa, Claude Desktop, Cursora i VS Code, dla obu sposobów logowania.

claude mcp add --transport http agenticos https://<your-deployment>/mcp

Albo połącz się kluczem API organizacji, jeśli klient nie potrafi otworzyć przeglądarki:

claude mcp add --transport http agenticos https://<your-deployment>/mcp \
  --header "Authorization: Bearer $AGENTICOS_KEY"

Połączenie działa jako członek, który wydał klucz, w granicach uprawnień klucza. Każde narzędzie to wywołanie publicznego API tym kluczem, więc jest odrzucane, limitowane i audytowane dokładnie tak jak to samo żądanie po HTTP; odmowa wraca jako błąd narzędzia nazywający brakujące uprawnienie.

Narzędzie Wymaga
whoami —
list_agents, get_agent, list_capabilities, list_models, search_mcp_servers agents:view
create_agent_draft, update_agent_draft, test_agent_draft agents:edit
list_sandbox_connections, list_sandbox_runtimes, get_sandbox_policy connections:view
list_org_connections mcp:manage
publish_agent agents:publish na tym agencie
discard_agent_draft agents:edit, dla twojego draftu, który nigdy nie był opublikowany
run_agent agents:run
list_routines agents:view
create_routine, run_routine_now agents:run na agencie
update_routine, delete_routine twórca rutyny albo agents:edit na jej agencie
list_runs, get_run, read_conversation, get_spend runs:view
list_knowledge_bases, search_knowledge collections:view
list_embedding_models —
create_knowledge_base, add_document collections:edit
list_skills skills:view
create_skill skills:edit
list_projects projects:view
get_project dostęp do projektu
create_project projects:edit
list_members members:view
invite_member members:manage i roles:manage
list_my_connections, set_my_language, set_my_profile — (własne wywołującego)

Wyszukiwanie przez list_projects zwraca tylko ID i nazwy projektów, pomijając opisy, instrukcje i pozostałe edytowalne etykiety. Odczyt wybranego projektu przez get_project zawiera je i przy polityce writes czeka na akceptację, tak jak read_conversation. Instrukcje innego udostępnionego projektu nie powinny trafiać do modelu wyłącznie dlatego, że szukał przestrzeni roboczej.

Agenta da się tu zbudować od początku do końca: utworzyć szkic, edytować go, wypróbować jako nieopublikowany draft przez test_agent_draft - run testowy, liczony do budżetu i zapisywany, odrzucany z podaniem powodu, gdy draft by się nie opublikował - i opublikować przez publish_agent, które wykonuje te same sprawdzenia co przycisk Publish w konsoli. cron_expression rutyny jest liczony w UTC. set_my_language przełącza język konsoli wywołującego (en, pl albo de) na każdym urządzeniu, na którym się loguje, a set_my_profile zapisuje jego rolę i to, czym się zajmuje, co od tej pory słyszy każdy agent. create_skill zapisuje procedurę, która zadziałała, jako skill - na „zrób z tego skill”.

Celowo nie ma tu dotykania poświadczeń ani usuwania czegokolwiek poza draftem agenta, który wywołujący sam utworzył i nigdy nie opublikował - to cofnięcie draftu utworzonego przez pomyłkę - albo rutyną. Podłączone aplikacje są widoczne w Ustawienia → Klienci MCP, gdzie odłączenie kończy ich dostęp razem z każdym tokenem. Wywołania, które coś zmieniają, czekają na zatwierdzenie, jak wyjaśnia sekcja wyżej.

Narzędzia draftów przyjmują skonfigurowane wiązania możliwości oraz same identyfikatory. Na przykład capabilities: [{id: sandbox, config: {backend: service, include_execute: true}}] daje agentowi programistycznemu powłokę na domyślnym hoście sandboxa organizacji. list_capabilities zwraca config_schema; list_sandbox_connections, list_sandbox_runtimes i get_sandbox_policy pozwalają sprawdzić hosty, aliasy runtime’ów i ograniczenia przed wyborem ustawień. Sandbox tylko na pliki (state) nie wykonuje poleceń.

update_agent_draft.add_capabilities dodaje lub aktualizuje wiązania: pominięte pola zachowują wartości, a podany config zastępuje całą konfigurację. Najpierw odczytaj draft, żeby zachować potrzebne ustawienia. Oba narzędzia przyjmują mcp_servers: identyfikatory połączeń organizacji z list_org_connections albo osobiste klucze katalogowe z search_mcp_servers. Identyfikator osobistego połączenia nie należy do współdzielonej specyfikacji. Lista wiązań MCP jest zastępowana w całości; [] odłącza wszystkie. Tworzenie przyjmuje też skill_ids i collection_ids. Testowanie i publikowanie zachowują te same zasady walidacji i akceptacji.

Udostępnienie go agentowi

Ten sam serwer jest też bindingiem MCP, który może mieć każdy agent, więc agent odpowie na „co wczoraj padło” albo „którzy agenci używają tej bazy wiedzy” z własnych zapisów platformy. W Builderze to pierwsza karta w Serwerach MCP, nazwana jak to wdrożenie; jej włączenie wiąże go jako mcp_servers: [{account: platform, approval: writes}].

  • Działa jako osoba, dla której działa agent. Run tworzy krótkotrwały klucz z uprawnieniami tej osoby, więc agent Viewera czyta to, co może czytać Viewer, i niczego nie tworzy. Nic nowego nie jest przyznawane, a gdy za runem nikt nie stoi - publiczny widget, harmonogram działający w niczyim imieniu - bindingu nie ma.
  • Zmiany czekają na zatwierdzenie. Domyślne writes wstrzymuje każde narzędzie, które coś zmienia (create_agent_draft, publish_agent, create_routine, run_agent, invite_member i pozostałe), do zgody osoby; all wstrzymuje też odczyt. none nie jest oferowane: te narzędzia działają z uprawnieniami człowieka. Jedyny zapis, który nigdy nie czeka, to set_my_language: zmienia język konsoli pytającego, na jego słowo, a karta zatwierdzenia dla „przełącz na angielski” byłaby całą rozmową. set_my_profile czeka jak pozostałe, bo to, co zapisuje, słyszy każdy agent, którego ta osoba uruchamia, a strona przeczytana przez agenta nie może tego zapisać niezauważenie.
  • Narzędzia można zawęzić w ustawieniach karty, które pokazują każde narzędzie i oznaczają te, które coś zmieniają.

Szablon AgenticOS wiąże go właśnie tak, podobnie jak każdy agent tworzony od zera, więc agent od razu sięga do platformy - i ustawia rutynę albo przełącza język konsoli, gdy się go o to poprosi.

Czego MCP ci nie daje

  • Gwarancji pokrycia. Wpisy katalogowe to metadane. Narzędzia należą do dostawcy i mogą zmienić ci się pod ręką między jedną turą a następną.
  • Zatwierdzeń, które wiedzą, co robi narzędzie. Polityka writes ufa, że serwer oznaczył narzędzia tylko do odczytu; narzędzie tak oznaczone, które coś zmienia, uruchamia się bez pytania. Dla serwera, którego nie kontrolujesz, użyj all i zawęź allowed_tools. Zobacz które wywołania czekają.
  • Przypisania kosztów. To, co serwer robi po swojej stronie, nie jest w budżecie tej platformy. Są w nim tylko tokeny modelu.

Podsumowanie

  • Serwer MCP to URL, który ktoś wkleił, a jego narzędzia pojawiają się bez deploymentu.
  • Połączenia osobiste docierają do asystenta jednego członka; tylko połączenia organizacji może wskazać opublikowany spec.
  • Każdy adres we flow OAuth jest sprawdzany i przypinany, łącznie z tymi, które wybrał zdalny serwer.
  • Token nigdy nie podąża za przeniesionym URL-em, wyłączone połączenie nie wydaje żadnego, a usunięcie połączenia wyrejestrowuje to, co ono zarejestrowało.
  • Nieosiągalny serwer zostaje pominięty, a nie podnosi wyjątku — tura odpowiada bez tych narzędzi.

Każda zaplanowana kontrola obejmuje najwyżej 64 aktywne serwery organizacji, zaczynając od najdawniej sprawdzanych, i wykonuje najwyżej osiem prób równocześnie. Nieużyteczne poświadczenia również aktualizują czas kontroli, bez zgłaszania awarii. Większe instalacje sprawdzają więc wszystkie serwery w kolejnych cyklach.

Odświeżenie OAuth ma osobną krótką transakcję: blokuje i ponownie sprawdza konto, wymienia poświadczenie i zatwierdza zapis przed zwróceniem tokena. Anulowanie czeka na zakończenie tej operacji; późniejszy rollback uruchomienia jej nie cofa. Błąd zapisu po wymianie u dostawcy jawnie przerywa żądanie i może wymagać ponownej autoryzacji konta. Polling skrzynek używa osobnej blokady doradczej konta; pozycja odczytu i zlecone zadania zatwierdzają się razem, a nieprawidłowa odpowiedź wycofuje tylko pracę tej skrzynki.

Kolejka kontroli stanu korzysta z osobnego, indeksowanego znacznika czasu. Odświeżenie OAuth ani polling skrzynki nie przesuwają kolejnej kontroli serwera. Po migracji istniejące serwery trafiają do kolejki jako jeszcze niesprawdzone.