@genne/genne-cli 0.0.0-stage → 0.1.33

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 (48) hide show
  1. package/GR.md +83 -0
  2. package/README.md +27 -2
  3. package/package.json +29 -4
  4. package/skills/genne-cli/SKILL.md +152 -0
  5. package/src/api.js +1 -0
  6. package/src/cli.js +7 -0
  7. package/src/commands/access.js +1 -0
  8. package/src/commands/companies.js +1 -0
  9. package/src/commands/content.js +2 -0
  10. package/src/commands/crm.js +4 -0
  11. package/src/commands/desktop-integrations.js +1 -0
  12. package/src/commands/driver-routes.js +1 -0
  13. package/src/commands/driver.js +1 -0
  14. package/src/commands/feedback.js +3 -0
  15. package/src/commands/financial.js +1 -0
  16. package/src/commands/gr.js +1 -0
  17. package/src/commands/identity.js +1 -0
  18. package/src/commands/logistics.js +1 -0
  19. package/src/commands/notifications.js +2 -0
  20. package/src/commands/operational-input.js +1 -0
  21. package/src/commands/operations-config.js +1 -0
  22. package/src/commands/orders.js +1 -0
  23. package/src/commands/routes.js +1 -0
  24. package/src/commands/support.js +2 -0
  25. package/src/commands/tower.js +1 -0
  26. package/src/commands/users.js +1 -0
  27. package/src/core-fetch.js +1 -0
  28. package/src/device-login.js +1 -0
  29. package/src/global.js +5 -0
  30. package/src/help.js +1 -0
  31. package/src/local-file.js +1 -0
  32. package/src/mcp-administration.js +1 -0
  33. package/src/mcp-desktop-operations.js +1 -0
  34. package/src/mcp-logistics.js +1 -0
  35. package/src/mcp-operational.js +1 -0
  36. package/src/mcp-routes-tower.js +1 -0
  37. package/src/mcp-support-feedback.js +1 -0
  38. package/src/mcp.js +2 -0
  39. package/src/operations.js +1 -0
  40. package/src/private-file.js +1 -0
  41. package/src/remote-auth-store.js +31 -0
  42. package/src/remote-auth.js +1 -0
  43. package/src/remote-core.js +1 -0
  44. package/src/remote-http.js +1 -0
  45. package/src/remote-mcp.js +1 -0
  46. package/src/remote-server.js +2 -0
  47. package/src/request-scope.js +1 -0
  48. package/src/session.js +1 -0
