Skip to main content

agentic


Agentic Domain

The Agentic domain manages the lifecycle of MCP (Model Context Protocol) servers within the Control Plane — from server registration through exposure to subscription. It acts as an abstraction layer above the Gateway domain, handling business logic for who can access which MCP servers and under what conditions.

Custom Resources​

ResourcePurpose
McpServerRegisters an MCP server endpoint for a given basePath. Created and owned by the Rover domain via McpSpecification. Only the oldest active McpServer per basePath is considered active.
McpExposureExposes an active McpServer on the AI Gateway by creating gateway Routes. Only one McpExposure per basePath can be active at a time (oldest-wins).
McpSubscriptionRequests access to an MCP exposure. Triggers an approval workflow; once approved, a ConsumeRoute is created on the gateway.

Reconciliation Flow​

rover-ctl apply mcpspec.yaml
│
├──▶ McpSpecification created (rover domain)
│ └──▶ McpServer created (registered)
│
├──▶ McpExposure created (by exposing team)
│ └──▶ AI Gateway Route(s) provisioned
│
└──▶ McpSubscription created (by subscribing team)
│
├──▶ Approval created (if strategy ≠ auto)
├──▶ Approval granted
└──▶ Gateway ConsumeRoute created (access granted)

Subscription Approval Scopes​

An AgenticSubscription approval request includes the requested spec.security.m2m.scopes in its properties, following the API subscription approval flow. These properties determine the request identity, so changing the requested scopes creates a distinct approval request. The configured approval strategy applies to that new request, including automatic approval where configured.

While the new request is pending or rejected, the existing ConsumeRoute remains unchanged. The controller updates its scopes once approval is granted for the new request. Rejecting or suspending the Approval itself removes the ConsumeRoute.

Route Provisioning​

When an McpExposure is reconciled, the Agentic operator provisions gateway Routes on the AI Gateway:

Route createdWhenLocation
Primary routeAlways — one per exposureProvider's zone namespace
Proxy routeFor each zone with an approved cross-zone subscription, and for the Telecontext Application's zone (TELECONTEXTMCP only)Proxy zone namespace, upstream = provider zone's AI Gateway

After approval, an AgenticSubscription publishes the path-specific AI Gateway URL in its status. The Projector persists this value and exposes it as gatewayURL on the GraphQL AgenticSubscription type.

Subscription Readiness​

AgenticSubscription uses the shared Ready condition reason vocabulary used by API subscriptions. The condition message provides the specific cause.

Ready statusReasonMeaning
TrueProvisionedSubscription provisioning completed.
FalsePreconditionNotMetAn active server, ready exposure, required route reference, or AI Gateway feature is unavailable.
FalseValidationFailedThe base path has a case conflict, or requested OAuth2 scopes are invalid or undefined by the server.
FalseAccessDeniedVisibility rules disallow the subscription, or its approval or approval request was denied.
FalseApprovalPendingAn approval decision is pending.
FalseProcessingA previously pending approval was granted; provisioning is in progress.
FalseSubResourceNotReadyThe child-resource readiness check has not passed.

Once approval is granted, a previous ApprovalPending reason is cleared before provisioning continues, including when a subsequent provisioning operation fails.

The child-resource readiness check reports Ready=False / SubResourceNotReady when a condition-bearing resource created or updated during reconciliation, including the ApprovalRequest or ConsumeRoute, explicitly reports Ready=False. This check does not reject missing or unknown Ready conditions and does not check child ObservedGeneration.

Cross-Zone Meshing​

When subscribers exist in a different zone than the exposure, the operator creates a proxy Route in the subscriber's zone. That proxy gateway stamps a Last-Mile-Security (LMS) token when forwarding traffic to the provider zone. The primary route therefore adds the subscriber zone's LmsIssuer to its TrustedIssuers so that forwarded requests are accepted.

Forwarded requests arrive at the primary route as the gateway mesh client (gateway consumer), so the primary route allows this consumer as soon as at least one proxy route exists. The proxy routes themselves do not allow the gateway consumer: they are the source of the mesh hop, not its target. Subscribers access their zone's proxy route through their ConsumeRoute.

The primary route's TrustedIssuers are composed as follows:

  • Exposure zone's IDP issuer — only when there are local callers: at least one local (same-zone) subscriber, or the Telecontext Application in the exposure zone (TELECONTEXTMCP only)
  • LMS issuers from each cross-zone proxy gateway — for mesh-forwarded traffic from proxy zones (subscriber zones and the Telecontext zone)

Variants​

An McpExposure can declare a spec.variant that changes how access is provisioned:

MCP (default)​

Standard exposure. The AI Gateway Route is created with normal access control. Consumers gain access by subscribing and having a ConsumeRoute provisioned.

TELECONTEXTMCP​

Used for MCP servers that should be accessible by the Telecontext platform consumer without going through the standard subscription/approval flow.

