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.
- Wykrycie — odpytaj serwer, ustal jego authorization server, pobierz metadane RFC 8414.
- 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.
- Zgoda — URL autoryzacji z PKCE, ze
statei wskaźnikiem zasobu wg RFC 8707; przeglądarka idzie pod ten adres. - 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ł.
- 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_HOSTSpomija 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-bootstrapgo ładuje, więc nowy deployment ma go bez czytania tego przez kogokolwiek.agenticos cmd mcp-registry-syncgo odświeża, a--fetchczyta ż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ą:
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.
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
writeswstrzymuje każde narzędzie, które coś zmienia (create_agent_draft,publish_agent,create_routine,run_agent,invite_memberi pozostałe), do zgody osoby;allwstrzymuje też odczyt.nonenie jest oferowane: te narzędzia działają z uprawnieniami człowieka. Jedyny zapis, który nigdy nie czeka, toset_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_profileczeka 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
writesufa, ż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żyjalli 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.