Skip to main content
Glama
KirillKulakow

MAS GitHub Pull Request Review

Фінальний проєкт: MAS рев'ю GitHub Pull Request

Мультиагентна система (LangGraph) + MCP-сервер для автоматичного рев'ю GitHub PR. Домен той самий, що в ДЗ1/ДЗ2: метадані PR, змінені файли, евристики ризику в patch, політики команди.

У SDK mcp 2.x клас FastMCP перейменовано на MCPServer (from mcp.server.mcpserver import MCPServer). Це той самий високорівневий сервер з методички.

Архітектура MAS

START → rate_limit_gate → input_gate → supervisor ─┬─ plan_reviewer → output_gate → END
                                                    ├─ rag_agent     → output_gate → END
                                                    └─ mcp_agent     → output_gate → END

Якщо rate-limit або input guardrail блокує запит, граф іде одразу в output_gate (без LLM). Supervisor робить structured routing (plan_reviewer | rag_agent | mcp_agent) і йде далі conditional edges. Кожен спеціаліст має свій system prompt і свій набір tools. HITL для post_pr_review живе в окремому hitl.py, не в цьому графі.

Агент

Роль

Tools

supervisor

маршрутизація

немає

plan_reviewer

повне рев'ю PR

локальні Pydantic tools з tools_legacy.py у циклі planner → executor → replanner

rag_agent

політики команди

search_knowledgechroma_db/

mcp_agent

live GitHub через MCP

get_pr_info, list_pr_files, analyze_patch, get_pr_comments, search_review_policy (+ post_pr_review у allowlist; виклик лише через HITL)

Persistence: AsyncSqliteSaver пише стан у agent_state.db. Демо «крах → resume» зупиняє граф після supervisor (interrupt_after) і відновлює той самий thread_id у новому процесі.

Траєкторія всього MAS — trajectory.json. Кожен крок має agent_name (розширення логера з ДЗ1).

Related MCP server: MCP Code Review Server

MCP-сервер

Файл mcp_server.py. Запуск: python mcp_server.py (transport stdio).

Tools (6) — обгортки payload-функцій з tools_legacy.py, з валідацією Pydantic і try/except (клієнт отримує JSON error, не traceback):

  1. get_pr_info — метадані PR

  2. list_pr_files — змінені файли

  3. analyze_patch — секрети / eval / TODO / великий diff

  4. get_pr_comments — issue-коментарі

  5. search_review_policy — семантичний пошук політик (ChromaDB)

  6. post_pr_review — ризиковий write: симуляція POST → рядок у posted_reviews.jsonl (реальний GitHub не викликається)

Resources (read-only):

  • review://verdicts — критерії approve / request_changes / comment

  • review://checklist — чекліст секретів, тестів, .env

Prompt: review_pr(owner, repo, pr_number) — шаблон бріфу для агента.

Підключення до LangGraph: MultiServerMCPClient у mcp_client.py (stdio → mcp_server.py). Пакет langchain-mcp-adapters 0.3.x не імпортується з mcp 2.x (немає FastMCP / RequestContext); клієнт повторює той самий API get_tools().

Запуск

cd final_hw_project
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# у .env: OPENAI_API_KEY=...  (опційно GITHUB_TOKEN=, LANGFUSE_*)

Перевірка залежностей:

python main.py

Unit tests MCP (≥8, async list_tools / call_tool / resources / prompts):

pytest test_mcp_server.py -v

Демо MAS (4 запити різного типу → консоль + trajectory.json):

python mas_langgraph.py demo

Той самий кейс у AutoGen (SelectorGroupChat, 4 агенти):

python mas_autogen.py demo   # → autogen_demo.json
python compare_mas.py        # LOC + токени з демо

Persistence (два процеси, один thread_id):

python mas_langgraph.py crash --thread demo-1
python mas_langgraph.py resume --thread demo-1

Self-tests guardrails і HITL для ризикового MCP-tool:

python guardrails.py
python hitl.py approve
python hitl.py reject
python hitl.py edit

Scenario evals і red-teaming:

python evals.py          # → eval_results.json (потрібен OPENAI_API_KEY)
python red_team.py       # → red_team_results.json

