Skip to content

Latest commit

 

History

History
288 lines (223 loc) · 8.57 KB

File metadata and controls

288 lines (223 loc) · 8.57 KB

Agentic React

Agentic React is a monorepo for React runtime inspection and local-dev MCP integrations. The packages are published under the @agentic-react namespace.

Demos

Single Select

Single Select demo

Multiselect

Multiselect demo

Packages

  • @agentic-react/core: bundler-agnostic browser runtime, React selection toolkit, and MCP primitives.
  • @agentic-react/vite: Vite adapter for local dev.
  • @agentic-react/webpack: Webpack adapter for local dev.
  • @agentic-react/next: Next.js adapter for local dev.

For full local-dev features, install the adapter for your bundler. The adapter depends on @agentic-react/core internally, so app users do not need to import both packages.

Local Dev Usage

Vite

pnpm install @agentic-react/vite -D
// vite.config.ts
import { defineConfig } from 'vite';
import AgenticReact from '@agentic-react/vite';

export default defineConfig({
  plugins: [AgenticReact()],
});

The Vite adapter injects the core browser runtime, attaches the runtime bridge to the dev server, and exposes MCP over:

http://localhost:<vite-port>/mcp

Webpack

pnpm install @agentic-react/webpack -D
// webpack.config.mjs
import withAgenticReactWebpack from '@agentic-react/webpack';

export default (env, argv) =>
  withAgenticReactWebpack(config, { mode: argv.mode });

The Webpack adapter prepends a generated runtime entry, attaches the runtime bridge to webpack-dev-server, and exposes MCP at:

http://localhost:<webpack-dev-server-port>/mcp

Next.js

pnpm install @agentic-react/next -D
// next.config.mjs
import withAgenticReactNext from '@agentic-react/next';

export default withAgenticReactNext(nextConfig);

The Next adapter injects the browser runtime through Next's Webpack config and starts a local bridge server. By default MCP is available at:

http://127.0.0.1:51426/mcp

Runtime-Only Usage

Use @agentic-react/core directly when you only need browser-side selection/runtime APIs and do not need local source-file lookup or MCP dev-server wiring.

pnpm install @agentic-react/core
import { createSelectionToolkit } from '@agentic-react/core';

const toolkit = createSelectionToolkit();
toolkit.enable();

Runtime-only mode can inspect the live browser tree, but it cannot read or edit local files. Source lookup and local MCP transport are the adapter layer's job.

What Adapters Add

@agentic-react/core runs in the browser and can select elements, inspect React fibers, highlight components, format selection context, and expose window.__AGENTIC_REACT__ / window.__AGENTIC_REACT_TOOLS__.

Bundler adapters add local-dev capabilities that the runtime cannot know on its own:

  • inject the core runtime automatically
  • attach a local MCP Streamable HTTP /mcp endpoint
  • bridge MCP calls from Node to the browser runtime
  • provide local source-root context for source lookup
  • keep dev-only tooling out of production bundles

Tuning Modal API

The selection overlay includes a tuning modal for turning visual adjustments into prompt text. Configure it through the adapter toolkit option, or at runtime with window.__AGENTIC_REACT__.setToolkitConfig().

import type { ToolkitConfig } from '@agentic-react/vite';

// Import ToolkitConfig from the adapter package you use.
const toolkit: ToolkitConfig = {
  enabled: true,
  defaultVisible: true,
  defaultExpanded: false,
  position: 'bottom-right',
  offset: { x: 20, y: 20 },
  accentColor: '#111827',
  zIndex: 2147483000,
  iconUrl: '/agentic-react-logo.png',
  tuningModal: {
    classNames: {
      surface: 'my-tuning-surface',
      panel: 'my-tuning-panel',
      control: 'my-tuning-control',
    },
    styles: {
      panel: { border: '1px solid rgba(15, 23, 42, 0.18)' },
      targetTag: { background: '#f8fafc', color: '#0f172a' },
    },
    tokens: {
      panelRadius: '14px',
      controlRadius: '10px',
      primaryButtonBackground: '#0f766e',
      primaryButtonColor: '#ffffff',
      panelShadow: '0 24px 72px rgba(15, 118, 110, 0.22)',
    },
  },
};

