Головна / Статті / Практичні зауваження: інструменти MCP у корпоративних додатках: підходяще для початківців

Практичні зауваження: інструменти MCP у корпоративних додатках: підходяще для початківців

Покрокове керівництво з практичних нотаток: інструменти MCP у корпоративних додатках: інтерфейс, зручний для початківців; контракти, перевірки та слоти для вставки коду для команд, які використовують цю схему.

2925 слів

Наведені нижче примітки описують практичний підхід до вивчення теми «MCP Tools Inside Enterprise Applications: A Beginner-Friendly Deep Dive». Основна увага приділяється контрактам, перевіркам та місцям для вставки коду, а не мотиваційним аспектам. Під час роботи на етапі огляду спочатку запишіть контракт: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допоможе зберегти чесність пізніших змін у коді. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового виконання завдань.

1. Проблема: Чому компаніям з самого початку були потрібні MCP

1. Проблема: етап найкраще функціонує, коли його розглядають як вимірювану поверхню. Зафіксуйте один ідеальний приклад роботи, один випадок збою та примітки щодо скасування змін перед розширенням обсягу роботи. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам під час переходу від демо-версії до спільних середовищ. Використовуйте інструменти з вузькими схемами та чіткими позначеннями побічних ефектів. Хостам потрібно знати, які виклики змінюють стан, перш ніж вони автоматично схвалюють їх.