MCP Inspector (опційно; потрібен Node ≥ 22, у nvm уже є v24.13.0; default зараз v18 і впаде з styleText):

nvm use 24
npx @modelcontextprotocol/inspector .venv/bin/python mcp_server.py

Аналіз результатів демо

Джерело: trajectory.json після python mas_langgraph.py demo. PR для live-даних: octocat/Hello-World#1.

Запит

Агент

Tools

Що видно

Повне рев'ю PR #1

plan_reviewer

get_pr_info (підграф Plan-and-Execute)

Supervisor правильно делегував. Planner склав 5 кроків; після get_pr_info replanner зробив finish, бо PR closed.

Коли request_changes через секрети?

rag_agent

search_knowledge

Відповідь з KB: секрети → request_changes, видалити з історії комітів, .gitignore.

Які файли в PR #1?

mcp_agent

MCP get_pr_info

Live GitHub через stdio MCP; 1 змінений файл.

Метадані PR #1

mcp_agent

MCP get_pr_info

title Edited README via GitHub, author, state=closed.

Crash/resume (thread_id=demo-1): після crash next_nodes=['plan_reviewer'], resolved=False. Новий процес resume дочитав SqliteSaver і завершив plan_reviewer (resolved=True, next_nodes=[]).

Де працює добре. Маршрутизація supervisor стабільна (structured output). RAG цитує політики, а не вигадує. MCP-tools реально ходять у GitHub. Checkpointer переживає рестарт процесу.

Обмеження. Для закритого octocat PR #1 Plan-and-Execute часто зупиняється після першого крока (finish). На відкритому PR цикл executor↔replanner довший. mcp_agent інколи бере get_pr_info замість list_pr_files для запиту про файли (поле changed_files уже є в метаданих).

Guardrails (4 шари)

Модуль guardrails.py. Хуки в mas_langgraph.py (rate_limit_gateinput_gate → … → output_gate) і в plan_subgraph.executor_node (allowlist перед ToolNode).

Шар

Що блокує / маскує

Де

Input

injection EN (ignore previous instructions, reveal the prompt, DAN, system prompt:) + UK (ігноруй попередні інструкції, забудь свої інструкції, покажи системний промпт, розкрий промпт, режим розробника); heuristics (role: system ×2, щільність спецсимволів); len > 5000

input_gate перед supervisor

Output

PII: email, phone +380…, card, IBAN UA (UA + 27 цифр), ІПН (10 цифр), паспорт [А-ЯA-Z]{2}\d{6}

output_gate перед END

Tool allowlist

заборонений tool → ToolMessage error, без MCP/GitHub

_tool_agent_node і executor_node

Rate-limit

rolling window 8 запитів / 60 с на session_id (= thread_id)

rate_limit_gate на вході MAS

Allowlist:

Агент

Дозволені tools

supervisor

plan_reviewer

get_pr_info, list_pr_files, analyze_patch, get_pr_comments, search_knowledge

rag_agent

search_knowledge

mcp_agent

get_pr_info, list_pr_files, analyze_patch, get_pr_comments, search_review_policy, post_pr_review

RISKY_TOOLS = {post_pr_review}. Supervisor tools не біндить; навіть якби LLM спробував post_pr_review, executor заблокує.

Перевірка: python guardrails.py (усі asserts input / output / tool / rate-limit).

HITL (hitl.py)

Окремий граф: propose → approval_gate (interrupt) → execute | reject. Resume: Command(resume={"action": "approve"|"reject"|"edit", "edits": {...}}). Checkpointer — той самий AsyncSqliteSaver / agent_state.db, thread_id на кшталт hitl-approve.

Сценарій

Що стається

python hitl.py approve

MCP post_pr_review виконується, рядок у posted_reviews.jsonl

python hitl.py reject

tool не виконується, лог не росте

python hitl.py edit

merge edits (verdict/body), потім виклик MCP

python mas_langgraph.py demo у HITL не заходить.

Observability (Langfuse)

