# Започване с MCP
Добре дошли в първите си стъпки с Model Context Protocol (MCP)! Независимо дали сте нови в MCP или искате да задълбочите разбирането си, това ръководство ще ви преведе през основния процес на настройка и разработка. Ще откриете как MCP позволява безпроблемна интеграция между AI модели и приложения, и ще научите как бързо да подготвите средата си за създаване и тестване на решения с MCP.
> TLDR; Ако създавате AI приложения, знаете, че можете да добавяте инструменти и други ресурси към вашия LLM (голям езиков модел), за да направите LLM по-знаещ. Но ако поставите тези инструменти и ресурси на сървър, възможностите на приложението и на сървъра могат да се използват от всеки клиент с/без LLM.
## Обзор
Този урок предоставя практическо ръководство за настройка на MCP среди и създаване на първите ви MCP приложения. Ще научите как да настроите необходимите инструменти и рамки, да създадете базови MCP сървъри, да създадете хост приложения и да тествате вашите реализации.
Model Context Protocol (MCP) е отворен протокол, който стандартизира начина, по който приложенията предоставят контекст на LLM. Мислете за MCP като за USB-C порт за AI приложения - той предлага стандартизиран начин за свързване на AI модели с различни източници на данни и инструменти.
## Учебни цели
Към края на този урок ще можете да:
- Настроите среди за разработка на MCP с C#, Java, Python, TypeScript и Rust
- Създадете и внедрите базови MCP сървъри с персонализирани функции (ресурси, подсказки и инструменти)
- Създадете хост приложения, които се свързват с MCP сървъри
- Тествате и отстранявате грешки при реализации на MCP
## Настройка на вашата MCP среда
Преди да започнете работа с MCP, е важно да подготвите средата си за разработка и да разберете основния работен процес. Този раздел ще ви преведе през първоначалните стъпки, за да ви осигури гладък старт с MCP.
### Изисквания
Преди да се потопите в разработката на MCP, уверете се, че имате:
- **Среда за разработка**: За избрания от вас език (C#, Java, Python, TypeScript или Rust)
- **IDE/редактор**: Visual Studio, Visual Studio Code, IntelliJ, Eclipse, PyCharm или някой модерен редактор за код
- **Мениджъри на пакети**: NuGet, Maven/Gradle, pip, npm/yarn или Cargo
- **API ключове**: За всички AI услуги, които планирате да използвате в хост приложенията си
## Основна структура на MCP сървър
MCP сървърът обикновено включва:
- **Конфигурация на сървъра**: Настройка на порт, удостоверяване и други настройки
- **Ресурси**: Данни и контекст, достъпни за LLM
- **Инструменти**: Функционалности, които моделите могат да извикват
- **Подсказки**: Шаблони за генериране или структуриране на текст
Ето един опростен пример на TypeScript:
```typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Създаване на MCP сървър
const server = new McpServer({
name: "Demo",
version: "1.0.0"
});
// Добавяне на инструмент за събиране
server.tool("add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
// Добавяне на динамичен ресурс за поздрав
server.resource(
"file",
// Параметърът 'list' контролира как ресурсът изброява наличните файлове. Задаването му на undefined деактивира изброяването за този ресурс.
new ResourceTemplate("file://{path}", { list: undefined }),
async (uri, { path }) => ({
contents: [{
uri: uri.href,
text: `File, ${path}!`
}]
})
);
// Добавяне на файлов ресурс, който чете съдържанието на файла
server.resource(
"file",
new ResourceTemplate("file://{path}", { list: undefined }),
async (uri, { path }) => {
let text;
try {
text = await fs.readFile(path, "utf8");
} catch (err) {
text = `Error reading file: ${err.message}`;
}
return {
contents: [{
uri: uri.href,
text
}]
};
}
);
server.prompt(
"review-code",
{ code: z.string() },
({ code }) => ({
messages: [{
role: "user",
content: {
type: "text",
text: `Please review this code:\n\n${code}`
}
}]
})
);
// Започнете да получавате съобщения на stdin и да изпращате съобщения на stdout
const transport = new StdioServerTransport();
await server.connect(transport);
```
В горния код ние:
- Импортираме необходимите класове от MCP TypeScript SDK.
- Създаваме и конфигурираме нов MCP сървър.
- Регистрираме персонализиран инструмент (`calculator`) с функция за обработка.
- Стартираме сървъра, за да слуша входящи MCP заявки.
## Тестване и отстраняване на грешки
Преди да започнете да тествате вашия MCP сървър, е важно да разберете наличните инструменти и добрите практики за отстраняване на грешки. Ефективното тестване гарантира, че вашият сървър работи както се очаква, и ви помага бързо да идентифицирате и разрешите проблеми. Следващият раздел описва препоръчителни подходи за валидиране на вашата MCP реализация.
MCP предоставя инструменти, които помагат при тестването и отстраняването на грешки на вашите сървъри:
- **Inspector tool**, този графичен интерфейс ви позволява да се свържете със сървъра и да тествате вашите инструменти, подсказки и ресурси.
- **curl**, можете също да се свържете със сървъра си чрез команден инструмент като curl или други клиенти, които могат да изготвят и изпращат HTTP команди.
### Използване на MCP Inspector
[MCP Inspector](https://github.com/modelcontextprotocol/inspector) е визуален инструмент за тестване, който ви помага да:
1. **Откриете възможностите на сървъра**: Автоматично откриване на налични ресурси, инструменти и подсказки
2. **Тествате изпълнението на инструменти**: Пробвайте различни параметри и вижте отговорите в реално време
3. **Прегледате метаданните на сървъра**: Изследвайте информацията за сървъра, схеми и конфигурации
```bash
# Пример TypeScript, инсталиране и стартиране на MCP Inspector
npx @modelcontextprotocol/inspector node build/index.js
```
Когато изпълните горните команди, MCP Inspector ще стартира локален уеб интерфейс в браузъра ви. Можете да очаквате табло за управление, показващо регистрираните MCP сървъри, наличните им инструменти, ресурси и подсказки. Интерфейсът ви позволява интерактивно да тествате изпълнението на инструменти, да преглеждате метаданни на сървъра и да виждате отговори в реално време, което улеснява валидирането и отстраняването на грешки при MCP реализации.
Ето екранна снимка на как може да изглежда:

## Често срещани проблеми при настройка и решения
| Проблем | Възможно решение |
|---------|------------------|
| Връзката отказана | Проверете дали сървърът работи и дали портът е правилен |
| Грешки при изпълнение на инструмент | Прегледайте валидацията на параметрите и обработката на грешки |
| Проблеми с удостоверяване | Проверете API ключовете и разрешенията |
| Грешки при валидация на схема | Уверете се, че параметрите съответстват на дефинираната схема |
| Сървърът не стартира | Проверете за конфликти на портове или липсващи зависимости |
| Грешки CORS | Настройте правилните CORS заглавки за заявки от други източници |
| Проблеми с удостоверяване | Проверете валидността на токена и разрешенията |
## Локална разработка
За локална разработка и тестване можете да стартирате MCP сървъри директно на вашия компютър:
1. **Стартирайте процеса на сървъра**: Стартирайте вашето MCP сървър приложение
2. **Конфигурирайте мрежата**: Уверете се, че сървърът е достъпен на очаквания порт
3. **Свържете клиенти**: Използвайте локални URL адреси като `http://localhost:3000`
```bash
# Пример: Стартиране на TypeScript MCP сървър локално
npm run start
# Сървърът работи на http://localhost:3000
```
## Създаване на първия ви MCP сървър
В предишен урок разгледахме [Основни концепции](../../01-CoreConcepts/README.md), сега е време да приложим тези знания на практика.
### Какво може да прави един сървър
Преди да започнем да пишем код, нека си припомним какво може да прави един сървър:
MCP сървърът може например да:
- Дава достъп до локални файлове и бази данни
- Свързва се с отдалечени API-та
- Извършва изчисления
- Интегрира се с други инструменти и услуги
- Предлага потребителски интерфейс за взаимодействие
Отлично, сега когато знаем какво може, нека започваме да пишем код.
## Упражнение: Създаване на сървър
За да създадете сървър, трябва да следвате следните стъпки:
- Инсталирайте MCP SDK.
- Създайте проект и настройте структурата на проекта.
- Напишете кода на сървъра.
- Тествайте сървъра.
### -1- Създаване на проект
#### TypeScript
```sh
# Създайте проектна директория и инициализирайте npm проект
mkdir calculator-server
cd calculator-server
npm init -y
```
#### Python
```sh
# Създайте директория за проекта
mkdir calculator-server
cd calculator-server
# Отворете папката във Visual Studio Code - Пропуснете това, ако използвате друг IDE
code .
```
#### .NET
```sh
dotnet new console -n McpCalculatorServer
cd McpCalculatorServer
```
#### Java
За Java създайте Spring Boot проект:
```bash
curl https://start.spring.io/starter.zip \
-d dependencies=web \
-d javaVersion=21 \
-d type=maven-project \
-d groupId=com.example \
-d artifactId=calculator-server \
-d name=McpServer \
-d packageName=com.microsoft.mcp.sample.server \
-o calculator-server.zip
```
Разархивирайте zip файла:
```bash
unzip calculator-server.zip -d calculator-server
cd calculator-server
# по желание премахнете неизползвания тест
rm -rf src/test/java
```
Добавете следната пълна конфигурация във вашия *pom.xml* файл:
```xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
3.5.0
com.example
calculator-server
0.0.1-SNAPSHOT
Calculator Server
Basic calculator MCP service for beginners
21
21
21
org.springframework.ai
spring-ai-bom
1.0.0-SNAPSHOT
pom
import
org.springframework.ai
spring-ai-starter-mcp-server-webflux
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
org.apache.maven.plugins
maven-compiler-plugin
21
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
false
```
#### Rust
```sh
mkdir calculator-server
cd calculator-server
cargo init
```
### -2- Добавяне на зависимости
След като имате създаден проект, нека добавим зависимостите:
#### TypeScript
```sh
# Ако не е инсталиран, инсталирайте TypeScript глобално
npm install typescript -g
# Инсталирайте MCP SDK и Zod за валидиране на схеми
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript
```
#### Python
```sh
# Създайте виртуална среда и инсталирайте зависимости
python -m venv venv
venv\Scripts\activate
pip install "mcp[cli]"
```
#### Java
```bash
cd calculator-server
./mvnw clean install -DskipTests
```
#### Rust
```sh
cargo add rmcp --features server,transport-io
cargo add serde
cargo add tokio --features rt-multi-thread
```
### -3- Създаване на файлове на проекта
#### TypeScript
Отворете файла *package.json* и заменете съдържанието му със следното, за да осигурите възможност за билд и стартиране на сървъра:
```json
{
"name": "calculator-server",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"build": "tsc",
"start": "npm run build && node ./build/index.js",
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "A simple calculator server using Model Context Protocol",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.16.0",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/node": "^24.0.14",
"typescript": "^5.8.3"
}
}
```
Създайте файл *tsconfig.json* със следното съдържание:
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
```
Създайте директория за изходния код:
```sh
mkdir src
touch src/index.ts
```
#### Python
Създайте файл *server.py*
```sh
touch server.py
```
#### .NET
Инсталирайте нужните NuGet пакети:
```sh
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting
```
#### Java
При Java Spring Boot проекти структурата на проекта се създава автоматично.
#### Rust
При Rust по подразбиране се създава файл *src/main.rs* при стартиране на `cargo init`. Отворете файла и изтрийте кода по подразбиране.
### -4- Създаване на код на сървъра
#### TypeScript
Създайте файл *index.ts* и добавете следния код:
```typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Създайте MCP сървър
const server = new McpServer({
name: "Calculator MCP Server",
version: "1.0.0"
});
```
Сега имате сървър, но той не прави много, нека оправим това.
#### Python
```python
# server.py
from mcp.server.fastmcp import FastMCP
# Създайте MCP сървър
mcp = FastMCP("Demo")
```
#### .NET
```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
// Configure all logs to go to stderr
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
// add features
```
#### Java
За Java създайте основните компоненти на сървъра. Първо модифицирайте основния клас на приложението:
*src/main/java/com/microsoft/mcp/sample/server/McpServerApplication.java*:
```java
package com.microsoft.mcp.sample.server;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.microsoft.mcp.sample.server.service.CalculatorService;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider calculatorTools(CalculatorService calculator) {
return MethodToolCallbackProvider.builder().toolObjects(calculator).build();
}
}
```
Създайте услугата калкулатор *src/main/java/com/microsoft/mcp/sample/server/service/CalculatorService.java*:
```java
package com.microsoft.mcp.sample.server.service;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
/**
* Service for basic calculator operations.
* This service provides simple calculator functionality through MCP.
*/
@Service
public class CalculatorService {
/**
* Add two numbers
* @param a The first number
* @param b The second number
* @return The sum of the two numbers
*/
@Tool(description = "Add two numbers together")
public String add(double a, double b) {
double result = a + b;
return formatResult(a, "+", b, result);
}
/**
* Subtract one number from another
* @param a The number to subtract from
* @param b The number to subtract
* @return The result of the subtraction
*/
@Tool(description = "Subtract the second number from the first number")
public String subtract(double a, double b) {
double result = a - b;
return formatResult(a, "-", b, result);
}
/**
* Multiply two numbers
* @param a The first number
* @param b The second number
* @return The product of the two numbers
*/
@Tool(description = "Multiply two numbers together")
public String multiply(double a, double b) {
double result = a * b;
return formatResult(a, "*", b, result);
}
/**
* Divide one number by another
* @param a The numerator
* @param b The denominator
* @return The result of the division
*/
@Tool(description = "Divide the first number by the second number")
public String divide(double a, double b) {
if (b == 0) {
return "Error: Cannot divide by zero";
}
double result = a / b;
return formatResult(a, "/", b, result);
}
/**
* Calculate the power of a number
* @param base The base number
* @param exponent The exponent
* @return The result of raising the base to the exponent
*/
@Tool(description = "Calculate the power of a number (base raised to an exponent)")
public String power(double base, double exponent) {
double result = Math.pow(base, exponent);
return formatResult(base, "^", exponent, result);
}
/**
* Calculate the square root of a number
* @param number The number to find the square root of
* @return The square root of the number
*/
@Tool(description = "Calculate the square root of a number")
public String squareRoot(double number) {
if (number < 0) {
return "Error: Cannot calculate square root of a negative number";
}
double result = Math.sqrt(number);
return String.format("√%.2f = %.2f", number, result);
}
/**
* Calculate the modulus (remainder) of division
* @param a The dividend
* @param b The divisor
* @return The remainder of the division
*/
@Tool(description = "Calculate the remainder when one number is divided by another")
public String modulus(double a, double b) {
if (b == 0) {
return "Error: Cannot divide by zero";
}
double result = a % b;
return formatResult(a, "%", b, result);
}
/**
* Calculate the absolute value of a number
* @param number The number to find the absolute value of
* @return The absolute value of the number
*/
@Tool(description = "Calculate the absolute value of a number")
public String absolute(double number) {
double result = Math.abs(number);
return String.format("|%.2f| = %.2f", number, result);
}
/**
* Get help about available calculator operations
* @return Information about available operations
*/
@Tool(description = "Get help about available calculator operations")
public String help() {
return "Basic Calculator MCP Service\n\n" +
"Available operations:\n" +
"1. add(a, b) - Adds two numbers\n" +
"2. subtract(a, b) - Subtracts the second number from the first\n" +
"3. multiply(a, b) - Multiplies two numbers\n" +
"4. divide(a, b) - Divides the first number by the second\n" +
"5. power(base, exponent) - Raises a number to a power\n" +
"6. squareRoot(number) - Calculates the square root\n" +
"7. modulus(a, b) - Calculates the remainder of division\n" +
"8. absolute(number) - Calculates the absolute value\n\n" +
"Example usage: add(5, 3) will return 5 + 3 = 8";
}
/**
* Format the result of a calculation
*/
private String formatResult(double a, String operator, double b, double result) {
return String.format("%.2f %s %.2f = %.2f", a, operator, b, result);
}
}
```
**Допълнителни компоненти за продукционно готова услуга:**
Създайте конфигурация за стартиране *src/main/java/com/microsoft/mcp/sample/server/config/StartupConfig.java*:
```java
package com.microsoft.mcp.sample.server.config;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class StartupConfig {
@Bean
public CommandLineRunner startupInfo() {
return args -> {
System.out.println("\n" + "=".repeat(60));
System.out.println("Calculator MCP Server is starting...");
System.out.println("SSE endpoint: http://localhost:8080/sse");
System.out.println("Health check: http://localhost:8080/actuator/health");
System.out.println("=".repeat(60) + "\n");
};
}
}
```
Създайте контролер за здравето *src/main/java/com/microsoft/mcp/sample/server/controller/HealthController.java*:
```java
package com.microsoft.mcp.sample.server.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
public class HealthController {
@GetMapping("/health")
public ResponseEntity