@@ -0,0 +1 @@
1
+ var d=Object.defineProperty;var t=(a,e)=>d(a,"name",{value:e,configurable:!0});import{z as o}from"zod";const r=o.enum(["admin","carrier","shipper"]),u=o.enum(["driver","carrier","admin"]);function s(a){return Object.entries(a).filter(([,e])=>e!==void 0).map(([e,i])=>`${e}=${i}`)}t(s,"queryArgs");function p(a){a("genne_driver_routes","Lista SavedRoutes do motorista da sess\xE3o. Filtros s\xE3o aplicados pelo endpoint Core; 202 nunca \xE9 tratado como rota conclu\xEDda.",{limit:o.number().int().positive().max(100).optional(),cursor:o.string().min(1).optional(),status:o.enum(["open","completed","closed"]).optional(),is_favorite:o.enum(["true","false"]).optional(),date_from:o.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),date_to:o.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),search:o.string().min(1).optional()},e=>["driver","routes","list",...s(e)]),a("genne_driver_route_show","Consulta SavedRoute, waypoints, manifesto e estado de execu\xE7\xE3o do motorista autenticado; a posse \xE9 revalidada pelo Core.",{route_id:o.uuid()},({route_id:e})=>["driver","routes",e,"show"]),a("genne_driver_place_search","Busca endere\xE7os no mercado do motorista; somente consulta, sem criar waypoint ou rota.",{query:o.string().min(1)},({query:e})=>["driver","places","search",e]),a("genne_driver_place_details","Resolve um place_id em endere\xE7o e coordenadas para o motorista; n\xE3o grava a rota.",{place_id:o.string().min(1)},({place_id:e})=>["driver","places","details",e]),a("genne_driver_optimization","Consulta status e resultado de um job de otimiza\xE7\xE3o pr\xF3prio; processing ou 202 n\xE3o significa geometria aplic\xE1vel.",{job_id:o.uuid()},({job_id:e})=>["driver","optimization",e,"show"]),a("genne_driver_calculation","Consulta status e resultado de um job de c\xE1lculo pr\xF3prio; processing ou 202 n\xE3o significa geometria aplic\xE1vel.",{job_id:o.uuid()},({job_id:e})=>["driver","calculation",e,"show"]),a("genne_driver_plan","Consulta o job de planejamento pr\xF3prio; 202 \xE9 aceita\xE7\xE3o e n\xE3o cria uma SavedRoute.",{job_id:o.uuid()},({job_id:e})=>["driver","routes","plan",e,"show"]),a("genne_driver_failure_policy","Consulta os motivos de insucesso e a exig\xEAncia de autoriza\xE7\xE3o da parada pr\xF3pria; n\xE3o consome c\xF3digo de autoriza\xE7\xE3o.",{route_id:o.uuid(),waypoint_id:o.uuid()},({route_id:e,waypoint_id:i})=>["driver","routes",e,"waypoints",i,"failure-policy"]),a("genne_routes","Lista rotas operacionais vis\xEDveis no papel ativo. O Core revalida membership, conta, base e ACL; filtros incompat\xEDveis com o papel s\xE3o recusados pelo comando.",{role:r,limit:o.number().int().positive().max(100).optional(),cursor:o.string().min(1).optional(),status:o.string().min(1).optional(),search:o.string().min(1).optional(),source_type:o.string().min(1).optional(),operation_mode:o.string().min(1).optional(),shipper_id:o.uuid().optional(),base_id:o.uuid().optional()},({role:e,...i})=>[e,"routes","list",...s(i)]),a("genne_shipper_route_candidates","Papel eleg\xEDvel: shipper. Lista candidatos de rota na hierarquia da sess\xE3o. O contrato aceita base_id/status, mas o handler atual ignora esses filtros e n\xE3o retorna cursor. Consulta s\xEDncrona, sem confirma\xE7\xE3o; estes registros ainda pertencem ao planejamento e n\xE3o s\xE3o SavedRoutes nem rotas operacionais publicadas.",{base_id:o.uuid().optional(),status:o.string().min(1).optional()},e=>["shipper","route-candidates","list",...s(e)]),a("genne_carrier_route_candidates","Papel eleg\xEDvel: carrier. Lista candidatos de rota atribu\xEDdos \xE0 transportadora da sess\xE3o. Consulta s\xEDncrona, sem confirma\xE7\xE3o; estes registros ainda pertencem ao planejamento e n\xE3o s\xE3o SavedRoutes nem rotas operacionais publicadas.",{},()=>["carrier","route-candidates","list"]),a("genne_route_show","Consulta o detalhe de uma rota operacional vis\xEDvel ao papel ativo; o Core decide a ACL efetiva.",{role:r,route_id:o.uuid()},({role:e,route_id:i})=>[e,"routes",i,"show"]),a("genne_workbench_scopes","Lista escopos do workbench com backlog pendente para o papel ativo.",{role:r},({role:e})=>[e,"workbench","scopes"]),a("genne_workbench_batch","Get the route planning overview for an authorized import batch. Provide batch_id and set role to the active admin, carrier, or shipper role. Returns batch status, route candidates, order processing counts, and planning issues. Processing may still be pending. This read does not run planning or publish routes.",{role:r,batch_id:o.uuid()},({role:e,batch_id:i})=>[e,"workbench","show",`batch_id=${i}`]),a("genne_workbench_base","Get the route planning overview for an authorized shipper base. Provide shipper_account_id and base_id, and set role to the active admin, carrier, or shipper role. Returns the latest batch status, route candidates, order processing counts, and planning issues. This read does not run planning or publish routes.",{role:r,shipper_account_id:o.uuid(),base_id:o.uuid()},({role:e,shipper_account_id:i,base_id:n})=>[e,"workbench","show",`shipper_account_id=${i}`,`base_id=${n}`]),a("genne_tower_batch_cockpit","Consulta o cockpit da torre por lote autorizado; a leitura n\xE3o executa triagem nem gera assist\xEAncia.",{role:r,batch_id:o.uuid()},({role:e,batch_id:i})=>[e,"tower","cockpit",`batch_id=${i}`]),a("genne_tower_base_cockpit","Consulta o cockpit da torre por embarcador e base autorizados; a leitura n\xE3o executa triagem nem atualiza cota\xE7\xE3o.",{role:r,shipper_account_id:o.uuid(),base_id:o.uuid()},({role:e,shipper_account_id:i,base_id:n})=>[e,"tower","cockpit",`shipper_account_id=${i}`,`base_id=${n}`]),a("genne_tower_chat_messages","Consulta mensagens de uma thread da torre autorizada pelo Core. N\xE3o abre thread, envia mensagem nem gera c\xF3digo.",{role:u,thread_id:o.uuid()},({role:e,thread_id:i})=>[e,"tower","chat","thread",i,"messages"]),a("genne_admin_tower_threads","Lista threads de atendimento operacional vis\xEDveis ao Admin conforme ACL do Core.",{},()=>["admin","tower","chat","threads"]),a("genne_admin_tower_overview","Consulta a vis\xE3o geral da torre autorizada ao Admin; n\xE3o executa a\xE7\xF5es operacionais.",{},()=>["admin","tower","overview"]),a("genne_admin_tower_failure_catalog","Consulta o cat\xE1logo de motivos de insucesso dispon\xEDvel ao Admin; n\xE3o consome autoriza\xE7\xE3o.",{},()=>["admin","tower","failure-reasons","catalog"]),a("genne_tower_failure_catalog","Pap\xE9is eleg\xEDveis: driver, admin, carrier e shipper. Consulta o cat\xE1logo global de motivos de insucesso; \xE9 s\xEDncrona, sem confirma\xE7\xE3o, e n\xE3o altera policy, consome autoriza\xE7\xE3o ou gera assist\xEAncia.",{role:o.enum(["driver","admin","carrier","shipper"]),search:o.string().min(1).optional()},({role:e,search:i})=>[e,"tower","failure-reasons","catalog-global",...i===void 0?[]:[`search=${i}`]]),a("genne_admin_tower_failure_policy","Consulta a policy de insucesso de uma conta autorizada ao Admin; n\xE3o altera policy nem consome c\xF3digo.",{account_type:o.enum(["shippers","carriers"]),account_id:o.uuid()},({account_type:e,account_id:i})=>["admin","tower","failure-reasons",e,i,"show"]),a("genne_tower_failure_policy","Consulta a policy de insucesso efetiva da conta carrier ou shipper ativa; n\xE3o altera policy.",{role:o.enum(["carrier","shipper"])},({role:e})=>[e,"tower","failure-reasons","policy","show"]),a("genne_driver_tower_query","Get the saved document lookup result for the authenticated driver using a previously returned query_id. Returns that query_id and its stored lookup data. This read does not start a new lookup, refresh enrichment, or use credits.",{query_id:o.uuid()},({query_id:e})=>["driver","tower","queries",e,"show"])}t(p,"registerRoutesTowerReads");export{p as registerRoutesTowerReads};
@@ -0,0 +1 @@
1
+ var y=Object.defineProperty;var a=(e,o)=>y(e,"name",{value:o,configurable:!0});import{z as t}from"zod";import{bindCoreFetch as l}from"./core-fetch.js";const k=a(e=>e?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(e)}/execute`:"/api/v1/auth/mcp/write-intents","writeIntentPath"),b=a((e,o)=>typeof e=="string"&&/^[A-Za-z0-9_.:-]{1,80}$/.test(e)?e:`http_${o}`,"safeErrorCode");async function h(e){try{return await e.json()}catch{return{}}}a(h,"responseJson");const v=[{name:"genne_admin_support_thread_set_status",operation:"admin.support_thread.set_status",description:"Solicita aprova\xE7\xE3o Admin para fechar ou reabrir um atendimento. Repita thread_id, status e idempotency_key com intent_id ap\xF3s a aprova\xE7\xE3o.",fields:{thread_id:t.uuid(),status:t.enum(["open","closed"])},destructiveHint:!0},{name:"genne_admin_feedback_delete",operation:"admin.feedback.delete",description:"Solicita aprova\xE7\xE3o Admin para excluir um feedback. Repita feedback_id e idempotency_key com intent_id ap\xF3s a aprova\xE7\xE3o.",fields:{feedback_id:t.uuid()},destructiveHint:!0},{name:"genne_admin_feedback_comment_delete",operation:"admin.feedback_comment.hide",description:"Solicita aprova\xE7\xE3o Admin para ocultar um coment\xE1rio de feedback. Repita os IDs e idempotency_key com intent_id ap\xF3s a aprova\xE7\xE3o.",fields:{feedback_id:t.uuid(),comment_id:t.uuid()},destructiveHint:!0},{name:"genne_admin_feedback_comment_restore",operation:"admin.feedback_comment.restore",description:"Solicita aprova\xE7\xE3o Admin para restaurar um coment\xE1rio de feedback. Repita os IDs e idempotency_key com intent_id ap\xF3s a aprova\xE7\xE3o.",fields:{feedback_id:t.uuid(),comment_id:t.uuid()},destructiveHint:!1}];function w(e,{coreOrigin:o,coreAccessToken:p,adapterKey:m,adminOrigin:u,fetchImpl:s=fetch}){s=l(s);for(const r of v)e.registerTool(r.name,{description:r.description,inputSchema:t.object({...r.fields,idempotency_key:t.string().min(16).max(128),intent_id:t.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:r.destructiveHint,idempotentHint:!0}},async({idempotency_key:_,intent_id:d,...f})=>{try{const n=await s(new URL(k(d),o),{method:"POST",headers:{authorization:`Bearer ${p}`,"x-genne-mcp-adapter-key":m,"idempotency-key":_,"content-type":"application/json"},body:JSON.stringify({operation:r.operation,...f})}),c=await h(n);if(!n.ok)return{isError:!0,content:[{type:"text",text:JSON.stringify({status:n.status,error:b(c?.error,n.status)})}]};const i=c?.data;return!i||typeof i!="object"||Array.isArray(i)?{isError:!0,content:[{type:"text",text:JSON.stringify({status:n.status,error:"invalid_core_response"})}]}:d?{content:[{type:"text",text:JSON.stringify(i)}]}:typeof i.public_id!="string"?{isError:!0,content:[{type:"text",text:JSON.stringify({status:n.status,error:"invalid_core_response"})}]}:{content:[{type:"text",text:JSON.stringify({...i,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(i.public_id)}?role=admin`,u).href,next_step:"Revise e aprove esta inten\xE7\xE3o em outra sess\xE3o Core de login por senha; depois repita com intent_id, os mesmos campos e idempotency_key."})}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}a(w,"registerSupportFeedbackWrites");export{w as registerSupportFeedbackWrites};
package/src/mcp.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ var $=Object.defineProperty;var h=(y,c)=>$(y,"name",{value:c,configurable:!0});import{McpServer as S}from"@modelcontextprotocol/server";import{serveStdio as U}from"@modelcontextprotocol/server/stdio";import{z as e}from"zod";import{pathToFileURL as j}from"node:url";import{CliError as I}from"./api.js";import{runOperation as H}from"./operations.js";import{registerLogisticsReads as L}from"./mcp-logistics.js";import{registerOperationalReads as O}from"./mcp-operational.js";import{registerAdministrationReads as E}from"./mcp-administration.js";import{registerRoutesTowerReads as N}from"./mcp-routes-tower.js";import{createRemoteMcpHandler as z}from"./remote-mcp.js";import{registerSupportFeedbackWrites as B}from"./mcp-support-feedback.js";import{registerDesktopOperationsWrites as J}from"./mcp-desktop-operations.js";import{bindCoreFetch as A}from"./core-fetch.js";function R(y=process.env){const c=new S({name:"genne-product",version:"0.1.0"}),a=h((t,o,r,n)=>{c.registerTool(t,{description:o,inputSchema:e.object(r),annotations:{readOnlyHint:!0,openWorldHint:t==="genne_driver_place_search"||t==="genne_driver_place_details",destructiveHint:!1}},async m=>{try{const i=await H(n(m),{env:y});return{content:[{type:"text",text:JSON.stringify(i)}]}}catch(i){return{isError:!0,content:[{type:"text",text:i instanceof I?i.message:"Falha interna do Genne MCP"}]}}})},"register");a("genne_help","Lista todos os comandos da CLI ou detalha um caminho; n\xE3o exige sess\xE3o Core.",{path:e.string().max(200).optional()},({path:t})=>["help",...t?.trim()?t.trim().split(/\s+/):[]]),a("genne_environment","Mostra o ambiente e a origem API efetivos sem expor credenciais.",{},()=>["env","show"]),a("genne_whoami","Consulta a identidade e o papel ativo da sess\xE3o Genne.",{},()=>["whoami"]),a("genne_shipper_route_show","Consulta uma rota operacional vis\xEDvel ao shipper da sess\xE3o.",{public_id:e.uuid()},({public_id:t})=>["shipper","route","show",t]),a("genne_user_me","Consulta os dados b\xE1sicos do usu\xE1rio da sess\xE3o.",{},()=>["users","me"]),a("genne_driver_profile","Consulta o perfil do motorista da sess\xE3o.",{},()=>["users","driver","profile"]),a("genne_driver_profile_details","Consulta o perfil operacional detalhado do motorista da sess\xE3o.",{},()=>["driver","profile","show"]),a("genne_driver_carriers","Lista transportadoras vinculadas ao motorista da sess\xE3o.",{},()=>["users","driver","carriers","list"]);for(const[t,o,r]of[["carrier","drivers","driver"],["driver","carriers","carrier"]])a(`genne_${t}_${r}_invitations`,`Lista convites da sess\xE3o ${t}; o Core decide ACL e escopo.`,{status:e.enum(["pending","accepted","declined","cancelled","expired"]).optional(),limit:e.number().int().min(1).max(100).optional(),cursor:e.string().optional()},n=>["users",t,o,"invitations","list",...Object.entries(n).filter(([,m])=>m!==void 0).map(([m,i])=>`${m}=${i}`)]),a(`genne_${t}_${r}_invitation_show`,`Consulta o estado can\xF4nico de um convite da sess\xE3o ${t}.`,{invitation_id:e.uuid()},({invitation_id:n})=>["users",t,o,"invitations","show",n]);a("genne_carrier_drivers","Lista motoristas vis\xEDveis \xE0 transportadora da sess\xE3o.",{},()=>["users","carrier","drivers","list"]),a("genne_carrier_driver_link","Consulta o v\xEDnculo de um motorista com a transportadora da sess\xE3o.",{driver_id:e.uuid()},({driver_id:t})=>["users","carrier","drivers","link",t]),a("genne_my_account_members","Lista os membros da conta shipper ou carrier da sess\xE3o.",{},()=>["access","my-account","members"]),a("genne_my_account_permission_catalog","Consulta permiss\xF5es B2B dispon\xEDveis na conta ativa.",{},()=>["access","my-account","catalog"]),a("genne_my_account_entitlements","Consulta m\xF3dulos habilitados na conta ativa.",{},()=>["access","my-account","entitlements"]),a("genne_my_account_member_access","Consulta permiss\xF5es de um membro da conta ativa.",{membership_id:e.uuid()},({membership_id:t})=>["access","my-account","member-access",t]),a("genne_admin_users","Lista usu\xE1rios vis\xEDveis ao admin da sess\xE3o.",{limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional(),role:e.string().optional(),search:e.string().optional()},({limit:t,cursor:o,role:r,search:n})=>["users","admin","list",...Object.entries({limit:t,cursor:o,role:r,search:n}).filter(([,m])=>m!==void 0).map(([m,i])=>`${m}=${i}`)]),a("genne_admin_user_show","Consulta um usu\xE1rio vis\xEDvel ao admin da sess\xE3o.",{user_id:e.uuid()},({user_id:t})=>["users","admin","show",t]),a("genne_admin_drivers","Lista motoristas vis\xEDveis ao admin da sess\xE3o.",{},()=>["users","drivers","list"]),a("genne_admin_driver_profile","Consulta os campos operacionais do motorista autorizados ao admin.",{user_id:e.uuid()},({user_id:t})=>["users","admin","driver-profile",t,"show"]),a("genne_admin_permission_catalog","Consulta o cat\xE1logo de permiss\xF5es internas.",{},()=>["access","catalog"]),a("genne_admin_access_accounts","Lista contas dispon\xEDveis para gest\xE3o de acesso pelo admin autorizado.",{account_type:e.enum(["shipper","carrier"]).optional(),search:e.string().optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional()},t=>["access","accounts","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_admin_access_members","Lista v\xEDnculos B2B vis\xEDveis ao admin autorizado.",{limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional(),search:e.string().optional(),status:e.string().optional(),membership_role:e.string().optional(),carrier_account_id:e.uuid().optional(),shipper_account_id:e.uuid().optional()},t=>["access","members","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_admin_internal_users","Lista usu\xE1rios internos para gest\xE3o de ACL pelo admin autorizado.",{},()=>["access","internal","list"]),a("genne_admin_internal_access","Consulta o acesso interno de um usu\xE1rio admin.",{user_id:e.uuid()},({user_id:t})=>["access","internal","show",t]),a("genne_admin_account_members","Lista membros de uma conta B2B autorizada ao admin.",{business_account_id:e.uuid()},({business_account_id:t})=>["access","account",t,"members"]),a("genne_admin_account_entitlements","Consulta m\xF3dulos de uma conta B2B autorizada ao admin.",{business_account_id:e.uuid()},({business_account_id:t})=>["access","account",t,"entitlements"]),a("genne_admin_account_member_access","Consulta permiss\xF5es de um membro B2B autorizado ao admin.",{business_account_id:e.uuid(),membership_id:e.uuid()},({business_account_id:t,membership_id:o})=>["access","account",t,"member-access",o]),a("genne_admin_account_member_bases","Consulta bases autorizadas para um membro B2B.",{business_account_id:e.uuid(),membership_id:e.uuid()},({business_account_id:t,membership_id:o})=>["access","account",t,"member-bases",o]),a("genne_admin_companies","Lista empresas B2B vis\xEDveis ao admin.",{account_type:e.enum(["shipper","carrier"]).optional(),search:e.string().optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional()},t=>["admin","companies","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_admin_company_show","Consulta uma empresa B2B pelo ID p\xFAblico.",{business_account_id:e.uuid()},({business_account_id:t})=>["admin","companies","show",t]),a("genne_admin_shipper_bases","Lista bases de um embarcador pelo ID operacional p\xFAblico.",{shipper_account_id:e.uuid()},({shipper_account_id:t})=>["admin","shippers",t,"bases","list"]),a("genne_admin_carrier_bases","Lista bases de uma transportadora pelo ID operacional p\xFAblico.",{carrier_account_id:e.uuid()},({carrier_account_id:t})=>["admin","carriers",t,"bases","list"]);for(const t of["shipper","carrier"])a(`genne_admin_${t}_base_zones`,"Consulta zonas efetivas salvas da base com papel Admin e network_configuration.view ou manage, revalidados pelo Core. Informe account_id operacional do propriet\xE1rio e base_id p\xFAblicos; valida a refer\xEAncia \xE0 conta antes da leitura. Consulta s\xEDncrona, sem confirma\xE7\xE3o; n\xE3o altera cobertura.",{account_id:e.uuid().describe("UUID p\xFAblico operacional da conta propriet\xE1ria; n\xE3o \xE9 o ID da empresa B2B."),base_id:e.uuid().describe("UUID p\xFAblico da base pertencente \xE0 conta informada.")},({account_id:o,base_id:r})=>["admin",`${t}s`,o,"bases",r,"zone-overrides","list"]);return a("genne_admin_shipper_base_carrier_shares","Consulta distribui\xE7\xE3o configurada de carriers da base shipper com papel Admin e network_configuration.view ou manage, revalidados pelo Core. Informe account_id operacional do embarcador e base_id p\xFAblicos. Consulta s\xEDncrona, sem confirma\xE7\xE3o; n\xE3o altera shares.",{account_id:e.uuid().describe("UUID p\xFAblico operacional do embarcador propriet\xE1rio."),base_id:e.uuid()},({account_id:t,base_id:o})=>["admin","shippers",t,"bases",o,"carrier-shares","list"]),a("genne_carrier_base_reference_zones","Consulta cat\xE1logo de refer\xEAncia OSM para uma base pr\xF3pria da conta carrier ativa, com membership, ownership e route_operations.view, workbench ou publish revalidados pelo Core. N\xE3o representa cobertura operacional salva. Consulta s\xEDncrona, sem confirma\xE7\xE3o; use meta para pagina\xE7\xE3o e include_geometry para geometrias.",{base_id:e.uuid().describe("UUID p\xFAblico da base carrier da conta ativa."),limit:e.number().int().positive().max(100).optional(),cursor:e.string().min(1).optional(),search:e.string().min(1).optional(),min_lng:e.number().min(-180).max(180).optional(),min_lat:e.number().min(-90).max(90).optional(),max_lng:e.number().min(-180).max(180).optional(),max_lat:e.number().min(-90).max(90).optional(),include_geometry:e.boolean().optional()},({base_id:t,...o})=>["carrier","bases",t,"reference-zone-features","list",...Object.entries(o).map(([r,n])=>`${r}=${n}`)]),a("genne_shipper_bases","Lista bases da conta shipper ativa.",{},()=>["shipper","bases","list"]),a("genne_shipper_base_carrier_shares","Lista shares de transportadoras em uma base da conta shipper.",{base_id:e.uuid()},({base_id:t})=>["shipper","bases",t,"carrier-shares","list"]),a("genne_shipper_base_reference_zones","Lista zonas de refer\xEAncia de uma base da conta shipper.",{base_id:e.uuid(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().min(1).optional(),search:e.string().min(1).optional(),min_lng:e.number().optional(),min_lat:e.number().optional(),max_lng:e.number().optional(),max_lat:e.number().optional(),include_geometry:e.boolean().optional()},({base_id:t,...o})=>["shipper","bases",t,"reference-zone-features","list",...Object.entries(o).map(([r,n])=>`${r}=${n}`)]),a("genne_my_company","Consulta a empresa ativa do embarcador ou transportadora da sess\xE3o.",{},()=>["company","my-account","show"]),a("genne_gr_requests","Lista solicita\xE7\xF5es de GR vis\xEDveis ao admin ou \xE0 transportadora da sess\xE3o.",{role:e.enum(["admin","carrier"]),carrier_account_id:e.uuid().optional(),provider_key:e.string().min(1).optional(),phase:e.string().min(1).optional(),operation_key:e.string().min(1).optional(),search:e.string().min(1).optional(),status:e.string().optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional()},({role:t,...o})=>[t,"gr","requests","list",...Object.entries(o).filter(([,r])=>r!==void 0).map(([r,n])=>`${r}=${n}`)]),a("genne_gr_request_show","Consulta uma solicita\xE7\xE3o de GR pelo ID p\xFAblico, com ACL do Core.",{role:e.enum(["admin","carrier"]),request_id:e.uuid()},({role:t,request_id:o})=>[t,"gr","requests",o,"show"]),a("genne_gr_request_trail","Consulta tentativas, evid\xEAncias ou eventos de uma solicita\xE7\xE3o de GR autorizada.",{role:e.enum(["admin","carrier"]),request_id:e.uuid(),kind:e.enum(["attempts","evidence","orchestration-events"]),limit:e.number().int().positive().max(100).optional(),cursor:e.string().min(1).optional()},({role:t,request_id:o,kind:r,...n})=>[t,"gr","requests",o,r,...Object.entries(n).map(([m,i])=>`${m}=${i}`)]),a("genne_gr_provider_definitions","Lista defini\xE7\xF5es de providers GR vis\xEDveis \xE0 sess\xE3o.",{role:e.enum(["admin","carrier"])},({role:t})=>[t,"gr","provider-definitions","list"]),a("genne_gr_provider_accounts","Lista contas de providers GR vis\xEDveis ao papel ativo. carrier_account_id \xE9 filtro exclusivo Admin; search \xE9 exclusivo carrier; filtros incompat\xEDveis s\xE3o recusados.",{role:e.enum(["admin","carrier"]),carrier_account_id:e.uuid().optional(),search:e.string().min(1).optional(),provider_key:e.string().min(1).optional(),status:e.string().min(1).optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().min(1).optional()},({role:t,...o})=>[t,"gr","providers","list",...Object.entries(o).map(([r,n])=>`${r}=${n}`)]),a("genne_gr_provider_mappings","Lista mapeamentos de opera\xE7\xF5es de uma conta GR autorizada.",{role:e.enum(["admin","carrier"]),provider_account_id:e.uuid(),active:e.boolean().optional()},({role:t,provider_account_id:o,...r})=>[t,"gr","providers",o,"mappings","list",...Object.entries(r).map(([n,m])=>`${n}=${m}`)]),a("genne_gr_provider_operations","Consulta opera\xE7\xF5es dispon\xEDveis na conta de provider GR autorizada.",{role:e.enum(["admin","carrier"]),provider_account_id:e.uuid()},({role:t,provider_account_id:o})=>[t,"gr","providers",o,"operations"]),a("genne_carrier_gr_blacklist","Lista v\xEDnculos bloqueados na transportadora da sess\xE3o.",{limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional(),search:e.string().optional()},t=>["carrier","gr","blacklist","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_admin_gr_blacklist","Lista v\xEDnculos bloqueados de uma transportadora vis\xEDvel ao admin.",{carrier_id:e.uuid(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional(),search:e.string().optional()},({carrier_id:t,...o})=>["admin","gr","carriers",t,"blacklist","list",...Object.entries(o).map(([r,n])=>`${r}=${n}`)]),a("genne_carrier_gr_driver_export","Consulta perfil completo e prontid\xE3o GR de motorista vinculado \xE0 transportadora da sess\xE3o.",{driver_profile_id:e.uuid()},({driver_profile_id:t})=>["carrier","gr","drivers",t,"export"]),a("genne_admin_gr_driver_export","Consulta perfil completo e prontid\xE3o GR de motorista vinculado \xE0 transportadora autorizada.",{carrier_id:e.uuid(),driver_profile_id:e.uuid()},({carrier_id:t,driver_profile_id:o})=>["admin","gr","carriers",t,"drivers",o,"export"]),a("genne_carrier_gr_dashboard","Consulta o painel GR da transportadora ativa.",{},()=>["carrier","gr","dashboard"]),a("genne_admin_gr_dashboard","Consulta o painel GR de uma transportadora vis\xEDvel ao admin.",{carrier_id:e.uuid()},({carrier_id:t})=>["admin","gr","carriers",t,"dashboard"]),a("genne_carrier_gr_drivers","Lista motoristas GR da transportadora ativa.",{provider_account_id:e.uuid().optional(),document:e.string().min(1).optional(),training_pending:e.boolean().optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional(),search:e.string().optional(),status:e.string().optional()},t=>["carrier","gr","drivers",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_admin_gr_drivers","Lista motoristas GR de uma transportadora vis\xEDvel ao admin.",{carrier_id:e.uuid(),provider_account_id:e.uuid().optional(),document:e.string().min(1).optional(),training_pending:e.boolean().optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional(),search:e.string().optional(),status:e.string().optional()},({carrier_id:t,...o})=>["admin","gr","carriers",t,"drivers",...Object.entries(o).map(([r,n])=>`${r}=${n}`)]),a("genne_admin_gr_driver_directory","Lista o diret\xF3rio GR global Admin, incluindo motoristas sem v\xEDnculo. carrier_account_id restringe \xE0 transportadora indicada; o Core exige gr.view ou gr.manage.",{carrier_account_id:e.uuid().optional(),provider_account_id:e.uuid().optional(),document:e.string().min(1).optional(),training_pending:e.boolean().optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional(),search:e.string().optional(),status:e.string().optional()},t=>["admin","gr","drivers",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_order_lookup","Consulta um pedido por c\xF3digo de barras na transportadora da sess\xE3o.",{barcode:e.string().min(1)},({barcode:t})=>["carrier","orders","lookup",t]),a("genne_carrier_shippers","Lista embarcadores geridos pela transportadora da sess\xE3o.",{},()=>["carrier","shippers","list"]),a("genne_carrier_shipper_bases","Lista bases de um embarcador vinculado \xE0 transportadora da sess\xE3o.",{shipper_id:e.uuid()},({shipper_id:t})=>["carrier","shippers",t,"bases","list"]),a("genne_admin_carrier_shippers","Lista embarcadores geridos por uma transportadora vis\xEDvel ao admin.",{carrier_id:e.uuid()},({carrier_id:t})=>["admin","operations",t,"shippers","list"]),a("genne_admin_carrier_shipper_bases","Lista bases de um embarcador gerido por uma transportadora vis\xEDvel ao admin.",{carrier_id:e.uuid(),shipper_id:e.uuid()},({carrier_id:t,shipper_id:o})=>["admin","operations",t,"shippers",o,"bases","list"]),a("genne_carrier_receiving_rules","Lista regras de recebimento da transportadora da sess\xE3o.",{},()=>["carrier","receiving","rules","list"]),a("genne_admin_receiving_rules","Lista regras de recebimento de uma transportadora vis\xEDvel ao admin.",{carrier_id:e.uuid()},({carrier_id:t})=>["admin","operations",t,"receiving","rules","list"]),a("genne_admin_order_lookup","Consulta pedido por c\xF3digo de barras em uma transportadora vis\xEDvel ao admin.",{carrier_id:e.uuid(),barcode:e.string().min(1)},({carrier_id:t,barcode:o})=>["admin","operations",t,"orders","lookup",o]),a("genne_admin_triage_batch","Consulta lote de triagem vis\xEDvel ao admin da sess\xE3o.",{batch_id:e.uuid()},({batch_id:t})=>["admin","triage","batches",t,"show"]),a("genne_admin_triage_batches","Lista lotes de triagem vis\xEDveis ao admin da sess\xE3o.",{limit:e.number().int().positive().max(100).optional(),cursor:e.string().min(1).optional(),search:e.string().min(1).optional()},t=>["admin","triage","batches","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_carrier_desktop_grants","Lista concess\xF5es de providers Desktop da transportadora ativa.",{},()=>["carrier","desktop","grants","list"]),a("genne_carrier_desktop_sync_runs","Lista execu\xE7\xF5es de sincroniza\xE7\xE3o Desktop na transportadora da sess\xE3o.",{shipper_id:e.uuid().optional(),base_id:e.uuid().optional(),connection_id:e.uuid().optional(),device_id:e.string().min(8).max(128).regex(/^[A-Za-z0-9._:-]+$/).optional(),order_id:e.uuid().optional(),status:e.enum(["queued","claimed","running","succeeded","failed","blocked_no_runner","blocked_auth","outcome_unknown","cancelled"]).optional(),cursor:e.string().min(1).optional()},t=>["carrier","desktop","sync-runs","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_carrier_desktop_execution","Consulta estado e receipt de uma execu\xE7\xE3o Desktop autorizada.",{execution_id:e.uuid()},({execution_id:t})=>["carrier","desktop","executions",t,"show"]),a("genne_carrier_desktop_candidates","Lista candidatos de pedido de uma execu\xE7\xE3o Desktop e dispositivo autorizados.",{execution_id:e.uuid(),device_id:e.string().min(8).max(128).regex(/^[A-Za-z0-9._:-]+$/),cursor:e.string().min(1).optional()},({execution_id:t,...o})=>["carrier","desktop","executions",t,"candidates","list",...Object.entries(o).map(([r,n])=>`${r}=${n}`)]),a("genne_carrier_desktop_receipt","Consulta receipt de importa\xE7\xE3o por execu\xE7\xE3o, dispositivo e chave de lote.",{execution_id:e.uuid(),device_id:e.string().min(8).max(128).regex(/^[A-Za-z0-9._:-]+$/),batch_key:e.string().min(16).max(128).regex(/^[A-Za-z0-9._:-]+$/)},({execution_id:t,device_id:o,batch_key:r})=>["carrier","desktop","executions",t,"receipt",`device_id=${o}`,`batch_key=${r}`]),a("genne_carrier_desktop_operation_routes","Lista revis\xF5es de rotas operacionais Desktop da transportadora.",{},()=>["carrier","desktop","operation-routes","list"]),a("genne_carrier_desktop_orders","Lista pedidos can\xF4nicos vis\xEDveis \xE0 transportadora ativa no Desktop.",{shipper_id:e.uuid().optional(),base_id:e.uuid().optional(),query:e.string().optional(),cursor:e.string().optional(),status_sync:e.literal(!0).optional()},t=>["carrier","desktop","orders","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_carrier_desktop_order_show","Consulta pedido can\xF4nico por ID na transportadora ativa no Desktop.",{order_id:e.uuid()},({order_id:t})=>["carrier","desktop","orders",t,"show"]),a("genne_carrier_desktop_device_runs","Lista resultados de recebimento de um dispositivo da transportadora.",{base_id:e.uuid().optional(),shipper_id:e.uuid().optional(),operation_kind:e.enum(["sack_receipt","package_receipt","route_creation","dispatch","transfer","return"]).optional(),device_id:e.string().min(8).max(128),cursor:e.string().optional(),limit:e.number().int().positive().max(100).optional()},t=>["carrier","desktop","operation-runs","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_carrier_desktop_monitor_runs","Lista resultados de recebimento no monitor da transportadora.",{base_id:e.uuid().optional(),shipper_id:e.uuid().optional(),operation_kind:e.enum(["sack_receipt","package_receipt","route_creation","dispatch","transfer","return"]).optional(),monitor:e.literal(!0),cursor:e.string().optional(),limit:e.number().int().positive().max(100).optional()},t=>["carrier","desktop","operation-runs","list",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_import_batch","Consulta o estado de um lote de importa\xE7\xE3o vis\xEDvel ao papel ativo.",{role:e.enum(["admin","carrier","shipper"]),batch_id:e.uuid(),include_orders:e.boolean().optional()},({role:t,batch_id:o,include_orders:r})=>[t,"orders","imports",o,"show",...r===void 0?[]:[`include_orders=${r}`]]),a("genne_import_orders","Lista pedidos de um lote de importa\xE7\xE3o vis\xEDvel ao papel ativo.",{role:e.enum(["admin","carrier","shipper"]),batch_id:e.uuid(),search:e.string().min(1).optional(),geocode_status:e.string().min(1).optional(),only_errors:e.boolean().optional(),limit:e.number().int().positive().max(100).optional(),cursor:e.string().optional()},({role:t,batch_id:o,...r})=>[t,"orders","imports",o,"orders","list",...Object.entries(r).filter(([,n])=>n!==void 0).map(([n,m])=>`${n}=${m}`)]),a("genne_carrier_status_outbox","Consulta eventos de status da transportadora da sess\xE3o.",{shipper_id:e.uuid().optional(),sink_type:e.enum(["webhook","ocoren","adapter"]).optional(),adapter_type:e.string().min(1).optional()},t=>["carrier","status-outbox",...Object.entries(t).map(([o,r])=>`${o}=${r}`)]),a("genne_admin_status_outbox","Consulta eventos de status de uma transportadora vis\xEDvel ao admin.",{carrier_account_id:e.uuid(),shipper_id:e.uuid().optional(),sink_type:e.enum(["webhook","ocoren","adapter"]).optional(),adapter_type:e.string().min(1).optional()},({carrier_account_id:t,...o})=>["admin","operations",t,"status-outbox",...Object.entries(o).map(([r,n])=>`${r}=${n}`)]),L(a),O(a),E(a),N(a),c}h(R,"createProductServer");function F(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_faq_save_draft",{description:"Solicita aprova\xE7\xE3o humana para salvar uma FAQ publicada como rascunho; ap\xF3s a aprova\xE7\xE3o, executa a mesma inten\xE7\xE3o e devolve o receipt.",inputSchema:e.object({target:e.uuid(),expected_version:e.number().int().positive(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({target:n,expected_version:m,idempotency_key:i,intent_id:s})=>{const l=s?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(s)}/execute`:"/api/v1/auth/mcp/write-intents";try{const u=await r(new URL(l,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":i,"content-type":"application/json"},body:JSON.stringify({target:n,expected_version:m})}),d=await u.json();if(!u.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${d.error??u.status}`}]};const p=d.data,_=s?p:{...p,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(p.public_id)}?role=${encodeURIComponent(p.active_role)}`,o).href,next_step:"A pessoa deve revisar e aprovar esta inten\xE7\xE3o em outra sess\xE3o Core de login por senha; depois repita a chamada com intent_id e os mesmos target, expected_version e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(_)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(F,"registerRemoteFaqDraft");function T(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_user_me_update",{description:"Solicita aprova\xE7\xE3o humana para alterar somente campos do pr\xF3prio perfil. Ap\xF3s aprova\xE7\xE3o, repita com intent_id, changes e idempotency_key id\xEAnticos para executar.",inputSchema:e.object({changes:e.object({name:e.string().optional(),phone:e.string().optional(),vehicle_type:e.string().optional(),navigation_app_preference:e.string().optional()}).strict(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({changes:n,idempotency_key:m,intent_id:i})=>{const s=i?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(i)}/execute`:"/api/v1/auth/mcp/write-intents";try{const l=await r(new URL(s,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":m,"content-type":"application/json"},body:JSON.stringify({operation:"user.me.update",changes:n})}),u=await l.json();if(!l.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${u.error??l.status}`}]};const d=u.data,p=i?d:{...d,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(d.public_id)}?role=${encodeURIComponent(d.active_role)}`,o).href,next_step:"Revise e aprove o antes/depois em outra sess\xE3o Core de login por senha; depois repita com intent_id, changes e idempotency_key id\xEAnticos."};return{content:[{type:"text",text:JSON.stringify(p)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(T,"registerRemoteProfileUpdate");function P(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_admin_internal_user_access_set",{description:"Substitui todo o ACL de um usu\xE1rio interno Admin ap\xF3s aprova\xE7\xE3o em outra sess\xE3o. Informe user_id, admin_access_level (staff ou super_admin) e a lista completa permission_keys; para super_admin a lista deve ser vazia. Repita com intent_id e os mesmos campos e idempotency_key para executar. O Core valida permiss\xE3o access_governance.manage e mudan\xE7as de super_admin.",inputSchema:e.object({user_id:e.uuid(),admin_access_level:e.enum(["staff","super_admin"]),permission_keys:e.array(e.string()).refine(n=>new Set(n).size===n.length),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({user_id:n,admin_access_level:m,permission_keys:i,idempotency_key:s,intent_id:l})=>{const u=l?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(l)}/execute`:"/api/v1/auth/mcp/write-intents";try{const d=await r(new URL(u,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":s,"content-type":"application/json"},body:JSON.stringify({operation:"admin.internal_user_access.set",user_id:n,admin_access_level:m,permission_keys:i})}),p=await d.json();if(!d.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${p.error??d.status}`}]};const _=p.data,v=l?_:{..._,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(_.public_id)}?role=${encodeURIComponent(_.active_role)}`,o).href,next_step:"Revise usu\xE1rio e ACL antes/depois em outra sess\xE3o Core; depois repita com intent_id, os mesmos campos e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(v)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(P,"registerRemoteAdminInternalUserAccessSet");function D(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_business_member_access_set",{description:"Substitui papel e lista completa de permiss\xF5es de um membro B2B com aprova\xE7\xE3o em outra sess\xE3o. Admin informa account_id; carrier/shipper usam a conta ativa e omitem account_id. Requer access_governance.manage no Admin ou workspace.permissions.manage no cliente. Repita com intent_id, os mesmos campos e idempotency_key para executar.",inputSchema:e.object({account_id:e.uuid().optional(),membership_id:e.uuid(),membership_role:e.enum(["owner","operator","dispatcher","finance"]),permission_keys:e.array(e.string()).refine(n=>new Set(n).size===n.length),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({account_id:n,membership_id:m,membership_role:i,permission_keys:s,idempotency_key:l,intent_id:u})=>{const d=u?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(u)}/execute`:"/api/v1/auth/mcp/write-intents";try{const p=await r(new URL(d,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":l,"content-type":"application/json"},body:JSON.stringify({operation:"business.member_access.set",account_id:n,membership_id:m,membership_role:i,permission_keys:s})}),_=await p.json();if(!p.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${_.error??p.status}`}]};const v=_.data,g=u?v:{...v,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(v.public_id)}?role=${encodeURIComponent(v.active_role)}`,o).href,next_step:"Revise empresa, membro e ACL antes/depois em outra sess\xE3o Core; depois repita com intent_id e a mesma idempotency_key."};return{content:[{type:"text",text:JSON.stringify(g)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(D,"registerRemoteBusinessMemberAccessSet");function W(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_business_member_status_set",{description:"Ativa ou desativa um membro B2B com aprova\xE7\xE3o em outra sess\xE3o. Admin informa account_id; carrier/shipper usam a conta ativa e omitem account_id. Requer business_accounts_registry.manage no Admin ou workspace.members.manage no cliente. Repita com intent_id e a mesma idempotency_key ap\xF3s a aprova\xE7\xE3o.",inputSchema:e.object({account_id:e.uuid().optional(),membership_id:e.uuid(),status:e.enum(["active","inactive"]),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({account_id:n,membership_id:m,status:i,idempotency_key:s,intent_id:l})=>{const u=l?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(l)}/execute`:"/api/v1/auth/mcp/write-intents";try{const d=await r(new URL(u,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":s,"content-type":"application/json"},body:JSON.stringify({operation:"business.member_status.set",account_id:n,membership_id:m,status:i})}),p=await d.json();if(!d.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${p.error??d.status}`}]};const _=p.data,v=l?_:{..._,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(_.public_id)}?role=${encodeURIComponent(_.active_role)}`,o).href,next_step:"Revise empresa, membro e status antes/depois em outra sess\xE3o Core; depois repita com intent_id e a mesma idempotency_key."};return{content:[{type:"text",text:JSON.stringify(v)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(W,"registerRemoteBusinessMemberStatusSet");function G(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){const n={account_id:e.uuid().optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()},m=[{name:"genne_business_member_invite",operation:"business.member.invite",description:"Convida um membro B2B com aprova\xE7\xE3o separada. Admin informa account_id e member.workspace_role (carrier ou shipper); clientes omitem ambos e usam a conta ativa. Carrier permite operator, dispatcher e finance; shipper permite operator e finance; Admin tamb\xE9m permite owner. Requer a ACL de gest\xE3o de membros do endpoint existente. Repita os mesmos dados e idempotency_key com intent_id. Um v\xEDnculo existente conserva o acesso e n\xE3o gera outro envio. Receipt pending significa e-mail enfileirado; consulte genne_my_account_members ou genne_admin_account_members para acompanhar o envio.",inputSchema:e.object({...n,member:e.object({email:e.string().trim().toLowerCase().pipe(e.email()),membership_role:e.enum(["owner","operator","dispatcher","finance"]),workspace_role:e.enum(["carrier","shipper"]).optional()}).strict()}).strict()},{name:"genne_business_member_invitation_resend",operation:"business.member_invitation.resend",description:"Reenvia um convite B2B conforme as regras atuais, com aprova\xE7\xE3o separada. Admin informa account_id; carrier/shipper omitem e usam a conta ativa. Informe membership_id e chave est\xE1vel; repita com intent_id ap\xF3s aprova\xE7\xE3o. Receipt pending significa enfileirado. Consulte genne_my_account_members ou genne_admin_account_members para acompanhar; convite de cadastro j\xE1 enviado n\xE3o pode ser reenviado.",inputSchema:e.object({...n,membership_id:e.uuid()}).strict()}];for(const{name:i,operation:s,description:l,inputSchema:u}of m)y.registerTool(i,{description:l,inputSchema:u,annotations:{readOnlyHint:!1,openWorldHint:i==="genne_business_member_invite",destructiveHint:!0,idempotentHint:!0}},async({idempotency_key:d,intent_id:p,..._})=>{const v=p?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(p)}/execute`:"/api/v1/auth/mcp/write-intents";try{const g=await r(new URL(v,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":d,"content-type":"application/json"},body:JSON.stringify({operation:s,..._})}),b=await g.json();if(!g.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${b.error??g.status}`}]};const f=b.data,x=p?f:{...f,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(f.public_id)}?role=${encodeURIComponent(f.active_role)}`,o).href,next_step:"Revise empresa, destinat\xE1rio e papel em outra sess\xE3o Core. Repita os mesmos dados e chave com intent_id ap\xF3s aprova\xE7\xE3o. Pending indica enfileirado; acompanhe o envio na consulta de membros."};return{content:[{type:"text",text:JSON.stringify(x)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(G,"registerRemoteBusinessMemberInvitations");function q(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_company_my_account_update",{description:"Solicita aprova\xE7\xE3o para mudar legal_name ou trading_name da empresa carrier/shipper ativa. Repita com intent_id e a mesma chave ap\xF3s a aprova\xE7\xE3o.",inputSchema:e.object({changes:e.object({legal_name:e.string().min(1).max(255).optional(),trading_name:e.string().min(1).max(255).optional()}).strict().refine(n=>Object.keys(n).length>0),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({changes:n,idempotency_key:m,intent_id:i})=>{const s=i?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(i)}/execute`:"/api/v1/auth/mcp/write-intents";try{const l=await r(new URL(s,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":m,"content-type":"application/json"},body:JSON.stringify({operation:"company.my_account.update",changes:n})}),u=await l.json();if(!l.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${u.error??l.status}`}]};const d=u.data,p=i?d:{...d,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(d.public_id)}?role=${encodeURIComponent(d.active_role)}`,o).href,next_step:"Revise e aprove a altera\xE7\xE3o da empresa ativa no navegador; depois repita com intent_id, changes e idempotency_key id\xEAnticos."};return{content:[{type:"text",text:JSON.stringify(p)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(q,"registerRemoteCompanyUpdate");function M(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_admin_company_update",{description:"Solicita aprova\xE7\xE3o para alterar legal_name ou trading_name de uma empresa B2B selecionada por UUID. Exige sess\xE3o Admin com business_accounts_registry.manage. Repita com intent_id, account_id, changes e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o Admin.",inputSchema:e.object({account_id:e.uuid(),changes:e.object({legal_name:e.string().min(1).max(255).optional(),trading_name:e.string().min(1).max(255).optional()}).strict().refine(n=>Object.keys(n).length>0),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({account_id:n,changes:m,idempotency_key:i,intent_id:s})=>{const l=s?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(s)}/execute`:"/api/v1/auth/mcp/write-intents";try{const u=await r(new URL(l,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":i,"content-type":"application/json"},body:JSON.stringify({operation:"company.admin.update",account_id:n,changes:m})}),d=await u.json();if(!u.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${d.error??u.status}`}]};const p=d.data,_=s?p:{...p,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(p.public_id)}?role=admin`,o).href,next_step:"Revise empresa e valores antes/depois em outra sess\xE3o Core Admin; depois repita com intent_id, account_id, changes e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(_)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(M,"registerRemoteAdminCompanyUpdate");function Z(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){for(const n of[{tool:"genne_admin_carrier_base_create",operation:"base.carrier.create",subject:"transportadora"},{tool:"genne_admin_shipper_base_create",operation:"base.admin_shipper.create",subject:"embarcador"}])y.registerTool(n.tool,{description:`Solicita aprova\xE7\xE3o para criar uma base de ${n.subject} como Admin com a ACL do Core. Repita com intent_id e os mesmos dados ap\xF3s aprova\xE7\xE3o.`,inputSchema:e.object({account_id:e.uuid(),base:e.object({code:e.string().trim().min(1).max(255),name:e.string().trim().min(1).max(255),origin_address:e.string().trim().min(1).max(255),market_id:e.uuid(),country_code:e.string().regex(/^[A-Z]{2}$/),currency_code:e.string().regex(/^[A-Z]{3}$/),timezone:e.string().trim().min(1).max(255)}).strict(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!1,idempotentHint:!0}},async({account_id:m,base:i,idempotency_key:s,intent_id:l})=>{const u=l?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(l)}/execute`:"/api/v1/auth/mcp/write-intents";try{const d=await r(new URL(u,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":s,"content-type":"application/json"},body:JSON.stringify({operation:n.operation,account_id:m,base:i})}),p=await d.json();if(!d.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${p.error??d.status}`}]};const _=p.data,v=l?_:{..._,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(_.public_id)}?role=admin`,o).href,next_step:`Revise ${n.subject} e base em outra sess\xE3o Core Admin; depois repita com intent_id, account_id, base e idempotency_key id\xEAnticos.`};return{content:[{type:"text",text:JSON.stringify(v)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(Z,"registerRemoteAdminBaseCreate");function X(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){const m={...Object.fromEntries(["code","name","origin_address","postal_code","place_id","street","street_number","neighborhood","city","state","state_code","country","geocode_provider","timezone"].map(i=>[i,e.string().optional()])),origin_lat:e.number().min(-90).max(90).optional(),origin_lng:e.number().min(-180).max(180).optional(),triage_rules:e.record(e.string(),e.unknown()).optional()};for(const i of[{tool:"genne_admin_shipper_base_update",operation:"base.admin_shipper.update",fields:{...m,metadata:e.record(e.string(),e.unknown()).optional(),balancing_policy:e.record(e.string(),e.unknown()).optional()}},{tool:"genne_admin_carrier_base_update",operation:"base.admin_carrier.update",fields:m},{tool:"genne_admin_shipper_base_set_status",operation:"base.admin_shipper.set_status"},{tool:"genne_admin_shipper_base_cutoff_windows_set",operation:"base.admin_shipper.cutoff_windows.set",cutoff:!0},{tool:"genne_admin_carrier_base_cutoff_windows_set",operation:"base.admin_carrier.cutoff_windows.set",cutoff:!0}])y.registerTool(i.tool,{description:i.fields?"Edita uma base com papel Admin standalone e network_configuration.manage. account_id \xE9 o UUID operacional da conta propriet\xE1ria. Revise conta, base, valores atuais e resultantes no link de aprova\xE7\xE3o; repita os mesmos dados e chave com intent_id. Campos omitidos s\xE3o preservados; mercado, country_code, moeda, ownership, status e null s\xE3o recusados. 412 exige nova leitura e inten\xE7\xE3o.":i.cutoff?"Substitui todos os hor\xE1rios de corte de uma base shipper/carrier com papel Admin standalone e network_configuration.manage. account_id \xE9 o UUID operacional propriet\xE1rio. windows cont\xE9m weekday 0..6, cutoff_time HH:MM[:SS] no timezone da base e auto_publish opcional; [] remove todos. Base shipper com execu\xE7\xF5es de corte vinculadas \xE9 recusada com 409 cutoff_dispatches_exist para preservar hist\xF3rico e execu\xE7\xE3o; n\xE3o h\xE1 reagendamento impl\xEDcito. Revise conta, base, timezone e hor\xE1rios atuais/resultantes na aprova\xE7\xE3o Core. Repita os mesmos dados e idempotency_key com intent_id. A execu\xE7\xE3o s\xEDncrona grava filhos e receipt atomicamente no Core; 412 exige nova inten\xE7\xE3o, replay retorna o receipt original.":"Ativa ou desativa uma base de embarcador com papel Admin standalone e network_configuration.manage. Informe account_id operacional da conta propriet\xE1ria, base_id e status active/inactive. Revise conta, base, status atual e resultante no link de aprova\xE7\xE3o; repita os mesmos dados e chave com intent_id. 412 exige nova leitura e inten\xE7\xE3o; replay devolve o receipt original.",inputSchema:e.object({account_id:e.uuid(),base_id:e.uuid(),...i.fields?{changes:e.object(i.fields).strict().refine(s=>Object.keys(s).length>0,"Informe uma altera\xE7\xE3o")}:i.cutoff?{windows:e.array(e.object({weekday:e.number().int().min(0).max(6),cutoff_time:e.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/),auto_publish:e.boolean().optional()}).strict())}:{status:e.enum(["active","inactive"])},idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({account_id:s,base_id:l,changes:u,status:d,windows:p,idempotency_key:_,intent_id:v})=>{const g=v?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(v)}/execute`:"/api/v1/auth/mcp/write-intents";try{const b=await r(new URL(g,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":_,"content-type":"application/json"},body:JSON.stringify({operation:i.operation,account_id:s,base_id:l,...i.fields?{changes:u}:i.cutoff?{windows:p}:{status:d}})}),f=await b.json();if(!b.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${f.error??b.status}`}]};const x=v?f.data:{...f.data,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(f.data.public_id)}?role=admin`,o).href,next_step:"Revise a base em outra sess\xE3o Admin e repita com intent_id e os mesmos dados e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(x)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(X,"registerRemoteAdminBaseChange");function Q(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_admin_carrier_base_set_status",{description:"Solicita aprova\xE7\xE3o para ativar ou desativar operacionalmente uma base carrier como Admin com network_configuration.manage. Repita com intent_id, base_id, status e a mesma chave ap\xF3s aprova\xE7\xE3o.",inputSchema:e.object({base_id:e.uuid(),status:e.enum(["active","inactive"]),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({base_id:n,status:m,idempotency_key:i,intent_id:s})=>{const l=s?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(s)}/execute`:"/api/v1/auth/mcp/write-intents";try{const u=await r(new URL(l,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":i,"content-type":"application/json"},body:JSON.stringify({operation:"base.admin_carrier.set_status",base_id:n,status:m})}),d=await u.json();if(!u.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${d.error??u.status}`}]};const p=d.data,_=s?p:{...p,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(p.public_id)}?role=admin`,o).href,next_step:"Revise base e estado antes/depois em outra sess\xE3o Core Admin; depois repita com intent_id, base_id, status e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(_)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(Q,"registerRemoteAdminCarrierBaseStatus");function V(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){const n=e.object({code:e.string().trim().min(1).max(255),name:e.string().trim().min(1).max(255),origin_address:e.string().trim().min(1).max(255).optional(),origin_lat:e.number().min(-90).max(90).optional(),origin_lng:e.number().min(-180).max(180).optional(),timezone:e.string().trim().min(1).max(255).optional(),triage_rules:e.record(e.string(),e.unknown()).optional(),metadata:e.record(e.string(),e.unknown()).optional()}).strict().refine(m=>m.origin_lat===void 0==(m.origin_lng===void 0),{message:"origin_lat e origin_lng devem ser informados juntos"});for(const m of[{tool:"genne_shipper_base_create",operation:"base.shipper.create",role:"shipper"},{tool:"genne_carrier_shipper_base_create",operation:"base.carrier_shipper.create",role:"carrier"}])y.registerTool(m.tool,{description:m.role==="carrier"?"Solicita aprova\xE7\xE3o para criar uma base nova de embarcador vinculada \xE0 transportadora ativa. Informe c\xF3digo em mai\xFAsculas; repita com intent_id e os mesmos dados ap\xF3s aprova\xE7\xE3o.":"Solicita aprova\xE7\xE3o para criar uma base da conta shipper ativa com route_operations.workbench. Repita com intent_id e os mesmos dados ap\xF3s aprova\xE7\xE3o.",inputSchema:e.object({...m.role==="carrier"?{shipper_id:e.uuid()}:{},base:m.role==="carrier"?n.refine(i=>i.code===i.code.toUpperCase(),{message:"code deve estar em mai\xFAsculas"}):n,idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!1,idempotentHint:!0}},async({shipper_id:i,base:s,idempotency_key:l,intent_id:u})=>{const d=u?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(u)}/execute`:"/api/v1/auth/mcp/write-intents";try{const p=await r(new URL(d,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":l,"content-type":"application/json"},body:JSON.stringify({operation:m.operation,...i?{shipper_id:i}:{},base:s})}),_=await p.json();if(!p.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${_.error??p.status}`}]};const v=_.data,g=u?v:{...v,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(v.public_id)}?role=${m.role}`,o).href,next_step:m.role==="carrier"?"Revise a transportadora, o embarcador e a base em outra sess\xE3o Core da mesma conta carrier; depois repita com intent_id, shipper_id, base e idempotency_key id\xEAnticos.":"Revise a base em outra sess\xE3o Core da mesma conta shipper; depois repita com intent_id, base e idempotency_key id\xEAnticos."};return{content:[{type:"text",text:JSON.stringify(g)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(V,"registerRemoteShipperBaseCreate");function Y(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_gr_driver_training_update",{description:"Solicita aprova\xE7\xE3o para marcar o treinamento GR de um motorista vis\xEDvel ao admin ou carrier. Repita com intent_id e a mesma chave ap\xF3s a aprova\xE7\xE3o.",inputSchema:e.object({target:e.uuid(),training_watched:e.boolean(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({target:n,training_watched:m,idempotency_key:i,intent_id:s})=>{const l=s?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(s)}/execute`:"/api/v1/auth/mcp/write-intents";try{const u=await r(new URL(l,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":i,"content-type":"application/json"},body:JSON.stringify({operation:"gr.driver_training.update",target:n,training_watched:m})}),d=await u.json();if(!u.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${d.error??u.status}`}]};const p=d.data,_=s?p:{...p,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(p.public_id)}?role=${encodeURIComponent(p.active_role)}`,o).href,next_step:"Revise e aprove o treinamento GR em outra sess\xE3o Core; depois repita com intent_id, target, training_watched e idempotency_key id\xEAnticos."};return{content:[{type:"text",text:JSON.stringify(_)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(Y,"registerRemoteGrTrainingUpdate");function K(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_order_triage_address_update",{description:"Solicita aprova\xE7\xE3o para corrigir o endere\xE7o de um pedido em lote de triagem (admin). Coordenadas manuais exigem latitude e longitude juntas. Repita com intent_id e a mesma chave ap\xF3s a aprova\xE7\xE3o.",inputSchema:e.object({batch_id:e.uuid(),order_id:e.uuid(),destination_address:e.string().min(1),destination_lat:e.number().min(-90).max(90).optional(),destination_lng:e.number().min(-180).max(180).optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({batch_id:n,order_id:m,destination_address:i,destination_lat:s,destination_lng:l,idempotency_key:u,intent_id:d})=>{const p=d?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(d)}/execute`:"/api/v1/auth/mcp/write-intents",_={operation:"order.triage_address.update",batch_id:n,order_id:m,destination_address:i};s!==void 0&&l!==void 0&&(_.destination_lat=s,_.destination_lng=l);try{const v=await r(new URL(p,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":u,"content-type":"application/json"},body:JSON.stringify(_)}),g=await v.json();if(!v.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${g.error??v.status}`}]};const b=g.data,f=d?b:{...b,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(b.public_id)}?role=${encodeURIComponent(b.active_role)}`,o).href,next_step:"Revise e aprove a corre\xE7\xE3o do pedido em outra sess\xE3o Core; depois repita com intent_id e os mesmos campos e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(f)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(K,"registerRemoteTriageOrderUpdate");function ee(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_receiving_scan",{description:"Solicita aprova\xE7\xE3o para registrar um bip de recebimento na carrier ativa. Admin informa carrier_account_id; carrier usa a conta da sess\xE3o. Repita com intent_id e a mesma chave ap\xF3s aprova\xE7\xE3o.",inputSchema:e.object({barcode:e.string().min(1),carrier_account_id:e.uuid().optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({barcode:n,carrier_account_id:m,idempotency_key:i,intent_id:s})=>{const l=s?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(s)}/execute`:"/api/v1/auth/mcp/write-intents",u={operation:"receiving.order.scan",barcode:n};m&&(u.carrier_account_id=m);try{const d=await r(new URL(l,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":i,"content-type":"application/json"},body:JSON.stringify(u)}),p=await d.json();if(!d.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${p.error??d.status}`}]};const _=p.data,v=s?_:{..._,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(_.public_id)}?role=${encodeURIComponent(_.active_role)}`,o).href,next_step:"Revise o pedido e c\xF3digo bipado em outra sess\xE3o Core; depois repita com intent_id, o mesmo barcode, carrier_account_id quando usado e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(v)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(ee,"registerRemoteReceivingScan");function te(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){const m={...{shipper_id:e.uuid().nullable().optional(),base_id:e.uuid().nullable().optional()},code:e.string().min(1).max(255),name:e.string().min(1).max(255),postal_code_start:e.string().min(1).max(16),postal_code_end:e.string().min(1).max(16),priority_order:e.number().int().min(0).optional(),status:e.enum(["active","inactive"]).optional(),metadata:e.record(e.string(),e.unknown()).optional()},i=e.object(m).strict(),s=i.partial().refine(u=>Object.keys(u).length>0,{message:"changes deve conter ao menos um campo"}),l=h(async({operation:u,carrier_account_id:d,rule_id:p,values:_,idempotency_key:v,intent_id:g})=>{const b=g?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(g)}/execute`:"/api/v1/auth/mcp/write-intents",f={operation:u,..._};d!==void 0&&(f.carrier_account_id=d),p!==void 0&&(f.rule_id=p);try{const x=await r(new URL(b,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":v,"content-type":"application/json"},body:JSON.stringify(f)}),k=await x.json();if(!x.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${k.error??x.status}`}]};const w=k.data,C=g?w:{...w,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(w.public_id)}?role=${encodeURIComponent(w.active_role)}`,o).href,next_step:"Revise transportadora, escopo e regra antes/depois em outra sess\xE3o Core; depois repita com intent_id, os mesmos campos e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(C)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}},"send");y.registerTool("genne_receiving_rule_create",{description:"Solicita aprova\xE7\xE3o para criar regra de recebimento global, de shipper ou por base. Admin informa carrier_account_id; carrier usa a conta ativa. Repita com intent_id e o mesmo rule ap\xF3s aprova\xE7\xE3o.",inputSchema:e.object({carrier_account_id:e.uuid().optional(),rule:i,idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!1,idempotentHint:!0}},async({carrier_account_id:u,rule:d,idempotency_key:p,intent_id:_})=>l({operation:"receiving.rule.create",carrier_account_id:u,values:d,idempotency_key:p,intent_id:_})),y.registerTool("genne_receiving_rule_update",{description:"Solicita aprova\xE7\xE3o para atualizar parcialmente uma regra de recebimento. Campos de escopo omitidos s\xE3o preservados e null expl\xEDcito \xE9 enviado ao Core. Admin informa carrier_account_id; carrier usa a conta ativa.",inputSchema:e.object({carrier_account_id:e.uuid().optional(),rule_id:e.uuid(),changes:s,idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}).strict(),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({carrier_account_id:u,rule_id:d,changes:p,idempotency_key:_,intent_id:v})=>l({operation:"receiving.rule.update",carrier_account_id:u,rule_id:d,values:p,idempotency_key:_,intent_id:v}))}h(te,"registerRemoteReceivingRules");function oe(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_dispatch_route_create",{description:"Solicita aprova\xE7\xE3o para criar rota de expedi\xE7\xE3o com pedidos recebidos na carrier ativa. Admin informa carrier_account_id. Repita com intent_id e os mesmos campos e chave ap\xF3s aprova\xE7\xE3o.",inputSchema:e.object({driver_user_id:e.uuid(),barcodes:e.array(e.string().min(1).max(128)).min(1).max(100),route_name:e.string().min(1).max(120).optional(),carrier_account_id:e.uuid().optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!1,idempotentHint:!0}},async({driver_user_id:n,barcodes:m,route_name:i,carrier_account_id:s,idempotency_key:l,intent_id:u})=>{const d=u?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(u)}/execute`:"/api/v1/auth/mcp/write-intents",p={operation:"dispatch.route.create",driver_user_id:n,barcodes:m};i&&(p.route_name=i),s&&(p.carrier_account_id=s);try{const _=await r(new URL(d,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":l,"content-type":"application/json"},body:JSON.stringify(p)}),v=await _.json();if(!_.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${v.error??_.status}`}]};const g=v.data,b=u?g:{...g,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(g.public_id)}?role=${encodeURIComponent(g.active_role)}`,o).href,next_step:"Revise motorista e pedidos em outra sess\xE3o Core; depois repita com intent_id, os mesmos campos e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(b)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(oe,"registerRemoteDispatchRouteCreate");function ae(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_dispatch_route_add_orders",{description:"Solicita aprova\xE7\xE3o para adicionar pedidos recebidos a uma rota de expedi\xE7\xE3o manual ativa da carrier. Admin informa carrier_account_id; carrier usa a conta ativa. A rota pode j\xE1 ter iniciado. Repita com intent_id e os mesmos campos e chave ap\xF3s aprova\xE7\xE3o.",inputSchema:e.object({route_id:e.uuid(),barcodes:e.array(e.string().min(1).max(128)).min(1).max(100),reason:e.string().min(1).max(500).optional(),carrier_account_id:e.uuid().optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({route_id:n,barcodes:m,reason:i,carrier_account_id:s,idempotency_key:l,intent_id:u})=>{const d=u?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(u)}/execute`:"/api/v1/auth/mcp/write-intents",p={operation:"dispatch.route.add_orders",route_id:n,barcodes:m};i!==void 0&&(p.reason=i),s&&(p.carrier_account_id=s);try{const _=await r(new URL(d,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":l,"content-type":"application/json"},body:JSON.stringify(p)}),v=await _.json();if(!_.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${v.error??_.status}`}]};const g=v.data,b=u?g:{...g,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(g.public_id)}?role=${encodeURIComponent(g.active_role)}`,o).href,next_step:"Revise a rota, os pedidos e o motivo em outra sess\xE3o Core; depois repita com intent_id, os mesmos campos e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(b)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(ae,"registerRemoteDispatchRouteAddOrders");function ne(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){for(const n of[{tool:"genne_driver_route_start",operation:"driver.route.start",verb:"iniciar"},{tool:"genne_driver_route_finish",operation:"driver.route.finish",verb:"concluir"}])y.registerTool(n.tool,{description:`Solicita aprova\xE7\xE3o para ${n.verb} uma SavedRoute pr\xF3pria do motorista. Repita com intent_id, o mesmo route_id e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.`,inputSchema:e.object({route_id:e.uuid(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({route_id:m,idempotency_key:i,intent_id:s})=>{const l=s?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(s)}/execute`:"/api/v1/auth/mcp/write-intents";try{const u=await r(new URL(l,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":i,"content-type":"application/json"},body:JSON.stringify({operation:n.operation,route_id:m})}),d=await u.json();if(!u.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${d.error??u.status}`}]};const p=d.data,_=s?p:{...p,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(p.public_id)}?role=driver`,o).href,next_step:"Revise a rota em outra sess\xE3o Core do mesmo motorista; depois repita com intent_id, route_id e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(_)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(ne,"registerRemoteDriverRouteTransitions");function ie(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_driver_waypoint_deliver",{description:"Solicita aprova\xE7\xE3o para entregar os itens pendentes de uma parada em SavedRoute pr\xF3pria. O Core valida check-in e atualiza manifesto e eventos quando aplic\xE1veis. Repita com intent_id, os mesmos IDs e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.",inputSchema:e.object({route_id:e.uuid(),waypoint_id:e.uuid(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({route_id:n,waypoint_id:m,idempotency_key:i,intent_id:s})=>{const l=s?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(s)}/execute`:"/api/v1/auth/mcp/write-intents";try{const u=await r(new URL(l,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":i,"content-type":"application/json"},body:JSON.stringify({operation:"driver.waypoint.deliver",route_id:n,waypoint_id:m})}),d=await u.json();if(!u.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${d.error??u.status}`}]};const p=d.data,_=s?p:{...p,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(p.public_id)}?role=driver`,o).href,next_step:"Revise rota e parada em outra sess\xE3o Core do mesmo motorista; depois repita com intent_id, route_id, waypoint_id e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(_)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(ie,"registerRemoteDriverWaypointDeliver");function re(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_driver_package_item_deliver",{description:"Solicita aprova\xE7\xE3o para entregar um item pendente do manifesto em parada de rota pr\xF3pria. O Core valida check-in, estado e eventos. Repita com intent_id, os mesmos IDs e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.",inputSchema:e.object({route_id:e.uuid(),waypoint_id:e.uuid(),item_id:e.uuid(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({route_id:n,waypoint_id:m,item_id:i,idempotency_key:s,intent_id:l})=>{const u=l?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(l)}/execute`:"/api/v1/auth/mcp/write-intents";try{const d=await r(new URL(u,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":s,"content-type":"application/json"},body:JSON.stringify({operation:"driver.package_item.deliver",route_id:n,waypoint_id:m,item_id:i})}),p=await d.json();if(!d.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${p.error??d.status}`}]};const _=p.data,v=l?_:{..._,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(_.public_id)}?role=driver`,o).href,next_step:"Revise rota, parada e item em outra sess\xE3o Core do mesmo motorista; depois repita com intent_id, route_id, waypoint_id, item_id e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(v)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(re,"registerRemoteDriverPackageItemDeliver");function se(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_driver_waypoint_navigation_start",{description:"Solicita aprova\xE7\xE3o para registrar um evento de in\xEDcio de navega\xE7\xE3o em uma parada pr\xF3pria. N\xE3o abre um aplicativo de navega\xE7\xE3o nem altera carga ou status. Telemetria \xE9 opcional; o provider padr\xE3o \xE9 navigation_sdk_in_app. O Core valida posse, janela de edi\xE7\xE3o e ACL. Repita com intent_id, os mesmos dados e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.",inputSchema:e.object({route_id:e.uuid(),waypoint_id:e.uuid(),navigation_provider:e.string().trim().min(1).optional(),nav_sdk_version:e.string().trim().min(1).optional(),boot_duration_ms:e.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),waypoint_index:e.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),packages_count:e.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!1,idempotentHint:!0}},async({idempotency_key:n,intent_id:m,...i})=>{const s=m?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(m)}/execute`:"/api/v1/auth/mcp/write-intents",l={operation:"driver.waypoint.navigation.start",...i};try{const u=await r(new URL(s,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":n,"content-type":"application/json"},body:JSON.stringify(l)}),d=await u.json();if(!u.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${d.error??u.status}`}]};const p=d.data,_=m?p:{...p,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(p.public_id)}?role=driver`,o).href,next_step:"Revise a rota, a parada e a telemetria do evento em outra sess\xE3o Core do mesmo motorista; depois repita com intent_id, os mesmos dados e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(_)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(se,"registerRemoteDriverWaypointNavigationStart");function pe(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_driver_waypoint_notes",{description:"Solicita aprova\xE7\xE3o para substituir a observa\xE7\xE3o de uma parada pr\xF3pria do motorista. Envie notes como string; uma string vazia limpa a observa\xE7\xE3o. O Core valida posse e janela de edi\xE7\xE3o. Repita com intent_id, os mesmos dados e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.",inputSchema:e.object({route_id:e.uuid(),waypoint_id:e.uuid(),notes:e.string(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({route_id:n,waypoint_id:m,notes:i,idempotency_key:s,intent_id:l})=>{const u=l?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(l)}/execute`:"/api/v1/auth/mcp/write-intents",d={operation:"driver.waypoint.notes",route_id:n,waypoint_id:m,notes:i};try{const p=await r(new URL(u,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":s,"content-type":"application/json"},body:JSON.stringify(d)}),_=await p.json();if(!p.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${_.error??p.status}`}]};const v=_.data,g=l?v:{...v,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(v.public_id)}?role=driver`,o).href,next_step:"Revise a rota, a parada e a observa\xE7\xE3o em outra sess\xE3o Core do mesmo motorista; depois repita com intent_id, os mesmos dados e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(g)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(pe,"registerRemoteDriverWaypointNotes");function ce(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_driver_waypoint_packages",{description:"Solicita aprova\xE7\xE3o para alterar a quantidade de volumes de uma parada pr\xF3pria sem manifesto importado. Zero \xE9 v\xE1lido. O Core protege os itens do manifesto, valida posse e janela de edi\xE7\xE3o. Repita com intent_id, os mesmos dados e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.",inputSchema:e.object({route_id:e.uuid(),waypoint_id:e.uuid(),packages_count:e.number().int().min(0).max(2147483647),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({route_id:n,waypoint_id:m,packages_count:i,idempotency_key:s,intent_id:l})=>{const u=l?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(l)}/execute`:"/api/v1/auth/mcp/write-intents",d={operation:"driver.waypoint.packages",route_id:n,waypoint_id:m,packages_count:i};try{const p=await r(new URL(u,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":s,"content-type":"application/json"},body:JSON.stringify(d)}),_=await p.json();if(!p.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${_.error??p.status}`}]};const v=_.data,g=l?v:{...v,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(v.public_id)}?role=driver`,o).href,next_step:"Revise a rota, a parada e a quantidade de volumes em outra sess\xE3o Core do mesmo motorista; depois repita com intent_id, os mesmos dados e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(g)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(ce,"registerRemoteDriverWaypointPackages");function de(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_driver_waypoint_check_in",{description:"Solicita aprova\xE7\xE3o para registrar a localiza\xE7\xE3o atual em uma parada pr\xF3pria do motorista. O check-in \xE9 aditivo e o Core calcula dist\xE2ncia, limite e alerta. Repita com intent_id, os mesmos dados e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.",inputSchema:e.object({route_id:e.uuid(),waypoint_id:e.uuid(),lat:e.number().min(-90).max(90),lng:e.number().min(-180).max(180),accuracy_meters:e.number().min(0).optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!1,idempotentHint:!0}},async({route_id:n,waypoint_id:m,lat:i,lng:s,accuracy_meters:l,idempotency_key:u,intent_id:d})=>{const p=d?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(d)}/execute`:"/api/v1/auth/mcp/write-intents",_={operation:"driver.waypoint.check_in",route_id:n,waypoint_id:m,lat:i,lng:s};l!==void 0&&(_.accuracy_meters=l);try{const v=await r(new URL(p,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":u,"content-type":"application/json"},body:JSON.stringify(_)}),g=await v.json();if(!v.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${g.error??v.status}`}]};const b=g.data,f=d?b:{...b,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(b.public_id)}?role=driver`,o).href,next_step:"Revise a rota, a parada e as coordenadas em outra sess\xE3o Core do mesmo motorista; depois repita com intent_id, os mesmos dados e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(f)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(de,"registerRemoteDriverWaypointCheckIn");function me(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_driver_carrier_link",{description:"Solicita aprova\xE7\xE3o para vincular o motorista da sess\xE3o \xE0 transportadora identificada pelo c\xF3digo. O c\xF3digo n\xE3o aparece na aprova\xE7\xE3o. Repita com intent_id, o mesmo c\xF3digo e a mesma chave ap\xF3s aprova\xE7\xE3o em outra sess\xE3o driver.",inputSchema:e.object({driver_link_code:e.string().regex(/^\s*[A-Za-z0-9]{5}\s*$/),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({driver_link_code:n,idempotency_key:m,intent_id:i})=>{const s=i?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(i)}/execute`:"/api/v1/auth/mcp/write-intents";try{const l=await r(new URL(s,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":m,"content-type":"application/json"},body:JSON.stringify({operation:"driver.carrier.link",driver_link_code:n.trim().toUpperCase()})}),u=await l.json();if(!l.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${u.error??l.status}`}]};const d=u.data,p=i?d:{...d,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(d.public_id)}?role=driver`,o).href,next_step:"Revise a transportadora e o estado do v\xEDnculo em outra sess\xE3o Core driver; depois repita com intent_id, driver_link_code e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(p)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(me,"registerRemoteDriverCarrierLink");function ue(y,{coreOrigin:c,coreAccessToken:a,adapterKey:t,adminOrigin:o,fetchImpl:r}){y.registerTool("genne_tower_failure_policy_update",{description:"Solicita aprova\xE7\xE3o para alterar os motivos de insucesso permitidos \xE0 conta carrier/shipper ativa. Admin informa account_type e account_id. Repita com intent_id e os mesmos dados ap\xF3s aprova\xE7\xE3o.",inputSchema:e.object({reason_codes:e.array(e.string().min(1).max(64)).max(100),account_type:e.enum(["carrier","shipper"]).optional(),account_id:e.uuid().optional(),idempotency_key:e.string().min(16).max(128),intent_id:e.uuid().optional()}),annotations:{readOnlyHint:!1,openWorldHint:!1,destructiveHint:!0,idempotentHint:!0}},async({reason_codes:n,account_type:m,account_id:i,idempotency_key:s,intent_id:l})=>{const u=l?`/api/v1/auth/mcp/write-intents/${encodeURIComponent(l)}/execute`:"/api/v1/auth/mcp/write-intents",d={operation:"tower.failure_policy.update",reason_codes:n};m&&(d.account_type=m),i&&(d.account_id=i);try{const p=await r(new URL(u,c),{method:"POST",headers:{authorization:`Bearer ${a}`,"x-genne-mcp-adapter-key":t,"idempotency-key":s,"content-type":"application/json"},body:JSON.stringify(d)}),_=await p.json();if(!p.ok)return{isError:!0,content:[{type:"text",text:`Core recusou a inten\xE7\xE3o: ${_.error??p.status}`}]};const v=_.data,g=l?v:{...v,approval_url:new URL(`/admin/mcp-write-intents/${encodeURIComponent(v.public_id)}?role=${encodeURIComponent(v.active_role)}`,o).href,next_step:"Revise conta e lista de motivos em outra sess\xE3o Core; depois repita com intent_id, os mesmos campos e idempotency_key."};return{content:[{type:"text",text:JSON.stringify(g)}]}}catch{return{isError:!0,content:[{type:"text",text:"Falha ao consultar a inten\xE7\xE3o no Core; repita com a mesma idempotency_key."}]}}})}h(ue,"registerRemoteTowerFailurePolicyUpdate");function Ue({auth:y,coreOrigin:c,resource:a,adapterKey:t,adminOrigin:o,fetchImpl:r=fetch}){return z({auth:y,coreOrigin:c,resource:a,createServerForContext:h(({coreAccessToken:n,context:m})=>{const i=R({GENNE_API_URL:c,GENNE_ACCESS_TOKEN:n});if(t&&o&&m.scopes?.includes("genne.write.request")){const s=A(r);B(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),J(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),F(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),T(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),P(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),D(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),W(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),G(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),q(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),M(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),Z(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),X(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),Q(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),V(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),Y(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),K(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),ee(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),te(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),oe(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),ae(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),ne(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),de(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),se(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),pe(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),ce(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),me(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),ie(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),re(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s}),ue(i,{coreOrigin:c,coreAccessToken:n,adapterKey:t,adminOrigin:o,fetchImpl:s})}return i},"createServerForContext")})}h(Ue,"createRemoteProductMcpHandler"),process.argv[1]&&import.meta.url===j(process.argv[1]).href&&U(()=>R());export{R as createProductServer,Ue as createRemoteProductMcpHandler};
@@ -0,0 +1 @@
1
+ var C=Object.defineProperty;var d=(o,t)=>C(o,"name",{value:t,configurable:!0});import{createApi as b,fail as i,uuid as p}from"./api.js";import{usersCommand as _}from"./commands/users.js";import{identityCommand as v}from"./commands/identity.js";import{accessCommand as w}from"./commands/access.js";import{driverCommand as R}from"./commands/driver.js";import{supportCommand as A}from"./commands/support.js";import{feedbackCommand as E}from"./commands/feedback.js";import{crmCommand as y}from"./commands/crm.js";import{notificationsCommand as S}from"./commands/notifications.js";import{contentCommand as T}from"./commands/content.js";import{companiesCommand as U}from"./commands/companies.js";import{grCommand as G}from"./commands/gr.js";import{ordersCommand as N}from"./commands/orders.js";import{driverRoutesCommand as O}from"./commands/driver-routes.js";import{logisticsCommand as P}from"./commands/logistics.js";import{operationsConfigCommand as I}from"./commands/operations-config.js";import{financialCommand as j}from"./commands/financial.js";import{routesCommand as q}from"./commands/routes.js";import{towerCommand as x}from"./commands/tower.js";import{commandHelp as F}from"./help.js";import{environmentCommand as H}from"./session.js";async function ro(o,{env:t=process.env,input:a,confirm:f}={}){if(o.length===0||o[0]==="help"||o.at(-1)==="--help"){const e=o[0]==="help"?o.slice(1).filter(n=>n!=="--help"):o.at(-1)==="--help"?o.slice(0,-1):[];return F(e)??i("USAGE",`Comando n\xE3o encontrado: ${e.join(" ")}. Use genne help.`,2)}if(o.length===2&&o[0]==="env"&&o[1]==="show")return H(t,["show"]);o.length===1&&o[0]==="logout"&&(o=["session","logout"]);const u=o.length===3&&o[0]==="users"&&o[1]==="driver"&&o[2]==="register",h=o.length===3&&o[0]==="auth"&&o[1]==="membership-invitations"&&o[2]==="accept",s=o[0]==="password"&&["forgot","reset"].includes(o[1])||u||h,c=o.length===4&&o[0]==="shipper"&&o[1]==="route"&&o[2]==="show";c&&p(o[3]);const r=b(t,{allowAnonymous:s});let m=null;s||(m=(await r("GET","/auth/me")).data,(!m||typeof m!="object"||typeof m.role!="string")&&i("RESPONSE","Resposta inv\xE1lida da API"));const l={api:r,user:m,uuid:p,fail:i,input:a??(()=>i("INPUT","Forne\xE7a JSON em stdin")),confirm:f??(()=>i("CONFIRM","Confirma\xE7\xE3o interativa necess\xE1ria")),requireRole(e){m?.role!==e&&i("HTTP_403","Acesso negado",403)}};if(o.length===1&&o[0]==="whoami"){const e=m.business_membership,n=e?.business_account_id&&["shipper","carrier"].includes(m.role)?{id:e.business_account_id,name:e.business_account?.name??null,membership_id:e.id,membership_role:e.membership_role}:null;return{data:{name:m.name,email:m.email,role:m.role,...n?{business_account:n}:{}}}}if(c)return l.requireRole("shipper"),r("GET",`/shipper/operational-routes/${p(o[3])}`);for(const e of[_,R,O,v,w,A,E,y,S,T,U,G,N,I,j,P,x,q]){const n=await e(o,l);if(n!==null)return n}i("USAGE","Comando desconhecido. Use genne help.",2)}d(ro,"runOperation");export{ro as runOperation};
@@ -0,0 +1 @@
1
+ var a=Object.defineProperty;var i=(e,r)=>a(e,"name",{value:r,configurable:!0});import{constants as t}from"node:fs";import{open as s}from"node:fs/promises";function c(e,r=!1){return(r?e.isDirectory():e.isFile())&&!e.isSymbolicLink()&&!(e.mode&63)&&(!process.getuid||e.uid===process.getuid())}i(c,"ownedFile");async function w(e){let r;try{r=await s(e,t.O_RDONLY|t.O_NOFOLLOW)}catch(o){throw o?.code==="ENOENT"?Object.assign(new Error("missing private file"),{code:"ENOENT"}):Object.assign(new Error("insecure private file"),{code:"INSECURE"})}try{if(!c(await r.stat()))throw Object.assign(new Error("insecure private file"),{code:"INSECURE"});return await r.readFile()}finally{await r.close()}}i(w,"readOwnedFile");export{c as ownedFile,w as readOwnedFile};
@@ -0,0 +1,31 @@
1
+ var I=Object.defineProperty;var s=(n,T)=>I(n,"name",{value:T,configurable:!0});import{createCipheriv as U,createDecipheriv as f,randomBytes as m}from"node:crypto";import{constants as c}from"node:fs";import{lstat as k,mkdir as D,open as L}from"node:fs/promises";import{dirname as l}from"node:path";import{DatabaseSync as X}from"node:sqlite";function A(n,T=!1){if((T?!n.isDirectory():!n.isFile())||n.isSymbolicLink()||n.mode&63||process.getuid&&n.uid!==process.getuid())throw new Error("Insecure remote auth storage")}s(A,"secure");async function M(n,T){if(!Buffer.isBuffer(T)||T.length!==32)throw new Error("Remote auth encryption key must be 32 bytes");await D(l(n),{recursive:!0,mode:448});const g=await L(l(n),c.O_RDONLY|c.O_DIRECTORY|c.O_NOFOLLOW).catch(()=>{throw new Error("Insecure remote auth storage")});try{A(await g.stat(),!0)}finally{await g.close()}try{await(await L(n,c.O_RDWR|c.O_CREAT|c.O_EXCL|c.O_NOFOLLOW,384)).close()}catch(e){if(e.code!=="EEXIST")throw new Error("Insecure remote auth storage")}const _=await L(n,c.O_RDWR|c.O_NOFOLLOW).catch(()=>{throw new Error("Insecure remote auth storage")});let r;try{A(await _.stat()),r=new X(n);const e=await k(n),t=await _.stat();if(e.isSymbolicLink()||e.dev!==t.dev||e.ino!==t.ino)throw new Error("Insecure remote auth storage")}catch(e){throw r?.close(),e?.message==="Insecure remote auth storage",e}finally{await _.close()}r.exec("PRAGMA busy_timeout = 5000; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON"),r.exec(`
2
+ CREATE TABLE IF NOT EXISTS authorizations (
3
+ id TEXT PRIMARY KEY, client_id TEXT NOT NULL, redirect_uri TEXT NOT NULL,
4
+ resource TEXT NOT NULL, scope TEXT NOT NULL, state TEXT NOT NULL,
5
+ challenge TEXT NOT NULL, expires_at INTEGER NOT NULL,
6
+ status TEXT NOT NULL, binding_hash TEXT, code_hash TEXT UNIQUE, grant_id TEXT
7
+ );
8
+ CREATE TABLE IF NOT EXISTS grants (
9
+ id TEXT PRIMARY KEY, client_id TEXT NOT NULL, resource TEXT NOT NULL,
10
+ scope TEXT NOT NULL, user_id TEXT NOT NULL, role TEXT NOT NULL,
11
+ membership_public_id TEXT, session_public_id TEXT NOT NULL,
12
+ core_tokens TEXT NOT NULL, expires_at INTEGER NOT NULL,
13
+ revoked_at INTEGER
14
+ );
15
+ CREATE TABLE IF NOT EXISTS tokens (
16
+ token_hash TEXT PRIMARY KEY, grant_id TEXT NOT NULL REFERENCES grants(id),
17
+ kind TEXT NOT NULL, status TEXT NOT NULL, expires_at INTEGER NOT NULL
18
+ );
19
+ CREATE INDEX IF NOT EXISTS grants_user ON grants(user_id);
20
+ CREATE INDEX IF NOT EXISTS tokens_grant ON tokens(grant_id);
21
+ `);const p=s(e=>{r.exec("BEGIN IMMEDIATE");try{const t=e();return r.exec("COMMIT"),t}catch(t){throw r.exec("ROLLBACK"),t}},"transaction"),h=s(e=>{const t=m(12),i=U("aes-256-gcm",T,t),o=Buffer.concat([i.update(JSON.stringify(e)),i.final()]);return Buffer.concat([t,i.getAuthTag(),o]).toString("base64url")},"seal"),S=s(e=>{const t=Buffer.from(e,"base64url"),i=f("aes-256-gcm",T,t.subarray(0,12));return i.setAuthTag(t.subarray(12,28)),JSON.parse(Buffer.concat([i.update(t.subarray(28)),i.final()]).toString())},"unseal"),N=s(e=>e&&{...e,core_tokens:S(e.core_tokens)},"grant"),O=s(e=>{r.prepare(`DELETE FROM authorizations
22
+ WHERE status IN ('pending', 'denied', 'approved') AND expires_at < ?`).run(e),r.prepare(`DELETE FROM authorizations
23
+ WHERE status = 'consumed' AND grant_id IN (
24
+ SELECT id FROM grants WHERE revoked_at IS NOT NULL OR expires_at < ?
25
+ )`).run(e)},"purgeAuthorizations");return{close:s(()=>r.close(),"close"),purgeAuthorizations:O,putAuthorization:s(e=>r.prepare(`INSERT INTO authorizations VALUES
26
+ (@id,@client_id,@redirect_uri,@resource,@scope,@state,@challenge,@expires_at,'pending',NULL,NULL,NULL)`).run(e),"putAuthorization"),getAuthorization:s(e=>r.prepare("SELECT * FROM authorizations WHERE id = ?").get(e),"getAuthorization"),setBindingHash:s((e,t,i)=>r.prepare(`UPDATE authorizations SET binding_hash = ?
27
+ WHERE id = ? AND status = 'pending' AND expires_at > ?`).run(t,e,i).changes===1,"setBindingHash"),denyAuthorization:s(e=>r.prepare("UPDATE authorizations SET status = 'denied' WHERE id = ? AND status = 'pending'").run(e).changes===1,"denyAuthorization"),approveAuthorization:s((e,t,i,o,d,E)=>p(()=>{const a=r.prepare("SELECT * FROM authorizations WHERE id = ?").get(e);return!a||a.status!=="pending"||a.expires_at<=E||a.binding_hash!==t?!1:(r.prepare(`INSERT INTO grants VALUES
28
+ (@id,@client_id,@resource,@scope,@user_id,@role,@membership_public_id,@session_public_id,@core_tokens,@expires_at,NULL)`).run({...o,core_tokens:h(d)}),r.prepare("UPDATE authorizations SET status = 'approved', code_hash = ?, grant_id = ? WHERE id = ?").run(i,o.id,e),!0)}),"approveAuthorization"),redeemCode:s((e,t,i,o,d,E)=>p(()=>{const a=r.prepare("SELECT * FROM authorizations WHERE code_hash = ?").get(e);return!a||a.client_id!==t||a.redirect_uri!==i||a.resource!==o||a.challenge!==d?null:a.status==="consumed"?(r.prepare("UPDATE grants SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL").run(E,a.grant_id),{error:"reuse",grant_id:a.grant_id}):a.status!=="approved"||a.expires_at<=E?null:(r.prepare("UPDATE authorizations SET status = 'consumed' WHERE id = ?").run(a.id),{authorization:a,grant:N(r.prepare("SELECT * FROM grants WHERE id = ?").get(a.grant_id))})}),"redeemCode"),insertTokens:s((e,t,i,o,d,E)=>p(()=>{const a=r.prepare("SELECT * FROM grants WHERE id = ?").get(e);if(!a||a.revoked_at||a.expires_at<=E)return!1;const u=r.prepare("INSERT INTO tokens VALUES (?, ?, ?, 'active', ?)");return u.run(t,e,"access",o),u.run(i,e,"refresh",d),!0}),"insertTokens"),getAccess:s((e,t)=>{O(t);const i=r.prepare(`SELECT g.* FROM tokens t JOIN grants g ON g.id = t.grant_id
29
+ WHERE t.token_hash = ? AND t.kind = 'access' AND t.status = 'active'
30
+ AND t.expires_at > ? AND g.expires_at > ? AND g.revoked_at IS NULL`).get(e,t,t);return N(i)},"getAccess"),rotateRefresh:s((e,t,i,o,d,E)=>p(()=>{const a=r.prepare("SELECT * FROM tokens WHERE token_hash = ? AND kind = 'refresh'").get(e);if(!a)return{error:"invalid_grant"};if(a.status==="rotated")return r.prepare("UPDATE grants SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL").run(E,a.grant_id),{error:"reuse",grant_id:a.grant_id};const u=r.prepare("SELECT * FROM grants WHERE id = ?").get(a.grant_id);if(a.status!=="active"||a.expires_at<=E||!u||u.revoked_at||u.expires_at<=E)return{error:"invalid_grant"};r.prepare("UPDATE tokens SET status = 'rotated' WHERE token_hash = ?").run(e);const R=r.prepare("INSERT INTO tokens VALUES (?, ?, ?, 'active', ?)");return R.run(t,u.id,"access",o),R.run(i,u.id,"refresh",d),{grant:N(u)}}),"rotateRefresh"),updateCoreTokens:s((e,t)=>r.prepare("UPDATE grants SET core_tokens = ? WHERE id = ? AND revoked_at IS NULL").run(h(t),e).changes===1,"updateCoreTokens"),getGrant:s(e=>N(r.prepare("SELECT * FROM grants WHERE id = ?").get(e)),"getGrant"),listGrants:s(e=>r.prepare(`SELECT id, client_id, resource, scope, role,
31
+ membership_public_id, session_public_id, expires_at, revoked_at FROM grants WHERE user_id = ? ORDER BY rowid DESC`).all(e),"listGrants"),revokeGrant:s((e,t)=>r.prepare("UPDATE grants SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL").run(t,e).changes===1,"revokeGrant")}}s(M,"openRemoteAuthStore");export{M as openRemoteAuthStore};
@@ -0,0 +1 @@
1
+ var T=Object.defineProperty;var u=(i,n)=>T(i,"name",{value:n,configurable:!0});import{createHash as $,randomBytes as O}from"node:crypto";const l=u(i=>$("sha256").update(i).digest("base64url"),"sha"),m=u(()=>O(32).toString("base64url"),"opaque"),U=u((i,n)=>i===n,"same"),o=u(()=>{throw new Error("invalid_grant")},"denied"),x=Object.freeze(["genne.read","genne.write.request"]),S=x.join(" ");function I(i){const n=O(16);n.writeUIntBE(i,0,6),n[6]=n[6]&15|112,n[8]=n[8]&63|128;const _=n.toString("hex");return`${_.slice(0,8)}-${_.slice(8,12)}-${_.slice(12,16)}-${_.slice(16,20)}-${_.slice(20)}`}u(I,"publicId");function C(i){return(!i||i.id===void 0||i.id===null)&&o(),{user_id:String(i.id),role:i.role,membership_public_id:i.business_membership?.id??i.membership?.id??null}}u(C,"identity");function f(i){const n=new URL(i);if(n.protocol!=="https:"||n.username||n.password||n.hash)throw new Error("Invalid OAuth URL");return n.href}u(f,"validHttps");function P(i,n){try{const _=JSON.parse(Buffer.from(i.split(".")[1],"base64url")).exp;return!Number.isInteger(_)||_*1e3<=n+6e4}catch{return!0}}u(P,"expiresSoon");function H({store:i,core:n,resource:_,issuer:y,clientId:b,redirectUris:A,now:c=Date.now}){if(f(_),f(y),!b||!Array.isArray(A)||!A.length)throw new Error("OAuth client not configured");const E=new Set(A.map(f)),w=new Map;function B(t){const e=i.getAuthorization(t);return(!e||e.status!=="pending"||e.expires_at<=c())&&o(),e}u(B,"pending");function G(t){return{authorization_id:t.id,client_id:t.client_id,redirect_uri:t.redirect_uri,resource:t.resource,scope:t.scope,state:t.state,code_challenge:t.challenge,code_challenge_method:"S256",expires_at:t.expires_at,callback_uri:new URL("/oauth/handoff",y).href}}u(G,"handoffBinding");async function z(t){try{let e=t.core_tokens;return P(e.token,c())&&(e=await n.refreshSession(e.refresh_token)),await n.revokeSession(e.token,t.session_public_id),!0}catch{return!1}}u(z,"revokeCoreSession");async function R(t){const r=(w.get(t.id)??Promise.resolve()).catch(()=>{}).then(async()=>{const s=i.getGrant(t.id);(!s||s.revoked_at||s.expires_at<=c()||s.client_id!==b||s.resource!==_||s.scope!==S)&&o();let a=s.core_tokens;if(P(a.token,c()))try{const d=await n.refreshSession(a.refresh_token);a={token:d.token,refresh_token:d.refresh_token},(!a.token||!a.refresh_token||!i.updateCoreTokens(t.id,a))&&o()}catch{i.revokeGrant(t.id,c()),o()}let p;try{p=await n.validateSession(a.token,s.session_public_id)}catch{i.revokeGrant(t.id,c()),o()}return(!U(String(p.user_id),s.user_id)||p.role!==s.role||(p.membership_public_id??null)!==s.membership_public_id||p.session_public_id!==s.session_public_id)&&(i.revokeGrant(t.id,c()),o()),{...s,core_tokens:a}});w.set(t.id,r);try{return await r}finally{w.get(t.id)===r&&w.delete(t.id)}}return u(R,"withCoreSession"),{protectedResourceMetadata:u(()=>({resource:_,authorization_servers:[y],scopes_supported:x}),"protectedResourceMetadata"),authorizationServerMetadata:u(()=>({issuer:y,authorization_endpoint:new URL("/oauth/authorize",y).href,token_endpoint:new URL("/oauth/token",y).href,response_types_supported:["code"],grant_types_supported:["authorization_code","refresh_token"],code_challenge_methods_supported:["S256"],token_endpoint_auth_methods_supported:["none"],scopes_supported:x}),"authorizationServerMetadata"),start(t){if(t.client_id!==b||!E.has(t.redirect_uri)||t.response_type!=="code"||t.resource!==_||t.scope!==S||t.code_challenge_method!=="S256"||!/^[A-Za-z0-9_-]{43,128}$/.test(t.code_challenge??"")||typeof t.state!="string"||t.state.length<8||t.state.length>1024)throw new Error("invalid_request");const e=m();return i.purgeAuthorizations(c()),i.putAuthorization({id:e,client_id:b,redirect_uri:t.redirect_uri,resource:_,scope:S,state:t.state,challenge:t.code_challenge,expires_at:c()+6e5}),{authorizationId:e,expiresIn:600}},handoffRequest(t){const e=B(t),r=G(e),s=l(JSON.stringify(r));return i.setBindingHash(t,s,c())||o(),r},denyAuthorization:u(t=>i.denyAuthorization(t),"denyAuthorization"),async completeHandoff(t,e){const r=i.getAuthorization(t);(!r||r.status!=="pending"||r.expires_at<=c())&&((!r||r.status==="pending")&&e?.token&&e?.session_public_id&&await n.revokeSession(e.token,e.session_public_id).catch(()=>{}),o());const s=G(r),a=l(JSON.stringify(s));if((!(e&&Object.entries(s).every(([h,L])=>e[h]===L))||r.binding_hash!==a||!["approved","denied"].includes(e.decision))&&(e?.token&&e?.session_public_id&&await n.revokeSession(e.token,e.session_public_id).catch(()=>{}),o()),e.decision==="denied"){(e.token||e.refresh_token||e.session_public_id)&&(e.token&&e.session_public_id&&await n.revokeSession(e.token,e.session_public_id).catch(()=>{}),o()),i.denyAuthorization(t)||o();const h=new URL(r.redirect_uri);return h.searchParams.set("error","access_denied"),h.searchParams.set("state",r.state),h.href}const d=I(c());(e.user_id===void 0||e.user_id===null||!["admin","driver","carrier","shipper"].includes(e.role)||["carrier","shipper"].includes(e.role)&&!e.membership_public_id||typeof e.session_public_id!="string"||!e.session_public_id||typeof e.token!="string"||!e.token||typeof e.refresh_token!="string"||!e.refresh_token)&&(e.token&&e.session_public_id&&await n.revokeSession(e.token,e.session_public_id).catch(()=>{}),o());const k=m();let g;try{g=i.approveAuthorization(t,a,l(k),{id:d,client_id:r.client_id,resource:r.resource,scope:r.scope,user_id:String(e.user_id),role:e.role,membership_public_id:e.membership_public_id??null,session_public_id:e.session_public_id,expires_at:c()+30*864e5},{token:e.token,refresh_token:e.refresh_token},c())}catch(h){throw await n.revokeSession(e.token,e.session_public_id).catch(()=>{}),h}g||(await n.revokeSession(e.token,e.session_public_id).catch(()=>{}),o());const v=new URL(r.redirect_uri);return v.searchParams.set("code",k),v.searchParams.set("state",r.state),v.href},async exchangeCode({code:t,code_verifier:e,client_id:r,redirect_uri:s,resource:a,scope:p}){(r!==b||!E.has(s)||a!==_||p!==void 0&&p!==S||typeof t!="string"||t.length!==43||!/^[A-Za-z0-9._~-]{43,128}$/.test(e??""))&&o();const d=i.redeemCode(l(t),r,s,_,l(e),c());if(d?.error==="reuse"){const h=i.getGrant(d.grant_id);h&&await z(h),o()}d||o();const k=await R(d.grant),g=m(),v=m();return i.insertTokens(k.id,l(g),l(v),c()+9e5,k.expires_at,c())||o(),{access_token:g,token_type:"Bearer",expires_in:900,refresh_token:v,scope:k.scope}},async refresh({refresh_token:t,client_id:e,resource:r,scope:s}){(e!==b||r!==_||s!==void 0&&s!==S||typeof t!="string")&&o();const a=m(),p=m(),d=i.rotateRefresh(l(t),l(a),l(p),c()+9e5,c()+30*864e5,c());if(d.error==="reuse"){const g=i.getGrant(d.grant_id);g&&await z(g)}d.error&&o();const k=await R(d.grant);return{access_token:a,token_type:"Bearer",expires_in:900,refresh_token:p,scope:k.scope}},async validateCall(t,e="genne.read"){(typeof t!="string"||t.length!==43)&&o();const r=i.getAccess(l(t),c());(!r||r.client_id!==b||r.resource!==_||r.scope!==S||!x.includes(e))&&o();const s=await R(r);return{grantPublicId:s.id,coreAccessToken:s.core_tokens.token,userId:s.user_id,role:s.role,membershipPublicId:s.membership_public_id,sessionPublicId:s.session_public_id,scopes:s.scope.split(" ")}},async listGrants(t){const e=C(await n.inspectApprover(t));return i.listGrants(e.user_id)},async revokeGrant(t,e){const r=C(await n.inspectApprover(e)),s=i.getGrant(t);return(!s||s.user_id!==r.user_id)&&o(),i.revokeGrant(t,c()),{revoked:!0,coreRevocationConfirmed:await z(s)}}}}u(H,"createRemoteAuth");export{S as REMOTE_SCOPE,x as REMOTE_SCOPES,H as createRemoteAuth};
@@ -0,0 +1 @@
1
+ var w=Object.defineProperty;var t=(h,i)=>w(h,"name",{value:i,configurable:!0});import{currentRequestSignal as m}from"./request-scope.js";function v({origin:h,adapterKey:i,consentOrigin:f,fetchImpl:p=fetch}){const n=new URL(h);if(n.protocol!=="https:"&&!["localhost","127.0.0.1","[::1]"].includes(n.hostname))throw new Error("Core API requires HTTPS");if(n.pathname!=="/"||n.search||n.hash||n.username||n.password||typeof i!="string"||i.length<32)throw new Error("Invalid Core adapter configuration");const a=new URL(f);if(a.protocol!=="https:"||a.pathname!=="/"||a.search||a.hash||a.username||a.password)throw new Error("Invalid Core/Admin consent origin");async function s(e,r,o,u,l=!1){let c;try{c=await p(`${n.origin}/api/v1${r}`,{method:e,redirect:"error",headers:{accept:"application/json",...o?{authorization:`Bearer ${o}`}:{},...l?{"x-genne-mcp-adapter-key":i}:{},...u===void 0?{}:{"content-type":"application/json"}},...u===void 0?{}:{body:JSON.stringify(u)},signal:AbortSignal.any([AbortSignal.timeout(15e3),m()].filter(Boolean))})}catch{throw new Error("Core unavailable")}if(!c.ok)throw Object.assign(new Error("Core denied session"),{status:c.status});if(c.status===204)return{};const d=await c.json().catch(()=>null);if(!d?.data||typeof d.data!="object")throw new Error("Invalid Core response");return d.data}return t(s,"request"),{async registerHandoff(e){const r=await s("POST","/auth/mcp/handoffs","",e,!0),o=new URL(r.authorization_url);if(o.origin!==a.origin||o.username||o.password||o.hash)throw new Error("Invalid Core/Admin consent redirect");return o.href},redeemHandoff:t((e,r)=>s("POST","/auth/mcp/handoffs/redeem","",{authorization_id:e,handoff_code:r},!0),"redeemHandoff"),inspectApprover:t(e=>s("GET","/auth/me",e),"inspectApprover"),validateSession:t((e,r)=>s("GET",`/auth/mcp/sessions/${encodeURIComponent(r)}`,e,void 0,!0),"validateSession"),revokeSession:t((e,r)=>s("POST",`/auth/mcp/sessions/${encodeURIComponent(r)}/revoke`,e,{},!0),"revokeSession"),refreshSession:t(e=>s("POST","/auth/refresh","",{refresh_token:e}),"refreshSession")}}t(v,"createRemoteCore");export{v as createRemoteCore};
@@ -0,0 +1 @@
1
+ var l=Object.defineProperty;var h=(t,n)=>l(t,"name",{value:n,configurable:!0});const p={"content-type":"application/json","cache-control":"no-store"},w=h(async t=>{if(Number(t.headers.get("content-length")??0)>8192)throw new Error("request_too_large");const n=await t.text();if(n.length>8192)throw new Error("request_too_large");return Object.fromEntries(new URLSearchParams(n))},"form"),a=h((t,n=200)=>new Response(JSON.stringify(t),{status:n,headers:p}),"json"),u=h(t=>new Response(null,{status:303,headers:{location:t,"cache-control":"no-store","referrer-policy":"no-referrer"}}),"redirect");function g({auth:t,core:n,mcpHandler:s}){const c=h(d=>/^Bearer (.+)$/.exec(d.headers.get("authorization")??"")?.[1],"browserToken");return h(async function(r){const o=new URL(r.url);try{if(r.method==="GET"&&o.pathname==="/.well-known/oauth-protected-resource")return a(t.protectedResourceMetadata());if(r.method==="GET"&&o.pathname==="/.well-known/oauth-authorization-server")return a(t.authorizationServerMetadata());if(r.method==="GET"&&o.pathname==="/oauth/authorize"){const e=t.start(Object.fromEntries(o.searchParams));try{return u(await n.registerHandoff(t.handoffRequest(e.authorizationId)))}catch(i){throw t.denyAuthorization(e.authorizationId),i}}if(r.method==="GET"&&o.pathname==="/oauth/handoff"){const e=o.searchParams.get("authorization_id")??"",i=o.searchParams.get("handoff_code")??"";if(!/^[A-Za-z0-9_-]{43}$/.test(e)||!/^[A-Za-z0-9_-]{43}$/.test(i))return a({error:"invalid_request"},400);const m=await n.redeemHandoff(e,i);return u(await t.completeHandoff(e,m))}if(r.method==="POST"&&o.pathname==="/oauth/token"){const e=await w(r),i=e.grant_type==="authorization_code"?await t.exchangeCode(e):e.grant_type==="refresh_token"?await t.refresh(e):null;return i?a(i):a({error:"unsupported_grant_type"},400)}if(r.method==="GET"&&o.pathname==="/oauth/grants"){const e=c(r);return e?a({data:await t.listGrants(e)}):a({error:"unauthorized"},401)}const f=/^\/oauth\/grants\/([0-9a-f-]{36})\/revoke$/.exec(o.pathname);if(r.method==="POST"&&f){const e=c(r);return e?a({data:await t.revokeGrant(f[1],e)}):a({error:"unauthorized"},401)}return o.pathname==="/mcp"&&s?s(r):a({error:"not_found"},404)}catch{return o.pathname==="/oauth/token"?a({error:"invalid_grant"},400):a({error:"authorization_failed"},400)}},"handleRemote")}h(g,"createRemoteOAuthHandler");export{g as createRemoteOAuthHandler};
@@ -0,0 +1 @@
1
+ var m=Object.defineProperty;var a=(e,t)=>m(e,"name",{value:t,configurable:!0});import{McpServer as y,WebStandardStreamableHTTPServerTransport as S}from"@modelcontextprotocol/server";import{z as E}from"zod";import{runOperation as O}from"./operations.js";import{REMOTE_SCOPE as R,REMOTE_SCOPES as g}from"./remote-auth.js";function v({coreOrigin:e,coreAccessToken:t}){const r=new y({name:"genne-product-remote",version:"0.1.0"});return r.registerTool("genne_whoami",{description:"Consulta a identidade e o papel ativo da sess\xE3o Genne.",inputSchema:E.object({}),annotations:{readOnlyHint:!0,openWorldHint:!1,destructiveHint:!1}},async()=>{const s=await O(["whoami"],{env:{GENNE_API_URL:e,GENNE_ACCESS_TOKEN:t}});return{content:[{type:"text",text:JSON.stringify(s)}]}}),r}a(v,"createBasicReadServer");function J({auth:e,coreOrigin:t,resource:r,createServerForContext:s=v}){const i=`Bearer resource_metadata="${new URL("/.well-known/oauth-protected-resource",r).href}", scope="${R}"`;return a(async function(p){const u=/^Bearer ([A-Za-z0-9_-]{43})$/.exec(p.headers.get("authorization")??"");if(!u)return new Response(JSON.stringify({error:"unauthorized"}),{status:401,headers:{"content-type":"application/json","www-authenticate":i}});let c;try{c=await e.validateCall(u[1])}catch{return new Response(JSON.stringify({error:"unauthorized"}),{status:401,headers:{"content-type":"application/json","www-authenticate":i}})}const l=s({coreOrigin:t,coreAccessToken:c.coreAccessToken,context:c}),d=new S({enableJsonResponse:!0});await l.connect(d);try{const n=await d.handleRequest(p);if(!n.headers.get("content-type")?.includes("application/json"))return n;const w=await n.text();if(!w)return new Response(null,n);const o=JSON.parse(w);for(const f of Array.isArray(o)?o:[o])for(const h of f.result?.tools??[])h.securitySchemes=[{type:"oauth2",scopes:g}];return new Response(JSON.stringify(o),n)}finally{await l.close()}},"handleMcp")}a(J,"createRemoteMcpHandler");export{v as createBasicReadServer,J as createRemoteMcpHandler};
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ var B=Object.defineProperty;var i=(t,r)=>B(t,"name",{value:r,configurable:!0});import{createServer as L}from"node:http";import{realpathSync as y}from"node:fs";import{readOwnedFile as U}from"./private-file.js";import{runWithRequestSignal as $}from"./request-scope.js";import{Readable as x}from"node:stream";import{isAbsolute as R}from"node:path";import{fileURLToPath as v}from"node:url";import Y from"../package.json"with{type:"json"};import{openRemoteAuthStore as F}from"./remote-auth-store.js";import{createRemoteAuth as H}from"./remote-auth.js";import{createRemoteCore as k}from"./remote-core.js";import{createRemoteOAuthHandler as W}from"./remote-http.js";import{createRemoteProductMcpHandler as z}from"./mcp.js";const K="genne-mcp-remote",V=Y.version,X=1024*1024,j=16*1024*1024,J=new Set(["localhost","127.0.0.1","[::1]"]),Q=new Set(["/health","/mcp","/oauth/authorize","/oauth/handoff","/oauth/token","/oauth/grants","/.well-known/oauth-protected-resource","/.well-known/oauth-authorization-server"]);class c extends Error{static{i(this,"RemoteConfigError")}constructor(r){super(r),this.name="RemoteConfigError"}}class I extends Error{static{i(this,"RequestTooLargeError")}constructor(){super("request_too_large"),this.name="RequestTooLargeError"}}class d extends Error{static{i(this,"InvalidRequestTargetError")}constructor(){super("invalid_request_target"),this.name="InvalidRequestTargetError"}}const C=i(t=>typeof t=="string"&&t.trim()!=="","hasValue");function p(t,r){if(C(t[r]))return t[r].trim()}i(p,"valueFrom");function E(t,r){const e=p(t,r);if(!e)throw new c(`Missing required configuration: ${r}`);return e}i(E,"requiredValue");function O(t,r,{https:e=!0,root:n=!1,expectedPath:a}={}){let o;try{o=new URL(t)}catch{throw new c(`Invalid ${r}`)}if(e&&o.protocol!=="https:"||!e&&!["https:","http:"].includes(o.protocol)||o.username||o.password||o.search||o.hash||n&&o.pathname!=="/"||a!==void 0&&o.pathname!==a)throw new c(`Invalid ${r}`);return o.href}i(O,"url");function g(t,r,{https:e=!0,allowLocalHttp:n=!1}={}){const a=O(t,r,{https:e&&!n}),o=new URL(a);if(o.pathname!=="/"||o.port&&!/^\d+$/.test(o.port))throw new c(`Invalid ${r}`);if(n&&o.protocol==="http:"&&!J.has(o.hostname))throw new c(`Invalid ${r}`);return o.origin}i(g,"origin");function Z(t){let r;try{r=t.startsWith("[")?JSON.parse(t):t.split(/[\n,]/u).map(n=>n.trim()).filter(Boolean)}catch{throw new c("Invalid GENNE_MCP_REDIRECT_URIS")}if(!Array.isArray(r)||r.length===0||r.some(n=>typeof n!="string"||!n.trim()))throw new c("Invalid GENNE_MCP_REDIRECT_URIS");const e=r.map(n=>O(n.trim(),"GENNE_MCP_REDIRECT_URIS",{https:!0}));if(new Set(e).size!==e.length)throw new c("Duplicate GENNE_MCP_REDIRECT_URIS");return e}i(Z,"redirectUris");function q(t,r){if(!C(t))return[];const e=t.split(/[\n,]/u).map(n=>n.trim()).filter(Boolean);if(e.length===0)throw new c(`Invalid ${r}`);return e.map(n=>g(n,r))}i(q,"origins");function P(t,r,{min:e,max:n}){if(!/^(?:0|[1-9]\d*)$/u.test(t))throw new c(`Invalid ${r}`);const a=Number(t);if(!Number.isSafeInteger(a)||a<e||a>n)throw new c(`Invalid ${r}`);return a}i(P,"integer");function tt(t,r){if(t.length===32)return t;const e=t.toString("utf8").trim();if(/^[0-9a-f]{64}$/iu.test(e))return Buffer.from(e,"hex");try{const n=Buffer.from(e,"base64url");if(n.length===32&&n.toString("base64url")===e.replace(/=+$/u,""))return n}catch{}throw new c(`Invalid ${r}`)}i(tt,"keyFromBytes");async function rt(t,r){try{return await U(t)}catch(e){throw e?.code==="ENOENT"?new c(`Cannot read ${r}`):new c(`Insecure ${r}`)}}i(rt,"secureFile");async function M(t,r,{key:e=!1}={}){const n=E(t,r),a=await rt(n,r),o=Buffer.isBuffer(a)?a:Buffer.from(a,"utf8");if(e)return tt(o,r);const s=o.toString("utf8").trim();if(s.length<32||/[\u0000-\u001f\u007f]/u.test(s))throw new c(`Invalid ${r}`);return s}i(M,"secret");function et(t=process.env){const r=O(E(t,"GENNE_MCP_RESOURCE"),"GENNE_MCP_RESOURCE",{expectedPath:"/mcp"}),e=g(E(t,"GENNE_MCP_ISSUER"),"GENNE_MCP_ISSUER"),n=g(E(t,"GENNE_MCP_CORE_ORIGIN"),"GENNE_MCP_CORE_ORIGIN",{allowLocalHttp:!0}),a=g(E(t,"GENNE_MCP_ADMIN_ORIGIN"),"GENNE_MCP_ADMIN_ORIGIN"),o=E(t,"GENNE_MCP_CLIENT_ID");if(!/^[A-Za-z0-9._~-]{1,128}$/u.test(o))throw new c("Invalid GENNE_MCP_CLIENT_ID");const s=Z(E(t,"GENNE_MCP_REDIRECT_URIS")),u=E(t,"GENNE_MCP_ADAPTER_KEY_FILE"),f=E(t,"GENNE_MCP_STORE_KEY_FILE");if(!R(u)||!R(f))throw new c("Secret file paths must be absolute");const l=E(t,"GENNE_MCP_STORE_PATH");if(!R(l))throw new c("GENNE_MCP_STORE_PATH must be absolute");const h=P(E(t,"GENNE_MCP_PORT"),"GENNE_MCP_PORT",{min:0,max:65535}),m=E(t,"GENNE_MCP_BIND");if(!/^(?:[A-Za-z0-9.-]+|\[[0-9A-Fa-f:]+\])$/u.test(m))throw new c("Invalid GENNE_MCP_BIND");const T=p(t,"GENNE_MCP_MAX_BODY_BYTES")?P(p(t,"GENNE_MCP_MAX_BODY_BYTES"),"GENNE_MCP_MAX_BODY_BYTES",{min:1,max:j}):X,S=q(p(t,"GENNE_MCP_ALLOWED_ORIGINS"),"GENNE_MCP_ALLOWED_ORIGINS"),G=new URL(r).origin,A=s.map(D=>new URL(D).origin),b=new Set(S.length?S:[e,G,...A]);return Object.freeze({resource:r,issuer:e,coreOrigin:n,adminOrigin:a,clientId:o,redirectUris:Object.freeze(s),adapterKeyFile:u,storeKeyFile:f,storePath:l,port:h,bind:m,maxBody:T,allowedOrigins:b})}i(et,"loadRemoteConfig");function _(t,r=200){return new Response(JSON.stringify(t),{status:r,headers:{"content-type":"application/json","cache-control":"no-store"}})}i(_,"responseJson");function nt(t,r){if(typeof t!="string"||!t.startsWith("/")||t.startsWith("//")||t.includes("\\"))throw new d;let e;try{e=new URL(t,r)}catch{throw new d}if(e.origin!==new URL(r).origin||e.username||e.password||e.hash||e.pathname.includes("//"))throw new d;return e}i(nt,"parseTarget");function ot(t){return Q.has(t)||/^\/oauth\/grants\/[0-9a-f-]{36}\/revoke$/u.test(t)}i(ot,"knownRequestPath");function it(t){const r=new Headers;for(const[e,n]of Object.entries(t.headers))if(Array.isArray(n))for(const a of n)r.append(e,a);else n!==void 0&&r.set(e,n);return r}i(it,"headerValues");function at(t){const r=t.headers["content-length"];if(r===void 0)return;if(Array.isArray(r)||!/^(?:0|[1-9]\d*)$/u.test(r))throw new d;const e=Number(r);if(!Number.isSafeInteger(e))throw new d;return e}i(at,"contentLength");async function st(t,r){let e;try{e=at(t)}catch(n){throw t.resume(),n}if(e!==void 0&&e>r)throw t.resume(),new I;return["GET","HEAD"].includes(t.method)?Buffer.alloc(0):new Promise((n,a)=>{const o=[];let s=0,u=!1;const f=i(l=>{u||(u=!0,t.resume(),a(l))},"fail");t.on("data",l=>{if(!u){if(s+=l.length,s>r){f(new I);return}o.push(l)}}),t.once("end",()=>{u||(u=!0,n(Buffer.concat(o,s)))}),t.once("aborted",()=>f(new d)),t.once("error",()=>f(new d))})}i(st,"readBoundedBody");function N(t,r){return r&&(t.headers.set("access-control-allow-origin",r),t.headers.set("access-control-expose-headers","WWW-Authenticate, MCP-Session-Id"),t.headers.append("vary","Origin")),t}i(N,"addCors");async function w(t,r){if(r.statusCode=t.status,t.headers.forEach((e,n)=>r.setHeader(n,e)),!t.body){r.end();return}try{for await(const e of x.fromWeb(t.body))r.write(e)||await new Promise((n,a)=>{const o=i(()=>{r.off("drain",s),r.off("close",u),r.off("error",f)},"cleanup"),s=i(()=>{o(),n()},"onDrain"),u=i(()=>{o(),a(new Error("response_closed"))},"onClose"),f=i(l=>{o(),a(l)},"onError");r.once("drain",s),r.once("close",u),r.once("error",f)});r.end()}catch{r.destroy()}}i(w,"sendResponse");function ct(t){return t instanceof I?_({error:"request_too_large"},413):t instanceof d?_({error:"invalid_request"},400):_({error:"internal_error"},500)}i(ct,"safeError");function ut({config:t,handler:r}){return async(e,n)=>{const a=new AbortController,o=i(()=>a.abort(),"onAbort");e.on("aborted",o);try{await $(a.signal,()=>ft(e,n,t,r))}finally{e.off("aborted",o)}}}i(ut,"requestHandler");async function ft(t,r,e,n){const a=t.headers.origin;if(a!==void 0&&(!C(a)||!e.allowedOrigins.has(a))){await w(_({error:"forbidden"},403),r);return}try{const o=nt(t.url,e.resource);if(t.method==="OPTIONS"){if(!a){await w(_({error:"invalid_request"},400),r);return}const h=new Response(null,{status:204,headers:{"cache-control":"no-store","access-control-allow-methods":"GET,HEAD,POST,OPTIONS","access-control-allow-headers":"Authorization, Content-Type, Accept, MCP-Protocol-Version, MCP-Session-Id, Last-Event-ID"}});await w(N(h,a),r);return}const s=await st(t,e.maxBody);if(o.pathname==="/health"){await w(N(_({service:K,version:V}),a),r);return}if(!ot(o.pathname)){await w(N(_({error:"not_found"},404),a),r);return}const u=it(t),f={method:t.method,headers:u};!["GET","HEAD"].includes(t.method)&&s.length>0&&(f.body=s);const l=await n(new Request(o,f));await w(N(l,a),r)}catch(o){await w(N(ct(o),a),r)}}i(ft,"serveRequest");function lt(t,r,e){return new Promise((n,a)=>{const o=i(u=>{t.off("listening",s),a(u)},"onError"),s=i(()=>{t.off("error",o),n(t.address())},"onListening");t.once("error",o),t.once("listening",s),t.listen(r,e)})}i(lt,"listen");async function Et(t){await new Promise((r,e)=>{t.close(n=>{!n||n.code==="ERR_SERVER_NOT_RUNNING"?r():e(n)})})}i(Et,"closeServer");async function dt({env:t=process.env,fetchImpl:r=fetch}={}){const e=et(t),n=await M(t,"GENNE_MCP_ADAPTER_KEY_FILE"),a=await M(t,"GENNE_MCP_STORE_KEY_FILE",{key:!0}),o=await F(e.storePath,a);try{const s=k({origin:e.coreOrigin,adapterKey:n,consentOrigin:e.adminOrigin,fetchImpl:r}),u=H({store:o,core:s,resource:e.resource,issuer:e.issuer,clientId:e.clientId,redirectUris:e.redirectUris}),f=z({auth:u,coreOrigin:e.coreOrigin,resource:e.resource,adapterKey:n,adminOrigin:e.adminOrigin,fetchImpl:r}),l=W({auth:u,core:s,mcpHandler:f}),h=L(ut({config:e,handler:l}));let m=!1;return{config:e,server:h,listen:i(()=>lt(h,e.port,e.bind),"listen"),close:i(async()=>{if(!m){m=!0;try{await Et(h)}finally{o.close()}}},"close")}}catch(s){throw o.close(),s}}i(dt,"createRemoteServer");async function ht(t={}){const r=await dt(t);try{return await r.listen(),r}catch(e){throw await r.close(),e}}i(ht,"startRemoteServer");async function _t(){const t=await ht(),r=i(async()=>{try{await t.close()}catch{process.exitCode=1}},"stop");process.once("SIGINT",r),process.once("SIGTERM",r)}i(_t,"main");function wt(){if(!process.argv[1])return!1;try{return y(process.argv[1])===y(v(import.meta.url))}catch{return!1}}i(wt,"isMainModule"),wt()&&_t().catch(()=>{console.error("genne-mcp-remote: failed to start; check the runtime configuration"),process.exitCode=1});export{X as DEFAULT_MAX_REQUEST_BODY_BYTES,K as REMOTE_SERVER_NAME,V as REMOTE_SERVER_VERSION,dt as createRemoteServer,et as loadRemoteConfig,ht as startRemoteServer};
@@ -0,0 +1 @@
1
+ var o=Object.defineProperty;var e=(n,t)=>o(n,"name",{value:t,configurable:!0});import{AsyncLocalStorage as u}from"node:async_hooks";const r=new u;function s(n,t){return r.run({signal:n},t)}e(s,"runWithRequestSignal");function a(){return r.getStore()?.signal}e(a,"currentRequestSignal");export{a as currentRequestSignal,s as runWithRequestSignal};
package/src/session.js ADDED
@@ -0,0 +1 @@
1
+ var v=Object.defineProperty;var i=(e,t)=>v(e,"name",{value:t,configurable:!0});import{constants as m}from"node:fs";import{lstat as g,mkdir as S,open as T,readFile as P,rename as U,rm as y,stat as R,unlink as d}from"node:fs/promises";import{homedir as b}from"node:os";import{basename as j,join as u}from"node:path";import{randomBytes as C}from"node:crypto";import{apiOrigin as D,fail as a}from"./api.js";const H=i(e=>new Promise(t=>setTimeout(t,e)),"wait"),h="https://genne.ai";function N(e){return u(e.XDG_STATE_HOME||u(b(),".local","state"),"genne-cli")}i(N,"stateDir");function k(e){return e.GENNE_API_URL?{origin:e.GENNE_API_URL,source:"GENNE_API_URL"}:{origin:h,source:"default"}}i(k,"selectedEnvironment");function X(e){return k(e).origin}i(X,"selectedOrigin");async function M(e,t){if(t.length===1&&t[0]==="show"){const n=k(e),r=D(n.origin),o=l(r)??"custom",s=N(e),c={prod:!!await p(s,h)},f=o==="custom"?!!await p(s,r):c[o];return{data:{environment:o,origin:r,source:n.source,credential_source:e.GENNE_ACCESS_TOKEN?"GENNE_ACCESS_TOKEN":f?"saved_session":"none",sessions:c}}}a("USAGE","Use genne env show; a sele\xE7\xE3o de ambiente foi removida",2)}i(M,"environmentCommand");async function _(e){const t=N(e);await S(t,{recursive:!0,mode:448});const n=await g(t);return(!n.isDirectory()||n.isSymbolicLink()||n.mode&63)&&a("AUTH","Diret\xF3rio de sess\xE3o inseguro"),t}i(_,"ensureDirectory");function I(e){try{const[,t]=e.split("."),{exp:n}=JSON.parse(Buffer.from(t,"base64url").toString());return!Number.isInteger(n)||n*1e3<=Date.now()+6e4}catch{return!0}}i(I,"expiresSoon");function l(e){return e===h?"prod":null}i(l,"sessionName");function A(e,t){return u(e,l(t)?`session-${l(t)}.json`:"session.json")}i(A,"sessionPath");async function w(e,t,n=!1){let r;try{r=await g(e)}catch(o){if(o.code==="ENOENT")return null;throw o}(!r.isFile()||r.isSymbolicLink()||r.mode&63||process.getuid&&r.uid!==process.getuid())&&a("AUTH","Arquivo de sess\xE3o inseguro");try{const o=JSON.parse(await P(e,"utf8"));return n&&o.origin!==t?null:((o.origin!==t||typeof o.access_token!="string"||typeof o.refresh_token!="string"||!o.access_token||!o.refresh_token)&&a("AUTH","Fa\xE7a login nesta API com genne login"),{session:o,path:e})}catch(o){if(o.code==="AUTH")throw o;a("AUTH","Sess\xE3o local inv\xE1lida; fa\xE7a genne login novamente")}}i(w,"readSessionAt");async function p(e,t){const n=await w(A(e,t),t);if(n)return n;if(l(t)){const r=await w(u(e,"session.json"),t,!0);if(r)return r}return null}i(p,"readSession");async function x(e,t,n){const r=u(e,`.session-${process.pid}-${C(8).toString("hex")}`);try{const o=await T(r,m.O_WRONLY|m.O_CREAT|m.O_EXCL,384);try{await o.writeFile(JSON.stringify(n)),await o.sync()}finally{await o.close()}await U(r,u(e,t))}finally{await y(r,{force:!0})}}i(x,"writePrivateFile");async function O(e,t){if(await x(e,j(A(e,t.origin)),t),l(t.origin)){const n=await w(u(e,"session.json"),t.origin,!0);n&&await d(n.path)}}i(O,"writeSession");async function E(e,t){const n=u(e,"session.lock"),r=Date.now()+35e3;for(;;)try{await S(n,{mode:448});break}catch(o){if(o.code!=="EEXIST")throw o;let s;try{s=Date.now()-(await R(n)).mtimeMs}catch(c){if(c.code==="ENOENT")continue;throw c}s>3e4&&await y(n,{recursive:!0,force:!0}),Date.now()>r&&a("AUTH","Sess\xE3o ocupada; tente novamente"),await H(100)}try{return await t()}finally{await y(n,{recursive:!0,force:!0})}}i(E,"withLock");async function W(e,t,n){(typeof n?.token!="string"||!n.token||typeof n?.refresh_token!="string"||!n.refresh_token)&&a("RESPONSE","Resposta inv\xE1lida da API");const r=await _(e);await E(r,()=>O(r,{origin:t,access_token:n.token,refresh_token:n.refresh_token}))}i(W,"saveSession");async function q(e,t,n){const r=await _(e);await E(r,async()=>{const o=await p(r,t);if(!(n!==void 0&&o?.session.access_token!==n)&&(o&&await d(o.path),l(t))){const s=await w(u(r,"session.json"),t,!0);s&&s.path!==o?.path&&await d(s.path)}})}i(q,"clearSession");async function Y(e,t){const n=e.GENNE_ACCESS_TOKEN?.trim();if(n)return n;const r=await _(e);return E(r,async()=>{const o=await p(r,t);o||a("AUTH","Fa\xE7a genne login");const{session:s}=o;if(!I(s.access_token))return s.access_token;let c;try{c=await fetch(`${t}/api/v1/auth/refresh`,{method:"POST",redirect:"error",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({refresh_token:s.refresh_token}),signal:AbortSignal.timeout(15e3)})}catch{a("NETWORK","N\xE3o foi poss\xEDvel renovar a sess\xE3o")}c.ok||([400,401,403].includes(c.status)&&await d(o.path),a("AUTH","Sess\xE3o expirada; fa\xE7a genne login novamente"));let f;try{f=(await c.json()).data}catch{a("RESPONSE","Resposta inv\xE1lida da API")}return(typeof f?.token!="string"||!f.token||typeof f?.refresh_token!="string"||!f.refresh_token)&&a("RESPONSE","Resposta inv\xE1lida da API"),await O(r,{origin:t,access_token:f.token,refresh_token:f.refresh_token}),f.token})}i(Y,"accessToken");export{Y as accessToken,q as clearSession,M as environmentCommand,W as saveSession,X as selectedOrigin};