@oomol-lab/open-connector 1.6.4 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/assets/open-connector/catalog/apps/aisa.json +6394 -0
  2. package/assets/open-connector/catalog/apps/baizhi_mcp.json +135 -0
  3. package/assets/open-connector/catalog/apps/bilibili.json +2586 -0
  4. package/assets/open-connector/catalog/apps/bitwarden.json +1423 -0
  5. package/assets/open-connector/catalog/apps/cronfree.json +303 -0
  6. package/assets/open-connector/catalog/apps/cufinder.json +368 -0
  7. package/assets/open-connector/catalog/apps/discordbot.json +2888 -248
  8. package/assets/open-connector/catalog/apps/drawio_mcp.json +192 -0
  9. package/assets/open-connector/catalog/apps/firecrawl.json +176 -32
  10. package/assets/open-connector/catalog/apps/framejet.json +273 -0
  11. package/assets/open-connector/catalog/apps/futunn.json +2967 -0
  12. package/assets/open-connector/catalog/apps/gmail.json +298 -0
  13. package/assets/open-connector/catalog/apps/google_analytics.json +4 -1
  14. package/assets/open-connector/catalog/apps/google_bigquery.json +4 -1
  15. package/assets/open-connector/catalog/apps/google_search_console.json +4 -1
  16. package/assets/open-connector/catalog/apps/googlecalendar.json +4 -1
  17. package/assets/open-connector/catalog/apps/googlechat.json +694 -7
  18. package/assets/open-connector/catalog/apps/googledocs.json +4 -1
  19. package/assets/open-connector/catalog/apps/googlesheets.json +4 -1
  20. package/assets/open-connector/catalog/apps/granola.json +23 -0
  21. package/assets/open-connector/catalog/apps/investoday_mcp.json +22228 -197
  22. package/assets/open-connector/catalog/apps/ixspy.json +2274 -0
  23. package/assets/open-connector/catalog/apps/keepa.json +3534 -987
  24. package/assets/open-connector/catalog/apps/linear.json +17 -0
  25. package/assets/open-connector/catalog/apps/linear_mcp.json +510 -0
  26. package/assets/open-connector/catalog/apps/moneyforward_mcp.json +1432 -0
  27. package/assets/open-connector/catalog/apps/notion.json +446 -1
  28. package/assets/open-connector/catalog/apps/notion_mcp.json +490 -0
  29. package/assets/open-connector/catalog/apps/odoo.json +619 -0
  30. package/assets/open-connector/catalog/apps/osv.json +663 -0
  31. package/assets/open-connector/catalog/apps/outlook.json +30 -8
  32. package/assets/open-connector/catalog/apps/outlook_calendar.json +23 -2
  33. package/assets/open-connector/catalog/apps/pdf_vector.json +329 -0
  34. package/assets/open-connector/catalog/apps/postiz.json +334 -0
  35. package/assets/open-connector/catalog/apps/proworkflow.json +529 -0
  36. package/assets/open-connector/catalog/apps/pulsetic.json +406 -0
  37. package/assets/open-connector/catalog/apps/sellersprite_mcp.json +2 -1
  38. package/assets/open-connector/catalog/apps/shopee.json +1785 -0
  39. package/assets/open-connector/catalog/apps/slack.json +304 -0
  40. package/assets/open-connector/catalog/apps/slackbot.json +295 -0
  41. package/assets/open-connector/catalog/apps/speak_ai.json +360 -0
  42. package/assets/open-connector/catalog/apps/tencent_docs.json +3 -0
  43. package/assets/open-connector/catalog/apps/wisburg.json +1528 -0
  44. package/assets/open-connector/catalog/apps/youtube.json +4 -1
  45. package/assets/open-connector/catalog/apps/zerotier.json +3319 -0
  46. package/assets/open-connector/catalog/apps/zyhub.json +1585 -0
  47. package/assets/open-connector/catalog/apps-index.json +1 -1
  48. package/package.json +1 -1
  49. package/src/core/cast.d.ts +10 -0
  50. package/src/core/cast.js +14 -0
  51. package/src/core/guarded-fetch.d.ts +6 -3
  52. package/src/core/guarded-fetch.js +6 -3
  53. package/src/core/json-schema.d.ts +5 -1
  54. package/src/core/json-schema.js +14 -2
  55. package/src/core/provider-scenarios.js +67 -13
  56. package/src/core/request.js +4 -1
  57. package/src/core/types.d.ts +10 -1
  58. package/src/mcp.js +10 -7
  59. package/src/oauth/oauth-client-config-service.d.ts +16 -1
  60. package/src/oauth/oauth-client-config-service.js +59 -3
  61. package/src/oauth/oauth-credential-refresh-service.js +3 -1
  62. package/src/oauth/oauth-flow-service.d.ts +6 -0
  63. package/src/oauth/oauth-flow-service.js +21 -4
  64. package/src/oauth/oauth-token.d.ts +13 -0
  65. package/src/providers/17track/runtime.js +1 -1
  66. package/src/providers/action-contracts.generated.d.ts +32 -8
  67. package/src/providers/aifinmarket/runtime.js +1 -1
  68. package/src/providers/aisa/executors.d.ts +4 -0
  69. package/src/providers/aisa/executors.js +864 -0
  70. package/src/providers/aliyun_ack/runtime.js +1 -1
  71. package/src/providers/aliyun_sls/runtime.js +1 -1
  72. package/src/providers/app_store_server/runtime-helpers.js +1 -1
  73. package/src/providers/baizhi_mcp/actions.d.ts +2 -0
  74. package/src/providers/baizhi_mcp/actions.js +40 -0
  75. package/src/providers/baizhi_mcp/executors.d.ts +3 -0
  76. package/src/providers/baizhi_mcp/executors.js +102 -0
  77. package/src/providers/bazhuayu/runtime.js +2 -2
  78. package/src/providers/bilibili/articles.d.ts +3 -0
  79. package/src/providers/bilibili/articles.js +369 -0
  80. package/src/providers/bilibili/executors.d.ts +8 -0
  81. package/src/providers/bilibili/executors.js +262 -0
  82. package/src/providers/bilibili/runtime.d.ts +95 -0
  83. package/src/providers/bilibili/runtime.js +236 -0
  84. package/src/providers/bilibili/upload.d.ts +14 -0
  85. package/src/providers/bilibili/upload.js +107 -0
  86. package/src/providers/bitwarden/executors.d.ts +3 -0
  87. package/src/providers/bitwarden/executors.js +146 -0
  88. package/src/providers/cloudflare_browser_rendering/executors.js +1 -1
  89. package/src/providers/cloudflare_dns/executors.js +1 -1
  90. package/src/providers/{cloudflare-current-user.js → cloudflare_dns/runtime-user.js} +2 -2
  91. package/src/providers/cloudflare_dns/runtime.d.ts +1 -1
  92. package/src/providers/cloudflare_dns/runtime.js +1 -1
  93. package/src/providers/cloudflare_r2/executors.js +1 -1
  94. package/src/providers/cloudflare_r2/runtime.d.ts +1 -1
  95. package/src/providers/cloudflare_r2/runtime.js +1 -1
  96. package/src/providers/cloudflare_worker/executors.js +1 -1
  97. package/src/providers/cloudflare_worker/runtime.d.ts +1 -1
  98. package/src/providers/cloudflare_worker/runtime.js +1 -1
  99. package/src/providers/cronfree/executors.d.ts +4 -0
  100. package/src/providers/cronfree/executors.js +89 -0
  101. package/src/providers/cufinder/executors.d.ts +4 -0
  102. package/src/providers/cufinder/executors.js +105 -0
  103. package/src/providers/dingtalk_mcp/runtime.js +1 -1
  104. package/src/providers/discordbot/executors.d.ts +0 -9
  105. package/src/providers/discordbot/executors.js +9 -101
  106. package/src/providers/discordbot/runtime-guilds.d.ts +3 -0
  107. package/src/providers/discordbot/runtime-guilds.js +464 -0
  108. package/src/providers/discordbot/runtime.d.ts +42 -0
  109. package/src/providers/discordbot/runtime.js +124 -0
  110. package/src/providers/drawio_mcp/executors.d.ts +3 -0
  111. package/src/providers/drawio_mcp/executors.js +19 -0
  112. package/src/providers/drawio_mcp/runtime.d.ts +8 -0
  113. package/src/providers/drawio_mcp/runtime.js +175 -0
  114. package/src/providers/elevenreader/runtime.js +6 -5
  115. package/src/providers/fastmoss_mcp/executors.js +2 -2
  116. package/src/providers/finchina/executors.js +1 -1
  117. package/src/providers/framejet/executors.d.ts +4 -0
  118. package/src/providers/framejet/executors.js +19 -0
  119. package/src/providers/framejet/runtime.d.ts +16 -0
  120. package/src/providers/framejet/runtime.js +148 -0
  121. package/src/providers/futunn/actions.d.ts +2 -0
  122. package/src/providers/futunn/actions.js +152 -0
  123. package/src/providers/futunn/actions.research.d.ts +2 -0
  124. package/src/providers/futunn/actions.research.js +423 -0
  125. package/src/providers/futunn/actions.trading.d.ts +2 -0
  126. package/src/providers/futunn/actions.trading.js +204 -0
  127. package/src/providers/futunn/executors.d.ts +3 -0
  128. package/src/providers/futunn/executors.js +24 -0
  129. package/src/providers/futunn/runtime-research.d.ts +3 -0
  130. package/src/providers/futunn/runtime-research.js +133 -0
  131. package/src/providers/futunn/runtime-trading.d.ts +3 -0
  132. package/src/providers/futunn/runtime-trading.js +39 -0
  133. package/src/providers/futunn/runtime.d.ts +2 -0
  134. package/src/providers/futunn/runtime.js +50 -0
  135. package/src/providers/futunn/transport.d.ts +11 -0
  136. package/src/providers/futunn/transport.js +76 -0
  137. package/src/providers/gildata/executors.js +1 -1
  138. package/src/providers/gmail/attachment-stream.d.ts +2 -0
  139. package/src/providers/gmail/attachment-stream.js +162 -0
  140. package/src/providers/gmail/executors.d.ts +3 -1
  141. package/src/providers/gmail/executors.js +54 -26
  142. package/src/providers/gmail/message.d.ts +6 -8
  143. package/src/providers/gmail/message.js +4 -0
  144. package/src/providers/gmail/scopes.d.ts +32 -0
  145. package/src/providers/gmail/scopes.js +37 -0
  146. package/src/providers/google_analytics/executors.js +2 -2
  147. package/src/providers/google_analytics/scopes.js +6 -1
  148. package/src/providers/google_bigquery/executors.js +2 -2
  149. package/src/providers/google_bigquery/scopes.js +2 -0
  150. package/src/providers/google_search_console/executors.js +2 -2
  151. package/src/providers/google_search_console/scopes.js +2 -0
  152. package/src/providers/googleads/executors.js +1 -1
  153. package/src/providers/googleads/scopes.d.ts +1 -3
  154. package/src/providers/googleads/scopes.js +2 -4
  155. package/src/providers/googlecalendar/executors.js +1 -1
  156. package/src/providers/googlecalendar/runtime-shared.js +2 -2
  157. package/src/providers/googlecalendar/scopes.js +2 -0
  158. package/src/providers/googlechat/executors.d.ts +1 -3
  159. package/src/providers/googlechat/executors.js +219 -28
  160. package/src/providers/googlechat/members.d.ts +55 -0
  161. package/src/providers/googlechat/members.js +293 -0
  162. package/src/providers/googlechat/runtime.d.ts +16 -0
  163. package/src/providers/googlechat/runtime.js +25 -0
  164. package/src/providers/googlechat/scopes.d.ts +22 -3
  165. package/src/providers/googlechat/scopes.js +30 -7
  166. package/src/providers/googledocs/executors.js +1 -1
  167. package/src/providers/googledrive/executors.js +2 -2
  168. package/src/providers/{google-auth.d.ts → googledrive/runtime-auth.d.ts} +2 -2
  169. package/src/providers/{google-auth.js → googledrive/runtime-auth.js} +3 -3
  170. package/src/providers/googledrive/runtime-collaboration.js +1 -1
  171. package/src/providers/{google-runtime.d.ts → googledrive/runtime-request.d.ts} +1 -1
  172. package/src/providers/{google-runtime.js → googledrive/runtime-request.js} +2 -2
  173. package/src/providers/googleforms/executors.js +2 -2
  174. package/src/providers/googleforms/scopes.d.ts +0 -3
  175. package/src/providers/googleforms/scopes.js +2 -6
  176. package/src/providers/googlemeet/executors.js +2 -2
  177. package/src/providers/googlemeet/scopes.d.ts +0 -3
  178. package/src/providers/googlemeet/scopes.js +2 -6
  179. package/src/providers/googlesheets/executors.js +1 -1
  180. package/src/providers/googlesheets/scopes.js +2 -0
  181. package/src/providers/googleslides/executors.js +2 -2
  182. package/src/providers/googleslides/scopes.d.ts +0 -3
  183. package/src/providers/googleslides/scopes.js +2 -6
  184. package/src/providers/googletasks/executors.js +2 -2
  185. package/src/providers/googletasks/scopes.d.ts +0 -3
  186. package/src/providers/googletasks/scopes.js +2 -6
  187. package/src/providers/granola/actions.js +2 -0
  188. package/src/providers/granola/runtime-mcp.js +2 -0
  189. package/src/providers/granola/runtime.js +2 -2
  190. package/src/providers/indiegogo/executors.js +1 -1
  191. package/src/providers/investoday_mcp/executors.js +2 -2
  192. package/src/providers/investoday_mcp/official-actions.js +19 -372
  193. package/src/providers/investoday_mcp/official-tool-types.d.ts +10 -0
  194. package/src/providers/investoday_mcp/official-tool-types.js +4 -0
  195. package/src/providers/investoday_mcp/official-tools/charts.d.ts +2 -0
  196. package/src/providers/investoday_mcp/official-tools/charts.js +32 -0
  197. package/src/providers/investoday_mcp/official-tools/fixed-income.d.ts +2 -0
  198. package/src/providers/investoday_mcp/official-tools/fixed-income.js +326 -0
  199. package/src/providers/investoday_mcp/official-tools/funds.d.ts +2 -0
  200. package/src/providers/investoday_mcp/official-tools/funds.js +1085 -0
  201. package/src/providers/investoday_mcp/official-tools/hong-kong.d.ts +2 -0
  202. package/src/providers/investoday_mcp/official-tools/hong-kong.js +275 -0
  203. package/src/providers/investoday_mcp/official-tools/indices-industries.d.ts +2 -0
  204. package/src/providers/investoday_mcp/official-tools/indices-industries.js +642 -0
  205. package/src/providers/investoday_mcp/official-tools/macro-calendar.d.ts +2 -0
  206. package/src/providers/investoday_mcp/official-tools/macro-calendar.js +398 -0
  207. package/src/providers/investoday_mcp/official-tools/other.d.ts +2 -0
  208. package/src/providers/investoday_mcp/official-tools/other.js +131 -0
  209. package/src/providers/investoday_mcp/official-tools/research-news.d.ts +2 -0
  210. package/src/providers/investoday_mcp/official-tools/research-news.js +302 -0
  211. package/src/providers/investoday_mcp/official-tools/stocks.d.ts +2 -0
  212. package/src/providers/investoday_mcp/official-tools/stocks.js +2829 -0
  213. package/src/providers/ixspy/executors.d.ts +3 -0
  214. package/src/providers/ixspy/executors.js +220 -0
  215. package/src/providers/iyunbiao/runtime.js +2 -2
  216. package/src/providers/keepa/actions.d.ts +1 -1
  217. package/src/providers/keepa/actions.js +371 -149
  218. package/src/providers/keepa/deal-attributes.d.ts +1 -0
  219. package/src/providers/keepa/deal-attributes.js +26 -0
  220. package/src/providers/keepa/runtime.js +212 -18
  221. package/src/providers/kingdee/executors.js +1 -1
  222. package/src/providers/kingdee/runtime.js +2 -2
  223. package/src/providers/kuaidi100/runtime.js +1 -1
  224. package/src/providers/linear/executors.js +12 -9
  225. package/src/providers/linear_mcp/actions.d.ts +47 -0
  226. package/src/providers/linear_mcp/actions.js +102 -0
  227. package/src/providers/linear_mcp/endpoints.d.ts +3 -0
  228. package/src/providers/linear_mcp/endpoints.js +3 -0
  229. package/src/providers/linear_mcp/executors.d.ts +3 -0
  230. package/src/providers/linear_mcp/executors.js +9 -0
  231. package/src/providers/linear_mcp/runtime-mcp.d.ts +15 -0
  232. package/src/providers/linear_mcp/runtime-mcp.js +238 -0
  233. package/src/providers/lingxing_mcp/runtime.js +1 -1
  234. package/src/providers/mcdonalds_cn_mcp/runtime.js +1 -1
  235. package/src/providers/metabase/mcp-runtime.js +1 -1
  236. package/src/providers/moneyforward_mcp/executors.d.ts +3 -0
  237. package/src/providers/moneyforward_mcp/executors.js +11 -0
  238. package/src/providers/moneyforward_mcp/manifest.d.ts +31 -0
  239. package/src/providers/moneyforward_mcp/manifest.js +204 -0
  240. package/src/providers/moneyforward_mcp/runtime.d.ts +18 -0
  241. package/src/providers/moneyforward_mcp/runtime.js +296 -0
  242. package/src/providers/notion/executors.js +39 -3
  243. package/src/providers/notion_mcp/endpoints.d.ts +3 -0
  244. package/src/providers/notion_mcp/endpoints.js +3 -0
  245. package/src/providers/notion_mcp/executors.d.ts +3 -0
  246. package/src/providers/notion_mcp/executors.js +176 -0
  247. package/src/providers/notion_mcp/mcp-response.d.ts +86 -0
  248. package/src/providers/notion_mcp/mcp-response.js +314 -0
  249. package/src/providers/odoo/executors.d.ts +3 -0
  250. package/src/providers/odoo/executors.js +32 -0
  251. package/src/providers/odoo/runtime.d.ts +16 -0
  252. package/src/providers/odoo/runtime.js +140 -0
  253. package/src/providers/osv/executors.d.ts +2 -0
  254. package/src/providers/osv/executors.js +11 -0
  255. package/src/providers/osv/runtime.d.ts +9 -0
  256. package/src/providers/osv/runtime.js +66 -0
  257. package/src/providers/outlook/executors.js +27 -6
  258. package/src/providers/outlook/microsoft-graph.js +17 -6
  259. package/src/providers/outlook_calendar/executors.js +24 -7
  260. package/src/providers/patsnap_mcp/executors.js +2 -2
  261. package/src/providers/pdf_vector/executors.d.ts +4 -0
  262. package/src/providers/pdf_vector/executors.js +108 -0
  263. package/src/providers/postiz/executors.d.ts +4 -0
  264. package/src/providers/postiz/executors.js +83 -0
  265. package/src/providers/provider-runtime.d.ts +18 -0
  266. package/src/providers/provider-runtime.js +60 -4
  267. package/src/providers/proworkflow/executors.d.ts +4 -0
  268. package/src/providers/proworkflow/executors.js +135 -0
  269. package/src/providers/pulsetic/executors.d.ts +4 -0
  270. package/src/providers/pulsetic/executors.js +126 -0
  271. package/src/providers/registry.generated.js +24 -0
  272. package/src/providers/scrape_creators/catalog.js +1 -1
  273. package/src/providers/scrape_creators/runtime.js +1 -1
  274. package/src/providers/sellersprite_mcp/executors.js +2 -2
  275. package/src/providers/sellersprite_mcp/official-actions.js +3 -2
  276. package/src/providers/sentry/runtime.js +6 -7
  277. package/src/providers/shopee/actions.d.ts +2 -0
  278. package/src/providers/shopee/actions.js +474 -0
  279. package/src/providers/shopee/executors.d.ts +3 -0
  280. package/src/providers/shopee/executors.js +85 -0
  281. package/src/providers/shopee/runtime.d.ts +79 -0
  282. package/src/providers/shopee/runtime.js +693 -0
  283. package/src/providers/slack/actions.js +69 -3
  284. package/src/providers/slack/runtime.js +116 -21
  285. package/src/providers/slickdeals/runtime.js +1 -1
  286. package/src/providers/sorftime_mcp/executors.js +2 -2
  287. package/src/providers/speak_ai/executors.d.ts +3 -0
  288. package/src/providers/speak_ai/executors.js +187 -0
  289. package/src/providers/tikhub/bounded-response.d.ts +1 -1
  290. package/src/providers/tikhub/bounded-response.js +8 -34
  291. package/src/providers/tikhub/endpoint-catalog.js +1 -1
  292. package/src/providers/tikhub/runtime.js +2 -2
  293. package/src/providers/tongdaxin/executors.js +79 -15
  294. package/src/providers/tushare/runtime.js +22 -9
  295. package/src/providers/uspto/executors.js +1 -1
  296. package/src/providers/waffo/executors.js +1 -1
  297. package/src/providers/waffo/runtime.js +1 -1
  298. package/src/providers/wecom_mcp/runtime.js +1 -1
  299. package/src/providers/wisburg/executors.d.ts +4 -0
  300. package/src/providers/wisburg/executors.js +13 -0
  301. package/src/providers/wisburg/runtime.d.ts +12 -0
  302. package/src/providers/wisburg/runtime.js +133 -0
  303. package/src/providers/xydc_mcp/executors.js +2 -2
  304. package/src/providers/youtube/executors.js +1 -1
  305. package/src/providers/youtube/runtime.js +1 -1
  306. package/src/providers/zerotier/executors.d.ts +9 -0
  307. package/src/providers/zerotier/executors.js +629 -0
  308. package/src/providers/zerotier/runtime.d.ts +54 -0
  309. package/src/providers/zerotier/runtime.js +207 -0
  310. package/src/providers/zyhub/executors.d.ts +3 -0
  311. package/src/providers/zyhub/executors.js +240 -0
  312. package/src/server/api/openapi.js +12 -2
  313. package/src/server/api/runtime-api.d.ts +8 -1
  314. package/src/server/api/runtime-api.js +19 -1
  315. package/src/server/connect-server.js +10 -2
  316. package/src/server/files/transit-files.d.ts +3 -2
  317. package/src/server/files/transit-files.js +31 -35
  318. package/src/providers/sentry/scopes.d.ts +0 -1
  319. package/src/providers/sentry/scopes.js +0 -7
  320. /package/src/providers/{cloudflare-current-user.d.ts → cloudflare_dns/runtime-user.d.ts} +0 -0
