Skip to content

RFC: Add Amazon Connect MCP Server (read-only realtime and historical contact center reporting) #3990

Description

@awsri

Is this related to an existing feature request or issue?

N/A — new MCP server proposal.

Summary

This RFC proposes a new MCP server, awslabs.amazon-connect-mcp-server, that lets an assistant answer natural-language questions about an Amazon Connect contact center by wrapping read-only Amazon Connect reporting APIs. It exposes seven @mcp.tool functions organized into three source modules — Discovery (resource enumeration), Realtime (live operational metrics and per-agent status), and Historical (metrics over the last 90 days) — all of which issue only List/Get/Describe calls through the boto3 connect client. All seven are registered as flat, individually-named FastMCP tools.

The server is already implemented (version 0.2.0) and passes the repository's lint, format, type, and test gates. This RFC documents the design for triage approval ahead of the corresponding new-server PR, as required by CONTRIBUTING.md (an RFC issue must precede a new-server PR).

Use case

Contact center operators, supervisors, and workforce/operations analysts routinely need answers to questions like "how many contacts are waiting in the Sales queue right now?", "what is the oldest contact age?", "which agents are available?", and "what was our service level and average handle time over the last week, grouped by queue?". Today, answering these requires navigating the Amazon Connect console or hand-writing scripts against the GetCurrentMetricData, GetCurrentUserData, and GetMetricDataV2 APIs — including resolving instance, queue, agent, and routing-profile identifiers, choosing valid metric/grouping names, and (for historical data) splitting wide time ranges into the API's required per-request windows.

An MCP server removes that friction: an assistant such as Amazon Q can translate plain-English operational questions directly into the correct read-only Connect API calls and return structured, report-ready results. Because the server is strictly read-only, it can be granted to a broad set of operational users without any risk of mutating contact center configuration or live contacts. There is no existing AWS Labs MCP server covering Amazon Connect realtime/historical reporting.

Proposal

Overview

awslabs.amazon-connect-mcp-server is a FastMCP server (mcp.server.fastmcp.FastMCP) whose tools live in three source modules (connect_admin, connect_realtime, connect_historical), each contributing tools via a register(mcp) call in server.py. The modules are an organizational convenience only — all seven tools are registered as flat, individually-named FastMCP tools with no group/tag metadata. Every tool constructs its boto3 connect client per invocation via get_aws_client('connect', region, profile_name) and calls only read APIs. Each tool takes a leading ctx: Context (not a model field) and most accept optional region: str | None = None and profile_name: str | None = None; absent those, the server honors AWS_REGION / AWS_PROFILE. Results are returned as Pydantic response models.

Tool list (7 tools, all read-only)

Discovery (module: connect_admin)

  • list_connect_instances — Lists Amazon Connect instances available to the caller. boto3: connect.list_instances (paginator). Params: max_items (default 50). Returns ListInstancesResponseinstances[] (instance_id, instance_arn, instance_alias, service_role, instance_status).
  • list_queues — Lists queues in an instance, optionally filtered by queue type. boto3: connect.list_queues (paginator). Params: instance_id (required), queue_types (STANDARD/AGENT), max_items (default 100). Returns ListQueuesResponsequeues[] (queue_id, queue_arn, name, queue_type), has_more_results.
  • list_agents — Lists users (agents) in an instance. boto3: connect.list_users (paginator). Params: instance_id (required), max_items (default 100). Returns ListAgentsResponseagents[] (user_id, user_arn, username), has_more_results. (The tool is named "agents"; the underlying API lists Connect users.)
  • list_routing_profiles — Lists routing profiles in an instance. boto3: connect.list_routing_profiles (paginator). Params: instance_id (required), max_items (default 100). Returns ListRoutingProfilesResponserouting_profiles[] (routing_profile_id, routing_profile_arn, name), has_more_results.

Realtime (module: connect_realtime)

  • get_current_metric_data — Retrieves live operational metrics for an instance. boto3: connect.get_current_metric_data (manual NextToken pagination). Params: instance_id (required), optional queue_idsFilters['Queues'], channels (VOICE/CHAT/TASK) → Filters['Channels'], metrics (defaults to AGENTS_ONLINE, AGENTS_AVAILABLE, AGENTS_ON_CALL, CONTACTS_IN_QUEUE, OLDEST_CONTACT_AGE), groupings (QUEUE/CHANNEL/ROUTING_PROFILE), max_items (default 100). When no queue/channel filter is supplied, channels default to all three. Realtime metric names and groupings are validated against the server's catalog and rejected early. Returns CurrentMetricDataResponseinstance_id, data_snapshot_time, results[] (dimensions + collections of name/unit/value), has_more_results.
  • get_current_agent_status — Retrieves live per-agent status. boto3: connect.get_current_user_data (manual NextToken pagination). Params: instance_id (required), optional queue_idsFilters['Queues'] and agent_idsFilters['Agents'], max_items (default 100). At least one of queue_ids or agent_ids is required at runtime (raises ValueError otherwise). Returns AgentRealtimeStatusResponseinstance_id, agents[] (agent_id, agent_username, status_name, status_start_timestamp, routing_profile_name, available_slots_by_channel, active_contacts), has_more_results.