BEFORE MCP — the N x M integration problem

  ┌───────────┐        ┌─────────────┐
  │  Agent A  │───────▶│  CRM API    │  (custom connector #1)
  └───────────┘        └─────────────┘
  ┌───────────┐        ┌─────────────┐
  │  Agent A  │───────▶│  Ticketing  │  (custom connector #2)
  └───────────┘        └─────────────┘
  ┌───────────┐        ┌─────────────┐
  │  Agent B  │───────▶│  CRM API    │  (custom connector #3 -
  └───────────┘        └─────────────┘   yes, AGAIN, for a different agent)
  ┌───────────┐        ┌─────────────┐
  │  Agent B  │───────▶│  Data       │  (custom connector #4)
  └───────────┘        │  Warehouse  │
                       └─────────────┘
  N agents x M systems = N x M custom, non-reusable integrations.
  Every new agent re-implements auth, retries, schemas, error handling.
AFTER MCP — one protocol, many servers, many clients

  ┌───────────┐                          ┌───────────────────┐
  │  Agent A  │──┐                   ┌─▶│  MCP Server: CRM   │
  └───────────┘  │    ┌───────────┐  │   └───────────────────┘
                 ├───▶│    MCP   │───┤  ┌───────────────────┐
  ┌───────────┐  │    │  (shared  │  ├─▶│ MCP Server: Ticket │
  │  Agent B  │──┘    │  protocol)│  │   └───────────────────┘
  └───────────┘       └───────────┘  │  ┌──────────────────┐
                                     └─▶│ MCP Server: DW   │
                                        └──────────────────┘
  Any MCP-compatible agent can now talk to any MCP server.
  Build the connector once, reuse it everywhere.

2. Основні концепції, пояснені просто

Етап «Пояснення двох основних концепцій» найкраще функціонує, якщо його розглядати як вимірювану поверхню. Збережіть один ідеальний зразок транскрипції, один випадок невдачі та примітку про скасування змін перед розширенням обсягу роботи. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та прапорці функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Запропонуйте інструменти з вузькими схемами та чіткими позначеннями побічних ефектів. Хостам потрібно знати, які виклики змінюють стан, перш ніж вони автоматично схвалять їх.

Три примітиви, які сервер може надавати

Цей етап працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Документуйте як успішний, так і відновлювальний шляхи. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Зробіть інструменти з вузькими схемами та чіткими позначеннями побічних ефектів доступними. Хостам потрібно знати, які виклики змінюють стан, перш ніж вони автоматично схвалять їх. Цей етап працює найкраще, коли його розглядають як вимірювану поверхню. Збережіть один ідеальний запис, один випадок збою та примітку про скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення роботи.

3. Архітектура, усі три шари разом

Для всіх етапів проєкту «Архітектура» необхідно визначити вхідні дані, відповідальну особу за кожен крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Чітке відображення витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні середовища. Аутентифікуйтеся біля шлюзу та повторно авторизуйтесь на рівні обробки даних. Один лише токен-носій не є межею окремого тенантства.

┌─────────────────────────── HOST APPLICATION ───────────────────────────┐
│   e.g. an internal AI assistant, IDE plugin, support copilot           │
│                                                                        │
│   ┌───────────────┐        ┌───────────────┐       ┌───────────────┐   │
│   │  MCP Client 1 │        │  MCP Client 2 │       │  MCP Client 3 │   │
│   └───────┬───────┘        └───────┬───────┘       └───────┬───────┘   │
└───────────┼────────────────────────┼───────────────────────┼───────────┘
            │ JSON-RPC over          │ JSON-RPC over         │ JSON-RPC over
            │ stdio / HTTPS          │ stdio / HTTPS         │ stdio / HTTPS
            ▼                        ▼                       ▼
   ┌──────────────────┐     ┌──────────────────┐     ┌─────────────────┐
   │   MCP Server     │     │   MCP Server     │     │   MCP Server    │
   │  wraps HR system │     │  wraps Ticketing │     │  wraps Data     │
   │  (tools: lookup, │     │  (tools: create, │     │  Warehouse      │
   │   update)        │     │   status, close) │     │  (tools: query) │
   └──────────────────┘     └──────────────────┘     └─────────────────┘

4. Створення вашого першого сервера MCP (Node.js / TypeScript)

На етапі 4 «Створення першого проекту» необхідно визначити вхідні дані, відповідального за крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не здогадуючись про прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Аутентифікуватися потрібно біля шлюзу, а повторна авторизація — на рівні обробки даних. Один лише токен-носій не є межею окремого тенанту.

4.1 Налаштування проекту

На етапі налаштування проекту 4 1 необхідно визначити вхідні дані, відповідальну особу за кожен крок та критерії завершення перед зміною коду. Оператори мають мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Необхідно документувати як шлях успішного виконання, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Аутентифікуватися потрібно на шлюзі, а повторна авторизація — на рівні обробки даних. Один лише токен-носій не є межею окремого тенантства.

mkdir helpdesk-mcp-server && cd helpdesk-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/node
npx tsc --init

На етапі налаштування проекту 4 1 необхідно визначити вхідні дані, відповідальну особу за кожен крок та критерії завершення перед зміною коду. Оператори мають мати можливість знову виконати крок з відомої точки контролю, не намагаючись вгадати прихований стан. Цей етап слід розглядати як контракт між вхідними даними та перевіреними результатами. Потрібно назвати всі елементи, визначити критерії успіху та не допускати мовчазного часткового завершення роботи.

4.2 Код сервера

Під час роботи над етапом 4.2 «Сервер» спочатку запишіть умови використання: необхідні параметри вхідних даних, сигнал про успішну обробку та наслідки часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Записуйте час виконання та витрати на токени або запити поруч із результатами функціональності. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам під час переходу від демо-середовища до спільних. Фіксуйте назву інструменту, хеш аргументів, час відгуку та результат кожного виклику. Без цих записів дебагування може займати години.

// src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// --- A stand-in for a real internal ticketing API client ---
// In a real enterprise server this would call your ITSM system
// (ServiceNow, Jira Service Management, Zendesk, an internal API, etc.)
const ticketStore = new Map<string, { status: string; subject: string }>();
let nextId = 1000;
// 1. Create the server instance.
//    "name" and "version" identify this server to any client that connects.
const server = new McpServer({
  name: "helpdesk-mcp-server",
  version: "1.0.0",
});
// 2. Register a tool: create_support_ticket
server.registerTool(
  "create_support_ticket",
  {
    title: "Create Support Ticket",
    description:
      "Creates a new IT helpdesk ticket for the requesting employee.",
    inputSchema: {
      subject: z.string().describe("Short summary of the issue"),
      priority: z.enum(["low", "medium", "high", "urgent"]),
      employeeId: z.string().describe("Requesting employee's ID"),
    },
    outputSchema: {
      ticketId: z.string(),
      status: z.string(),
    },
  },
  async ({ subject, priority, employeeId }) => {
    const ticketId = `TCK-${nextId++}`;
    ticketStore.set(ticketId, { status: "open", subject });
    const output = { ticketId, status: "open" };
    // MCP tool results return a "content" array (what a human/LLM reads)
    // and, optionally, "structuredContent" (typed data other code can use).
    return {
      content: [
        {
          type: "text",
          text: `Created ticket ${ticketId} (priority: ${priority}) for employee ${employeeId}.`,
        },
      ],
      structuredContent: output,
    };
  }
);
// 3. Register a second tool: get_ticket_status
server.registerTool(
  "get_ticket_status",
  {
    title: "Get Ticket Status",
    description: "Looks up the current status of an existing support ticket.",
    inputSchema: {
      ticketId: z.string(),
    },
    outputSchema: {
      status: z.string(),
    },
  },
  async ({ ticketId }) => {
    const ticket = ticketStore.get(ticketId);
    if (!ticket) {
      // Returning isError lets the model know the call failed
      // WITHOUT crashing the whole conversation.
      return {
        content: [{ type: "text", text: `No ticket found with ID ${ticketId}.` }],
        isError: true,
      };
    }
    return {
      content: [{ type: "text", text: `Ticket ${ticketId} is currently "${ticket.status}".` }],
      structuredContent: { status: ticket.status },
    };
  }
);
// 4. Wire the server to a transport and start listening.
//    stdio is perfect for local development and desktop-hosted tools.
const transport = new StdioServerTransport();
await server.connect(transport);

4.3 Що насправді відбувається тут (теорія рядок за рядком)

Під час роботи над етапом 4 3 What s спочатку запишіть умови контракту: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища секретних даних та флаги функцій мають знаходитися в одному місці, де оператори можуть їх перевіряти, не читаючи весь код. Фіксуйте назву інструменту, хеш аргументів, час відгуку та результат кожного виклику. Без цих записів дебагування займає години.

4.4 Запуск

Під час роботи над етапом «4 4 Running it» спочатку запишіть умови виконання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Одночасно задокументуйте шлях успішного виконання та шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Фіксуйте назву інструменту, хеш аргументів, час виконання та результат кожного виклику. Без цих записів дебагування займає години.

npx tsx src/server.ts

Під час роботи над етапом «4 4 Running it» спочатку запишіть умови виконання: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Цей перелік допомагає зберігати чесність у подальших змінах коду. Розглядайте цей етап як угоду між вхідними даними та перевіреними результатами. Назвіть всі елементи, визначте критерії успіху та не допускайте мовчазного часткового завершення роботи.

5. Створення клієнта MCP у межах корпоративного додатку

Етап 5 «Створення MCP» найкраще функціонує, якщо його розглядати як вимірювану характеристику. Збережіть один ідеальний зразок роботи, один випадок збою та примітки щодо скасування змін перед розширенням обсягу роботи. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Візуалізація витрат на ранньому етапі запобігає несподіваним рахункам під час переходу від демо-версії до спільних середовищ. Робіть інструменти доступними з вузькими схемами та чіткими позначеннями побічних ефектів. Хостам потрібно знати, які виклики змінюють стан, перш ніж вони автоматично схвалюють їх.

// src/client.ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

async function main() {
  // 1. Describe how to launch the server. Here we spawn it as a
  //    local subprocess - in production you'd more commonly point
  //    this at a remote HTTP-based server instead (see Section 6).
  const transport = new StdioClientTransport({
    command: "npx",
    args: ["tsx", "src/server.ts"],
  });
  // 2. Create a client and connect. This performs the MCP
  //    handshake and capability negotiation automatically.
  const client = new Client({ name: "internal-ai-assistant", version: "1.0.0" });
  await client.connect(transport);
  // 3. Discover what tools this server offers - this is the same
  //    mechanism an LLM uses to "learn" what it can do.
  const { tools } = await client.listTools();
  console.log("Available tools:", tools.map((t) => t.name));
  // 4. Call a tool, just like the LLM would.
  const result = await client.callTool({
    name: "create_support_ticket",
    arguments: {
      subject: "VPN keeps disconnecting",
      priority: "high",
      employeeId: "E-4821",
    },
  });
  console.log(result.content);
  await client.close();
}
main();

Чому це має концептуальне значення

Концепція «Чому це має значення» найкраще функціонує, якщо її розглядати як вимірювану поверхню. Зафіксуйте один ідеальний приклад роботи, один випадок збою та примітки щодо скасування змін перед розширенням обсягу роботи. Тримайте конфігурацію окремо від коду додатку. Файли середовища, сховища конфіденційних даних та прапорці функцій мають знаходитися в одному місці, щоб оператори могли їх перевіряти, не читаючи весь код. Запропонуйте інструменти з вузькими схемами та чіткими позначеннями побічних ефектів. Хостам потрібно знати, які виклики змінюють стан, перш ніж вони автоматично схвалять їх.

6. Від локального прототипу до корпоративного розгортання

Етап „6 From Local Prototype“ найкраще функціонує, якщо його розглядати як вимірювану поверхню. Зафіксуйте один ідеальний запис, один випадок збою та примітку щодо скасування змін перед розширенням обсягу роботи. Документуйте як успішний, так і відновлювальний сценарії роботи разом. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої доробки. Зробіть інструменти з вузькими схемами та чіткими позначеннями побічних ефектів доступними. Хостам потрібно знати, які виклики змінюють стан, перш ніж вони автоматично схвалять їх. Етап „6 From Local Prototype“ найкраще функціонує, якщо його розглядати як вимірювану поверхню. Зафіксуйте один ідеальний запис, один випадок збою та примітку щодо скасування змін перед розширенням обсягу роботи. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.

// src/httpServer.ts
import express from "express";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";

const app = express();
app.use(express.json());
app.post("/mcp", async (req, res) => {
  // In a real enterprise deployment, authentication middleware would
  // run BEFORE this point - verifying a bearer token, checking scopes,
  // and attaching the caller's identity to the request.
  const server = buildHelpdeskServer(); // same registerTool calls as before
  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined, // stateless mode: simplest to scale horizontally
  });
  res.on("close", () => transport.close());
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});
app.listen(3000, () => console.log("MCP server listening on :3000"));

7. Чек-лист критеріїв рівня корпоративних продуктів

На етапі 7 «Чек-лист критеріїв рівня Enterprise» необхідно визначити вхідні дані, відповідальну особу за крок та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись визначити прихований стан. Записуйте час виконання та витрати на токени чи запити поруч із функціональними результатами. Чітке бачення витрат заздалегідь запобігає несподіваним рахункам під час переходу з демо-середовища у спільні. Аутентифікуйтеся біля шлюзу та повторно авторизуйтесь на рівні обробки даних. Один лише токен-носій не є межею окремого тенанту.

8. Де це використовується у реальних корпоративних сценаріях

Для етапу 8 «Where This Shows» необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Конфігурацію слід тримати окремо від коду додатку. Файли середовища, сховища конфіденційних даних та флаги функціоналу мають знаходитися в одному місці, яке оператори можуть перевіряти, не читаючи весь архітектурний план. Аутентифікуватися потрібно на шлюзі, а повторна авторизація — на рівні обробки даних. Один лише токен-носій не є межею окремого тенантства.

9. Поширені проблеми, з якими стикаються початківці

На етапі «9 поширених помилок для початківців» необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Необхідно документувати як шлях успішного виконання, так і шлях відновлення. Повторні спроби, людський контроль та обробка некоректних повідомлень є частиною продукту, а не етапом подальшої оптимізації. Аутентифікуйтеся біля шлюзу та знову авторизуйтесь на рівні обробки даних. Один лише токен-носій не є межею окремого тенанту. На етапі «9 поширених помилок для початківців» необхідно визначити вхідні дані, власника кроку та критерії завершення перед зміною коду. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не намагаючись вгадати прихований стан. Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте безповідомного часткового завершення роботи.

10. Підсумки

Під час виконання етапу «10. Підсумки» спочатку запишіть умови контракту: необхідні вхідні дані, сигнал про успіх та те, що відбувається у разі часткової невдачі. Такий перелік допомагає зберігати чесність пізніших змін у коді. Запишіть час виконання та витрати на токени або запити поруч із результатами функціональності. Відображення витрат заздалегідь запобігає несподіваним рахункам, коли процес переходить від демо-середовища до спільних. Записуйте назву інструменту, хеш аргументів, затримку та результат кожного виклику. Без цих записів дебагування може займати години.

Чек-лист для експлуатації

На етапі чек-листу для експлуатації перед зміною коду необхідно визначити вхідні дані, відповідальну особу за крок та критерії завершення. Оператори повинні мати можливість перезапустити крок з відомої точки контролю, не здогадуючись про прихований стан.

Віддавайте перевагу малим, тестованим одиницям перед величезними скриптами. Коли якийсь крок зазнає невдачі, причина має вказувати на конкретну відповідальність, а не на заплутану послідовність операцій.

Аутентифікуйтеся біля шлюзу та повторно авторизуйтесь на рівні обробки даних. Один лише токен-носій не є межею окремого тенанту.

Напишіть короткий посібник: як оновлювати ключі, як спорожнювати чергу, як скасовувати останнє завантаження даних.

Розглядайте цей етап як контракт між вхідними даними та перевіреними результатами. Позначте всі елементи, визначте критерії успіху та не допускайте мовчазного часткового виконання завдань.

Аутентифікуйтеся біля шлюзу та повторно авторизуйтесь на рівні обробки даних. Один лише токен-носій не є межею окремого тенанту.

Перш ніж запускати стек у продакшн, заморозьте версії, створіть «золотий» запис для критичного шляху та підтвердьте кроки відкату. У спільних середовищах необхідні обмеження на частоту запитів, перевірки прав власності та чіткий власник для зміни секретів. Віддавайте перевагу надійності перед креативними одноразовими демонстраціями.

Примітка до версії 100916d5ed60: не зберігайте ключі постачальника у репозиторії, встановіть ліміт токенів на сеанс та зберігайте записи поруч із фікстурами для оцінки, щоб подальша заміна моделей залишалася порівнянною.