1. Навіщо взагалі потрібен MCP‑інспектор
Уявіть, що ви налагоджуєте фронтенд, але вам заборонили відкривати DevTools. Приблизно так і виглядає життя без MCP‑інспектора. MCP‑протокол працює «за лаштунками» ChatGPT та Apps SDK. Якщо ви бачите лише відповідь у чаті й думаєте: «Ну чому він не бачить мій інструмент?», — ви, по суті, стріляєте навмання.
Інспектори на кшталт MCP Inspector (офіційного) або MCP Jam — це спеціальні MCP‑клієнти для розробників. Вони вміють:
- підʼєднуватися до вашого MCP‑сервера так само, як це робить ChatGPT;
- проходити handshake / capabilities;
- запитувати список tools/resources/prompts;
- викликати будь‑який tool вручну — із довільними аргументами;
- показувати сирі JSON‑повідомлення (requests / replies / errors).
По суті, це «Postman для MCP, але розумніший». На відміну від звичайного REST‑клієнта, інспектор знає специфіку MCP. Він розуміє tools/list і tools/call, уміє показувати схеми аргументів і часом підтримує навіть OAuth‑флоу для захищених серверів.
Без інспектора налагодження зазвичай виглядає так: ви запускаєте ChatGPT, намагаєтеся викликати застосунок, бачите «Error talking to app» або те, що tool узагалі не викликається, і починаєте гадати: модель не захотіла викликати інструмент, ваш MCP не піднявся чи це JSON‑помилка? З інспектором ви можете перевірити кожен шар окремо: спочатку — MCP‑сервер один на один з інспектором, а потім уже звʼязку ChatGPT ↔ MCP.
2. Міні‑огляд інспекторів: MCP Inspector, Jam та інші
На практиці найчастіше ви користуватиметеся двома типами інспекторів для MCP.
По‑перше, це офіційний MCP Inspector з репозиторію Model Context Protocol. Це вебзастосунок (зазвичай SPA на React), який запускається або локально, або через npx/Docker і вміє підʼєднуватися до вашого MCP‑сервера через HTTP/SSE.
По‑друге, є інспектори на кшталт MCP Jam, які часто додають і зручні можливості для OAuth. Вони можуть самі прочитати .well-known/oauth-protected-resource, витягти звідти authorization_endpoint і token_endpoint, пройти PKCE‑флоу і вже в авторизованому стані звертатися до MCP.
MCP Jam створено розробниками на основі MCP Inspector. Якщо MCP Inspector реалізує мінімальний набір засобів налагодження, то MCP Jam дає майже все, що потрібно розробнику для щоденної роботи з MCP. Раджу одразу користуватися MCP Jam, щоб потім не перевчатися.
З погляду нашого курсу різниця така:
- базовий Inspector потрібен вам завжди — навіть для найпростішого незахищеного MCP‑сервера;
- MCP Jam (або аналог) стає особливо корисним, коли ви дійдете до модулів про автентифікацію й авторизацію.
Але загальна ідея одна: це звичайний MCP‑клієнт — просто він наочно показує те, що ChatGPT робить «мовчки».
3. Типовий сценарій роботи з MCP‑інспектором
Пройдімо типовий сценарій: ви написали новий tool у своєму MCP‑сервері й хочете переконатися, що він справді працює.
У попередній лекції ви вже підняли мінімальний MCP‑сервер. Тепер додамо системності: пройдемо повний цикл «сервер → інспектор → JSON‑логіка» крок за кроком.
Крок 1 — запускаємо MCP‑сервер
Ви вже робили це в попередній лекції. Припустімо, у вас є скрипт npm run mcp-dev:
# приклад запуску MCP‑сервера
npm run mcp-dev
# під капотом щось на кшталт: ts-node src/mcp-server.ts
Важливо, щоб сервер слухав обраний вами транспорт. У курсі зазвичай це HTTP endpoint /mcp на якомусь порту, наприклад http://localhost:4001/mcp.
Крок 2 — запускаємо MCP Jam
Другий термінал:
# один із варіантів запуску MCP Jam
npx @mcpjam/inspector@latest
# за потреби можна додати --port 4002 тощо
Після цього інспектор відкривається в браузері — найчастіше на http://localhost:6274 або на схожому порту.
На стартовому екрані MCP Jam вас попросять указати URL MCP‑сервера. Ви вводите:
http://localhost:4001/mcp
або URL вашого тунелю, якщо ви вже пропускаєте все через ngrok.
Крок 3 — handshake / capabilities
Щойно MCP Jam підʼєднується, він автоматично робить те саме, що й ChatGPT:
- Надсилає ініціалізаційний запит (initialize) з даними про клієнта.
- Отримує відповідь із версією протоколу та capabilities вашого сервера.
- На основі capabilities визначає, чи підтримує сервер tools, resources, prompts та інші можливості.
В інтерфейсі це зазвичай виглядає приблизно так:
Connected
Protocol: mcp/2025-06-18
Capabilities:
- tools: list, call
- resources: list, read
- prompts: list, get
Якщо вже на цьому кроці інспектор не може підʼєднатися (connection refused, CORS, 500 тощо), ви одразу бачите помилку й розумієте: проблема точно не в моделі і не в ChatGPT, а у вашій серверній частині або в мережі.
Крок 4 — discovery: дивимося tools/resources/prompts
Після успішного handshake інспектор зазвичай сам викликає методи на кшталт tools/list, resources/list, prompts/list, щоб заповнити бічну панель. Ви побачите:
- список інструментів з описами та JSON Schema вхідних аргументів;
- список ресурсів, згрупованих за колекціями/шляхами;
- список промптів із короткими описами.
Якщо ви щойно додали новий tool, але його немає в списку, отже, він некоректно зареєстрований на сервері або сервер не піднявся з оновленим кодом. Це значно легше помітити тут, ніж гадати, чому ChatGPT «не хоче» викликати ваш інструмент.
4. Ручний виклик tools через MCP Jam
Найкорисніша функція MCP Jam — ручний виклик інструментів. Це ваш особистий інтерфейс для tools/call.
Обираємо інструмент і заповнюємо аргументи
Припустімо, у попередньому модулі ви написали tool suggest_gifts:
// десь у src/mcp/tools/suggestGifts.ts
export const suggestGiftsTool = {
name: "suggest_gifts",
description: "Підбирає ідеї подарунків за віком, бюджетом і інтересами",
inputSchema: {
type: "object",
properties: {
age: { type: "number" },
budget: { type: "number" },
interests: {
type: "array",
items: { type: "string" }
}
},
required: ["age", "budget"]
},
// handler визначається окремо
};
У MCP Jam ви натискаєте на suggest_gifts. Праворуч відкривається форма, згенерована за inputSchema. Там ви заповнюєте:
{
"age": 30,
"budget": 100,
"interests": ["ігри", "книги"]
}
і натискаєте «Call» або аналогічну кнопку.
Інспектор надсилає MCP‑запит tools/call, і ви одразу бачите:
- сирі JSON‑дані запиту (що саме йде на сервер);
- сирі JSON‑дані відповіді (result або error);
- можливо, зручний попередній перегляд результату.
Читаємо JSON‑логи в інспекторі
Зазвичай інспектор показує щось на кшталт:
// Request
{
"id": "1",
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "suggest_gifts",
"arguments": {
"age": 30,
"budget": 100,
"interests": ["ігри", "книги"]
}
}
}
// Reply
{
"id": "1",
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "1) Настільна гра ... 2) Подарунковий сертифікат у книжковий ..."
}
]
}
}
Якщо ваш handler падає з винятком, ви побачите error у стилі JSON‑RPC:
{
"id": "1",
"jsonrpc": "2.0",
"error": {
"code": -32603,
"message": "Internal error",
"data": "TypeError: Cannot read properties of undefined ..."
}
}
Дуже важливо: саме тут ви бачите протокольний рівень. Якщо у відповіді не той формат, якого очікують Apps SDK/ChatGPT, ви зможете помітити це ще до того, як почнете нарікати на «баґи GPT».
5. Налагодження ресурсів і промптів
Інструменти — не все, що вміє MCP. Ви вже знаєте, що є ще resources і prompts.
Через інспектор ви можете:
- відкрити список ресурсів (resources/list) і подивитися їхні метадані;
- прочитати конкретний ресурс (resources/read) і переконатися, що дані коректні;
- виконати пошук по ресурсах (якщо реалізували таку можливість);
- переглянути заготовлені промпти та їхній текст.
Наприклад, якщо у вас є ресурс gift_catalog:
// псевдокод реєстрації ресурсу
registerResource({
uri: "resource://giftgenius/catalog",
name: "Каталог подарунків",
mimeType: "application/json",
handler: async () => {
return JSON.stringify(giftCatalogData);
}
});
В інспекторі ви побачите цей ресурс, натиснете на нього й зможете одразу переглянути JSON. Якщо виявиться, що JSON невалідний або MIME‑тип дивний, — ви зловите це ще до того, як ChatGPT почне спотикатися, намагаючись його прочитати або вбудувати у віджет.
6. Логи MCP‑сервера: що, де й як логувати
MCP Jam — добрий інструмент, але цього замало: вам потрібні логи самого MCP‑сервера. Без них будь‑яка промислова експлуатація перетвориться на лотерею.
Що логувати
Корисний мінімум:
- кожне вхідне MCP‑повідомлення (request/notification) з:
- часом;
- методом (tools/call, tools/list тощо);
- іменем інструмента (якщо є);
- усіченими аргументами (без чутливих даних);
- кожну вихідну відповідь із:
- статусом (успіх / помилка);
- часом виконання;
- скороченою версією результату або принаймні його типом;
- технічні помилки:
- помилки JSON‑парсингу;
- неочікувані винятки в обробниках (handlers).
Водночас дуже важливо не логувати PII та секрети повністю: токени, паролі, повні тексти конфіденційних запитів. Для промислового логування зазвичай прямо радять записувати лише дані з усіченою PII.
Куди писати логи: stdout / stderr
У MCP є важлива вимога: JSON‑повідомлення мають іти «правильним каналом», а всі відладні логи — іншим. Наприклад, якщо ви використовуєте транспорт поверх stdout/stderr, то:
- JSON‑RPC‑повідомлення повинні йти в stdout;
- усі console.log, console.error тощо потрібно спрямовувати в stderr.
Якщо ви змішаєте JSON і текстові логи в одному потоці, клієнт (MCP Jam або ChatGPT) просто не зможе розпарсити повідомлення, бо серед JSON раптово опиниться рядок на кшталт Server started at http://localhost:4001. Це одна з найпоширеніших помилок у MCP‑серверах.
В HTTP‑сценарії проблема простіша, але принцип той самий: в HTTP‑відповіді має бути чистий JSON, а всі логи — у консоль/файл, але не в тіло відповіді.
Простий логер для TypeScript MCP‑сервера
Додаймо в наш умовний MCP‑сервер невеликий логер:
// src/logger.ts
export function logRequest(method: string, details: unknown) {
console.error(
JSON.stringify({
level: "info",
type: "request",
method,
details,
ts: new Date().toISOString(),
})
);
}
export function logError(method: string, error: unknown) {
console.error(
JSON.stringify({
level: "error",
type: "error",
method,
error: String(error),
ts: new Date().toISOString(),
})
);
}
І в обробнику tools:
// src/mcp-server.ts (фрагмент)
server.setRequestHandler("tools/call", async (req) => {
logRequest("tools/call", {
name: req.params?.name,
// тут краще не класти всю payload, а лише safe-поля
});
try {
const result = await handleToolCall(req);
return result;
} catch (e) {
logError("tools/call", e);
throw e;
}
});
Так ви бачитимете в консолі структуровані JSON‑логи, які потім легко зіставляти між собою за ts або за додатковим requestId.
7. Звʼязка: MCP Jam + логи
Правильна стратегія налагодження MCP майже завжди виглядає так:
- Ви відтворюєте проблему в інспекторі: бачите, що tools/list повертає порожній список, tools/call падає, JSON‑відповідь дивна тощо.
- У той самий момент дивитеся логи MCP‑сервера: що він пише під час запуску, які помилки виводить на кожне повідомлення, чи є stack trace.
- Зіставляєте id, method, ts у логах із тим, що бачить інспектор.
Наприклад, ви бачите в інспекторі:
{
"error": {
"code": -32603,
"message": "Internal error"
}
}
І паралельно в логах:
{
"level": "error",
"type": "error",
"method": "tools/call",
"error": "TypeError: Cannot read properties of undefined (reading 'age')",
"ts": "2025-11-21T10:15:12.345Z"
}
Усе, діагноз зрозумілий: десь в обробнику ви очікуєте age, але схема/аргументи інші.
8. Мінічекліст «чи готовий MCP‑сервер до інтеграції із застосунком»
Перш ніж підʼєднувати MCP‑сервер до реального застосунку ChatGPT, зручно пройтися невеликим чеклістом через інспектор.
По‑перше, handshake і capabilities мають проходити без помилок. MCP Jam повинен показувати, що сервер підтримує потрібні вам сутності: щонайменше tools і, якщо використовується, resources / prompts.
По‑друге, список tools/resources/prompts в інспекторі має збігатися з тим набором інструментів, ресурсів і промптів, який ви вважаєте реалізованим. Будь‑які описки в name, пропущені реєстрації тощо ловляться тут миттєво.
По‑третє, виклики інструментів із валідними аргументами мають стабільно повертати коректний result. Бажано спробувати кілька типових кейсів (запити, на які ви реально розраховуєте в робочому середовищі).
По‑четверте, виклики з невалідними аргументами повинні повертати зрозумілі error-відповіді в стилі JSON‑RPC, а не падати з 500. Наприклад, якщо бракує обовʼязкового параметра, добре б повернути структуровану помилку, яку ChatGPT потім зможе перетворити на зрозуміле користувачеві повідомлення.
По‑пʼяте, логи сервера при цьому не повинні засипати консоль гігабайтами stack trace на кожен чих. Помилки мають бути структуровані, а чутливі дані — акуратно відфільтровані.
Якщо все це виконується в інспекторі, можна з набагато спокійнішою душею підʼєднувати MCP‑сервер до Apps SDK і бавитися з віджетами в Dev Mode.
9. Типові баґи MCP‑сервера і як їх ловити через інспектор
Тепер пройдімося найцікавішим — що найчастіше ламається і як це помітити.
Конфігурація і підключення
Іноді здається, що «сервер не працює», а проблема в тому, що він узагалі не слухає потрібний порт або endpoint. У такому разі інспектор чесно скаже connection refused або взагалі не зможе підʼєднатися. Поширені причини: неправильний URL (наприклад, /mcp замість /api/mcp), порт зайнятий іншим процесом, тунель не піднято або CORS блокує запити.
Невалідний JSON / змішування логів і протоколу
Одна з найболючіших історій — коли ви друкуєте console.log("Server started") у stdout, а поверх цього мають іти JSON‑RPC‑повідомлення. Клієнт очікує чистий JSON, а отримує текст + JSON, намагається розпарсити й падає з помилкою формату.
Рішення просте: суворо розділити, що йде в протокольний потік (stdout або тіло HTTP‑відповіді), а що — у логи (stderr або окремий лог‑файл).
Невідповідність схеми та реалізації інструмента
Ще одна популярна помилка: у inputSchema ви оголосили одне, а в коді очікуєте інше. Наприклад, схема каже: age — число, interests — необовʼязковий масив рядків, а код намагається робити arguments.interests.toLowerCase(). Модель (і інспектор) чесно надсилають interests як null або взагалі не надсилають поле — і тут усе падає.
Інспектор дає змогу явно побачити, який JSON насправді йде в tools/call, і зіставити це з вашим кодом.
Неправильні імена tools/resources
Якщо в capabilities / tools/list ви експортуєте tool як suggest_gifts_v2, а в маніфесті застосунку або віджеті очікуєте suggest_gifts, то «інструмент не знайдено» супроводжуватиме вас до кінця проєкту. В інспекторі — за списком tools і їхніми полями name — це видно відразу, без спроб гадати, що «думає GPT».
Повільні або зависаючі tools
Якщо виклик інструмента в інспекторі триває по 30 с, а потім падає за таймаутом, — не варто сподіватися, що ChatGPT зреагує краще. MCP‑інспектор допоможе зрозуміти, на якому саме етапі ви гальмуєте: мережевий виклик, база даних, зовнішній API. У логах добре мати час початку й завершення обробки кожного запиту, щоб одразу бачити викиди.
10. Типові помилки під час інспекції та налагодження MCP
Помилка № 1: намагатися налагоджувати MCP лише через ChatGPT.
Багато розробників спершу підʼєднують MCP до застосунку, бачать, що «щось не працює», і починають змінювати промпти, опис інструмента, інколи навіть версію моделі. При цьому MCP‑сервер узагалі не піднімається або tools/list порожній. Завжди починайте з інспектора: якщо там усе погано, модель тут ні до чого.
Помилка № 2: змішувати JSON‑RPC і логи в одному потоці.
Коли MCP‑клієнт очікує чистий JSON, а ви друкуєте в stdout відладні рядки, результат передбачуваний — парсинг ламається, Inspector показує дивні помилки. Логи мають іти окремо (stderr, файли, зовнішні системи логування), а протокольні повідомлення — суворо у своєму каналі.
Помилка № 3: не дивитися на capabilities і список tools.
Часто інструмент «зникає» просто тому, що ви забули його зареєструвати або ввімкнути відповідну capability. Якщо не дивитися на capabilities і tools/list в інспекторі, можна довго думати, що винна модель, а не ваш код реєстрації.
Помилка № 4: ігнорувати помилки схеми та невідповідність JSON.
Коли inputSchema і фактичний JSON розходяться, модель та інспектор закономірно починають поводитися дивно. Якщо ви не дивитеся на сирі JSON‑повідомлення в інспекторі й не валідовуєте схему, ці помилки вилізатимуть у найнесподіваніших місцях.
Помилка № 5: логувати все підряд, зокрема PII та токени.
У запалі налагодження легко почати друкувати в логи повний request body, включно з можливими персональними даними або секретами. У промисловій експлуатації це перетворюється на міну сповільненої дії: витоки, проблеми з комплаєнсом тощо. Логуйте лише те, що справді потрібно для діагностики, і з усіченими/анонімізованими даними.
Помилка № 6: не відтворювати проблему мінімальними кейсами.
Іноді баґ проявляється у складному діалозі через ChatGPT, і розробник намагається налагоджувати його «як є». Набагато ефективніше відтворити той самий сценарій в інспекторі одним‑двома MCP‑запитами, відсікти вплив промптів, історії діалогу і «настрою» моделі.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