官方更新 AWS ML Blog Thu, 29 Oct 2026 正文 ok 2741 words

MoEngage 如何借助 AgentCore Gateway 将 400 多个内部 API 转变为 Agent 工具

英文标题:How MoEngage turned over 400 APIs into agent tools with AgentCore Gateway

MoEngage 在 7 个 AWS 区域内拥有由 25 个团队维护的约 400 个私有 REST API,在构建 AI Agent 时面临避免公网暴露、防止模型篡改身份以及多达 400 个工具导致上下文窗口溢出等核心挑战。MoEngage 没有选择为每个服务单独搭建 MCP 服务器,而是基于 Amazon Bedrock AgentCore Gateway、Cedar 策略引擎与 Amazon VPC Lattice,直接由 OpenAPI 规范全自动生成受权限管控的 Agent 工具。该方案为 MoEngage 节省了约 6 个月的平台工程研发工作量,将新 API 的接入耗时从数天压缩至数小时,为大型企业安全落地 Agent 工具调用提供了极具参考价值的架构范式。
打开原文相关 5.4 · 机会 5
media1.3 MB media1.3 MB media2.4 KB media345.0 KB media141.2 KB media346.5 KB media254.1 KB media22.0 KB media23.1 KB media17.9 KB media16.5 KB media227.8 KB

中文

本文由 MoEngage 的 Nikhil Kumar 和 Shakir Khan 共同撰写。

当工程团队着手构建 AI Agent 时,这些 Agent 所需的能力通常早已作为内部 API 存在——例如活动创建、受众分群查询、送达率统计等。真正的挑战不在于构建新功能,而在于如何在不向公共互联网暴露接口、不将身份控制权交给模型,且不让数百个工具定义挤爆上下文窗口的前提下,让 Agent 能够安全地调用这数百个私有 API。

作为服务于 1350 多个消费品牌、跨推送通知、电子邮件、应用内消息、短信、WhatsApp 和 RCS 提供个性化体验的 Agent 化客户互动平台,MoEngage 正面临着这一难题。在产品背后,运行着由 25 个工程团队构建的约 400 个内部 REST API,它们分布在 7 个 AWS 区域的私有虚拟私有云(VPC)中。MoEngage 在区域层面隔离了这些 API 以满足数据驻留承诺,并且绝不向公共互联网暴露。Agent 所需的能力已经在生产环境中稳定运行,如何让它安全可达,才是最棘手的部分。

在本文中,我们将深入探讨 MoEngage 如何利用 Amazon Bedrock AgentCore 的核心功能 AgentCore Gateway,将这些私有 API 转化为具有权限作用域的 Agent 工具。该方案为 MoEngage 节省了预估 6 个月的平台工程工作量,如今接入一个新 API 仅需数小时,而非数天。没有业务团队需要编写 Model Context Protocol(MCP)服务器代码,无需为每个集成单独配置网络,整个调用链路中也不存在任何公共端点。

为什么部署 20 多个 MCP 服务器是错误的解法

Model Context Protocol(MCP)为 Agent 提供了一种发现和调用工具的标准机制。采用它的最直接路径是让每个团队暴露自己的 MCP 服务器。MoEngage 对此进行了成本测算,并最终否决了该方案。

维护 20 多个 MCP 服务器意味着要有 20 多个部署需要监控、打补丁,并在 MCP 演进过程中保持协议兼容。跨领域 Agent(那些需要读取营销活动、核对分群并检查投递数据的实用 Agent)将不得不连接到多个服务器并处理兼容对齐问题。此外,每个团队都被迫去学习与自身业务无关的 MCP 专业知识。

因此,MoEngage 确立了一条奠定后续所有架构决策的核心原则:业务工程团队不实现 MCP。团队只负责构建 REST API 并声明哪些操作应当作为工具;AI 平台团队端到端全权负责 MCP 层。业务团队的职责边界止于一份描述完备的 OpenAPI 规范。

该原则随即带来了三项硬性要求:

  1. 一个集中的工具暴露面,供 Agent 统一连接,而非按服务逐一连接;
  2. 在服务端强制执行针对单 Agent 的细粒度授权,而非依赖客户端约定;
  3. 无需为每个新 API 重复搭建的私有网络连通能力。