How it works: When spec.variant: TELECONTEXTMCP is set on an McpExposure, the operator resolves the Telecontext Application using a platform-level configuration (AGENTIC_TELECONTEXT_APPLICATION_ID, format: group--team--appName). From this, the operator:

  1. Looks up the Application CR to discover its zone and uses its status.clientId (group--team--appName) as the consumer name. This is the name of the Application's gateway consumer and its ACL group, and the same value that subscriptions use for their ConsumeRoutes.
  2. Adds the consumer to spec.security.defaultConsumers of the Route that the Telecontext Application calls directly, giving it pre-authorized access without a ConsumeRoute or approval flow:
    • Telecontext in another zone: the proxy route in the Telecontext zone. The operator creates this proxy route even if no regular subscribers exist in that zone. The primary route does not get the consumer, because mesh-forwarded traffic arrives there as the gateway consumer.
    • Telecontext in the exposure zone: the primary route. The primary route then also trusts the exposure zone's own IDP issuer, even without local subscribers.
  3. Trusts the Telecontext zone's LMS issuer on the primary route if the Telecontext Application is in another zone, so mesh-forwarded traffic from the Telecontext zone is accepted

Subscribers in other zones keep their own proxy routes, which only allow the subscribers' ConsumeRoute consumers. If the Telecontext zone is also a subscriber zone, the operator creates a single proxy route for that zone.

If the Telecontext Application does not exist, is not ready, or has no client ID, the exposure is blocked. The operator does not change the existing routes and keeps them in the exposure status, so subscriptions keep their route reference. The exposure controller does not watch Applications, so a Telecontext Application that becomes ready later is picked up at the next periodic reconcile.

This mirrors how the legacy Java controlplane handled Telecontext integration: iterating all zones and creating proxy routes where the Telecontext Application is located, plus granting access via a dedicated RoutePermission (now replaced by the DefaultConsumers mechanism).

Why not a ConsumeRoute? A ConsumeRoute is namespace-scoped and goes through the approval flow. DefaultConsumers is a gateway-level bypass that is more appropriate for a trusted platform component that needs seamless, always-on access to TeleMCP servers across the whole platform.

McpExposure (variant: TELECONTEXTMCP)
│
├──▶ Resolve Application (from AGENTIC_TELECONTEXT_APPLICATION_ID)
│ └──▶ Get zone + status.clientId (e.g. mcp--telecontext--tcapp)
│
├──▶ AI Gateway Route (proxy, one per subscriber zone + Telecontext zone — if different)
│ ├──▶ upstream = exposure zone's AI Gateway
│ └──▶ spec.security.defaultConsumers:
│ - mcp--telecontext--tcapp (only on the proxy route in the Telecontext zone)
│
└──▶ AI Gateway Route (primary, on exposure zone)
├──▶ spec.security.defaultConsumers:
│ - gateway (if any proxy route exists)
│ - mcp--telecontext--tcapp (only if Telecontext is in the exposure zone)
└──▶ spec.security.trustedIssuers:
- exposure zone's IDP issuer (if local subscribers exist or Telecontext is in the exposure zone)
- LMS issuer of each proxy zone

The AGENTIC_TELECONTEXT_APPLICATION_ID value is injected at operator startup via environment variable and must be configured for environments that support the TELECONTEXTMCP variant.

Domain Interactions​

  • Rover domain — Creates McpSpecification which owns the McpServer. McpExposure and McpSubscription are also created from rover configuration.
  • Gateway domain — The Agentic operator creates Route (primary, proxy) and ConsumeRoute resources on the AI Gateway.
  • Admin domain — Zones provide the AI Gateway reference, preset URLs, and identity issuers used to wire up routes and mesh trust.
  • Approval domain — Subscriptions trigger approval workflows before ConsumeRoute is created.
  • Projector / ControlPlane API — The Projector syncs McpServer, AgentCard, AgenticExposure (from McpExposure), and AgenticSubscription (from McpSubscription) into PostgreSQL, making the agentic catalogue and subscription state queryable via GraphQL. See ControlPlane API & Projector.

The AI Gateway​

The AI Gateway is a regular zone gateway that an AI-typed preset points at:

# Excerpt: spec.gateways and spec.presets only. A complete Zone also needs
# visibility and identityProviders — see Environments and Zones below.
spec:
gateways:
- name: standard
admin:
identityProviderRef: primary
url: https://gateway-admin.example.com
- name: ai
admin:
identityProviderRef: primary
url: https://ai-gateway-admin.example.com
presets:
# Every zone needs an API preset: it is the representative profile for
# callers that carry no traffic type of their own.
- name: default
type: API
default: true
gatewayRef: standard
identityProviderRef: primary
urls:
- hostname: api.gateway.example.com
basePath: /
- name: ai
type: AI
default: true
gatewayRef: ai
identityProviderRef: primary
urls:
- hostname: ai.gateway.example.com
basePath: /

The type lives on the preset, not on the gateway: a gateway serves the union of the types of the presets referencing it. The two presets above could equally point at the same gateway, which is how you run agentic and API traffic on one gateway instance. The Agentic operator resolves its routes through the AI preset of the zone; a zone with no AI preset rejects agentic exposures and subscriptions during Rover validation. See Environments and Zones for the full traffic type reference and the rules the admission webhook enforces.