Historical (module: connect_historical)

  • get_historical_metric_data — Builds historical reports over the last 90 days. boto3: connect.describe_instance (resolve instance ARN) + connect.list_queues (paginator, only when no non-CHANNEL filter is supplied, to default the report to the instance's queues) + connect.get_metric_data_v2 (main call, manual NextToken pagination, looped per 24-hour interval). Params: instance_id (required), start_time/end_time (ISO 8601; default last 24h), metrics (defaults to 15 common metrics incl. CONTACTS_HANDLED, CONTACTS_ABANDONED, AVG_HANDLE_TIME, SERVICE_LEVEL, ABANDONMENT_RATE, AGENT_OCCUPANCY), filters queue_ids/channels/agent_ids/routing_profile_ids, groupings (validated: QUEUE, CHANNEL, ROUTING_PROFILE, AGENT, AGENT_HIERARCHY_LEVEL_ONE..FIVE, CONTACT_REASON, ROUTING_STEP_EXPRESSION), service_level_threshold_seconds (default 120, applied with comparison LT for threshold metrics), max_items (default 100). Behavior: start_time must be before end_time; ranges older than 90 days (MAX_LOOKBACK_DAYS) are rejected; wider ranges are split into consecutive 24-hour intervals (the API per-request limit) and fetched in sequence under a 45-second wall-clock fetch budget that returns partial results with has_more_results=True. Returns HistoricalMetricDataResponseresource_arn, start_time, end_time, interval_count, results[] (dimensions, interval_start, interval_end, metrics of name/value), has_more_results. Results are reported per interval and are not aggregated across intervals (see Out of scope).

Security posture (read-only, least privilege)

All seven tools call only List/Get/Describe operations; no Create/Update/Delete/Put API is invoked, and the server never mutates Connect configuration or contacts. The FastMCP server instructions explicitly state read-only operation. The complete IAM action set required is:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "connect:ListInstances",
        "connect:DescribeInstance",
        "connect:ListQueues",
        "connect:ListUsers",
        "connect:ListRoutingProfiles",
        "connect:GetCurrentMetricData",
        "connect:GetCurrentUserData",
        "connect:GetMetricDataV2"
      ],
      "Resource": "*"
    }
  ]
}

Operators are advised to scope Resource to specific instance ARNs where possible. Credentials are sourced from the standard AWS credential chain (or the optional profile_name) and stay local to the host running the MCP client.

Before / after UX

Before: a supervisor opens the Amazon Connect console or writes a script, manually resolves instance/queue IDs, selects valid metric and grouping names, and (for historical reports) chunks date ranges to satisfy the 24-hour-per-request API limit.

After: the supervisor asks an assistant in natural language, and the assistant chains discovery and reporting tools to answer directly. Examples the server now supports:

  • "How many contacts are in queue right now and what is the oldest contact age?" → list_connect_instances then get_current_metric_data (CONTACTS_IN_QUEUE, OLDEST_CONTACT_AGE).
  • "Which agents on the Support queue are available?" → list_queues + list_agents then get_current_agent_status (scoped by queue).
  • "What were our service level, average handle time, and abandonment rate last week, grouped by queue?" → get_historical_metric_data with a 7-day range auto-split into 24-hour intervals, grouped by QUEUE.

Out of scope

  • No write or administrative mutations. The server provides no tools to create, update, or delete instances, queues, users, routing profiles, flows, or any other Connect configuration, and no tools to initiate, transfer, or modify live contacts. The least-privilege IAM policy contains no mutating actions.
  • No contact-level or interaction content. The server reports aggregated/operational metrics and per-agent status only; it does not retrieve contact records, transcripts, recordings, or customer PII.
  • No metric aggregation across historical intervals. Each 24-hour interval yields its own result rows for every metric; the server performs no cross-interval combination of any metric. Callers must sum count metrics (e.g. CONTACTS_HANDLED) across intervals themselves, and must not naively sum average/rate metrics (e.g. AVG_HANDLE_TIME, SERVICE_LEVEL) — these are only meaningful per interval. This is intentional, to keep values accurate.
  • No data older than 90 days. start_time values beyond the 90-day GetMetricDataV2 retention window are rejected; longer-horizon analytics are out of scope.
  • No additional Connect domains. Capabilities such as Contact Lens analytics, forecasting/scheduling, Customer Profiles, Cases, or Connect API operations not listed above are not included in this proposal.
  • No remote/hosted deployment model. The server is intended to run locally alongside the MCP client using the host's AWS credentials.