从零自研所有组件也是一种选择。自研一个中央 MCP 服务器确实可以解决“20 个服务器”的运维碎片化问题,但这将导致 MoEngage 必须自行研发工具生成流水线、策略文件格式、用于重命名的工具别名注册中心以及熔断机制。所有这些都是定制代码,全由一个团队背负,并且全都属于无法让 MoEngage 的 Agent 变得更聪明、也无法让客户的营销活动变得更好的无差异重活。

决定架构形态的四大约束条件

在评估任何解决方案之前,MoEngage 明确了四项约束条件。这四项必须同时满足,任何只能解决其中两个却破坏另外两个的方案都不可行。

绝不暴露任何公共端点。 根据安全策略,MoEngage 的内部 API 严格限定在 VPC 私有网络内。任何需要将其公开发布(哪怕有额外认证鉴权层)的方案都是不可接受的。传统的变通做法是为每个集成单独搭建网络:这里放一个 NAT 网关,那里放一个反向代理,第三处建一条 VPN 隧道。一旦乘以 7 个区域,运维面的膨胀速度将远快于 Agent 数量的增长。每一个新 API 都意味着一份新的网络变更申请、又一轮安全审查以及另一项需要维护的基础设施。

身份凭证绝不能由 Agent 决定。 每次内部 API 调用都携带着租户、用户、角色和数据库上下文。如果将这些上下文作为大语言模型(LLM)可见的工具参数,模型就可能填错,甚至可能被 Prompt 注入诱骗篡改。MoEngage 需要在结构上将身份信息置于模型不可触及的范围之外,由调用方服务直接注入,绝不能暴露为模型可以设置或覆盖的内容。

400 个工具的完整目录无法塞入上下文窗口。 每个工具的 JSON schema 大约占用 50 个 token,跨整个资产目录执行一次完整的 tools/list,每次连接就会传输超过 20,000 个 token。甚至在 Agent 开始执行任何实质任务之前,这部分 token 预算就已经被耗尽,并且会挤占 Agent 真正用于任务推理所需的上下文空间。客户端过滤(如 ADK 或 MCP SDK 中的 tool_filter)无法解决这个问题——因为完整目录已经通过网络传输完毕,且按客户端约定过滤并不构成授权边界。一个本不应看到写操作的 Agent,从一开始就不应该接收到这些操作的定义。

正是最后这项约束排除了那些显而易见的替代方案。自研中央 MCP 服务器虽能解决 20 个服务器的分散问题,却依然需要 MoEngage 维护一整套工具生成流水线、策略格式、别名注册表和熔断器——全部是自研代码,全部压在单一团队肩上,且对提升产品核心竞争力毫无助益。

AgentCore Gateway 如何匹配这些约束

Amazon Bedrock AgentCore Gateway 是一个全托管的 MCP 服务器。你只需将 OpenAPI 规范注册为 Target,Gateway 就会从中生成 MCP 工具,并将调用路由到底层后端服务。它的四项特性与 MoEngage 的约束完美契合:

输入 OpenAPI,输出 MCP 工具。 无需构建或运维 MCP 服务器,也不需要维护与 API 保持同步的额外工件。团队现有的 API 规范就是工具定义。每个操作都会转化为名为 Target___operationId 的工具,例如 CampaignsAPI___searchCampaigns。规范变更,工具即刻变更;团队新增端点,工具立即出现;团队删除端点,工具随即下线。无需部署,无需掌握协议细节,更无需与 AI 平台团队沟通协调。

在目录序列化前评估 Cedar 策略。 AgentCore 策略引擎利用偏特化求值(Partial Evaluation)针对每个调用主体过滤 tools/list。每个 Agent 都以独立的 IAM 角色进行身份验证,其关联的 Cedar 策略决定了它可以查看和调用哪些工具。这使得支撑 400 个工具成为可能——它绝非事后的客户端过滤,而是在构建响应前完成的服务端作用域裁剪。

例如,一个营销活动质检 Bot(Campaign QA Bot)只拥有对活动与分群工具的读取权限,无法调用写操作:

cedar permit( principal == Agent::"campaign-qa-bot-v1", action == Action::"tools/call", resource in ToolGroup::"campaigns-read" );

forbid( principal == Agent::"campaign-qa-bot-v1", action == Action::"tools/call", resource in ToolGroup::"write-actions" );

