- Language/Version: Python 3.10+
- Core Libraries:
agent-utilities,fastmcp,pydantic-ai - Key principles: Functional patterns, Pydantic for data validation, asynchronous tool execution.
- Architecture:
mcp_server.py: Main MCP server entry point and tool registration.agent_server.py: Pydantic AI agent definition and logic.skills/: Directory containing modular agent skills (if applicable).agent/: Internal agent logic and prompt templates.
graph TD
User([User/A2A]) --> Server[A2A Server / FastAPI]
Server --> Agent[Pydantic AI Agent]
Agent --> Skills[Modular Skills]
Agent --> MCP[MCP Server / FastMCP]
MCP --> Client[API Client / Wrapper]
Client --> ExternalAPI([External Service API])
sequenceDiagram
participant U as User
participant S as Server
participant A as Agent
participant T as MCP Tool
participant API as External API
U->>S: Request
S->>A: Process Query
A->>T: Invoke Tool
T->>API: API Request
API-->>T: API Response
T-->>A: Tool Result
A-->>S: Final Response
S-->>U: Output
pip install .[all]
pre-commit run --all-files
- MCP Entry Point →
mcp_server.py - Agent Entry Point →
agent_server.py - Source Code →
gitlab_api/ - Skills →
skills/(if exists)
├── .bumpversion.cfg\n├── .dockerignore\n├── .env\n├── .gitattributes\n├── .github\n│ └── workflows\n│ └── pipeline.yml\n├── .gitignore\n├── .pre-commit-config.yaml\n├── .pytest_cache\n│ ├── .gitignore\n│ ├── CACHEDIR.TAG\n│ ├── README.md\n│ └── v\n│ └── cache\n├── AGENTS.md\n├── Dockerfile\n├── LICENSE\n├── MANIFEST.in\n├── README.md\n├── build-requirements.txt\n├── compose.yml\n├── debug.Dockerfile\n├── gitlab_api\n│ ├── __init__.py\n│ ├── __main__.py\n│ ├── agent\n│ │ ├── AGENTS.md\n│ │ ├── CRON.md\n│ │ ├── CRON_LOG.md\n│ │ ├── HEARTBEAT.md\n│ │ ├── IDENTITY.md\n│ │ ├── MEMORY.md\n│ │ ├── USER.md\n│ │ ├── mcp_config.json\n│ │ └── templates.py\n│ ├── agent_server.py\n│ ├── auth.py\n│ ├── gitlab_api.py\n│ ├── gitlab_gql.py\n│ ├── gitlab_input_models.py\n│ ├── gitlab_response_models.py\n│ └── mcp_server.py\n├── mcp.compose.yml\n├── pyproject.toml\n├── pytest.ini\n├── requirements.txt\n├── scripts\n│ ├── validate_a2a_agent_server.py\n│ └── validate_agent_server.py\n├── test-requirements.txt\n└── tests\n ├── test_gitlab_a2a_validation.py\n ├── test_gitlab_api.py\n ├── test_gitlab_mcp_validation.py\n ├── test_gitlab_models.py\n ├── test_verify_agent_server.py\n └── verify_a2a_queries.py
Always:
- Use
agent-utilitiesfor common patterns (e.g.,create_mcp_server,create_agent). - Define input/output models using Pydantic.
- Include descriptive docstrings for all tools (they are used as tool descriptions for LLMs).
- Check for optional dependencies using
try/except ImportError.
Good example:
from agent_utilities import create_mcp_server
from mcp.server.fastmcp import FastMCP
mcp = create_mcp_server("my-agent")
@mcp.tool()
async def my_tool(param: str) -> str:
"""Description for LLM."""
return f"Result: {param}"Do:
- Run
pre-commitbefore pushing changes. - Use existing patterns from
agent-utilities. - Keep tools focused and idempotent where possible.
Don't:
- Use
cdcommands in scripts; use absolute paths or relative to project root. - Add new dependencies to
dependenciesinpyproject.tomlwithout checkingoptional-dependenciesfirst. - Hardcode secrets; use environment variables or
.envfiles.
Always do:
- Run lint/test via
pre-commit. - Use
agent-utilitiesbase classes.
Ask first:
- Major refactors of
mcp_server.pyoragent_server.py. - Deleting or renaming public tool functions.
Never do:
- Commit
.envfiles or secrets. - Modify
agent-utilitiesoruniversal-skillsfiles from within this package.
- Propose a plan first before making large changes.
- Check
agent-utilitiesdocumentation for existing helpers.
This agent uses pydantic-graph orchestration for intelligent routing and optimal context management.
---
title: Gitlab API Graph Agent
---
stateDiagram-v2
[*] --> RouterNode: User Query
RouterNode --> DomainNode: Classified Domain
RouterNode --> [*]: Low confidence / Error
DomainNode --> [*]: Domain Result
- RouterNode: A fast, lightweight LLM (e.g.,
nvidia/nemotron-3-super) that classifies the user's query into one of the specialized domains. - DomainNode: The executor node. For the selected domain, it dynamically sets environment variables to temporarily enable ONLY the tools relevant to that domain, creating a highly focused sub-agent (e.g.,
gpt-4o) to complete the request. This preserves LLM context and prevents tool hallucination.