Aeolus 网关
@aeolus-fleet/gateway: MCP 服务器外部和客户端加入 a 欧洛斯语Name 舰队作为舰只,通过核心旁边的一个通道。 其设计为aeolus-fleet的docs/design/interop/interop.md.
运行
npm install && npm run build
DATABASE_URL=postgresql://... FLEET_URL=https://fleet.example.com npm start
| 变量 | 默认 | 含义 |
|---|---|---|
DATABASE_URL | 所需经费 | 网关的自有 Postgres 16 或更新的数据库,可直接连接 |
FLEET_URL | 所需经费 | 车队的公开URL(http:// 或者说 https://(中文(简体) ) |
HOST | 127.0.0.1 | 要监听的界面 |
PORT | 4200 | 要监听的端口 |
GATEWAY_PUBLIC_URL | http://127.0.0.1:<PORT> | 外部 MCP 客户端到达网关的地方: OAuth 发行器, MCP 端点位于 /mcp |
GATEWAY_SECRET | 所需经费 | 至少32个字符。 在MCP客户端之外按下该船的别名: 同一秘密将每个别名都保存在重启时, 一个新的将每艘船改名给他们 |
MCP_WAIT_MAX_MS | 10000 | 一个外部的MCP客户端的工具呼叫等待其答案多久后才能被解答其手柄; 0 立即回答手柄 |
INSTALLATION_TOKEN | 未设定 | 托管服务给安装程序(至少32个字符,第0021号决定)的代号。 取消:它们关闭,每个舰队都得到服务,作为自我托管的网关需求; 取消:一个舰队一旦开启就得到服务 |
PAGASAE_URL, (中文(简体) ), PAGASAE_CLIENT_ID, (中文(简体) ), PAGASAE_CLIENT_SECRET | 未设定 | pagasae,人们在这里签名(第0054号决定),以及网关的客户端在那里,注册在重新定向的URI <GATEWAY_PUBLIC_URL>/pagasae/callback。所有3个或无;未设置,没有人签名,所以没有MCP客户端连接(只有一个账户要求一个) |
PAGASAE_APP_CLIENT_ID, (中文(简体) ), PAGASAE_APP_CLIENT_SECRET | 未设定 | 网关的页面作为 pagasae 的应用程序 APP_CLIENTS,调整URI方向 <GATEWAY_PUBLIC_URL>/sign-in/done),除了为外部MCP客户端的客户端:人们在页面上签名,并在每个Aeolus app股份(Aeolus-fleet头部设计,H5)中签入账号. 两者皆有或无相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相 PAGASAE_URL; 未设置, 没有人在网络应用程序的页面中签名 |
EMAIL_WAKE_WINDOW_MINUTES | 60 | 至少一个 电子邮件频道每多分钟最多送出一人一发; 等待的时间在下一发(aeolus-fleet's wake a person design, W3, W10). 电子邮件唤醒需要 PAGASAE_URL 财务报告和审定财务报表 INSTALLATION_TOKEN它的网关给pagasae带来 /api/wakes |
WEB_PUSH_PUBLIC_KEY, (中文(简体) ), WEB_PUSH_PRIVATE_KEY, (中文(简体) ), WEB_PUSH_SUBJECT | 未设定 | 网关的按键( VAPID, 如 npx web-push generate-vapid-keys 以示警告 mailto: 或者说 https: URL 驱动服务可能联系他们 。 三者或无; 未设置, Bridge 的设置不会提供网络推力 |
WEB_PUSH_WAKE_WINDOW_MINUTES | 10 | 至少一个 网络推力每多分钟最多送出一艘船;等待的时间是下一个(W3,W10) |
ROUTING_ON_BY_DEFAULT | decide:chat,do:chat,stay-aware:chat,everything-else:chat | 工作与地点,而一个人没有选择 自己,因为逗号分隔 job:place 双(文件/设计/桥,第8节,CC19)。 工作: decide, (中文(简体) ), do, (中文(简体) ), stay-aware, (中文(简体) ), everything-else; 地点 : slack, (中文(简体) ), chat, (中文(简体) ), web-push, (中文(简体) ), email其它地方都关了,直到人打开为止,空的就把东西都关了 |
SLACK_API_URL | https://slack.com/api | Slack的Web API,其中网关制造并安装了车队的Slack bots;测试将其设定为他们的Slack双人 |
OPENAI_APPS_CHALLENGE | 未设定 | OpenAI 的插件门户显示以证明域名, 作为纯文本 /.well-known/openai-apps-challenge (chatgpt-plugin设计, 7.5). 按设计公开;未设置,没有这样的地址 |
LOG_LEVEL | info | fatal, (中文(简体) ), error, (中文(简体) ), warn, (中文(简体) ), info, (中文(简体) ), debug, (中文(简体) ), trace 或者说 silent |
| 命令 | 对 |
|---|---|
aeolus-gateway start | 读取核心的版本并退出 1 当核心比它需要的年长(核心0.28.0或更晚), 表示两个版本; 迁移其数据库; 服务 |
aeolus-gateway migrate | Migrates它的数据库, 没有别的。 需求 DATABASE_URL 一个人 |
网关的网页是它的网络应用,一个Next.js的应用 web/ (aeolus-fleet的头设计,H3),同一服务器在同一地址回答: npm run build 在服务器旁边建起它,从源头开始(npx tsx src/bin/aeolus-gateway.ts start它按要求汇编。 它回答一个地址,没有服务器自己的页面, 它不在其中,在它的框架里,它的页眉取自共享页眉 @aeolus-fleet/common/header 曾经是普通船.
GET /api/version 回答它运行的版本 GET /api/health 答题 { "status": "ok" } 数据库里还有503个.
连接
argo将网关的船作为应用船委托到控制台(第0044号决定:它是软件,因此其信息没有模式) fleet:read, (中文(简体) ), fleet:commission, (中文(简体) ), fleet:on-behalf 财务报告和审定财务报表 scopes:declare,并用它连接网关;网关用船的秘密注册,只保存船员的标志,并宣布自己的范围, gateway:approve (第0056号决定):船队批准其批准的任何行为者,以及 gateway:slack:它连接了舰队与Slack工作空间(Aeolus-fleet的网关瞄准镜设计,B6). 在它开始的时候,网关在它连接的每个舰队中再次宣布它们. 一支不接受申报的舰队,就像另一艘船持有 gateway 名称空间,拒绝使用(CONFLICT)。 网关连接并被切换到舰队拥有的任何网络上(interop I-3):由舰队决定其网络. 机队的外方(在MCP服务器和客户端之外)是一个开关,默认关闭:在关闭时,网关批准不给任何方,不接任何方的电话,拒绝客户方的代号 /mcp (403) (英语). outsideParties.status 读取; outsideParties.set 需求 fleet:network在舰队没有适用网络规则时打开(fleet.networkRules,读作演员)回答 PRECONDITION FAILED的警告,直到电话确认它与 isOpenNetworkConfirmed。 。 。 .
偷懒
账户 gateway:slack 通过粘贴应用程序配置刷新令牌将机队与Slack页面上的一个Slack工作空间相连接,每个用户和工作空间在其应用程序管理页面(aeolus-fleet的网关瞄准镜设计, 9.1)上发布. 网关将信使保存在数据库中并在12小时结束前旋转,然后制作自己的bot,一个以机队命名的Slack应用程序,账户通过Slack的安装屏幕安装;Slack将它发回 <GATEWAY_PUBLIC_URL>/gw/slack/install。一个符号Slack拒绝保留,直到有人再次连接;bots已经安装继续工作。 断开连接可以移除所有制作的网关,然后忘记工作空间.
演员持有 gateway:slack在舰只的管理范围内,将代理船或外A2A代理船暴露为"Slack bot"(绝不是外MCP服务器的):网关从一份清单中制作出它的应用,用声明摘要以船名命名,并安装同样的方式. 博特被其id绑在了船上:每10分钟有网关将Slack中被更名的一艘船的博特重新取名并删除了退役一艘船的博特. Slack将每个应用程序的事件发送给 <GATEWAY_PUBLIC_URL>/gw/slack/events,仅与该应用的签名 秘密在5分钟内; 一个未安装或被吊销的标志 显示在斯拉克删除的机器人. slack.view 读给任何演员听; slack.connect, (中文(简体) ), slack.install, (中文(简体) ), slack.exposable, (中文(简体) ), slack.expose, (中文(简体) ), slack.remove 财务报告和审定财务报表 slack.disconnect 需求 gateway:slack。 。 。 .
一个人用Link Slack(9.3)从Bridge的设置连接他们的Slack账户: /slack/link 如果需要的话,让他们签到Pagasae, 然后和Slack签到 通过舰队自己的机器人,它送他们回来 <GATEWAY_PUBLIC_URL>/gw/slack/link。一个Slack用户链接到每个机队一个账户,一个账户连接到一个Slack用户;第二个链接被拒绝,命名第一个。 给机器人留言或提及机器人的无关联者只得到他们看到的答案,并带有"Link Slack"按钮,他们的信息不被保存. 当pagasae告诉网关一个账户被禁用时,它的链接停止了,它的Slack用户被告知该账户现在不能给机队发信息. slack.link, (中文(简体) ), slack.startLink 财务报告和审定财务报表 slack.unlink 一个人的.
一个链接人物对一个机器人的直接信息,或者在频道中提及它,作为他们的个人船(9.4)进入了舰队:网关通过Slack的事件ID来保存它,回答Slack,并以Markdown(删除的提及,共享文件作为它的Slack链接)的形式发送给了机器人的飞船,由事件ID按键,每隔5秒,直到核心存储或拒绝. Stored,网关对"Slack"消息的反应;被拒绝,说明了线条中的原因("你可能不会发出消息放行-注","放行-注已退役"). Slack 重试不会改变任何东西。 一个事件的身份被保存一个小时;一个核心在24小时内没有被带走被删除,线条中告诉的人.
在Slack(9.5)中等待联系人的人的船在Slack(9.5)中为Slack的每一项工作所显示的是,在Where things(docs/design/bridge, 第8节)中,只有他们打开它后到达的:对Slack在对话或线上发来的消息的答复,在bot直接消息中发来的一个bot船的消息,其他任何通过舰队自己的bot,由发送者领导. 机器人飞船的留言和对Slack的回信 仍然显示在那里 换个工作也无济于事 文本和 Markdown 显示为文本, 每个选项有一个按钮的问题( 按 <GATEWAY_PUBLIC_URL>/gw/slack/actions jSON作为密码块; 其他一切,或超过Slack的全程显示, 作为连接桥。 每封送货都用频道 slack 并张贴,从未承认:只有当事人的行为才这样做,按下按钮或按线回信(CC6)。 Slack所显示的, 在寄出的邮件下面的线索里有一个答案 用来回答它,然后把它交给我。 在斯莱克拆掉的一具机器人 回到了舰队自己的机器人 和斯莱克的工作, 否则去网络推取和电子邮件.
API是 TRPC 位于 /trpc它的程序采用一个演员(第0057号决定):在转发的网页应用程序的一页中共享签名的账户,argo's 或取景者控制台的会话 cookie, 与车队的检查 console.session或者任何船的船员代号 作为无记名代号 对于一个舰队来说 网关是相连的 演员可以称它为舰队所持有的瞄准镜,由网关的舰只代表舰只阅读(所以它自己读取的瞄准镜),或为其记号所携带的瞄准镜的帐户阅读;需要改变 fleet:manage。 。 。 . requests.toDecide 财务报告和审定财务报表 requests.decide 需求 gateway:approve (第0056号决定):每一次未决的舰队请求,以及就一次作出决定。 核准代理船名、船主(人船)及其范围,只核准人持有的范围 messages:send 财务报告和审定财务报表 messages:receive,对于一个外部的MCP服务器,它的证书和货币;网关佣金和船员将代理船当作自己的船来使用,而舰队拒绝网关的船所没有的范围. 初决有分. 请求被保留了7天,然后到期;被拒绝的代理船则留待处理。 请求外部的MCP服务器的结果会告知每个请求者携带一款人船,作为网关的飞船的短信:用决定书或一次交易中到期书写,一次发送,每分钟在同一个同能键下再次发送,直到舰队储存. 一个被船队拒绝 被留在网关的页面。 同一回合中,到期请求到期。 当一个请求打开时,网关的船会问它的船主(从舰队读出;当Argo拥有它时,Argo)一个问题(第0038号决定),指出网关的 /bridge/settings,其中,任何持有者 gateway:approve 决定;一旦请求被裁定或期满,就撤回问题。 两者都保存并再次被放入同一密钥下,直到舰队储备. installation.setEnabled, (中文(简体) ), installation.get 财务报告和审定财务报表 installation.delete 将安装符记入 x-aeolus-installation-token。 。 。 .
缔约方
argo 批准一个外部 MCP 服务器作为聚会 parties.approve (argo's Control session):它的名称,可以流取的HTTP URL,网关的证书用它调用(没有,因为服务器只通过私人网络到达,所以网关发送的不是授权头;静态的持卡人;OAuth客户端的证书及其发行人;或者每个人在下面签名),所有者为它选择(一个人的船或argo),它一次性需要多少呼叫(1至10个,最核心的一次推收手;默认4个),并且从同样持有的演员那里发出 gateway:approve, (中文(简体) ), tools:检查所回答的、打开或关闭的每个工具。 该网关作为自己的船,委托党的应用代理船类型 mcp-server 和那个主人,船员, 并保存船员的标志。 argo在控制台上给代理船贴上标签,作为任何船只,供网络规则选择. parties.list 显示没有证书或船员证的各方,其代理船的船主和船队所持的瞄准镜,读作问号的演员(第0056号决定:船主是核心的,网关不保留自己的;在演员的阅读范围之外无效,而没有代理船,或船队不回答). parties.get {name} 显示一个. parties.changeOwner {name, ownerShipId} (需求数) fleet:owner和 parties.changeScopes {name, grant, revoke} (需求数) scopes:grant,只有演员持有的瞄准镜)改变舰队中的代理船作为演员,因此舰队检查其管理范围(第0056号决定);网关也保留了两者. parties.retire 退休缔约方(第0056号决定):需要 fleet:manage,而"网关"则将舰队中的代理船作为要求的演员退役,因此"舰队"检查它的管理范围;只有这样,"网关"才会忘记"党"并吊销其客户的代币. 一艘已退役的代理船已经算作已退役. 再来一次是新要求 一艘代理船离开等待船员(委员会的答复丢失了,它的秘密也随之消失) 从新的开始即刻取出一个新的秘密 parties.crew。 。 。 .
一旦代理船被船员使用,该网关的船会将网关检查的内容写成可核实的事实(fleet:verify,第0059号决定,其中的发现表明: tlsHost 用于访问 https 上的 MCP 服务器, clientIdDocumentDomain 对于一个由 https 元数据文档所认识的 MCP 客户端。 一支拒绝的舰队被记录下来,并按原样离开批准;在一个适用自己网络规则的舰队中,网关的舰只对其代理舰只没有管理范围,因此舰队在那里拒绝. 门户的船需要 fleet:verify 连接.
仅使用 OAuth 签名的服务器会添加证书 { kind: 'personSignIn' } (第00-67号决定):每个人向它签字,作为他们自己的账户。 网关从它的401's找到授权服务器 resource_metadata,否则它著名的保护资源元数据(RFC 9728),然后是授权服务器的元数据(RFC 8414,否则就是OpenID Connect),其发行者必须是被命名的元数据. 它拒绝一个不命名授权服务器的服务器,一个元数据缺失的授权服务器,命名另一个发行人或不声明PKCE S256,以及一个不提供动态注册,保留一无所有的授权服务器. 否则,它将为该方登记一个保密客户(RFC 7591),并命名为: Aeolus: <party>,并重定向URI /outside-parties/sign-in/done 而外部范围是每个登录人要求的(401's, 换句话说, 服务器列表中的每个范围, 以及 offline_access 财务报告和审定财务报表 openid (b) 委托和船员代理船舶,将签发人写成其核实的事实(oauthSubject,发行人和当事人的委托人身份证明,从不记人户口. 代理船在有人签字之前不申报; parties.state 答题 PRECONDITION_FAILED 同时.
舰队的每个说法都有个人船号 自己登入这样的服务器(Q16). parties.startSignIn 回答该方授权服务器的地址,将浏览器发送到: 与 PKCE S256 的代码流,客户端的范围和 resource (RFC 8707),以及a state 封住在谁的标志 及其核查人, 10分钟。 授权服务器将浏览器发回 /outside-parties/sign-in/done。在那里,代码仅在这10分钟之内被赎回,在一个浏览器中,该浏览器将启动该代码的账户共用签名名称,并且与该方的发行人一起,该响应名称为一个或服务器表示它总是这样做(RFC 9207);从符号端点直接读取的ID标志必须给该方的发行人和客户点取名。 赠款(外部账户为身份证代号、访问和刷新代号,当访问代号结束时)是为代替其前一个代号的人保存的,代理船则从中注明。 作为外部账户的签入,另一人对党名的认可被取消,其标志被放弃(问题13)。 浏览器继续 /outside-parties/<party>?fleet=<fleet id>&sign-in=<outcome>,结果 signed-in, (中文(简体) ), not-signed-in (拒绝同意), failed, (中文(简体) ), turned-away 或者说 unavailable,使用服务器的 OAuth error 密码,它回答一个. parties.ownSignIn 回答个人的赠款,从来不是象征性的; parties.removeOwnSignIn 撤销其刷新并访问服务器提供撤销的令牌(RFC 7009),然后放弃. 将每个人签名的服务器列入其声明、工具及其开关,在访问令牌尚未终止的任何赠款下列出,这是最近首次使用的(问题15).
船舶对此类服务器的调用由拥有索要船的人,拥有自己的人船(Q1,Q11)的许可而出. 网关在检查工具开关和瞄准镜后,每次交接时都会从核心读出主人,作为自己代表问船的船;虽然核心不回答,但在等待后再接听电话,没有它的赠款就永远不会发出. 船主Argo得到一个错误结果,说没有人可以签(Q10). 一个没有赠款的业主得到一个错误的结果, 命名他们缺失的登录 和党的页面, /outside-parties/<party>?fleet=<fleet id>,服务器从不看电话 (Q5); 网关的船每方问一次, 一步(application/vnd.aeolus.step+json,Docs/design/bridge CC14)以该页作为链接的船名,并且仅在(Q6,Q9)之间签入后再次登入. 他们的登录完成这一步骤时没有媒体:网关承认,如果他们没有打开它,它就是自己的船;报告它处理过,并通过网关完成。 任一出错结果在被回复之前都会被保存,所以重启后再次回复. 10分钟内结束的补助 在电话发出前重新刷新 一通电话服务器拒绝401刷新一次与派对客户端的赠款,并再次出道;第二通401刷新拒绝,或无刷新令牌的赠款解答缺失的签入错误结果并告诉了当事人. 更新授权服务器不保存授权 : 调用时会持有访问令牌, 否则会被置之不理, 等待后再次发送 。 403电话被拒绝 insufficient_scope 获得一个错误结果, 指定要再次签名的页面, 并保留赠款 。 服务器回复的电话设置了上次使用的赠款 .
赠款保持不变(问题7)。 一个刷新符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符符 每个网关实例还每5分钟开一圈,刷新进入证书在10分钟内结束的赠款,以及自签入或最后一次刷新以来一天内没有刷新的资金,最多每圈100个。 更新回复 invalid_grant 失去补助金:补助金保留在何时和为什么,不提供任何服务(缺失的签入错误结果),一旦其签入结束,就告诉当事人,页面将再次签名; parties.ownSignIn 接电话 lost。一个新的登录替换它。 任何其他拒绝,或没有答复,都保留原样的赠款,下一轮再次尝试.
赠款结束(问题6,问题14)。 每笔赠款都以同样的方式结束:在服务器提供撤销(RFC 7009)的地方,其刷新和访问令牌被吊销,然后被丢弃,所以其本人的船会得到缺失的签入错误结果. 演员持有 gateway:approve 正如舰队所回答的那样,在代理舰队的管理范围内,每个人都会得到 parties.signIns {name, after},每行20页next 名称,在下一页开始的地方) fleet.list 读取页面,命名其中每个人的船)以及是否是演员自己的船,并删除任何与 parties.removeSignIn {name, personShipId} (问题12),任何人被拒绝,只见他们自己的. installation.accountDisabled 结束舰队帐户的每一笔拨款 赠款回合还将持有赠款的每艘船作为网关代表其拥有的船舶,并结束退休船舶的每一笔赠款(核心答复是代表退休船舶读作没有这种船舶). parties.retire ,然后删除其客户端,其注册答复了客户端配置端点(RFC 7592)。 代理船的一位新船主不改变赠款.
网关保存外部的证书和机组代号,如同它们自己在数据库中一样,因为中队保存机组代号:同一服务器上的一键将只保护备份. 保护数据库及其备份.
parties.state 从服务器上重新声明代理船 tools/list: 每一个工具都是一种具有其多边CP领域和说明的能力,使用 application/vnd.aeolus.mcp-tool+json; name=<tool> (工具参数作为 JSON 对象) application/vnd.aeolus.mcp-result+json; name=<tool> (工具结果). 摘要只取出该方的名称,从不取其URL或证书. 每种能力都说明网关本身的时间: waitMs, 外部客户端等待答案需要多长时间(MCP_WAIT_MAX_MS),以及 deadlineMs当网关在服务器上放弃时 tools/call (单位:千美元)TOOL_CALL_TIMEOUT_MS) (中文(简体) ). parties.markTool 标记一个可重复的工具,或取消标记,并立即声明:只有argo的标记让网关接一个又被解答的电话;服务器的提示永远不会实现.
每个服务器的工具都有一个开关,每方:每艘可能到达该方的船只都到达相同的工具(aeolus-fleet#1151). 语句只保留了打开的工具,对一个没有打开的工具的调用被解答错误结果 tool not enabled for this party 永远不能到达服务器. parties.switchTool {name, tool, isOn} (需求数) gateway:approve)保持一个开关,然后立即写出代理船;虽然不能写出,但开关等待它的下个声明,并且同时拒绝打电话. parties.tools 对服务器现在列出的每个工具进行解答, isNew 用于开关保存后列出的开关 isReadOnly 当它的注解如此说。 服务器后加的工具启动 。 一个没有选择工具的政党(在开关之前,通过请求,或由没有选择工具的演员)加入 gateway:approve在下一次发言中保留它列出的所有工具.
当事方的页
当事人的网页是网络应用程序,按范围进行核算,在机队中他们的地址(地址:?fleet=<fleet id>: /parties (各方按其状况,并按其账户 fleet:manage * 核准一个MCP服务器的表格和每个当事方交出新的秘密、说明其工具并标记可重复的工具的表格, /outside-parties (开关,用于 fleet:network和每个外部方),一个外部方在 /outside-parties/<name> (改变其所有者和范围,使其退休,并用于账户) gateway:approve 服务器每个工具的切换器,每个工具都说它做了什么; 对于一个服务器,每个人都在它的事实和工具之间签入自己的签入:不与Sign签入,与外部账户签入,何时和最后使用,再次签入并删除,或丢失签入的时间和原因,以及浏览器返回时的签入方式;一个没有任何人的账户被告知它需要一个;在下面,用于账户持有 gateway:approve,每个人的签入:每个人,他们的外部账户,状态和最后使用,20页,多显示,删除确认到位)和在 /outside-parties/add (其用于账户持有的工具) gateway:approve; 服务器, 每个人在地址、 所有者、 签名中签名, 在按下 Add 时检查其签入, 拒绝表示到位, 然后批准者自己签入, 或者在它的页面后面。 每页都从网关端端口的服务器上询问API,如浏览器所要求;每个表单都是服务器动作,相同的服务器答案,API检查每个范围.
桥
/bridge?fleet=<fleet id> 是网络应用程序,用于与共享登录签名的账户,以及土地签名的账户(docs/design/bridge,CC18)。 桥梁之家列出等待人员的情况、问题和步骤(决定和步骤),其中一项计数是:其个人船只的出入口、开通和尚未处理的事项(people.home) (中文(简体) ). 除此以外,留心饲料列出了他们没有见过的警报和通知,在计数之外. 打开项目确认并显示整个项目(people.open(三); people.item 以任何状态的交付代号来显示一个整体,等待、打开或完成,并承认和保存任何信息,拒绝未找到的不是船舶本身的交付; 信息得到回答或完成,提问的答案进入篮子,并立即报告警报或通知(CC16)。 一个步骤表明它与东道主的联系为何,它与主机的联系及其笔记字段在Done和Colon之前;或者发出其步骤结果(application/vnd.aeolus.step-outcome+json)一时给驴子取出,如果写出一分一分,回回接一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一分一 完成( N)/bridge/done)从核心读出人船的纪录一次有20页,最出名的第一页(第1页)people.record核心项目 ship/record),每个项目都有它的工作,状态,一旦一个人采取行动,它有什么结果,在哪里: Bridge,一个聊天(一个人的MCP工具),Slack,或者它所看到的自己一步的出入口完整,保存在入口上 item_outcomes。当核心不回答时, Bridge 表示现在无法读取记录,每10秒再读一次。 桥的设置( E)/bridge/settings链接到事物显示的地方,并持有关于决定持有者的请求 gateway:approve,每个决定 /bridge/settings/requests/<request id>和他们的要求。 每页在机队要求或人物物品更改时, 都会重新阅读自己 requests.changes (服务器发送事件) /bridge/changes。 。 。 .
篮子/bridge/basket,Docs/design/Bridge 第9节载有对在Bridge中被选中但没有被发送、由网关保存的问题的答复 basket_entries 每艘舰只和人船,每问题一次people.putInBasket, (中文(简体) ), people.removeFromBasket, (中文(简体) ), people.basket;桥的导航显示它从 people.basketCount) (中文(简体) ). Bridge的提问只把选项N放入篮子;没有寄出,它仍然在等待人物. 发送 N 答案( N)people.sendBasket) 将每个条目存储为发送并唤醒网关的发送者,按个人船舶的顺序,单独发送每个发送者:对关键下的问题的答复 answer-<question uuid>,所以舰队储存它一次 不管它经常被发送。 每个分舰队商店都报告得到处理并离开篮子;一个没有用同样的钥匙再次发送,每5秒一次重启后;一个拒绝留在篮子中,说明原因,删除标记其问题完成,没有发送。 其驴子退出或替换的问题,或者Slack或聊天先回答的问题,没有发送:发送跳过,说出,取出.
东西显示的地方( Where things shows (/bridge/settings/routing,docs/design/ Bridge 第8节 上方的地段,人物的Slack链接,一个聊天,每个浏览器的网页推取(打开询问浏览器的许可,列出,一个接一个取出,其中网关握有推取键)和电子邮件,然后每个工作(决定,做,注意,其他一切),每个地方上下,Bridge总是(people.routing, (中文(简体) ), people.turnRoute,保留在 routes 每艘舰队、人船、工作和地点;缺省: ROUTING_ON_BY_DEFAULT 人选择什么。 一次更改适用, 却一无所获: 聊天打开了任务未完成的每个项目列表; 仅以Slack, web push和电子邮件的形式发送到之后的地址 。 每次送货都是一次, 由第一个显示它。 桥的一页正在集中 /bridge/focus 打开( API ) people.focus)和网关掌上 通过渠道到达的人 page(W6,唤醒一个人;Slack,继续工作,继续张贴) 一个网络推叫声只说舰队的名字, 某事等待和Bridge的链接 /wake-worker.js 服务人员。 一个浏览器,其推取服务回答404或410,不再被唤醒,而该部分说它已经消失了.
阿尔戈的收件箱
网关的自有船阅读了argo的开放收件箱,供可能充当argo的人使用(aeolus-fleet的docs/design/argo-inbox,AI1和AI9),在控制台的网络页面上用手读取了argo的规则: 文档/argo-inbox-read-rule.md 是向导。 在每支舰队中,它都读取了Argo的开放收件箱整体,然后跟踪舰队有关argo的事件(英语:fleet.follow),并读出每一个再次改变的訊息;一个重启,或者规则返回,再读出整个消息. 它读到的东西只保存在记忆中:argo的收件箱保留了唯一的记录,而核心发送的网关什么也没有. 没有规则,它没有读取任何内容,而Bridge Home告诉一个被允许作为argo的账户,将向导联系起来(people.argoInboxNotice) (中文(简体) ). 允许作为Argo的账户及其所属船只在下列地点保存: argo_accounts 从每个账户的最新账户代号(其 argo :每一次签入、ID-JAG、刷新和共享的签入交换,一旦一个令牌说不再允许,或者一旦pagasae拒绝刷新,就如同一个已停用账户一样.
MCP 关闭
从一开始,一旦一个党被船员化,网关就把每个被船员化的代理船的来电作为船员(interop 5.2). 舰队的一艘船呼叫工具 通过发送代理船的工具输入类型, application/vnd.aeolus.mcp-tool+json; name=<tool>,工具参数作为 JSON 对象。 传送的网关报告 tools/call 和对结果的答复(包括一个错误结果) 命名请求,然后确认和报告它处理。 它在数据库中保留每一次呼叫,所以重启回复,而不再调用可能运行的响应.
- 服务器从未接到的一通电话(无法接通,或拒绝证书)在等待后再次接通,而舰队在第五次尝试时就停止了.
- 当argo标记其工具可重复时,才再次发出无答复的电话(断流,5分钟内无答复)。 否则,网关报告它没有处理:它可能已经运行了,一个可以检查外部系统的人重新发送或解职.
- 一方最多一次使用其汇兑限额.
每个交接者都命名它的频道, mcp (会话5.1). 在控制台的“需要”中未处理的电话.
MCP 客户端签名
该网关是面向外部MCP客户端的OAuth 2.1授权服务器,如克洛德,ChatGPT或Cursor(MCP 2026-07-28):
/.well-known/oauth-protected-resource(RFC 9728)将网关命名为其MCP端点的授权服务器,<GATEWAY_PUBLIC_URL>/mcp· ;/.well-known/oauth-authorization-server(RFC 8414)说明了它所服务的内容.- 插件的地址 :,
<GATEWAY_PUBLIC_URL>/plugin/mcp,服务于相同的工具(chatgpt-plugin设计,6). 它的元数据是/.well-known/oauth-protected-resource/plugin/mcp准确命名那个地址./authorize当作resource显示不选取, 并发送个人到自己签名的 pagasae ; 拒绝请求客户访问(invalid_request) (中文(简体) ). 它不会给更多的东西:一个人得到什么核心答案来代替自己的船. - 一个客户端被阿尔戈预先注册
oauth.registerClient(它的名称,它重定向的URI,以及它是否保持一个秘密,一次回答),或以其客户端元数据文档(CIMD)所知道:它的客户端id是该文件的https URL. 没有动态注册. /authorize检查请求并发送浏览器到网络应用程序/authorize/pick,它显示客户端和两个选择(第0056号决定,Q1 a):作为自己签名,或者为这个客户端请求访问。 要么派人去Pagasae登记 任何阻止浏览器,未知客户端或其中另一个浏览器的登录,都是网页app的页面/authorize/failed。只提供与PKCE S256的授权代码,而且resource必须是网关的两个MCP地址之一(RFC 8707);一个符号只取自它所发的地址.- 一个人通过pagasae签字(第0054号决定)。 Pagasae回答他们唯一的船队, 或问谁,并把他们送回
/pagasae/callback;作为自己签名,网关保存他们的账户赠款(账户,其舰队,其人船和pagasae的道具),并用其代码寄回他们的客户,未经批准. 正在办理的签注 被封入了帕加赛state因此,在舰队已知之前,没有储存任何东西。 启动的浏览器有一个秘密封口, 在一个 HttpOnly cookie 中/pagasae/callback用于它的10分钟,所以没有其他浏览器完成它(login CSRF). 网关不服务的舰队被拒绝. 一个人的委托人得到他们自己的船工具:aeolus_setup(在每次谈话中称为第一,如服务器的指示及其描述,与客户端的聊天运行在:claude,claude-code,claude-code,chargpt或副驾驶;它回答让聊天像客户端允许的那样频繁检查收件箱的规则,聊天时有一个的监视器工具,其他在每次回合的开始和结束,以及让每个新对话都称之为第一的一次性步骤),aeolus_inbox(根据标题,最多只有10份工作需要聊天,每份工作一到就未完成),aeolus_open(一整批交货;打开后确认,立即处理警报或打开的通知,即Bridge CC16),aeolus_answer(答复发件人,然后处理)和aeolus_done(处理后无答复;一步的结果完成或不能,用可选的便条,先发送给发件人). 每个人物工具的答案首先保留了自己的块并加上了第二个文本块,与人物的收件箱状态:从一个核心呼叫中,有多少个交付等待,没有取出,有多少人打开并且没有处理;一个状态,一个舰队不回答就离开答案. 每个人的工具都说明readOnlyHint, (中文(简体) ),destructiveHint财务报告和审定财务报表openWorldHint,则asecuritySchemes类型oauth2电话被拒绝,因为当事人的签名结束_meta["mcp/www_authenticate"],因此客户端要求他们再次签名(chatgpt-plugin 设计, 7.4. 该网关作为账户的自有人员船只的船员发出这些呼叫,并附有账户的代号(第0057号决定):它将船员乘船一次,由乘客的每个客户共同使用,并在租赁结束后再次船员乘船. 一个无人的账户 船是被告知的, 而舰队没有被要求.aeolus_ask_for_server以 http 或 https 地址请求外部的 MCP 服务器, 作为账户( 第0056号决定) : 它打开一个待决请求, 或者加入同一服务器的待决请求, 而批准人会以证书添加服务器 。 一个已经是派对的服务器是这么说的。 舰队外出时没人问 如果情况显示每艘个人船只打开和关闭电子邮件,则默认无任何内容(Docs/design/bridge, 第8节)。 该网关在船员的船上等待;一旦一个从未交付过等待的送货,一个工作邮件就开着,并且自开通以来就发送,它请帕加萨埃将一个人的账户发出一个叫醒,它只说有些东西在舰队中等待,有Bridge的链接,最多每一次EMAIL_WAKE_WINDOW_MINUTES;每件包裹的货被递出否。 1 有频道email醒来后,帕加赛拒绝或不回答任何问题,在1,5之后,每15分钟再试一次. - 网络应用的页面以共享账户的登录方式(标题设计H5)为人签名:
/sign-in/start?return_to=<a path of the gateway's>将浏览器与代码流和PKCE一起发送到 pagasae,命名为无机群,以及/sign-in/done把它带回页面; 网关没有保留任何东西, 因为pagasae把签入 自己的饼干aeolus_account_session在域名上,每个Aeolus应用程序的股份。 在地址中有一页标明其车队的名称(?fleet=<fleet id>)和web app的服务器转发 单独登录和车队在aeolus-fleet标题;然后API通过代币pagasae作为账户,在机队中交换签入,保存到结束前一分钟.account.inView答案是:它显示机队的页面是(它的账户和范围),当它命名为无(第一个账户可能打开的网关)时,机队可以前往,或者当它显示的应用程序不能打开网关(H9);UNAUTHARIZED,没有共享的登录。 出错的是页面/sign-in/failed。将表格张贴到/sign-in/end从网关自己的网页上结束在pagasae的共享登录,在每个Aeolus应用程序中签名的人. - 一个要求客户访问的人会问他们的账户。 已经是当事人的客户端 立即被带回其当事人的密码 否则账户会打开客户端的待决请求, 或者加入待决请求, 其浏览器会在网络应用的等待
/authorize/waiting/approval,在请求之后/authorize/waiting/live并回到/authorize/waiting一旦它不再等待,就会被发送到: 批准和它的代理船船员,客户得到其党的代码; 拒绝或过期,access_denied。同时关闭,在否定或过期之后的下一次尝试以access_denied一次,以后再试一次 等待者在页面地址上密封出行,浏览器在只发送到等待地址的HtpOnly cookie中握有签名入行后的秘密,请求时间为7天. 舰队外出时没人问 每个客户都有自己的应用代理船,类型mcp-client;客户方的每个标志都取出它的党名,所以每个舰队给客户打电话,都是它的代理船名,在它的能及范围内;一个人的标志取出他们账户的赠款.parties.list显示服务器方旁边的客户端方. /token使用密码一次,在分钟内,用于访问符(一个小时)和刷新符(30天). 刷新会旋转对;使用过两次的代码或刷新令牌会撤销它给出的东西.- ID-JAG(aeolus-fleet Company sign-in design, s切片 6):一个人的MCP客户,其公司管理它(企业管理的授权)职位到
/tokeniD-JAG公司为网关的发行人发放的公司身份证明,并获得JWT无记名赠款(urn:ietf:params:oauth:grant-type:jwt-bearer,ID-JAG作为assertion),不需要浏览器。 只有登记了代码流的客户端才有,如果有它的秘密;还有人invalid_client。网关将ID-JAG交给Pagasae,与自己的客户进行象征性交换,给客户取名,Pagasae将它与组织连接的Okta进行核对,并发现该账户被记录在其中。 该账户的赠款保留在浏览器登录后,客户端获得一个访问令牌(一个小时)作为客户端机组的账户,没有刷新令牌:它要求其身份提供者提供新的ID-JAG. ID-JAG只用于一个机队的账户:pagasae拒绝一个账号,账号为若干(b)invalid_grant在网关的地址上签名 在帕加萨的拒绝是invalid_grant帕加赛不接电话temporarily_unavailable(503) (英语). 元数据说明赠款和authorization_grant_profiles_supported: ["urn:ietf:params:oauth:grant-profile:id-jag"]人们通过pagasae签名.
密码和信物只作为散文保存,客户秘密也一样.
服务于自己的网关,例如 https://gateway.example.com,与 GATEWAY_PUBLIC_URL 设定:RFC 8414和RFC 9728将元数据放入源的根部 /authorize 财务报告和审定财务报表 /token 在那里服务.
ChatGPT 插件
plugin/ 持有 ChatGPT 插件目录中列出的插件( chatgpt- plugin 设计, 7.2: ): plugin.json (清单文本和审查案件OpenAI运行), mcp.json (一个服务器在 https://gateway.aeolus-fleet.dev/plugin/mcp的标志和 skills/aeolus/SKILL.md (模型需要知道一个人的Aeolus;OpenAI要求至少一个技能). npm run plugin:build 将网关的版本设置在 plugin.json 写作 dist/aeolus-<version>.zip, (中文(简体) ), dist/aeolus-<version>.tools.json (个人工具为: tools/list 回答他们)和 dist/aeolus-<version>.notes.md· ; --out <dir> 在别处写 它拒绝,命名字段,一个打破OpenAI限制的软件包,一个审查大小写或一个技能命名一个网关不服务的工具,一个没有技能或有一个打破Agent Swill格式的软件包,以及一个没有三个提示的人物工具. 鉴于 --previous <dir> 持有上版的"ZIP"和工具,注释中表示软件包是否改变(版本搁置),并取出新的,更改或去除的工具名称;拒绝使用上版以外的软件包名称(plugin_name_mismatch) (中文(简体) ). 发布工作流程在发布前运行,并将ZIP和工具附加到GitHub发布.
MCP 客户列表和呼叫工具
<GATEWAY_PUBLIC_URL>/mcp 是网关的MCP端点(Streamable HTTP,无国籍). 没有标志的电话,或者有一个网关没有发出, 得到401与 resource_metadata 名称(RFC 9728).
tools/list客户代理船现在可能发送的 舰队的能力discover回答: 网关没有增加它自己的接触范围.- 一个工具被命名
<alias>__<capability>该别名是8个字母和数字,来源于该船在以下GATEWAY_SECRET:客户从未见过一艘船的名字或身份. - 它的描述是能力的,然后是舰只的总结. 一个需要纯文本的能力首先得到一个
text参数。 每个工具都有一个选项aeolus_idempotency_key。 。 。 . - 出道:argo,船员没有说明的舰艇,其第一个输入类型既不是JSON,也不是纯文本,或者其输入计划不是对象的能力,以及工具名称超过128个字符.
- 没有工具说明输出计划:一个呼叫可能回答一个手柄,MCP客户端对照它检查每一个答案.
tools/call发送参数,没有aeolus_idempotency_key,作为客户代理飞船给工具飞船的信息,在能力的第一个输入类型下. 只有在舰队回复发送后,客户方才会得到答复. 只要有这个能力 呼叫就等着答案waitMs国家,最多MCP_WAIT_MAX_MS(第5.3段),当它没有表示时,完全没有:在其中回答,客户自己得到答案;否则{"handle": "...", "state": "submitted"}(或working) (中文(简体) ). 拒绝发送的舰队会得到一个工具出错,无法到达的舰队不会给出任何理由.- 一样
aeolus_idempotency_key也不再发出第二个消息。 发送的密钥来源于下面GATEWAY_SECRET,以及信件中的把手,所以客户端从未见过msg_编号. aeolus_result({ handle })阅读客户端自己的电话:submitted, (中文(简体) ),working一旦收到另一类型的答复,其答复一旦完成,或失败后的工具出错(interop 3.4).- MCP 任务( E)
io.modelcontextprotocol/tasks,在server/discover: 客户端在它的tools/call被解答的任务代替了手柄、手柄taskId手柄.tasks/get读它:working在提交或工作期间,completed答案为:result,或failed一旦期限过后 任务永远不会到期( A)ttlMs完全无效,因为网关 保持每一个呼叫.tasks/cancel财务报告和审定财务报表tasks/update不被承认,也不改变任何事情:发送的电话不能不接,还没有任何电话要求输入. - 能力的第一个输出型号的第一个回复完成;平版文本完成呼叫一个没有输出型号的船. 由于MCP给出了一个答复,一个外部工具的结果就由此得到回答.
- 呼叫失败了
deadlineMs在没有答复的情况下发出,在能力没有说明的情况下,从没有提出(第3.4段)。 截止日期后的答复保留下来,没有任何变化. - 每个客户方的工人都收到对其电话的答复
receiveReply(aeolus-fleet#953)每通电话既未完成也未超过截止日期,最多一次10通电话,每通电话依次为:每通电话均保留答复,然后确认并处理发送。 从不送货pushReceive所以代理船的租约没有问题receiveReply需要帮助。 给代理舰的留言,对无来电的答复在舰队中等待,而不回复.
开发
npm install
npm run typecheck && npm run lint && npm test
集成测试需要多克克或波德曼:在测试容器中启动Postgres,并从中启动一个真正的核心 @aeolus-fleet/core 德从相生.
许可证
阿帕奇2.0 (英语).