该 Bot 在其 tools/list 响应中根本看不到写工具。客户端无需进行任何过滤,因为这些工具压根就没有下发。

基于 Amazon VPC Lattice 的托管出站(Managed Egress)。 Gateway 通过 AgentCore 托管出站访问 MoEngage 的内部服务,无需 MoEngage 亲自搭建和维护复杂的网络链路。入站方面,Gateway 仅能通过带有私有 DNS 的 VPC 接口端点(Interface Endpoint)访问,全程没有公网路径。接入新 API 只需要增加一个 Target,而无需更改网络拓扑。正是这一特性彻底破除了“乘以 7 个区域”的网络复杂性恶梦:网络设施只需构建一次,所有 API 均可复用。

作为 Gateway 原生能力的语义搜索。 借助 x_amz_bedrock_agentcore_search 能力,Agent 可以通过描述任务来查找工具,而无需预先知晓工具名称。这省去了自建发现层的需要,并顺带消除了因接口重命名导致的脆弱性:如果 get_segment_user_count 更名为 get_segment_size,搜索“分群用户数量(segment user count)”的 Agent 依然能够命中它,因为匹配依据是语义描述而非标识符字面量。

落地架构实践

从 Agent 到内部 API 的请求链路非常简短,且每一层都有明确的职责分工。Agent 服务通过 VPC 接口端点连接到 AgentCore Gateway,Gateway 负责评估 Cedar 策略,并通过基于 Amazon VPC Lattice 的托管出站将工具调用路由至内部 API。

下图展示了各组件的连接方式:

AgentCore Gateway 架构:Agent 服务通过私有 VPC 接口端点访问 Gateway,Gateway 评估 Cedar 策略并通过 Amazon VPC Lattice 将调用路由至内部 API

图 1:MoEngage AgentCore Gateway 架构

运行在 Amazon Elastic Compute Cloud(Amazon EC2)或容器内的 Agent 服务负责调用 MCP 客户端。客户端可以是官方 MCP SDK、LangChain、Google ADK 或 MoEngage 自研的 Agent 运行器。客户端使用该服务已有的 AWS Identity and Access Management(IAM)角色通过 SigV4 对请求进行签名。请求通过 HTTPS 传输至带有私有 DNS 的 VPC 接口端点,全程没有任何公网跳转。AgentCore Gateway 接收请求并评估 Cedar 策略以确定该主体有权查看或调用的内容,随后通过基于 Amazon VPC Lattice 的托管出站将工具调用路由给内部 API。

MoEngage 的两项认证决策值得借鉴:

首先,在内部网关中选择了 SigV4 而非 JWT。这里的 Agent 是本身就拥有 IAM 角色的后台服务。借助 SigV4,它们可以直接使用现有凭证签名,无需签发、轮转或存储任何新凭据。而 MoEngage 独立的公共 MCP 服务器(用于服务来自 Claude 及其他客户端的人工认证会话)则在 AgentCore 运行时上使用 OIDC JWT。那是具有不同需求的独立受信任面。

其次,身份信息作为请求头传递,而非工具参数。租户、用户、角色及数据库上下文由客户端库从轻量的 Identity 对象转换为 X-MOE-* 系列请求头。模型看不到这些信息,更无法篡改它们。在类似构建中需要注意的一个技术细节是:由于 SigV4 签名占用了 Authorization 头,调用方传递的 Bearer Token 必须转移至其他位置。MoEngage 将其封装在专用的 MoEngage 前缀请求头中进行传递。同时限制了请求头透传上限,确保请求头集合始终处于明确管控之下而非无限累积。

工具发现和执行遵循不同的身份要求:列举和搜索工具不携带租户身份,只有 tools/call 才会携带。这种隔离保证了发现操作的高效轻量,并确保了审计追踪链路的清晰透明——每一个携带身份信息的请求都是一次真实的业务数据访问。

即使 Cedar 策略已将 Agent 限制在目录的子集内,该子集的规模有时依然庞大。MoEngage 的客户端库向模型仅暴露一个元工具(Meta-tool):search_tools。模型描述自身需求,Gateway 的语义搜索返回候选工具,而在本轮对话的剩余交互中,仅有这些被检索出的候选工具变为可调用状态。完整目录不会涌入上下文;Agent 在对话开始时上下文中仅包含一个工具定义,在搜索后仅包含少数相关工具定义,彻底摆脱了充斥数百个无关工具定义的困扰。

