Ops MCP Server
Provides tools for interacting with Confluence, enabling users to search for content, read page text, manage page hierarchies, and create or update documentation and metadata.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Ops MCP Server Why did the ttdcustom_processing DAG fail today?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Ops Tools MCP Server
One chat window to talk to all your infrastructure — Airflow, EMR, S3, Confluence, and Azure DevOps.
No more jumping between 5 different UIs. Just ask what you want in plain English.
What Is This?
It's an MCP (Model Context Protocol) server that gives AI assistants (like Gemini CLI) access to 44 tools across your entire ops stack. You talk to it in natural language, and it calls the right APIs for you.
Example:
You: "Which DAGs failed today in prod?" AI: calls the Airflow API, gets all runs, filters failures, shows you a summary with diagnosis commands
Related MCP server: EKS Log Analyzer MCP Server
Quick Start
1. Install Dependencies
pip install -r requirements.txt2. Set Up Your .env File
Copy the example and fill in your values:
cp .env.example .env3. Run the Server
python -m mcp_server.mainThe server runs on stdio — connect it to Gemini CLI, VS Code, or any MCP client.
4. Connect from Gemini CLI
Add this to your MCP config (server.json):
{
"mcpServers": {
"ops-tools": {
"command": "python",
"args": ["-m", "mcp_server.main"],
"cwd": "D:\\MCP"
}
}
}Environment Setup
This server works across 4 AWS accounts (dev, uat, test, prod). Each is a separate AWS account with its own credentials.
AWS Profiles (via gimme-aws-creds)
AWS_REGION=eu-west-2
AWS_PROFILE_DEV=consumersync-dev
AWS_PROFILE_UAT=consumersync-uat
AWS_PROFILE_TEST=consumersync-test
AWS_PROFILE_PROD=consumersync-prodMWAA Environments (Airflow)
MWAA_ENV_DEV=eec-aws-uk-ms-dev-consumersyncenv-mwaa
MWAA_ENV_UAT=eec-aws-uk-ms-uat-consumersync-mwaa
MWAA_ENV_TEST=eec-aws-uk-ms-tst-consumersync-mwaa
MWAA_ENV_PROD=eec-aws-uk-ms-prod-consumersync-mwaaEMR Log Buckets
EMR_LOG_BUCKET_DEV=eec-aws-uk-ms-consumersync-dev-logs-bucket
EMR_LOG_BUCKET_UAT=eec-aws-uk-ms-consumersync-uat-logs-bucket
EMR_LOG_BUCKET_TEST=eec-aws-uk-ms-consumersync-tst-logs-bucket
EMR_LOG_BUCKET_PROD=eec-aws-uk-ms-consumersync-prod-logs-bucket
EMR_LOG_PREFIX=spark-logsConfluence
CONFLUENCE_BASE_URL=https://pages.experian.local
CONFLUENCE_PAT=your-personal-access-token
CONFLUENCE_SPACE_KEY=ACTIVATEAzure DevOps (TFS)
AZDO_BASE_URL=https://ukfhpapcvt02.uk.experian.local/tfs/DefaultCollection
AZDO_PAT=your-personal-access-token
AZDO_PROJECT=Activate
AZDO_TEAM=Activate TeamImportant: The AI will always ask you "Which environment?" before calling any AWS tool. It never defaults silently — this prevents accidental cross-account mistakes.
All 44 Tools
Airflow / MWAA (11 tools)
Everything you need to monitor, debug, and manage your DAGs.
Tool | What It Does |
| Lists all DAGs with their schedule and pause status |
| Shows runs for today/yesterday/any date — numbered list so you can pick one |
| Full task-level breakdown for a specific run — which tasks passed, which failed |
| Reads the Airflow log for a specific task attempt — the raw log output |
| Manually kicks off a DAG run (with optional config) |
| Pauses a DAG so it won't run on schedule (already-running jobs finish) |
| Unpauses a DAG so scheduled runs resume |
| Retries a failed task without re-running the entire DAG |
| Shows the DAG's Python source code, tasks, operators, and dependencies |
| Full dashboard of ALL DAGs — states, schedules, failures, everything at a glance |
| Analytics: success rate, duration trends, failure patterns, visual streaks |
Common things you'd say:
"Show me all DAGs in dev"
"Which DAGs failed today in prod?"
"How has hem_processing been running lately?"
"Trigger ttdcustom_processing in uat"
"Pause digital_taxonomy in prod"
"Retry the initialise task on yesterday's failed run"
EMR Serverless (10 tools)
Manage Spark jobs, read driver logs, browse S3 log files, track costs.
Tool | What It Does |
| Lists all EMR Serverless apps (note: DAGs create temporary apps that get cleaned up) |
| Shows job runs for an application — with state and duration |
| Deep dive into a job: Spark config, resource usage, S3 log paths |
| Reads stdout/stderr from the Spark driver — the actual Python output and errors |
| Navigates the S3 log directory structure folder by folder |
| Cancels a running or stuck Spark job |
| Stops an EMR app — auto-cancels running jobs if needed |
| Permanently deletes an EMR app — force mode stops and deletes in one call |
| Reads any file from S3 (CSV, TXT, JSON, Parquet) — 5 MB limit, auto-detects format |
| Shows vCPU hours, memory, storage usage — broken down per app |
Common things you'd say:
"Show me the Spark driver log for this job"
"What failed in the stdout log?"
"Cancel that stuck job"
"Stop that EMR application"
"Force-stop the app and cancel all running jobs"
"Delete that EMR application"
"How much has EMR cost us this week?"
"Read this S3 file: s3://bucket/path/to/file.csv"
S3 — General (4 tools)
Browse any S3 bucket in the account — not just EMR logs.
Tool | What It Does |
| Lists all S3 buckets in the AWS account |
| Interactive folder/file browsing — like a file explorer for S3 |
| Recursively lists ALL files end-to-end with filters and size summary |
| Shows file metadata (size, modified date, content type, encryption) without downloading |
Common things you'd say:
"What S3 buckets do we have in dev?"
"Show me what's in the raw data bucket"
"List all CSV files in the raw bucket"
"How much data is in this S3 folder?"
"Read this parquet file from S3"
"How big is this file?"
Confluence (9 tools)
Search, read, and write documentation — without opening a browser.
Tool | What It Does |
| Full-text search across pages — ranked by relevance (same as the web UI) |
| Reads a page's full content — converted from HTML to clean text |
| Lists all child pages under a parent page |
| Lists all pages in a space (paginated) |
| Lists file attachments on a page (name, size, download URL) |
| Shows tags/labels on a page |
| Reads comments and discussions on a page |
| Creates a new page (plain text or HTML content) |
| Updates an existing page — replace or append content |
Common things you'd say:
"Find documentation about Audience Engine"
"Read that runbook page"
"Create a new troubleshooting guide under the runbooks section"
"What are the child pages under the HEM documentation?"
Pro tip: When you say "docs", "documentation", "wiki", or "runbook", the AI knows to search Confluence automatically.
Azure DevOps / TFS (8 tools)
Sprint tracking, work items, source code — all from chat.
Tool | What It Does |
| Lists all Git repositories in the project |
| Browse files and folders in a repo — one folder at a time |
| Full recursive file tree of a repo in one call — shows every file with correct paths |
| Read the content of any file (with syntax highlighting) |
| Shows active sprint name, dates, and days remaining |
| All PBIs, Tasks, and Bugs in the sprint — who's doing what |
| Full details for a PBI/Task/Bug: description, acceptance criteria, links |
| Items not in the current sprint — what's coming next |
Common things you'd say:
"What sprint are we in?"
"What's everyone working on?"
"Show me PBI 12345"
"What's in the backlog?"
"Show me all the files in the hem_processing repo"
"List all Python files in this repo"
"What's the folder structure of this repo?"
Orchestration (1 tool)
The power tool — chains multiple tools together for one-shot answers.
Tool | What It Does |
| Complete failure diagnosis in one call — finds the failed run, reads task logs, extracts EMR IDs, reads Spark driver logs, returns root cause analysis |
What you'd say:
"Diagnose the failure for hem_processing in prod"
"What went wrong with ttdcustom_processing yesterday?"
This one tool replaces 5-6 manual steps that used to take 20 minutes.
Utility (1 tool)
Tool | What It Does |
| Confirms the server is running and connected |
How It Works
You (plain English) → AI (Gemini/Claude) → MCP Server → APIs (Airflow, EMR, S3, Confluence, TFS)You type a question in natural language
The AI figures out which tool(s) to call
The MCP server calls the actual APIs (MWAA, boto3, Confluence REST, Azure DevOps REST)
Results come back formatted and readable
The AI can chain tools together — e.g. find a failed run → read its logs → show root cause
Architecture
D:\MCP\
├── mcp_server/
│ ├── main.py # Server entry point + tool registration
│ ├── config.py # Environment config (4 AWS accounts)
│ └── tools/
│ ├── _aws_helpers.py # Shared AWS helpers (S3 client, formatting)
│ ├── mwaa_tools.py # 11 Airflow tools
│ ├── emr_tools.py # 10 EMR Serverless tools
│ ├── s3_tools.py # 4 general S3 tools
│ ├── confluence_tools.py # 9 Confluence tools
│ ├── azdo_tools.py # 8 Azure DevOps tools
│ ├── orchestration_tools.py # 1 orchestration tool
│ └── utility_tools.py # 1 utility tool
├── .env # Your local config (not committed)
├── .env.example # Template for .env
├── server.json # MCP client config
├── requirements.txt # Python dependencies
├── DEMO_SCRIPT.md # 15-minute demo walkthrough
└── README.md # This fileKey Design Decisions
Fresh credentials every call — No client caching for S3 or EMR. Every API call gets a fresh boto3 session so expired credentials never cause silent failures.
Environment-aware — All AWS tools require you to specify dev/uat/test/prod. The AI asks if you forget. Each env points to a different AWS account.
MWAA session cache — The Airflow login token is cached (it needs auth cookies), but the cache clears automatically on 401/403 errors and retries.
Clean log output — Spark driver logs are auto-decompressed from .gz, Confluence HTML is converted to clean markdown text.
Interactive responses — DAG runs are numbered so you can say "tell me about run #3". Work items show ready-to-use follow-up commands.
Troubleshooting
Problem | Fix |
"Cannot connect to MWAA webserver" | Connect to VPN first |
"Access denied" on S3 | Run |
"CONFLUENCE_PAT not set" | Add your Confluence Personal Access Token to |
"AZDO_PAT not set" | Generate a PAT in Azure DevOps → User Settings → Personal Access Tokens |
AI calls all environments at once | The server instructions should prevent this — if it happens, say "just dev" |
Stale Airflow session | The server auto-retries on 401/403 — if it persists, restart the server |
Requirements
Python 3.10+
VPN access (for MWAA, Confluence, Azure DevOps)
gimme-aws-credsconfigured for all 4 AWS accountsConfluence PAT
Azure DevOps PAT
MCP-compatible client (Gemini CLI, VS Code, Claude Code, etc.)
Available Tools
44 toolsbrowse_repoA
Browse files and folders in a Git repository — like a directory listing.
USE THIS TOOL when the user wants to see what files are in a repo, explore folder structure, or find a specific file path.
Args: repo_name: Repository name (from list_repos). path: Folder path to browse (default '/' for root). Use forward slashes. branch: Branch name (default: repo's default branch). project: Project name (default from config).
Returns a directory listing with file/folder names and paths. Use read_repo_file(repo_name='...', path='...') to read a file's content.
Inputs: repo_name (required), path, branch, project. Returns: result
browse_repo_recursiveA
List ALL files in a Git repository recursively — the full file tree.
USE THIS TOOL when the user asks 'what files are in this repo?', 'show me the whole repo structure', 'list all Python files', or needs to find correct file paths before reading. Much faster than calling browse_repo folder-by-folder.
Args: repo_name: Repository name (from list_repos). path: Starting folder path (default '/' for entire repo). branch: Branch name (default: repo's default branch). extension_filter: Filter by file extension, e.g. '.py', '.json', '.yaml'. Case-insensitive. Only files matching this extension are shown. project: Project name (default from config).
Returns a tree of ALL files and folders with full paths. Use read_repo_file(repo_name='...', path='...') to read any file.
Inputs: repo_name (required), path, branch, extension_filter, +1 more. Returns: result
browse_s3A
Browse folders and files in any S3 bucket interactively.
USE THIS TOOL when the user asks to see what's in an S3 bucket, list files in a folder, navigate S3, or explore any S3 path.
Start with no prefix to see top-level folders, then drill into subfolders using the hints in the output.
Args: bucket: S3 bucket name (required). prefix: S3 prefix/path to browse (default: root of bucket). Example: 'raw/hem_processing/' to see that folder. max_results: Max items to show (default 200). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a directory listing showing folders and files with sizes and last modified times.
Inputs: bucket (required), prefix, max_results, env. Returns: result
browse_s3_logsA
Browse the S3 log directory structure. Navigate into folders to find logs.
Args: prefix: S3 prefix/path to browse (default: EMR_LOG_PREFIX from config, e.g. 'spark-logs/'). Use the output to navigate deeper, e.g. 'spark-logs/ttdgeo_metadata_SE/'. bucket: S3 bucket (default from config). max_items: Max items to show (default 50). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a directory listing of the S3 prefix showing folders and files.
Inputs: prefix, bucket, max_items, env. Returns: result
cancel_job_runA
Cancel a running or pending EMR Serverless job run.
Use this when a Spark job is stuck, taking too long, or was started with incorrect parameters. The cancellation is asynchronous — the job will transition to CANCELLING and then CANCELLED state.
Args: application_id: The EMR Serverless application ID. job_run_id: The job run ID to cancel. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns confirmation of the cancellation request.
Inputs: application_id (required), job_run_id (required), env. Returns: result
clear_task_instanceA
Clear a task instance to retry it without re-triggering the entire DAG.
Use this when a task failed due to a transient issue (e.g. network timeout, temporary S3 error) and you want to retry just that task and optionally all tasks downstream of it.
Args: dag_id: The DAG identifier. dag_run_id: The run ID. task_id: The task to clear/retry. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. include_downstream: If True, also clear all downstream tasks (default: False).
Returns confirmation with the list of cleared task instances.
Inputs: dag_id (required), dag_run_id (required), task_id (required), env, +1 more. Returns: result
create_confluence_pageA
Create a new Confluence page.
Use this to create incident reports, runbook entries, meeting notes, or any documentation. Content should be in simple HTML or plain text (which will be wrapped in HTML paragraphs).
Args: title: The page title (must be unique within the space). body: The page content. Can be HTML or plain text. For plain text, paragraphs are separated by blank lines. space_key: Space key (default from config). parent_page_id: Optional parent page ID to nest under.
Returns confirmation with the new page ID and URL.
Inputs: title (required), body (required), space_key, parent_page_id. Returns: result
dag_analyticsA
Get run statistics and trend analysis for a specific DAG.
Use this when the user asks about DAG reliability, performance trends, statistics, or historical patterns — "how's digital taxonomy been running?", "is this DAG stable?", "show me stats for HEM processing".
Unlike list_dag_runs (flat list of individual runs), this tool provides:
Success rate and failure rate over the time period
Duration stats: average, min, max, and trend direction
Failure pattern detection (e.g. "fails on Mondays")
Recent run streak (visual ✅/❌ sequence)
Day-by-day breakdown
Args: dag_id: The DAG identifier to analyse. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. days: Number of days to look back (default: 14, max: 180).
Returns a formatted analytics report with trends and patterns.
Inputs: dag_id (required), env, days. Returns: result
delete_emr_applicationA
Delete an EMR Serverless application permanently.
The application must be in STOPPED or CREATED state to be deleted. If the application is still running:
With force=False: returns an error asking you to stop it first.
With force=True: automatically stops the app (cancelling any running jobs), waits for it to reach STOPPED state, then deletes it.
Args: application_id: The EMR Serverless application ID. force: If True, stop the app first (cancelling jobs) then delete. If False, only delete if already stopped. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a step-by-step report of what was done.
Inputs: application_id (required), force, env. Returns: result
diagnose_dag_failureA
One-shot diagnosis of a failed DAG run.
This tool does everything automatically:
Finds the most recent failed run (today or specified date)
Identifies which task(s) failed
Reads the failed task logs
Extracts EMR application ID from the 'initialise' task
Reads the Spark driver logs (stdout) for Python app errors
Returns a complete failure analysis
This replaces the need to call 5-6 tools manually.
Args: dag_id: The DAG to diagnose (e.g. 'ttdcustom_processing'). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. date: Optional date to check (ISO format or 'yesterday'). Default: today.
Returns a comprehensive failure report with root cause analysis.
Inputs: dag_id (required), env, date. Returns: result
get_backlogA
Get backlog items (PBIs/User Stories not in the current sprint).
USE THIS TOOL when the user asks about the backlog, upcoming work, 'what's next?', 'what's not in the sprint?', or items waiting to be picked up.
Args: project: Project name (default from config). team: Team name (default from config). max_results: Maximum items to return (default 50).
Returns backlog items ordered by priority with state and effort.
Inputs: project, team, max_results. Returns: result
get_child_pagesA
List all child pages of a given parent page.
Args: page_id: The parent page ID. include_content: If True, include a short content preview for each child. max_results: Max children to return (default 50).
Returns a list of child pages with titles and IDs.
Inputs: page_id (required), include_content, max_results. Returns: result
get_current_sprintA
Get the current (active) sprint/iteration with dates and summary.
USE THIS TOOL when the user asks 'what sprint are we in?', 'current iteration', 'sprint dates', 'when does the sprint end?', or any question about the active sprint.
Args: project: Project name (default from config). team: Team name (default from config).
Returns current sprint name, date range, and time remaining. Use get_sprint_work_items() to see what's in the sprint.
Inputs: project, team. Returns: result
get_dag_run_detailsA
Get full details for a specific DAG run, including every task instance.
Use this to see ALL tasks in a DAG run with their pass/fail status. For any failed tasks, the output includes ready-to-use get_task_log() hints. Common DAG task flow: start → create_arguments → check_inputs → initialise (creates EMR app) → processing → finalise.
Args: dag_id: The DAG identifier. dag_run_id: The run ID (e.g. 'scheduled__2026-02-16T00:00:00+00:00' or 'manual__...'). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns formatted output showing each task with state, duration and try count.
Inputs: dag_id (required), dag_run_id (required), env. Returns: result
get_dag_sourceA
Get the source code / definition of a DAG.
Use this to understand what a DAG does — its tasks, operators, dependencies, schedule, and configuration. Useful for debugging or understanding a pipeline's structure.
Args: dag_id: The DAG identifier. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns the DAG details including file location, schedule, tags, and task list.
Inputs: dag_id (required), env. Returns: result
get_dags_status_dashboardA
Get a complete status dashboard of ALL DAGs — the go-to tool for any overview question.
USE THIS TOOL when the user asks:
"What's the status of all DAGs?"
"Which DAGs failed today?"
"Show me a DAG report / dashboard / overview"
"What's running right now?"
"Are all DAGs healthy?"
Shows every DAG with:
Active/Paused state
Schedule interval
Last run: state (success/failed/running), date, and duration
Summary counts at the top
Failed DAGs highlighted at the bottom with diagnosis commands
Args: env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. limit: Maximum number of DAGs to return (default 100).
Returns a formatted status report with every DAG and its current health.
Inputs: env, limit. Returns: result
get_emr_cost_summaryA
Get a summary of EMR Serverless resource usage and estimated costs.
Aggregates vCPU hours, memory GB-hours, and storage GB-hours across recent job runs. Useful for understanding compute costs.
Args: application_id: Optional — filter to one application. If omitted, scans all. days: Number of days to look back (default 7). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a cost summary with per-job and total resource usage.
Inputs: application_id, days, env. Returns: result
get_job_run_detailsA
Get detailed information about a specific EMR Serverless job run.
Shows the Spark submit config (entry point script, arguments), resource usage (vCPU hours, memory), and S3 log locations. Includes ready-to-use hints for read_spark_driver_log and browse_s3_logs.
Args: application_id: The EMR Serverless application ID (from Airflow 'initialise' task log). job_run_id: The job run ID (from Airflow processing task log). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns comprehensive details: state, config, resource usage, S3 log paths.
Inputs: application_id (required), job_run_id (required), env. Returns: result
get_page_attachmentsA
List all file attachments on a Confluence page.
Args: page_id: The page ID. max_results: Max attachments to return (default 50).
Returns a list of attachments with name, size, type, and download URL.
Inputs: page_id (required), max_results. Returns: result
get_page_commentsA
Get comments on a Confluence page.
Args: page_id: The page ID. max_results: Max comments to return (default 25).
Returns comments with author, date, and content. Useful for understanding discussions and context around a page.
Inputs: page_id (required), max_results. Returns: result
get_page_contentA
Read the full content of a Confluence page.
Args: page_id: The page ID (numeric). Provide this OR title. title: Page title to look up (slower, requires space_key). space_key: Space key (default from config). Required if using title. include_metadata: Include page metadata header (default True).
Returns the page content converted to clean readable text.
Inputs: page_id, title, space_key, include_metadata. Returns: result
get_page_labelsB
Get all labels (tags) on a Confluence page.
Args: page_id: The page ID.
Returns a list of labels. Useful for finding related pages or understanding page categorization.
Inputs: page_id (required). Returns: result
get_s3_object_infoA
Get detailed metadata for a single S3 object without downloading it.
USE THIS TOOL when the user asks about a specific file's size, modification time, type, or other details. This is fast because it only reads the metadata header, not the file content.
Args: s3_uri: Full S3 URI (e.g. 's3://bucket-name/path/to/file.csv'). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns file metadata: size, last modified, content type, storage class, encryption, and ETag.
Inputs: s3_uri (required), env. Returns: result
get_space_pagesB
List all pages in a Confluence space.
Args: space_key: Space key (default: ACTIVATE from config). max_results: Max pages per request (default 50, max 100). page_type: 'page' or 'blogpost' (default 'page'). start: Pagination offset (default 0).
Returns a list of pages with titles, IDs, and URLs (paginated).
Inputs: space_key, max_results, page_type, start. Returns: result
get_sprint_work_itemsA
Get all work items (PBIs, Tasks, Bugs) in a sprint with full details.
USE THIS TOOL when the user asks 'what's in the sprint?', 'sprint board', 'who's working on what?', 'sprint details', or wants to see sprint content.
Shows each work item with type, title, state, assigned person, effort/story points. Groups items by type (PBI, Task, Bug) with totals.
Args: iteration_path: Full iteration path (e.g. 'Activate\Sprint 23 Q4 FY26'). If omitted, uses the current sprint automatically. project: Project name (default from config). team: Team name (default from config).
Returns all work items grouped by type with assignee, state, effort, and priority. Use get_work_item_details(work_item_id=...) for full details of any item.
Inputs: iteration_path, project, team. Returns: result
get_task_logA
Read the Airflow log for a specific task attempt.
IMPORTANT for EMR debugging:
Read the 'initialise' (or 'ae_initialize_emr_application') task log to find the EMR application ID. Look for: 'EMR serverless application created: 00gXXXXXXXXX' or 'Created EMR application 00gXXXXXXXXX'.
Read the failed processing task log to find the job_run_id. Look for: 'EMR serverless job started: 00gXXXXXXXXX'.
Then use read_spark_driver_log(application_id, job_run_id, log_type='stdout') to get the Python app output.
Args: dag_id: The DAG identifier. dag_run_id: The run ID. task_id: The task identifier. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. try_number: Which attempt (default 1). tail_lines: Number of lines to return from the end (default 200).
Returns the raw log text, trimmed to the last N lines.
Inputs: dag_id (required), dag_run_id (required), task_id (required), env, +2 more. Returns: result
get_work_item_detailsA
Get full details of a single work item (PBI, Task, Bug, Feature, Epic).
USE THIS TOOL when the user asks about a specific work item by ID, wants the description, acceptance criteria, history, or full details.
Args: work_item_id: The numeric work item ID (e.g. 12345). project: Project name (default from config).
Returns complete work item details including description, acceptance criteria, parent/child links, and all metadata fields.
Inputs: work_item_id (required), project. Returns: result
list_dag_runsA
Get DAG runs for today, yesterday, last week, or a specific date.
This is the go-to tool when the user asks about DAG runs, processing status, or historical failures. Returns a numbered interactive list so the user can pick a specific run for deeper investigation.
Args: env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. dag_id: Optional — filter to a specific DAG. If omitted, shows ALL DAGs. date: 'today' (default), 'yesterday', 'last_week', or ISO date (e.g. '2026-02-15'). limit: Max runs to return (default 50).
Returns a numbered list of runs with status, timing and duration. Present these to the user so they can pick one by number.
Inputs: env, dag_id, date, limit. Returns: result
list_dagsA
List all DAGs in the MWAA environment.
Args: env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. limit: Maximum number of DAGs to return (default 100). only_active: If True, show only unpaused DAGs.
Returns a formatted table of DAGs with schedule interval and pause status.
Inputs: env, limit, only_active. Returns: result
list_emr_applicationsA
List all EMR Serverless applications.
Note: DAGs create temporary EMR apps that are deleted after each run. If an app is not found here, it was already cleaned up — but job run details and S3 logs are still available via get_job_run_details and read_spark_driver_log using the application_id from the Airflow task log.
Args: states: Optional comma-separated state filter (e.g. 'STARTED,CREATED'). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a formatted list of applications with IDs, types and states.
Inputs: states, env. Returns: result
list_job_runsA
List job runs for an EMR Serverless application.
Args: application_id: The EMR Serverless application ID. max_results: Max runs to return (default 30). states: Optional comma-separated state filter (e.g. 'SUCCESS,FAILED'). created_after: Optional ISO date — only runs after this date (e.g. '2026-02-16'). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a list of job runs with status, timing and duration.
Inputs: application_id (required), max_results, states, created_after, +1 more. Returns: result
list_reposA
List all Git repositories in the Azure DevOps project.
USE THIS TOOL when the user asks about repos, code repositories, or wants to browse source code in Azure DevOps / TFS.
Args: project: Project name (default: Activate from config).
Returns a list of repositories with name, default branch, size, and URL. Use browse_repo(repo_name='...') to explore a repo's files.
Inputs: project. Returns: result
list_s3_bucketsA
List all S3 buckets in the AWS account.
USE THIS TOOL when the user asks about S3 buckets, storage, "what buckets do we have", or anything about S3 at account level.
Args: env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns every bucket with its creation date, sorted alphabetically.
Inputs: env. Returns: result
list_s3_recursiveA
Recursively list ALL files under an S3 bucket/prefix in a single call.
USE THIS TOOL when the user asks to see everything in a bucket or folder end-to-end, wants a full file listing, or needs to find files by name or extension across nested folders.
Args: bucket: S3 bucket name (required). prefix: Starting prefix/folder (default: root of bucket). Example: 'raw/hem_processing/' to list that subtree. name_filter: Optional — case-insensitive substring match on filename. Example: 'taxonomy' shows only files with 'taxonomy' in the name. extension_filter: Optional — file extension to filter by (with or without dot). Example: '.csv' or 'csv' or '.parquet' or '.gz' max_results: Max files to return (default 500, max 2000). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a full recursive file listing with sizes, plus a summary with total count, total size, and file type breakdown.
Inputs: bucket (required), prefix, name_filter, extension_filter, +2 more. Returns: result
pause_dagA
Pause a DAG — prevents future scheduled runs from triggering.
The DAG will still be visible in the Airflow UI but won't execute on its schedule. Already-running DAG runs will continue to completion.
Args: dag_id: The DAG to pause. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns confirmation of the pause action.
Inputs: dag_id (required), env. Returns: result
read_repo_fileA
Read the content of a single file from a Git repository.
USE THIS TOOL when the user wants to see source code, config, or content of a specific file. Get the path from browse_repo first.
Args: repo_name: Repository name. path: Full file path (e.g. '/src/main.py'). Use forward slashes. branch: Branch name (default: repo's default branch). project: Project name (default from config).
Returns the raw file content with metadata header.
Inputs: repo_name (required), path (required), branch, project. Returns: result
read_s3_fileA
Read any file from S3 by its full URI and display in chat.
Supports CSV, TXT, JSON, log files, .gz compressed files, and Parquet. Files larger than 5 MB are rejected to avoid crashing the server.
For Parquet files: reads the file and displays the first N rows as a formatted table (default 50 rows). Parquet files are binary so they cannot be tailed or searched — use head_rows to control output.
Args: s3_uri: Full S3 URI (e.g. 's3://bucket-name/path/to/file.csv'). tail_lines: Lines from the end for text files (default 100). -1 for all. search_text: Filter matching lines (text files only). head_rows: Rows to display for Parquet files (default 50). env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns the file contents, optionally filtered and tailed.
Inputs: s3_uri (required), tail_lines, search_text, head_rows, +1 more. Returns: result
read_spark_driver_logA
Read the Spark driver log from S3 for an EMR Serverless job run.
DEFAULT: Reads stdout.gz — this is the PRIMARY log containing Python print statements, row counts, file paths, and application errors. This is what you want 90% of the time.
Use log_type='stderr' only when you need Spark framework logs (executor allocation, memory warnings, shuffle errors).
Use read_both=True to get BOTH logs in one call (stdout first, then stderr filtered to ERROR lines only).
How to find application_id and job_run_id:
application_id: from the 'initialise' Airflow task log → 'EMR serverless application created: 00gXXX'
job_run_id: from the processing Airflow task log → 'EMR serverless job started: 00gXXX'
Or use list_emr_applications() then list_job_runs()
Args: application_id: The EMR Serverless application ID (e.g. '00g16i3marao0c0t'). job_run_id: The job run ID (e.g. '00g16i5g2pm56o0v'). log_type: 'stdout' (default, Python app output) or 'stderr' (Spark framework logs). s3_log_uri: Optional full S3 URI to read directly (e.g. 's3://bucket/path/stdout.gz'). process_name: Optional folder name under spark-logs/ (e.g. 'stackadapt_main'). Speeds up log discovery. tail_lines: Number of lines from the end (default 300). Use -1 for all lines. search_text: Optional text to filter log lines (e.g. 'ERROR', 'Exception'). bucket: S3 bucket override (default from config). read_both: If True, read BOTH stdout and stderr in one call. stdout shown first, stderr filtered to ERROR lines.
Returns the log content, optionally filtered and tailed.
Inputs: application_id (required), job_run_id (required), log_type, s3_log_uri, +6 more. Returns: result
search_confluenceA
Search Confluence pages — the primary tool for finding documentation.
USE THIS TOOL when the user says 'docs', 'documentation', 'wiki', 'runbook', 'find page about X', or any documentation-related question.
Searches both page titles and content, ranked by relevance (same as the web UI).
Args: query: The search text (e.g. 'Audience Engine'). Also supports raw CQL queries (e.g. "type=page AND title~'Walkthrough'"). space_key: Space to search in (default: ACTIVATE from config). ancestor_page_id: Optional parent page ID to scope search within a page tree. max_results: Max results to return (default 50). start: Pagination offset — skip this many results (default 0). Use for page 2, 3, etc.
Returns a list of matching pages with titles, space, last modified, and URLs. Use get_page_content(page_id='...') to read any result.
Inputs: query (required), space_key, ancestor_page_id, max_results, +1 more. Returns: result
server_health_checkA
Check connectivity to all configured services.
Tests AWS credentials for each environment (dev/uat/test/prod), MWAA environments, EMR Serverless API, S3 log bucket access per env, S3 general access, Confluence PAT, and Azure DevOps connectivity.
Use this FIRST to verify everything is connected before running other tools. Requires VPN and valid AWS credentials.
Returns a status report for each service.
Inputs: no named parameters. Returns: result
stop_emr_applicationA
Stop an EMR Serverless application. If jobs are running, cancels them first.
Smart flow:
Tries to stop the application directly.
If it fails because jobs are still running — automatically finds and cancels ALL running/pending jobs, then retries the stop.
Reports every step taken so the user knows exactly what happened.
Use force=True to skip the initial stop attempt and go straight to cancelling all jobs first (useful when you know jobs are running).
Args: application_id: The EMR Serverless application ID. force: If True, cancel all running jobs first without trying to stop. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns a step-by-step report of what was done.
Inputs: application_id (required), force, env. Returns: result
trigger_dagA
Manually trigger a DAG run.
Args: dag_id: The DAG to trigger. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified. conf: Optional JSON string of DAG run configuration.
Returns confirmation with the new run ID.
Inputs: dag_id (required), env, conf. Returns: result
unpause_dagA
Unpause a DAG — allows scheduled runs to trigger again.
Args: dag_id: The DAG to unpause. env: Target environment — 'dev', 'uat', 'test', or 'prod'. IMPORTANT: Do NOT guess or default. Ask the user which environment if not specified.
Returns confirmation of the unpause action.
Inputs: dag_id (required), env. Returns: result
update_confluence_pageA
Update an existing Confluence page's content.
Args: page_id: The page ID to update. body: New page content (HTML or plain text). title: Optional new title. If omitted, keeps the existing title. append: If True, append to existing content instead of replacing.
Returns confirmation of the update.
Inputs: page_id (required), body (required), title, append. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 44 tools
Most tools have distinct purposes, but there is some overlap that could cause confusion. For example, browse_repo and browse_repo_recursive both explore Git repositories, with the latter being a more comprehensive version, which might lead to misselection if an agent doesn't carefully read descriptions. Similarly, browse_s3 and browse_s3_logs both browse S3, but the latter is specialized for logs, creating a potential boundary issue. However, the majority of tools, like those for DAG management, EMR, Confluence, and Azure DevOps, are clearly differentiated.
Tool names follow a highly consistent verb_noun pattern throughout, such as browse_repo, cancel_job_run, create_confluence_page, and get_dag_run_details. There are no deviations in naming conventions (e.g., no mixing of camelCase or other styles), making the set predictable and easy to understand. This consistency aids agents in quickly identifying tool purposes.
With 44 tools, the count is excessive for a single server, even given its broad scope covering Git, S3, EMR, Airflow DAGs, Confluence, and Azure DevOps. This many tools can overwhelm agents, increasing cognitive load and the risk of misselection. A more modular approach with separate servers for each domain (e.g., one for DAGs, one for Confluence) would be more appropriate, as the current set feels heavy and unfocused.
The tool set provides comprehensive coverage across its integrated domains, with no obvious gaps. For Git, it includes browsing and reading files; for S3, browsing, reading, and listing; for EMR, full lifecycle management (create, list, stop, cancel, delete, cost analysis); for Airflow DAGs, CRUD operations (trigger, pause, unpause), monitoring, and diagnostics; for Confluence, CRUD pages and search; and for Azure DevOps, repository and sprint management. Each domain is well-covered, enabling agents to handle end-to-end workflows without dead ends.
Related MCP Connectors
Query your app's logs, metrics and incidents from your AI assistant.
Provides capabilities that let LLM agents perform a range of infrastructure management tasks.
Manage uptime monitors and incidents and search logs, metrics and traces from an AI assistant.
Autonomous and governed SRE & MLOps control plane for AI agent platforms.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Google Cloud Platform services for log analysis and root cause investigation. Provides tools to query Cloud Logging, detect error patterns, and perform real-time log streaming across multiple GCP projects.MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to analyze Amazon EKS node logs collected by the EKS Log Collector script. It provides tools and troubleshooting workflows for diagnosing issues with VPC CNI, kubelet, DNS, and general node connectivity.-
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to autonomously query AWS CloudWatch Logs and perform structured root-cause analysis via natural language prompts, using MCP tools for log group listing and Insights queries.MIT
- FlicenseNot gradedqualityDmaintenanceEnables autonomous infrastructure health management by exposing tools for retrieving system logs, querying a knowledge base, executing SQL analytics, and simulating system commands, all integrated into an AI-driven incident response workflow.-