From 192af6eaeacd116a5b60a47a836c00cb99c493fc Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Wed, 7 Oct 2026 12:22:25 +1100 Subject: [PATCH] feat(mcp): prepare ChatGPT and Claude directory listings Both directories scan the live MCP server before they list it. Each tool now has a title, and descriptions say what a tool does instead of telling the model how to behave. Claude rejects a description that sends the model to fetch instructions from a URL, so the fork hint left get_skill. The toolkit answered 403 to any request with another site's Origin. Claude and ChatGPT origins are now allowed; other origins still fail. OpenAI needs terms of service, a domain challenge, and a plugin package. Claude has a prefilled custom connector link that works before review. --- app/app.vue | 6 ++ docs/runbooks/agent-app-directories.md | 81 +++++++++++++++ integrations/openai-plugin/assets/logo.png | Bin 0 -> 8207 bytes integrations/openai-plugin/mcp.json | 9 ++ integrations/openai-plugin/plugin.json | 96 ++++++++++++++++++ layers/marketing/app/pages/developers.vue | 19 +++- layers/marketing/app/pages/terms.vue | 11 ++ layers/marketing/app/utils/developer-setup.ts | 9 ++ layers/marketing/app/utils/page-admissions.ts | 1 + layers/marketing/content/pages/privacy.md | 22 +++- layers/marketing/content/pages/terms.md | 68 +++++++++++++ layers/marketing/nuxt.config.ts | 2 +- layers/mcp/server/mcp/index.ts | 3 +- .../.well-known/openai-apps-challenge.get.ts | 10 ++ layers/mcp/shared/mcp-tools.ts | 40 ++++++-- nuxt.config.ts | 9 ++ test/unit/developer-setup.test.ts | 10 +- test/unit/mcp-discovery.test.ts | 12 ++- 18 files changed, 389 insertions(+), 19 deletions(-) create mode 100644 docs/runbooks/agent-app-directories.md create mode 100644 integrations/openai-plugin/assets/logo.png create mode 100644 integrations/openai-plugin/mcp.json create mode 100644 integrations/openai-plugin/plugin.json create mode 100644 layers/marketing/app/pages/terms.vue create mode 100644 layers/marketing/content/pages/terms.md create mode 100644 layers/mcp/server/routes/.well-known/openai-apps-challenge.get.ts diff --git a/app/app.vue b/app/app.vue index 1b8019ca..4ff011a5 100644 --- a/app/app.vue +++ b/app/app.vue @@ -282,6 +282,12 @@ watch(() => route.fullPath, () => { > Privacy + + Terms + Fz+PKc>`qbm zOl9RomEtC$I7ghoTX+5gqxi0cT+(}Ym0DRL%jlJLLuTD{dBxu&%rm^G)0&X#p_LH1 z>Oy4y-;aHqUq4u5Q*|LSL*QNYxW+aoJw0HF?4d_YUu5H|KmA3UQ=B=pSDUk1IqCNW zo^D|o8v9ylWbFFkgn%VY4)gqe3terQq2z7lAMscBHr{8r!{Uo%0jqwh_)3(0B_z!8 zsCr>g#rge4bKKl)1nVUmQY-~2T2lf8t>f#HLtFJ^zPC&l2Zim2SJBJAk?mXE)g?7U9Wj2#JD>D>_8 zdSB)%SOh1xS6xu(aT3z!Oq-(?xp)aw>M{4Iur3uzvdA#FG0?muO1w$s>;f`Zj|Qhq zj46+G!KaXO^1W2mUJBKZVjiBYD=jrnd1q+;8t(9Odjhu{9xkwwFGtur7j2}UY39ia zyo`GL261EWSd(cMa&);{RW@PYYh!W* zC%z|)SZpUMpo%k^8$yH2zXb+V%}mP*ulA(bRDw>hPzkHp=b;`Z-SY47WoK1M>*O%h*&UE;o?|PGx^CVC0j`IpN*&{n0DO(hmh~#(o#I zyT5*9of2-N!JVsDBG#wJ(7IR9-kf5t*6WQyE?SmcP?{B+^i4bM@8?UQvMs#fbXP^N zGB|CkDrw41Dw^W0L?1iAO0Md8@HIn9V*Hz6bT6Utn_IkC@wYk>qe}x+sxIVTD%$Fy zofdU_CbY}ICH3(;e?e_bX#TY*b!>FhH!E+uSc))j9?pE{b6oK8gZYIP1#SfmZZ7wl zVZIYe{Q0N-4>yz-YzFop>#mZ&s=+=v@aC3YW2x-1fYZnLV~4|poaHE0b2SZ{x!1jn z{bS>wzCQ+gBnsHoyZW zVN}g5Z7>Zp4@H@e-L)^ra!`=sIgE(9J9#{J#2xh66#Ji=2bk5Zu{|f4TXEPr(vF7gQyGzX7E#FF{Vx7 ze%0RVIi>(PRhBK)$VvVjv-q6pU?)a=gPJTz9#f$K#l?S1Aiwpc)^Jp3Hq@Rmd9~jg zC;24gfM6uXeg0m2Ql|eX*~|%yC@J@C)Gvz)ZCwOBZ;O_*1rLpf@2g@@-^^8e5Y7ZR)B9~65*v}wp!z|`Xb6;Y z$p*0VpkU*KiT#|K}et^0(~JAhe_& z4i??@Ze0pGG?EKO%N8f~>kt1_W)41)>*fxRvtjXF2SyRRu;hg--gaf_?M=c(@Q$%$;DNk3JXwXMp}4gN0ob{GZ+;P`RcB zOMfat`ZPqSTbWSlM#Je%;81CYY=}pCEipZdI8%(&VWP_L5z%@q( zH_isfdZl#q?*|nlUtT+@@&*5ANDyn@j^qkwLkz+-#fkM!TG@?+oEA)~tcMwl?WFWP z#1YwxQ^#r18_AA)4-wfCsTx=?#K|{{ooHJpAXNHU?D^1uKj0O|BHklEb16Tx# zb?0_ih=ATZBcP+CYmdSqlmv|^bi4xOlrjn(<~JRQ9f4;kCOlh&<*q>(d4qf%oR6mx z<&CX}tdC6x$F(FR=3<9P+9`5X5Y|DI@lG$o$Uiu2%|xuQ0bGC0M6B4$5OBB#k&%Dq zgNn=MaSfDcmmL#n=bl7vRnMBRVUAN-IfbxMg=+*78b-JyqDdQ{r-7m-bUf0+y^2Fp z2H;Wb0o)OUM8z)Ese+Cf$puIOK15-0gApex_9dB+e`t)$e?4Rdj917z3O4}d=<-!C z!9d4@D3SEzh(l0sqn@3#h!x|iW_TY^ifVO8F4PnlMbgh$VDhOnD=6A5VzfM8k3Uj4 za&bQr*@LFXognv6-;vh%+&Qu@SxqxNf4NLV(jXR0c(+_VW;>J7o1W6Fwxv|pQU<{<*oTSgwCbLfznarohv`wXc~Gljl7h0)GFmLKg+rjfcl&1&PZW=YMk(Tq{5UA#!1I z1q>1=`E(!u(Y`b?$jp*^=X0TEI^dHa%@`W2Ft{v&;%3Unj#h}PE|P5o)H{sUd5(%bLeM2}jz&1PEbmft&L zHzlv4zqZvmZ->DDUn8j1B%&1XVDK@=I=7C$f>}C{D0>tpednF;WzU>G&r{+Pw!xPI zdXqt+zt7@yczWvdNBFs6*|g<8>#rSX))N@J?@%If9VT;Ey?Ab4UwB7ZOjD1>(nziX zEn*XOCmqbU6Y);9f8Qn-cKds%W0lF8Z{<9VW$L0k!1zvti06-Xzr%B_^K*m0@fVrN zM9KZ5`cg)SC0$O1!n}#tv6+>P5%0U5gXHeF?DhuB9~j5eb~`YUMBzlav1yg(JZpN# zT;sMX^vWyZj$0bIh<^j~(*%dk%#+{c%~Ri)@}3S5{fEPEu?C5Y_4b~LdORmfzp2fTIlHokni4x@yAg?QJZa_f*0H_(!J*vm@4EXq zTJ!cv9JBwjBx7Z0RUpjOt`3rScg(=?%7{tCEqp8H-+fb z{7iEX=->+xH#xjVA?QMP+5o>YRY&3G2H;uym>F!~a^5u+Wk%h?m$U5M^)lwz!=Qqt z8-Lv0Q69ZdF1jAPK^XzwDkPyW)~W`7SuU)(pydB{rN=Lu`eg0ra~Gv+k}(frA?B`O z4kQgn=JeIhPSaTwN>EH9)LK{T{cUHI4U(59$;WR1jaiu&(0bOJ~(OD*PiXBz3GNe+qq-A+~}F z{~1;a;?I@!_lCC4%pc2;%TijNYS_+58*`lC!`|EFCs*|x+nz1vEJA7IjD1PV>tnWR zwLD3Q(D59KpD;wfRe6t}O>_3_kjA(EN^kq|D;=@lS(HulWZ^^GxNSeSaq*!7G{nb; zim}3u&NSvszme1Ka@$**&{qHC8~-L&%Iy&Ok)+%1e%DFSW+=#{-v#B5o{8Mck%QWelAwg|e{MrD9j1abJjMt@!GF!NqOw|2u6C z)T0_Y*u+XJMDTuhIYu_Y`OlHWnPDq^HM69M#U8)-lCdVoAaT1iMX0FS zEU!=6<5{$HlL2(zvh1+xEB9*RtPO>SLp<6%b(XwBqjlyYG!ddgn07*0v3SHfO_i0? zTNqqm5=1c`As<1}E z|MCyc3T0SpIDxA_H3hmmdO2uq*y<1%A(Yv)OCSE2!3eh*dxNh(cZWMH`t)tl7U`Qb zehau*qWHB-+uF29A^%&xHyyy`5s{aoY~~6ZZN}7m?D6K3RR(^w($LCKFR`YKr+P4m)L^QF;A zYRn;x=+>ENd*bB&zJZ7^Exc<7N#1u}KEEWV<%(eD=Qew$uB4ACUJKX#el4z zcodG=+XY0&PT5$VG*&QRFDsE|tpoFwgy~{K@-peETjR= ze}%37&e5?2*38Y!MnkxhI^iNmuX5cvJ8{zRu2a*SOF0b`(28r9po%CFXC*&APEQz3 ziKOube0MSyV~%Hpzh&im`WfMy{+e(y_R@kF^6fG_#|+7jJ~R5M+23aP*ofqTez35Q zMB>&y$_gj)AgxSE)7&bQiJ61v`-eJ`V$wPlNZdV>L5(=mw@cW`v?* zTP_~DgueZRBg6Z2mBS=+t*wJ}n_qDF6fi`EU7pREhidG^s3lu9i*!gTH3prSNw++F zmh}sQdY26pUqF4ev3X4WzHS(y$_f;N^%Gxf`lw;>geS(+CwuIxGDx3uC^&=ez!*jzP zE47*J`S?Cf(sTHc(ukzL}|kZ z^TsbU@qqo1hoon7v3|q8%SGa@J#zFh*w@*%k^;XID@|+&&1C`FE)wxjNS+RAXklTY zL9~ZFm^=|>I{MV_zBQ4*voAEk?FQirz8%#@6VJOzlKxXg?EM(R!#@o80TlY#|H9jl+2)ht2IxFBUKH36Is%RJN{{%zPht7l`iwSoV5_{( zTuWm3woBn5aq^4uYSJ)Yi)6{;gXlDB0J~8t%;({Q&6Oo$QXx8m)4{C-L1YtWzN2@C z6)q#I7_3IAVVuARu@D;f5q=h(2M9b49TU;v6UEI5KU-fRF%Y6VLVT@=3l8FfGjKul z5mHQD1jq`0!sQKvd7qLAI_=R}3fydcwi8kbp9;bV4DVG8{z3>EA;A<}uyYDJQs?5P z(O#1{cq5$m8_;358#g$9FekKo@#FddoX^Qb1YSeN!NrL8dxC`&9jSSd1f({CtR!qR z(d$j>xa|m}ZL$)#J+_(XE#S7tdk#2`IwF}&upqh;R9xjf;^Sn2tNe>ML!RTv4(!c&FgF5^@W)k!2lkVsJ51X~VI>6mN-C;~sMN zB6ZZ9LF#Jj(BMvDFdYr9(!~eABlTJbTs<96XEz=T_=Ka6|Gkf|DuS%~ViSwaj>M}ynp+qG1!>!vQ$9kNP0|D8P~m$udRm2Oa3s0Q#Z?V>|}-cnl8U z{oWyZLsaZXSD-5<7==B(i>^zWc$utAsK=^nSsGq?^__2MeMZkZba&!%_R!veYX|3 z_9PN}R;kvdBIloLwIOidaCAmX65imha|&h%IzNXOlhVD!qK5kMONPNc=#nAgd+kew zVv>0}l?uBYR53wXy2So~2EbVFHwkTh+7!%~Or~>ImWHEShHrX*xhilK&H|f{$j#Dr zo}*T=lyoh49=he*AspzCqu#nInbDB%+t4)IjD*>RjJ7caN9vA}8Rk}Rge7$r(Rh>F zF!9hT_csB9oh`xdey${4EAhyzBt^JnI3Rp{=E)#Wq>X!&ai#+?eSOpw^W4qx4b;)GdQ%{>gvGS-Y@oYkHbR{fG#Z?GyiF1{(S@%ZY2Tx>28kL*;F6! z=S0)MVV2t}n9ic2#-L9^|8v8ltxdDcTwfo8M;+v4_x&`AsKGl>%YDW(pFA^fD=TX= z$v1iAS2gTo6-tI-nYc_|JR7xpM|<{ZM6b%WMy>xvNAjvrEPF4z9@VvjWfU^K?&}_j zHJ^t9@xM0#E;r`K%3S|Yq#u|8ko->KEi+qW4Pi?F{;5!VH^hAKlkhlVUxTTwE(-PH zBMEg4=>FuifybfWT~Tw81dM+UeEvVKJe+t(_(IyVsfzSg)$_op z9Eg{hzG?v-wJH0`?#W7jWvKzCd^oQvaTO<`CND4V$;gq$Rde7oor1cFS2{~+vmH@C zy6vp@);CJ)0WN=_@+EQTqHIOLbkwi5YPFL8@rZOyZ964?K{t(8S}K1v6&mu{ocirJ|RCfW(s`;jpOUOx}i5n z7hs!KlDb7{Zb5;TQa)vi4eTcFy0q%UPb)y`HZ56Ht7$qBBbmlsijJaBTfjuv6X6;cKJ`=17(yunt4&~>>+4XX6E1H_? z&+G~{uP%M*D?w2%z>aAhV_R119LoDJJ$9s~@-wXFGt6uMJ~=k{BJ=l)+ju{ZC7e#t zBE!ZfF+n4~4Rh2jdRiXew_TkTBK#0JjcMEW=#(Aoj@zo7uuAQKnp(oOzu0xtnK=hE zozoq7rRf-TGkS7`3pS^9+>SW7=~jAtkP6J7L!