Модуль observability.py: якщо задані LANGFUSE_PUBLIC_KEY і LANGFUSE_SECRET_KEY, обидва MAS пишуть у той самий Langfuse. Без ключів усе працює як раніше.

  • LangGraphCallbackHandler з langfuse.langchain у graph config (вузли графа + LLM + tools).

  • AutoGenlangfuse.openai патчить OpenAI SDK (його викликає OpenAIChatCompletionClient) і обгортає team.run() батьківським span autogen:<session_id>. У UI це LLM generations, не вузли LangGraph.

LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=
LANGFUSE_BASE_URL=https://cloud.langfuse.com
# self-host: LANGFUSE_BASE_URL=http://localhost:3000

Після python mas_langgraph.py demo або python evals.py у dashboard видно ланцюг: rate_limit_gateinput_gatesupervisorplan_reviewer | rag_agent | mcp_agent → LLM generations / tool calls → output_gate. Session = thread_id.

Після python mas_autogen.py demo з тими самими ключами — traces з тегом autogen, session autogen-<query_id>. CLI друкує Langfuse: on|off.

Приклад trace E1_rag_secrets (supervisor → rag_agentsearch_knowledge):

Langfuse trace E1_rag_secrets

UI: http://localhost:3000/project/cmtpwcw16000bnw07qw5rybq3/traces/d01722f675598687d3f63afabab61356 (локальний Langfuse з практики курсу).

Evals і red-team

eval_results.json — 5/5 scenario-based evals (scenario_id, query, expected_behavior, actual, pass/fail, latency_ms, agents_used, tools_called): E1 RAG secrets, E2 MCP files, E3 MCP metadata, E4 plan review, E5 injection block.

red_team_results.json — 7/7: injection EN/UK, jailbreak (DAN / режим розробника), PII leak, scope confusion (rag_agent + analyze_patch), tool misuse (supervisor + post_pr_review), plus live MAS для injection.

OWASP Top 10 for Agentic Applications 2026

П’ять найрелевантніших ризиків для цього PR-review MAS (OWASP ASI 2026):

ID

Ризик

Як мітигує guardrail / HITL

Що лишилось немітигованим

ASI01

Agent Goal Hijack

input_gate: regex EN/UK, heuristics, ліміт довжини — hijack не доходить до supervisor

Непрямий injection у body GitHub PR / patch (дані як інструкції для planner/MCP)

ASI02

Tool Misuse & Exploitation

Allowlist перед ToolNode; заборонений tool → error без GitHub/MCP

mcp_agent має post_pr_review у allowlist; HITL живе лише в hitl.py, не в основному MAS

ASI03

Identity & Privilege Abuse

Supervisor set() tools; least privilege per agent

Один GITHUB_TOKEN на процес, без per-agent credentials / short-lived tokens

ASI06

Memory & Context Poisoning

Chroma KB read-only з локальних docs; юзер не пише в пам’ять

Немає валідації retrieved GitHub-тексту перед planner; отруєний PR body може змінити план

ASI09

Human-Agent Trust Exploitation

HITL interrupt + Command(resume) перед симульованим POST review

Людина може approve сліпо; mas_langgraph.py demo не форсить HITL на ризиковий tool

AutoGen MAS

Той самий кейс у mas_autogen.py: SelectorGroupChat з supervisor (без tools) і трьома спеціалістами. Tools — payload-функції з tools_legacy.py (ті самі, що MCP); allowlist tool_guardrail і input/output guardrails ті самі. HITL і SqliteSaver у AutoGen не повторюються — як і в mas_langgraph.py demo.

