No description
  • Go 98.6%
  • Dockerfile 1.3%
Find a file
ymnuk 46c11ffdb2
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
fix: Загрузка конфигов
2026-08-14 14:09:44 +03:00
cmd/server fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00
docs fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00
internal fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00
.gitignore fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00
.woodpecker.yml fix: CI 2026-08-10 20:22:42 +03:00
config.yml.example fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00
continue.sh first commit 2026-08-10 15:49:38 +03:00
Dockerfile fix: CI 2026-08-10 21:02:58 +03:00
go.mod fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00
go.sum fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00
LICENSE first commit 2026-08-10 15:49:38 +03:00
README.md fix: Загрузка конфигов 2026-08-14 14:09:44 +03:00

mcp-http — MCP-сервер для HTTP-запросов

Модуль: git.ymnuktech.ru/ymnuk/mcp-http

MCP-сервер, выполняющий HTTP-запросы с поддержкой whitelist/blacklist фильтрации адресов, пользовательских TLS-сертификатов и гибкого логирования. Инструмент http_request доступен через протокол MCP как tools/call.

Возможности

  • Выполнение HTTP-запросов всех методов (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
  • Whitelist/Blacklist фильтрация (домены, wildcard, IP, CIDR)
  • TLS: пользовательские CA-сертификаты + опция tls_insecure_skip_verify для самоподписанных
  • Кастомные заголовки и User-Agent с приоритетом источника
  • Определение типа контента ответа (text/image/audio/binary)
  • JSONL логирование через slog (debug, info, warn, error, off)
  • Два транспорта: stdio (по умолчанию) и http (streamable over HTTP)
  • Конфигурация через CLI → ENV → YAML с автоматическим поиском путей
  • Pinned-режим: локдаун на один домен/IP (base_url) + обязательные заголовки, клиент передаёт только path

Быстрый старт

# Сборка
go build -o mcp-http ./cmd/server

# stdio + логирование
./mcp-http --log-level debug --config ./config.yaml

# HTTP-сервер
./mcp-http --transport http --http-addr :8080 --tls-insecure-skip-verify

Docker

docker run -p 8080:8080 \
  -v ./config.yml:/config.yml \
  git.ymnuktech.ru/ymnuk/mcp-http:v0.1.0 \
  --config /config.yml

Docker Compose

services:
  mcp-http:
    image: git.ymnuktech.ru/ymnuk/mcp-http:v0.1.0
    command: ["--config", "/config.yml"]
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    networks: [mcp-network]
    restart: unless-stopped
    configs:
      - source: mcp-http-v1.yml
        target: /config.yml

configs:
  mcp-http-v1.yml:
    file: ./config/mcp-http.yml

Конфигурация

Приоритет источников (от высшего к низшему)

  1. CLI флаги (--whitelist, --log-level и т.д.)
  2. ENV переменные (MCP_HTTP_USER_AGENT, MCP_HTTP_LOG_LEVEL и т.д.)
  3. Конфиг файл YAML/JSON
  4. Значения по умолчанию (в коде)

go-simple-args применяет значения последовательно — последние побеждают первые.

Поиск конфигурационного файла

Приоритет поиска (первый найденный используется):

  1. --config <path> — явный CLI флаг
  2. $MCP_HTTP_CONFIG — переменная окружения
  3. ./config.yaml / ./config.yml / ./config.json — рабочая директория
  4. ~/.config/mcp-http/config.yaml — домашняя директория пользователя
  5. /etc/mcp-http/config.yaml — системный путь

Пример конфига (config/example.yaml)

# User-Agent для всех HTTP-запросов (переопределяется CLI/ENV флагом)
user_agent: "mcp-http/1.0"

# Whitelist — разрешенные домены, IP или CIDR подсети
whitelist:
  - example.com
  - "*.internal.local"
  - 192.168.0.0/16
  - 10.0.0.1

# Blacklist — запрещённые домены, IP или CIDR подсети
blacklist:
  - evil.com
  - "172.16.0.0/12"

# Пути к пользовательским CA сертификатам (TLS)
ca_cert_files:
  - /etc/ssl/certs/my-ca.pem

# Игнорировать ошибки TLS (самоподписанные, недействительные сертификаты)
tls_insecure_skip_verify: false

# Базовые заголовки для всех запросов
headers:
  Authorization: "Bearer <token>"

# Уровень логирования: debug, info, warn, error, off
log_level: "debug"

# Путь к файлу логов (если пустой — логи в stderr/stdout)
log_file: "/var/log/mcp-http.jsonl"

# Транспорт и HTTP-сервер для http-режима
transport: "stdio"
http_server:
  enabled: true
  addr: ":8080"

CLI флаги и ENV переменные

Флаг Переменная окружения Описание По умолчанию Тип
--config, -c <path> MCP_HTTP_CONFIG Путь к YAML/JSON конфигу автопоиск (см. выше) string
--user-agent, --ua <string> MCP_HTTP_USER_AGENT User-Agent для HTTP-запросов "mcp-http/0.1.0" string
--log-level <level> MCP_HTTP_LOG_LEVEL Уровень логирования: debug/info/warn/error/off "off" enum
--log-file <path> MCP_HTTP_LOG_FILE Путь к файлу логов (JSONL) пустой (stderr/stdout) string
--transport <type> MCP_HTTP_TRANSPORT Транспорт: stdio/http "stdio" enum
--tls-insecure-skip-verify MCP_HTTP_TLS_INSECURE_SKIP_VERIFY Пропускать валидацию TLS (самоподписанные) false bool
--whitelist, -w <host> MCP_HTTP_WHITELIST Разрешённые адреса (можно повторять) пустой string[]
--blacklist, -b <host> MCP_HTTP_BLACKLIST Запрещённые адреса (можно повторять) пустой string[]
--ca-certs <path> MCP_HTTP_CA_CERTS Пути к CA-сертификатам PEM (можно повторять) пустой string[]
--header, -H <kv> MCP_HTTP_HEADERS Базовый заголовок key=value (можно повторять) пустой string[]
--http-enable MCP_HTTP_HTTP_ENABLE Включить HTTP-сервер auto по --transport bool
--http-addr <host:port> MCP_HTTP_ADDR Адрес слушания для HTTP-режима ":8080" string
--base-url <url> MCP_HTTP_BASE_URL Базовый адрес — включает pinned-режим пустой string
--alias <name> MCP_HTTP_ALIAS Имя инструмента в pinned-режиме (иначе авто-имя из хоста) пустой string
--mandatory-header, -hm <kv> MCP_HTTP_MANDATORY_HEADERS Обязательный заголовок key=value (можно повторять), клиент не может перезаписать пустой string[]
--version, -v Версия и выход flag

Пример запуска с TLS и whitelist

./mcp-http \
  --config ./config.yaml \
  --tls-insecure-skip-verify \
  --whitelist api.internal.local \
  --ca-certs /opt/certs/my-ca.pem \
  --log-level debug

Pinned-режим

Если задан base_url, сервер выполняет запросы только к этому хосту. Инструмент http_request не регистрируется — вместо него появляется единственный инструмент http_request_path, и клиент передаёт только path (домен ему не виден и не может быть изменён).

# example.yml.example (фрагмент)
base_url: "http://192.168.0.18:1880"   # включает pinned-режим
alias: "node_red"                       # имя инструмента (иначе авто-имя из хоста)
mandatory_headers:                      # нельзя перезаписать клиентом
  Authorization: "Bearer <secret>"

Имя инструмента генерируется из base_url, если alias не задан:

Вход Имя
https://192.168.0.24 192_168_0_24
http://192.168.0.18:1880 192_168_0_18_1880
http://langflow:7860 langflow_7860
http://node-red:1880 node_red_1880
не парсится pinned_request

Входные параметры http_request_path

Параметр Тип Обязательный По умолчанию Описание
path string Да Путь на базовом хосте, напр. /v1/users?limit=10 (без хоста и схемы)
method string Нет "GET" HTTP метод
headers map[string]string Нет {} Доп. заголовки (не перезаписывают обязательные)
body string Нет "" Тело запроса
timeout int Нет 30 Таймаут в секундах

Обязательные заголовки (mandatory_headers) всегда побеждают заголовки из запроса и не попадают в описание инструмента — LLM не видит секреты. Выходной формат такой же, как у http_request.

Инструмент MCP http_request

Входные параметры (CallToolRequest.params)

Параметр Тип Обязательный По умолчанию Описание
url string Да URL для HTTP-запроса
method string Нет "GET" HTTP метод: GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS
headers map[string]string Нет {} Кастомные заголовки поверх конфига (request priority)
body string Нет "" Тело запроса для POST/PUT/PATCH
timeout int Нет 30 Таймаут в секундах

Выходные параметры (structuredContent)

Поле Тип Описание
status_code int HTTP код ответа (200, 404, 500 и т.д.)
headers map[string][]string Все заголовки ответа
body string Тело ответа: для text/json — raw содержимое, для images/audio — метаданные [image/png, 256 KB]
content_type string MIME Content-Type (из Response Headers)
duration_ms float64 Длительность запроса в миллисекундах
is_image bool true если ответ — изображение

Логирование MCP-запросов (middleware)

Middleware логирует все входящие запросы через slog:

Уровень Поля Описание
INFO (всегда) method, tool, args_bytes/params Входящий MCP-запрос
DEBUG (после) duration_ms, error, result/content_size/image_size_bytes/result_type Исходящий ответ

params > 512 байт логируется только как "512+ bytes" (без содержимого). Текст ответа < 256 символов копируется полностью, остальное — в content_size: N. Images — в image_size_bytes.

Сборка и CI/CD

Локальная сборка

go build -o mcp-http ./cmd/server

# Сборка с версией (ldflags)
CGO_ENABLED=0 GOOS=linux go build \
  -ldflags="-s -w -X git.ymnuktech.ru/ymnuk/mcp-http/internal/version.Version=1.0.0" \
  -o mcp-http ./cmd/server/

./mcp-http --version
# → mcp-http 1.0.0 (commit: abc123, built: 2026-08-10T00:00:00Z)

Docker образ

Двухэтапная сборка (builder + alpine):

  • Builder: golang:1.26.5-alpine с CA-сертификатами и timezone
  • Final: alpine:3.21 — минимальный образ с CA certs, tzdata, user nobody:nogroup
  • Порт: 8080
  • Default transport: http (поэтому не нужно явно указывать в CMD)

Woodpecker CI/CD (.woodpecker.yml)

Pipeline запускается только по тегу на ветке main:

Этап Назначение Делает
build-binary amd64 бинарник Сборка go-binary с version injection через ldflags
build-docker Multi-arch образ docker-buildx → push на git.ymnuktech.ru/ymnuk/mcp-http:{tag}
release Pypi/Gitea release Загрузка бинарника в релиз

Тестирование

# Запуск всех тестов с покрытием
go test ./... -cover

# Покрытие по пакетам:
#   internal/config     81.7%
#   internal/filter     80.7%
#   internal/httpclient 75.4%
#   internal/logger      90.5%
#   internal/middleware (middleware-based)
# Итого ~81.5% покрытие по коду, 51 тест

Документация проекта

Файл Описание
Зависимости Полная документация по всем библиотекам: go-simple-args, go-yaml, go-sdk/mcp v1.7.0, godotenv
Проект Архитектура, приоритеты конфигов, API tool, логирование, транспорты, whitelist/blacklist engine
Roadmap План разработки с декомпозицией на этапы и задачи (~15-20 часов)

Зависимости

git.ymnuktech.ru/ymnuk/go-simple-args   v0.1.1  — CLI / ENV / config files (auto precedence)
github.com/goccy/go-yaml                 v1.19.2 — YAML parsing
github.com/modelcontextprotocol/go-sdk    v1.7.0 — MCP server/sdk + content types
github.com/joho/godotenv                 v1.5.1  — .env file loading