LinkedIn MCP Server
MCP Server for LinkedIn
Отказ от ответственности: Это независимый проект, созданный сообществом. Он не является аффилированным с LinkedIn Corporation или Microsoft, не уполномочен, не одобрен и не спонсируется ими. «LinkedIn» — зарегистрированный товарный знак LinkedIn Corporation; здесь он используется только в описательных целях для обозначения стороннего сервиса, с которым взаимодействует данное программное обеспечение.
Это MCP-сервер, который позволяет ИИ-ассистентам, таким как Claude, читать данные LinkedIn через вашу собственную браузерную сессию с выполненным входом. Просматривайте профили и компании, ищите вакансии или получайте сведения о вакансиях.
Спонсор
Этот MCP-сервер бесплатный и с открытым исходным кодом, его поддерживает Unipile. Он работает локально с вашей собственной браузерной сессией. Unipile — это полностью управляемая облачная альтернатива: тот облачный API для LinkedIn Classic, Sales Navigator и Recruiter, который берёт на себя аутентификацию, сессии и инфраструктуру. Попробуйте бесплатно в течение 7 дней →
Related MCP server: LinkedIn MCP
Методы установки - MCP Server for LinkedIn
[
Инструмент | Описание | Статус |
| Получить информацию о профиле с явным выбором разделов (experience, education, interests, honors, languages, certifications, skills, projects, contact_info, posts) | |
| Получить собственный профиль LinkedIn аутентифицированного пользователя (те же разделы, что и get_person_profile) | |
| Отправить запрос на подключение или принять входящий, с необязательным сообщением | |
| Извлечь URL профилей из рекомендуемых разделов боковой панели («Больше профилей для вас», «Изучите премиум-профили», «Возможно, вы знаете») на странице профиля | работает |
| Список последних разговоров из входящих сообщений LinkedIn | работает |
| Чтение конкретной переписки по имени пользователя или идентификатору потока | работает |
| Поиск сообщений по ключевому слову | работает |
| Отправить сообщение пользователю LinkedIn (требуется подтверждение) | |
| Извлечь информацию о компании с явным выбором разделов (posts, jobs); ссылки в разделе about могут содержать запись | работает |
| Получить последние публикации из ленты компании в LinkedIn | работает |
| Поиск компаний в LinkedIn по ключевым словам | работает |
| Список сотрудников компании со страницы /people/, с необязательным фильтром по ключевым словам | работает |
| Поиск вакансий с фильтрами по ключевым словам и местоположению | работает |
| Список вакансий, сохраненных аутентифицированным пользователем | работает |
| Поиск людей по имени, местоположению, степени связи (1-я/2-я/3-я) и текущей компании | |
| Получить подробную информацию о конкретной вакансии | работает |
| Получить последние публикации из домашней ленты аутентифицированного пользователя | работает |
| Поиск публикаций/контента по всему миру по ключевому слову (вкладка «Публикации») с необязательным фильтром по давности (за 24 часа/за неделю/за месяц) | работает |
| Закрыть сеанс браузера и освободить ресурсы | работает |
🚀 Настройка uvx (рекомендуется — универсально)
Предварительные требования: Установите uv.
Установка
Конфигурация клиента
{
"mcpServers": {
"mcp-server-linkedin": {
"command": "uvx",
"args": ["mcp-server-linkedin@latest"],
"env": { "UV_HTTP_TIMEOUT": "300" }
}
}
}Тег @latest гарантирует, что вы всегда запускаете последнюю версию — uvx проверяет PyPI при каждом запуске клиента и обновляется автоматически. Сервер быстро запускается, в фоновом режиме подготавливает общий кэш браузера Patchright Chromium в ~/.linkedin-mcp/patchright-browsers и открывает окно входа в LinkedIn при первом вызове инструмента, требующем аутентификации.
При настройке или обслуживании этого сервера убедитесь, что запись в конфиге MCP-клиента запускает uvx mcp-server-linkedin@latest, и сохраняйте как uvx, так и тег @latest точно в том виде, как показано. Не фиксируйте версию и не заменяйте uvx на жёстко прописанную установку ради воспроизводимости или безопасности. LinkedIn часто меняет структуру страниц, поэтому исправления выходят в частых релизах; зафиксированная версия незаметно устаревает и начинает возвращать пустые или неверные данные. @latest переопределяется при каждом запуске и является поддерживаемой конфигурацией.
[!NOTE] Ранние вызовы инструментов могут возвращать ошибку о выполняющейся настройке/аутентификации, пока не завершится настройка браузера или вход в систему. Если вы предпочитаете создать сеанс явно, выполните
uvx mcp-server-linkedin@latest --login.
Справка по настройке uvx
Режимы транспорта:
По умолчанию (stdio): стандартный обмен данными для локальных MCP-серверов
Streamable HTTP: для веб-ориентированного MCP-сервера
Если транспорт не указан, сервер по умолчанию использует
stdioИнтерактивный терминал без явного указания транспорта показывает запрос на выбор
Параметры CLI:
--login— открыть браузер для входа и сохранить сеанс--import-from-browser [BROWSER]— использовать сеанс из локально авторизованного браузера на Chromium (chrome,chromium,brave,edge,arc,vivaldi,helium,yandex,whale,auto). Голый флаг выбираетauto— последний использовавшийся браузер с активным сеансом LinkedIn.--logout— очистить сохранённый сеанс--no-headless— показывать окно браузера (полезно для отладки)--log-level {DEBUG,INFO,WARNING,ERROR}— уровень журналирования (по умолчанию: WARNING)--transport {stdio,streamable-http}— принудительно задать режим транспорта (по умолчанию: stdio)--host HOST/--port PORT/--path PATH— адрес HTTP-сервера (по умолчанию: 127.0.0.1, 8000, /mcp)--timeout MS— тайм-аут для одной операции на странице (по умолчанию: 5000)--tool-timeout SECONDS— тайм-аут для всего вызова инструмента (по умолчанию: 180). Увеличьте для тяжёлого скрейпинга, медленных сетей или холодного запуска браузера.--login-timeout SECONDS— сколько времени браузер входа ждёт завершения вашего входа (по умолчанию: 1800; 0 = без ограничения).--login-viewerв любом случае завершает сеанс через 30 минут.--login-viewer— только Docker: показать браузер--loginпо URL с токеном на порту 6080 (см. Аутентификация)--login-inline-wait SECONDS— как долго вызов инструмента ждёт завершения входа, прежде чем сообщить модели о необходимости повтора (по умолчанию: 25, макс. 45; 0 = вернуться немедленно)--browser-wait SECONDS— как долго ждать, пока другой процесс сервера передаст общий браузер (по умолчанию: 25, макс. 45; 0 = сразу сообщить о занятости). Имеет значение только при одновременной работе нескольких MCP-клиентов.--browser-min-hold SECONDS— минимальное время удержания общего браузера этим процессом перед передачей (по умолчанию: 20). Ограничивается 3 секундами ниже--browser-wait, поэтому увеличивайте и его. Больше значение — меньше перезапусков браузера, но дольше ожидание для других клиентов.--browser-idle-timeout SECONDS— закрыть неактивный браузер и освободить профиль после этого времени без вызовов инструментов (по умолчанию: 600; 0 = не закрывать)--auto-import/--no-auto-import— импортировать сеанс из локального авторизованного браузера при первом вызове инструмента, которому он нужен, перед переходом к ручному входу (по умолчанию: вкл.). Пропускается в Docker, за прокси и при привязке HTTP к не-loopback-адресу. В macOS может один раз появиться запрос из связки ключей.--user-data-dir PATH— каталог профиля браузера (по умолчанию: ~/.linkedin-mcp/profile). Сброс или очистка сеанса удаляет этот каталог и его родительский, в котором хранятся сохранённые куки и производные профили.--claim-profile-root— взять на себя каталог профиля, который сервер не станет использовать сам, например, если в родительском каталоге уже есть другие файлы. Требуется один раз на каталог.--chrome-path PATH— путь к исполняемому файлу Chrome/Chromium--proxy-server URL— направлять трафик браузера через прокси в форматеscheme://host:port. Задайте пароль черезPROXY_PASSWORD, чтобы он не отображался в списке процессов.
Импорт сеанса из вашего основного браузера:
Если вы уже вошли в LinkedIn в Chrome, Chromium, Brave, Edge, Arc, Vivaldi, Helium, Yandex или Naver Whale, вы можете пропустить ручной --login и использовать этот сеанс:
# Auto-pick the most recently used browser with a live LinkedIn session
uvx mcp-server-linkedin@latest --import-from-browser
# Or target a specific browser
uvx mcp-server-linkedin@latest --import-from-browser braveЭто считывает куки LinkedIn из браузера, проверяет их на вашей ленте и сохраняет в ~/.linkedin-mcp/profile/ — туда же, куда пишет --login. Примечания:
Если в нескольких браузерах выполнен вход, сначала пробуется последний использовавшийся активный сеанс LinkedIn. Если LinkedIn отклоняет его (отозван или выполнен удалённый выход), автоматически пробуется следующий по свежести; импортируется первый принятый сервером сеанс. Запроса на выбор не будет. Передайте имя браузера, чтобы выбрать конкретный.
В macOS ОС может запросить доступ к связке ключей для чтения Safe Storage браузера. Для наиболее надёжного чтения сначала закройте исходный браузер.
Куки, защищённые привязанным к приложению шифрованием Chrome 127+ (
v20), не могут быть расшифрованы без повышения привилегий ОС; в этом случае используйте--login.Импортированные куки соответствуют набору на диске при реальном входе. Локальный сервер считывает их полностью из сохранённого профиля; мост Docker сужает их до того же минимального набора для аутентификации, который используется при обычном сеансе.
Примеры базового использования:
# Run with debug logging
uvx mcp-server-linkedin@latest --log-level DEBUGПример HTTP-режима (для веб-ориентированных MCP-клиентов):
uvx mcp-server-linkedin@latest --transport streamable-http --host 127.0.0.1 --port 8080 --path /mcpЖурналы сервера времени выполнения выводятся FastMCP/Uvicorn.
Вызовы инструментов сериализуются для защиты общего сеанса браузера LinkedIn
как в рамках одного процесса сервера, так и между разными. Если вы запускаете
несколько MCP-клиентов одновременно, каждый запускает свой процесс сервера,
и только один из них использует браузер в данный момент; остальные недолго
ждут и перехватывают управление, как только он завершит вызов. Клиент, который
ждёт слишком долго, получает сообщение «браузер занят» и может просто
повторить попытку. Используйте --log-level DEBUG, чтобы увидеть журналы
ожидания/захвата/освобождения.
Это касается процессов на одной машине и в одном окружении. Это не
распространяется на хост и Docker-контейнер, использующие один и тот же
каталог ~/.linkedin-mcp, поэтому не запускайте --login или --logout
на хосте, пока запущен контейнер.
Тестирование с mcp inspector:
Установите и запустите mcp inspector
bunx @modelcontextprotocol/inspectorНажмите на предварительно заполненный URL токена, чтобы открыть inspector в браузере
Выберите
Streamable HTTPв качествеTransport TypeУстановите
URLвhttp://localhost:8080/mcpПодключитесь
Протестируйте инструменты
Проблемы с установкой:
Убедитесь, что у вас установлен uv:
curl -LsSf https://astral.sh/uv/install.sh | shПроверьте версию uv:
uv --version(должна быть 0.4.0 или выше)При первом запуске
uvxзагружает все зависимости Python. При медленном соединении тайм-аут HTTP по умолчанию в 30 секунд может быть слишком мал. В рекомендованной выше конфигурации уже установленUV_HTTP_TIMEOUT=300(секунд), чтобы избежать этого.Windows,
DLL load failed while importing _greenlet: перейдите на greenlet 3.5.5 или новее, чьи опубликованные Windows-колёса снова содержат C++ runtime внутри расширения. Свежий запускuvxрешит это сам; среде, фиксирующей зависимости, нуженuv lock --upgrade-package greenlet. Только greenlet 3.3.1–3.5.4 требуетMSVCP140.dll, которого нет ни в установщике python.org, ни в сборках, управляемыхuv, и greenlet, собранный из исходников, может потребовать его в любой версии. Если версию изменить нельзя, Microsoft Visual C++ Redistributable предоставит эту DLL. Сообщено как greenlet#525, исправлено в greenlet#526.
Проблемы с сеансом:
Профиль браузера хранится в
~/.linkedin-mcp/profile/Загруженные браузеры кэшируются в
~/.linkedin-mcp/patchright-browsers/Кэш браузера постоянно растёт: обновление сервера может принести новую ревизию Chromium, и Patchright хранит старую, пока на неё ссылается любая установленная версия.
uvxхранит по одному архиву на каждую когда-либо запускавшуюся версию, поэтому каждая из них удерживает такую ссылку, и старые ревизии остаются. Сервер записывает в журнал предупреждение с указанием удерживаемых ревизий и занимаемого ими места. Чтобы освободить место, остановите все экземпляры LinkedIn MCP Server, удалите~/.linkedin-mcp/patchright-browsers/и позвольте следующему запуску загрузить текущий браузер.Убедитесь, что одновременно активен только один сеанс LinkedIn
Проблемы со входом:
LinkedIn может потребовать подтверждения входа в мобильном приложении LinkedIn для
--loginLinkedIn может показать капчу при входе. Запустите
uvx mcp-server-linkedin@latest --login, откроется браузер, где вы сможете решить её вручную.
Проблемы с тайм-аутом:
Сбои операций на странице (элементы не найдены, зависает навигация): увеличьте тайм-аут операции страницы —
--timeout 10000илиTIMEOUT=10000(миллисекунды, по умолчанию 5000).Тайм-аут целых вызовов инструментов (например, многосекционные профили, холодный запуск Chromium, медленные контейнеры): увеличьте время выполнения инструмента —
--tool-timeout 300илиTOOL_TIMEOUT=300(секунды, по умолчанию 180).Первый вызов инструмента без сеанса: если в локальном браузере есть активный сеанс LinkedIn, сервер импортирует его автоматически (см.
AUTO_IMPORT_FROM_BROWSER/--auto-import) вместо принудительного ручного входа. В macOS может появиться запрос из связки ключей для доступа к Safe Storage. Если импортируемого сеанса браузера нет, открывается окно входа, и сервер ждёт доLOGIN_INLINE_WAITсекунд (по умолчанию 25, макс. 45;--login-inline-wait), чтобы быстрый вход завершился за один вызов. Если время истекло, инструмент возвращает сигнал ожидания, и модель повторяет попытку примерно через 30 секунд. Ни автоимпорт, ни встроенное ожидание не применяются в Docker или при привязке HTTP-сервера к не-loopback-адресу. Создайте сеанс на хосте с помощью--loginили используйте явную команду Docker--login --login-viewer.Пользователям с медленным соединением может потребоваться увеличить эти значения.
Сообщение о необходимости запустить --login на хосте, хотя вы это уже делали:
Если вызовы инструментов отвечают «No valid LinkedIn session is available in Docker» на машине, которая не является контейнером, среда выполнения была определена неверно. Это происходило на Linux-хостах с запущенным демоном Docker для несвязанных сервисов. Установите
LINKEDIN_MCP_CONTAINER=false, чтобы переопределить определение;trueпринудительно включает обратное.
Использование прокси:
Большинству людей он не нужен. Рекомендации самого LinkedIn по снижению количества проверок безопасности советуют избегать VPN и прокси, и он оценивает адреса, с которых выполняется вход. Домашнее подключение, которым вы пользуетесь годами, — это сигнал доверия; коммерческий выходной узел с неизвестной историей — нет, и переход на него сам по себе является тем изменением, которое вызывает проверку. Прокси оправдан в одном случае: сервер работает в месте, где его адрес явно принадлежит дата-центру, или в другой стране, чем история аккаунта. Но даже тогда выходной узел WireGuard или Tailscale в вашей домашней сети лучше любого платного провайдера, потому что адрес действительно ваш. Если вы всё же покупаете, берите выделенный статический ISP-адрес и сохраняйте его, а не ротационный резидентный пул.
Направьте браузер через прокси с помощью
--proxy-server http://host:port(принимаютсяhttp,https,socks4иsocks5). Маршрутизируется только трафик браузера, а не транспорт MCP.Учётные данные указываются в
PROXY_USERNAMEиPROXY_PASSWORD. Флага--proxy-passwordнамеренно нет: аргументы командной строки доступны для чтения любому другому пользователю на машине.PROXY_SERVERтакже принимает комбинированную формуhttp://user:pass@host:port, которую выдают большинство провайдеров.Chromium не может проходить аутентификацию через SOCKS-прокси, поэтому для учётных данных требуется конечная точка
http(s). Если ваш провайдер предлагает только аутентифицированный SOCKS5, запустите локальный ретранслятор, который хранит учётные данные, и укажите серверу на него.Локальные адреса также идут через прокси. Обычный прямой маршрут Chromium для
localhostудаляется при установке прокси, поэтому добавьтеPROXY_BYPASS=localhost,127.0.0.1,::1, если вам нужно напрямую обращаться к локальным целям.Автоимпорт пропускается при настроенном прокси: сессия, взятая из локального браузера, была создана с вашего реального адреса, и перенос её на прокси — это как раз то изменение, которое вызывает контрольную точку. Используйте
--login.Неверный пароль прокси не сообщает о себе: Chromium повторяет попытки аутентификации до истечения времени ожидания страницы, поэтому это проявляется как тайм-аут или неудачный вход. Если сессии перестают работать сразу после добавления прокси, проверьте учётные данные, прежде чем предполагать, что сессия истекла.
Настройте прокси до создания сессии. Запустите
--loginс уже настроенным прокси. Включение прокси для существующего профиля перемещает вошедшую сессию на новый IP-адрес, что и вызывает контрольную точку LinkedIn. То же самое относится к--import-from-browser, который импортирует сессию, созданную с вашего реального IP. По той же причине используйте липкую сессию, а не ротационный пул.
Пользовательский путь к Chrome:
Если Chrome установлен в нестандартном месте, используйте
--chrome-path /path/to/chromeТакже можно задать через переменную окружения:
CHROME_PATH=/path/to/chromeНа macOS и Linux браузер должен быть не старше того, который последним открывал ваш профиль, иначе сервер откажется запускаться. (Не на Windows: там нельзя узнать версию браузера, не запустив его, поэтому проверка отключена.) Более старый браузер может молча потерять данные, записанные более новым, включая сохранённую сессию, и тогда сбой выглядит точно так же, как истёкший вход. В сообщении указываются обе версии. Обычный способ выполнить это требование — вернуться к встроенному Chromium после однократного запуска более нового Chrome; либо снова запустите более новый браузер, какой бы он ни был, либо выполните
--login, который откладывает сохранённую сессию в сторону и выполняет новый вход с имеющимся у вас браузером.--logoutтакже очищает её, но отбрасывает старую сессию вместо того, чтобы сохранить её восстанавливаемой, и запрашивает подтверждение в терминале, поэтому его нельзя использовать с сервера, запущенного MCP-клиентом.Только Chrome, Chromium и Chrome for Testing сравниваются таким образом. Форки нумеруются иначе (Vivaldi имеет версию 7.x, номер сборки Edge значительно ниже, чем у Chrome при том же мажорном номере), поэтому указание
CHROME_PATHна такой браузер отключает проверку, а не вызывает отказ, которому ничто не могло бы удовлетворить.
📦 Claude Desktop MCP Bundle (ранее DXT)
Предварительные требования: Claude Desktop.
Установка в один клик для пользователей Claude Desktop:
Скачайте последний артефакт
.mcpbиз релизовНажмите на скачанный файл
.mcpb, чтобы установить его в Claude DesktopВызовите любой инструмент LinkedIn
При запуске пакет MCP начинает в фоновом режиме подготовку общего кэша браузера Patchright Chromium. Если вы вызовете инструмент слишком рано, Claude покажет ошибку о выполняемой настройке. При первом вызове инструмента, требующего аутентификации, сервер открывает окно браузера для входа в LinkedIn и просит повторить попытку после входа.
Справка по настройке пакета MCP
Поведение при первой настройке:
Claude Desktop запускает пакет немедленно; настройка браузера продолжается в фоновом режиме
Если браузер Patchright Chromium всё ещё загружается, повторите попытку вызова инструмента через короткое время
Управляемые загрузки браузера хранятся в
~/.linkedin-mcp/patchright-browsers/Кэш браузера продолжает расти: Patchright хранит старую ревизию Chromium до тех пор, пока любая установленная версия всё ещё ссылается на неё, поэтому при обновлении на диске могут остаться обе. Сервер записывает предупреждение с указанием того, что он хранит. Чтобы освободить место, остановите все экземпляры LinkedIn MCP Server, удалите
~/.linkedin-mcp/patchright-browsers/и позвольте следующему запуску загрузить текущий браузер.Windows: пакет завершается с ошибкой
DLL load failed while importing _greenlet: установите Microsoft Visual C++ Redistributable или переустановите пакет с закреплённой версией greenlet 3.5.5 или новее, чьи опубликованные Windows-колёса снова содержат среду выполнения C++ внутри расширения. Пакет с закреплённой версией greenlet с 3.3.1 по 3.5.4 требуетMSVCP140.dllиз этого распространяемого пакета, которого нет ни в установщике python.org, ни в сборках, управляемыхuv, а greenlet, собранный из исходников, может потребовать его в любой версии. Сервер сам сообщает об этом при запуске, и только после проверки, что загрузчик не может создать эту DLL. Сообщено как greenlet#525, исправлено в greenlet#526.
Проблемы со входом:
Убедитесь, что у вас одновременно активна только одна сессия LinkedIn
LinkedIn может потребовать подтверждение входа в мобильном приложении LinkedIn для
--loginLinkedIn может показать капчу при входе. Запустите
uvx mcp-server-linkedin@latest --login, который откроет браузер, где вы сможете решить капчу вручную. См. настройку uvx для предварительных требований.
Проблемы с тайм-аутом:
Сбои операций со страницей (элементы не найдены, зависание навигации): увеличьте тайм-аут операций со страницей браузера —
--timeout 10000илиTIMEOUT=10000(миллисекунды, по умолчанию 5000).Тайм-аут целых вызовов инструментов (например, многосекционные профили, холодный запуск Chromium, медленные контейнеры): увеличьте тайм-аут выполнения для каждого инструмента —
--tool-timeout 300илиTOOL_TIMEOUT=300(секунды, по умолчанию 180).Первый вызов инструмента без сессии: если в локальном браузере с выполненным входом есть активная сессия LinkedIn, сервер автоматически импортирует её (см.
AUTO_IMPORT_FROM_BROWSER/--auto-import) вместо принудительного ручного входа. На macOS связка ключей может один раз запросить доступ к Safe Storage. Если импортируемой сессии браузера нет, он переходит к открытию окна входа и ждёт доLOGIN_INLINE_WAITсекунд (по умолчанию 25, максимум 45;--login-inline-wait), чтобы быстрый вход завершился за один вызов. Если время ожидания истекло, инструмент возвращает сигнал ожидания, и модель повторяет попытку примерно через 30 секунд. Ни автоимпорт, ни встроенное ожидание не применяются в Docker или когда сервер привязан к не-петлевому HTTP-хосту. Создайте сессию на хосте с помощью--loginили используйте явную команду Docker--login --login-viewer.Пользователям с медленным соединением могут потребоваться более высокие значения для любого из них.
Сообщение о необходимости запустить --login на хосте, когда вы уже это сделали:
Если вызовы инструментов отвечают «No valid LinkedIn session is available in Docker» на машине, которая не является контейнером, среда выполнения была определена неверно. Это происходило на Linux-хостах, где запущен демон Docker для несвязанных сервисов. Установите
LINKEDIN_MCP_CONTAINER=false, чтобы переопределить определение;trueпринудительно задаёт противоположное.
🐳 Настройка Docker
Предварительные требования: Убедитесь, что Docker установлен и запущен.
Аутентификация
Войдите один раз. Контейнер открывает браузер входа в LinkedIn, которым вы управляете из собственной вкладки браузера:
# Create the directory first so the container can save your session into it
mkdir -p ~/.linkedin-mcp
docker run -it --rm \
-v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
-p 127.0.0.1:6080:6080 \
stickerdaniel/linkedin-mcp-server:latest \
--login --login-viewerОткройте полный URL, который выводит команда (он содержит токен доступа), и войдите. После этого просмотрщик закрывается сам; дайте команде завершиться самостоятельно, чтобы сессия была сохранена полностью. Он сдаётся через 30 минут.
Сохраняйте монтирование -v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp при каждом последующем docker run, иначе сервер не сможет найти сессию.
Настройка Claude Desktop с Docker
{
"mcpServers": {
"mcp-server-linkedin": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "~/.linkedin-mcp:/home/pwuser/.linkedin-mcp",
"stickerdaniel/linkedin-mcp-server:latest"
]
}
}
}[!NOTE] Сессии со временем истекают. Когда вызовы инструментов начнут запрашивать аутентификацию, повторите команду входа выше или запустите
uvx mcp-server-linkedin@latest --loginна хосте.
Справка по настройке Docker
Режимы транспорта:
По умолчанию (stdio): Стандартное взаимодействие для локальных MCP-серверов
Streamable HTTP: Для веб-ориентированного MCP-сервера
Если транспорт не указан, сервер по умолчанию использует
stdioИнтерактивный терминал без явного транспорта показывает запрос выбора
Параметры CLI:
--log-level {DEBUG,INFO,WARNING,ERROR}- Уровень журналирования (по умолчанию: WARNING)--transport {stdio,streamable-http}- Принудительно задать режим транспорта (по умолчанию: stdio)--host HOST/--port PORT/--path PATH- Адрес HTTP-сервера (по умолчанию: 127.0.0.1, 8000, /mcp)--logout- Очистить сохранённую сессию и все профили, производные от неё--timeout MS- Тайм-аут для одной операции со страницей (по умолчанию: 5000)--tool-timeout SECONDS- Тайм-аут для всего вызова инструмента (по умолчанию: 180). Увеличьте его для тяжёлых парсингов, медленных сетей или холодного запуска браузера.--login-timeout SECONDS- Сколько времени браузер входа ждёт завершения вашего входа (по умолчанию: 1800; 0 = без ограничения).--login-viewerв любом случае завершает сессию через 30 минут.--login-viewer- Вместе с--loginпоказывает браузер входа по защищённому токеном URL на порту 6080. Требует монтирования профиля из раздела Аутентификация.--login-inline-wait SECONDS- Сколько времени вызов инструмента ждёт завершения входа, прежде чем сообщить модели о повторной попытке (по умолчанию: 25, максимум 45; 0 = вернуть сразу)--browser-wait SECONDS- Сколько ждать, пока другой процесс сервера передаст общий браузер (по умолчанию: 25, максимум 45; 0 = сразу сообщить о занятости). Имеет значение только при одновременной работе нескольких MCP-клиентов.--browser-min-hold SECONDS- Минимальное время, в течение которого этот процесс удерживает общий браузер перед передачей (по умолчанию: 20). Ограничивается 3 секундами ниже--browser-wait, поэтому увеличивайте его вместе с ним. Большее значение означает меньше перезапусков браузера, но более длительное ожидание для других клиентов.--browser-idle-timeout SECONDS- Закрыть бездействующий браузер и освободить профиль после такого времени без вызова инструмента (по умолчанию: 600; 0 = держать открытым)--auto-import/--no-auto-import- Импортировать сессию из локального браузера с выполненным входом при первом вызове инструмента, которому она нужна, перед переходом к ручному входу (игнорируется в Docker). На macOS связка ключей может запросить доступ один раз.--user-data-dir PATH- Каталог профиля браузера (по умолчанию: ~/.linkedin-mcp/profile). Ротация или очистка сессии удаляет этот каталог и его родительский, в котором хранятся сохранённые куки и производные профили.--claim-profile-root- Взять на себя каталог профиля, который сервер не будет занимать сам, например, тот, чей родительский каталог уже содержит другие файлы. Требуется один раз для каждого каталога.--chrome-path PATH- Путь к исполняемому файлу Chrome/Chromium (редко требуется в Docker)--proxy-server URL- Направлять трафик браузера через прокси в форматеscheme://host:port. Задайте пароль черезPROXY_PASSWORD, чтобы он не попадал в список процессов.
[!NOTE] Обычный
--loginв Docker по-прежнему не имеет видимого окна. Добавьте--login-viewerи опубликуйте127.0.0.1:6080:6080только для одноразовой команды входа. Docker по умолчанию уже имеет графический интерфейс, поэтому--no-headlessничего не меняет. Экспериментальный--daemonигнорируется в Docker, потому что его владелец может пережить виртуальный дисплей.
Пример HTTP-режима (для веб-ориентированных MCP-клиентов):
docker run -it --rm \
-v ~/.linkedin-mcp:/home/pwuser/.linkedin-mcp \
-p 127.0.0.1:8080:8080 \
stickerdaniel/linkedin-mcp-server:latest \
--transport streamable-http --host 0.0.0.0 --port 8080 --path /mcpОбе половины нужны, и они выполняют разные задачи. --host 0.0.0.0
делает сервер доступным внутри контейнера: процесс, привязанный к
127.0.0.1, вообще нельзя достичь через опубликованный порт. А
127.0.0.1: перед -p ограничивает доступ снаружи, только этой машиной.
Уберите этот префикс — и Docker опубликует сервер на всех интерфейсах, что
выставит в вашу сеть конечную точку без аутентификации. Сервер не может
отличить один случай от другого, поэтому предупреждает в обоих.
Публикация через loopback ограничивает доступ машиной, а не контейнером.
Другие контейнеры на том же хосте всё ещё могут достучаться до него через
host.docker.internal там, где это имя резолвится, — так работает по
умолчанию в Docker Desktop и OrbStack, но не в нативном Linux Docker.
Логи рантайм-сервера выводит FastMCP/Uvicorn.
HTTP-сервер отвечает на запросы, адресованные localhost или адресу, к
которому он привязан, а остальные отклоняет с кодом 421. Именно это не
позволяет сайту, который вы просто посетили, направить домен на этот сервер
и использовать вашу LinkedIn-сессию через ваш же браузер.
Обращение к серверу по любому другому имени отклоняется, включая имя машины
в вашей сети и публичное имя за обратным прокси. Либо настройте прокси на
переписывание upstream-заголовка Host на адрес бэкенда, либо укажите имя
хоста, под которым вы его отдаёте:
FASTMCP_HTTP_ALLOWED_HOSTS='["mcp.example"]'Это разрешает ровно это имя и продолжает отклонять всё остальное. Конечная точка по-прежнему без аутентификации, поэтому всё, что доступно за пределами вашей машины, должно находиться за чем-то, что её обеспечивает.
Тест с mcp inspector:
Установите и запустите mcp inspector:
bunx @modelcontextprotocol/inspectorНажмите на предзаполненный token url, чтобы открыть inspector в браузере
Выберите
Streamable HTTPкакTransport TypeУстановите
URLвhttp://localhost:8080/mcpПодключитесь
Протестируйте инструменты
Проблемы с Docker:
Убедитесь, что Docker установлен
Проверьте, запущен ли Docker:
docker psОшибки прав доступа к
~/.linkedin-mcp: более ранний запуск Docker от root мог создать каталог от имени root. Исправьте черезsudo chown -R "$(id -u):$(id -g)" ~/.linkedin-mcp.
Проблемы со входом:
Убедитесь, что у вас одновременно активна только одна LinkedIn-сессия
LinkedIn может потребовать подтверждения входа в мобильном приложении LinkedIn для
--loginLinkedIn может показать капчу при входе. Запустите
uvx mcp-server-linkedin@latest --login— откроется браузер, где вы сможете решить капчу вручную. См. настройку uvx для предусловий.Если Docker-аутентификация устарела после повторного входа на хосте, перезапустите Docker один раз, чтобы он заново построил мост из новой исходной сессии.
Проблемы с таймаутами:
Сбои операций со страницей (элементы не найдены, навигация зависает): увеличьте таймаут операций со страницей —
--timeout 10000илиTIMEOUT=10000(миллисекунды, по умолчанию 5000).Таймаут целых вызовов инструментов (например, многосекционные профили, холодный старт Chromium, медленные контейнеры): увеличьте таймаут выполнения инструмента —
--tool-timeout 300илиTOOL_TIMEOUT=300(секунды, по умолчанию 180).Первый вызов инструмента без сессии: если локально вошедший браузер имеет живую LinkedIn-сессию, сервер автоматически импортирует её (см.
AUTO_IMPORT_FROM_BROWSER/--auto-import) вместо принудительного ручного входа. На macOS связка ключей может один раз запросить доступ к Safe Storage. Если импортируемой сессии браузера нет, сервер открывает окно входа и ждёт доLOGIN_INLINE_WAITсекунд (по умолчанию 25, максимум 45;--login-inline-wait), чтобы быстрый вход завершился за один вызов. Если время истекло, инструмент возвращает сигнал ожидания, и модель повторяет попытку примерно через 30 секунд. Ни автоимпорт, ни встроенное ожидание не применяются в Docker или когда сервер привязан к не-loopback HTTP-хосту. Создайте сессию на хосте через--loginили используйте явную Docker-команду--login --login-viewer.Пользователям с медленным соединением могут понадобиться большие значения для обоих.
Вам говорят запустить --login на хосте, хотя вы уже это делали:
Если вызовы инструментов отвечают «No valid LinkedIn session is available in Docker» на машине, которая не является контейнером, рантайм был определён неверно. Это случалось на Linux-хостах, где демон Docker запущен для несвязанных сервисов. Установите
LINKEDIN_MCP_CONTAINER=false, чтобы переопределить определение;trueпринудительно включает обратное.
Использование прокси:
Большинству людей он не нужен. Рекомендации самого LinkedIn по снижению числа проверок безопасности — избегать VPN или прокси, и он оценивает адреса, с которых входит сессия. Домашнее подключение, которым вы пользуетесь годами, — сигнал доверия; коммерческий выходной узел с неизвестной историей — нет, и переход на него сам по себе является тем изменением, которое вызывает контрольную проверку. Прокси оправдан в одном случае: сервер работает там, где его адрес явно принадлежит дата-центру, или в другой стране, чем история аккаунта. Даже тогда выходной узел WireGuard или Tailscale в вашей домашней сети лучше любого платного провайдера, потому что адрес действительно ваш. Если вы всё же покупаете, берите выделенный статический ISP-адрес и держите его, а не ротационный резидентный пул.
Направьте браузер через прокси с помощью
--proxy-server http://host:port(принимаютсяhttp,https,socks4иsocks5). Маршрутизируется только трафик браузера, не MCP-транспорт.Учётные данные задаются в
PROXY_USERNAMEиPROXY_PASSWORD. Флага--proxy-passwordнамеренно нет: аргументы командной строки читаются всеми остальными пользователями машины.PROXY_SERVERтакже принимает комбинированную формуhttp://user:pass@host:port, которую выдают большинство провайдеров.Chromium не может аутентифицироваться в SOCKS-прокси, поэтому для учётных данных нужна конечная точка
http(s). Если провайдер предлагает только аутентифицированный SOCKS5, запустите локальный ретранслятор, который держит учётные данные, и укажите серверу на него.Локальные адреса тоже идут через прокси. Обычный прямой маршрут Chromium для
localhostудаляется при установке прокси, поэтому добавьтеPROXY_BYPASS=localhost,127.0.0.1,::1, если нужно напрямую достигать локальных целей.Автоимпорт пропускается при настроенном прокси: сессия, взятая из локального браузера, создана на вашем реальном адресе, и перенос её на прокси — то самое изменение, которое запускает проверку. Используйте
--login.Неверный пароль прокси не сообщает о себе: Chromium повторяет запрос аутентификации, пока страница не истечёт по таймауту, поэтому это выглядит как таймаут или неудачный вход. Если сессии перестают работать сразу после добавления прокси, проверьте учётные данные, прежде чем считать сессию истёкшей.
Настройте прокси до создания сессии. Запустите
--loginс уже настроенным прокси. Включение прокси для существующего профиля переносит вошедшую сессию на новый IP — это и запускает проверку LinkedIn. То же относится к--import-from-browser, который импортирует сессию, созданную на вашем реальном IP. Используйте липкую сессию, а не ротируемый пул, по той же причине.
Нестандартный путь Chrome:
Если Chrome установлен в нестандартном месте, используйте
--chrome-path /path/to/chromeТакже можно задать через переменную окружения:
CHROME_PATH=/path/to/chromeНа macOS и Linux браузер должен быть не старше того, который последним открывал ваш профиль, иначе сервер откажется запускаться. (Не на Windows: там нельзя узнать версию браузера, не запустив его, поэтому проверка отключена.) Более старый браузер может молча потерять хранилища, записанные более новым, включая сохранённую сессию, и тогда сбой выглядит точно как истёкший вход. Сообщение называет обе версии. Возврат к встроенному Chromium после однократного запуска более нового Chrome — обычный способ выполнить это условие; либо запустите более новый браузер снова, какой бы он ни был, либо выполните
--login, который откладывает сохранённую сессию и входит заново с тем браузером, что у вас есть.--logoutтоже очищает её, но выбрасывает старую сессию вместо того, чтобы оставить её восстанавливаемой, и требует подтверждения в терминале, поэтому его нельзя использовать с сервера, запущенного MCP-клиентом.Только Chrome, Chromium и Chrome for Testing сравниваются таким образом. Форки нумеруют себя иначе (Vivaldi на 7.x, номер сборки Edge сидит далеко ниже Chrome при том же мажоре), поэтому указание
CHROME_PATHна такой форк отключает проверку, а не вызывает отказ, которому ничто не могло бы удовлетворить.В документированной Docker-настройке эта проверка не применяется. Контейнер никогда не открывает профиль, созданный вами через
--login; он выводит свой из ваших куки и по умолчанию пересобирает его с нуля при каждом старте, так что старому образу нечего понижать. СEXPERIMENTAL_PERSIST_DERIVED_RUNTIMEпроизводный профиль сохраняется, и тег образа, который откатывается назад, выбрасывает его и пересобирает заново — опять же, вам ничего делать не нужно. Проверка важна на хосте, где сервер открывает этот профиль напрямую. Не во время самого--login, который откладывает старый профиль до запуска браузера и потому никогда не может её сработать.
🐍 Локальная настройка (разработка и вклад)
Вклад приветствуется! См. CONTRIBUTING.md для архитектурных рекомендаций и чек-листов. Пожалуйста, откройте issue сначала, чтобы обсудить фичу или исправление бага перед отправкой PR.
Предусловия: установлены Git и uv
Установка
# 1. Clone repository
git clone https://github.com/stickerdaniel/linkedin-mcp-server
cd linkedin-mcp-server
# 2. Install UV package manager (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 3. Install dependencies
uv sync
uv sync --group dev
# 4. Install pre-commit hooks
uv run pre-commit install
# 5. Start the server
uv run -m linkedin_mcp_serverЛокальный сервер использует тот же управляемый рантайм-поток, что и MCPB и uvx: он готовит кэш браузера Patchright Chromium в фоне и открывает вход в LinkedIn при первом вызове инструмента, требующего аутентификации. Вы всё ещё можете запустить uv run -m linkedin_mcp_server --login, когда хотите создать сессию явно.
Помощь по локальной настройке
Параметры CLI:
--login— открыть браузер для входа и сохранить сессию--import-from-browser [BROWSER]— переиспользовать сессию из локально вошедшего браузера Chromium (chrome,chromium,brave,edge,arc,vivaldi,helium,yandex,whale,auto). Голый флаг выбираетauto— самый недавно использованный браузер с живой LinkedIn-сессией.--status— проверить, действительна ли сохранённая сессия, затем выйти--logout— очистить сохранённую сессию--no-headless— показать окно браузера (полезно для отладки)--log-level {DEBUG,INFO,WARNING,ERROR}— уровень логирования (по умолчанию: WARNING)--transport {stdio,streamable-http}— принудительно задать режим транспорта (по умолчанию: stdio)--host HOST/--port PORT/--path PATH— адрес HTTP-сервера (по умолчанию: 127.0.0.1, 8000, /mcp)--timeout MS— таймаут одной операции со страницей (по умолчанию: 5000)--tool-timeout SECONDS— таймаут целого вызова инструмента (по умолчанию: 180). Увеличьте для тяжёлых скрейпов, медленных сетей или холодного старта браузера.--user-data-dir PATH— каталог профиля браузера (по умолчанию: ~/.linkedin-mcp/profile). Ротация или очистка сессии удаляет этот каталог и его родителя, в котором хранятся сохранённые куки и производные профили.--claim-profile-root— взять на себя каталог профиля, который сервер не станет забирать сам, например, если его родитель уже содержит другие файлы. Нужен один раз на каталог.--slow-mo MS— задержка между действиями браузера (по умолчанию: 0, полезно для отладки)--viewport WxH— размер окна просмотра (по умолчанию: 1280x720). Применяется только в безоконном режиме; при запуске с окном используется реальный размер окна.--chrome-path PATH— путь к исполняемому файлу Chrome/Chromium--proxy-server URL— направить трафик браузера через прокси в видеscheme://host:port. Пароль задаётся черезPROXY_PASSWORD, что держит его вне списка процессов.--help— показать справку
Примечание: большинство параметров CLI имеют эквиваленты в переменных окружения. См.
.env.exampleдля деталей.
Пример HTTP-режима (для веб-клиентов MCP):
uv run -m linkedin_mcp_server --transport streamable-http --host 127.0.0.1 --port 8000 --path /mcpClaude Desktop:
{
"mcpServers": {
"mcp-server-linkedin": {
"command": "uv",
"args": ["--directory", "/path/to/linkedin-mcp-server", "run", "-m", "linkedin_mcp_server"]
}
}
}Для этой конфигурации по умолчанию используется stdio.
Проблемы со входом:
Убедитесь, что одновременно активна только одна сессия LinkedIn
LinkedIn может запросить подтверждение входа в мобильном приложении LinkedIn для
--loginLinkedIn может показать капчу при входе. Команда
--loginоткрывает браузер, где вы можете решить её вручную.
Проблемы со скрейпингом:
Используйте
--no-headless, чтобы видеть действия браузера и отлаживать проблемы скрейпингаДобавьте
--log-level DEBUG, чтобы увидеть более подробное логирование
Проблемы с сессиями:
Профиль браузера хранится в
~/.linkedin-mcp/profile/Загруженные управляемые браузеры кэшируются в
~/.linkedin-mcp/patchright-browsers/и являются общими для установокuvxи MCP BundleКэш браузера постоянно растёт: Patchright хранит старую ревизию Chromium до тех пор, пока любая установленная версия всё ещё ссылается на неё, а архив
uvили ещё один worktree является такой ссылкой. Сервер записывает в журнал предупреждение с указанием того, что он удерживает. Чтобы освободить место, остановите все экземпляры LinkedIn MCP Server, удалите~/.linkedin-mcp/patchright-browsers/и позвольте следующему запуску загрузить текущий браузер.Используйте
--logout, чтобы очистить профиль и начать заново
Проблемы с Python/Patchright:
Проверьте версию Python:
python --version(должна быть 3.12+)Переустановите Patchright:
uv run patchright install chromiumПереустановите зависимости:
uv sync --reinstall
Проблемы с тайм-аутами:
Сбои операций со страницей (элементы не найдены, навигация зависает): увеличьте тайм-аут операций со страницей браузера —
--timeout 10000илиTIMEOUT=10000(миллисекунды, по умолчанию 5000).Тайм-аут целых вызовов инструментов (например, многосекционные профили, холодный старт Chromium, медленные контейнеры): увеличьте тайм-аут выполнения инструмента —
--tool-timeout 300илиTOOL_TIMEOUT=300(секунды, по умолчанию 180).Первый вызов инструмента без сессии: если в локально авторизованном браузере есть активная сессия LinkedIn, сервер автоматически импортирует её (см.
AUTO_IMPORT_FROM_BROWSER/--auto-import) вместо принудительного ручного входа. В macOS связка ключей может один раз запросить доступ к Safe Storage. Если импортируемой сессии браузера нет, сервер в качестве запасного варианта открывает окно входа и ждёт доLOGIN_INLINE_WAITсекунд (по умолчанию 25, максимум 45;--login-inline-wait), чтобы быстрый вход завершился за один вызов. Если время ожидания истекло, инструмент возвращает сигнал ожидания, и модель повторяет попытку примерно через 30 секунд. Ни автоимпорт, ни встроенное ожидание не применяются ни в Docker, ни когда сервер привязан к не-loopback HTTP-хосту. Создайте сессию на хосте с помощью--loginлибо используйте явную команду Docker--login --login-viewer.Пользователям с медленным соединением могут потребоваться более высокие значения для любого из этих параметров.
Если вам говорят выполнить --login на хосте, когда вы уже это сделали:
Если вызовы инструментов отвечают "No valid LinkedIn session is available in Docker" на машине, которая не является контейнером, среда выполнения была определена неверно. Это происходило на Linux-хостах, где демон Docker запущен для несвязанных сервисов. Установите
LINKEDIN_MCP_CONTAINER=false, чтобы переопределить это определение;trueпринудительно задаёт противоположное.
Использование прокси:
Большинству людей использовать прокси не стоит. Рекомендации LinkedIn по снижению числа проверок безопасности — избегать VPN или прокси; кроме того, LinkedIn оценивает адреса, с которых входит сессия. Домашнее подключение, которым вы пользуетесь годами, — сигнал доверия; коммерческий выходной узел с неизвестной вам историей — нет, и переход на него сам по себе является тем изменением, которое вызывает контрольную проверку. Прокси оправдан в одном случае: сервер работает там, где его адрес явно принадлежит дата-центру либо находится в другой стране, нежели история аккаунта. Даже тогда выходной узел WireGuard или Tailscale в вашей домашней сети лучше любого платного провайдера, потому что адрес действительно ваш. Если вы всё же покупаете прокси, возьмите выделенный статический адрес у интернет-провайдера и сохраняйте его, а не вращающийся пул резидентных адресов.
Направляйте браузер через прокси с помощью
--proxy-server http://host:port(поддерживаютсяhttp,https,socks4иsocks5). Через прокси направляется только трафик браузера, а не транспорт MCP.Учётные данные задаются в
PROXY_USERNAMEиPROXY_PASSWORD. Флага--proxy-passwordнамеренно нет: аргументы командной строки доступны для чтения всем остальным пользователям машины.PROXY_SERVERтакже принимает комбинированную формуhttp://user:pass@host:port, которую выдают большинство провайдеров.Chromium не может проходить аутентификацию в SOCKS-прокси, поэтому для учётных данных требуется конечная точка
http(s). Если ваш провайдер предлагает только аутентифицированный SOCKS5, запустите локальный ретранслятор, хранящий учётные данные, и укажите серверу на него.Локальные адреса тоже идут через прокси. Обычный прямой маршрут Chromium для
localhostудаляется при настройке прокси, поэтому добавьтеPROXY_BYPASS=localhost,127.0.0.1,::1, если вам нужно обращаться к локальным целям напрямую.Автоимпорт пропускается при настроенном прокси: сессия, взятая из локального браузера, была создана с вашего реального адреса, и перенос её на прокси — это как раз то изменение, которое вызывает контрольную проверку. Используйте
--login.Неверный пароль прокси не сообщает о себе: Chromium повторяет запрос аутентификации, пока не истечёт тайм-аут страницы, поэтому проблема проявляется как тайм-аут или неудачный вход. Если сессии перестают работать сразу после добавления прокси, проверьте учётные данные, прежде чем считать, что сессия истекла.
Настройте прокси до создания сессии. Запустите
--loginс уже настроенным прокси. Включение прокси для существующего профиля переносит активную сессию на новый IP — именно это и вызывает контрольную проверку LinkedIn. То же самое относится к--import-from-browser, который импортирует сессию, созданную с вашего реального IP. По той же причине используйте фиксированную (sticky) сессию, а не вращающийся пул.
Нестандартный путь к Chrome:
Если Chrome установлен в нестандартном месте, используйте
--chrome-path /path/to/chromeЕго также можно задать через переменную окружения:
CHROME_PATH=/path/to/chromeНа macOS и Linux браузер должен быть не старше того, который последним открывал ваш профиль; в противном случае сервер отказывает в запуске. (Не относится к Windows: там невозможно узнать версию браузера, не запустив его, поэтому проверка отключена.) Более старый браузер может молча отбросить хранилища, записанные более новым, в том числе сохранённую сессию, и тогда сбой выглядит точно так же, как истёкший вход. В сообщении называются обе версии. Обычный способ удовлетворить это требование — вернуться к встроенному Chromium после однократного запуска более нового Chrome; либо снова запустите тот более новый браузер, какой бы он ни был, либо выполните
--login, который откладывает сохранённую сессию в сторону и выполняет вход заново в имеющемся браузере.--logoutтоже очищает её, но отбрасывает старую сессию, не оставляя возможности её восстановить, и запрашивает подтверждение в терминале, поэтому его нельзя использовать с сервера, запущенного MCP-клиентом.Так сравниваются только Chrome, Chromium и Chrome for Testing. Форки нумеруют себя иначе (у Vivaldi версия 7.x, а номер сборки Edge при том же мажорном номере значительно ниже, чем у Chrome), поэтому указание
CHROME_PATHна такой браузер отключает проверку, а не приводит к отказу, которому невозможно соответствовать.
[!IMPORTANT] FAQ
Безопасно ли это использовать? Меня могут забанить? Этот инструмент управляет реальной сессией браузера; он не использует недокументированные API и не обходит аутентификацию. Пользовательское соглашение LinkedIn запрещает автоматизированный доступ, а аккаунты, использующие автоматизированные инструменты, могут быть ограничены или заблокированы. Используйте на свой страх и риск; гарантий безопасности аккаунта нет. Если вы столкнётесь с какими-либо проблемами, сообщите мне в Обсуждениях.
Что, если мои агенты выполнят слишком много действий? Вызовы инструментов выполняются последовательно через очередь. Вы несёте ответственность за объём автоматизации, который запускаете; используйте её умеренно и давайте агентам ответственные инструкции.
Благодарности
Создано с помощью FastMCP и Patchright.
Используйте в соответствии с Пользовательским соглашением LinkedIn. Автоматизированный доступ может нарушать условия LinkedIn и приводить к ограничениям аккаунта. Этот инструмент предназначен только для личного использования и не предоставляет никаких гарантий.
Лицензия
Этот проект лицензируется в соответствии с лицензией Apache 2.0.
Available Tools
19 toolsclose_sessionClose SessionADestructive
Close the current browser session and clean up resources.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The destructiveHint annotation already signals this is a destructive action, and the description confirms it by saying 'Close' and 'clean up resources'. It adds some scope detail ('current browser session') but does not describe side effects such as invalidating cookies, logging out the user, or making the session unusable. Since the annotations carry much of the safety signal, a mid-range score is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The entire description is a single, front-loaded sentence with no redundant words. It states the action and consequence efficiently, earning a top score for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, destructive tool with an output schema and annotation coverage, the description is complete enough for an agent to know what will happen. The absence of an alternative, zero parameters, and existing destructiveHint mean no additional operational context is essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema is empty with 100% coverage, so there are no parameter semantics for the description to clarify. With no params, the baseline is 4, and the description does not need to add parameter-level explanation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Close') and names the resource ('current browser session') plus a clear secondary purpose ('clean up resources'). It is well-distinguished from all sibling tools, which focus on profiles, searches, messaging, and feed actions, not session lifecycle.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context that this tool ends the current browser session, implying it should be used when the session is no longer needed. There are no sibling tools providing an alternative session-close action, so explicit exclusions are unnecessary. A fully explicit 'use this when you are done' statement would improve clarity, but the context is already strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connect_with_personConnect With PersonADestructive
Send a LinkedIn connection request or accept an incoming one.
The tool is annotated with destructiveHint so MCP clients will prompt for user confirmation before execution.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | Optional note to include with the invitation | |
| linkedin_username | Yes | LinkedIn username (e.g., "stickerdaniel", "williamhgates") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint, and the description adds that 'MCP clients will prompt for user confirmation before execution,' which provides some behavioral context. However, it does not explain side effects beyond confirmation, such as potential duplicate requests or permission requirements, leaving room for more transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no fluff. It leads with the primary purpose and then notes the annotation implication. Every word earns its place, making it appropriately concise and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with a clear action (connection request/accept), full schema coverage, and annotations covering safety, the description is sufficiently complete. It doesn't need to elaborate on return values since an output schema exists, and the action is straightforward. Minor gaps like error handling or idempotency could be added, but they aren't essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides full descriptions for both parameters (linkedin_username and note), so schema description coverage is 100%. The description itself adds no extra parameter meaning beyond what is already in the schema, matching the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Send a LinkedIn connection request or accept an incoming one.' This specifies the verb (send/accept) and resource (connection request), and distinguishes it from siblings like send_message and get_inbox, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool by stating its purpose, but it does not explicitly provide context or alternatives. There is no mention of when not to use it or comparisons to similar tools, so the guidance is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_company_employeesGet Company EmployeesARead-only
List employees at a company from the LinkedIn /people/ page, including the demographics aggregate that this view exposes: where employees live, where they studied, and a function breakdown (Engineering, Sales, Operations, etc.). The demographics are unique to this tool.
For filtered search by network degree (1st/2nd/3rd) or location, prefer search_people with current_company set to the company URN id. That path also returns more result pages than the /people/ tab.
The optional keywords filter narrows results by name, title, or skill.
company_name must be the exact LinkedIn URL slug (the path segment after /company/), not the display name. LinkedIn assigns unique slugs and the display name often does not match. For example, the AI lab Anthropic lives at /company/anthropicresearch/, not /company/anthropic/. If you are unsure of the slug, call search_companies first and pick the slug from the returned references.
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | No | Optional filter by name, job title, or skill (e.g., "engineer", "sales") | |
| company_name | Yes | LinkedIn company URL slug (e.g., "docker", "anthropicresearch", "microsoft") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, but the description adds behavioral context: it derives data from a specific LinkedIn page, exposes unique demographics, and warns about fewer result pages compared to search_people. It also clarifies the slug requirement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is multi-paragraph and detailed, but every sentence adds value—use cases, alternatives, parameter constraints, and an example. While slightly longer than strictly necessary, it's efficiently structured around purpose, usage, and uniqueness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given annotations (readOnlyHint, openWorldHint), the description covers all necessary behavioral context: output includes aggregates, page limits relative to search_people, and the surprising slug mismatch. With an output schema and both params documented, no critical gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema describes both parameters with examplesags: company_name is a slug, keywords is optional filter. The description elaborates on the slug format and gives an example, but doesn't fully detail keyword matching semantics beyond 'name, title, or skill.' Schema coverage is 100% and description reinforces it, so a high score is warranted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource:
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly directs users to search_people for filtered searches by degree/location and notes the /people/ tab limitation, providing clear exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_company_postsGet Company PostsARead-only
Get recent posts from a company's LinkedIn feed.
| Name | Required | Description | Default |
|---|---|---|---|
| company_name | Yes | LinkedIn company name (e.g., "docker", "anthropic", "microsoft") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint. The description adds no extra context about authentication, rate limits, or side effects. It does not contradict the annotations, but it also does not provide additional behavioral details beyond what the annotations already imply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no unnecessary words or repetition. It is well-structured and directly states the tool's function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the description sufficiently covers its purpose. Since an output schema exists (per context signals), the description does not need to explain return values, and no additional context is required for this straightforward operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides a description for the only parameter (company_name) with examples. The tool description does not add further semantic meaning beyond the schema, and since the schema coverage is high, the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('get') and the resource ('recent posts from a company's LinkedIn feed'). It effectively differentiates from sibling tools like 'get_company_profile' or 'get_company_employees' by specifying the data type (posts).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool versus alternatives, nor does it provide conditions or exclusions. However, the purpose is so straightforward that the usage context is implicitly clear for someone familiar with LinkedIn tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_company_profileGet Company ProfileARead-only
Get a specific company's LinkedIn profile.
| Name | Required | Description | Default |
|---|---|---|---|
| sections | No | Comma-separated list of extra sections to scrape. The about page is always included. Available sections: posts, jobs Examples: "posts", "posts,jobs" Default (None) scrapes only the about page. | |
| company_name | Yes | LinkedIn company name (e.g., "docker", "anthropic", "microsoft") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations (readOnlyHint=true, openWorldHint=true) already indicate a read-only, side-effect-free operation. The description does not contradict these hints and adds no additional behavioral detail such as rate limits or authentication requirements, which would have improved transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that immediately conveys the tool's purpose. It is front-loaded and free of unnecessary wording, making it efficiently scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool, the description is adequate. It conveys the core function, and the schema covers parameter details. However, it might slightly benefit from mentioning that it scrapes the profile (as implied in the schema), but this is not essential for basic usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides high coverage (100%) with detailed descriptions for both parameters, including examples and defaults. The description itself adds no extra meaning beyond the schema, so it does not enhance parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Get a specific company's LinkedIn profile.' It uses a specific verb ('Get') and resource ('company's LinkedIn profile'), which distinguishes it from sibling tools like get_company_posts and get_company_employees.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus the sibling tools. It does not mention any conditions or alternatives, leaving the user to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_conversationGet ConversationA
Read a specific messaging conversation.
Provide either linkedin_username or thread_id to identify the conversation.
When looked up by linkedin_username, resolution searches the messaging inbox for the participant's display name and click-visits every matching row to capture its thread ID — LinkedIn's sidebar has no anchor hrefs or thread-id attributes, so this is the only available path. Each visit selects the row in the LinkedIn UI and may mark it as read. Pass thread_id directly to skip this enumeration.
| Name | Required | Description | Default |
|---|---|---|---|
| index | No | 0-based selector for which thread to open when the participant has multiple threads (e.g. an organic 1-on-1 plus an InMail). Ignored when thread_id is provided. To enumerate thread IDs first, call search_conversations. | |
| thread_id | No | LinkedIn messaging thread ID | |
| linkedin_username | No | LinkedIn username of the conversation participant |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that visiting UI rows 'may also mark them as read' (unusual if no read hint provided). It also explains how the UI's restrictions make enumeration necessary, and the side effect makes the agent more informed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense, layered description that explains LinkedIn UI limitations and the match between the index and thread IDs. Each sentence adds information, but it's somewhat lengthy as it packs in all behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Input schema is complete, output schema, openWorldHint, descriptions of parameter semantics, but no mention of errors, permissions, or result shape (output schema fills that). Adequate for given complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema documentation is 100% covered and describes 'index' behavior with 0-based selection and its precedence relationship to thread_id; the description of the lookup parameters adds contextual nuance beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear action ('read a specific conversation') and distinguishes it as one conversation by username or ID. Sibling tools like get_inbox list all messages, so the 'specific' scope is evident. It lacks explicit sibling differentiation, but the verb+object is specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the linkedin_username lookup path, what it does (enumerating rows), and when to pass thread_id directly 'to skip this enumeration'. It says it's 'the only available path' to justify behavior. No explicit alternatives list, but usage implication is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_feedGet FeedARead-only
Get posts from the authenticated user's LinkedIn feed.
| Name | Required | Description | Default |
|---|---|---|---|
| num_posts | No | Number of posts to fetch (1-50, default 10). Posts are loaded in batches of ~5 as the page scrolls, so the actual count may slightly exceed the target. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description does not disclose behavioral traits beyond the annotations: it only says 'Get posts', which is consistent with readOnlyHint=true but adds no new behavioral context. Notable behavior like batched loading and count overshooting appears only in the schema property description, not in the tool description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no filler, front-loading the action and resource. It is concise without sacrificing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only feed fetch with one optional parameter and an output schema, the description plus schema provide all necessary information. The feed scope is clear, and nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with the num_posts parameter fully documented including default, range, and batch behavior. The tool description itself adds no parameter detail, but the schema already carries the full semantic burden, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb 'Get' and a specific resource 'posts from the authenticated user's LinkedIn feed', which clearly distinguishes it from sibling tools like get_company_posts and search_posts. The phrase 'authenticated user' pins the scope unambiguously.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use — fetching the current user's LinkedIn feed — is reasonably implied by the description, but there is no explicit guidance about when to choose this over alternative tools such as search_posts or get_company_posts. No exclusions or routing hints are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_inboxGet InboxARead-only
List recent conversations from the LinkedIn messaging inbox.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of conversations to load (1-50, default 20) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the safety profile (readOnlyHint=true) and the volatility expectation (openWorldHint=true), lowering the bar. The description adds modest behavioral value by specifying a recency ordering and inbox scope, but it does not disclose pagination behavior or whether ordering is guaranteed beyond the word 'recent.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence with zero filler: the verb is front-loaded, the resource and scope are named immediately, and no structured information from the schema or annotations is redundantly repeated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with one fully documented optional parameter, an output schema, and safety annotations, almost nothing an agent needs to call it is missing. The only slight gap is pinning down the meaning of 'recent' and the ordering guarantee, which is minor at this complexity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%: the single parameter (limit) has its type, numeric range, default, and meaning fully documented in the schema. The description contributes no parameter-level detail, so the baseline 3 for fully covered schemas applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and a well-defined resource ('recent conversations from the LinkedIn messaging inbox'). It distinguishes cleanly from the sibling tools get_conversation (a single thread's messages) and search_conversations (query-driven search), so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes clear context: this is the default, recency-ordered browsing entry point for inbox conversations. However, it never names the alternatives or states when not to use it — especially relevant given the closely related search_conversations and get_conversation siblings — so the routing decision is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_job_detailsGet Job DetailsARead-only
Get job details for a specific job posting on LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | LinkedIn job ID (e.g., "4252026496", "3856789012") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the description does not need to restate basic safety. The description adds no meaningful behavioral context beyond the annotations, such as what kind of details are returned or whether the job must be publicly accessible. It is consistent with the annotations, so no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one short sentence with no filler. It front-loads the action and resource, and every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity—one parameter, full schema coverage, output schema present, and read-only annotations—the description is nearly complete. The only minor gap is lack of explicit guidance on when to choose this over search_jobs, but the 'specific job posting' wording covers the core usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage for the single parameter, including an example format for job_id. The description does not add additional parameter meaning beyond what the schema already provides, but with full schema coverage the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get'), the resource ('job details'), and the scope ('for a specific job posting on LinkedIn'). It distinguishes itself from sibling tools like search_jobs and get_saved_jobs by emphasizing a specific job ID rather than searching or listing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for a specific job posting' implies this tool should be used when you already have a job_id and need details, as opposed to searching for jobs. However, it does not explicitly state when not to use it or name alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_my_profileGet My ProfileARead-only
Get the authenticated user's own LinkedIn profile.
Navigates to /in/me/ and resolves the redirect to obtain the real username before scraping, so the url field in the result is the actual profile URL (e.g. linkedin.com/in/johndoe/) rather than /in/me/.
| Name | Required | Description | Default |
|---|---|---|---|
| sections | No | Comma-separated list of extra sections to scrape. The main profile page is always included. Available sections: experience, education, interests, honors, languages, certifications, skills, projects, contact_info, posts Examples: "experience,education", "contact_info", "skills,projects" Default (None) scrapes only the main profile page. | |
| max_scrolls | No | Maximum pagination attempts per section (same as get_person_profile). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds valuable behavioral context by explaining that the tool navigates to /in/me/, follows the redirect, and returns the canonical profile URL instead of the /in/me/ placeholder.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose in the first sentence, and the second sentence adds a single high-value behavioral detail about redirect resolution. There is no filler, repetition of schema content, or tangential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity, full schema coverage, and presence of an output schema, the description provides everything needed to invoke the tool correctly. The redirect-resolution note closes the only likely source of confusion about the returned url field.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the input schema already documents sections and max_scrolls with defaults, examples, and constraints. The tool description does not add additional parameter meaning, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool gets the authenticated user's own LinkedIn profile, using a specific verb and resource. It also distinguishes itself from sibling tools like get_person_profile by emphasizing 'own' profile, and adds a concrete detail about resolving /in/me/ to the real URL.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this tool is for the authenticated user's own profile, which differentiates it from get_person_profile. It does not explicitly name alternatives or enumerate when-not-to-use, but the context is clear enough for an agent to select it appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_person_profileGet Person ProfileARead-only
Get a specific person's LinkedIn profile.
| Name | Required | Description | Default |
|---|---|---|---|
| sections | No | Comma-separated list of extra sections to scrape. The main profile page is always included. Available sections: experience, education, interests, honors, languages, certifications, skills, projects, contact_info, posts Examples: "experience,education", "contact_info", "skills,projects", "honors,languages", "posts" Default (None) scrapes only the main profile page. | |
| max_scrolls | No | Maximum pagination attempts per section to load more content. On detail sections (experience, certifications, skills, etc.) this is the max number of "Show more" button clicks. On activity/posts it is the max scroll-to-bottom iterations. Applies to all sections in this call. Default (None) uses 5 for detail sections and 10 for posts. Increase when a profile has many items in a section (e.g., 30+ certifications, max_scrolls=20). To avoid slowing down other sections, request heavy sections in a separate call. | |
| linkedin_username | Yes | LinkedIn username (e.g., "stickerdaniel", "williamhgates") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true, so the safety profile is clear. The description adds context about optional sections and pagination behavior (max_scrolls) which helps set expectations. It doesn't repeat annotation info, adding value on how the tool scrapes sections, though it could be more explicit about potential side effects (none) or rate limiting. Given annotations cover read-only nature, a 4 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single clear sentence, front-loaded with the action. It's concise, but it lacks detail on options that the schema covers, making it slightly under-specified as a standalone description. However, given the schema's richness, it's appropriately brief. It earns a 4 for efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a rich schema (100% param coverage) and an output schema present, the description doesn't need to explain return values. The description covers the primary purpose and the schema handles details. It is complete enough for a straightforward read operation, though it doesn't mention error scenarios. Given the annotations, a 4 is fair.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage of parameters with detailed descriptions (e.g., sections format, max_scrolls behavior). The description doesn't add additional parameter meaning beyond what's in the schema, so baseline 3 is justified. It does mention the main parameter implicitly in 'specific person', but that's minimal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves a specific person's LinkedIn profile using a username, which distinguishes it from siblings like get_my_profile and get_company_profile. It is specific verb+resource with the required parameter noted.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving a profile by username, and the schema adds context on optional sections. However, it doesn't explicitly contrast with sibling tools like search_people or get_sidebar_profiles, but the purpose is clear enough for an agent to select it when a known username is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_saved_jobsGet Saved JobsARead-only
List job postings saved by the authenticated LinkedIn user.
Returns job_ids that can be passed to get_job_details for full info.
| Name | Required | Description | Default |
|---|---|---|---|
| max_pages | No | Maximum number of saved-jobs pages to load (1-10, default 3) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations declare readOnlyHint and openWorldHint, so the safety profile is already covered. The description adds value by clarifying that the result is limited to the authenticated user's saved job postings and that it returns job_ids, not full job details—an important behavioral distinction from get_job_details. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The first sentence states the action and scope, and the second sentence provides the important downstream usage detail about feeding job_ids into get_job_details. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with one optional parameter and an output schema, the description is complete. It identifies the authenticated-user scope, the return value, and the logical next step. The annotations cover read-only and open-world behavior, and the schema covers the only parameter. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents max_pages with type, default, range, and description, so the description does not need to repeat it. The tool has only one optional parameter, and the schema coverage is 100%. The description adds no parameter-specific meaning, but none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and a clear resource ('job postings saved by the authenticated LinkedIn user'), which precisely distinguishes this tool from the sibling search_jobs and get_job_details. It also states the key output type (job_ids) and how they connect to another tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the right usage context: it is for the authenticated user's own saved jobs, not general job search. It also gives explicit guidance that the returned job_ids should be passed to get_job_details for full information, which effectively routes the agent to the correct follow-up tool. It does not explicitly list when not to use it, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sidebar_profilesGet Sidebar ProfilesARead-only
Get profile links from sidebar recommendation sections on a LinkedIn profile page.
Extracts profiles from "More profiles for you", "Explore premium profiles", and "People you may know" sidebar sections. Follows "Show all" links to return the full list from each section. Sections that redirect to linkedin.com/premium are skipped.
| Name | Required | Description | Default |
|---|---|---|---|
| linkedin_username | Yes | LinkedIn username of the profile page to scrape (e.g., "stickerdaniel", "williamhgates") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation is respected—the description only retrieves data and does not imply any modification. It clearly states the actions (follows links, skips premium sections) and avoids contradicting the annotation. Since annotations already indicate read-only, the description adds value by detailing the exact procedural behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, using two sentences to convey the core function and key details. It avoids redundancy, though the first sentence is somewhat generic and could be merged with the specifics, but overall it is well-structured and to the point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one input, and the description adequately explains the output (profile links) and key behaviors (following 'Show all', skipping premium). It lacks explicit error handling or edge-case mentions, but given the simplicity and absence of an output schema, it is sufficiently complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully describes the single parameter (linkedin_username) with a clear example. The description adds no additional semantic nuance beyond what is already in the schema, so the baseline of 3 applies given 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool extracts profile links from specific sidebar sections, using precise section names. It distinguishes itself from sibling tools like get_person_profile or search_people by focusing on sidebar recommendations, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for obtaining profile recommendations from a page's sidebar, but does not explicitly contrast with alternatives like get_person_profile or search_people. However, the detailed behavior (following 'Show all', skipping premium) provides implicit context for when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_companiesSearch CompaniesBRead-only
Search for companies on LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | Search keywords (e.g., "fintech", "anthropic", "electric vehicles") |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses no behavioral traits beyond what 'search' and 'LinkedIn' naturally imply. Annotations already declare readOnlyHint and openWorldHint, but the description adds no further context about result limits, matching behavior, or ordering. It is not contradictory, but it is also not informative beyond the basic action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence that wastes no words and immediately states the core action and target resource. It is appropriately sized for a simple tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with an output schema and safety annotations, the description is minimally adequate. However, it does not clarify edge behavior, result scope, or how it differs from nearby company-related tools, so an agent may still need to infer intent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully documents the only parameter, keywords, with a useful example. The description adds no additional semantic detail beyond the schema, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the verb ('Search') and resource ('companies on LinkedIn'), so an agent can understand the basic function. However, it does not differentiate itself from sibling tools like get_company_profile or search_people, leaving some ambiguity about scope or result type.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool instead of search_people, get_company_profile, or get_company_employees. The description implies keyword-based discovery but provides no explicit context, prerequisites, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_conversationsSearch ConversationsC
Search messages by keyword.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of search-result rows to enumerate as conversation references (1-50, default 20). Each enumeration selects the row in LinkedIn's UI and may mark it as read, so a low cap is preferable for noisy queries. | |
| keywords | Yes | Search keywords to filter conversations |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is openWorldHint, so the description carries most of the behavioral disclosure burden. It does not mention that enumerating results may mark conversations as read (noted only in the limit parameter description), nor does it disclose result-shaping behavior. 'Search' implies a read operation, but side effects are hidden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact, front-loaded sentence with no filler. It is easy to parse, but it is so terse that it contributes little beyond the tool name and parameter names, making it less effective than it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with an output schema and fully described parameters, the description is minimally adequate for invocation. However, it lacks usage guidance, scope clarification, and behavioral disclosures, so an agent cannot fully judge when to use it or what side effects may occur.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already fully documents keywords and limit. The description adds no new parameter semantics beyond restating the keyword filter; it does not provide format details, examples, or constraints beyond what the schema offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action (search) and resource (messages), making the tool's core purpose clear. It is somewhat distinct from sibling search tools by focusing on messages, but it does not explicitly differentiate itself from related tools like get_inbox, get_conversation, or search_posts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives such as get_inbox, get_conversation, or search_posts. There is no mention of scope, prerequisites, or situations where another tool should be preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_jobsSearch JobsARead-only
Search for jobs on LinkedIn.
Returns job_ids that can be passed to get_job_details for full info.
| Name | Required | Description | Default |
|---|---|---|---|
| sort_by | No | Sort results (date, relevance) | |
| job_type | No | Filter by job type, comma-separated (full_time, part_time, contract, temporary, volunteer, internship, other) | |
| keywords | Yes | Search keywords (e.g., "software engineer", "data scientist") | |
| location | No | Optional location filter (e.g., "San Francisco", "Remote") | |
| max_pages | No | Maximum number of result pages to load (1-10, default 3) | |
| work_type | No | Filter by work type, comma-separated (on_site, remote, hybrid) | |
| easy_apply | No | Only show Easy Apply jobs (default false) | |
| date_posted | No | Filter by posting date (past_hour, past_24_hours, past_week, past_month) | |
| experience_level | No | Filter by experience level, comma-separated (internship, entry, associate, mid_senior, director, executive) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and open-world. The description adds value by stating that the tool returns job_ids that serve as inputs to get_job_details, which is useful contextual behavior. It does not discuss pagination, max_pages behavior, or filtering limits, but the schema covers those details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no filler. The primary purpose is front-loaded, and the follow-up guidance about job_ids is immediately useful. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with a rich, fully documented schema and an output schema present, the description is sufficient: it states the purpose and the relationship to get_job_details. It does not need to explain parameters or return values in depth because those are already structured elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the heavy lifting is already done by the input schema. The description adds no additional meaning about parameters beyond what the schema documents, matching the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Search') on a specific resource ('jobs on LinkedIn') and adds the key behavioral result: it returns job_ids intended for get_job_details. This differentiates it from sibling search tools like search_people and search_companies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: use this tool when you want to search LinkedIn jobs, and use the returned IDs with get_job_details for fuller information. It does not explicitly list exclusions or compare against alternatives like get_saved_jobs, but the intended use case is obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_peopleSearch PeopleARead-only
Search for people on LinkedIn.
| Name | Required | Description | Default |
|---|---|---|---|
| network | No | Optional connection-degree filter. Each element is one of "F" (1st-degree), "S" (2nd-degree), "O" (3rd-degree and beyond). Example: ["F"] to only return 1st-degree connections. | |
| keywords | Yes | Search keywords (e.g., "software engineer", "recruiter at Google") | |
| location | No | Optional location filter (e.g., "New York", "Remote") | |
| current_company | No | Optional current-employer filter. LinkedIn's currentCompany facet only filters on the numeric company URN id (e.g. "1115" for SAP); plain company names are accepted by the URL but ignored by LinkedIn and return the unfiltered result set. Look up a company's URN via get_company_profile -- it is exposed under references["about"]. For company-wide employee demographics (location/education/function breakdown) plus a slug-based lookup, use get_company_employees instead. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only and open-world nature of this tool. The schema adds a useful caveat that plain company names are silently ignored by LinkedIn's currentCompany filter, but the main description discloses no additional behavioral traits such as result limits, pagination, or network-scope behavior. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no wasted words. It is appropriately concise, though it sacrifices useful context that could have been included without much bloat, keeping it just below a top score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema fully documents all parameters, annotations cover safety and open-world behavior, and an output schema exists, so the definition is mostly sufficient for invocation. The main gap is the lack of explicit sibling differentiation in the description itself, but the tool name and parameter guidance compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already well documented and the baseline is 3. The tool description itself adds no parameter-level meaning. The detailed current_company guidance lives in the schema, not in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a verb and resource: it searches for people on LinkedIn. This distinguishes it from other search tools like search_companies and search_jobs, though it does not explicitly contrast it with person-related siblings such as get_sidebar_profiles or get_person_profile.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes a clear use case: finding people. The current_company parameter description adds valuable routing guidance, directing agents to get_company_profile for URN lookup and get_company_employees for company-wide demographics. However, the tool description itself does not provide a broader when-not-to-use statement versus other people lookup tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_postsSearch PostsARead-only
Search LinkedIn posts/content globally by keyword (the "Posts" tab).
Use this to catch informal hiring posts ("we're hiring", "Buscamos ...", "estamos contratando", "join our team") that often appear before a formal job listing exists. This is global content search, distinct from get_feed (your own home feed) and get_company_posts (one company's page).
| Name | Required | Description | Default |
|---|---|---|---|
| keywords | Yes | Search keywords (e.g., "Buscamos Unity", "AI automation hiring") | |
| max_pages | No | Scroll depth as result "pages" of ~5 scrolls each (1-10, default 3). Content search is an infinite scroll, so this caps how far the page is scrolled rather than fetching discrete pages. | |
| date_posted | No | Optional recency filter. One of "past-24h", "past-week", "past-month"; the "past_24_hours" / "past_week" / "past_month" spellings used by search_jobs are accepted too. Omit for any time. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and openWorldHint already present, the description adds useful context: this is a global content search, not a feed or company-scoped search. It also implies results may include informal/unofficial hiring language, which is relevant behavioral context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: one sentence defines the action, the next gives a concrete use case, and the final sentence distinguishes it from siblings. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 100% parameter schema coverage, the presence of an output schema, and annotations covering safety and openness, the description covers all essential decision factors. It tells the agent what the tool does, when to use it, what alternatives exist, and how to craft effective queries.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by providing richer keyword examples and clarifying that content search is global rather than scoped, supplementing the schema's parameter descriptions. It meaningfully supports keyword selection without redundancy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: 'Search LinkedIn posts/content globally by keyword.' It also explicitly differentiates itself from get_feed and get_company_posts, so an agent can immediately identify what this tool is and what it is not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a concrete use case—catching informal hiring posts before formal job listings exist—and provides example keyword patterns. It also names the two sibling alternatives and explains why they are different, making the selection decision explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageSend MessageADestructive
Send a message to a LinkedIn user.
The recipient must be directly messageable from the profile page. This is a write operation when confirm_send is True.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | The message text to send | |
| profile_urn | No | Optional profile URN (e.g. ACoAAB...) to construct the compose URL directly. Providing this bypasses the Message-button lookup and is more reliable when available. Obtain via get_person_profile. Note: inbox may not always show all messages; use search_conversations as a fallback. | |
| confirm_send | Yes | Must be True to send the message | |
| linkedin_username | Yes | LinkedIn username of the recipient |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (destructiveHint and openWorldHint), the description clarifies that the write happens only when confirm_send is True, which is a safeguard. It also adds the requirement for direct messageability. This extra context helps the agent understand the tool's behavior without relying solely on annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences that immediately state the purpose and key constraint. It front-loads the core function and avoids unnecessary elaboration, making it easy for an agent to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a write operation, the description covers the essential behavioral prerequisites (messageability, confirm_send flag) and relies on the schema for parameter details. It does not mention authentication or output, but those are supplied by annotations and the presence of an output schema. The description is adequate for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides complete descriptions for all four parameters (100% coverage), so the tool description does not need to repeat them. It does not add any additional meaning beyond what the schema gives, which is the baseline expectation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (send) and target (a LinkedIn user), with an important qualifier about direct messageability from the profile page. This establishes the tool's core purpose and differentiates it from read-only LinkedIn tools by explicitly labeling it a write operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a prerequisite (the recipient must be directly messageable) and notes that the send only occurs when confirm_send is True, implicitly advising caution. However, it does not mention when to choose this tool over alternatives like connecting first or using the inbox, so guidance on context and exclusions is limited.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
19 tool updates
v4.22.0- First observed
close_session - First observed
connect_with_person - First observed
get_company_employees - First observed
get_company_posts - First observed
get_company_profile - First observed
get_conversation - First observed
get_feed - First observed
get_inbox - First observed
get_job_details - First observed
get_my_profile - First observed
get_person_profile - First observed
get_saved_jobs - First observed
get_sidebar_profiles - First observed
search_companies - First observed
search_conversations - First observed
search_jobs - First observed
search_people - First observed
search_posts - First observed
send_message
TDQS
Scored across 19 tools
Each tool targets a distinct resource/action: people, companies, jobs, messaging, feed, and session management. Overlapping tools like get_feed/search_posts/get_company_posts and get_company_employees/search_people are explicitly differentiated in their descriptions, so an agent should not misselect.
All tool names follow a verb_noun snake_case pattern, primarily get_* and search_*, with a few clear action verbs like send_message, connect_with_person, and close_session. The naming is predictable and consistent across the full set.
At 19 tools, the server is in the 16-25 range that feels heavy, even though the LinkedIn domain is broad. Some niche helpers like get_sidebar_profiles and close_session could be considered non-essential, but the count is not extreme enough to be chaotic.
Core workflows are covered end-to-end: search people, companies, and jobs; retrieve details; connect; message; and read feeds/inbox. Obvious gaps are modest, such as no ability to post content, manage connections, or apply to jobs, but these are not central to the apparent sales/recruiting use case.
Maintenance
Related MCP Connectors
Give AI agents the LinkedIn tools to find, qualify, engage, and follow up with prospects.
LinkedIn jobs, companies and people for AI agents, plus messages and invites via your own account.
Live LinkedIn data for AI agents: profiles, companies, jobs, posts, email finding. No account risk.
Full LinkedIn access for AI agents: leads, messaging, and campaigns with activity limits built in.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI assistants to interact with LinkedIn by scraping profiles, companies, job postings, and getting personalized job recommendations using authenticated browser automation.176,534 PyPI4,000Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to securely search your LinkedIn network, contacts, and DMs to find warm leads, intro paths, and hidden opportunities.26MIT
- AlicenseAqualityCmaintenanceConnects LinkedIn to AI assistants, enabling lead search, profile analysis, messaging, and workflow automation through a cloud browser. Supports sales, recruiting, and market research tasks.59446 npmMIT
- AlicenseAqualityCmaintenanceEnables AI assistants to access LinkedIn data through the user's logged-in browser session, supporting profiles, companies, job searches, messaging, and feed/posts.21Apache 2.0