Демо (4 запити octocat/Hello-World#1) зафіксовано в autogen_demo.json на gpt-5.4-mini-2026-03-17: rag_agent + search_knowledge на політики секретів; mcp_agent на файли (README) і метадані (closed / unoju); повне рев'ю supervisor знову віддав mcp_agent (не plan_reviewer) — selector менш жорсткий, ніж structured routing LangGraph.

Порівняльна таблиця LangGraph vs AutoGen

Один і той самий набір з 4 DEMO_QUERIES, модель gpt-5.4-mini-2026-03-17 (snapshot GPT-5.4 mini; alias gpt-5.4-mini на цьому API-проєкті дає 403). Токени: LangGraph — UsageMetadataCallbackHandler (python compare_mas.py --langgraph); AutoGen — models_usage у TaskResult (python mas_autogen.py demo). Тариф: $0.75 / 1M input, $4.50 / 1M output.

Критерій

LangGraph

AutoGen

LOC (основний MAS-файл)

577 (mas_langgraph.py)

390 (mas_autogen.py)

LOC ядра (з Plan-and-Execute)

874 (+ plan_subgraph.py + plan_state.py)

390

Час розробки (хвилини)

~90 (граф, gates, MCP stdio, підграф, persistence)

~35 (SelectorGroupChat + ті самі payload-tools)

Рівень контролю (1–5)

5 — умовні ребра, structured RouteDecision, interrupt_after

3selector_func + промпт ROUTE; LLM може віддати повне рев'ю mcp_agent

Зручність debugging (1–5)

5 — вузол у trace/Langfuse, checkpointer snapshot

3 — Langfuse LLM spans без вузлів графа; dump повідомлень групи

Token usage (4 запити)

8222 (prompt 7522 + completion 700)

5856 (prompt 5074 + completion 782)

Вартість за 4 запити ($)

0.0088

0.0073

MCP інтеграція

stdio MultiServerMCPClient

ті самі payload-функції, без окремого MCP-процеса

Guardrails

вузли rate/input/output + allowlist перед ToolNode

ті самі функції на вході run_autogen_query і в обгортках tools

HITL / persistence

hitl.py + AsyncSqliteSaver

немає (як demo LangGraph)

Handoff

явні conditional edges

group chat + selector

Деталі вимірювання: compare_results.json, autogen_demo.json.

Висновки. AutoGen зібрав робочий MAS швидше і з меншим файлом: SelectorGroupChat + AssistantAgent майже без boilerplate графа. На gpt-5.4-mini він усе ще дешевший (5856 vs 8222 токенів, $0.0073 vs $0.0088), бо немає structured-output схеми supervisor і окремого Plan-and-Execute циклу; розрив менший, ніж був на gpt-4.1. Контроль і debugging сильніші в LangGraph: маршрутизація не «випадково» віддає повне рев'ю mcp_agent, crash/resume і Langfuse-вузли читаються лінійно. Для HITL і MCP-сервера лишаємо LangGraph; AutoGen зручний як друга реалізація того ж кейсу.

Структура

Файл

Призначення

observability.py

Langfuse: LangGraph CallbackHandler + AutoGen openai wrap

evals.py

scenario-based evals MAS

red_team.py

adversarial tests (injection, PII, tools)

eval_results.json

результати evals

red_team_results.json

результати red-team

docs/langfuse_trace.png

скріншот Langfuse trace

mas_langgraph.py

MAS + CLI demo/crash/resume (хуки guardrails, без HITL-графа)

mas_autogen.py

той самий MAS у AutoGen SelectorGroupChat

autogen_demo.json

зафіксоване демо AutoGen (відповіді + токени)

compare_mas.py / compare_results.json

LOC і токени LangGraph vs AutoGen

guardrails.py

input / output / allowlist / rate-limit + self-tests

hitl.py

HITL approve/reject/edit для MCP post_pr_review

mcp_server.py

MCP Server

test_mcp_server.py

unit tests MCP

tools_legacy.py

Pydantic tools + RAG (ДЗ1/ДЗ2)

trajectory_logger.py

лог з agent_name

plan_subgraph.py

Plan-and-Execute (allowlist перед ToolNode)

knowledge.py

ChromaDB KB

mcp_client.py

MultiServerMCPClient (mcp 2 / stdio)

agent_state.db

AsyncSqliteSaver

posted_reviews.jsonl

аудит симульованих POST review

trajectory.json

траєкторія MAS

chroma_db/

persistent Chroma

.env

шаблон ключів

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • -
    license
    B
    quality
    Not graded
    maintenance
    Enables AI-driven orchestration of GitHub development workflows including automated issue analysis, code generation, code review, and PR creation through multiple specialized agents. Integrates with GitHub Actions to automate the complete development process from issue to pull request.
    7
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides AI agents with a secure PR review gateway through 9 MCP tools for managing pull requests, including context retrieval, diff, checks, and merge with two-layer access control.
    14
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/KirillKulakow/final_agentic_mcp_gh_reviewer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server