# How OpenSEO Monitors AI Search Visibility: Architecture and Implementation

> OpenSEO monitors AI search visibility with a three-layer pipeline querying DataForSEO API, storing metrics in PostgreSQL/SQLite, and rendering results via React Router.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: architecture
- Published: 2026-08-05

---

**OpenSEO tracks AI search visibility through a three-layer pipeline that queries DataForSEO’s AI-search API via an MCP tool, persists brand mention metrics to PostgreSQL or SQLite, and renders real-time results through a TanStack React Router interface.**

OpenSEO (from the repository `every-app/open-seo`) treats **AI search visibility** as a core SEO signal alongside traditional rankings. The platform monitors how brands appear in AI-driven search results—such as ChatGPT responses and Google AI Overviews—by tracking mentions, citations, and referring domains. This article breaks down the exact implementation, from the feature definition in the frontend to the DataForSEO API integration on the backend.

## The Three-Layer Monitoring Architecture

OpenSEO’s **AI search visibility** monitoring consists of distinct layers that handle feature configuration, routing, and data collection.

### 1. Feature Definition in the UI Schema

The feature specification lives in [`web/src/lib/feature-pages.ts`](https://github.com/every-app/open-seo/blob/main/web/src/lib/feature-pages.ts) at lines 537–606. This file declares the "AI Brand Visibility" feature and defines the four metrics that constitute **AI search visibility**:

- **Mentions** – How often the brand appears in AI-generated responses
- **Citations** – The number of pages citing the brand
- **Platforms** – Which AI platforms (ChatGPT, Google AI Overview, etc.) contain the citations
- **Cited Domains** – The count of distinct domains that cite the brand

This configuration also maps the "Find visibility gaps" workflow and FAQ content that explains the monitoring methodology to end users.

### 2. Route Registration and Page Rendering

The frontend route is registered in [`web/src/routes/_marketing/features/ai-brand-visibility.tsx`](https://github.com/every-app/open-seo/blob/main/web/src/routes/_marketing/features/ai-brand-visibility.tsx) at lines 9–20 using TanStack React Router. This file wires the URL path `/features/ai-brand-visibility` to the generic `FeaturePageTemplate` component.

When a user navigates to this route, the template fetches the latest **AI search visibility** data from the server and renders the four metric cards defined in the feature schema. The route file itself handles the layout and initial data loading, delegating the metric display to the reusable template.

### 3. Backend Data Collection via MCP

The data acquisition happens in [`src/server/mcp/tools/dataforseo-research-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/dataforseo-research-tools.ts). This **Multi-Chain Processor (MCP) tool** communicates directly with DataForSEO’s AI-search endpoints to retrieve brand monitoring data.

The tool constructs a POST request to `/ai/search/brand-lookup` with the target domain and requested metrics:

```typescript
const response = await dataForSeoClient.post('/ai/search/brand-lookup', {
  domain,
  metrics: ['mentions', 'citations', 'platforms', 'cited_domains'],
});

```

The response is normalized into a structured payload (`{ mentions: number, citations: number, platforms: number, citedDomains: number }`) and returned to the frontend. According to the `every-app/open-seo` source code, this data is persisted in the database schema defined in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts), which supports both PostgreSQL and SQLite backends.

## How the Data Pipeline Works

The **AI search visibility** pipeline operates in real-time when a user accesses the feature page. The flow follows this sequence:

1. **User Request** – The TanStack Router triggers a loader function that calls the backend API
2. **MCP Processing** – The [`dataforseo-research-tools.ts`](https://github.com/every-app/open-seo/blob/main/dataforseo-research-tools.ts) MCP tool validates the domain and constructs the DataForSEO API request
3. **External Query** – DataForSEO returns raw brand mention data from ChatGPT, Google AI Overview, and other platforms
4. **Normalization** – The tool sorts results by `visibility` (the default ordering) and extracts the four key metrics
5. **Persistence** – Results are stored in the database tables defined in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts) for historical tracking
6. **Rendering** – The frontend receives the JSON payload and displays it through the `FeaturePageTemplate`

This architecture allows the system to run on-demand when users open the page, or via scheduled background jobs for continuous monitoring.

## Implementation Examples

### Client-Side Data Fetching with TanStack Query

The frontend consumes **AI search visibility** data using a custom React Hook built on TanStack Query. This pattern handles caching, loading states, and error boundaries:

```tsx
import { useQuery } from '@tanstack/react-query';

function useAiBrandVisibility(domain: string) {
  return useQuery(['aiBrandVisibility', domain], async () => {
    const res = await fetch(`/api/ai-brand-visibility?domain=${domain}`);
    if (!res.ok) throw new Error('Failed to load AI visibility');
    return res.json(); // { mentions, citations, platforms, citedDomains }
  });
}

// Example component
export function AiVisibilityCard({ domain }: { domain: string }) {
  const { data, isLoading, error } = useAiBrandVisibility(domain);
  if (isLoading) return <div>Loading…</div>;
  if (error) return <div>Error loading visibility</div>;

  return (
    <div className="grid grid-cols-4 gap-4">
      <Metric label="Mentions" value={data.mentions} />
      <Metric label="Citations" value={data.citations} />
      <Metric label="Platforms" value={data.platforms} />
      <Metric label="Cited domains" value={data.citedDomains} />
    </div>
  );
}

```

### Server-Side Route Handler

The API endpoint that serves the frontend is implemented using TanStack Server Router. The handler in [`src/server/routes/ai-brand-visibility.ts`](https://github.com/every-app/open-seo/blob/main/src/server/routes/ai-brand-visibility.ts) (or similar) invokes the MCP tool:

```typescript
import { createServerRoute } from '@tanstack/server-router';
import { getAiBrandVisibility } from '@/server/mcp/tools/dataforseo-research-tools';

export const Route = createServerRoute('/api/ai-brand-visibility')({
  async loader({ request }) {
    const url = new URL(request.url);
    const domain = url.searchParams.get('domain');
    if (!domain) throw new Error('Domain required');
    const visibility = await getAiBrandVisibility(domain);
    return new Response(JSON.stringify(visibility), {
      headers: { 'Content-Type': 'application/json' },
    });
  },
});

```

## Summary

- OpenSEO monitors **AI search visibility** as a distinct signal from traditional SEO, tracking how brands appear in ChatGPT and Google AI Overview responses.
- The monitoring pipeline spans three layers: feature definition in [`web/src/lib/feature-pages.ts`](https://github.com/every-app/open-seo/blob/main/web/src/lib/feature-pages.ts), routing in [`web/src/routes/_marketing/features/ai-brand-visibility.tsx`](https://github.com/every-app/open-seo/blob/main/web/src/routes/_marketing/features/ai-brand-visibility.tsx), and data collection via the MCP tool in [`src/server/mcp/tools/dataforseo-research-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/dataforseo-research-tools.ts).
- Four core metrics—**mentions**, **citations**, **platforms**, and **cited domains**—are fetched from the DataForSEO API and persisted in the database schema defined in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts).
- The frontend uses TanStack Query for data fetching and React Router for navigation, providing real-time visibility into AI-driven brand presence.

## Frequently Asked Questions

### What metrics does OpenSEO track for AI search visibility?

OpenSEO tracks four primary metrics for **AI search visibility**: **Mentions** (how often the brand appears in AI responses), **Citations** (the volume of pages citing the brand), **Platforms** (which AI systems contain the citations), and **Cited Domains** (the number of unique referring domains). These metrics are defined in [`web/src/lib/feature-pages.ts`](https://github.com/every-app/open-seo/blob/main/web/src/lib/feature-pages.ts) and provide a comprehensive view of brand presence across generative search results.

### How does OpenSEO fetch AI brand mention data?

The platform uses a **Multi-Chain Processor (MCP) tool** located in [`src/server/mcp/tools/dataforseo-research-tools.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/dataforseo-research-tools.ts) to fetch data. This tool sends authenticated requests to the DataForSEO API endpoint `/ai/search/brand-lookup`, passing the target domain and requested metrics. The tool then normalizes the response and sorts results by visibility before returning the data to the frontend or persisting it to the database.

### Where is AI visibility data stored in OpenSEO?

**AI search visibility** data is stored in the relational database schema defined in [`src/db/schema.ts`](https://github.com/every-app/open-seo/blob/main/src/db/schema.ts). OpenSEO supports both PostgreSQL and SQLite backends. The MCP tool writes the normalized metrics (mentions, citations, platforms, cited domains) to this schema, enabling historical tracking and trend analysis for monitored domains.

### Can the AI visibility monitoring be automated?

Yes. While the **AI search visibility** feature runs on-demand when a user opens the `/features/ai-brand-visibility` page, the MCP-based architecture supports scheduled background jobs. You can configure cron jobs or queue workers to periodically invoke the `getAiBrandVisibility` function for specific domains, ensuring the database always contains fresh AI-search metrics without requiring manual page loads.