diff --git a/.cursor/rules/architecture.mdc b/.cursor/rules/architecture.mdc new file mode 100644 index 0000000..7f4ca20 --- /dev/null +++ b/.cursor/rules/architecture.mdc @@ -0,0 +1,72 @@ +--- +alwaysApply: true +--- + +## Product Website Architecture + +- **Framework**: Next.js 15 (App Router) + React 19 + TypeScript 5. +- **Runtime/PM**: Bun (see `bun.lock`). Prefer `bun run` for scripts. +- **Purpose**: Product landing page with purchase links, documentation links, and blog for SEO. + +### Routing & Rendering + +- `app/page.tsx`: Main landing page with product information. +- `app/blog/page.tsx`: Blog listing page. +- `app/blog/[id]/page.tsx`: Individual blog post pages. +- `app/blog/author/[id]/page.tsx`: Author pages. +- `app/privacy/page.tsx` & `app/terms/page.tsx`: Legal pages. +- `app/layout.tsx`: Root layout with Navigation and Footer components. +- `app/chart/page.tsx`: Client-side chart rendering page (from GraphGPT fork). + +### Content Organization + +- `app/blog/posts/`: MDX blog posts with frontmatter. +- `app/blog/authors/authors.json`: Author metadata (name, profile picture). +- `public/`: Static assets (images, fonts, etc.). +- Blog posts support frontmatter: `title`, `description`, `date`, `author`, `tags`, `image`, `featured`. + +### MDX Setup + +- Uses `next-mdx-remote` (RSC) for MDX compilation. +- `mdx-components.tsx`: Custom MDX components (H1, H2, H3, P, Bold, links, etc.). +- Custom components: `BlogEntry`, `ArticleImage`, `AiMarketShareChart`. +- Posts are compiled server-side with `compileMDX` from `next-mdx-remote/rsc`. + +### Blog Features + +- `app/lib/blog.ts`: Blog utilities (`getAllPosts`, `getBlogPosts`, `getPostBySlug`). +- Automatic reading time estimation. +- Featured post support. +- Author linking and profiles. +- Tag support. + +### Configuration + +- `next.config.ts`: Basic config with asset prefixing via `baseUrl.ts`. +- `tsconfig.json`: Strict TypeScript, modern ESM (`moduleResolution: Bundler`). +- `tailwind.config.ts`: Tailwind CSS configuration. +- `siteConfig.ts`: Site-wide configuration (name, URL, metadata). + +### Styling + +- Tailwind CSS for styling. +- Radix UI components for accessible primitives. +- `@tailwindcss/typography` for prose content. +- Custom CSS variables for theming. + +### Components + +- `app/components/ui/`: UI components (Navbar, Footer, Hero, FAQs, etc.). +- `app/components/blog/`: Blog-specific components (BlogPostCard, FeaturedPost, etc.). +- Server components by default; add `"use client"` only when needed. + +### Build & Commands + +- Scripts: `bun run dev`, `bun run build`, `bun run start`. +- Build generates static pages from MDX posts. + +### Notes + +- This is a product landing page, not a documentation site. +- Blog is for SEO and content marketing. +- Forked from GraphGPT but repurposed for Oraxen product. diff --git a/.cursor/rules/conventions.mdc b/.cursor/rules/conventions.mdc new file mode 100644 index 0000000..1f96d07 --- /dev/null +++ b/.cursor/rules/conventions.mdc @@ -0,0 +1,67 @@ +--- +alwaysApply: true +--- + +## Project Conventions + +- **Tech Stack**: Next.js 15 (App Router), React 19, TypeScript 5, Bun. +- **Run commands**: use Bun + - `bun run dev`, `bun run build`, `bun run start`. +- **Directory layout**: + - `app/`: Next App Router routes and components. + - `app/blog/posts/`: MDX blog posts. + - `app/components/`: React components (UI and blog-specific). + - `app/lib/`: Utility functions (blog helpers, scroll hooks, etc.). + - `public/`: Static assets (images, fonts, SVG icons). + +### TypeScript & React + +- **Strict mode**: keep `tsconfig` strict; no `any` unless absolutely necessary. +- **ESM only**: use modern ESM imports; no CommonJS. +- **Naming**: descriptive, self-explanatory names; avoid 1–2 char identifiers. +- **Components**: server components by default; add `"use client"` only when needed. +- **Control flow**: prefer early returns; avoid unnecessary try/catch. + +### MDX Authoring + +- Blog posts use standard Markdown in MDX files. +- Frontmatter required: `title`, `description`, `date`, `author`, `tags`, `image`. +- Optional: `featured`, `modifiedDate`, `readingTime`. +- Custom components available: `BlogEntry`, `ArticleImage`, styled headings. +- Images: Use Markdown `![Alt](...)` syntax. + +### Blog Post Structure + +```mdx +--- +title: Post Title +description: Post description +date: 2024-01-01 +author: author-id +tags: [tag1, tag2] +image: /path/to/image.webp +featured: true +--- + +Content here... +``` + +### Styling + +- Tailwind CSS for all styling. +- Use Radix UI components for accessible primitives. +- Custom design system components in `app/components/`. +- Follow existing patterns for consistency. + +### Build & Validation + +- Builds must pass `bun run build`; TypeScript must compile cleanly. +- Blog posts are compiled at build time via `next-mdx-remote/rsc`. +- Always verify the site builds after edits. + +### SEO Focus + +- This is a product landing page with blog for SEO. +- Include proper metadata in pages (title, description, OG tags). +- Blog posts should be keyword-rich and well-structured. +- Use semantic HTML and proper heading hierarchy. diff --git a/.cursor/rules/design-guidelines.mdc b/.cursor/rules/design-guidelines.mdc deleted file mode 100644 index f562560..0000000 --- a/.cursor/rules/design-guidelines.mdc +++ /dev/null @@ -1,277 +0,0 @@ ---- -alwaysApply: true ---- - -# App Design Guidelines - -**Design guidelines for developers building on the Apps SDK** - ---- - -## Overview - -Apps are developer-built experiences that live inside ChatGPT. -They extend what users can do without breaking the flow of conversation, appearing through lightweight cards, carousels, fullscreen views, and other display modes that integrate seamlessly into ChatGPT’s interface while maintaining its clarity, trust, and voice. - -These guidelines will give you everything you need to begin building high-quality, consistent, and user-friendly experiences inside ChatGPT. - ---- - -## Best Practices - -Apps are most valuable when they help people accomplish meaningful tasks directly within ChatGPT — without breaking the conversational flow. -The goal is to design experiences that feel consistent, useful, and trustworthy while extending ChatGPT in ways that add real value. - -**Good use cases include:** -- Booking a ride -- Ordering food -- Checking availability -- Tracking a delivery - -These are tasks that are conversational, time-bound, and easy to summarize visually with a clear call to action. - -**Poor use cases include:** -- Pasting long-form content from a website -- Complex multi-step workflows -- Ads or irrelevant messaging - ---- - -## Principles - -| Principle | Description | -|------------|--------------| -| **Conversational** | Experiences should feel like a natural extension of ChatGPT, fitting seamlessly into the conversational flow and UI. | -| **Intelligent** | Tools should be aware of conversation context, anticipating user intent with relevant responses and UI. | -| **Simple** | Each interaction should focus on a single clear action or outcome. | -| **Responsive** | Tools should feel fast and lightweight, enhancing the conversation. | -| **Accessible** | Designs must support users of all abilities, including those using assistive technologies. | - ---- - -## Boundaries - -ChatGPT controls system-level elements such as: -- Voice -- Chrome -- Styles -- Navigation -- Composer - -Developers customize: -- Content -- Brand presence -- Actions inside the system framework - -This ensures all apps feel native to ChatGPT while expressing unique brand value. - ---- - -## Good Use Cases - -A good app should answer “yes” to most of these: - -- Does this task fit naturally into a conversation? -- Is it time-bound or action-oriented? -- Is the information valuable in the moment? -- Can it be summarized visually and simply? -- Does it extend ChatGPT in a meaningful way? - ---- - -## Poor Use Cases - -Avoid tools that: -- Display long-form or static content better suited for a website. -- Require complex multi-step workflows. -- Use space for ads or upsells. -- Surface private information in public view. -- Duplicate ChatGPT’s system functions. - ---- - -## Display Modes - -Display modes define how apps appear inside ChatGPT. -They make experiences feel native to conversation. - -### Inline - -**When to use:** -- Single actions or decisions (e.g., confirm a booking) -- Small structured data (map, summary, status) -- Self-contained widgets (audio player, score card) - -**Layout elements:** -- Icon & tool call -- Inline display area -- Follow-up (model-generated next steps) - -**Rules of thumb:** -- Max two primary actions (CTA + secondary) -- No deep navigation or nested scrolling -- No duplicated inputs - ---- - -### Inline Carousel - -**When to use:** -- Displaying multiple similar items (e.g., restaurants, events) -- Each with visual and key metadata - -**Layout:** -- Image (always include one) -- Title -- Metadata (max two lines) -- Badge (optional) -- Single clear CTA - -**Rules of thumb:** -- 3–8 items per carousel -- Max three lines of metadata -- Consistent visual hierarchy - ---- - -### Fullscreen - -**When to use:** -- Rich tasks needing more space (maps, diagrams, listings) -- Multi-step workflows - -**Layout:** -- System close control -- Fullscreen content area -- Persistent composer overlay - -**Rules of thumb:** -- Support natural conversation through composer -- Don’t replicate full native apps -- Use fullscreen for deeper engagement only - ---- - -### Picture-in-Picture (PiP) - -**When to use:** -- Ongoing or live sessions (games, videos) -- Activities that react to chat input - -**Interaction patterns:** -- **Activated:** Stays fixed when scrolling -- **Pinned:** Remains until dismissed -- **Session ends:** Returns inline and scrolls away - -**Rules of thumb:** -- Update dynamically with conversation -- Close automatically at session end -- Avoid clutter and static content - ---- - -## Visual Design Guidelines - -A consistent look and feel ensures partner-built tools feel native to ChatGPT while maintaining trust and clarity. - -### Why This Matters - -Visual consistency preserves user trust and system clarity while allowing subtle brand differentiation. - ---- - -### Color - -**Rules of thumb:** -- Use system colors for text, icons, and dividers. -- Brand accents (logos, icons) may be added — not background or text colors. -- Avoid gradients or custom patterns. -- Apply brand accent colors only to primary buttons. - ---- - -### Typography - -ChatGPT uses system fonts (SF Pro on iOS, Roboto on Android). - -**Rules of thumb:** -- Always inherit the system font stack. -- Use bold/italic only in content areas, not UI. -- Limit font size variation. -- Don’t use custom fonts, even in fullscreen. - ---- - -### Spacing & Layout - -**Rules of thumb:** -- Follow system grid spacing. -- Keep consistent padding and margins. -- Respect system corner rounding. -- Maintain visual hierarchy (headline → supporting text → CTA). - ---- - -### Icons & Imagery - -**Rules of thumb:** -- Use system or monochromatic outlined icons. -- Don’t include your logo in responses (ChatGPT adds it automatically). -- Follow aspect ratios to prevent distortion. - ---- - -## Accessibility - -Accessibility is **required** for all partner experiences. - -**Rules of thumb:** -- Maintain WCAG AA contrast ratios. -- Provide alt text for all images. -- Support text resizing without layout issues. - ---- - -## Tone & Proactivity - -Tone defines how partner tools “speak” within ChatGPT. -Partners must align with ChatGPT’s clear, conversational, and trustworthy voice. - -### Tone Ownership - -- ChatGPT defines the overall voice. -- Partners provide content **within** that framework. -- Result: seamless, natural experiences. - ---- - -### Content Guidelines - -- Keep content concise and scannable. -- Always context-driven — respond to what the user asked. -- Avoid spam, jargon, or promotions. -- Prioritize helpfulness and clarity. - ---- - -### Proactivity Rules - -**Allowed:** Contextual nudges (e.g., “Your ride is arriving.”) -**Not allowed:** Promotions or re-engagements (e.g., “Check out our latest deals.”) - -**Transparency:** -Always show why and when your tool resurfaces. -Proactivity should feel like a continuation, not an interruption. - ---- - -### Why This Matters - -Consistent tone and thoughtful re-engagement ensure: -- User trust -- Clear value -- A seamless conversational experience - ---- - -© OpenAI — Apps SDK Design Guidelines diff --git a/.cursor/rules/ux-guidelines.mdc b/.cursor/rules/ux-guidelines.mdc deleted file mode 100644 index 110113c..0000000 --- a/.cursor/rules/ux-guidelines.mdc +++ /dev/null @@ -1,363 +0,0 @@ ---- -alwaysApply: true ---- - -# Build a Custom UX & UI Components for ChatGPT Apps - -## Overview - -**UI components** turn structured tool results into a human-friendly UI. -Apps SDK components are typically **React components** that run inside an iframe, communicate with the host via the `window.openai` API, and render inline within the conversation. - -This guide describes how to: -- Structure your component project -- Bundle it -- Wire it up to your MCP server - -You can also check out the **examples repository** on GitHub for reference. - ---- - -## Understand the `window.openai` API - -`window.openai` is the **bridge** between your frontend and ChatGPT. -It allows your UI to manage data, state, and layout interactions between your component and the ChatGPT host. - -### Type Declarations - -```ts -declare global { - interface Window { - openai: API & OpenAiGlobals; - } - - interface WindowEventMap { - [SET_GLOBALS_EVENT_TYPE]: SetGlobalsEvent; - } -} - -type OpenAiGlobals< - ToolInput extends UnknownObject = UnknownObject, - ToolOutput extends UnknownObject = UnknownObject, - ToolResponseMetadata extends UnknownObject = UnknownObject, - WidgetState extends UnknownObject = UnknownObject -> = { - theme: Theme; - userAgent: UserAgent; - locale: string; - - // layout - maxHeight: number; - displayMode: DisplayMode; - safeArea: SafeArea; - - // state - toolInput: ToolInput; - toolOutput: ToolOutput | null; - toolResponseMetadata: ToolResponseMetadata | null; - widgetState: WidgetState | null; -}; -```` - -### API Methods - -```ts -type API = { - /** Calls a tool on your MCP. Returns the full response. */ - callTool: (name: string, args: Record) => Promise; - - /** Triggers a follow-up turn in the ChatGPT conversation */ - sendFollowUpMessage: (args: { prompt: string }) => Promise; - - /** Opens an external link, redirects web page or mobile app */ - openExternal(payload: { href: string }): void; - - /** Requests an alternate display mode (inline, PiP, fullscreen) */ - requestDisplayMode: (args: { mode: DisplayMode }) => Promise<{ mode: DisplayMode }>; - - /** Persists widget state */ - setWidgetState: (state: WidgetState) => Promise; -}; -``` - -### Event Handling - -```ts -export const SET_GLOBALS_EVENT_TYPE = "openai:set_globals"; - -export class SetGlobalsEvent extends CustomEvent<{ - globals: Partial; -}> { - readonly type = SET_GLOBALS_EVENT_TYPE; -} -``` - ---- - -## React Hook: `useOpenAiGlobal` - -Many Apps SDK projects wrap `window.openai` access inside small **React hooks** for testability and reactivity. - -```ts -export function useOpenAiGlobal( - key: K -): OpenAiGlobals[K] { - return useSyncExternalStore( - (onChange) => { - const handleSetGlobal = (event: SetGlobalsEvent) => { - const value = event.detail.globals[key]; - if (value === undefined) return; - onChange(); - }; - - window.addEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal, { passive: true }); - return () => window.removeEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal); - }, - () => window.openai[key] - ); -} -``` - -### Example Usage - -```ts -export function useToolInput() { - return useOpenAiGlobal('toolInput'); -} - -export function useToolOutput() { - return useOpenAiGlobal('toolOutput'); -} - -export function useToolResponseMetadata() { - return useOpenAiGlobal('toolResponseMetadata'); -} -``` - -This hook allows your app to reactively respond to theme changes, display mode shifts, or tool updates. - ---- - -## Persist Component State & Expose Context to ChatGPT - -`widgetState` persists user data across sessions and exposes it to ChatGPT. -Everything passed to `setWidgetState` becomes visible to the model and hydrated into `window.openai.widgetState`. - -⚠️ **Performance Tip:** Keep widget state small — ideally under **4K tokens**. - ---- - -## Trigger Server Actions - -Use `window.openai.callTool()` to directly invoke tools on your MCP server. - -```ts -async function refreshPlaces(city: string) { - await window.openai?.callTool("refresh_pizza_list", { city }); -} -``` - -Ensure your tool is marked as **component-initiable**. - ---- - -## Send Conversational Follow-Ups - -```ts -await window.openai?.sendFollowUpMessage({ - prompt: "Draft a tasting itinerary for the pizzerias I favorited.", -}); -``` - -This inserts a new message into the ChatGPT conversation as if the user had asked it. - ---- - -## Request Alternate Layouts - -If your UI requires more space (e.g., maps, tables, editors), request fullscreen or PiP mode. - -```ts -await window.openai?.requestDisplayMode({ mode: "fullscreen" }); -// Note: On mobile, PiP may be coerced to fullscreen -``` - ---- - -## Use Host-Backed Navigation - -Skybridge (the sandbox runtime) mirrors the iframe’s navigation into ChatGPT’s UI. - -### React Router Example - -```tsx -export default function PizzaListRouter() { - return ( - - - }> - } /> - - - - ); -} -``` - -### Programmatic Navigation - -```ts -const navigate = useNavigate(); - -function openDetails(placeId: string) { - navigate(`place/${placeId}`, { replace: false }); -} - -function closeDetails() { - navigate("..", { replace: true }); -} -``` - ---- - -## Scaffold the Component Project - -Keep frontend code separate from your MCP server logic. - -``` -app/ - server/ # MCP server (Python or Node) - web/ # Component bundle source - package.json - tsconfig.json - src/component.tsx - dist/component.js # Build output -``` - -### Initialize the Project - -```bash -cd app/web -npm init -y -npm install react@^18 react-dom@^18 -npm install -D typescript esbuild -``` - -Keep dependencies minimal to reduce bundle size. - ---- - -## Author the React Component - -Mount your app into the host shell and use the OpenAI globals for layout and data. - -### Example: “Pizza List” App - -1. **Mount the component** - -```ts -createRoot(document.getElementById("pizzaz-list-root")) - .render(); -``` - -2. **Subscribe to host globals** - -```ts -const displayMode = useOpenAiGlobal("displayMode"); -const maxHeight = useOpenAiGlobal("maxHeight"); -``` - -3. **Render from tool output** - -```ts -const places = useOpenAiGlobal("toolOutput"); -``` - -4. **Persist state & trigger actions** - -```ts -await window.openai.setWidgetState(newFavorites); -await window.openai.requestDisplayMode({ mode: "fullscreen" }); -await window.openai.callTool("refresh_pizza_list", { city }); -``` - ---- - -## Explore Example Components - -| Component | Description | -| ------------------- | ----------------------------------------------------- | -| **Pizzaz List** | Ranked card list with favorites and CTA buttons | -| **Pizzaz Carousel** | Media-heavy horizontal scroller (embla-powered) | -| **Pizzaz Map** | Mapbox integration with fullscreen inspector | -| **Pizzaz Album** | Stacked gallery for single-item deep dives | -| **Pizzaz Video** | Scripted player with overlays and fullscreen controls | - -Each example demonstrates asset bundling, host API usage, and state management for conversational UIs. - ---- - -## React Helper Hook: `useWidgetState` - -Keeps host-persisted widget state synchronized with React local state. - -```ts -export function useWidgetState( - defaultState?: T | (() => T | null) | null -): readonly [T | null, (state: SetStateAction) => void] { - const widgetStateFromWindow = useOpenAiGlobal("widgetState") as T; - const [widgetState, _setWidgetState] = useState(() => - widgetStateFromWindow ?? (typeof defaultState === "function" - ? defaultState() - : defaultState ?? null) - ); - - useEffect(() => { - _setWidgetState(widgetStateFromWindow); - }, [widgetStateFromWindow]); - - const setWidgetState = useCallback((state: SetStateAction) => { - _setWidgetState(prev => { - const newState = typeof state === "function" ? state(prev) : state; - if (newState != null) window.openai.setWidgetState(newState); - return newState; - }); - }, []); - - return [widgetState, setWidgetState] as const; -} -``` - ---- - -## Bundle for the Iframe - -Use **esbuild** to bundle your React component. - -```json -{ - "scripts": { - "build": "esbuild src/component.tsx --bundle --format=esm --outfile=dist/component.js" - } -} -``` - -Run: - -```bash -npm run build -``` - -If esbuild reports missing dependencies, recheck `npm install` and import paths. - ---- - -## Embed the Component in the Server Response - -Refer to the **“Set up your server”** documentation to embed the component within your MCP server response. - -> ✅ **Recommendation:** Use component UI templates for production. - -During development, rebuild your component bundle whenever React code changes for live updates. - ---- diff --git a/.gitignore b/.gitignore index 5ef6a52..a846611 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# smoke / local test artifacts +.smoke/ diff --git a/README.md b/README.md index 2c752d0..9151c06 100644 --- a/README.md +++ b/README.md @@ -1,174 +1,85 @@ -# GraphGPT — Create Charts in ChatGPT | Visualize Data with AI +# Oraxen | Minecraft Custom Items Plugin -**Create beautiful, responsive charts and graphs directly inside ChatGPT.** GraphGPT is the easiest way to visualize data in ChatGPT. Generate line charts, bar graphs, pie charts, and area charts from your conversations without leaving the chat interface. +**Oraxen** is a free, open-source Minecraft plugin for Spigot and Paper servers. Create unlimited custom items, blocks, furniture, and armor with automatic resource pack generation. No manual resource pack creation required. -**[Try GraphGPT Now →](https://graphgpt.app)** | **[Installation Guide →](https://graphgpt.app/#how-it-works)** +**[Download Free →](https://oraxen.com)** | **[Documentation →](https://docs.oraxen.com)** -![GraphGPT creating a chart in ChatGPT - Data visualization tool](https://graphgpt.app/tutorial/graphGPT_installation_step3.webp) - ---- +![Oraxen showcase](https://oraxen.com/assets/demo.png) ## Features -- **Visualize Data Instantly**: Generate charts from pasted tables, CSV files, or natural language descriptions—perfect for ChatGPT data visualization. -- **Multiple Chart Types**: Supports line charts, bar graphs, pie charts, and area charts for comprehensive data analysis. -- **Simple Install**: Connect to the MCP server in seconds with no authentication required—works with any ChatGPT account. -- **Interactive & Responsive**: Charts are rendered with Recharts in a secure iframe and adapt to desktop, tablet, and mobile screens. -- **Customizable**: Tweak the title, colors, dimensions, axes labels, and data keys to match your brand or analysis needs. - ---- - -## How to Use GraphGPT - -GraphGPT can visualize data from your prompts. Simply describe what you want to chart in ChatGPT: - -- "Plot monthly revenue from this table." -- "Show revenue vs expenses as a multi-line chart." -- "Create a pie chart of category shares." -- "Visualize sales data as a bar graph." -- "Turn this CSV into a line chart showing trends over time." - -**Learn more:** [Browse example use cases →](https://graphgpt.app) - ---- - -## How to Install GraphGPT in ChatGPT - -Get GraphGPT set up in under 2 minutes: - -1. In ChatGPT, navigate to **Settings → Apps & Connectors**. -2. Click **Create** → **Advanced settings**. -3. Create a new developer connector with these details: - - **Name**: `GraphGPT` - - **MCP Server URL**: `https://graphgpt.app/mcp` - - **Authentication**: `No authentication` - -Once connected, select **GraphGPT** from the `+` menu in the message composer and ask it to create a chart. - -> **Example Prompt:** -> _"Create a line chart of monthly revenue: Jan 10, Feb 14, Mar 18. Set xKey to 'month' and yKey to 'value'."_ - -**📖 Full installation guide:** [Step-by-step tutorial with screenshots →](https://graphgpt.app) - ---- +- ✅ **Custom Items & Blocks** — Create items with custom textures and models via YAML +- ✅ **Automatic Resource Packs** — Auto-generated and hosted for players +- ✅ **Custom Furniture** — Build furniture with precise positioning and models +- ✅ **Custom Armor** — Component-based (1.21.2+) or trim-based (1.20-1.21.1) +- ✅ **Glyphs & Emoji** — Custom communication tools +- ✅ **Open Source** — Free with full API for developers -## Frequently Asked Questions +## Quick Start -### What is GraphGPT? -GraphGPT is a ChatGPT app that enables you to create charts and graphs directly inside your ChatGPT conversations. Simply describe your data, and GraphGPT generates beautiful visualizations. +### Installation -### What chart types does GraphGPT support? -GraphGPT supports four chart types: **line charts**, **bar graphs**, **pie charts**, and **area charts**. Each chart type is fully customizable with custom colors, titles, and data keys. +1. Download [CommandAPI](https://commandapi.jorel.dev/downloads) (required) +2. Download [Oraxen](https://www.spigotmc.org/resources/oraxen.72448/) from Spigot or [Polymart](https://polymart.org/resource/oraxen.629) +3. Place both `.jar` files in `/plugins/` +4. Restart server +5. Configure items in `/plugins/oraxen/items/` -### How do I add GraphGPT to ChatGPT? -Navigate to Settings → Apps & Connectors → Create → Advanced settings, then add GraphGPT using the MCP URL `https://graphgpt.app/mcp`. No authentication required. +**Compatibility:** Minecraft 1.18 - 1.21.4 | Spigot & Paper | ProtocolLib optional -### Can I visualize data from files or tables? -Yes! GraphGPT can generate charts from pasted tables, CSV data, or natural language descriptions. Just paste your data into ChatGPT and ask GraphGPT to visualize it. +### Usage -### Is GraphGPT free to use? -Yes, GraphGPT is completely free. Simply install the MCP connector and start creating charts in ChatGPT. +Create YAML files in `/plugins/oraxen/items/`: -### Does GraphGPT work on mobile? -Yes, all charts are responsive and adapt to mobile, tablet, and desktop screens. GraphGPT works seamlessly across all devices. - -**More questions?** [Visit our FAQ page →](https://graphgpt.app) - ---- - -## Technical Overview - -This repository contains a Next.js application that provides the charting widget and the MCP server. - -- **MCP Server (`app/mcp/route.ts`)**: Exposes a `render_chart` tool that accepts chart parameters. -- **Chart Widget (`app/chart/page.tsx`)**: A client page that renders a Recharts chart from `window.openai.toolOutput`. -- **Host Integration (`app/layout.tsx`)**: Includes bootstrap scripts to ensure correct asset loading and navigation inside the ChatGPT iframe. -- **CORS Middleware (`middleware.ts`)**: Handles cross-origin requests required for client-side navigation. - -The `render_chart` tool returns `structuredContent` with fields like `chartType`, `data`, `xKey`, `yKey`, and other options, which the widget page consumes to render the visualization. - ---- - -### Example Tool Payload - -```json -{ - "chartType": "line", - "title": "Monthly Revenue", - "xKey": "month", - "yKey": "revenue", - "height": 360, - "colors": ["#4f46e5"], - "data": [ - { "month": "Jan", "revenue": 10 }, - { "month": "Feb", "revenue": 14 }, - { "month": "Mar", "revenue": 18 } - ] -} +```yaml +items: + custom_sword: + displayname: "Custom Sword" + material: GOLDEN_SWORD + texture: items/my_sword + generate_model: GENERATE_ITEM ``` ---- +Players automatically receive the resource pack when joining. -## Local Development +## FAQ -1. Clone the repository. -2. Install dependencies: - ```bash - npm install - ``` -3. Run the development server: - ```bash - npm run dev - ``` +**What is Oraxen?** +A Minecraft plugin for creating custom items, blocks, furniture, and armor with automatic resource pack generation. -The application will be available at `http://localhost:3000`, and the MCP server will be at `http://localhost:3000/mcp`. +**Is it free?** +Yes, Oraxen is completely free and open source. ---- +**What versions are supported?** +Minecraft 1.18 through 1.21.4 on Spigot and Paper servers. -## Deployment +**What's required?** +CommandAPI (required) and ProtocolLib (recommended). -This project is optimized for deployment on [Vercel](https://vercel.com). The production deployment at **graphgpt.app** demonstrates the full ChatGPT chart visualization capabilities. +**Does it work with other plugins?** +Yes, integrates with BossShopPro, MythicMobs, ModelEngine, MMoItems, and more. -The repository includes: -- `baseUrl.ts` and `next.config.ts` for correct asset origins in iframes. -- `middleware.ts` for handling CORS on client-side RSC fetches. -- `app/sitemap.ts` and `public/robots.txt` configured for SEO. +## Development -After deploying, connect ChatGPT to your production MCP URL: `https://your-app.vercel.app/mcp`. Live example: [GraphGPT Production →](https://graphgpt.app) +This is the Oraxen website built with Next.js 15, Tailwind CSS, and TypeScript. ---- +### Setup -## Project Structure - -``` -app/ - chart/ # Client page that renders Recharts from tool output - mcp/ # MCP server exposing tools and resources - layout.tsx # Root layout with metadata & iframe bootstrap - page.tsx # Landing page with install steps and FAQs -middleware.ts # CORS handling for RSC -next.config.ts # Asset prefixing for iframe compatibility +```bash +pnpm install +pnpm run dev ``` ---- - -## Why GraphGPT? - -**GraphGPT** is the **simplest way to create charts in ChatGPT**. Unlike external chart tools that require you to leave your conversation, GraphGPT renders visualizations directly inside ChatGPT's interface using the Model Context Protocol (MCP). - -**Perfect for:** -- 📊 **Data analysts** who want quick visualizations during ChatGPT conversations -- 💼 **Business professionals** creating charts from reports and tables -- 🎓 **Students** visualizing data for projects and presentations -- 🧪 **Researchers** turning data into insights without switching tools +Visit `http://localhost:3000` -**[Get started with GraphGPT →](https://graphgpt.app)** +### Deploy ---- +Optimized for Vercel. Configured with SEO, sitemap, and robots.txt. -## Related Resources +## Links -- [OpenAI Apps SDK Documentation](https://developers.openai.com/apps-sdk) -- [Model Context Protocol (MCP)](https://modelcontextprotocol.io) -- [Next.js Documentation](https://nextjs.org/docs) -- [Recharts Documentation](https://recharts.org) +- 🌐 **Website:** [oraxen.com](https://oraxen.com) +- 📚 **Docs:** [docs.oraxen.com](https://docs.oraxen.com) +- 📦 **Spigot:** [Download](https://www.spigotmc.org/resources/oraxen.72448/) +- 🛒 **Polymart:** [Download](https://polymart.org/resource/oraxen.629) +- 💻 **GitHub:** [Source Code](https://git.io/oraxen) diff --git a/app/blog/[id]/page.tsx b/app/blog/[id]/page.tsx index ff4289c..27483fa 100644 --- a/app/blog/[id]/page.tsx +++ b/app/blog/[id]/page.tsx @@ -6,6 +6,7 @@ import { Metadata } from "next"; import Image from "next/image"; import Link from "next/link"; import { notFound } from "next/navigation"; +import { siteConfig } from "../../siteConfig"; interface ArticlePageProps { params: Promise<{ @@ -30,7 +31,7 @@ export async function generateMetadata({ title: post.frontmatter.title, description: post.frontmatter.description, alternates: { - canonical: `https://relens.ai/blog/${id}`, + canonical: `${siteConfig.url}/blog/${id}`, }, openGraph: { title: post.frontmatter.title, @@ -72,32 +73,32 @@ export default async function ArticlePage({ params }: ArticlePageProps) { "@type": "BlogPosting", headline: post.frontmatter.title, description: post.frontmatter.description, - image: `https://relens.ai${post.frontmatter.image}`, + image: `${siteConfig.url}${post.frontmatter.image}`, keywords: "GEO, Generative Engine Optimization, AI visibility, brand monitoring, AI SEO", author: { "@type": "Person", name: author?.name || post.frontmatter.author, - url: `https://relens.ai/blog/author/${post.frontmatter.author}`, + url: `${siteConfig.url}/blog/author/${post.frontmatter.author}`, }, publisher: { "@type": "Organization", - name: "ReLens AI", + name: siteConfig.name, logo: { "@type": "ImageObject", - url: "https://relens.ai/images/preview.png", + url: `${siteConfig.url}/logo.svg`, }, }, about: [ { "@type": "Thing", name: "Generative Engine Optimization" }, { "@type": "Thing", name: "AI SEO" }, ], - sameAs: ["https://relens.ai"], + sameAs: [siteConfig.url], datePublished: post.frontmatter.date, dateModified: post.frontmatter.modifiedDate, mainEntityOfPage: { "@type": "WebPage", - "@id": `https://relens.ai/blog/${id}`, + "@id": `${siteConfig.url}/blog/${id}`, }, }; @@ -112,11 +113,11 @@ export default async function ArticlePage({ params }: ArticlePageProps) {
Article -

+

{post.frontmatter.title}

-
+
-
{post.content}
+ {/* Article body */} +
+ {post.content} +
-