接入新 API 的流程

业务团队若想将 API 暴露为 Agent 工具,只需在其现有 OpenAPI 规范中添加一个代码块:

yaml paths: /campaigns: get: operationId: listCampaigns description: | Returns a paginated list of campaigns. Supports filtering by status, channel, date range, and tags. x-moe-mcp: expose: external: false internal: true tool_description: | Find campaigns by status or channel. Returns campaign ID, name, status, and channel. Use the returned campaign_id with get_campaign for full details, or send_campaign to launch it. param_overrides: status: description: | Filter by campaign status. Use 'active' for running campaigns, 'scheduled' for upcoming. Omit for all.

该配置块蕴含了四项关键设计决策:

暴露机制必须显式声明(Opt-in)。 没有包含 x-moe-mcp 块的端点绝不会成为工具。持续集成(CI)流水线不会因缺少该配置而发出告警,因为对于大多数端点而言,不暴露才是正确的状态。缓存预热路由或数据迁移触发器根本不是 Agent 工具,不应引导团队将其工具化。借助 internal 和 external 标志,团队可以独立将操作暴露给内部 Agent、公网 MCP 服务器,或两者兼具。

工具描述不等于 API 描述。 API 描述是给查阅文档的开发者看的,告知端点返回什么数据;工具描述则是给模型看的,指导模型何时该选用该工具以及应该传递什么参数。MoEngage 发现,原样复用 API 描述会导致工具选取表现极差。模型往往会根据实现细节(如“返回分页列表”)而非业务意图(如“按状态或渠道查找营销活动”)来挑选工具。tool_description 和 param_overrides 字段的设立,正是为了给团队提供编写面向模型提示语的专用空间,而无需破坏面向开发者的既有文档。

CI 流水线自动化打通从规范到在线运行工具的全流程。 当团队推送规范变更时,CI 流水线会自动校验 x-moe-mcp 代码块,将 Target 注册到 AgentCore Gateway,并应用对应的 Cedar 策略。无需人工操作,无需向 AI 平台团队提交工单。一个对 MCP 一无所知的业务团队,在流水线跑完的时间内即可完成将现有 API 操作上线为 Agent 工具的全过程。

客户端工具管理...

English / 原文

This post was co-written with Nikhil Kumar and Shakir Khan from MoEngage.

When engineering teams start building AI agents, the capabilities those agents need usually already exist as internal APIs. Campaign creation, segment queries, delivery stats. The challenge isn’t building new functionality. The challenge is making hundreds of private APIs safely reachable by agents without exposing them to the public internet, without giving models control over identity, and without flooding context windows with hundreds of tool definitions.

MoEngage, the agentic customer engagement platform that more than 1,350 consumer brands use to deliver personalized experiences across push, email, in-app, SMS, WhatsApp, and RCS, faced exactly this problem. Behind the product sit roughly 400 internal REST APIs, built by 25 engineering teams, running in private virtual private clouds (VPCs) across seven AWS Regions. MoEngage isolates these APIs regionally to meet data residency commitments and doesn’t expose them to the public internet. The capability the agents needed was already running in production. Making it reachable, safely, was the hard part.

In this post, we walk through how MoEngage used AgentCore Gateway, a capability of Amazon Bedrock AgentCore, to turn those private APIs into permission-scoped agent tools. The approach saved MoEngage an estimated six months of platform engineering effort, and onboarding a new API now takes hours instead of days. No product team wrote Model Context Protocol (MCP) server code, no networking was provisioned per integration, and no public endpoint exists anywhere in the path.

Why 20 MCP servers was the wrong answer

The Model Context Protocol (MCP) gives agents a standard way to discover and call tools. The straightforward path to adopting it is for each team to expose its own MCP server. MoEngage costed that out and rejected it.

Over 20 MCP servers means over 20 deployments to monitor, patch, and keep protocol-compatible as MCP evolves. Cross-domain agents, the useful ones that read a campaign, check its segment, and inspect delivery stats, would need to connect to several servers and reconcile them. And every team would need MCP expertise unrelated to its actual product work.

