人工智能
MoEngage 如何将 400 个API 转换成带有 Agent Core Gateway 的 agent 工具
此帖与来自MoEngage的Nikhil Kumar和Shakir Khan共同撰写。
当工程团队开始建设AI agents时,这些agents需要的能力通常已经作为内部API存在。 运动创建,分部查询,交付统计。 挑战不是建立新的功能。 挑战在于让数以百计的私人API安全地通过agents实现,而不将其暴露在公共互联网上,不给模型控制身份,不淹没带有数百个工具定义的背景windows.
MoEngage是超过1,350个消费者品牌利用代理客户参与平台,通过推、电子邮件、在线、短信、WhatsApp和RCS提供个性化体验。 产品背后坐落着大约400个内部REST API,由25个工程团队建造,运行于私人虚拟私人云层(VPC),跨越7个AWS区域。 且不会在公共互联网上曝光。 agents所需的能力已经在生产中运行。 让它可以安全地到达是困难的部分。
在这个帖子中,我们走过MoEngage如何使用Agent Core Gateway,一种Amazon Bedrock Agent Core的能力,将那些私人API变成允许范围agent工具。 这种方法使MoEngage节省了大约六个月的平台工程工作,现在登上一个新的API需要几个小时而不是几天。 没有产品团队写出Model Content Protocol(MCP)服务器代码,没有提供每个集成的网络,在路径的任何地方也没有公共终点。
为什么20个MCP服务器是错误的答案
模型背景协议(MCP)为agents提供了发现和调用工具的标准方法。 采用它的直截了当的途径是,每个团队都要暴露自己的MCP服务器。 MoEngage把费用计算出来了拒绝了
超过20个MCP服务器是指随着MCP的演化,20多个部署来监测,补丁,并保持协议兼容性。 跨域的agents,即读取运动,检查其部分,并检查发送数据,需要连接到几个服务器并进行调节。 而每个团队都需要与实际产品工作无关的MCP专业知识。
因此MoEngage确立了塑造之后一切的原则:单个工程团队不执行MCP. 团队建立REST API,并声明哪些操作应该是工具。 AI平台团队拥有MCP层端到端。 一个团队的责任以精心描述的OpenAPI spec结束。
这一原则立即产生了三个要求:agents连接一次而不是每次服务的中央工具表面,每agent授权执行服务器侧而不是通过惯例执行,私人连接不需要为每一个新的API重建。
从零开始建造这一切是一个选择。 一个自定义的中央 MCP 服务器可以解决20服务器的问题,但离开 MoEngage 构建一个工具生成管道,一个政策文件格式,一个重命名的工具化名注册,以及断路器。 所有自定义代码,都归一个团队所有
塑造建筑结构的四个制约因素
在评估任何解决方案之前,MoEngage定义了四个制约因素。 四者必须同时满足。 解决两个问题但打破第三个和第四个问题的解决办法是不可行的。
没有什么会得到一个公开的终点。 MoEngage内部的API从政策上讲是VPC-私人的。 任何需要披露这些内容的解决办法,即使是在额外认证之后,都是不启动的。 传统的工作方式是每个集成网络:一个NAT网关在这里,一个反向代理在那里,第三个是VPN隧道。 乘以7个大区和操作表面的生长速度快于agents集的生长速度。 每个新的API都意味着另一个网络变更请求,另一套安全审查,另一个需要维护的基础设施。
身份不可能是agent的决定。 每个内部API呼叫都包含租户,用户,角色,以及数据库背景。 如果上下文是一个大型语言模型(LLM)-可见工具参数,一个模型可能会弄错了或者被劝说修改。 MoEngage需要身份才能在结构上超出模型的能及范围
一个400个工具目录并不适合上下文窗口。 大约每个工具有50个符号的JSON schema,一个完整的工具/清单横跨整个庄园,在每个连接上传输超过20,000个符号。 这个象征性的预算是在agent做任何有用的事情之前花费的,它挤出上下文agent实际上需要解释这个任务。 客户端过滤( ADK 或 MCP SDK 中的工具过滤器) 并不修复此功能。 完整目录已经跨越了电线,agent不该看到写操作
最后一个限制因素是避免了明显的替代办法。 一个自定义的中央 MCP 服务器解决了20服务器的问题,但仍然离开 MoEngage 构建一个工具生成管道,一个政策文件格式,一个重命名的工具化名注册,以及断路器。 所有自定义代码都归一个团队所有
Agent Core Gateway如何绘制这些制约因素的地图
Amazon Bedrock Agent Core Gateway是一个完全管理的MCP服务器。 您将 OpenAPI 规格注册为目标,网关从中生成 MCP 工具,然后路由调用到辅助服务。 四个属性直接映射到MoEngage的制约因素。
OpenAPI in, MCP 工具退出。 没有MCP服务器可以构建或运行,也没有单独的文物可以与API同步。 已经维护的光谱小组是工具定义。 每个操作都成为名为Goal OperationId的工具,例如CampesAPI SearchCampaigns. 当光谱改变时,工具就会改变。 当一个团队新增作为终点时,工具出现。 当一个团队移除一个时,工具就会消失。 没有部署,没有协议专业知识,没有与AI平台团队的协调。
锡达政策,在编目序列化前进行评估。 Agent Core政策引擎使用部分评价来过滤每个主机的工具/列表。 每个agent认证为它自己的IAM角色,它的Cedar政策决定它能看到和调用哪些工具。 这使得400个工具可以使用。 而非事后客户端过滤
但无法使用写作操作:
机器人不在其工具/列表响应中看到写工具。 因为工具没有发送
管理着Amazon VPC Lattice上空的入侵。 该网关通过Core代理公司管理的Egress,而不是通过联网的MoEngage建设和运营,进入MoEngage的内部服务。 入境,网关只能通过与私人DNS的VPC接口端点才能到达。 没有公开途径。 登上一个新的API 新增目标,而不是网络地形变化。 这就是打破了7个大区问题。 网络存在一次,每个API都使用它。
语义搜索作为网关能力。 有了x amz bedrock agentcore search能力,agent可以通过描述任务而不是命名工具来找到工具。 它取消了自定义发现层的需要。 它还移除了重命名脆弱性作为副作用:如果 get segment user count变成 get segment size,agent搜索分区用户计数仍然发现它,因为匹配发生在描述而不是标识符上。
实际结构
从agent到内部API的请求流很短,每层都有特定的工作。 Agent服务通过一个VPC接口端点连接到Agent Core Gateway,该端点通过Amazon VPC Lattice至内部API的有管理的Egress对Cedar政策和路由工具呼叫进行评价。
下图显示元件如何连接。
agent服务运行于Amazon弹性计算云(Amazon EC2)或在一个容器中称为MCP客户端。 客户端可以是官方MCP SDK,LangChain,Google ADK,也可以是MoEngage自己的agent跑车。 客户端使用服务已经具备的AWS身份和访问管理(IAM)角色与SigV4一起签名请求。 请求通过HTTPS前往一个与私人DNS的VPC接口端点。 没有公开的跳跃。 Agent Core Gateway接收请求并评价雪松政策,以确定本主能看到或调用什么。 它然后将工具引用通过Amazon VPC Lattice上空的有管理的Egress引向内部API.
MoEngage做出了两个值得召唤的认证决定。
首先,他们选择了SigV4而不是JWT作为内部网关。 Agents是已经具有IAM角色的服务。 有了SigV4,他们可以签到他们已经拥有的证书。 没有新东西可以发行、旋转或储存。 MoEngage的单独的公共MCP服务器服务于来自Claude和其他客户端的经人验证的会话,在AgentCore运行时使用OIDC JWTs. 这是一个不同的表面,有不同的要求。
其次,身份旅行是作为头符,而不是作为工具参数。 租户,用户,角色,和数据库上下文由客户端库从一个小的身份对象转换成X-MOE-*头。 模型看不到它们,一个细节对于任何建造类似东西的人来说很重要:因为SigV4签名占据了授权信头,呼叫人前传的无记名标志必须移动到别处。 MoEngage将它宣传为专用的MoEngage前置标题。 信头的传播也被封顶,所以这套信头是故意的而不是积累的。
发现和执行有不同的身份要求。 列名和查询工具没有租户身份。 只有工具/电话才是如此。 这种分离使发现变得便宜,使审计线索变得毫不含糊。 每个具有身份的请求都是实际的数据访问。
即使Cedar将 agent 范围定义为目录的一个子集,子集也可以是大的。 MoEngage的客户端库向模型暴露了单一的meta工具,搜索工具。 这个模式描述了它需要什么,网关的语义搜索返回候选人,完整目录没有输入上下文。 agent的上下文包含了一个起始时的工具定义和少数在搜索后的相关定义,而不是它永远不会使用的几百个定义。
装入新的 API
一个团队将一个API 暴露为 agent 工具新增块到其现有的 OpenAPI 规格:
该区块的四个设计选择值得解释。
接触是明确的选择。 没有x-moe-mcp块的终点不是工具。 持续整合(CI)并不警告其缺失,因为对于大多数端点缺失都是正确的状态。 Cache-warmup 路线和迁移触发器不是agent工具,任何事物都不应该让一个团队把它们变成一个工具。 使用内外旗,一个团队可以将一个操作暴露给内部的agents,公共的MCP服务器,或者两者独立地曝光。
工具描述不是 API 描述。 API描述告诉一个开发者读取docs后返回的终点是什么。 一个工具描述讲述了这个工具何时到达和通过什么。 MoEngage发现,重复使用API描述逐字导致工具选择不佳。 模型选择的工具是根据执行细节(“退回一份标注清单”)而不是意图(“按地位或渠道寻找活动”)。 工具描述和param overrides 字段特别存在,可以给团队一个位置,在不更改其开发者-facing docs的情况下编写模型化文本。
CI管道也处理所有事务
本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。
Artificial Intelligence
How MoEngage turned over 400 APIs into agent tools with AgentCore Gateway
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:
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.
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:
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 too
Auto-fetched and translated by AI Atlas. All rights belong to the original author.