[{"data":1,"prerenderedAt":5234},["ShallowReactive",2],{"published-article-paths":3,"search-navigation":348,"\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp":421,"\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp-surround":1404},[4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,346],{"path":5},"\u002Fde\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":7},"\u002Fde\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":9},"\u002Fde\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":11},"\u002Fde\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":13},"\u002Fde\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":15},"\u002Fde\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":17},"\u002Fde\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":19},"\u002Fde\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":21},"\u002Fde\u002Farticle\u002Fsetup-antigravity-2",{"path":23},"\u002Fde\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":25},"\u002Fde\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":27},"\u002Fde\u002Farticle\u002Fsync-obsidian-across-devices",{"path":29},"\u002Fde\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":31},"\u002Fde\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":33},"\u002Fde\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":35},"\u002Fde\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":37},"\u002Fen\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":39},"\u002Fen\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":41},"\u002Fen\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":43},"\u002Fen\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":45},"\u002Fen\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":47},"\u002Fen\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":49},"\u002Fen\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":51},"\u002Fen\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":53},"\u002Fen\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":55},"\u002Fen\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":57},"\u002Fen\u002Farticle\u002Fsetup-antigravity-2",{"path":59},"\u002Fen\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":61},"\u002Fen\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":63},"\u002Fen\u002Farticle\u002Fsync-obsidian-across-devices",{"path":65},"\u002Fen\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":67},"\u002Fen\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":69},"\u002Fen\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":71},"\u002Fen\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":73},"\u002Fes\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":75},"\u002Fes\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":77},"\u002Fes\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":79},"\u002Fes\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":81},"\u002Fes\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":83},"\u002Fes\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":85},"\u002Fes\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":87},"\u002Fes\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":89},"\u002Fes\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":91},"\u002Fes\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":93},"\u002Fes\u002Farticle\u002Fsetup-antigravity-2",{"path":95},"\u002Fes\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":97},"\u002Fes\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":99},"\u002Fes\u002Farticle\u002Fsync-obsidian-across-devices",{"path":101},"\u002Fes\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":103},"\u002Fes\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":105},"\u002Fes\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":107},"\u002Fes\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":109},"\u002Ffr\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":111},"\u002Ffr\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":113},"\u002Ffr\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":115},"\u002Ffr\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":117},"\u002Ffr\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":119},"\u002Ffr\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":121},"\u002Ffr\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":123},"\u002Ffr\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":125},"\u002Ffr\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":127},"\u002Ffr\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":129},"\u002Ffr\u002Farticle\u002Fsetup-antigravity-2",{"path":131},"\u002Ffr\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":133},"\u002Ffr\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":135},"\u002Ffr\u002Farticle\u002Fsync-obsidian-across-devices",{"path":137},"\u002Ffr\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":139},"\u002Ffr\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":141},"\u002Ffr\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":143},"\u002Ffr\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":145},"\u002Fid\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":147},"\u002Fid\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":149},"\u002Fid\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":151},"\u002Fid\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":153},"\u002Fid\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":155},"\u002Fid\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":157},"\u002Fid\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":159},"\u002Fid\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":161},"\u002Fid\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":163},"\u002Fid\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":165},"\u002Fid\u002Farticle\u002Fsetup-antigravity-2",{"path":167},"\u002Fid\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":169},"\u002Fid\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":171},"\u002Fid\u002Farticle\u002Fsync-obsidian-across-devices",{"path":173},"\u002Fid\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":175},"\u002Fid\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":177},"\u002Fid\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":179},"\u002Fid\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":181},"\u002Fja\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":183},"\u002Fja\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":185},"\u002Fja\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":187},"\u002Fja\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":189},"\u002Fja\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":191},"\u002Fja\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":193},"\u002Fja\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":195},"\u002Fja\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":197},"\u002Fja\u002Farticle\u002Fsetup-antigravity-2",{"path":199},"\u002Fja\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":201},"\u002Fja\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":203},"\u002Fja\u002Farticle\u002Fsync-obsidian-across-devices",{"path":205},"\u002Fja\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":207},"\u002Fja\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":209},"\u002Fja\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":211},"\u002Fja\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":213},"\u002Fpt\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":215},"\u002Fpt\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":217},"\u002Fpt\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":219},"\u002Fpt\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":221},"\u002Fpt\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":223},"\u002Fpt\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":225},"\u002Fpt\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":227},"\u002Fpt\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":229},"\u002Fpt\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":231},"\u002Fpt\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":233},"\u002Fpt\u002Farticle\u002Fsetup-antigravity-2",{"path":235},"\u002Fpt\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":237},"\u002Fpt\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":239},"\u002Fpt\u002Farticle\u002Fsync-obsidian-across-devices",{"path":241},"\u002Fpt\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":243},"\u002Fpt\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":245},"\u002Fpt\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":247},"\u002Fpt\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":249},"\u002Ftw\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":251},"\u002Ftw\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":253},"\u002Ftw\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":255},"\u002Ftw\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":257},"\u002Ftw\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":259},"\u002Ftw\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":261},"\u002Ftw\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":263},"\u002Ftw\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":265},"\u002Ftw\u002Farticle\u002Fsetup-antigravity-2",{"path":267},"\u002Ftw\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":269},"\u002Ftw\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":271},"\u002Ftw\u002Farticle\u002Fsync-obsidian-across-devices",{"path":273},"\u002Ftw\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":275},"\u002Ftw\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":277},"\u002Ftw\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":279},"\u002Ftw\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":281},"\u002Fvi\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":283},"\u002Fvi\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":285},"\u002Fvi\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":287},"\u002Fvi\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":289},"\u002Fvi\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":291},"\u002Fvi\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":293},"\u002Fvi\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":295},"\u002Fvi\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":297},"\u002Fvi\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":299},"\u002Fvi\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":301},"\u002Fvi\u002Farticle\u002Fsetup-antigravity-2",{"path":303},"\u002Fvi\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":305},"\u002Fvi\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":307},"\u002Fvi\u002Farticle\u002Fsync-obsidian-across-devices",{"path":309},"\u002Fvi\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":311},"\u002Fvi\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":313},"\u002Fvi\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":315},"\u002Fvi\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":317},"\u002Fzh\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":319},"\u002Fzh\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":321},"\u002Fzh\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":323},"\u002Fzh\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":325},"\u002Fzh\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":327},"\u002Fzh\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":329},"\u002Fzh\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":331},"\u002Fzh\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":333},"\u002Fzh\u002Farticle\u002Fsetup-antigravity-2",{"path":335},"\u002Fzh\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":337},"\u002Fzh\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":339},"\u002Fzh\u002Farticle\u002Fsync-obsidian-across-devices",{"path":341},"\u002Fzh\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":343},"\u002Fzh\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":345},"\u002Fzh\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":347},"\u002Fzh\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",[349,353,357,361,365,369,373,377,381,385,389,393,397,401,405,409,413,417],{"title":350,"path":351,"stem":352},"AI Agent Skills: What They Are & How to Create Them","\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them","en\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"title":354,"path":355,"stem":356},"Bringing Buzz to DeepSeek Harness: Taught to Speak Nostr","\u002Farticle\u002Fbringing-buzz-to-deepseek-harness","en\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"title":358,"path":359,"stem":360},"Solving AI Agent Skills Fragmentation with npx skills","\u002Farticle\u002Fcentralised-the-skills-for-agents","en\u002Farticle\u002Fcentralised-the-skills-for-agents",{"title":362,"path":363,"stem":364},"How to Expose Hermes Agent Privately with Cloudflare WARP","\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp","en\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"title":366,"path":367,"stem":368},"How AI Agent Skills Replace Nuxt App Scaffolding Scripts","\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts","en\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"title":370,"path":371,"stem":372},"Stop Exposing Your Vault: Secure NodeWarden with Cloudflare","\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare","en\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"title":374,"path":375,"stem":376},"How to Deploy Hermes Agent on a Linux VPS","\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server","en\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"title":378,"path":379,"stem":380},"Self-Host Your Travel Itineraries with TREK and Docker","\u002Farticle\u002Fself-hosted-travel-planner-trek","en\u002Farticle\u002Fself-hosted-travel-planner-trek",{"title":382,"path":383,"stem":384},"Self-Host Block's Buzz: Shared AI Agent Workspace","\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues","en\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"title":386,"path":387,"stem":388},"How to Self-Host a BitWarden Compatible Server Nodewarden","\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare","en\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"title":390,"path":391,"stem":392},"Google Antigravity 2 Hands-On: Setup & First Impressions","\u002Farticle\u002Fsetup-antigravity-2","en\u002Farticle\u002Fsetup-antigravity-2",{"title":394,"path":395,"stem":396},"NetSuite AI Connector Guide: MCP Setup & Use Cases","\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude","en\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"title":398,"path":399,"stem":400},"Switch Between Multiple Cloudflare WARP Orgs on Mac","\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac","en\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"title":402,"path":403,"stem":404},"How to Sync Obsidian Vaults Across Devices Securely","\u002Farticle\u002Fsync-obsidian-across-devices","en\u002Farticle\u002Fsync-obsidian-across-devices",{"title":406,"path":407,"stem":408},"Testing Claude Fable 5: A Financial Analysis Review","\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis","en\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"title":410,"path":411,"stem":412},"Guide to Browser and Scheduler in Antigravity 2","\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2","en\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"title":414,"path":415,"stem":416},"Build a Persistent AI Memory System on Cloudflare","\u002Farticle\u002Fuse-cloudflare-as-ai-memory","en\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"title":418,"path":419,"stem":420},"Antigravity 2 in Action: AI Agents, Skills, and MCP","\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2","en\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"id":422,"title":362,"author":423,"body":424,"category":1352,"date":1355,"description":1356,"extension":1357,"image":1358,"imageAlt":1359,"isPublished":644,"meta":1360,"minRead":1020,"navigation":644,"path":43,"seo":1397,"stem":364,"tags":1399,"updatedAt":1396,"__hash__":1403},"article\u002Fen\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp.md","",{"type":425,"value":426,"toc":1334},"minimark",[427,444,454,459,462,476,481,490,494,498,551,555,708,712,745,749,752,819,822,858,861,888,892,902,907,946,1039,1043,1048,1065,1074,1154,1159,1205,1209,1254,1268,1272,1316,1320,1330],[428,429,430,431,435,436,439,440,443],"p",{},"A common challenge arises when you want to access your ",[432,433,434],"strong",{},"Hermes Agent"," from other devices such as laptops, tablets, or phones without exposing it to the public internet. Utilizing ",[432,437,438],{},"Cloudflare WARP"," with ",[432,441,442],{},"Cloudflare Zero Trust"," allows you to expose the Hermes Agent globally without opening a single inbound port on your firewall.",[428,445,446,447,450,451,453],{},"If you followed our previous guide, '",[448,449,374],"a",{"href":375},"', a Hermes Agent is already up and running 24\u002F7. Instead of dealing with the overhead of traditional VPNs, we will use the ",[432,452,438],{}," client to expose the Hermes Agent to a private network over the internet.",[455,456,458],"h2",{"id":457},"understanding-the-architecture","Understanding the Architecture",[428,460,461],{},"The components at play:",[463,464,465,471],"ol",{},[466,467,468,470],"li",{},[432,469,442],{},": The dashboard at Cloudflare where you define routing rules and access policies.",[466,472,473,475],{},[432,474,438],{},": The client application installed on your devices (VPS, laptops, phones). It intercepts traffic destined for your private network and routes it securely.",[477,478,480],"h3",{"id":479},"prerequisites","Prerequisites",[482,483,484,487],"ul",{},[466,485,486],{},"A running Hermes Agent on your VPS.",[466,488,489],{},"A free Cloudflare account.",[455,491,493],{"id":492},"step-by-step-guide","Step-by-Step Guide",[477,495,497],{"id":496},"step-1-set-up-cloudflare-zero-trust","Step 1: Set Up Cloudflare Zero Trust",[463,499,500,510,518,530,537,544],{},[466,501,502,503,509],{},"Log in to your ",[448,504,508],{"href":505,"rel":506},"https:\u002F\u002Fdash.cloudflare.com\u002F",[507],"nofollow","Cloudflare Dashboard",".",[466,511,512,513],{},"Click on 'Zero Trust' from the left menu.\n",[514,515],"img",{"alt":516,"src":517},"Cloudflare dashboard left sidebar navigation menu with Zero Trust option","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-zero-trust-left-menu.webp",[466,519,520,521,525,526],{},"If this is your first time, you will be prompted to choose a plan (the Free tier is perfectly fine for this setup) and name your team (e.g., ",[522,523,524],"code",{},"ai-team",").\n",[514,527],{"alt":528,"src":529},"Setting up first-time Cloudflare Zero Trust account and naming the team","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-zero-trust-team-setup.webp",[466,531,532,533],{},"Click on 'Access' then 'Policies' to create an access policy defining who has access to the network.\n",[514,534],{"alt":535,"src":536},"Cloudflare Zero Trust Access Policies page showing newly configured access rules","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-access-policies-page.webp",[466,538,539,540],{},"Click on 'Create new policy'.\n",[514,541],{"alt":542,"src":543},"Cloudflare Access policies page showing no policies added and a button to create a new policy.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20secure%20NodeWarden%20at%20Cloudflare\u002Fcloudflare-access-no-policies-create-button.png",[466,545,546,547],{},"Select 'Emails' and enter your email under 'Policy rules'.\n",[514,548],{"alt":549,"src":550},"Cloudflare Access policy rule configuration screen with an email address specified as the inclusion criteria.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20secure%20NodeWarden%20at%20Cloudflare\u002Fcloudflare-access-policy-rule-email.png",[477,552,554],{"id":553},"step-2-set-up-cloudflare-warp-client-on-vps","Step 2: Set Up Cloudflare WARP Client on VPS",[463,556,557,568,574,581,584,599,602,701],{},[466,558,559,560,563,564,567],{},"Run ",[522,561,562],{},"sudo apt update"," and ",[522,565,566],{},"sudo apt install cloudflare-warp"," in the terminal on your VPS.",[466,569,559,570,573],{},[522,571,572],{},"warp-cli registration new \u003CTEAM-NAME>"," in the terminal on your VPS, which will print out a URL.",[466,575,576,577,580],{},"Copy the printed URL, which will look like ",[522,578,579],{},"https:\u002F\u002F\u003Cteam>.cloudflareaccess.com\u002Fwarp",", and paste it in your browser for authentication.",[466,582,583],{},"Since email authentication is used in the policy rule setup above, enter your email to authenticate.",[466,585,586,587,590,591,594,595,598],{},"On the '",[432,588,589],{},"Success","' page in the browser, right-click and select '",[432,592,593],{},"Inspect","' on the blue '",[432,596,597],{},"Open Cloudflare WARP","' button.",[466,600,601],{},"Copy the long token that is shown in the button's link.",[466,603,559,604,607,608,611,612],{},[522,605,606],{},"warp-cli --accept-tos registration token \"https:\u002F\u002F\u003Cteam>.cloudflareaccess.com\u002Fauth?token=\u003Ccopied_token>\""," in the terminal on your VPS to connect it to Cloudflare Zero Trust.",[609,610],"br",{},"If the 'Error: Failed to communicate with the WARP API' is encounter on Ubuntu 26, run the following commands:",[613,614,618],"pre",{"className":615,"code":616,"language":617,"meta":423,"style":423},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sudo systemctl restart warp-svc.service\n\n# Check status\nsudo systemctl status warp-svc.service\n\n# Run the warp-cli registration token again\nwarp-cli --accept-tos registration token   \"https:\u002F\u002F\u003Cteam>.cloudflareaccess.com\u002Fauth?token=\u003Ccopied_token>\"\n","bash",[522,619,620,639,646,653,665,670,676],{"__ignoreMap":423},[621,622,625,629,633,636],"span",{"class":623,"line":624},"line",1,[621,626,628],{"class":627},"sBMFI","sudo",[621,630,632],{"class":631},"sfazB"," systemctl",[621,634,635],{"class":631}," restart",[621,637,638],{"class":631}," warp-svc.service\n",[621,640,642],{"class":623,"line":641},2,[621,643,645],{"emptyLinePlaceholder":644},true,"\n",[621,647,649],{"class":623,"line":648},3,[621,650,652],{"class":651},"sHwdD","# Check status\n",[621,654,656,658,660,663],{"class":623,"line":655},4,[621,657,628],{"class":627},[621,659,632],{"class":631},[621,661,662],{"class":631}," status",[621,664,638],{"class":631},[621,666,668],{"class":623,"line":667},5,[621,669,645],{"emptyLinePlaceholder":644},[621,671,673],{"class":623,"line":672},6,[621,674,675],{"class":651},"# Run the warp-cli registration token again\n",[621,677,679,682,685,688,691,695,698],{"class":623,"line":678},7,[621,680,681],{"class":627},"warp-cli",[621,683,684],{"class":631}," --accept-tos",[621,686,687],{"class":631}," registration",[621,689,690],{"class":631}," token",[621,692,694],{"class":693},"sMK4o","   \"",[621,696,697],{"class":631},"https:\u002F\u002F\u003Cteam>.cloudflareaccess.com\u002Fauth?token=\u003Ccopied_token>",[621,699,700],{"class":693},"\"\n",[466,702,703,704],{},"Head back to the Cloudflare Zero Trust dashboard, and click on 'Devices'. Your VPS device should now be displayed.\n",[514,705],{"alt":706,"src":707},"Zero Trust Devices dashboard confirming the Linux VPS is connected","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-zero-trust-devices-vps-connected.webp",[477,709,711],{"id":710},"step-3-set-up-traffic-routing","Step 3: Set Up Traffic Routing",[463,713,714,721,728,735],{},[466,715,716,717],{},"Click the profile for your VPS on the Devices dashboard.\n",[514,718],{"alt":719,"src":720},"Accessing details and split tunnel settings for the registered VPS device","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-zero-trust-device-profile.webp",[466,722,723,724],{},"Scroll down to the 'Split Tunnels' section.\n",[514,725],{"alt":726,"src":727},"Split Tunnels section under VPS profile settings","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-zero-trust-split-tunnels-section.webp",[466,729,730,731],{},"Click the 'Manage' button and configure the settings as shown below. Replace the IP address if necessary.\n",[514,732],{"alt":733,"src":734},"Managing Split Tunnels IP and hostname exclusions in Cloudflare settings","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-zero-trust-manage-split-tunnels.webp",[466,736,737,738,563,741,744],{},"Exposing the ",[522,739,740],{},"address",[522,742,743],{},"host"," will route traffic to your services over the same private network.",[477,746,748],{"id":747},"step-4-configure-firewall-on-the-vps","Step 4: Configure Firewall on the VPS",[428,750,751],{},"Enable the firewall to allow the '100.96.0.0\u002F12' subnet only, blocking all other public incoming access.",[613,753,755],{"className":615,"code":754,"language":617,"meta":423,"style":423},"sudo ufw enable \nsudo ufw default allow outgoing \nsudo ufw default deny incoming\nsudo ufw allow in from 100.96.0.0\u002F12\n",[522,756,757,771,788,802],{"__ignoreMap":423},[621,758,759,761,764,767],{"class":623,"line":624},[621,760,628],{"class":627},[621,762,763],{"class":631}," ufw",[621,765,766],{"class":631}," enable",[621,768,770],{"class":769},"sTEyZ"," \n",[621,772,773,775,777,780,783,786],{"class":623,"line":641},[621,774,628],{"class":627},[621,776,763],{"class":631},[621,778,779],{"class":631}," default",[621,781,782],{"class":631}," allow",[621,784,785],{"class":631}," outgoing",[621,787,770],{"class":769},[621,789,790,792,794,796,799],{"class":623,"line":648},[621,791,628],{"class":627},[621,793,763],{"class":631},[621,795,779],{"class":631},[621,797,798],{"class":631}," deny",[621,800,801],{"class":631}," incoming\n",[621,803,804,806,808,810,813,816],{"class":623,"line":655},[621,805,628],{"class":627},[621,807,763],{"class":631},[621,809,782],{"class":631},[621,811,812],{"class":631}," in",[621,814,815],{"class":631}," from",[621,817,818],{"class":631}," 100.96.0.0\u002F12\n",[428,820,821],{},"Allow loopback traffic to avoid breaking local services:",[613,823,825],{"className":615,"code":824,"language":617,"meta":423,"style":423},"sudo ufw allow in on lo\nsudo ufw allow out on lo\n",[522,826,827,843],{"__ignoreMap":423},[621,828,829,831,833,835,837,840],{"class":623,"line":624},[621,830,628],{"class":627},[621,832,763],{"class":631},[621,834,782],{"class":631},[621,836,812],{"class":631},[621,838,839],{"class":631}," on",[621,841,842],{"class":631}," lo\n",[621,844,845,847,849,851,854,856],{"class":623,"line":641},[621,846,628],{"class":627},[621,848,763],{"class":631},[621,850,782],{"class":631},[621,852,853],{"class":631}," out",[621,855,839],{"class":631},[621,857,842],{"class":631},[428,859,860],{},"Reload the firewall and verify status:",[613,862,864],{"className":615,"code":863,"language":617,"meta":423,"style":423},"sudo ufw reload \nsudo ufw status verbose\n",[522,865,866,877],{"__ignoreMap":423},[621,867,868,870,872,875],{"class":623,"line":624},[621,869,628],{"class":627},[621,871,763],{"class":631},[621,873,874],{"class":631}," reload",[621,876,770],{"class":769},[621,878,879,881,883,885],{"class":623,"line":641},[621,880,628],{"class":627},[621,882,763],{"class":631},[621,884,662],{"class":631},[621,886,887],{"class":631}," verbose\n",[477,889,891],{"id":890},"step-5-expose-hermes-agent-to-the-private-network","Step 5: Expose Hermes Agent to the Private Network",[428,893,894,895,898,899,509],{},"We will expose the ",[432,896,897],{},"Hermes Agent Web Dashboard"," to our private network and use the default authentication provider, ",[432,900,901],{},"Nous Research",[903,904,906],"h4",{"id":905},"set-up-the-auth-provider","Set Up the Auth Provider",[463,908,909,918,925,932,939],{},[466,910,911,912,917],{},"Head to ",[448,913,916],{"href":914,"rel":915},"https:\u002F\u002Fportal.nousresearch.com",[507],"portal.nousresearch.com"," to register an account.",[466,919,920,921],{},"Select 'Local Dashboards'.\n",[514,922],{"alt":923,"src":924},"Selecting Local Dashboards option in the Nous Research portal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fnous-portal-local-dashboards-selection.webp",[466,926,927,928],{},"Click 'Register Dashboard'.\n",[514,929],{"alt":930,"src":931},"Clicking Register Dashboard button to create a new dashboard entry","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fnous-portal-register-dashboard.webp",[466,933,934,935],{},"Enter the private network IP address of your VPS as the 'Dashboard redirect URI' and click 'Save'.\n",[514,936],{"alt":937,"src":938},"Registering the private network VPS IP address as redirect URI in Nous Research portal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fnous-portal-register-redirect-uri.webp",[466,940,941,942,945],{},"Copy the 'OAuth client ID' and paste it in your ",[522,943,944],{},"config.yaml"," file:",[613,947,951],{"className":948,"code":949,"language":950,"meta":423,"style":423},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","dashboard:\n  theme: default\n  show_token_analytics: false\n  oauth:\n    client_id: agent:cmq02x7ha0002jk0ba3kfnb\n    portal_url: https:\u002F\u002Fportal.nousresearch.com\n  basic_auth:\n    username: ''\n    password_hash: ''\n","yaml",[522,952,953,962,973,984,991,1001,1011,1018,1029],{"__ignoreMap":423},[621,954,955,959],{"class":623,"line":624},[621,956,958],{"class":957},"swJcz","dashboard",[621,960,961],{"class":693},":\n",[621,963,964,967,970],{"class":623,"line":641},[621,965,966],{"class":957},"  theme",[621,968,969],{"class":693},":",[621,971,972],{"class":631}," default\n",[621,974,975,978,980],{"class":623,"line":648},[621,976,977],{"class":957},"  show_token_analytics",[621,979,969],{"class":693},[621,981,983],{"class":982},"sfNiH"," false\n",[621,985,986,989],{"class":623,"line":655},[621,987,988],{"class":957},"  oauth",[621,990,961],{"class":693},[621,992,993,996,998],{"class":623,"line":667},[621,994,995],{"class":957},"    client_id",[621,997,969],{"class":693},[621,999,1000],{"class":631}," agent:cmq02x7ha0002jk0ba3kfnb\n",[621,1002,1003,1006,1008],{"class":623,"line":672},[621,1004,1005],{"class":957},"    portal_url",[621,1007,969],{"class":693},[621,1009,1010],{"class":631}," https:\u002F\u002Fportal.nousresearch.com\n",[621,1012,1013,1016],{"class":623,"line":678},[621,1014,1015],{"class":957},"  basic_auth",[621,1017,961],{"class":693},[621,1019,1021,1024,1026],{"class":623,"line":1020},8,[621,1022,1023],{"class":957},"    username",[621,1025,969],{"class":693},[621,1027,1028],{"class":693}," ''\n",[621,1030,1032,1035,1037],{"class":623,"line":1031},9,[621,1033,1034],{"class":957},"    password_hash",[621,1036,969],{"class":693},[621,1038,1028],{"class":693},[903,1040,1042],{"id":1041},"set-up-systemd-to-autostart-the-hermes-dashboard","Set Up Systemd to Autostart the Hermes Dashboard",[463,1044,1045],{},[466,1046,1047],{},"Create a service file:",[613,1049,1053],{"className":1050,"code":1051,"language":1052,"meta":423,"style":423},"language-shell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sudo nano \u002Fetc\u002Fsystemd\u002Fsystem\u002Fhermes-dashboard.service\n","shell",[522,1054,1055],{"__ignoreMap":423},[621,1056,1057,1059,1062],{"class":623,"line":624},[621,1058,628],{"class":627},[621,1060,1061],{"class":631}," nano",[621,1063,1064],{"class":631}," \u002Fetc\u002Fsystemd\u002Fsystem\u002Fhermes-dashboard.service\n",[463,1066,1067],{"start":641},[466,1068,1069,1070,1073],{},"Paste the following configuration, ensuring ",[522,1071,1072],{},"--host 0.0.0.0"," is part of the command:",[613,1075,1079],{"className":1076,"code":1077,"language":1078,"meta":423,"style":423},"language-ini shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[Unit]\nDescription=Hermes Dashboard\nAfter=network.target\n\n[Service]\nUser=hermes\nWorkingDirectory=\u002Fhome\u002Fhermes\nExecStart=\u002Fhome\u002Fhermes\u002F.local\u002Fbin\u002Fhermes dashboard --host 0.0.0.0\nRestart=always\nRestartSec=10\nEnvironment=PATH=\u002Fhome\u002Fhermes\u002F.local\u002Fbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin\n\n[Install]\nWantedBy=multi-user.target\n","ini",[522,1080,1081,1086,1091,1096,1100,1105,1110,1115,1120,1125,1131,1137,1142,1148],{"__ignoreMap":423},[621,1082,1083],{"class":623,"line":624},[621,1084,1085],{},"[Unit]\n",[621,1087,1088],{"class":623,"line":641},[621,1089,1090],{},"Description=Hermes Dashboard\n",[621,1092,1093],{"class":623,"line":648},[621,1094,1095],{},"After=network.target\n",[621,1097,1098],{"class":623,"line":655},[621,1099,645],{"emptyLinePlaceholder":644},[621,1101,1102],{"class":623,"line":667},[621,1103,1104],{},"[Service]\n",[621,1106,1107],{"class":623,"line":672},[621,1108,1109],{},"User=hermes\n",[621,1111,1112],{"class":623,"line":678},[621,1113,1114],{},"WorkingDirectory=\u002Fhome\u002Fhermes\n",[621,1116,1117],{"class":623,"line":1020},[621,1118,1119],{},"ExecStart=\u002Fhome\u002Fhermes\u002F.local\u002Fbin\u002Fhermes dashboard --host 0.0.0.0\n",[621,1121,1122],{"class":623,"line":1031},[621,1123,1124],{},"Restart=always\n",[621,1126,1128],{"class":623,"line":1127},10,[621,1129,1130],{},"RestartSec=10\n",[621,1132,1134],{"class":623,"line":1133},11,[621,1135,1136],{},"Environment=PATH=\u002Fhome\u002Fhermes\u002F.local\u002Fbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin\n",[621,1138,1140],{"class":623,"line":1139},12,[621,1141,645],{"emptyLinePlaceholder":644},[621,1143,1145],{"class":623,"line":1144},13,[621,1146,1147],{},"[Install]\n",[621,1149,1151],{"class":623,"line":1150},14,[621,1152,1153],{},"WantedBy=multi-user.target\n",[463,1155,1156],{"start":648},[466,1157,1158],{},"Enable and start the service:",[613,1160,1162],{"className":1050,"code":1161,"language":1052,"meta":423,"style":423},"sudo systemctl daemon-reload\nsudo systemctl enable hermes-dashboard\nsudo systemctl start hermes-dashboard\nsudo systemctl status hermes-dashboard\n",[522,1163,1164,1173,1184,1195],{"__ignoreMap":423},[621,1165,1166,1168,1170],{"class":623,"line":624},[621,1167,628],{"class":627},[621,1169,632],{"class":631},[621,1171,1172],{"class":631}," daemon-reload\n",[621,1174,1175,1177,1179,1181],{"class":623,"line":641},[621,1176,628],{"class":627},[621,1178,632],{"class":631},[621,1180,766],{"class":631},[621,1182,1183],{"class":631}," hermes-dashboard\n",[621,1185,1186,1188,1190,1193],{"class":623,"line":648},[621,1187,628],{"class":627},[621,1189,632],{"class":631},[621,1191,1192],{"class":631}," start",[621,1194,1183],{"class":631},[621,1196,1197,1199,1201,1203],{"class":623,"line":655},[621,1198,628],{"class":627},[621,1200,632],{"class":631},[621,1202,662],{"class":631},[621,1204,1183],{"class":631},[477,1206,1208],{"id":1207},"step-6-install-cloudflare-warp-client-on-desktop","Step 6: Install Cloudflare WARP Client on Desktop",[463,1210,1211,1219,1222,1229,1236,1243],{},[466,1212,1213,1214,509],{},"Download the Cloudflare WARP client from ",[448,1215,1218],{"href":1216,"rel":1217},"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fwarp-client\u002Fget-started\u002F",[507],"Cloudflare's portal",[466,1220,1221],{},"Open and launch the Cloudflare WARP client after installation.",[466,1223,1224,1225],{},"Log in when prompted.\n",[514,1226],{"alt":1227,"src":1228},"Cloudflare WARP client login prompt on desktop machine","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-warp-desktop-login-prompt.webp",[466,1230,1231,1232],{},"A 'Success' page will be displayed after a successful login.\n",[514,1233],{"alt":1234,"src":1235},"Authentication success webpage after logging in to Cloudflare Zero Trust on desktop","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-warp-desktop-login-success.webp",[466,1237,1238,1239],{},"The WARP client should now show it is connected to your Zero Trust team.\n",[514,1240],{"alt":1241,"src":1242},"Desktop Cloudflare WARP client confirming active connection to Zero Trust private network","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-warp-desktop-client-connected.webp",[466,1244,1245,1246,1249,1250],{},"Navigate to your web browser and enter your private IP (e.g., ",[522,1247,1248],{},"100.96.0.3","). The Hermes Web Dashboard should load successfully.\n",[514,1251],{"alt":1252,"src":1253},"Accessing the private Hermes Agent Web Dashboard in browser on desktop","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fhermes-agent-dashboard-desktop-view.webp",[1255,1256,1257],"blockquote",{},[428,1258,1259,1262,1263,1267],{},[432,1260,1261],{},"Pro Tip for macOS Users:"," If you are using the WARP client to access multiple Cloudflare accounts, check out our quick guide on ",[432,1264,1265],{},[448,1266,398],{"href":399}," to make switching between accounts seamless.",[477,1269,1271],{"id":1270},"step-7-install-cloudflare-warp-client-on-ios-devices","Step 7: Install Cloudflare WARP Client on iOS Devices",[463,1273,1274,1281,1289,1297,1305],{},[466,1275,1276,1277,1280],{},"Install ",[432,1278,1279],{},"Cloudflare One"," from the App Store.",[466,1282,1283,1284],{},"Open the Cloudflare One app and enter your team name when prompted.\n",[514,1285],{"alt":1286,"src":1287,"width":1288},"Entering Cloudflare Zero Trust team name in Cloudflare One app on iOS","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-one-ios-team-name-prompt.webp",239,[466,1290,1291,1292],{},"Log in using the same email address that was configured in the policy rule above.\n",[514,1293],{"alt":1294,"src":1295,"width":1296},"Email authentication prompt for Cloudflare Zero Trust on iOS","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-one-ios-email-login.webp",229,[466,1298,1299,1300],{},"Once it is connected, it should look like the following:\n",[514,1301],{"alt":1302,"src":1303,"width":1304},"Cloudflare One app showing connected status on iOS mobile device","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fcloudflare-one-ios-client-connected.webp",322,[466,1306,1307,1308,1310,1311],{},"Navigate to your web browser and enter the private IP ",[522,1309,1248],{}," to access the Hermes Web Dashboard on your mobile device.\n",[514,1312],{"alt":1313,"src":1314,"width":1315},"Accessing Hermes Agent Web Dashboard interface on mobile phone browser","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002Fhermes-agent-dashboard-mobile-view.webp",345,[455,1317,1319],{"id":1318},"conclusion","Conclusion",[428,1321,1322,1323,1325,1326,1329],{},"With ",[432,1324,442],{}," handling identity policies and the ",[432,1327,1328],{},"WARP"," client routing traffic over an encrypted tunnel, your Hermes Agent is securely reachable from your devices globally. This setup lays a secure, robust foundation for building and accessing a fully remote, private AI infrastructure.",[1331,1332,1333],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":423,"searchDepth":641,"depth":648,"links":1335},[1336,1339,1351],{"id":457,"depth":641,"text":458,"children":1337},[1338],{"id":479,"depth":648,"text":480},{"id":492,"depth":641,"text":493,"children":1340},[1341,1342,1343,1344,1345,1349,1350],{"id":496,"depth":648,"text":497},{"id":553,"depth":648,"text":554},{"id":710,"depth":648,"text":711},{"id":747,"depth":648,"text":748},{"id":890,"depth":648,"text":891,"children":1346},[1347,1348],{"id":905,"depth":655,"text":906},{"id":1041,"depth":655,"text":1042},{"id":1207,"depth":648,"text":1208},{"id":1270,"depth":648,"text":1271},{"id":1318,"depth":641,"text":1319},[1353,1354],"ai-agents","security","2026-07-09","Learn how to securely expose and access your Hermes Agent globally using Cloudflare WARP and Zero Trust without opening inbound firewall ports.","md","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002FEN-Exposing-Hermes-Agent-to-Private-Network-Using-Cloudflare-WARP.webp","Securely exposing Hermes Agent to a private network using Cloudflare Zero Trust and WARP tunnel",{"schemaOrg":1361,"robots":1394,"sitemap":1395},[1362],{"@type":1363,"headline":362,"description":1356,"name":362,"image":1358,"step":1364},"HowTo",[1365,1370,1374,1378,1382,1386,1390],{"@type":1366,"name":1367,"text":1368,"url":1369,"image":517},"HowToStep","Set Up Cloudflare Zero Trust","Log in to your Cloudflare Dashboard. Click on 'Zero Trust' from the left menu. If this is your first time, you will be prompted to choose a plan (the Free tier is perfectly fine for this setup) and name your team (e.g., ai-team). Click on 'Access' th","#step-1",{"@type":1366,"name":1371,"text":1372,"url":1373,"image":707},"Set Up Cloudflare WARP Client on VPS","Run sudo apt update and sudo apt install cloudflare-warp in the terminal on your VPS. Run warp-cli registration new \u003CTEAM-NAME> in the terminal on your VPS, which will print out a URL. Copy the printed URL, which will look like https:\u002F\u002F\u003Cteam>.cloudfl","#step-2",{"@type":1366,"name":1375,"text":1376,"url":1377,"image":720},"Set Up Traffic Routing","Click the profile for your VPS on the Devices dashboard. Scroll down to the 'Split Tunnels' section. Click the 'Manage' button and configure the settings as shown below. Replace the IP address if necessary. Exposing the address and host will route tr","#step-3",{"@type":1366,"name":1379,"text":1380,"url":1381},"Configure Firewall on the VPS","Enable the firewall to allow the '100.96.0.0\u002F12' subnet only, blocking all other public incoming access. bash Allow loopback traffic to avoid breaking local services: bash Reload the firewall and verify status: bash","#step-4",{"@type":1366,"name":1383,"text":1384,"url":1385},"Expose Hermes Agent to the Private Network","We will expose the Hermes Agent Web Dashboard to our private network and use the default authentication provider, Nous Research.","#step-5",{"@type":1366,"name":1387,"text":1388,"url":1389,"image":1228},"Install Cloudflare WARP Client on Desktop","Download the Cloudflare WARP client from Cloudflare's portal. Open and launch the Cloudflare WARP client after installation. Log in when prompted. A 'Success' page will be displayed after a successful login. The WARP client should now show it is conn","#step-6",{"@type":1366,"name":1391,"text":1392,"url":1393,"image":1287},"Install Cloudflare WARP Client on iOS Devices","Install Cloudflare One from the App Store. Open the Cloudflare One app and enter your team name when prompted. Log in using the same email address that was configured in the policy rule above. Once it is connected, it should look like the following:","#step-7","index, follow",{"lastmod":1396},"2026-09-28",{"title":1398,"description":1356,"ogTitle":362,"ogDescription":1356,"twitterTitle":362,"twitterDescription":1356},"Secure Hermes Agent Access with Cloudflare Zero Trust",[438,1400,434,1401,1402],"Zero Trust","VPN","Tutorial","7w7yHDwhXSX7-e5xSvZ3rQ_6OcpB47010zvSqV1GJ9M",{"surround":1405,"related":4058},[1406,2861],{"id":1407,"title":402,"author":423,"body":1408,"category":2840,"date":2842,"description":2843,"extension":1357,"image":2844,"imageAlt":2845,"isPublished":644,"meta":2846,"minRead":1150,"navigation":644,"path":403,"seo":2853,"stem":404,"tags":2855,"updatedAt":2859,"__hash__":2860},"article\u002Fen\u002Farticle\u002Fsync-obsidian-across-devices.md",{"type":425,"value":1409,"toc":2818},[1410,1413,1418,1427,1436,1453,1458,1463,1467,1472,1486,1502,1505,1509,1513,1520,1525,1529,1534,1592,1600,1632,1636,1643,1651,1658,1720,1723,1742,1749,1761,1765,1769,1780,1785,1791,1795,1816,1821,1835,1840,1845,1850,1864,1867,1872,1875,1880,1884,1889,1903,1907,1921,1932,1936,1941,1944,1954,1987,1991,1994,2138,2172,2178,2199,2210,2215,2219,2229,2300,2304,2310,2348,2479,2486,2492,2498,2504,2507,2513,2519,2533,2544,2551,2557,2564,2693,2699,2704,2707,2712,2715,2719,2724,2729,2735,2746,2756,2760,2771,2776,2782,2788,2792,2815],[428,1411,1412],{},"Obsidian is a local-first knowledge management app. Every note is a markdown file on your device and remains entirely under your control. However, we often want the same vault across our laptop, phone, and other devices, or to be able to access it through a web browser remotely.",[514,1414],{"src":1415,"alt":1416,"style":1417},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-multi-device-sync-illustration.webp","Illustration of Obsidian vault synchronized across multiple devices","max-width: 667px; width: 100%; height: auto;",[428,1419,1420,1421,1426],{},"A number of synchronisation solutions are available for Obsidian, but they all make trade-offs regarding conflict handling, encryption, or data sovereignty. ",[448,1422,1425],{"href":1423,"rel":1424},"https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch",[507],"Synch"," is an open-source application that synchronises your Obsidian vault with end-to-end encryption and automatic conflict handling on a self-hosted server.",[428,1428,1429,1430,1435],{},"While Obsidian's local-first approach works perfectly most of the time, we may still need to access our vault through a web browser remotely on some occasions. ",[448,1431,1434],{"href":1432,"rel":1433},"https:\u002F\u002Fgithub.com\u002FNystik-gh\u002Fignis",[507],"Ignis"," is an open-source application that runs Obsidian inside a web browser in a close-to-native format, allowing you to read and edit your vault from anywhere.",[428,1437,1438,1439,563,1441,1443,1444,1447,1448,1452],{},"In this guide, we will set up ",[432,1440,1425],{},[432,1442,1434],{}," on a ",[432,1445,1446],{},"VPS"," (Virtual Private Server), hosting them securely inside a ",[432,1449,1450],{},[448,1451,442],{"href":363}," private network rather than exposing them to the open internet.",[514,1454],{"src":1455,"alt":1456,"style":1457},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-sync-cloudflare-zero-trust-architecture.webp","Architecture diagram of Obsidian sync using Cloudflare Zero Trust","max-width: 671px; width: 100%; height: auto;",[1459,1460],"article-card",{"description":1356,"image":1358,"image-alt":1359,"label":1461,"min-read":1462,"title":362,"to":363},"Related guide","8",[455,1464,1466],{"id":1465},"secure-obsidian-vault-synchronisation-with-synch","Secure Obsidian Vault Synchronisation with Synch",[428,1468,1469,1471],{},[432,1470,1425],{}," provides the following features:",[482,1473,1474,1477,1480,1483],{},[466,1475,1476],{},"Syncs your vault as soon as changes are detected",[466,1478,1479],{},"Encrypts vault data before upload",[466,1481,1482],{},"Allows restoration from version history",[466,1484,1485],{},"Includes automatic conflict handling",[428,1487,1488,1490,1491,1494,1495,1498,1499,1501],{},[432,1489,1425],{}," generates a random 32-byte ",[432,1492,1493],{},"vault key"," on your device, which is used to encrypt your vault data. When you create a remote vault, you choose a ",[432,1496,1497],{},"vault password","; this password is used to protect the ",[432,1500,1493],{}," so that the key can be stored securely on the server and unlocked on other devices.",[428,1503,1504],{},"Note conflict resolution is handled on your client devices rather than on the server. If two devices edit the same note simultaneously, the server keeps whichever version arrives first and flags the other device as out of date. The out-of-date device then automatically merges the newer version with its local changes before uploading the final merged note.",[477,1506,1508],{"id":1507},"set-up-synch-on-your-vps","Set Up Synch on Your VPS",[903,1510,1512],{"id":1511},"create-a-domain-name","Create a Domain Name",[428,1514,1515,1516,1519],{},"Create an A record in Cloudflare and set its proxy status to ",[432,1517,1518],{},"DNS only"," (bypassing the Cloudflare CDN).",[514,1521],{"src":1522,"alt":1523,"style":1524},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fcloudflare-dns-a-record-synch-server.webp","Configuring a DNS A record for the Synch server in Cloudflare","max-width: 538px; width: 100%; height: auto;",[903,1526,1528],{"id":1527},"install-synch-docker-on-ubuntu","Install Synch Docker on Ubuntu",[1530,1531,1533],"h5",{"id":1532},"clone-the-repository","Clone the Repository",[613,1535,1537],{"className":615,"code":1536,"language":617,"meta":423,"style":423},"git clone https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git       \n        \n# Navigate to the API folder\ncd synch\u002Fapps\u002Fapi\n        \n# Copy the example environment file:\ncp .env.example .env\n",[522,1538,1539,1553,1558,1563,1572,1576,1581],{"__ignoreMap":423},[621,1540,1541,1544,1547,1550],{"class":623,"line":624},[621,1542,1543],{"class":627},"git",[621,1545,1546],{"class":631}," clone",[621,1548,1549],{"class":631}," https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git",[621,1551,1552],{"class":769},"       \n",[621,1554,1555],{"class":623,"line":641},[621,1556,1557],{"class":769},"        \n",[621,1559,1560],{"class":623,"line":648},[621,1561,1562],{"class":651},"# Navigate to the API folder\n",[621,1564,1565,1569],{"class":623,"line":655},[621,1566,1568],{"class":1567},"s2Zo4","cd",[621,1570,1571],{"class":631}," synch\u002Fapps\u002Fapi\n",[621,1573,1574],{"class":623,"line":667},[621,1575,1557],{"class":769},[621,1577,1578],{"class":623,"line":672},[621,1579,1580],{"class":651},"# Copy the example environment file:\n",[621,1582,1583,1586,1589],{"class":623,"line":678},[621,1584,1585],{"class":627},"cp",[621,1587,1588],{"class":631}," .env.example",[621,1590,1591],{"class":631}," .env\n",[1530,1593,1595,1596,1599],{"id":1594},"edit-env-values","Edit ",[522,1597,1598],{},".env"," Values",[482,1601,1602,1608,1626],{},[466,1603,1604,1607],{},[522,1605,1606],{},"PUBLIC_URL=synch.pafor.me",": Enter the public domain name of your Synch server (the domain name created in the previous step).",[466,1609,1610,563,1613,1616,1617,1621,1622,1625],{},[522,1611,1612],{},"BETTER_AUTH_SECRET",[522,1614,1615],{},"SYNC_TOKEN_SECRET",": Generate secure keys using this ",[448,1618,1620],{"href":1619},"\u002Ftools\u002Fsecret-key-hex","online secret-key tool"," or by running ",[522,1623,1624],{},"openssl rand -hex 32"," twice in your terminal.",[466,1627,1628,1631],{},[522,1629,1630],{},"AUTH_ALLOWED_EMAILS",": A comma-separated list of the email addresses permitted to sign up and create accounts.",[1530,1633,1635],{"id":1634},"add-the-domain-to-caddyfile","Add the Domain to Caddyfile",[428,1637,1638,1639,509],{},"The details of how the Cloudflare DNS module is integrated with Caddy and started within a container can be found in our ",[448,1640,1642],{"href":1641},"\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#_4-enable-https-with-caddy","self-hosting Buzz article",[1459,1644],{"description":1645,"image":1646,"image-alt":1647,"label":1648,"min-read":1649,"title":1650,"to":1641},"Learn how to configure Caddy to automatically provision SSL\u002FTLS certificates using Cloudflare DNS challenges in Docker containers.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002FEN-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp","Configuring Caddy with Cloudflare DNS API token for automated SSL\u002FTLS certificate generation in a self-hosted workspace","Self-hosting guide","12","How to Enable HTTPS with Caddy and Cloudflare DNS",[428,1652,1653,1654,1657],{},"Include the ",[522,1655,1656],{},"SYNCH_DOMAIN"," directive in your Caddyfile, pointing to port 8787 (the port used by the Synch container):",[613,1659,1663],{"className":1660,"code":1661,"language":1662,"meta":423,"style":423},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}\n}\n\n{$SYNCH_DOMAIN} {\n  encode zstd gzip\n  reverse_proxy host.docker.internal:8787\n}\n","json",[522,1664,1665,1670,1678,1682,1686,1700,1705,1716],{"__ignoreMap":423},[621,1666,1667],{"class":623,"line":624},[621,1668,1669],{"class":693},"{\n",[621,1671,1672,1675],{"class":623,"line":641},[621,1673,1674],{"class":769},"  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN",[621,1676,1677],{"class":693},"}\n",[621,1679,1680],{"class":623,"line":648},[621,1681,1677],{"class":769},[621,1683,1684],{"class":623,"line":655},[621,1685,645],{"emptyLinePlaceholder":644},[621,1687,1688,1691,1694,1697],{"class":623,"line":667},[621,1689,1690],{"class":693},"{",[621,1692,1693],{"class":769},"$SYNCH_DOMAIN",[621,1695,1696],{"class":693},"}",[621,1698,1699],{"class":693}," {\n",[621,1701,1702],{"class":623,"line":672},[621,1703,1704],{"class":769},"  encode zstd gzip\n",[621,1706,1707,1710,1712],{"class":623,"line":678},[621,1708,1709],{"class":769},"  reverse_proxy host.docker.internal",[621,1711,969],{"class":693},[621,1713,1715],{"class":1714},"sbssI","8787\n",[621,1717,1718],{"class":623,"line":1020},[621,1719,1677],{"class":693},[428,1721,1722],{},"Start the container:",[613,1724,1726],{"className":615,"code":1725,"language":617,"meta":423,"style":423},"docker compose up -d\n",[522,1727,1728],{"__ignoreMap":423},[621,1729,1730,1733,1736,1739],{"class":623,"line":624},[621,1731,1732],{"class":627},"docker",[621,1734,1735],{"class":631}," compose",[621,1737,1738],{"class":631}," up",[621,1740,1741],{"class":631}," -d\n",[428,1743,1744,1745,1748],{},"Run the following ",[522,1746,1747],{},"curl"," command to check its availability:",[613,1750,1752],{"className":615,"code":1751,"language":617,"meta":423,"style":423},"curl https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[522,1753,1754],{"__ignoreMap":423},[621,1755,1756,1758],{"class":623,"line":624},[621,1757,1747],{"class":627},[621,1759,1760],{"class":631}," https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[477,1762,1764],{"id":1763},"connecting-obsidian-to-your-synch-server","Connecting Obsidian to Your Synch Server",[903,1766,1768],{"id":1767},"install-the-synch-plugin-on-obsidian","Install the Synch Plugin on Obsidian",[428,1770,1771,1772,1775,1776,1779],{},"Open Obsidian Settings, navigate to ",[432,1773,1774],{},"Community plugins",", and click the ",[432,1777,1778],{},"'Browse'"," button:",[514,1781],{"src":1782,"alt":1783,"style":1784},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-community-plugins-browse.webp","Browsing community plugins in Obsidian settings","max-width: 523px; width: 100%; height: auto;",[428,1786,1787,1788,969],{},"Search for and install ",[432,1789,1790],{},"'Synchrun'",[514,1792],{"src":1793,"alt":1794,"style":1524},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-install-synchrun-plugin.webp","Installing the Synchrun plugin in Obsidian",[428,1796,1797,1798,1800,1801,1804,1805,1808,1809,1812,1813,509],{},"Once ",[432,1799,1790],{}," is installed, open the plugin settings and enable ",[432,1802,1803],{},"'Use a self-hosted server'",". Then, enter ",[522,1806,1807],{},"https:\u002F\u002Fsynch.pafor.me"," in the ",[432,1810,1811],{},"'Server URL'"," field and click ",[432,1814,1815],{},"'Save'",[514,1817],{"src":1818,"alt":1819,"style":1820},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-plugin-settings-self-hosted.webp","Configuring self-hosted server URL in Synchrun plugin settings","max-width: 525px; width: 100%; height: auto;",[428,1822,1823,1824,1827,1828,1831,1832,1834],{},"Click the ",[432,1825,1826],{},"'Sign in on this device'"," button under ",[432,1829,1830],{},"'Account'",". Next, sign up for an account using the email address you specified in your ",[522,1833,1630],{}," list; you will then be redirected to the following authorization page:",[514,1836],{"src":1837,"alt":1838,"style":1839},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-account-authorization-page.webp","Account authorization page for Synchrun","max-width: 494px; width: 100%; height: auto;",[428,1841,1823,1842,1779],{},[432,1843,1844],{},"'Allow Obsidian sign-in'",[514,1846],{"src":1847,"alt":1848,"style":1849},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-allow-obsidian-signin.webp","Allowing Obsidian sign-in for Synch","max-width: 498px; width: 100%; height: auto;",[428,1851,1823,1852,1855,1856,961,1859],{},[432,1853,1854],{},"'Return to Obsidian'"," button, and then click ",[432,1857,1858],{},"'Create vault'",[514,1860],{"src":1861,"alt":1862,"style":1863},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-create-remote-vault.webp","Creating a new remote vault in Synchrun","max-width: 496px; width: 100%; height: auto;",[428,1865,1866],{},"Enter a name and secure password to create your remote vault.",[514,1868],{"src":1869,"alt":1870,"style":1871},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-vault-password-setup.webp","Setting up a secure password for the Obsidian remote vault","max-width: 500px; width: 100%; height: auto;",[428,1873,1874],{},"The synchronisation process will begin immediately and may take a while depending on the size of your vault. Once completed, your total storage usage will be displayed.",[514,1876],{"src":1877,"alt":1878,"style":1879},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-sync-completed-storage.webp","Synchrun sync completed showing total storage used","max-width: 508px; width: 100%; height: auto;",[455,1881,1883],{"id":1882},"browser-based-obsidian-access-with-ignis","Browser-Based Obsidian Access with Ignis",[428,1885,1886,1888],{},[432,1887,1434],{}," replaces Obsidian's Electron APIs with Web APIs, which allows Obsidian's JavaScript code to be executed directly in a standard web browser. All your markdown files and attachments are stored directly in the host server's file system.",[428,1890,1891,1892,563,1897,1902],{},"However, there are a few limitations compared to the standalone Obsidian desktop application. Certain features or plugins that require Electron or Node.js APIs—which have no direct equivalent in a browser environment—will not work. Please refer to the Ignis ",[448,1893,1896],{"href":1894,"rel":1895},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Flimitations\u002F",[507],"Limitations",[448,1898,1901],{"href":1899,"rel":1900},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Fplugin-compatibility\u002F",[507],"Plugin compatibility"," guides for detailed compatibility listings.",[477,1904,1906],{"id":1905},"ignis-setup","Ignis Setup",[428,1908,1909,1910,1912,1913,1916,1917,1920],{},"We will install ",[432,1911,1434],{}," on our VPS using Docker, mounting it to the local ",[522,1914,1915],{},".\u002Fvaults"," folder. This vault directory will be synchronised using the ",[432,1918,1919],{},"Synch CLI"," to pull note updates from the remote vault we set up earlier.",[428,1922,1923,1924,1926,1927,1931],{},"Since ",[432,1925,1434],{}," does not have built-in authentication, it must be secured behind a ",[432,1928,1929],{},[448,1930,442],{"href":363}," private network.",[903,1933,1935],{"id":1934},"create-dns-record","Create DNS Record",[514,1937],{"src":1938,"alt":1939,"style":1940},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fcloudflare-dns-a-record-ignis.webp","Configuring a DNS A record for the Ignis web client in Cloudflare","max-width: 552px; width: 100%; height: auto;",[903,1942,1635],{"id":1943},"add-the-domain-to-caddyfile-1",[428,1945,1946,1947,1950,1951,969],{},"Add ",[522,1948,1949],{},"obsidian.pafor.me"," to your Caddyfile in the same way as ",[522,1952,1953],{},"synch.pafor.me",[613,1955,1957],{"className":1660,"code":1956,"language":1662,"meta":423,"style":423},"{$OBSIDIAN_DOMAIN} {\n  encode zstd gzip\n  reverse_proxy host.docker.internal:9898\n}\n",[522,1958,1959,1970,1974,1983],{"__ignoreMap":423},[621,1960,1961,1963,1966,1968],{"class":623,"line":624},[621,1962,1690],{"class":693},[621,1964,1965],{"class":769},"$OBSIDIAN_DOMAIN",[621,1967,1696],{"class":693},[621,1969,1699],{"class":693},[621,1971,1972],{"class":623,"line":641},[621,1973,1704],{"class":769},[621,1975,1976,1978,1980],{"class":623,"line":648},[621,1977,1709],{"class":769},[621,1979,969],{"class":693},[621,1981,1982],{"class":1714},"9898\n",[621,1984,1985],{"class":623,"line":655},[621,1986,1677],{"class":693},[903,1988,1990],{"id":1989},"start-ignis-using-docker","Start Ignis using Docker",[428,1992,1993],{},"Save the following docker compose yml as ignis-docker-compose.yml on VPS:",[613,1995,1999],{"className":1996,"code":1997,"language":1998,"meta":423,"style":423},"language-yml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","services:\n  ignis:\n    image: nobbe\u002Fignis:latest\n    ports:\n      - \"9898:8080\"\n    environment:\n      # match these to your host user (run: id)\n      - PUID=1000\n      - PGID=1000\n      - WS_ORIGINS=https:\u002F\u002Fobsidian.pafor.me\n    volumes:\n      - .\u002Fvaults:\u002Fvaults\n      - .\u002Fdata:\u002Fapp\u002Fdata\n      - obsidian-app:\u002Fapp\u002Fobsidian-app\n    restart: unless-stopped\n\nvolumes:\n  obsidian-app:\n","yml",[522,2000,2001,2008,2015,2025,2032,2045,2052,2057,2064,2071,2078,2085,2092,2099,2106,2117,2122,2130],{"__ignoreMap":423},[621,2002,2003,2006],{"class":623,"line":624},[621,2004,2005],{"class":957},"services",[621,2007,961],{"class":693},[621,2009,2010,2013],{"class":623,"line":641},[621,2011,2012],{"class":957},"  ignis",[621,2014,961],{"class":693},[621,2016,2017,2020,2022],{"class":623,"line":648},[621,2018,2019],{"class":957},"    image",[621,2021,969],{"class":693},[621,2023,2024],{"class":631}," nobbe\u002Fignis:latest\n",[621,2026,2027,2030],{"class":623,"line":655},[621,2028,2029],{"class":957},"    ports",[621,2031,961],{"class":693},[621,2033,2034,2037,2040,2043],{"class":623,"line":667},[621,2035,2036],{"class":693},"      -",[621,2038,2039],{"class":693}," \"",[621,2041,2042],{"class":631},"9898:8080",[621,2044,700],{"class":693},[621,2046,2047,2050],{"class":623,"line":672},[621,2048,2049],{"class":957},"    environment",[621,2051,961],{"class":693},[621,2053,2054],{"class":623,"line":678},[621,2055,2056],{"class":651},"      # match these to your host user (run: id)\n",[621,2058,2059,2061],{"class":623,"line":1020},[621,2060,2036],{"class":693},[621,2062,2063],{"class":631}," PUID=1000\n",[621,2065,2066,2068],{"class":623,"line":1031},[621,2067,2036],{"class":693},[621,2069,2070],{"class":631}," PGID=1000\n",[621,2072,2073,2075],{"class":623,"line":1127},[621,2074,2036],{"class":693},[621,2076,2077],{"class":631}," WS_ORIGINS=https:\u002F\u002Fobsidian.pafor.me\n",[621,2079,2080,2083],{"class":623,"line":1133},[621,2081,2082],{"class":957},"    volumes",[621,2084,961],{"class":693},[621,2086,2087,2089],{"class":623,"line":1139},[621,2088,2036],{"class":693},[621,2090,2091],{"class":631}," .\u002Fvaults:\u002Fvaults\n",[621,2093,2094,2096],{"class":623,"line":1144},[621,2095,2036],{"class":693},[621,2097,2098],{"class":631}," .\u002Fdata:\u002Fapp\u002Fdata\n",[621,2100,2101,2103],{"class":623,"line":1150},[621,2102,2036],{"class":693},[621,2104,2105],{"class":631}," obsidian-app:\u002Fapp\u002Fobsidian-app\n",[621,2107,2109,2112,2114],{"class":623,"line":2108},15,[621,2110,2111],{"class":957},"    restart",[621,2113,969],{"class":693},[621,2115,2116],{"class":631}," unless-stopped\n",[621,2118,2120],{"class":623,"line":2119},16,[621,2121,645],{"emptyLinePlaceholder":644},[621,2123,2125,2128],{"class":623,"line":2124},17,[621,2126,2127],{"class":957},"volumes",[621,2129,961],{"class":693},[621,2131,2133,2136],{"class":623,"line":2132},18,[621,2134,2135],{"class":957},"  obsidian-app",[621,2137,961],{"class":693},[482,2139,2140,2151,2165],{},[466,2141,2142,2143,2146,2147,2150],{},"Use port ",[522,2144,2145],{},"9898"," on the host, as ",[522,2148,2149],{},"8080"," is commonly used by other services.",[466,2152,2153,2154,2157,2158,563,2161,2164],{},"Run the ",[522,2155,2156],{},"id"," command on your VPS to verify your host user's ",[522,2159,2160],{},"UID",[522,2162,2163],{},"GID"," to ensure correct file system permissions.",[466,2166,2167,2168,2171],{},"Set ",[522,2169,2170],{},"WS_ORIGINS"," to only allow WebSocket connections originating from your specific domain name.",[428,2173,2174,2175,2177],{},"Start the ",[432,2176,1434],{}," docker:",[613,2179,2181],{"className":615,"code":2180,"language":617,"meta":423,"style":423},"docker compose -f ignis-docker-compose.yml up -d\n",[522,2182,2183],{"__ignoreMap":423},[621,2184,2185,2187,2189,2192,2195,2197],{"class":623,"line":624},[621,2186,1732],{"class":627},[621,2188,1735],{"class":631},[621,2190,2191],{"class":631}," -f",[621,2193,2194],{"class":631}," ignis-docker-compose.yml",[621,2196,1738],{"class":631},[621,2198,1741],{"class":631},[428,2200,2201,2202,2205,2206,2209],{},"When you navigate to your domain in a web browser, the ",[432,2203,2204],{},"'Vault Manager'"," will appear. It will be empty as no vaults are configured yet. We will set up the ",[432,2207,2208],{},"'Synch CLI'"," in the next section to synchronise contents from our remote vault.",[514,2211],{"src":2212,"alt":2213,"style":2214},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-vault-manager-empty.webp","Empty Vault Manager interface in Ignis web client","max-width: 466px; width: 100%; height: auto;",[903,2216,2218],{"id":2217},"firewall-issue","Firewall Issue",[428,2220,2221,2222,2225,2226,969],{},"By default, Docker automatically inserts its own DNAT and FORWARD rules, which route public traffic directly to active containers. This bypasses the standard Ubuntu UFW\u002Fiptables ",[522,2223,2224],{},"INPUT"," chain. To block external public traffic and keep the containers private, manually add the following rules to ",[522,2227,2228],{},"iptables",[613,2230,2232],{"className":615,"code":2231,"language":617,"meta":423,"style":423},"# Block all external public traffic\nsudo iptables -I DOCKER-USER -i ext_if -j DROP \n\n# Allow traffic only from your Cloudflare WARP client private IP\nsudo iptables -I DOCKER-USER -i ext_if -s 100.96.0.10 -j ACCEPT\n",[522,2233,2234,2239,2266,2270,2275],{"__ignoreMap":423},[621,2235,2236],{"class":623,"line":624},[621,2237,2238],{"class":651},"# Block all external public traffic\n",[621,2240,2241,2243,2246,2249,2252,2255,2258,2261,2264],{"class":623,"line":641},[621,2242,628],{"class":627},[621,2244,2245],{"class":631}," iptables",[621,2247,2248],{"class":631}," -I",[621,2250,2251],{"class":631}," DOCKER-USER",[621,2253,2254],{"class":631}," -i",[621,2256,2257],{"class":631}," ext_if",[621,2259,2260],{"class":631}," -j",[621,2262,2263],{"class":631}," DROP",[621,2265,770],{"class":769},[621,2267,2268],{"class":623,"line":648},[621,2269,645],{"emptyLinePlaceholder":644},[621,2271,2272],{"class":623,"line":655},[621,2273,2274],{"class":651},"# Allow traffic only from your Cloudflare WARP client private IP\n",[621,2276,2277,2279,2281,2283,2285,2287,2289,2292,2295,2297],{"class":623,"line":667},[621,2278,628],{"class":627},[621,2280,2245],{"class":631},[621,2282,2248],{"class":631},[621,2284,2251],{"class":631},[621,2286,2254],{"class":631},[621,2288,2257],{"class":631},[621,2290,2291],{"class":631}," -s",[621,2293,2294],{"class":1714}," 100.96.0.10",[621,2296,2260],{"class":631},[621,2298,2299],{"class":631}," ACCEPT\n",[903,2301,2303],{"id":2302},"synch-cli-configuration","Synch CLI Configuration",[428,2305,2306,2307,2309],{},"The ",[432,2308,1919],{}," is a headless tool that allows an Obsidian vault directory to be synchronised directly on remote servers without requiring the full desktop application to be installed.",[428,2311,2312,2313,2315,2316,2319,2320,2323,2324,2327,2328,2331,2332,2335,2336,2339,2340,2343,2344,2347],{},"Build the ",[432,2314,1919],{}," from your cloned ",[522,2317,2318],{},"synch"," repository. Building requires ",[432,2321,2322],{},"Node.js >= 22.5"," (as the CLI depends on ",[522,2325,2326],{},"node:sqlite"," and global browser APIs such as ",[522,2329,2330],{},"fetch",", ",[522,2333,2334],{},"WebSocket",", and ",[522,2337,2338],{},"WebCrypto",") and ",[432,2341,2342],{},"pnpm"," (since the repository is structured as a pnpm workspace using version ",[522,2345,2346],{},"10.33.0","):",[613,2349,2351],{"className":615,"code":2350,"language":617,"meta":423,"style":423},"# Check versions\nnode --version   # must be >= 22.5\npnpm --version\n\n# In the repos root\npnpm install\n\n# Build the CLI bundle\npnpm -C apps\u002Fcli build\n\n# After a successful build you have `apps\u002Fcli\u002Fdist\u002Fsynch.js`. Make it executable and put it on your PATH\nchmod +x apps\u002Fcli\u002Fdist\u002Fsynch.js\nln -sf \"$PWD\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js\" \"$HOME\u002F.local\u002Fbin\u002Fsynch\"\n\n# Verification\nsynch --help\n",[522,2352,2353,2358,2369,2376,2380,2385,2392,2396,2401,2414,2418,2423,2434,2463,2467,2472],{"__ignoreMap":423},[621,2354,2355],{"class":623,"line":624},[621,2356,2357],{"class":651},"# Check versions\n",[621,2359,2360,2363,2366],{"class":623,"line":641},[621,2361,2362],{"class":627},"node",[621,2364,2365],{"class":631}," --version",[621,2367,2368],{"class":651},"   # must be >= 22.5\n",[621,2370,2371,2373],{"class":623,"line":648},[621,2372,2342],{"class":627},[621,2374,2375],{"class":631}," --version\n",[621,2377,2378],{"class":623,"line":655},[621,2379,645],{"emptyLinePlaceholder":644},[621,2381,2382],{"class":623,"line":667},[621,2383,2384],{"class":651},"# In the repos root\n",[621,2386,2387,2389],{"class":623,"line":672},[621,2388,2342],{"class":627},[621,2390,2391],{"class":631}," install\n",[621,2393,2394],{"class":623,"line":678},[621,2395,645],{"emptyLinePlaceholder":644},[621,2397,2398],{"class":623,"line":1020},[621,2399,2400],{"class":651},"# Build the CLI bundle\n",[621,2402,2403,2405,2408,2411],{"class":623,"line":1031},[621,2404,2342],{"class":627},[621,2406,2407],{"class":631}," -C",[621,2409,2410],{"class":631}," apps\u002Fcli",[621,2412,2413],{"class":631}," build\n",[621,2415,2416],{"class":623,"line":1127},[621,2417,645],{"emptyLinePlaceholder":644},[621,2419,2420],{"class":623,"line":1133},[621,2421,2422],{"class":651},"# After a successful build you have `apps\u002Fcli\u002Fdist\u002Fsynch.js`. Make it executable and put it on your PATH\n",[621,2424,2425,2428,2431],{"class":623,"line":1139},[621,2426,2427],{"class":627},"chmod",[621,2429,2430],{"class":631}," +x",[621,2432,2433],{"class":631}," apps\u002Fcli\u002Fdist\u002Fsynch.js\n",[621,2435,2436,2439,2442,2444,2447,2450,2453,2455,2458,2461],{"class":623,"line":1144},[621,2437,2438],{"class":627},"ln",[621,2440,2441],{"class":631}," -sf",[621,2443,2039],{"class":693},[621,2445,2446],{"class":769},"$PWD",[621,2448,2449],{"class":631},"\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js",[621,2451,2452],{"class":693},"\"",[621,2454,2039],{"class":693},[621,2456,2457],{"class":769},"$HOME",[621,2459,2460],{"class":631},"\u002F.local\u002Fbin\u002Fsynch",[621,2462,700],{"class":693},[621,2464,2465],{"class":623,"line":1150},[621,2466,645],{"emptyLinePlaceholder":644},[621,2468,2469],{"class":623,"line":2108},[621,2470,2471],{"class":651},"# Verification\n",[621,2473,2474,2476],{"class":623,"line":2119},[621,2475,2318],{"class":627},[621,2477,2478],{"class":631}," --help\n",[428,2480,2481,2482,2485],{},"Since the Synch CLI is running on the same VPS as your Synch remote vault, it can connect to the local API server directly. If you are configuring a different server, run ",[522,2483,2484],{},"synch login --api-url \u003Cremote-synch-api-url>"," to define your target API endpoint.",[428,2487,2488],{},[514,2489],{"alt":2490,"src":2491},"Running synch login with custom API URL in terminal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-api-url-terminal.webp",[428,2493,559,2494,2497],{},[522,2495,2496],{},"synch login"," in your terminal, and you will receive an authentication URL:",[428,2499,2500],{},[514,2501],{"alt":2502,"src":2503},"Terminal output showing the authentication URL for Synch CLI","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-auth-url-terminal.webp",[428,2505,2506],{},"Log in via the web page using the same email address registered with your Obsidian desktop Synchrun plugin.",[428,2508,2509],{},[514,2510],{"alt":2511,"src":2512},"Successful web login for Synch CLI authorization","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-web-login-success.webp",[428,2514,559,2515,2518],{},[522,2516,2517],{},"synch vault connect --vault ~\u002Fvaults\u002F\u003Cvaultname> --vault-id asadqe-7b29-4677-fsad-234asdafasd"," to link your local vault directory on the VPS to the remote vault.",[428,2520,2521,2522,2525,2526,2529,2530,2347],{},"The remote vault ID can be found inside the ",[432,2523,2524],{},"Synchrun"," plugin settings by clicking ",[432,2527,2528],{},"'Manage remote vaults'",". This will display a web page showing a list of your remote vaults, each identified by a unique GUID (e.g., ",[522,2531,2532],{},"123e4567-e89b-12d3-a456-426614174000",[428,2534,2535,2540],{},[514,2536],{"src":2537,"alt":2538,"style":2539},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-manage-remote-vaults.webp","Managing remote vaults in the Synchrun plugin","max-width: 582px; width: 100%; height: auto;",[514,2541],{"alt":2542,"src":2543},"Locating the unique remote vault ID in Synchrun","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-remote-vault-id.webp",[428,2545,2546,2547,2550],{},"Enter your vault password when prompted to establish the link. Once connected, run ",[522,2548,2549],{},"synch sync --vault ~\u002Fvaults\u002F\u003Cvault-name>"," to perform your initial synchronisation. This first run may take some time depending on your vault size.",[428,2552,2553],{},[514,2554],{"alt":2555,"src":2556},"Initial vault synchronization progress in Synch CLI","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-cli-initial-sync-progress.webp",[428,2558,2559,2560,2563],{},"To automate this, set up and enable a systemd service to run ",[522,2561,2562],{},"synch watch"," continuously, ensuring changes are synchronised instantly on boot:",[613,2565,2567],{"className":615,"code":2566,"language":617,"meta":423,"style":423},"sudo tee \u002Fetc\u002Fsystemd\u002Fsystem\u002Fsynch-watch.service \u003C\u003C'EOF'\n[Unit]\nDescription=Synch vault watcher\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nUser=\u003Cusername>\nExecStart=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin\u002Fsynch watch --vault \u002Fhome\u002F\u003Cusername>\u002Fvaults\u002F\u003Cvault-name>\nWorkingDirectory=\u002Fhome\u002F\u003Cusername>\u002Fvaults\nEnvironment=\"PATH=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin:\u002Fhome\u002F\u003Cusername>\u002F.cargo\u002Fbin:\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fsbin:\u002Fusr\u002Fbin:\u002Fsbin:\u002Fbin\"\nEnvironment=\"HOME=\u002Fhome\u002F\u003Cusername>\"\nRestart=always\nRestartSec=5\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsudo systemctl daemon-reload\nsudo systemctl enable --now synch-watch.service\n",[522,2568,2569,2585,2589,2594,2599,2604,2608,2612,2617,2622,2627,2632,2637,2642,2646,2651,2655,2659,2663,2669,2678],{"__ignoreMap":423},[621,2570,2571,2573,2576,2579,2582],{"class":623,"line":624},[621,2572,628],{"class":627},[621,2574,2575],{"class":631}," tee",[621,2577,2578],{"class":631}," \u002Fetc\u002Fsystemd\u002Fsystem\u002Fsynch-watch.service",[621,2580,2581],{"class":693}," \u003C\u003C",[621,2583,2584],{"class":693},"'EOF'\n",[621,2586,2587],{"class":623,"line":641},[621,2588,1085],{"class":631},[621,2590,2591],{"class":623,"line":648},[621,2592,2593],{"class":631},"Description=Synch vault watcher\n",[621,2595,2596],{"class":623,"line":655},[621,2597,2598],{"class":631},"After=network-online.target\n",[621,2600,2601],{"class":623,"line":667},[621,2602,2603],{"class":631},"Wants=network-online.target\n",[621,2605,2606],{"class":623,"line":672},[621,2607,645],{"emptyLinePlaceholder":644},[621,2609,2610],{"class":623,"line":678},[621,2611,1104],{"class":631},[621,2613,2614],{"class":623,"line":1020},[621,2615,2616],{"class":631},"Type=simple\n",[621,2618,2619],{"class":623,"line":1031},[621,2620,2621],{"class":631},"User=\u003Cusername>\n",[621,2623,2624],{"class":623,"line":1127},[621,2625,2626],{"class":631},"ExecStart=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin\u002Fsynch watch --vault \u002Fhome\u002F\u003Cusername>\u002Fvaults\u002F\u003Cvault-name>\n",[621,2628,2629],{"class":623,"line":1133},[621,2630,2631],{"class":631},"WorkingDirectory=\u002Fhome\u002F\u003Cusername>\u002Fvaults\n",[621,2633,2634],{"class":623,"line":1139},[621,2635,2636],{"class":631},"Environment=\"PATH=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin:\u002Fhome\u002F\u003Cusername>\u002F.cargo\u002Fbin:\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fsbin:\u002Fusr\u002Fbin:\u002Fsbin:\u002Fbin\"\n",[621,2638,2639],{"class":623,"line":1144},[621,2640,2641],{"class":631},"Environment=\"HOME=\u002Fhome\u002F\u003Cusername>\"\n",[621,2643,2644],{"class":623,"line":1150},[621,2645,1124],{"class":631},[621,2647,2648],{"class":623,"line":2108},[621,2649,2650],{"class":631},"RestartSec=5\n",[621,2652,2653],{"class":623,"line":2119},[621,2654,645],{"emptyLinePlaceholder":644},[621,2656,2657],{"class":623,"line":2124},[621,2658,1147],{"class":631},[621,2660,2661],{"class":623,"line":2132},[621,2662,1153],{"class":631},[621,2664,2666],{"class":623,"line":2665},19,[621,2667,2668],{"class":693},"EOF\n",[621,2670,2672,2674,2676],{"class":623,"line":2671},20,[621,2673,628],{"class":627},[621,2675,632],{"class":631},[621,2677,1172],{"class":631},[621,2679,2681,2683,2685,2687,2690],{"class":623,"line":2680},21,[621,2682,628],{"class":627},[621,2684,632],{"class":631},[621,2686,766],{"class":631},[621,2688,2689],{"class":631}," --now",[621,2691,2692],{"class":631}," synch-watch.service\n",[428,2694,2695,2696,2698],{},"Open ",[522,2697,1949],{}," in your web browser. You will find that the user interface and layout are virtually identical to the desktop app:",[514,2700],{"src":2701,"alt":2702,"style":2703},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-web-interface-desktop-view.webp","Ignis web interface displaying the Obsidian vault on desktop","max-width: 593px; width: 100%; height: auto;",[428,2705,2706],{},"Clicking the settings icon reveals that almost all core configurations are intact, though your community plugins will need to be reinstalled:",[514,2708],{"src":2709,"alt":2710,"style":2711},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-settings-community-plugins.webp","Community plugins settings in the Ignis web interface","max-width: 597px; width: 100%; height: auto;",[428,2713,2714],{},"To test the setup, you can add a new note via the web interface:",[514,2716],{"src":2717,"alt":2718,"style":2711},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-create-new-note-web.webp","Creating a new markdown note via the Ignis web interface",[428,2720,2721,2722,509],{},"The note is immediately synchronised back to your Obsidian desktop app. Note that empty folders do not appear in ",[432,2723,1434],{},[514,2725],{"src":2726,"alt":2727,"style":2728},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-desktop-synced-note.webp","Newly created note successfully synced to the Obsidian desktop app","max-width: 502px; width: 100%; height: auto;",[428,2730,2731,2732,2734],{},"Viewing ",[522,2733,1949],{}," on a mobile web browser:",[428,2736,2737,2742],{},[514,2738],{"src":2739,"alt":2740,"style":2741},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-sidebar.webp","Sidebar navigation of the Ignis web client on a mobile device","max-width: 269px; width: 100%; height: auto;",[514,2743],{"src":2744,"alt":2745,"style":2741},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-editor.webp","Markdown note editor of the Ignis web client on a mobile device",[428,2747,2748,2749,2751,2752,2755],{},"When you delete a note on ",[432,2750,1434],{},", it is safely moved to your local vault's ",[522,2753,2754],{},"~\u002Fvaults\u002F\u003Cvault-name>\u002F.trash"," folder.",[455,2757,2759],{"id":2758},"final-thoughts-on-self-hosted-vaults","Final Thoughts on Self-Hosted Vaults",[428,2761,2762,2763,563,2765,2767,2768,2770],{},"Together, ",[432,2764,1425],{},[432,2766,1434],{}," make your primary Obsidian vault seamlessly available across all of your devices, completely hosted on infrastructure under your direct control. Positioning these services inside a ",[432,2769,442],{}," private network ensures that your personal notes are entirely shielded from the public internet.",[428,2772,2773,2775],{},[432,2774,1434],{}," is not intended to fully replace the native Obsidian desktop app. Instead, it serves as a lightweight, temporary web client for accessing and editing your vault when you are away from your main computer. For day-to-day writing and extensive vault management, the native Obsidian application remains the most comfortable choice.",[428,2777,2778,2779,2781],{},"Because Synch uses end-to-end encryption, your remote vault password must be highly secure to protect against brute-force guessing attacks. It is critical that you never lose this password—the server does not store the unencrypted ",[432,2780,1493],{},", and if forgotten, your data will be completely unrecoverable. Additionally, ensure that your VPS instance, alongside any automated snapshots or backups, is properly secured and maintained.",[428,2783,2784,2785,2787],{},"While ",[432,2786,1425],{},"'s encrypted version history and deleted-file recovery tools cover most accidental losses, keeping a separate, independent backup of your Obsidian vault is still highly recommended.",[455,2789,2791],{"id":2790},"references","References",[482,2793,2794,2801,2808],{},[466,2795,2796],{},[448,2797,2800],{"href":2798,"rel":2799},"https:\u002F\u002Fsynch.run\u002Fself-hosting-docker\u002F",[507],"Synch Deploy with Docker Compose",[466,2802,2803],{},[448,2804,2807],{"href":2805,"rel":2806},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fserver\u002Fdeploy\u002F",[507],"Ignis Deploy with Docker",[466,2809,2810],{},[448,2811,2814],{"href":2812,"rel":2813},"https:\u002F\u002Fsynch.run\u002Fblog\u002Fencryption-and-decryption\u002F",[507],"How does end-to-end encryption work in Synch?",[1331,2816,2817],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":423,"searchDepth":641,"depth":648,"links":2819},[2820,2829,2838,2839],{"id":1465,"depth":641,"text":1466,"children":2821},[2822,2826],{"id":1507,"depth":648,"text":1508,"children":2823},[2824,2825],{"id":1511,"depth":655,"text":1512},{"id":1527,"depth":655,"text":1528},{"id":1763,"depth":648,"text":1764,"children":2827},[2828],{"id":1767,"depth":655,"text":1768},{"id":1882,"depth":641,"text":1883,"children":2830},[2831],{"id":1905,"depth":648,"text":1906,"children":2832},[2833,2834,2835,2836,2837],{"id":1934,"depth":655,"text":1935},{"id":1943,"depth":655,"text":1635},{"id":1989,"depth":655,"text":1990},{"id":2217,"depth":655,"text":2218},{"id":2302,"depth":655,"text":2303},{"id":2758,"depth":641,"text":2759},{"id":2790,"depth":641,"text":2791},[2841],"productivity","2026-09-15","Securely synchronise Obsidian vaults across your devices and access notes on the web using self-hosted Synch and Ignis within Cloudflare Zero Trust.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002FEN-Sync-Obsidian-Across-Devices.webp","Securely synchronising Obsidian vaults across multiple devices using self-hosted Synch and Ignis web client inside Cloudflare Zero Trust",{"schemaOrg":2847,"robots":1394,"sitemap":2851},[2848,2850],{"@type":2849,"headline":402,"description":2843,"image":2844},"Article",{"@type":1363,"name":402,"description":2843,"image":2844},{"lastmod":2852},"2026-09-16",{"title":2854,"description":2843,"ogTitle":402,"ogDescription":2843,"twitterTitle":402,"twitterDescription":2843},"Secure Self-Hosted Obsidian Sync with Synch & Ignis",[2856,2857,2858,1400],"Self-hosting","Obsidian","Sync",null,"NmSkE1ri49cYPhoFTZtGO8tViPA-_S4FK-pDGfoT1H4",{"id":2862,"title":354,"author":423,"body":2863,"category":4020,"date":4023,"description":4024,"extension":1357,"image":4025,"imageAlt":4026,"isPublished":644,"meta":4027,"minRead":1031,"navigation":644,"path":355,"seo":4052,"stem":356,"tags":4054,"updatedAt":2859,"__hash__":4057},"article\u002Fen\u002Farticle\u002Fbringing-buzz-to-deepseek-harness.md",{"type":425,"value":2864,"toc":4004},[2865,2871,2892,2897,2900,2904,2910,2952,2955,3013,3017,3023,3285,3288,3292,3296,3303,3307,3321,3325,3335,3381,3388,3392,3395,3426,3430,3435,3476,3481,3487,3492,3498,3513,3526,3530,3539,3568,3590,3638,3646,3651,3657,3664,3670,3675,3682,3696,3702,3711,3746,3749,3755,3762,3768,3772,3775,3925,3929,3962,3966,3972,3975,4001],[428,2866,2867],{},[514,2868],{"alt":2869,"src":2870},"DeepSeek Harness message gateway connected to Block Buzz channel overview","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-nostr-gateway-overview.webp",[428,2872,2873,2874,2881,2882,2887,2888,509],{},"The DeepSeek Harness (DSH) plugin, ",[432,2875,2876],{},[448,2877,2880],{"href":2878,"rel":2879},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway",[507],"dsh-message-gateway",", extends the DeepSeek Harness assistant across messaging platforms such as Discord, Telegram, and WeChat. The plugin repository was forked and extended to add the ",[432,2883,2884],{},[448,2885,2886],{"href":383},"Buzz"," platform to the list. The forked repository is available on GitHub at ",[448,2889,2890],{"href":2890,"rel":2891},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway",[507],[1459,2893],{"description":2894,"image":1646,"image-alt":2895,"label":2896,"min-read":1649,"title":382,"to":383},"Learn how to self-host Block's Buzz on a Linux VPS behind Cloudflare DNS. Run a secure, Nostr-powered workspace where humans and AI agents collaborate.","A premium 16:9 technology card with deep blue and orange accents illustrating how to self-host Block's Buzz relay on an Ubuntu VPS, featuring a clean glassmorphic panel with centered typography.","Prerequisite guide",[428,2898,2899],{},"The DSH assistant joins a Buzz relay as a member, receives direct messages (DMs) and channel messages where it is @mentioned, and responds through the same per-chat agent pipeline used by the Web UI.",[455,2901,2903],{"id":2902},"architecture-of-the-dsh-message-gateway-plugin","Architecture of the dsh-message-gateway Plugin",[428,2905,2906,2907,2909],{},"The architecture of the ",[432,2908,2880],{}," plugin splits into two parts:",[482,2911,2912,2942],{},[466,2913,2914,2917,2918,2921,2922,2925,2926,2929,2930,2933,2934,2937,2938,2941],{},[432,2915,2916],{},"Host"," (Node): ",[522,2919,2920],{},"gateway-store"," (credentials, ",[522,2923,2924],{},"~\u002F.dsh\u002Fgateway.json","), ",[522,2927,2928],{},"platforms.ts"," (platform definitions + connection tests), ",[522,2931,2932],{},"routes.ts"," (",[522,2935,2936],{},"\u002Fgateway\u002F*"," endpoints), and ",[522,2939,2940],{},"bridge-manager.ts"," (the resident bridges: per-chat independent agent sessions + streamed replies).",[466,2943,2944,2947,2948,2951],{},[432,2945,2946],{},"Client"," (browser): the sidebar \"",[432,2949,2950],{},"Message platforms","\" page where you save credentials, test connections, and monitor status.",[428,2953,2954],{},"Adding a new platform involves the following steps:",[463,2956,2957,2974,2988],{},[466,2958,2959,2962,2963,2966,2967,2970,2971,509],{},[432,2960,2961],{},"A bridge class"," — ",[522,2964,2965],{},"start\u002Fstop\u002Fstatus"," plus an ",[522,2968,2969],{},"onText(text, frame)"," callback, mirroring ",[522,2972,2973],{},"wecom-bridge.ts",[466,2975,2976,2979,2980,2983,2984,2987],{},[432,2977,2978],{},"Bridge-manager wiring"," — reuse the existing per-chat pipeline (",[522,2981,2982],{},"ensureAgentForKey"," + ",[522,2985,2986],{},"pendingMap",") and swap in the platform's reply sink.",[466,2989,2990,2993,2994,563,2997,3000,3001,3004,3005,3008,3009,3012],{},[432,2991,2992],{},"Storage\u002Froute wiring"," — in ",[522,2995,2996],{},"\u002Fgateway\u002Fsave",[522,2998,2999],{},"\u002Fgateway\u002Fdelete",": ",[432,3002,3003],{},"saving credentials starts the bridge, deleting stops it"," — plus an ",[522,3006,3007],{},"autoStartXxx"," flag so ",[522,3010,3011],{},"dsh web"," reconnects on boot.",[455,3014,3016],{"id":3015},"building-the-buzz-bridge-nostr-protocol-event-lifecycle","Building the Buzz Bridge: Nostr Protocol & Event Lifecycle",[428,3018,2306,3019,3022],{},[432,3020,3021],{},"DeepSeek Harness"," was used to implement the Buzz bridge. The implementation conforms to the following Nostr protocol specifications:",[3024,3025,3026,3052],"table",{},[3027,3028,3029],"thead",{},[3030,3031,3032,3038],"tr",{},[3033,3034,3035],"th",{},[432,3036,3037],{},"Transport",[3033,3039,3040,3041,3044,3045,3048,3049],{},"One NIP-42-authenticated WebSocket; default ",[522,3042,3043],{},"ws:\u002F\u002Flocalhost:3000","; ",[522,3046,3047],{},"http(s):\u002F\u002F"," is normalised to ",[522,3050,3051],{},"ws(s):\u002F\u002F",[3053,3054,3055,3074,3102,3120,3144,3167,3188,3202,3215,3231,3248,3262],"tbody",{},[3030,3056,3057,3063],{},[3058,3059,3060],"td",{},[432,3061,3062],{},"Auth",[3058,3064,3065,3066,3069,3070,3073],{},"AUTH event ",[522,3067,3068],{},"kind 22242",", tags ",[522,3071,3072],{},"[[\"relay\", url], [\"challenge\", challenge]]",", empty content, signed with the agent key",[3030,3075,3076,3081],{},[3058,3077,3078],{},[432,3079,3080],{},"Subscriptions",[3058,3082,3083,3000,3086,3089,3090,3093,3094,3097,3098,3101],{},[432,3084,3085],{},"Channel-scoped",[522,3087,3088],{},"REQ {\"kinds\":[9], \"#h\":[\u003Cuuid>]}"," — one REQ per channel. A global ",[522,3091,3092],{},"kinds:[9]"," REQ gets EOSE but never fans out; multi-value ",[522,3095,3096],{},"#h"," does ",[432,3099,3100],{},"not"," work",[3030,3103,3104,3109],{},[3058,3105,3106],{},[432,3107,3108],{},"Discovery",[3058,3110,3111,3112,3115,3116,3119],{},"Historical ",[522,3113,3114],{},"REQ {kinds:[39000]}"," for channel metadata (",[522,3117,3118],{},"type == \"dm\""," marks a DM channel)",[3030,3121,3122,3127],{},[3058,3123,3124],{},[432,3125,3126],{},"Membership",[3058,3128,3129,3130,3133,3134,3136,3137,3140,3141],{},"Live ",[522,3131,3132],{},"REQ {kinds:[44100,44101], \"#p\":[our pubkey], since: now-60s}"," — 44100 = added, 44101 = removed, each carrying ",[522,3135,428],{},"+",[522,3138,3139],{},"h","; membership changes update subscriptions ",[432,3142,3143],{},"without reconnect",[3030,3145,3146,3151],{},[3058,3147,3148],{},[432,3149,3150],{},"Chat events",[3058,3152,3153,3156,3157,3160,3161,2331,3164],{},[522,3154,3155],{},"kind 9"," with tags ",[522,3158,3159],{},"[\"h\", channel]",", optional ",[522,3162,3163],{},"[\"e\", replyTo]",[522,3165,3166],{},"[\"p\", mention]",[3030,3168,3169,3174],{},[3058,3170,3171],{},[432,3172,3173],{},"In-place edits",[3058,3175,3176,439,3179,2983,3181,3184,3185,3187],{},[522,3177,3178],{},"kind 40003",[522,3180,3139],{},[522,3182,3183],{},"e","→target; content replaces; 64 KB relay cap → keep payloads ≤ 60,000 B; oversized replies chunk — chunk 0 rides the edit, overflow chunks are appended as threaded kind-9 messages (",[522,3186,3183],{},"→thread root)",[3030,3189,3190,3195],{},[3058,3191,3192],{},[432,3193,3194],{},"CLOSED frames",[3058,3196,3197,3198,3201],{},"Pre-AUTH ",[522,3199,3200],{},"auth-required"," is normal bootstrap (finish AUTH, reopen subs); post-AUTH → bounded resubscribe (3 attempts, 0\u002F1\u002F2 s backoff); reconnect rebuilds everything",[3030,3203,3204,3209],{},[3058,3205,3206],{},[432,3207,3208],{},"Relay caps",[3058,3210,3211,3212],{},"≤ 2000 historical events per subscription, newest-first even with ",[522,3213,3214],{},"since",[3030,3216,3217,3222],{},[3058,3218,3219],{},[432,3220,3221],{},"Mention gating",[3058,3223,3224,3225,3227,3228,3230],{},"Act on inbound kind-9 only when (a) ",[522,3226,428],{},"-tag includes our pubkey, (b) channel is a DM, or (c) the ",[522,3229,3183],{}," root is our own event (thread follow). Ignore our own pubkey — loop prevention",[3030,3232,3233,3238],{},[3058,3234,3235],{},[432,3236,3237],{},"Outbound mentions",[3058,3239,3240,3241,3244,3245,3247],{},"Outbound text is published verbatim — the relay does not pre-check ",[522,3242,3243],{},"@"," tokens; ",[522,3246,428],{}," tags carry the inbound author + up to 7 other mentioned pubkeys (max 8)",[3030,3249,3250,3255],{},[3058,3251,3252],{},[432,3253,3254],{},"DMs",[3058,3256,3257,3258,3261],{},"Relay-scoped plaintext channels (",[522,3259,3260],{},"type: \"dm\""," metadata) — no NIP-04\u002F44 encryption in this bridge",[3030,3263,3264,3269],{},[3058,3265,3266],{},[432,3267,3268],{},"Attachments (inbound)",[3058,3270,3271,3272,2933,3275,2331,3278,2331,3281,3284],{},"NIP-92 ",[522,3273,3274],{},"imeta",[522,3276,3277],{},"url",[522,3279,3280],{},"sha256",[522,3282,3283],{},"m",") → plain http(s) download, verify SHA-256, 20 MB cap, max 4 per message; outbound images have no documented publish path → explicitly unsupported",[428,3286,3287],{},"The diagram below illustrates how the Buzz bridge bootstraps:",[514,3289],{"src":3290,"alt":3291},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-bootstrap.webp","Sequence diagram illustrating the Buzz bridge bootstrap and NIP-42 authentication process",[477,3293,3295],{"id":3294},"real-time-streaming-via-nostr-in-place-edits-kind-40003","Real-Time Streaming via Nostr In-Place Edits (Kind 40003)",[428,3297,3298,3299,3302],{},"Nostr has no native typing indicator, and events are append-only. To make replies feel responsive and alive, the Buzz bridge ",[432,3300,3301],{},"simulates streaming using in-place edits"," as shown below:",[514,3304],{"src":3305,"alt":3306},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-reply.webp","Diagram of in-place editing flow simulating live streaming responses with kind 40003 events",[482,3308,3309],{},[466,3310,3311],{},[3312,3313,3314,3315,3317,3318,3320],"em",{},"The Buzz bridge publishes a placeholder ",[522,3316,3155],{}," event, then progressively rewrites it with rate-limited ",[522,3319,3178],{}," in-place edits, before writing the final edit when the agent completes its run. This mirrors the \"send then edit\" pattern used by Telegram and Discord bridges.",[477,3322,3324],{"id":3323},"bridging-deepseek-harness-workspaces-via-chat-commands","Bridging DeepSeek Harness Workspaces via Chat Commands",[428,3326,3327,3328,3331,3332,2347],{},"The DSH \"Workspaces\" feature in the Web UI is backed by the ",[522,3329,3330],{},"workspaceRegistry"," service (",[522,3333,3334],{},"@deepseek-ai\u002Fdsh-workspace",[613,3336,3340],{"className":3337,"code":3338,"language":3339,"meta":423,"style":423},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const existing = await ctx.workspaceRegistry.resolveByPath(request.path);\n","typescript",[522,3341,3342],{"__ignoreMap":423},[621,3343,3344,3348,3351,3354,3358,3361,3363,3365,3367,3370,3373,3375,3378],{"class":623,"line":624},[621,3345,3347],{"class":3346},"spNyl","const",[621,3349,3350],{"class":769}," existing ",[621,3352,3353],{"class":693},"=",[621,3355,3357],{"class":3356},"s7zQu"," await",[621,3359,3360],{"class":769}," ctx",[621,3362,509],{"class":693},[621,3364,3330],{"class":769},[621,3366,509],{"class":693},[621,3368,3369],{"class":1567},"resolveByPath",[621,3371,3372],{"class":769},"(request",[621,3374,509],{"class":693},[621,3376,3377],{"class":769},"path)",[621,3379,3380],{"class":693},";\n",[428,3382,3383,3384,3387],{},"The Buzz bridge exposes a chat command, ",[522,3385,3386],{},"\u002Fworkspace \u003Cfolder>",", which registers an existing folder in DSH. Any new session through the gateway attaches to it and appears in the Web UI.",[514,3389],{"src":3390,"alt":3391},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace.webp","Architecture of DeepSeek Harness workspace registration from chat commands via gateway",[428,3393,3394],{},"Three design considerations to note:",[482,3396,3397,3407,3416],{},[466,3398,3399,3402,3403,3406],{},[432,3400,3401],{},"Switching folder = new session."," ",[522,3404,3405],{},"cwd"," is written into the session header at creation and cannot be mutated afterwards.",[466,3408,3409,3402,3412,3415],{},[432,3410,3411],{},"Folder must already exist.",[522,3413,3414],{},"create"," rejects non-existent paths.",[466,3417,3418,3421,3422,3425],{},[432,3419,3420],{},"Security-sensitive command."," Every session operates under an ",[432,3423,3424],{},"auto-approve"," policy, granting file access to the target folder.",[455,3427,3429],{"id":3428},"step-by-step-installation-configuration-guide","Step-by-Step Installation & Configuration Guide",[463,3431,3432],{},[466,3433,3434],{},"Run the following commands:",[613,3436,3438],{"className":615,"code":3437,"language":617,"meta":423,"style":423},"dsh plugin --profile web add https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway.git\n\n# Start DSH web\ndsh web\n",[522,3439,3440,3460,3464,3469],{"__ignoreMap":423},[621,3441,3442,3445,3448,3451,3454,3457],{"class":623,"line":624},[621,3443,3444],{"class":627},"dsh",[621,3446,3447],{"class":631}," plugin",[621,3449,3450],{"class":631}," --profile",[621,3452,3453],{"class":631}," web",[621,3455,3456],{"class":631}," add",[621,3458,3459],{"class":631}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway.git\n",[621,3461,3462],{"class":623,"line":641},[621,3463,645],{"emptyLinePlaceholder":644},[621,3465,3466],{"class":623,"line":648},[621,3467,3468],{"class":651},"# Start DSH web\n",[621,3470,3471,3473],{"class":623,"line":655},[621,3472,3444],{"class":627},[621,3474,3475],{"class":631}," web\n",[463,3477,3478],{"start":641},[466,3479,3480],{},"Once the DSH Web UI is opened in a web browser, click on the 'Message platforms' icon:",[428,3482,3483],{},[514,3484],{"alt":3485,"src":3486},"DeepSeek Harness Web UI sidebar highlighting the Message platforms configuration menu","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-message-platforms-sidebar-icon.webp",[463,3488,3489],{"start":648},[466,3490,3491],{},"Click on 'Buzz' on the left panel:",[428,3493,3494],{},[514,3495],{"alt":3496,"src":3497},"Buzz bridge configuration settings panel in DeepSeek Harness message gateway","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-message-gateway-buzz-config-panel.webp",[463,3499,3500,3507,3510],{"start":655},[466,3501,3502,3503,3506],{},"Click 'Generate keypair' to generate a Nostr key pair. Copy the ",[522,3504,3505],{},"npub"," public key somewhere safe, as you will need it later.",[466,3508,3509],{},"Enter the 'Relay URL' and 'Channels' (the allowlist of channel UUIDs to subscribe to).",[466,3511,3512],{},"Click the 'Save' button.",[428,3514,3515,3516,3519,3520,3523,3524,509],{},"Saving the form stores the credentials and ",[432,3517,3518],{},"starts the bridge",". The ",[522,3521,3522],{},"nsec"," private key is treated as a secret and stored exclusively in ",[522,3525,2924],{},[477,3527,3529],{"id":3528},"registering-the-dsh-assistant-keypair-on-the-buzz-nostr-relay","Registering the DSH Assistant Keypair on the Buzz Nostr Relay",[428,3531,3532,3535,3536,3538],{},[432,3533,3534],{},"Add the DSH assistant to the relay as a member."," The pubkey will be the ",[522,3537,3505],{}," generated above:",[613,3540,3542],{"className":615,"code":3541,"language":617,"meta":423,"style":423},"docker compose exec relay buzz-admin add-member --pubkey npub123123123\n",[522,3543,3544],{"__ignoreMap":423},[621,3545,3546,3548,3550,3553,3556,3559,3562,3565],{"class":623,"line":624},[621,3547,1732],{"class":627},[621,3549,1735],{"class":631},[621,3551,3552],{"class":631}," exec",[621,3554,3555],{"class":631}," relay",[621,3557,3558],{"class":631}," buzz-admin",[621,3560,3561],{"class":631}," add-member",[621,3563,3564],{"class":631}," --pubkey",[621,3566,3567],{"class":631}," npub123123123\n",[428,3569,3570,3573,3574,3577,3578,3581,3582,3585,3586,3589],{},[432,3571,3572],{},"Add the DSH assistant to a channel."," Adding a member registers it on the relay, but the member will not yet appear or be searchable within channels. To add the agent to a specific channel using ",[522,3575,3576],{},"buzz-cli",", note that the ",[522,3579,3580],{},"--pubkey"," parameter must be in ",[432,3583,3584],{},"HEX"," format, not npub (the ",[522,3587,3588],{},"buzz-admin add-member"," command prints the member's HEX pubkey).",[613,3591,3593],{"className":615,"code":3592,"language":617,"meta":423,"style":423},"buzz channels add-member --channel \u003CCHANNEL_UUID> --pubkey \u003CAGENT_HEX> --role member\n",[522,3594,3595],{"__ignoreMap":423},[621,3596,3597,3600,3603,3605,3608,3611,3614,3617,3620,3622,3624,3627,3630,3632,3635],{"class":623,"line":624},[621,3598,3599],{"class":627},"buzz",[621,3601,3602],{"class":631}," channels",[621,3604,3561],{"class":631},[621,3606,3607],{"class":631}," --channel",[621,3609,3610],{"class":693}," \u003C",[621,3612,3613],{"class":631},"CHANNEL_UUI",[621,3615,3616],{"class":769},"D",[621,3618,3619],{"class":693},">",[621,3621,3564],{"class":631},[621,3623,3610],{"class":693},[621,3625,3626],{"class":631},"AGENT_HE",[621,3628,3629],{"class":769},"X",[621,3631,3619],{"class":693},[621,3633,3634],{"class":631}," --role",[621,3636,3637],{"class":631}," member\n",[1459,3639],{"description":3640,"image":1646,"image-alt":3641,"label":3642,"min-read":3643,"title":3644,"to":3645},"Step-by-step instructions to install and configure buzz-cli for managing Nostr channels, member keys, and AI agent permissions.","Configuring buzz-cli commands to manage Nostr channel members and agent roles","CLI guide","5","How to Install and Use buzz-cli","\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#install-buzz-cli",[428,3647,3648,3649,969],{},"Update the DSH assistant's profile on the Nostr relay to a more meaningful display name using ",[522,3650,3576],{},[428,3652,3653],{},[514,3654],{"alt":3655,"src":3656},"Updating the DeepSeek Harness assistant display name on Nostr relay using buzz-cli","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-assistant-buzz-cli-profile-update.webp",[428,3658,3659,3660,3663],{},"Send a ",[432,3661,3662],{},"Wave"," (Buzz's DM greeting) to the DSH assistant. The wave comes back:",[428,3665,3666],{},[514,3667],{"alt":3668,"src":3669},"Testing connection by sending a Wave DM to DeepSeek Harness assistant in Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-dm-wave-greeting-reply.webp",[428,3671,3672],{},[3312,3673,3674],{},"Sending a Wave as a DM to the DSH assistant — the bridge is alive.",[477,3676,3678,3679],{"id":3677},"enabling-workspace","Enabling ",[522,3680,3681],{},"\u002Fworkspace",[428,3683,3684,3685,3688,3689,3692,3693,3695],{},"Because the ",[522,3686,3687],{},"allowWorkspace"," setting defaults to ",[522,3690,3691],{},"false",", issuing the ",[522,3694,3681],{}," command is initially rejected:",[428,3697,3698],{},[514,3699],{"alt":3700,"src":3701},"Error notification showing workspace command rejected when allowWorkspace is disabled","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-rejected-error.webp",[428,3703,3704,3705,3708,3709,969],{},"Enable it in ",[522,3706,3707],{},"~\u002F.dsh\u002Fprofiles\u002Fweb\u002Fcordis.patch.yml",", then restart ",[522,3710,3011],{},[613,3712,3714],{"className":1996,"code":3713,"language":1998,"meta":423,"style":423},"- id: ui-message-gateway\n  config:\n    allowWorkspace: true\n",[522,3715,3716,3729,3736],{"__ignoreMap":423},[621,3717,3718,3721,3724,3726],{"class":623,"line":624},[621,3719,3720],{"class":693},"-",[621,3722,3723],{"class":957}," id",[621,3725,969],{"class":693},[621,3727,3728],{"class":631}," ui-message-gateway\n",[621,3730,3731,3734],{"class":623,"line":641},[621,3732,3733],{"class":957},"  config",[621,3735,961],{"class":693},[621,3737,3738,3741,3743],{"class":623,"line":648},[621,3739,3740],{"class":957},"    allowWorkspace",[621,3742,969],{"class":693},[621,3744,3745],{"class":982}," true\n",[428,3747,3748],{},"After the restart:",[428,3750,3751],{},[514,3752],{"alt":3753,"src":3754},"Successful confirmation message after executing workspace registration command in Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-success-confirmation.webp",[428,3756,3757,3758,3761],{},"One gotcha: this assumes the workspace folder (",[522,3759,3760],{},"TechVoyage"," in the screenshots) lives in the default user directory. Specify a full path otherwise. Any new session registered under this workspace via Buzz also appears in the DeepSeek Harness Web UI.",[428,3763,3764],{},[514,3765],{"alt":3766,"src":3767},"DeepSeek Harness Web UI displaying the active workspace session synchronized from Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-synced-workspace-session.webp",[477,3769,3771],{"id":3770},"available-commands","Available Commands",[428,3773,3774],{},"Everything that other supported platforms offer works seamlessly on Buzz:",[3024,3776,3777,3787],{},[3027,3778,3779],{},[3030,3780,3781,3784],{},[3033,3782,3783],{},"Command",[3033,3785,3786],{},"What it does",[3053,3788,3789,3798,3808,3818,3828,3838,3848,3858,3868,3888,3908],{},[3030,3790,3791,3795],{},[3058,3792,3793],{},[522,3794,3386],{},[3058,3796,3797],{},"Register an existing folder as the chat's workspace (config-gated)",[3030,3799,3800,3805],{},[3058,3801,3802],{},[522,3803,3804],{},"\u002Fhelp",[3058,3806,3807],{},"List available commands",[3030,3809,3810,3815],{},[3058,3811,3812],{},[522,3813,3814],{},"\u002Ftime",[3058,3816,3817],{},"Current time",[3030,3819,3820,3825],{},[3058,3821,3822],{},[522,3823,3824],{},"\u002Fnew",[3058,3826,3827],{},"Start a fresh session",[3030,3829,3830,3835],{},[3058,3831,3832],{},[522,3833,3834],{},"\u002Fclear",[3058,3836,3837],{},"Clear the conversation",[3030,3839,3840,3845],{},[3058,3841,3842],{},[522,3843,3844],{},"\u002Fstatus",[3058,3846,3847],{},"Bridge status",[3030,3849,3850,3855],{},[3058,3851,3852],{},[522,3853,3854],{},"\u002Fstats",[3058,3856,3857],{},"Chat count + per-bridge status lines (all platforms, incl. Buzz)",[3030,3859,3860,3865],{},[3058,3861,3862],{},[522,3863,3864],{},"\u002Fcommands",[3058,3866,3867],{},"Every command descriptor",[3030,3869,3870,3875],{},[3058,3871,3872],{},[522,3873,3874],{},"@path\u002Fto\u002Ffile",[3058,3876,3877,3878,2331,3880,3883,3884,3887],{},"Works exactly like Web @ mentions — the model reads the file relative to the chat's workspace; a bare ",[522,3879,3243],{},[522,3881,3882],{},"@prefix",", or ",[522,3885,3886],{},"\u002Ffiles \u003Cprefix>"," replies with matching files\u002Ffolders from the same discovery source",[3030,3889,3890,3895],{},[3058,3891,3892],{},[522,3893,3894],{},"\u002Fmodel",[3058,3896,3897,3900,3901,3903,3904,3907],{},[522,3898,3899],{},"[provider model effort]"," — validated against the live LLM catalog, switches that chat's model + effort; ",[522,3902,3894],{}," alone lists options, ",[522,3905,3906],{},"\u002Fmodel reset"," restores defaults",[3030,3909,3910,3915],{},[3058,3911,3912],{},[522,3913,3914],{},"\u002Feffort",[3058,3916,3917,3920,3921,3924],{},[522,3918,3919],{},"\u003Cid>"," adjusts reasoning effort only; ",[522,3922,3923],{},"\u002Feffort reset"," restores the default",[477,3926,3928],{"id":3927},"security-in-snapshot","Security in Snapshot",[482,3930,3931,3943,3953],{},[466,3932,2306,3933,3935,3936,3938,3939,3942],{},[432,3934,3522],{}," lives only in ",[522,3937,2924],{}," (0600, atomic write) — never in ",[522,3940,3941],{},"\u002Fgateway\u002Flist",", never in logs.",[466,3944,3945,3946,2933,3949,3952],{},"Every inbound event is ",[432,3947,3948],{},"signature-verified",[522,3950,3951],{},"verifyEvent","), deduplicated, self-filtered, and mention-gated before it reaches the agent.",[466,3954,3955,2933,3958,3961],{},[432,3956,3957],{},"Workspace registration is config-gated",[522,3959,3960],{},"allowWorkspace: false"," by default) since gateway sessions auto-approve.",[455,3963,3965],{"id":3964},"key-takeaways","Key Takeaways",[428,3967,3968,3969,3971],{},"The harder part of adding Buzz to ",[522,3970,2880],{}," was fulfilling the Nostr protocol contract. The existing plugin already provided a architectural foundation for per-chat sessions and command routing, making the bridge integration straightforward.",[455,3973,3974],{"id":2790},"References:",[482,3976,3977,3985,3993],{},[466,3978,3979,3984],{},[448,3980,3983],{"href":3981,"rel":3982},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway\u002Fblob\u002Fmain\u002Fdocs\u002Farchitecture.md",[507],"dsh-message-gateway architecture guide"," — extension recipe, module map, security notes (bridges default to hidden)",[466,3986,3987,3992],{},[448,3988,3991],{"href":3989,"rel":3990},"https:\u002F\u002Fgithub.com\u002Fnbd-wtf\u002Fnostr-tools",[507],"nostr-tools"," — the Nostr library used under the hood",[466,3994,3995,4000],{},[448,3996,3999],{"href":3997,"rel":3998},"https:\u002F\u002Fgithub.com\u002Fbytedance\u002Fdeer-flow\u002Fblob\u002Fmain\u002Fbackend\u002Fdocs\u002FIM_CHANNEL_CONNECTIONS.md",[507],"deer-flow IM channel connections"," — reference for IM channel connection patterns",[1331,4002,4003],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":423,"searchDepth":641,"depth":648,"links":4005},[4006,4007,4011,4018,4019],{"id":2902,"depth":641,"text":2903},{"id":3015,"depth":641,"text":3016,"children":4008},[4009,4010],{"id":3294,"depth":648,"text":3295},{"id":3323,"depth":648,"text":3324},{"id":3428,"depth":641,"text":3429,"children":4012},[4013,4014,4016,4017],{"id":3528,"depth":648,"text":3529},{"id":3677,"depth":648,"text":4015},"Enabling \u002Fworkspace",{"id":3770,"depth":648,"text":3771},{"id":3927,"depth":648,"text":3928},{"id":3964,"depth":641,"text":3965},{"id":2790,"depth":641,"text":3974},[1353,4021,3599,4022],"collaboration","deepseek-harness","2026-09-30","Integrate DeepSeek Harness with Block Buzz using a Nostr bridge. Configure NIP-42 auth, in-place message streaming, and per-channel agent workspaces.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002FEN-Bringing-Buzz-to-DeepSeek-Harness.webp","A premium 16:9 technology card with deep indigo and amber accents illustrating how to connect DeepSeek Harness to Block Buzz via a Nostr gateway, featuring a clean glassmorphic panel with centered typography.",{"schemaOrg":4028,"robots":1394,"sitemap":4051},[4029,4031],{"@type":4030,"headline":354,"description":4024,"image":4025},"TechArticle",{"@type":1363,"name":354,"description":4024,"image":4025,"step":4032},[4033,4036,4039,4042,4045,4048],{"@type":1366,"name":4034,"text":4035},"Phase 1: Install Gateway Plugin","Install the dsh-message-gateway plugin and start the DSH web service.",{"@type":1366,"name":4037,"text":4038},"Phase 2: Access Message Platforms","Open the DSH Web UI and navigate to Message platforms settings.",{"@type":1366,"name":4040,"text":4041},"Phase 3: Configure Buzz Bridge","Generate a Nostr keypair, enter the Relay URL, and set channel subscriptions.",{"@type":1366,"name":4043,"text":4044},"Phase 4: Register Agent on Relay","Add the DSH assistant to the Buzz Nostr relay using buzz-admin.",{"@type":1366,"name":4046,"text":4047},"Phase 5: Assign Agent to Channel","Add the assistant HEX pubkey to designated channels using buzz-cli.",{"@type":1366,"name":4049,"text":4050},"Phase 6: Enable Workspace Access","Configure allowWorkspace in cordis.patch.yml to enable local folder commands.",{"lastmod":4023},{"title":4053,"description":4024,"ogTitle":354,"ogDescription":4024,"twitterTitle":354,"twitterDescription":4024},"DeepSeek Harness Buzz Plugin: Build a Nostr Bridge",[3021,2886,4055,4056,2880],"Nostr","AI Agents","3ILGY8-EUYBkB7RoFM4yH49qiefLt3OYDlH5S748n_g",[4059,4603,5233],{"id":4060,"title":398,"author":423,"body":4061,"category":4588,"date":4590,"description":4591,"extension":1357,"image":4592,"imageAlt":4593,"isPublished":644,"meta":4594,"minRead":655,"navigation":644,"path":399,"seo":4598,"stem":400,"tags":4599,"updatedAt":2859,"__hash__":4602},"article\u002Fen\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac.md",{"type":425,"value":4062,"toc":4581},[4063,4067,4070,4077,4081,4087,4090,4093,4097,4100,4107,4123,4429,4541,4543,4546,4548,4578],[455,4064,4066],{"id":4065},"what-is-cloudflare-warp","What Is Cloudflare WARP?",[428,4068,4069],{},"Cloudflare WARP is a client-side application that routes specified device traffic through Cloudflare's global network instead of directly out to the public internet.",[428,4071,4072,4073,4076],{},"It creates an encrypted tunnel built on the ",[432,4074,4075],{},"WireGuard"," protocol, securing traffic from the device to the nearest Cloudflare data center. Policies can then be created in your Cloudflare dashboard to filter, log, inspect, or route this incoming traffic.",[455,4078,4080],{"id":4079},"why-do-we-need-cloudflare-warp","Why Do We Need Cloudflare WARP?",[428,4082,4083,4084,509],{},"To securely expose internal resources—such as private web services or SaaS applications—to employees, contractors, and other stakeholders, the Cloudflare WARP client is the as the client-side enforcement point for ",[432,4085,4086],{},"Zero Trust Network Access (ZTNA)",[428,4088,4089],{},"The Cloudflare WARP client is installed on a user’s laptop or phone. It requires users to authenticate and meet specific security posture checks (such as coming from an approved IP range, using a registered email domain, or running an active firewall) before granting access.",[428,4091,4092],{},"By tunneling device traffic directly to Cloudflare, the user's identity, device, and policies are verified before requests ever reach internal resources. As a result, internal resources are never exposed to the public internet, and every single request is fully logged and audited.",[455,4094,4096],{"id":4095},"supporting-multiple-warp-profiles-on-one-device","Supporting Multiple WARP Profiles on One Device",[428,4098,4099],{},"When users need to switch between personal and corporate Cloudflare accounts, or when system administrators manage multiple tenants, supporting multiple WARP profiles on a single device becomes crucial.",[428,4101,4102,4103,4106],{},"To achieve this on macOS, we can use a ",[522,4104,4105],{},".mobileconfig"," MDM profile file to define and register the different WARP environments.",[482,4108,4109,4120],{},[466,4110,4111,4119],{},[448,4112,4115,4116,4118],{"href":4113,"rel":4114},"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcloudflare-one\u002Fstatic\u002Fmdm\u002Fmultiple-orgs\u002FCloudflareWARP.mobileconfig",[507],"Download a sample ",[522,4117,4105],{}," file"," directly from Cloudflare.",[466,4121,4122],{},"Below is an example of what this configuration looks like:",[613,4124,4128],{"className":4125,"code":4126,"language":4127,"meta":423,"style":423},"language-xml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003C!DOCTYPE plist PUBLIC \"-\u002F\u002FApple\u002F\u002FDTD PLIST 1.0\u002F\u002FEN\" \"http:\u002F\u002Fwww.apple.com\u002FDTDs\u002FPropertyList-1.0.dtd\">\n\u003Cplist version=\"1.0\">\n\u003Cdict>\n  \u003Ckey>PayloadContent\u003C\u002Fkey>\n  \u003Carray>\n    \u003Cdict>\n      \u003Ckey>PayloadDisplayName\u003C\u002Fkey>\n      \u003Cstring>Warp Configuration\u003C\u002Fstring>\n      \u003Ckey>PayloadIdentifier\u003C\u002Fkey>\n      \u003Cstring>com.cloudflare.warp.CB8B22D4-50E1-48E8-8874-A7594627013A\u003C\u002Fstring>\n      \u003Ckey>PayloadOrganization\u003C\u002Fkey>\n      \u003Cstring>Cloudflare Ltd.\u003C\u002Fstring>\n      \u003Ckey>PayloadType\u003C\u002Fkey>\n      \u003Cstring>com.cloudflare.warp\u003C\u002Fstring>\n      \u003Ckey>PayloadUUID\u003C\u002Fkey>\n      \u003Cstring>CB8B22D4-50E1-48E8-8874-A7594627013A\u003C\u002Fstring>\n      \u003Ckey>PayloadVersion\u003C\u002Fkey>\n      \u003Cinteger>1\u003C\u002Finteger>\n      \u003Ckey>configs\u003C\u002Fkey>\n      \u003Carray>\n        \u003Cdict>\n          \u003Ckey>organization\u003C\u002Fkey>\n          \u003Cstring>your-team-name-1\u003C\u002Fstring>\n          \u003Ckey>display_name\u003C\u002Fkey>\n          \u003Cstring>Team 1\u003C\u002Fstring>\n        \u003C\u002Fdict>\n        \u003Cdict>\n          \u003Ckey>organization\u003C\u002Fkey>\n          \u003Cstring>your-team-name-2\u003C\u002Fstring>\n          \u003Ckey>display_name\u003C\u002Fkey>\n          \u003Cstring>Team 2\u003C\u002Fstring>\n        \u003C\u002Fdict>\n      \u003C\u002Farray>\n    \u003C\u002Fdict>\n  \u003C\u002Farray>\n  \u003Ckey>PayloadDisplayName\u003C\u002Fkey>\n  \u003Cstring>Cloudflare WARP\u003C\u002Fstring>\n  \u003Ckey>PayloadIdentifier\u003C\u002Fkey>\n  \u003Cstring>cloudflare_warp\u003C\u002Fstring>\n  \u003Ckey>PayloadOrganization\u003C\u002Fkey>\n  \u003Cstring>Cloudflare, Ltd.\u003C\u002Fstring>\n  \u003Ckey>PayloadRemovalDisallowed\u003C\u002Fkey>\n  \u003Cfalse\u002F>\n  \u003Ckey>PayloadScope\u003C\u002Fkey>\n  \u003Cstring>System\u003C\u002Fstring>\n  \u003Ckey>PayloadType\u003C\u002Fkey>\n  \u003Cstring>Configuration\u003C\u002Fstring>\n  \u003Ckey>PayloadUUID\u003C\u002Fkey>\n  \u003Cstring>2B7763B8-64F6-41EB-AA5E-7761651B8131\u003C\u002Fstring>\n  \u003Ckey>PayloadVersion\u003C\u002Fkey>\n  \u003Cinteger>1\u003C\u002Finteger>\n\u003C\u002Fdict>\n\u003C\u002Fplist>\n","xml",[522,4129,4130,4135,4140,4145,4150,4155,4160,4165,4170,4175,4180,4185,4190,4195,4200,4205,4210,4215,4220,4225,4230,4235,4241,4247,4253,4259,4265,4271,4276,4281,4287,4292,4298,4303,4309,4315,4321,4327,4333,4339,4345,4351,4357,4363,4369,4375,4381,4387,4393,4399,4405,4411,4417,4423],{"__ignoreMap":423},[621,4131,4132],{"class":623,"line":624},[621,4133,4134],{},"\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",[621,4136,4137],{"class":623,"line":641},[621,4138,4139],{},"\u003C!DOCTYPE plist PUBLIC \"-\u002F\u002FApple\u002F\u002FDTD PLIST 1.0\u002F\u002FEN\" \"http:\u002F\u002Fwww.apple.com\u002FDTDs\u002FPropertyList-1.0.dtd\">\n",[621,4141,4142],{"class":623,"line":648},[621,4143,4144],{},"\u003Cplist version=\"1.0\">\n",[621,4146,4147],{"class":623,"line":655},[621,4148,4149],{},"\u003Cdict>\n",[621,4151,4152],{"class":623,"line":667},[621,4153,4154],{},"  \u003Ckey>PayloadContent\u003C\u002Fkey>\n",[621,4156,4157],{"class":623,"line":672},[621,4158,4159],{},"  \u003Carray>\n",[621,4161,4162],{"class":623,"line":678},[621,4163,4164],{},"    \u003Cdict>\n",[621,4166,4167],{"class":623,"line":1020},[621,4168,4169],{},"      \u003Ckey>PayloadDisplayName\u003C\u002Fkey>\n",[621,4171,4172],{"class":623,"line":1031},[621,4173,4174],{},"      \u003Cstring>Warp Configuration\u003C\u002Fstring>\n",[621,4176,4177],{"class":623,"line":1127},[621,4178,4179],{},"      \u003Ckey>PayloadIdentifier\u003C\u002Fkey>\n",[621,4181,4182],{"class":623,"line":1133},[621,4183,4184],{},"      \u003Cstring>com.cloudflare.warp.CB8B22D4-50E1-48E8-8874-A7594627013A\u003C\u002Fstring>\n",[621,4186,4187],{"class":623,"line":1139},[621,4188,4189],{},"      \u003Ckey>PayloadOrganization\u003C\u002Fkey>\n",[621,4191,4192],{"class":623,"line":1144},[621,4193,4194],{},"      \u003Cstring>Cloudflare Ltd.\u003C\u002Fstring>\n",[621,4196,4197],{"class":623,"line":1150},[621,4198,4199],{},"      \u003Ckey>PayloadType\u003C\u002Fkey>\n",[621,4201,4202],{"class":623,"line":2108},[621,4203,4204],{},"      \u003Cstring>com.cloudflare.warp\u003C\u002Fstring>\n",[621,4206,4207],{"class":623,"line":2119},[621,4208,4209],{},"      \u003Ckey>PayloadUUID\u003C\u002Fkey>\n",[621,4211,4212],{"class":623,"line":2124},[621,4213,4214],{},"      \u003Cstring>CB8B22D4-50E1-48E8-8874-A7594627013A\u003C\u002Fstring>\n",[621,4216,4217],{"class":623,"line":2132},[621,4218,4219],{},"      \u003Ckey>PayloadVersion\u003C\u002Fkey>\n",[621,4221,4222],{"class":623,"line":2665},[621,4223,4224],{},"      \u003Cinteger>1\u003C\u002Finteger>\n",[621,4226,4227],{"class":623,"line":2671},[621,4228,4229],{},"      \u003Ckey>configs\u003C\u002Fkey>\n",[621,4231,4232],{"class":623,"line":2680},[621,4233,4234],{},"      \u003Carray>\n",[621,4236,4238],{"class":623,"line":4237},22,[621,4239,4240],{},"        \u003Cdict>\n",[621,4242,4244],{"class":623,"line":4243},23,[621,4245,4246],{},"          \u003Ckey>organization\u003C\u002Fkey>\n",[621,4248,4250],{"class":623,"line":4249},24,[621,4251,4252],{},"          \u003Cstring>your-team-name-1\u003C\u002Fstring>\n",[621,4254,4256],{"class":623,"line":4255},25,[621,4257,4258],{},"          \u003Ckey>display_name\u003C\u002Fkey>\n",[621,4260,4262],{"class":623,"line":4261},26,[621,4263,4264],{},"          \u003Cstring>Team 1\u003C\u002Fstring>\n",[621,4266,4268],{"class":623,"line":4267},27,[621,4269,4270],{},"        \u003C\u002Fdict>\n",[621,4272,4274],{"class":623,"line":4273},28,[621,4275,4240],{},[621,4277,4279],{"class":623,"line":4278},29,[621,4280,4246],{},[621,4282,4284],{"class":623,"line":4283},30,[621,4285,4286],{},"          \u003Cstring>your-team-name-2\u003C\u002Fstring>\n",[621,4288,4290],{"class":623,"line":4289},31,[621,4291,4258],{},[621,4293,4295],{"class":623,"line":4294},32,[621,4296,4297],{},"          \u003Cstring>Team 2\u003C\u002Fstring>\n",[621,4299,4301],{"class":623,"line":4300},33,[621,4302,4270],{},[621,4304,4306],{"class":623,"line":4305},34,[621,4307,4308],{},"      \u003C\u002Farray>\n",[621,4310,4312],{"class":623,"line":4311},35,[621,4313,4314],{},"    \u003C\u002Fdict>\n",[621,4316,4318],{"class":623,"line":4317},36,[621,4319,4320],{},"  \u003C\u002Farray>\n",[621,4322,4324],{"class":623,"line":4323},37,[621,4325,4326],{},"  \u003Ckey>PayloadDisplayName\u003C\u002Fkey>\n",[621,4328,4330],{"class":623,"line":4329},38,[621,4331,4332],{},"  \u003Cstring>Cloudflare WARP\u003C\u002Fstring>\n",[621,4334,4336],{"class":623,"line":4335},39,[621,4337,4338],{},"  \u003Ckey>PayloadIdentifier\u003C\u002Fkey>\n",[621,4340,4342],{"class":623,"line":4341},40,[621,4343,4344],{},"  \u003Cstring>cloudflare_warp\u003C\u002Fstring>\n",[621,4346,4348],{"class":623,"line":4347},41,[621,4349,4350],{},"  \u003Ckey>PayloadOrganization\u003C\u002Fkey>\n",[621,4352,4354],{"class":623,"line":4353},42,[621,4355,4356],{},"  \u003Cstring>Cloudflare, Ltd.\u003C\u002Fstring>\n",[621,4358,4360],{"class":623,"line":4359},43,[621,4361,4362],{},"  \u003Ckey>PayloadRemovalDisallowed\u003C\u002Fkey>\n",[621,4364,4366],{"class":623,"line":4365},44,[621,4367,4368],{},"  \u003Cfalse\u002F>\n",[621,4370,4372],{"class":623,"line":4371},45,[621,4373,4374],{},"  \u003Ckey>PayloadScope\u003C\u002Fkey>\n",[621,4376,4378],{"class":623,"line":4377},46,[621,4379,4380],{},"  \u003Cstring>System\u003C\u002Fstring>\n",[621,4382,4384],{"class":623,"line":4383},47,[621,4385,4386],{},"  \u003Ckey>PayloadType\u003C\u002Fkey>\n",[621,4388,4390],{"class":623,"line":4389},48,[621,4391,4392],{},"  \u003Cstring>Configuration\u003C\u002Fstring>\n",[621,4394,4396],{"class":623,"line":4395},49,[621,4397,4398],{},"  \u003Ckey>PayloadUUID\u003C\u002Fkey>\n",[621,4400,4402],{"class":623,"line":4401},50,[621,4403,4404],{},"  \u003Cstring>2B7763B8-64F6-41EB-AA5E-7761651B8131\u003C\u002Fstring>\n",[621,4406,4408],{"class":623,"line":4407},51,[621,4409,4410],{},"  \u003Ckey>PayloadVersion\u003C\u002Fkey>\n",[621,4412,4414],{"class":623,"line":4413},52,[621,4415,4416],{},"  \u003Cinteger>1\u003C\u002Finteger>\n",[621,4418,4420],{"class":623,"line":4419},53,[621,4421,4422],{},"\u003C\u002Fdict>\n",[621,4424,4426],{"class":623,"line":4425},54,[621,4427,4428],{},"\u003C\u002Fplist>\n",[482,4430,4431,4441,4455,4465,4470,4486,4499,4516,4532],{},[466,4432,4433,4434,563,4437,4440],{},"Replace ",[522,4435,4436],{},"your-team-name-1",[522,4438,4439],{},"your-team-name-2"," with your respective Cloudflare Zero Trust team names.",[466,4442,4443,4444,4447,4448,4451,4452,4454],{},"Run the command ",[522,4445,4446],{},"uuidgen"," in your Terminal to generate unique UUIDs, and use them to replace the placeholder ",[522,4449,4450],{},"PayloadUUID"," values in the ",[522,4453,4105],{}," file.",[466,4456,4457,4458,4461,4462,4464],{},"Make sure that the ",[522,4459,4460],{},"PayloadIdentifier"," string also contains the updated ",[522,4463,4450],{}," to keep the profile distinct.",[466,4466,4467,4468,4454],{},"Save your edited ",[522,4469,4105],{},[466,4471,2695,4472,4475,4476,4479,4480,4482],{},[432,4473,4474],{},"System Settings"," on your Mac, search for ",[432,4477,4478],{},"Profiles",", and select it.",[609,4481],{},[514,4483],{"alt":4484,"src":4485},"macOS System Settings Profiles pane","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSwitch%20Between%20Multiple%20Cloudflare%20WARP%20Orgs%20on%20Mac\u002Fmacos-system-settings-profiles.webp",[466,4487,4488,4489,4492,4493,4495],{},"Click on ",[432,4490,4491],{},"Install, view or remove..."," to begin adding your new configuration profile.",[609,4494],{},[514,4496],{"alt":4497,"src":4498},"macOS Profiles install view or remove button","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSwitch%20Between%20Multiple%20Cloudflare%20WARP%20Orgs%20on%20Mac\u002Fmacos-profiles-view-remove.webp",[466,4500,1823,4501,4503,4504,4454,4506,4508,4512],{},[432,4502,3136],{}," (plus) icon in the bottom-left corner and select your saved ",[522,4505,4105],{},[609,4507],{},[514,4509],{"alt":4510,"src":4511},"macOS Profiles plus button to add a new profile","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSwitch%20Between%20Multiple%20Cloudflare%20WARP%20Orgs%20on%20Mac\u002Fmacos-profiles-add-profile.webp",[514,4513],{"alt":4514,"src":4515},"Selecting the mobileconfig file on macOS","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSwitch%20Between%20Multiple%20Cloudflare%20WARP%20Orgs%20on%20Mac\u002Fmacos-select-mobileconfig-file.webp",[466,4517,4518,4519,4521,4522,4525,4526,4528],{},"Select ",[432,4520,438],{}," and click ",[432,4523,4524],{},"Install"," to apply the configuration.",[609,4527],{},[514,4529],{"alt":4530,"src":4531},"Confirming Cloudflare WARP profile installation on macOS","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSwitch%20Between%20Multiple%20Cloudflare%20WARP%20Orgs%20on%20Mac\u002Fmacos-install-cloudflare-warp-profile.webp",[466,4533,4534,4535,4537],{},"Restart your Cloudflare WARP client. You should now see the multi-profile switcher in the user interface:",[609,4536],{},[514,4538],{"alt":4539,"src":4540},"Cloudflare WARP client with multi-profile switcher on macOS","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSwitch%20Between%20Multiple%20Cloudflare%20WARP%20Orgs%20on%20Mac\u002Fcloudflare-warp-multi-profile-switcher.webp",[455,4542,1319],{"id":1318},[428,4544,4545],{},"The Cloudflare WARP client acts as a critical security point on user devices, making Zero Trust Network Access both robust and highly practical. Keeping internal resources isolated from the public internet ensures that every connection attempt is securely authenticated, evaluated, and audited.",[455,4547,2791],{"id":2790},[482,4549,4550,4557,4564,4571],{},[466,4551,4552],{},[448,4553,4556],{"href":4554,"rel":4555},"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcloudflare-one\u002Fteam-and-resources\u002Fdevices\u002Fcloudflare-one-client\u002Fdeployment\u002Fmdm-deployment\u002F#prepare-file-for-mdm-deployment",[507],"Managed Deployment Preparation",[466,4558,4559],{},[448,4560,4563],{"href":4561,"rel":4562},"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcloudflare-one\u002Fteam-and-resources\u002Fdevices\u002Fcloudflare-one-client\u002Fdeployment\u002Fmdm-deployment\u002Fswitch-organizations\u002F",[507],"Switch Between Zero Trust Organizations",[466,4565,4566],{},[448,4567,4570],{"href":4568,"rel":4569},"https:\u002F\u002Fblog.cloudflare.com\u002Fintroducing-warp-connector-paving-the-path-to-any-to-any-connectivity-2\u002F",[507],"Introducing WARP Connector: Paving the Path to Any-to-Any Connectivity",[466,4572,4573],{},[448,4574,4577],{"href":4575,"rel":4576},"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcloudflare-one\u002Fteam-and-resources\u002Fdevices\u002Fcloudflare-one-client\u002F",[507],"Cloudflare One Client Documentation",[1331,4579,4580],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":423,"searchDepth":641,"depth":648,"links":4582},[4583,4584,4585,4586,4587],{"id":4065,"depth":641,"text":4066},{"id":4079,"depth":641,"text":4080},{"id":4095,"depth":641,"text":4096},{"id":1318,"depth":641,"text":1319},{"id":2790,"depth":641,"text":2791},[1354,4589],"cloudflare","2026-07-04","Configure and switch multiple Cloudflare WARP organisations on macOS using a .mobileconfig file. A complete MDM guide for IT admins.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSwitch%20Between%20Multiple%20Cloudflare%20WARP%20Orgs%20on%20Mac\u002FEN-Switch-Between-Multiple-Cloudflare-WARP-Orgs-on-Mac.webp","Configure Multiple Cloudflare WARP Profiles on macOS",{"schemaOrg":4595,"robots":1394,"sitemap":4597},[4596],{"@type":1363,"headline":398,"description":4591},{"lastmod":4590},{"title":4593,"description":4591,"ogTitle":398,"ogDescription":4591,"twitterTitle":398,"twitterDescription":4591},[4600,438,4601,1400],"macOS","MDM","1b-JmgD0tsBcQooHgG1MNPYYvTAdh8f83JMRp2OWhJ8",{"id":4604,"title":374,"author":423,"body":4605,"category":5206,"date":5207,"description":5208,"extension":1357,"image":5209,"imageAlt":5210,"isPublished":644,"meta":5211,"minRead":667,"navigation":644,"path":375,"seo":5225,"stem":376,"tags":5227,"updatedAt":2859,"__hash__":5232},"article\u002Fen\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server.md",{"type":425,"value":4606,"toc":5195},[4607,4611,4614,4617,4621,4625,4628,4641,4647,4650,4679,4686,4713,4720,4725,4739,4751,4759,4764,4780,4784,4787,4808,4814,4817,4828,4838,4849,4880,4884,4894,4903,4914,4924,4931,4941,4947,4974,4990,4994,5000,5012,5017,5051,5055,5058,5072,5078,5141,5143,5187,5189,5192],[455,4608,4610],{"id":4609},"why-host-hermes-agent-on-a-remote-vps","Why Host Hermes Agent on a Remote VPS?",[428,4612,4613],{},"Since the Hermes Agent is capable of running background tasks, scheduling tasks, and responding to webhook calls, we need a machine to be on standby 24\u002F7. Local machines can lose power, get disconnected from Internet or having the resources maxed out. A remote server guarantees 99% uptime and makes it easy to scale computation resources when needed.",[428,4615,4616],{},"There are several affordable virtual private server(VPS)) providers out there such as Hetzner, Hostinger and Contabo. We have been using Contabo for a while, and so far so good.",[455,4618,4620],{"id":4619},"how-to-set-up-hermes-agent-on-a-linux-vps","How to Set Up Hermes Agent on a Linux VPS",[477,4622,4624],{"id":4623},"step-1-connect-to-your-vps","Step 1: Connect to Your VPS",[428,4626,4627],{},"Open the terminal and SSH into your remote machine:",[613,4629,4631],{"className":615,"code":4630,"language":617,"meta":423,"style":423},"ssh root@your_server_ip\n",[522,4632,4633],{"__ignoreMap":423},[621,4634,4635,4638],{"class":623,"line":624},[621,4636,4637],{"class":627},"ssh",[621,4639,4640],{"class":631}," root@your_server_ip\n",[428,4642,4643],{},[514,4644],{"alt":4645,"src":4646},"SSH connection to the Linux VPS server in terminal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fvps-terminal-ssh-connection.webp",[428,4648,4649],{},"Ensure your server packages are up to date:",[613,4651,4653],{"className":615,"code":4652,"language":617,"meta":423,"style":423},"sudo apt update && sudo apt upgrade -y\n",[522,4654,4655],{"__ignoreMap":423},[621,4656,4657,4659,4662,4665,4668,4671,4673,4676],{"class":623,"line":624},[621,4658,628],{"class":627},[621,4660,4661],{"class":631}," apt",[621,4663,4664],{"class":631}," update",[621,4666,4667],{"class":693}," &&",[621,4669,4670],{"class":627}," sudo",[621,4672,4661],{"class":631},[621,4674,4675],{"class":631}," upgrade",[621,4677,4678],{"class":631}," -y\n",[428,4680,4681,4682,4685],{},"Add a new user, ",[522,4683,4684],{},"hermes",", or your preferred username:",[613,4687,4689],{"className":615,"code":4688,"language":617,"meta":423,"style":423},"sudo adduser hermes \nsudo passwd hermes\n",[522,4690,4691,4703],{"__ignoreMap":423},[621,4692,4693,4695,4698,4701],{"class":623,"line":624},[621,4694,628],{"class":627},[621,4696,4697],{"class":631}," adduser",[621,4699,4700],{"class":631}," hermes",[621,4702,770],{"class":769},[621,4704,4705,4707,4710],{"class":623,"line":641},[621,4706,628],{"class":627},[621,4708,4709],{"class":631}," passwd",[621,4711,4712],{"class":631}," hermes\n",[428,4714,4715,4716,4719],{},"Turn off ",[522,4717,4718],{},"root"," password login:",[463,4721,4722],{},[466,4723,4724],{},"Open the SSH configuration file:",[613,4726,4728],{"className":615,"code":4727,"language":617,"meta":423,"style":423},"sudo nano \u002Fetc\u002Fssh\u002Fsshd_config\n",[522,4729,4730],{"__ignoreMap":423},[621,4731,4732,4734,4736],{"class":623,"line":624},[621,4733,628],{"class":627},[621,4735,1061],{"class":631},[621,4737,4738],{"class":631}," \u002Fetc\u002Fssh\u002Fsshd_config\n",[463,4740,4741],{"start":641},[466,4742,4743,4744,4747,4748,969],{},"Locate the ",[522,4745,4746],{},"PermitRootLogin"," line and change its value to ",[522,4749,4750],{},"no",[613,4752,4757],{"className":4753,"code":4755,"language":4756,"meta":423},[4754],"language-text","PermitRootLogin no\n","text",[522,4758,4755],{"__ignoreMap":423},[463,4760,4761],{"start":648},[466,4762,4763],{},"Save the file and restart the SSH service:",[613,4765,4767],{"className":615,"code":4766,"language":617,"meta":423,"style":423},"sudo systemctl restart ssh\n",[522,4768,4769],{"__ignoreMap":423},[621,4770,4771,4773,4775,4777],{"class":623,"line":624},[621,4772,628],{"class":627},[621,4774,632],{"class":631},[621,4776,635],{"class":631},[621,4778,4779],{"class":631}," ssh\n",[477,4781,4783],{"id":4782},"step-2-install-hermes-agent","Step 2: Install Hermes Agent",[428,4785,4786],{},"Run the following command:",[613,4788,4790],{"className":615,"code":4789,"language":617,"meta":423,"style":423},"curl -fsSL https:\u002F\u002Fhermes-agent.nousresearch.com\u002Finstall.sh | bash\n",[522,4791,4792],{"__ignoreMap":423},[621,4793,4794,4796,4799,4802,4805],{"class":623,"line":624},[621,4795,1747],{"class":627},[621,4797,4798],{"class":631}," -fsSL",[621,4800,4801],{"class":631}," https:\u002F\u002Fhermes-agent.nousresearch.com\u002Finstall.sh",[621,4803,4804],{"class":693}," |",[621,4806,4807],{"class":627}," bash\n",[428,4809,4810],{},[514,4811],{"alt":4812,"src":4813},"Running the Hermes Agent installation script in terminal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-agent-installation-terminal.webp",[428,4815,4816],{},"Once installed, verify the installation by typing:",[613,4818,4820],{"className":615,"code":4819,"language":617,"meta":423,"style":423},"hermes --version\n",[522,4821,4822],{"__ignoreMap":423},[621,4823,4824,4826],{"class":623,"line":624},[621,4825,4684],{"class":627},[621,4827,2375],{"class":631},[428,4829,559,4830,4833,4834],{},[522,4831,4832],{},"hermes setup"," to configure the Hermes Agent:\n",[514,4835],{"alt":4836,"src":4837},"Running the hermes setup command in terminal to start configuration","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-agent-setup-wizard.webp",[428,4839,4840,4841,4844,4845],{},"Select an LLM provider, start with ",[522,4842,4843],{},"DeepSeek"," and add others later.\n",[514,4846],{"alt":4847,"src":4848},"Selecting DeepSeek as the LLM provider in Hermes setup","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-llm-provider-selection.webp",[428,4850,4851,4852,4854,4855,4859,4863,4864,4867,4868,4863,4872,4875,4876],{},"Enter ",[522,4853,4843],{},"API key:\n",[514,4856],{"alt":4857,"src":4858},"Entering the DeepSeek API key in the terminal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-enter-api-key.webp",[514,4860],{"alt":4861,"src":4862},"Successful confirmation of the LLM provider API key","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-api-key-success.webp","\nSelect ",[522,4865,4866],{},"local machine"," for running the Hermes Agent:\n",[514,4869],{"alt":4870,"src":4871},"Selecting local machine for Hermes Agent execution environment","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-select-local-machine.webp",[522,4873,4874],{},"Telegram"," in the channels. Other channels can be configured later.\n",[514,4877],{"alt":4878,"src":4879},"Selecting Telegram as the communication channel in Hermes setup","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-select-telegram-channel.webp",[477,4881,4883],{"id":4882},"step-3-integrating-with-telegram","Step 3: Integrating with Telegram",[428,4885,4518,4886,4889,4890],{},[522,4887,4888],{},"[2]"," for using Telegram bot.\n",[514,4891],{"alt":4892,"src":4893},"Selecting option to configure Telegram bot integration","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-bot-integration-option.webp",[428,4895,911,4896,4898,4899],{},[522,4897,4874],{}," and search for 'BotFather'.\n",[514,4900],{"alt":4901,"src":4902},"Searching for BotFather in the Telegram application","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-search-botfather.webp",[428,4904,4905,4906,4909,4910],{},"Click ",[522,4907,4908],{},"Open"," to open 'BotFather'.\n",[514,4911],{"alt":4912,"src":4913},"Opening the chat interface with BotFather on Telegram","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-open-botfather-chat.webp",[428,4915,4905,4916,4919,4920],{},[522,4917,4918],{},"Create a New Bot",".\n",[514,4921],{"alt":4922,"src":4923},"Sending newbot command to BotFather to create a new Telegram bot","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fbotfather-create-new-bot.webp",[428,4925,4926,4927],{},"Fill in the names and create the bot.\n",[514,4928],{"alt":4929,"src":4930},"Configuring the name and username for the new Telegram bot","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fbotfather-bot-details-configured.webp",[428,4932,4905,4933,4936,4937],{},[522,4934,4935],{},"Copy"," to copy the token and paste it back to the terminal.\n",[514,4938],{"alt":4939,"src":4940},"Copying the HTTP API token of the newly created Telegram bot","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fbotfather-copy-http-api-token.webp",[428,4942,4943,4944,4946],{},"Find the ",[522,4945,4874],{}," user account ID and add it to the 'Allowed user list':",[482,4948,4949,4958,4971],{},[466,4950,4951,4952,4954],{},"Search '@raw_data_bot' on ",[522,4953,4874],{},[514,4955],{"alt":4956,"src":4957},"Searching for raw data bot on Telegram to retrieve user ID","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-search-raw-data-bot.webp",[466,4959,4488,4960,4963,4964,4919,4967],{},[522,4961,4962],{},"RawDataBot"," then click Start button. The user ID will be shown behind ",[522,4965,4966],{},"P.S. Your ID:",[514,4968],{"alt":4969,"src":4970},"Starting RawDataBot to view the user account ID","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-raw-data-bot-user-id.webp",[466,4972,4973],{},"Copy the user ID and paste to the terminal.",[428,4975,4976,4977,4981,4982,4986],{},"Since we are running on the cloud, we want the service to be started automatically.\n",[514,4978],{"alt":4979,"src":4980},"Configuring the autostart option for Hermes systemd service","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-autostart-service-option.webp","\nLeave everything as default:\n",[514,4983],{"alt":4984,"src":4985},"Leaving setup configurations as default values in terminal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-leave-defaults-1.webp",[514,4987],{"alt":4988,"src":4989},"Completing the default setup options in Hermes configuration","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Fhermes-setup-leave-defaults-2.webp",[455,4991,4993],{"id":4992},"testing-your-hermes-agent-with-telegram-bot","Testing Your Hermes Agent with Telegram Bot",[428,4995,4996,4997,969],{},"Run the following command to start the ",[522,4998,4999],{},"hermes gateway",[613,5001,5003],{"className":615,"code":5002,"language":617,"meta":423,"style":423},"hermes gateway\n",[522,5004,5005],{"__ignoreMap":423},[621,5006,5007,5009],{"class":623,"line":624},[621,5008,4684],{"class":627},[621,5010,5011],{"class":631}," gateway\n",[428,5013,911,5014,5016],{},[522,5015,4874],{}," and add the created bot, '@tech_cloud_hermes_bot', to our chats.",[482,5018,5019,5032,5042],{},[466,5020,5021,5022,5024,5025,5027,5028],{},"type '\u002Fnew' in ",[522,5023,4874],{}," to start a new ",[522,5026,434],{}," session.\n",[514,5029],{"alt":5030,"src":5031},"Typing new command in Telegram to start a new Hermes Agent session","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-chat-hermes-new-session.webp",[466,5033,5034,5035,5037,5038],{},"type ",[522,5036,3864],{}," will list all available commands.\n",[514,5039],{"alt":5040,"src":5041},"Typing commands in Telegram to view available Hermes instructions","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-chat-hermes-commands-list.webp",[466,5043,5034,5044,5046,5047],{},[522,5045,3894],{}," to see a list of available LLMs.\n",[514,5048],{"alt":5049,"src":5050},"Typing model in Telegram to see the list of active LLMs","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002Ftelegram-chat-hermes-model-selection.webp",[455,5052,5054],{"id":5053},"running-hermes-gateway-as-a-background-service","Running Hermes Gateway as a Background Service",[428,5056,5057],{},"Create service file:",[613,5059,5061],{"className":1050,"code":5060,"language":1052,"meta":423,"style":423},"sudo nano \u002Fetc\u002Fsystemd\u002Fsystem\u002Fhermes-gateway.service\n",[522,5062,5063],{"__ignoreMap":423},[621,5064,5065,5067,5069],{"class":623,"line":624},[621,5066,628],{"class":627},[621,5068,1061],{"class":631},[621,5070,5071],{"class":631}," \u002Fetc\u002Fsystemd\u002Fsystem\u002Fhermes-gateway.service\n",[428,5073,5074,5075,5077],{},"Paste the following, replace ",[522,5076,4684],{}," in '\u002Fhome\u002Fhermes' with your preferred username:",[613,5079,5081],{"className":1076,"code":5080,"language":1078,"meta":423,"style":423},"[Unit]\nDescription=Hermes Gateway\nAfter=network.target\n\n[Service]\nUser=hermes\nWorkingDirectory=\u002Fhome\u002Fhermes\nExecStart=\u002Fhome\u002Fhermes\u002F.local\u002Fbin\u002Fhermes gateway\nRestart=always\nRestartSec=10\nEnvironment=PATH=\u002Fhome\u002Fhermes\u002F.local\u002Fbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin\n\n[Install]\nWantedBy=multi-user.target\n",[522,5082,5083,5087,5092,5096,5100,5104,5108,5112,5117,5121,5125,5129,5133,5137],{"__ignoreMap":423},[621,5084,5085],{"class":623,"line":624},[621,5086,1085],{},[621,5088,5089],{"class":623,"line":641},[621,5090,5091],{},"Description=Hermes Gateway\n",[621,5093,5094],{"class":623,"line":648},[621,5095,1095],{},[621,5097,5098],{"class":623,"line":655},[621,5099,645],{"emptyLinePlaceholder":644},[621,5101,5102],{"class":623,"line":667},[621,5103,1104],{},[621,5105,5106],{"class":623,"line":672},[621,5107,1109],{},[621,5109,5110],{"class":623,"line":678},[621,5111,1114],{},[621,5113,5114],{"class":623,"line":1020},[621,5115,5116],{},"ExecStart=\u002Fhome\u002Fhermes\u002F.local\u002Fbin\u002Fhermes gateway\n",[621,5118,5119],{"class":623,"line":1031},[621,5120,1124],{},[621,5122,5123],{"class":623,"line":1127},[621,5124,1130],{},[621,5126,5127],{"class":623,"line":1133},[621,5128,1136],{},[621,5130,5131],{"class":623,"line":1139},[621,5132,645],{"emptyLinePlaceholder":644},[621,5134,5135],{"class":623,"line":1144},[621,5136,1147],{},[621,5138,5139],{"class":623,"line":1150},[621,5140,1153],{},[428,5142,1158],{},[613,5144,5146],{"className":1050,"code":5145,"language":1052,"meta":423,"style":423},"sudo systemctl daemon-reload\nsudo systemctl enable hermes-gateway\nsudo systemctl start hermes-gateway\nsudo systemctl status hermes-gateway\n",[522,5147,5148,5156,5167,5177],{"__ignoreMap":423},[621,5149,5150,5152,5154],{"class":623,"line":624},[621,5151,628],{"class":627},[621,5153,632],{"class":631},[621,5155,1172],{"class":631},[621,5157,5158,5160,5162,5164],{"class":623,"line":641},[621,5159,628],{"class":627},[621,5161,632],{"class":631},[621,5163,766],{"class":631},[621,5165,5166],{"class":631}," hermes-gateway\n",[621,5168,5169,5171,5173,5175],{"class":623,"line":648},[621,5170,628],{"class":627},[621,5172,632],{"class":631},[621,5174,1192],{"class":631},[621,5176,5166],{"class":631},[621,5178,5179,5181,5183,5185],{"class":623,"line":655},[621,5180,628],{"class":627},[621,5182,632],{"class":631},[621,5184,662],{"class":631},[621,5186,5166],{"class":631},[455,5188,1319],{"id":1318},[428,5190,5191],{},"In this article, we focused on how to set up the Hermes Agent and use Telegram to communicate with it. Having the Hermes Agent running on a remote server provides a true digital assistant that runs 24\u002F7.",[1331,5193,5194],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":423,"searchDepth":641,"depth":648,"links":5196},[5197,5198,5203,5204,5205],{"id":4609,"depth":641,"text":4610},{"id":4619,"depth":641,"text":4620,"children":5199},[5200,5201,5202],{"id":4623,"depth":648,"text":4624},{"id":4782,"depth":648,"text":4783},{"id":4882,"depth":648,"text":4883},{"id":4992,"depth":641,"text":4993},{"id":5053,"depth":641,"text":5054},{"id":1318,"depth":641,"text":1319},[1353],"2026-06-19","Deploy the Hermes Agent on a remote VPS for 24\u002F7 uptime. Follow our step-by-step guide to integrate it with a custom Telegram bot.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server\u002FHow%20to%20Setup%20Hermes%20on%20Remote%20Server.webp","A step-by-step guide to deploying Hermes Agent on a remote Linux VPS and integrating it with a custom Telegram bot for 24\u002F7 uptime.",{"schemaOrg":5212,"robots":1394,"sitemap":5224},[5213],{"@type":1363,"name":374,"description":5208,"image":5209,"step":5214},[5215,5218,5221],{"@type":1366,"name":4624,"text":5216,"image":4646,"url":5217},"Open the terminal and SSH into your remote machine: Ensure your server packages are up to date: Add a new user, `hermes`, or your preferred usernam...","#step-1-connect-to-your-vps",{"@type":1366,"name":4783,"text":5219,"image":4813,"url":5220},"Run the following command: Once installed, verify the installation by typing: Run `hermes setup` to configure the Hermes Agent: Select an LLM provi...","#step-2-install-hermes-agent",{"@type":1366,"name":4883,"text":5222,"image":4893,"url":5223},"Select `[2]` for using Telegram bot. Head to `Telegram` and search for 'BotFather'. Click `Open` to open 'BotFather'. Click `Create a New Bot`. Fil...","#step-3-integrating-with-telegram",{"lastmod":5207},{"title":5226,"description":5208,"ogTitle":374,"ogDescription":5208,"twitterTitle":374,"twitterDescription":5208},"Hermes Agent VPS Setup: Telegram Bot Integration Guide",[434,5228,5229,5230,5231],"VPS Setup","Telegram Bot","Linux VPS","AI Agent","gfsduy5l7mhQlgk1B5l15odagbzetTgFxjC5hIpUmKg",{"id":2862,"title":354,"author":423,"body":2863,"category":4020,"date":4023,"description":4024,"extension":1357,"image":4025,"imageAlt":4026,"isPublished":644,"meta":4027,"minRead":1031,"navigation":644,"path":355,"seo":4052,"stem":356,"tags":4054,"updatedAt":2859,"__hash__":4057},1792489979261]