So MoEngage established the principle that shaped everything that followed: Individual engineering teams do not implement MCP. Teams build REST APIs and declare which operations should be tools. The AI Platform team owns the MCP layer end to end. A team’s responsibility ends at a well-described OpenAPI spec.

That principle immediately created three requirements: a central tool surface that agents connect to once rather than per-service, per-agent authorization enforced server-side rather than by convention, and private connectivity that does not need to be rebuilt for every new API.

Building all of this from scratch was an option. A custom central MCP server would solve the 20-servers problem but leave MoEngage building a tool-generation pipeline, a policy file format, a tool-alias registry for renames, and circuit breakers. All custom code, all owned by one team, all of it undifferentiated work that does not make MoEngage’s agents smarter or its customers’ campaigns better.

Four constraints that shaped the architecture

Before evaluating any solution, MoEngage defined four constraints. All four had to be met simultaneously. A solution that addressed two but broke the third and fourth was not viable.

Nothing gets a public endpoint. MoEngage’s internal APIs are VPC-private by policy. Any solution that required exposing them, even behind additional authentication, was a non-starter. The conventional workaround is per-integration networking: a NAT gateway here, a reverse proxy there, a VPN tunnel for the third one. Multiply that by seven Regions and the operational surface grows faster than the set of agents does. Every new API would mean another networking change request, another set of security reviews, another piece of infrastructure to maintain.

Identity can’t be an agent’s decision. Every internal API call carries tenant, user, role, and database context. If that context is a large language model (LLM)-visible tool parameter, a model can get it wrong or be talked into changing it. MoEngage needed identity to be structurally out of the model’s reach, injected by the calling service and not surfaced as something the model can set or override.

A 400-tool catalog doesn’t fit in a context window. At roughly 50 tokens of JSON schema per tool, a full tools/list across the estate is over 20,000 tokens transmitted on every connection. That token budget is spent before the agent does anything useful, and it crowds out the context the agent actually needs to reason about the task. Client-side filtering (tool_filter in ADK or the MCP SDK) doesn’t fix this. The full catalog has already crossed the wire, and filtering by client convention isn’t an authorization boundary. An agent that is not supposed to see write operations shouldn’t receive them in the first place.

That last constraint is the one that avoided the obvious alternatives. A custom central MCP server solves the 20-servers problem but still leaves MoEngage building a tool-generation pipeline, a policy file format, a tool-alias registry for renames, and circuit breakers. All custom code, all owned by one team, none of it making MoEngage’s product better.

How AgentCore Gateway maps to those constraints

Amazon Bedrock AgentCore Gateway is a fully managed MCP server. You register OpenAPI specs as targets and the gateway generates MCP tools from them, then routes calls to the backing services. Four properties mapped directly onto MoEngage’s constraints.

OpenAPI in, MCP tools out. There’s no MCP server to build or operate, and no separate artifact to keep in sync with the API. The spec teams already maintain is the tool definition. Each operation becomes a tool named Target___operationId, for example CampaignsAPI___searchCampaigns. When the spec changes, the tool changes. When a team adds an endpoint, the tool appears. When a team removes one, the tool disappears. No deployment, no protocol expertise, no coordination with the AI Platform team.

Cedar policies, evaluated before the catalog is serialized. The AgentCore policy engine uses partial evaluation to filter tools/list per principal. Each agent authenticates as its own IAM role, and its Cedar policy determines which tools it can see and call. This is what makes 400 tools tractable. It isn’t client-side filtering after the fact, but server-side scoping before the response is built.

A campaign QA bot, for example, gets read access to campaign and segment tools but can’t call a write operation:

permit(
    principal == Agent::"campaign-qa-bot-v1",
    action == Action::"tools/call",
    resource in ToolGroup::"campaigns-read"
);

forbid(
    principal == Agent::"campaign-qa-bot-v1",
    action == Action::"tools/call",
    resource in ToolGroup::"write-actions"
);

The bot doesn’t see write tools in its tools/list response. There’s nothing to filter on the client side because the tools weren’t sent.

Managed egress over Amazon VPC Lattice. The gateway reaches MoEngage’s internal services through AgentCore managed egress rather than through networking MoEngage builds and operates. Inbound, the gateway is reachable only through a VPC interface endpoint with private DNS. There’s no public path to it. Onboarding a new API adds a target, not a network topology change. This is the property that broke the multiply by seven Regions problem. The networking exists once and every API uses it.

