Files
hatchet/frontend/docs/components/McpSetup.tsx
T
Gabe Ruttner 94066fab98 Feat--llm-readable-docs (#3030)
* feat: generate flat files

* feat: init mcp

* feat: enhance tab labels with themed icons and add new logos for programming languages

* feat: install in onboarding flows

* structural cleanup

* chore: remove desktop and add buttons

* feat: posthog instrumentation

* fix: responsive buttons

* nit: raw

* feat: minisearch

* feat: wip improved search

* feat: update MCP installation documentation and links

* chore: lint

* chore: cleanup comment

* fix: docstring

* fix: improve search highlighting and scrolling behavior

* chore: lint

* chore: review

* feat: add safeBase64Encode function and update origin handling in theme.config.tsx

* chore: feedback

* feat: ruby logo

* chore: lint
2026-02-16 03:07:45 -08:00

153 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useState } from "react";
import posthog from "posthog-js";
import { CodeBlock } from "./code/CodeBlock";
import { Button } from "./ui/button";
/* ── Tab label styles ─────────────────────────────────────── */
const tabLabelStyle: React.CSSProperties = {
display: "inline-flex",
alignItems: "center",
gap: "6px",
};
/** Renders an SVG as a CSS mask filled with currentColor (works in light + dark mode). */
function ThemedIcon({ src }: { src: string }) {
return (
<span
style={
{
display: "inline-block",
width: 16,
height: 16,
flexShrink: 0,
backgroundColor: "currentColor",
WebkitMaskImage: `url(${src})`,
WebkitMaskSize: "contain",
WebkitMaskRepeat: "no-repeat",
WebkitMaskPosition: "center",
maskImage: `url(${src})`,
maskSize: "contain",
maskRepeat: "no-repeat",
maskPosition: "center",
} as React.CSSProperties
}
/>
);
}
/** Cursor IDE tab label with official logo. */
export function CursorTabLabel() {
return (
<span style={tabLabelStyle}>
<ThemedIcon src="/cursor-logo.svg" />
Cursor
</span>
);
}
/** Claude Code tab label with official Claude logo. */
export function ClaudeCodeTabLabel() {
return (
<span style={tabLabelStyle}>
<ThemedIcon src="/claude-logo.svg" />
Claude Code
</span>
);
}
/** Globe icon used for the "Other Agents" tab. */
export function OtherAgentsTabLabel() {
return (
<span style={tabLabelStyle}>
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="10" />
<path d="M2 12h20" />
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10A15.3 15.3 0 0 1 12 2z" />
</svg>
Other Agents
</span>
);
}
/** Returns the MCP endpoint URL based on current origin. */
function useMcpUrl(): string {
const [origin, setOrigin] = useState("https://docs.hatchet.run");
useEffect(() => {
setOrigin(window.location.origin);
}, []);
return `${origin}/api/mcp`;
}
/** Renders the MCP endpoint URL as inline code. */
export function McpUrl() {
const url = useMcpUrl();
return <code>{url}</code>;
}
/** Cursor one-click install deeplink button. */
export function CursorDeeplinkButton() {
const url = useMcpUrl();
const config = JSON.stringify({
command: "npx",
args: ["-y", "mcp-remote", url],
});
const encoded =
typeof window !== "undefined"
? btoa(config)
: Buffer.from(config).toString("base64");
const deeplink = `cursor://anysphere.cursor-deeplink/mcp/install?name=hatchet-docs&config=${encoded}`;
return (
<Button variant="outline" size="lg" asChild className="mt-4">
<a
href={deeplink}
className="no-underline flex items-center gap-2"
onClick={() =>
posthog.capture("mcp_install_click", {
editor: "cursor",
method: "deeplink_button",
page: "install-docs-mcp",
})
}
>
<ThemedIcon src="/cursor-logo.svg" />
Install MCP Server in Cursor
</a>
</Button>
);
}
/** Renders a JSON config code block with the dynamic MCP URL. */
export function CursorMcpConfig() {
const url = useMcpUrl();
const config = JSON.stringify(
{ "hatchet-docs": { command: "npx", args: ["-y", "mcp-remote", url] } },
null,
2,
);
return <CodeBlock source={{ language: "json", raw: config }} />;
}
/** Renders the claude mcp add command with dynamic URL. */
export function ClaudeCodeCommand() {
const url = useMcpUrl();
return (
<CodeBlock
source={{
language: "bash",
raw: `claude mcp add --transport http hatchet-docs ${url}`,
}}
/>
);
}