@@ -0,0 +1,204 @@
1
+ import { s } from "../../core/json-schema.js";
2
+ import { defineProviderAction } from "../../core/provider-definition.js";
3
+ export const futunnTradingActions = [
4
+ defineProviderAction("futunn", {
5
+ name: "list_open_orders",
6
+ operationType: "read",
7
+ description: "List recent orders, including pending orders and orders filled or cancelled in the last 24 hours.",
8
+ requiredScopes: ["trade:read"],
9
+ inputSchema: s.object("Account order or fill query.", {
10
+ accountId: s.string("Trading account ID as a decimal string.", { pattern: "^[0-9]+$" }),
11
+ market: s.stringEnum("Trading market; HKCC denotes China Stock Connect.", [
12
+ "NONE",
13
+ "HK",
14
+ "US",
15
+ "SG",
16
+ "HKCC",
17
+ "CA",
18
+ "FUTURES",
19
+ "JP",
20
+ "KR",
21
+ "MY",
22
+ "AU",
23
+ ]),
24
+ pageFlag: s.string("Opaque page flag; omit or use an empty string for the first page."),
25
+ pageSize: s.integer("Page size; default 50, range 10-100.", { minimum: 10, maximum: 100 }),
26
+ }, { optional: ["pageFlag", "pageSize"] }),
27
+ outputSchema: s.requiredObject("One page of account records.", {
28
+ orders: s.array("Returned account records in provider order.", s.looseObject("Order with original quantities, prices and status fields.", {
29
+ order_id: s.string("Order ID."),
30
+ code: s.string("Security code including market prefix, for example HK.00700.", {
31
+ minLength: 1,
32
+ }),
33
+ order_status: s.string("Order status."),
34
+ qty: s.string("Quantity as a decimal string."),
35
+ price: s.string("Price as a decimal string."),
36
+ create_time: s.integer("Creation timestamp in microseconds."),
37
+ })),
38
+ pageFlag: s.nullable(s.string("Next-page flag; null when omitted.")),
39
+ completed: s.nullable(s.boolean("True means this batch is complete; null means the provider omitted the flag.")),
40
+ }),
41
+ }),
42
+ defineProviderAction("futunn", {
43
+ name: "list_history_orders",
44
+ operationType: "read",
45
+ description: "List historical orders filtered by creation time in microseconds.",
46
+ requiredScopes: ["trade:read"],
47
+ inputSchema: s.object("Account order or fill query.", {
48
+ accountId: s.string("Trading account ID as a decimal string.", { pattern: "^[0-9]+$" }),
49
+ market: s.stringEnum("Trading market; HKCC denotes China Stock Connect.", [
50
+ "NONE",
51
+ "HK",
52
+ "US",
53
+ "SG",
54
+ "HKCC",
55
+ "CA",
56
+ "FUTURES",
57
+ "JP",
58
+ "KR",
59
+ "MY",
60
+ "AU",
61
+ ]),
62
+ pageFlag: s.string("Opaque page flag; omit or use an empty string for the first page."),
63
+ pageSize: s.integer("Page size; default 50, range 10-100.", { minimum: 10, maximum: 100 }),
64
+ code: s.string("Security code including market prefix, for example HK.00700.", {
65
+ minLength: 1,
66
+ }),
67
+ start: s.string("Unix timestamp in microseconds as a decimal string; 0 uses the provider 90-day default window.", { pattern: "^[0-9]+$" }),
68
+ end: s.string("Unix timestamp in microseconds as a decimal string; 0 uses the provider 90-day default window.", { pattern: "^[0-9]+$" }),
69
+ }, { optional: ["pageFlag", "pageSize", "code", "start", "end"] }),
70
+ outputSchema: s.requiredObject("One page of account records.", {
71
+ orders: s.array("Returned account records in provider order.", s.looseObject("Order with original quantities, prices and status fields.", {
72
+ order_id: s.string("Order ID."),
73
+ code: s.string("Security code including market prefix, for example HK.00700.", {
74
+ minLength: 1,
75
+ }),
76
+ order_status: s.string("Order status."),
77
+ qty: s.string("Quantity as a decimal string."),
78
+ price: s.string("Price as a decimal string."),
79
+ create_time: s.integer("Creation timestamp in microseconds."),
80
+ })),
81
+ pageFlag: s.nullable(s.string("Next-page flag; null when omitted.")),
82
+ completed: s.nullable(s.boolean("True means this batch is complete; null means the provider omitted the flag.")),
83
+ }),
84
+ }),
85
+ defineProviderAction("futunn", {
86
+ name: "list_today_deals",
87
+ operationType: "read",
88
+ description: "List today's execution fills for a trading account.",
89
+ requiredScopes: ["trade:read"],
90
+ inputSchema: s.object("Account order or fill query.", {
91
+ accountId: s.string("Trading account ID as a decimal string.", { pattern: "^[0-9]+$" }),
92
+ market: s.stringEnum("Trading market; HKCC denotes China Stock Connect.", [
93
+ "NONE",
94
+ "HK",
95
+ "US",
96
+ "SG",
97
+ "HKCC",
98
+ "CA",
99
+ "FUTURES",
100
+ "JP",
101
+ "KR",
102
+ "MY",
103
+ "AU",
104
+ ]),
105
+ pageFlag: s.string("Opaque page flag; omit or use an empty string for the first page."),
106
+ pageSize: s.integer("Page size; default 50, range 10-100.", { minimum: 10, maximum: 100 }),
107
+ }, { optional: ["pageFlag", "pageSize"] }),
108
+ outputSchema: s.requiredObject("One page of account records.", {
109
+ deals: s.array("Returned account records in provider order.", s.looseObject("Execution fill record.", {
110
+ deal_id: s.string("Case-sensitive base58 fill ID; preserve exactly."),
111
+ order_id: s.string("Order ID."),
112
+ qty: s.string("Quantity as a decimal string."),
113
+ price: s.string("Price as a decimal string."),
114
+ create_time: s.integer("Creation timestamp in microseconds."),
115
+ })),
116
+ pageFlag: s.nullable(s.string("Next-page flag; null when omitted.")),
117
+ completed: s.nullable(s.boolean("True means this batch is complete; null means the provider omitted the flag.")),
118
+ }),
119
+ }),
120
+ defineProviderAction("futunn", {
121
+ name: "list_history_deals",
122
+ operationType: "read",
123
+ description: "List historical execution fills filtered by update time in microseconds.",
124
+ requiredScopes: ["trade:read"],
125
+ inputSchema: s.object("Account order or fill query.", {
126
+ accountId: s.string("Trading account ID as a decimal string.", { pattern: "^[0-9]+$" }),
127
+ market: s.stringEnum("Trading market; HKCC denotes China Stock Connect.", [
128
+ "NONE",
129
+ "HK",
130
+ "US",
131
+ "SG",
132
+ "HKCC",
133
+ "CA",
134
+ "FUTURES",
135
+ "JP",
136
+ "KR",
137
+ "MY",
138
+ "AU",
139
+ ]),
140
+ pageFlag: s.string("Opaque page flag; omit or use an empty string for the first page."),
141
+ pageSize: s.integer("Page size; default 50, range 10-50.", { minimum: 10, maximum: 50 }),
142
+ code: s.string("Security code including market prefix, for example HK.00700.", {
143
+ minLength: 1,
144
+ }),
145
+ start: s.string("Unix timestamp in microseconds as a decimal string; 0 uses the provider 90-day default window.", { pattern: "^[0-9]+$" }),
146
+ end: s.string("Unix timestamp in microseconds as a decimal string; 0 uses the provider 90-day default window.", { pattern: "^[0-9]+$" }),
147
+ }, { optional: ["pageFlag", "pageSize", "code", "start", "end"] }),
148
+ outputSchema: s.requiredObject("One page of account records.", {
149
+ deals: s.array("Returned account records in provider order.", s.looseObject("Execution fill record.", {
150
+ deal_id: s.string("Case-sensitive base58 fill ID; preserve exactly."),
151
+ order_id: s.string("Order ID."),
152
+ qty: s.string("Quantity as a decimal string."),
153
+ price: s.string("Price as a decimal string."),
154
+ create_time: s.integer("Creation timestamp in microseconds."),
155
+ })),
156
+ pageFlag: s.nullable(s.string("Next-page flag; null when omitted.")),
157
+ completed: s.nullable(s.boolean("True means this batch is complete; null means the provider omitted the flag.")),
158
+ }),
159
+ }),
160
+ defineProviderAction("futunn", {
161
+ name: "get_order_details",
162
+ operationType: "read",
163
+ description: "Get details of fewer than 50 orders from the same exchange.",
164
+ requiredScopes: ["trade:read"],
165
+ inputSchema: s.requiredObject("Order detail query.", {
166
+ accountId: s.string("Trading account ID as a decimal string.", { pattern: "^[0-9]+$" }),
167
+ exchange: s.stringEnum("Exchange shared by all requested orders.", [
168
+ "US",
169
+ "SEHK",
170
+ "SGX",
171
+ "SSE",
172
+ "SZSE",
173
+ "JP",
174
+ "CA",
175
+ "CME",
176
+ "CBOT",
177
+ "NYMEX",
178
+ "COMEX",
179
+ "CBOE",
180
+ "HKFE",
181
+ "KR",
182
+ "BMS",
183
+ "BMD",
184
+ "ASX",
185
+ ]),
186
+ orderIds: s.array("Order IDs from the same exchange.", s.string("Order ID.", { minLength: 1 }), {
187
+ minItems: 1,
188
+ maxItems: 49,
189
+ }),
190
+ }),
191
+ outputSchema: s.requiredObject("Order detail results.", {
192
+ orders: s.array("Order details.", s.looseObject("Order with original quantities, prices and status fields.", {
193
+ order_id: s.string("Order ID."),
194
+ code: s.string("Security code including market prefix, for example HK.00700.", {
195
+ minLength: 1,
196
+ }),
197
+ order_status: s.string("Order status."),
198
+ qty: s.string("Quantity as a decimal string."),
199
+ price: s.string("Price as a decimal string."),
200
+ create_time: s.integer("Creation timestamp in microseconds."),
201
+ })),
202
+ }),
203
+ }),
204
+ ];
@@ -0,0 +1,3 @@
1
+ import type { ProviderExecutors, ProviderProxyExecutor } from "../../core/types.ts";
2
+ export declare const executors: ProviderExecutors;
3
+ export declare const proxy: ProviderProxyExecutor;
@@ -0,0 +1,24 @@
1
+ import { defineOAuthProviderExecutors, defineProviderProxy } from "../provider-runtime.js";
2
+ import { futunnActions } from "./actions.js";
3
+ import { executeFutunnAction } from "./runtime.js";
4
+ import { futunnApiBaseUrl } from "./transport.js";
5
+ const service = "futunn";
6
+ function createHandler(actionName) {
7
+ return (input, context) => executeFutunnAction({
8
+ actionName,
9
+ input,
10
+ accessToken: context.accessToken,
11
+ signal: context.signal,
12
+ }, context.fetcher);
13
+ }
14
+ const handlers = Object.fromEntries(futunnActions.map((action) => [action.name, createHandler(action.name)]));
15
+ export const executors = defineOAuthProviderExecutors(service, handlers);
16
+ export const proxy = defineProviderProxy({
17
+ service,
18
+ baseUrl: futunnApiBaseUrl,
19
+ auth: { type: "oauth_bearer" },
20
+ skipDnsValidation: true,
21
+ customizeRequest({ headers }) {
22
+ headers.set("accept", "application/json");
23
+ },
24
+ });
@@ -0,0 +1,3 @@
1
+ import type { FutunnActionInput } from "./transport.ts";
2
+ export declare function isFutunnResearchAction(name: string): boolean;
3
+ export declare function executeFutunnResearchAction(input: FutunnActionInput, fetcher: typeof fetch): Promise<unknown>;
@@ -0,0 +1,133 @@
1
+ import { optionalNumber, optionalRecord } from "../../core/cast.js";
2
+ import { ProviderRequestError, requiredInputString, requiredResponseRecord } from "../provider-runtime.js";
3
+ import { futunnResearchActions } from "./actions.research.js";
4
+ import { readFutunnData, readFutunnList, requestFutunn } from "./transport.js";
5
+ const researchNames = new Set(futunnResearchActions.map((action) => action.name));
6
+ export function isFutunnResearchAction(name) {
7
+ return researchNames.has(name);
8
+ }
9
+ export async function executeFutunnResearchAction(input, fetcher) {
10
+ const v = input.input;
11
+ const request = (path, query, body, allowNoData = false) => requestFutunn(input, fetcher, path, query, body, allowNoData);
12
+ const securityPath = (suffix) => `/api/v1.0/quote/${encodeURIComponent(requiredInputString(v.symbol, "symbol"))}/${suffix}`;
13
+ switch (input.actionName) {
14
+ case "search_news":
15
+ case "search_community": {
16
+ const news = input.actionName === "search_news";
17
+ const envelope = await request(`/api/v1.0/quote/${news ? "find-news" : "find-community"}`, {
18
+ symbol: v.keyword,
19
+ size: v.size,
20
+ [news ? "news_type" : "community_type"]: v.type,
21
+ sort_type: v.sortType,
22
+ lang: v.language,
23
+ });
24
+ return { items: readFutunnList(readFutunnData(envelope), "search results") };
25
+ }
26
+ case "get_security_info": {
27
+ const data = requiredResponseRecord(readFutunnData(await request("/api/v1.0/quote/stock-basicinfo", {}, { code_list: v.symbols })), "Futunn security info");
28
+ return { securities: readFutunnList(data.basic_list, "basic_list") };
29
+ }
30
+ case "get_market_state": {
31
+ const data = requiredResponseRecord(readFutunnData(await request("/api/v1.0/quote/market-state", {}, {
32
+ code_list: v.symbols,
33
+ is_contain_ba: v.includePreAfterMarket,
34
+ is_contain_overnight: v.includeOvernight,
35
+ is_need_crypto_multi_broker: v.includeCryptoBrokers,
36
+ })), "Futunn market state");
37
+ return { states: readFutunnList(data.market_state_list, "market_state_list") };
38
+ }
39
+ case "screen_stocks": {
40
+ const envelope = await request("/api/v1.0/quote/stock-screen", {}, {
41
+ screen_queries: v.screenQueries,
42
+ retrieve_queries: v.retrieveQueries,
43
+ sort: v.sort,
44
+ sorts: v.sorts,
45
+ next_key: v.nextKey,
46
+ limit: v.limit,
47
+ watchlist_stock_ids: v.watchlistStockIds,
48
+ holding_stock_ids: v.holdingStockIds,
49
+ user_stock_list_mode: v.userStockListMode,
50
+ });
51
+ const data = requiredResponseRecord(readFutunnData(envelope), "Futunn screening data");
52
+ return {
53
+ items: readFutunnList(data.items, "screening items"),
54
+ pagination: optionalRecord(envelope.pagination) ?? null,
55
+ };
56
+ }
57
+ case "get_financial_statements": {
58
+ const envelope = await request(securityPath("financials/statements"), {
59
+ statement_type: v.statementType,
60
+ financial_type: v.financialType,
61
+ currency_code: v.currencyCode,
62
+ next_key: v.nextKey,
63
+ limit: v.limit,
64
+ }, undefined, true);
65
+ const noData = envelope.ret_code === -10;
66
+ const data = noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn financial statements");
67
+ return {
68
+ reports: data === null ? [] : readFutunnList(data.report_list, "report_list"),
69
+ pagination: optionalRecord(envelope.pagination) ?? null,
70
+ noData,
71
+ };
72
+ }
73
+ case "get_revenue_breakdown": {
74
+ const envelope = await request(securityPath("financials/revenue-breakdown"), { date: v.date, financial_type: v.financialType, currency_code: v.currencyCode }, undefined, true);
75
+ const noData = envelope.ret_code === -10;
76
+ return {
77
+ revenue: noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn revenue breakdown"),
78
+ noData,
79
+ };
80
+ }
81
+ case "get_operational_efficiency": {
82
+ const envelope = await request(securityPath("company/operational-efficiency"), {
83
+ limit: v.limit,
84
+ financial_type: v.financialType,
85
+ currency_code: v.currencyCode,
86
+ next_key: v.nextKey,
87
+ }, undefined, true);
88
+ const noData = envelope.ret_code === -10;
89
+ return {
90
+ efficiency: noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn operational efficiency"),
91
+ pagination: optionalRecord(envelope.pagination) ?? null,
92
+ noData,
93
+ };
94
+ }
95
+ case "get_valuation":
96
+ return {
97
+ valuation: requiredResponseRecord(readFutunnData(await request(securityPath("valuation/detail"), {
98
+ valuation_type: v.valuationType,
99
+ interval_type: v.intervalType,
100
+ })), "Futunn valuation"),
101
+ };
102
+ case "get_capital_flow": {
103
+ const data = requiredResponseRecord(readFutunnData(await request(securityPath("capital-flow"), { section: v.section })), "Futunn capital flow");
104
+ return {
105
+ flows: readFutunnList(data.flow_list, "flow_list"),
106
+ lastValidTime: optionalNumber(data.last_valid_time) ?? null,
107
+ };
108
+ }
109
+ case "get_capital_flow_history": {
110
+ const envelope = await request(securityPath("capital-flow/history"), {
111
+ period_type: v.periodType,
112
+ start: v.start,
113
+ end: v.end,
114
+ count: v.count,
115
+ });
116
+ const data = requiredResponseRecord(readFutunnData(envelope), "Futunn capital flow history");
117
+ return {
118
+ flows: readFutunnList(data.flow_list, "flow_list"),
119
+ pagination: optionalRecord(envelope.pagination) ?? null,
120
+ };
121
+ }
122
+ case "get_capital_distribution": {
123
+ const envelope = await request(securityPath("capital-distribution"), {}, undefined, true);
124
+ const noData = envelope.ret_code === -10;
125
+ return {
126
+ distribution: noData ? null : requiredResponseRecord(readFutunnData(envelope), "Futunn capital distribution"),
127
+ noData,
128
+ };
129
+ }
130
+ default:
131
+ throw new ProviderRequestError(400, `Unknown Futunn research action: ${input.actionName}`);
132
+ }
133
+ }
@@ -0,0 +1,3 @@
1
+ import type { FutunnActionInput } from "./transport.ts";
2
+ export declare function isFutunnTradingAction(name: string): boolean;
3
+ export declare function executeFutunnTradingAction(input: FutunnActionInput, fetcher: typeof fetch): Promise<unknown>;
@@ -0,0 +1,39 @@
1
+ import { optionalBoolean, optionalString } from "../../core/cast.js";
2
+ import { ProviderRequestError, requiredInputString, requiredResponseRecord } from "../provider-runtime.js";
3
+ import { futunnTradingActions } from "./actions.trading.js";
4
+ import { readFutunnData, readFutunnList, requestFutunn } from "./transport.js";
5
+ const tradingNames = new Set(futunnTradingActions.map((action) => action.name));
6
+ export function isFutunnTradingAction(name) {
7
+ return tradingNames.has(name);
8
+ }
9
+ const listEndpoints = {
10
+ list_open_orders: { path: "orders", field: "orders", history: false },
11
+ list_history_orders: { path: "orders_history", field: "orders", history: true },
12
+ list_today_deals: { path: "order_fills", field: "order_fills", history: false },
13
+ list_history_deals: { path: "fills_history", field: "order_fills", history: true },
14
+ };
15
+ export async function executeFutunnTradingAction(input, fetcher) {
16
+ const v = input.input;
17
+ const path = `/api/v1.0/accounts/${encodeURIComponent(requiredInputString(v.accountId, "accountId"))}`;
18
+ if (input.actionName === "get_order_details") {
19
+ const envelope = await requestFutunn(input, fetcher, `${path}/orders/detail`, {}, { exchange: v.exchange, order_ids: v.orderIds });
20
+ return { orders: readFutunnList(readFutunnData(envelope), "order details") };
21
+ }
22
+ const endpoint = listEndpoints[input.actionName];
23
+ if (!endpoint)
24
+ throw new ProviderRequestError(400, `Unknown Futunn trading action: ${input.actionName}`);
25
+ const envelope = await requestFutunn(input, fetcher, `${path}/${endpoint.path}`, {
26
+ trd_market: v.market,
27
+ page_flag: v.pageFlag ?? "",
28
+ page_size: v.pageSize,
29
+ code: endpoint.history ? v.code : undefined,
30
+ start: endpoint.history ? v.start : undefined,
31
+ end: endpoint.history ? v.end : undefined,
32
+ });
33
+ const data = requiredResponseRecord(readFutunnData(envelope), "Futunn account records");
34
+ return {
35
+ [endpoint.field === "orders" ? "orders" : "deals"]: readFutunnList(data[endpoint.field], endpoint.field),
36
+ pageFlag: optionalString(data.page_flag) ?? null,
37
+ completed: optionalBoolean(data.completed) ?? null,
38
+ };
39
+ }
@@ -0,0 +1,2 @@
1
+ import type { FutunnActionInput } from "./transport.ts";
2
+ export declare function executeFutunnAction(input: FutunnActionInput, fetcher: typeof fetch): Promise<unknown>;
@@ -0,0 +1,50 @@
1
+ import { optionalNumber } from "../../core/cast.js";
2
+ import { requiredInputString, requiredResponseRecord } from "../provider-runtime.js";
3
+ import { executeFutunnResearchAction, isFutunnResearchAction } from "./runtime-research.js";
4
+ import { executeFutunnTradingAction, isFutunnTradingAction } from "./runtime-trading.js";
5
+ import { readFutunnData, readFutunnList, requestFutunn } from "./transport.js";
6
+ export async function executeFutunnAction(input, fetcher) {
7
+ const values = input.input;
8
+ const request = (path, query, body) => requestFutunn(input, fetcher, path, query, body).then(readFutunnData);
9
+ if (isFutunnResearchAction(input.actionName))
10
+ return executeFutunnResearchAction(input, fetcher);
11
+ if (isFutunnTradingAction(input.actionName))
12
+ return executeFutunnTradingAction(input, fetcher);
13
+ switch (input.actionName) {
14
+ case "get_market_snapshot": {
15
+ const data = requiredResponseRecord(await request("/api/v1.0/quote/snapshot", {}, { code_list: values.symbols }), "Futunn snapshot data");
16
+ return { snapshots: readFutunnList(data.snapshot_list, "snapshot_list") };
17
+ }
18
+ case "get_history_kline": {
19
+ const data = requiredResponseRecord(await request(`/api/v1.0/quote/${encodeURIComponent(requiredInputString(values.symbol, "symbol"))}/history-kline`, {
20
+ start: values.start,
21
+ end: values.end,
22
+ ktype: values.ktype,
23
+ autype: values.autype,
24
+ num: values.num,
25
+ extended_time: values.extendedTime,
26
+ }), "Futunn history data");
27
+ return {
28
+ bars: readFutunnList(data.kline_list, "kline_list"),
29
+ nextTime: optionalNumber(data.next_time) ?? null,
30
+ volumePrecision: optionalNumber(data.volume_precision) ?? null,
31
+ };
32
+ }
33
+ case "list_trading_days": {
34
+ const data = requiredResponseRecord(await request("/api/v1.0/quote/trading-days", values), "Futunn calendar data");
35
+ return { tradingDays: readFutunnList(data.trading_days, "trading_days") };
36
+ }
37
+ case "list_accounts": {
38
+ const data = requiredResponseRecord(await request("/api/v1.0/accounts/authorized_trd_accs"), "Futunn account data");
39
+ return { accounts: readFutunnList(data.accounts, "accounts") };
40
+ }
41
+ case "get_account_funds":
42
+ return {
43
+ funds: requiredResponseRecord(await request(`/api/v1.0/accounts/${encodeURIComponent(requiredInputString(values.accountId, "accountId"))}/funds`, { currency: values.currency }), "Futunn funds"),
44
+ };
45
+ case "list_positions":
46
+ return {
47
+ positions: readFutunnList(await request(`/api/v1.0/accounts/${encodeURIComponent(requiredInputString(values.accountId, "accountId"))}/positions`, { code: values.code, pl_ratio_min: values.plRatioMin, pl_ratio_max: values.plRatioMax }), "positions"),
48
+ };
49
+ }
50
+ }
@@ -0,0 +1,11 @@
1
+ export interface FutunnActionInput {
2
+ actionName: string;
3
+ input: Record<string, unknown>;
4
+ accessToken: string;
5
+ signal?: AbortSignal;
6
+ }
7
+ export declare const futunnApiBaseUrl = "https://webapi.futunn.com";
8
+ export declare function readFutunnResponse(response: Response, allowNoData?: boolean): Promise<Record<string, unknown>>;
9
+ export declare function requestFutunn(input: FutunnActionInput, fetcher: typeof fetch, path: string, query?: Record<string, unknown>, body?: unknown, allowNoData?: boolean): Promise<Record<string, unknown>>;
10
+ export declare function readFutunnList(value: unknown, label: string): unknown[];
11
+ export declare function readFutunnData(envelope: Record<string, unknown>): unknown;
@@ -0,0 +1,76 @@
1
+ import { optionalRecord, optionalString } from "../../core/cast.js";
2
+ import { ProviderRequestError, providerUserAgent, requiredResponseRecord, runProviderRequest, } from "../provider-runtime.js";
3
+ export const futunnApiBaseUrl = "https://webapi.futunn.com";
4
+ export async function readFutunnResponse(response, allowNoData = false) {
5
+ let payload;
6
+ try {
7
+ payload = JSON.parse(await response.text(), (key, value, context) => {
8
+ // Preserve the source decimal text of uint64 trading account IDs during JSON parsing.
9
+ if (key !== "account_id" || typeof value !== "number")
10
+ return value;
11
+ if (!Number.isInteger(value))
12
+ throw new Error("Invalid Futunn account ID");
13
+ if (Number.isSafeInteger(value))
14
+ return String(value);
15
+ if (!context?.source)
16
+ throw new Error("Futunn account ID source is unavailable");
17
+ return BigInt(context.source).toString();
18
+ });
19
+ }
20
+ catch {
21
+ throw new ProviderRequestError(response.ok ? 502 : response.status, "Futunn returned invalid JSON");
22
+ }
23
+ const envelope = requiredResponseRecord(payload, "Futunn response");
24
+ if (response.ok && allowNoData && envelope.ret_code === -10)
25
+ return envelope;
26
+ const error = optionalRecord(envelope.error);
27
+ if (!response.ok ||
28
+ envelope.s === "error" ||
29
+ (envelope.ret_code !== undefined && envelope.ret_code !== 0) ||
30
+ envelope.error) {
31
+ const message = optionalString(envelope.errmsg) ??
32
+ optionalString(envelope.ret_msg) ??
33
+ optionalString(envelope.error_description) ??
34
+ optionalString(error?.message) ??
35
+ optionalString(envelope.error) ??
36
+ "request failed";
37
+ const code = envelope.errcode ?? envelope.ret_code ?? error?.code;
38
+ throw new ProviderRequestError(response.ok ? 502 : response.status, `Futunn${code === undefined ? "" : ` (${String(code)})`}: ${message}`);
39
+ }
40
+ return envelope;
41
+ }
42
+ export async function requestFutunn(input, fetcher, path, query = {}, body, allowNoData = false) {
43
+ const url = new URL(path, futunnApiBaseUrl);
44
+ for (const [key, value] of Object.entries(query)) {
45
+ if (value !== undefined)
46
+ url.searchParams.set(key, String(value));
47
+ }
48
+ return runProviderRequest({ label: "Futunn", signal: input.signal }, async (signal) => {
49
+ const response = await fetcher(url, {
50
+ method: body === undefined ? "GET" : "POST",
51
+ headers: {
52
+ authorization: `Bearer ${input.accessToken}`,
53
+ accept: "application/json",
54
+ "content-type": "application/json",
55
+ "user-agent": providerUserAgent,
56
+ },
57
+ body: body === undefined ? undefined : JSON.stringify(body),
58
+ signal,
59
+ redirect: "manual",
60
+ });
61
+ const envelope = await readFutunnResponse(response, allowNoData);
62
+ if (envelope.s === "ok" || envelope.ret_code === 0 || (allowNoData && envelope.ret_code === -10))
63
+ return envelope;
64
+ throw new ProviderRequestError(502, "Futunn response is missing its success envelope");
65
+ });
66
+ }
67
+ export function readFutunnList(value, label) {
68
+ if (!Array.isArray(value))
69
+ throw new ProviderRequestError(502, `Futunn ${label} must be an array`);
70
+ return value;
71
+ }
72
+ export function readFutunnData(envelope) {
73
+ if (envelope.ret_code === -10)
74
+ return null;
75
+ return envelope.s === "ok" ? envelope.d : envelope.data;
76
+ }
@@ -202,7 +202,7 @@ function buildGildataMcpInput(serverType, apiKey, fetcher, parentSignal, request
202
202
  }
203
203
  return response;
204
204
  },
205
- redirect: "error",
205
+ redirect: "manual",
206
206
  terminateSession: true,
207
207
  signal: parentSignal,
208
208
  requestTimeoutMs,
@@ -0,0 +1,2 @@
1
+ /** Decode MessagePartBody.data while retaining only a small JSON envelope and one base64 block. */
2
+ export declare function decodeGmailAttachment(body: ReadableStream<Uint8Array>, maxBytes: number): ReadableStream<Uint8Array>;