Semantic search as a gateway capability. With the x_amz_bedrock_agentcore_search capability, an agent can find tools by describing the task instead of naming the tool. It removed the need for a custom discovery layer. It also removed rename fragility as a side effect: if get_segment_user_count becomes get_segment_size, an agent searching for segment user count still finds it, because matching happens on description rather than identifier.

The architecture in practice

The request flow from agent to internal API is short, and every layer has a specific job. Agent services connect through a VPC interface endpoint to AgentCore Gateway, which evaluates Cedar policies and routes tool calls through managed egress over Amazon VPC Lattice to internal APIs.

The following diagram shows how the components connect.

AgentCore Gateway architecture: agent services reach the gateway through a private VPC interface endpoint, which evaluates Cedar policies and routes calls over Amazon VPC Lattice to internal APIs

Figure 1: MoEngage AgentCore Gateway architecture

An agent service running on Amazon Elastic Compute Cloud (Amazon EC2) or in a container calls the MCP client. The client can be the official MCP SDK, LangChain, Google ADK, or MoEngage’s own agent runner. The client signs the request with SigV4 using the AWS Identity and Access Management (IAM) role the service already has. The request travels over HTTPS to a VPC interface endpoint with private DNS. There’s no public hop. AgentCore Gateway receives the request and evaluates Cedar policies to determine what this principal can see or call. It then routes tool invocations through managed egress over Amazon VPC Lattice to the internal API.

MoEngage made two authentication decisions worth calling out.

First, they chose SigV4 over JWT for the internal gateway. Agents here are services that already have IAM roles. With SigV4, they can sign with credentials they already have. Nothing new to issue, rotate, or store. MoEngage’s separate public MCP server, which serves human-authenticated sessions from Claude and other clients, uses OIDC JWTs on AgentCore runtime. That is a different surface with different requirements.

Second, identity travels as headers, not as tool arguments. Tenant, user, role, and database context are converted by the client library from a small Identity object into X-MOE-* headers. The model doesn’t see them and can’t set them. One detail matters for anyone building something similar: Because SigV4 signing occupies the Authorization header, caller-forwarded bearer tokens must move elsewhere. MoEngage propagates it as a dedicated MoEngage-prefixed header. Header propagation is also capped, so the set of headers is deliberate rather than accumulated.

Discovery and execution have different identity requirements. Listing and searching tools carries no tenant identity. Only tools/call does. That separation keeps discovery cheap and makes the audit trail unambiguous. Every identity-bearing request is an actual data access.

Even with Cedar scoping an agent to a subset of the catalog, the subset can be large. MoEngage’s client library exposes a single meta-tool, search_tools, to the model. The model describes what it needs, the gateway’s semantic search returns candidates, and only those candidates become callable for the rest of the turn. The full catalog doesn’t enter context. The agent’s context contains one tool definition at the start and a handful of relevant ones after a search, instead of several hundred definitions it will never use.

Onboarding a new API

A team exposing an API as an agent tool adds a block to its existing OpenAPI spec:

paths:
  /campaigns:
    get:
      operationId: listCampaigns
      description: |
        Returns a paginated list of campaigns. Supports filtering by
        status, channel, date range, and tags.
      x-moe-mcp:
        expose:
          external: false
          internal: true
        tool_description: |
          Find campaigns by status or channel. Returns campaign ID, name,
          status, and channel. Use the returned campaign_id with
          get_campaign for full details, or send_campaign to launch it.
        param_overrides:
          status:
            description: |
              Filter by campaign status. Use 'active' for running
              campaigns, 'scheduled' for upcoming. Omit for all.

Four design choices in that block are worth explaining.

Exposure is explicit opt-in. An endpoint with no x-moe-mcp block is not a tool. Continuous integration (CI) does not warn about its absence, because for most endpoints absence is the correct state. Cache-warmup routes and migration triggers are not agent tools, and nothing should nudge a team toward making them one. With the internal and external flags, a team can expose an operation to internal agents, to the public MCP server, or to both, independently.

Tool descriptions aren’t API descriptions. An API description tells a developer reading docs what an endpoint returns. A tool description tells a model when to reach for this tool and what to pass. MoEngage found that reusing API descriptions verbatim led to poor tool selection. Models picked tools based on implementation detail (“Returns a paginated list”) rather than intent (“Find campaigns by status or channel”). The tool_description and param_overrides fields exist specifically to give teams a place to write model-facing text without changing their developer-facing docs.