Potential challenges

  • API pagination quirk. GetMetricDataV2, GetCurrentMetricData, and GetCurrentUserData are not registered with boto3 paginators, so pagination is driven manually via NextToken (this avoids the OperationNotPageableError fixed in 0.1.1). Only the list_* discovery APIs use native paginators.
  • 24-hour request limit and long ranges. GetMetricDataV2 accepts at most a 24-hour window per request. The historical tool splits wider ranges into consecutive 24-hour intervals and fetches them sequentially; to bound latency it enforces a 45-second wall-clock fetch budget and returns partial results with has_more_results=True rather than blocking. Callers must therefore handle partial responses and per-interval (not aggregated) values.
  • Filter requirements. GetMetricDataV2 requires at least one non-CHANNEL filter key; a CHANNEL-only filter is invalid. To keep the tool usable with minimal input, when no queue/agent/routing-profile filter is supplied the historical tool defaults the report to the instance's queues (up to 100). Similarly, get_current_agent_status requires at least one of queue_ids or agent_ids and raises ValueError if neither is provided.
  • Validation coverage is asymmetric. Realtime metric names and groupings, and historical groupings, are validated against the server's catalog and rejected early. Historical metric names are not pre-validated — unsupported names are surfaced as GetMetricDataV2 API errors rather than caught locally. Aligning historical metric-name validation with the realtime path is a candidate follow-up.
  • Known data-quality items to resolve before/around merge.
    • In get_current_agent_status, _transform_user_data populates the agent_username field from the user's ARN (user.get('Arn')) rather than an actual login name, while the AgentRealtimeStatus.agent_username model field is documented as the login name. This mapping should be corrected (or the field renamed) before release.
    • The server-level instructions string states historical reporting covers "the last 35 days," but the historical tool's actual limit is 90 days (MAX_LOOKBACK_DAYS=90, matching the 0.2.0 changelog and README). This stale instruction text should be updated to 90 days for consistency.
  • Naming clarity. list_agents is backed by connect.list_users; the tool/field naming should be documented clearly so the assistant and operators understand it enumerates Connect users.

Dependencies and Integrations

Package: awslabs.amazon-connect-mcp-server (version 0.2.0). Python >=3.10 (classifiers cover 3.10–3.13). License Apache-2.0. Build backend hatchling.build. Entry point awslabs.amazon-connect-mcp-server = awslabs.amazon_connect_mcp_server.server:main.

Runtime dependencies (from pyproject.toml): boto3>=1.38.22, loguru>=0.7.0, mcp[cli]>=1.23.0, pydantic>=2.10.6. Dev/test tooling: commitizen, pre-commit, ruff, pyright, pytest, pytest-asyncio, pytest-cov, pytest-mock, moto.

Integrations: built on the boto3 connect service client and the standard AWS credential chain (with optional per-call region/profile_name and environment AWS_REGION/AWS_PROFILE). Targets MCP clients such as Amazon Q and Kiro, registered via uvx awslabs.amazon-connect-mcp-server@latest. Multi-region and multi-profile usage is supported. The server is already scaffolded to the AWS Labs server layout, and the README will be cross-linked from the root README's "Browse by What You're Building" and "Browse by How You're Working" sections per CONTRIBUTING.md.

Alternative solutions

  • Console / scripts only (status quo). Continue using the Amazon Connect console or bespoke boto3 scripts. This works but requires manual ID resolution, metric/grouping selection, and date-range chunking, and offers no natural-language interface for operational staff.
  • Fold Connect reporting into an existing AWS Labs server. There is no existing server covering Amazon Connect realtime/historical reporting, and these APIs form a coherent, self-contained domain. A dedicated server keeps scope clear, allows a minimal Connect-only IAM policy, and matches the repo's pattern of one task-oriented server per service domain.
  • Expose raw, ungrouped Connect APIs as thin pass-throughs. Rejected in favor of task-oriented tools (Discovery / Realtime / Historical) that apply sensible metric defaults, validate inputs where practical, and transparently handle the 24-hour interval splitting — consistent with sibling servers (e.g. cloudwatch-mcp-server) that encapsulate one or more APIs into task-oriented operations.

Metadata for admin purposes (left empty):

  • RFC PR:
  • Approved by: ''
  • Reviewed by: ''

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions