11---
22// Document-style homepage body. Reads like a short paper about the product:
33// one modest headline, plain first-person prose, six beats separated by
4- // hairlines, the two demos kept as numbered figures, and one way to start.
4+ // hairlines, the two demos kept as numbered figures, and one door in: Cloud,
5+ // with a setup prompt for visitors who already have an agent open.
56// Sits inside the rail layout; the rail's "On this page" list points at the
67// section ids below.
78import { AnimatedBeamDemo } from " ../animated-beam-demo" ;
89import { ContextBloatDemo } from " ../context-bloat-demo" ;
9- import { setupPrompt } from " ../../content/site-copy" ;
1010import Testimonials from " ./testimonials.astro" ;
11+ import IntroSteps from " ./intro-steps.astro" ;
12+ import CopyPrompt from " ./copy-prompt.astro" ;
1113import " ../../styles/variants/doc.css" ;
1214// Avatar goes through Vite so it ships as a hashed asset; new /public files
1315// are not picked up by the deploy pipeline.
1416import rhysAvatar from " ../../assets/rhys-sullivan.jpg" ;
15- // Brand marks for the hover reveals in the intro steps.
16- const logos = import .meta .glob <string >(" ../../assets/logos/*.svg" , {
17- eager: true ,
18- query: " ?url" ,
19- import: " default" ,
20- });
21- const logo = (name : string ): string => {
22- const hit = Object .entries (logos ).find (([k ]) => k .endsWith (` /${name }.svg ` ));
23- if (! hit ) throw new Error (` missing logo ${name } ` );
24- return hit [1 ];
25- };
26- const toolLogos = [" github" , " linear" , " sentry" , " stripe" , " notion" , " slack" , " jira" , " gmail" ];
27- const agentLogos = [" claude" , " codex" , " cursor" , " chatgpt" , " gemini" , " hermes" , " copilot" , " windsurf" , " opencode" , " zed" , " grok" ];
28- // The three marks on the copy button; the full list would crowd it.
29- const agentLogosShort = [" claude" , " codex" , " cursor" ];
3017const X_URL = " https://x.com/RhysSullivan" ;
3118
3219interface Props {
@@ -39,91 +26,15 @@ const { gh } = Astro.props;
3926 { /* ── Intro ── */ }
4027 <header class =" doc__intro" >
4128 <h1 class =" doc__title" >Executor is an MCP gateway.</h1 >
42- <ol class =" doc__steps" >
43- <li >
44- <span class =" doc__num" >01</span >
45- <span >
46- Connect{ " " }
47- <span class =" doc__pop" tabindex =" 0" >
48- <span class =" doc__pop-word" >everything</span >
49- <span class =" doc__pop-panel" aria-hidden =" true" inert >
50- { toolLogos .map ((n , i ) => (
51- <span class = " doc__pop-tile" style = { ` --i:${i } ` } ><img src = { logo (n )} alt = " " width = " 18" height = " 18" /></span >
52- ))}
53- <span class =" doc__pop-pill" style ={ ` --i:${toolLogos .length } ` } >any OpenAPI, GraphQL, or MCP</span >
54- </span >
55- </span >
56- { " " } to Executor.
57- </span >
58- </li >
59- <li >
60- <span class =" doc__num" >02</span >
61- <span >
62- Give{ " " }
63- <span class =" doc__pop" tabindex =" 0" >
64- <span class =" doc__pop-word" >your agent</span >
65- <span class =" doc__pop-panel" aria-hidden =" true" inert >
66- { agentLogos .map ((n , i ) => (
67- <span class = " doc__pop-tile" style = { ` --i:${i } ` } ><img src = { logo (n )} alt = " " width = " 18" height = " 18" /></span >
68- ))}
69- <span class =" doc__pop-pill" style ={ ` --i:${agentLogos .length } ` } >any MCP client</span >
70- </span >
71- </span >
72- { " " } the Executor tool.
73- </span >
74- </li >
75- <li >
76- <span class =" doc__num" >03</span >
77- <span >That's it.{ " " } <a href =" #install" >Get started.</a ></span >
78- </li >
79- </ol >
80- <p class =" doc__subhead" >One MCP. All your accounts.</p >
81- <div class =" doc__tabs" role =" tablist" aria-label =" How to run Executor" >
82- <button type =" button" role =" tab" aria-selected =" true" data-doc-tab =" cloud" >Cloud</button >
83- <button type =" button" role =" tab" aria-selected =" false" data-doc-tab =" local" >Desktop / CLI</button >
84- <button type =" button" role =" tab" aria-selected =" false" data-doc-tab =" self" >Self-hosted</button >
85- </div >
86- <div class =" doc__tabpanes" >
87- <div role =" tabpanel" data-doc-pane =" cloud" >
88- <p >Sign in, point your agent at one URL, done. Free for up to three people and 100,000 executions a month.</p >
89- <div class =" doc__actions" ><a href =" /cloud" class =" btn-primary" >Start on Cloud</a ><button type =" button" class =" btn-secondary copy-btn doc__copy" data-copy ={ setupPrompt } data-event =" marketing_setup_prompt_copied" >
90- <span class =" doc__copy-logos" aria-hidden =" true" >
91- { agentLogosShort .map ((n ) => <img src = { logo (n )} alt = " " width = " 14" height = " 14" />)}
92- </span >
93- <span >Copy setup prompt</span >
94- <span class =" copy-icons" aria-hidden =" true" >
95- <svg class =" copy-icon-copy" xmlns =" http://www.w3.org/2000/svg" width =" 14" height =" 14" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 2" stroke-linecap =" round" stroke-linejoin =" round" ><rect width =" 14" height =" 14" x =" 8" y =" 8" rx =" 2" ry =" 2" ></rect ><path d =" M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" ></path ></svg >
96- <svg class =" copy-icon-check" xmlns =" http://www.w3.org/2000/svg" width =" 14" height =" 14" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 2" stroke-linecap =" round" stroke-linejoin =" round" ><path d =" M20 6 9 17l-5-5" ></path ></svg >
97- </span >
98- </button ></div >
99- </div >
100- <div role =" tabpanel" data-doc-pane =" local" data-inactive aria-hidden =" true" inert >
101- <p >Nothing leaves your machine. A desktop app for Mac, Windows, and Linux, or a CLI that runs in the background. Same local endpoint either way.</p >
102- <div class =" doc__actions" ><span class =" doc__dl" data-download >
103- <a data-os =" mac-arm64" href ={ ` ${gh }/releases/latest/download/executor-desktop-mac-arm64.dmg ` } class =" btn-primary" >Download for Mac</a >
104- <a data-os =" mac-x64" href ={ ` ${gh }/releases/latest/download/executor-desktop-mac-x64.dmg ` } class =" btn-primary" >Download for Mac (Intel)</a >
105- <a data-os =" win-x64" href ={ ` ${gh }/releases/latest/download/executor-desktop-win-x64.exe ` } class =" btn-primary" >Download for Windows</a >
106- <a data-os =" linux-x64" href ={ ` ${gh }/releases/latest/download/executor-desktop-linux-x86_64.AppImage ` } class =" btn-primary" >Download for Linux</a >
107- <details class =" download-other doc__dl-other hidden" data-download-other >
108- <summary >Other platforms ▾</summary >
109- <div class =" download-other-list" data-download-other-list ></div >
110- </details >
111- </span ><code class =" doc__cmd" >npm i -g executor</code ><button type =" button" class =" btn-secondary copy-btn doc__copy" data-copy ={ setupPrompt } data-event =" marketing_setup_prompt_copied" >
112- <span class =" doc__copy-logos" aria-hidden =" true" >
113- { agentLogosShort .map ((n ) => <img src = { logo (n )} alt = " " width = " 14" height = " 14" />)}
114- </span >
115- <span >Copy setup prompt</span >
116- <span class =" copy-icons" aria-hidden =" true" >
117- <svg class =" copy-icon-copy" xmlns =" http://www.w3.org/2000/svg" width =" 14" height =" 14" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 2" stroke-linecap =" round" stroke-linejoin =" round" ><rect width =" 14" height =" 14" x =" 8" y =" 8" rx =" 2" ry =" 2" ></rect ><path d =" M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" ></path ></svg >
118- <svg class =" copy-icon-check" xmlns =" http://www.w3.org/2000/svg" width =" 14" height =" 14" viewBox =" 0 0 24 24" fill =" none" stroke =" currentColor" stroke-width =" 2" stroke-linecap =" round" stroke-linejoin =" round" ><path d =" M20 6 9 17l-5-5" ></path ></svg >
119- </span >
120- </button ></div >
121- </div >
122- <div role =" tabpanel" data-doc-pane =" self" data-inactive aria-hidden =" true" inert >
123- <p >One Docker image on your own box. It is the same code Cloud runs.</p >
124- <div class =" doc__actions" ><a href =" https://executor.sh/docs/hosted/docker" class =" btn-primary" >Self-hosting docs</a ><a href ={ gh } class =" btn-secondary" >Source on GitHub</a ></div >
125- </div >
29+ <IntroSteps />
30+ <p class =" doc__subhead" >One MCP. All your accounts. Free for up to three people.</p >
31+ <div class =" doc__actions" >
32+ <a href =" /cloud" class =" btn-primary" >Start on Cloud</a >
33+ <CopyPrompt />
12634 </div >
35+ <p class =" doc__subhead doc__subhead--fine" >
36+ Rather keep it on your machine? <a href =" #install" >Desktop, CLI, or self-hosted ↓</a >
37+ </p >
12738 </header >
12839
12940 <figure class =" doc__fig doc__fig--hero" >
@@ -305,29 +216,6 @@ const { gh } = Astro.props;
305216 </section >
306217</article >
307218
308- <script >
309- for (const list of document.querySelectorAll<HTMLElement>(".doc__tabs")) {
310- const root = list.parentElement!;
311- list.addEventListener("click", (e) => {
312- const tab = (e.target as HTMLElement).closest<HTMLElement>("[data-doc-tab]");
313- if (!tab) return;
314- const key = tab.dataset.docTab;
315- for (const t of list.querySelectorAll<HTMLElement>("[data-doc-tab]")) {
316- t.setAttribute("aria-selected", String(t === tab));
317- }
318- for (const p of root.querySelectorAll<HTMLElement>("[data-doc-pane]")) {
319- const off = p.dataset.docPane !== key;
320- p.toggleAttribute("data-inactive", off);
321- p.toggleAttribute("inert", off);
322- p.setAttribute("aria-hidden", String(off));
323- for (const el of p.querySelectorAll<HTMLElement>("a, button")) {
324- el.tabIndex = off ? -1 : 0;
325- }
326- }
327- });
328- }
329- </script >
330-
331219<script >
332220 // Show one download button for the visitor's OS and tuck the rest behind
333221 // "Other platforms". Without JS or on an unknown OS, all four stay visible.
0 commit comments