The CI pipeline handles everything from spec to running tool. When a team pushes a spec change, the pipeline validates the x-moe-mcp block, registers the target with AgentCore Gateway, and applies the Cedar policy. No manual steps, no tickets to the AI Platform team. A team that has never thought about MCP can have an operation available as an agent tool in the time it takes the pipeline to run.

The client library comes in two modes. A plug-in mode wraps the AgentCore Gateway MCP server inside LangChain, Google ADK, or an MCP-compatible framework as a tool provider. An agent runner mode runs a complete agent loop for teams that want a standalone agent without adopting a framework.

What MoEngage runs today

MoEngage’s AgentCore Gateway deployment runs in seven AWS Regions today. The gateway serves roughly 400 registered API operations to 10 internal agents. No product team has written MCP server code. No product team has provisioned networking for an agent integration. No product team has implemented Cedar policies. The AI Platform team owns all of that, and the cost of onboarding a new API is a spec annotation and a CI run. AgentCore feature availability varies by Region. For supported Regions, see the Amazon Bedrock AgentCore documentation.

The system has been running in production for three months. The agents span the workflow a marketing team member touches daily. A campaign QA agent validates targeting rules and content before launch. A delivery health agent monitors send rates and bounce patterns across channels. A segment builder agent translates natural-language audience descriptions into segment queries. Each agent authenticates with its own IAM role, sees only the tools its Cedar policy permits, and discovers tools by describing the task rather than memorizing tool names. By removing the need to build and operate 20 separate MCP servers and provision per-API networking across seven Regions, MoEngage estimates the approach saved approximately six months of engineering effort. Onboarding a new API now takes hours of spec annotation instead of days of networking provisioning and security review.

The search-first pattern changed how MoEngage thinks about agent design. New agents start with zero hardcoded tool references. They describe intent, receive candidates, and call what they find. When a team renames an operation or ships a new one, existing agents pick it up without a code change.

Conclusion

The key insight behind MoEngage’s approach is a separation of concerns that maps to how engineering organizations actually work. Product teams own APIs and describe them well. A platform team owns the protocol layer, the policy layer, and the connectivity layer. AgentCore Gateway made that split practical by removing the undifferentiated work in between: no MCP server code, no per-API networking, no client-side filtering pretending to be authorization.

The result is an agent system where adding a new tool is a spec change, restricting access is a policy change, and neither requires the other team to be involved.

To get started with AgentCore Gateway, see the Amazon Bedrock AgentCore documentation. For Cedar policy authoring, see the Cedar policy language reference. For private connectivity patterns, see the Amazon VPC Lattice documentation.

To discuss a similar architecture for your organization, contact your AWS account team or reach out to AWS.


About the authors

Nikhil Kumar

Nikhil is a Lead Software Engineer in the CTO’s office at MoEngage, where he leads the AI Labs team building agentic AI capabilities. His work spans MCP server and tool-catalog architecture, LLM gateway and routing infrastructure, and evaluating agent frameworks for both internal tooling and public agent experiences. He has over 4 years of experience building software and cloud infrastructure at scale.

Shakir Khan

Shakir is an Architect at MoEngage, where he leads API governance and builds core streaming infrastructure powering the company’s customer engagement platform. His work spans gateway architecture, real-time streaming with Flink and Kafka, and large-scale data migrations. He has over 11 years of experience designing systems that serve billions of customer interactions, including 5 years at MoEngage.

Bhupesh Chadha

Bhupesh is a Principal Account Manager at Amazon Web Services, where he partners with independent software vendors (ISVs) to align their platform strategy with their business goals. He works with C-suite and senior leadership to accelerate growth, bring new capabilities to market, and turn technical investments into customer reach and differentiation.

Anant Murarka

Anant is a Solutions Architect at Amazon Web Services, where he works with ISV customers to design multi-tenant architectures and productionize AI-driven solutions. His areas of expertise include agentic AI, agent orchestration patterns, responsible AI, and helping product companies adopt generative AI on AWS. Outside of work, Anant is passionate about exploring how emerging AI paradigms reshape the way software products are built and delivered.