tuningModal.classNames adds classes to modal slots. tuningModal.styles applies inline style objects to the same slots. Supported slots are root, surface, panel, arrow, title, body, targetTag, customPromptForm, customPromptInput, customPromptButton, sectionTitle, row, label, controlWrap, control, colorInput, numberInput, stepperButton, select, textarea, suffix, and closeButton.

tuningModal.tokens maps camelCase token names to CSS variables prefixed with --agentic-react-tuning-. For example, panelRadius becomes --agentic-react-tuning-panel-radius, and primaryButtonBackground becomes --agentic-react-tuning-primary-button-background. Built-in controls currently read tokens such as panelBackground, panelBorder, panelRadius, panelShadow, panelColor, controlBorder, controlRadius, controlBackground, controlColor, labelColor, sectionColor, primaryButtonBorder, primaryButtonBackground, primaryButtonColor, secondaryButtonBackground, and secondaryButtonColor.

Adapters pass the config as:

// Vite
AgenticReact({ toolkit });

// Webpack
withAgenticReactWebpack(config, { mode: 'development' }, { toolkit });

// Next.js
withAgenticReactNext(nextConfig, { toolkit });

For structural extensions, register a browser-side tuning modal extension. Slot renderers can add custom DOM before fields, after fields, or in the footer. wrapModal receives the modal surfaceElement and panelElement, which lets design systems add wrappers, data attributes, observers, portals, or cleanup-aware behavior around the rendered modal.

const unregister = window.__AGENTIC_REACT__?.registerTuningModalExtension({
  id: 'design-system-audit',
  beforeFields({ container, context }) {
    const badge = document.createElement('div');
    badge.textContent = `Editing ${context.tagName}`;
    badge.className = 'agentic-design-system-badge';
    container.appendChild(badge);
  },
  wrapModal({ surfaceElement, actions }) {
    surfaceElement.dataset.designSystem = 'acme';
    const onTransitionEnd = () => actions.requestReposition();
    surfaceElement.addEventListener('transitionend', onTransitionEnd);
    return () => {
      surfaceElement.removeEventListener('transitionend', onTransitionEnd);
    };
  },
});

Concrete playground example:

// playground/agentic-react-vite-playground/vite.config.js
AgenticReact({
  toolkit: {
    iconUrl: '/agentic-react-logo.png',
    tuningModal: {
      classNames: {
        surface: 'vite-playground-tuning-surface',
        panel: 'vite-playground-tuning-panel',
        control: 'vite-playground-tuning-control',
      },
      tokens: {
        panelRadius: '14px',
        controlRadius: '10px',
        primaryButtonBackground: '#0f766e',
        primaryButtonColor: '#ffffff',
        panelShadow: '0 24px 72px rgba(15, 118, 110, 0.22)',
      },
      styles: {
        surface: {
          filter: 'drop-shadow(0 18px 40px rgba(15, 118, 110, 0.16))',
        },
        panel: {
          border: '1px solid rgba(15, 118, 110, 0.22)',
        },
        targetTag: {
          background: '#ecfeff',
          color: '#0f766e',
        },
        sectionTitle: {
          color: '#0f766e',
        },
      },
    },
  },
});

Custom Tools

Adapters accept browser-side custom tools. Import shared types from the adapter package you use:

import type { ToolResultValue } from '@agentic-react/vite';

export default function logMessage(args: { message: string }): ToolResultValue {
  return {
    success: true,
    message: `Received: ${args.message}`,
  };
}
import { defineConfig } from 'vite';
import AgenticReact from '@agentic-react/vite';
import { z } from 'zod';
import logMessage from './src/tools/logMessage';

export default defineConfig({
  plugins: [
    AgenticReact({
      customTools: [
        {
          name: 'log-message',
          description: 'Log a message in the browser runtime',
          schema: z.object({ message: z.string() }),
          clientFunction: logMessage,
        },
      ],
    }),
  ],
});

Development

pnpm run build
pnpm run playground:vite
pnpm run playground:webpack
pnpm run playground:next
pnpm run playground:nx-mf

For e2e automation, Playwright uses fixed local ports configured in the playground package configs.

Acknowledgement

This project is inspired by vite-plugin-vue-mcp.

License

MIT