# What Is the Model Context Protocol (MCP) Server in OpenSEO?

> Explore the Model Context Protocol MCP server in OpenSEO. Access powerful remote SEO tools like keyword research and SERP inspection via an HTTP endpoint for AI clients.

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

---

**The Model Context Protocol (MCP) server in OpenSEO is an HTTP endpoint at `/mcp` that exposes SEO-focused tools—keyword research, SERP inspection, backlink profiling, and more—as remote procedures callable by any MCP-compatible AI client such as Claude, Cursor, or Codex.**

OpenSEO's **MCP server** acts as a bridge between AI agents and the platform's backend SEO services. Rather than requiring custom API integrations, developers and SEO professionals can connect standard MCP clients to run real-time queries against OpenSEO's data. This article examines how the server is architected, how to call its tools, and where to find the source implementation in the every-app/open-seo repository.

## How the MCP Server Works

The server follows a layered request-handling pipeline defined across several TypeScript modules.

### Transport Layer: Receiving MCP Requests

Incoming HTTP requests hit **[`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts)**, which validates CORS headers, MCP protocol headers, and authentication credentials (OAuth or API key). Valid requests are dispatched to the MCP handler created by `createMcpHandler` from the `agents/mcp` package.

```typescript
// Conceptual flow from src/server/mcp/transport.ts
POST /mcp
  → validate CORS & headers
  → authenticate (Bearer token or OAuth)
  → createMcpHandler(req, res)
  → route to tool implementation

```

### Context Building: Scoped Access Control

The **[`src/server/mcp/context.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/context.ts)** module constructs a `ProjectMeta` object for each request. This context grants the AI client **scoped access levels**—typically `user`, `sam`, or `mcp`—ensuring tools operate only within authorized project boundaries.

### Authorization: Securing Tool Calls

Two files handle authorization:

- **[`src/server/mcp/project-auth.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/project-auth.ts)** – Verifies project-level permissions
- **[`src/server/mcp/api-key-auth.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/api-key-auth.ts)** – Validates API key authenticity and rate limits

### Tool Implementations: The SEO Logic

Individual tools live in **`src/server/mcp/tools/*`**. Each exports a function that receives a `ToolContext` and input arguments, then returns structured data wrapped by `mcpResponse()` from [`src/server/mcp/formatters.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/formatters.ts).

| Tool File | Purpose |
|-----------|---------|
| [`research-keywords.ts`](https://github.com/every-app/open-seo/blob/main/research-keywords.ts) | Keyword metrics and suggestions |
| [`get-serp-results.ts`](https://github.com/every-app/open-seo/blob/main/get-serp-results.ts) | Search engine results page data |
| [`list-projects.ts`](https://github.com/every-app/open-seo/blob/main/list-projects.ts) | Available project enumeration |
| [`get-domain-overview.ts`](https://github.com/every-app/open-seo/blob/main/get-domain-overview.ts) | Domain authority and backlink summary |

### Server Assembly: Wiring It Together

**[`src/server/mcp/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts)** registers the `/mcp` endpoint with the main Fastify server ([`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts)), attaches all tool handlers, and exports the configured MCP server instance.

## Calling the OpenSEO MCP Server

### Method 1: Direct HTTP with curl

```bash
curl -X POST https://app.openseo.so/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Method: whoami" \
  -H "Mcp-Name: whoami" \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -d '{}'

```

**Response format** (generated by [`src/server/mcp/formatters.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/formatters.ts)):

```json
{
  "result": {
    "type": "whoami",
    "userId": "12345",
    "scopes": ["user", "mcp"]
  }
}

```

### Method 2: Claude MCP CLI

```bash

# Register the OpenSEO server

claude mcp add --transport http --scope user openseo https://app.openseo.so/mcp

# Call a keyword research tool

claude mcp call openseo research-keywords '{"projectId":"proj_abc","keywords":["svelte","vite"]}'

```

See **[`/web/content/docs/claude-code-plugin.md`](https://github.com/every-app/open-seo/blob/main//web/content/docs/claude-code-plugin.md)** for complete setup instructions.

### Method 3: Programmatic JavaScript Client

```javascript
import { createMcpClient } from "agents/mcp/client";

const client = createMcpClient({
  url: "https://app.openseo.so/mcp",
  headers: { Authorization: `Bearer ${process.env.OPENSEO_API_KEY}` },
});

async function research() {
  const res = await client.call({
    method: "research-keywords",
    name: "research-keywords",
    args: { projectId: "proj_1", keywords: ["react hooks"] },
  });
  console.log(res);
}

research();

```

The call routes to [`src/server/mcp/tools/research-keywords.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/tools/research-keywords.ts), which queries OpenSEO's keyword-metrics database and returns structured results.

## Extending the MCP Server: Adding Custom Tools

New tools follow a consistent pattern. Here's an illustrative implementation:

```typescript
// src/server/mcp/tools/example-tool.ts
import { mcpResponse } from "@/server/mcp/formatters";
import { type ToolContext } from "@/server/mcp/context";

export async function exampleTool(ctx: ToolContext, input: { msg: string }) {
  return mcpResponse({
    result: { echo: input.msg, user: ctx.auth.userId },
    meta: { source: "mcp" },
  });
}

```

Register the tool in **[`src/server/mcp/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts)** to make it callable via the MCP protocol.

## Key Source Files for the MCP Server

| Path | Responsibility |
|------|----------------|
| [`src/server/mcp/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts) | Main MCP server registration and tool attachment |
| [`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts) | HTTP request validation and handler dispatch |
| [`src/server/mcp/context.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/context.ts) | Project-scoped context (`ProjectMeta`) construction |
| [`src/server/mcp/project-auth.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/project-auth.ts) | Project-level permission checks |
| [`src/server/mcp/api-key-auth.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/api-key-auth.ts) | API key validation |
| [`src/server/mcp/formatters.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/formatters.ts) | `mcpResponse`wrapper for tool results |
| `src/server/mcp/tools/*.ts` | Individual SEO tool implementations |
| [`web/content/docs/mcp.md`](https://github.com/every-app/open-seo/blob/main/web/content/docs/mcp.md) | User documentation for endpoint setup |
| [`web/content/docs/claude-code-plugin.md`](https://github.com/every-app/open-seo/blob/main/web/content/docs/claude-code-plugin.md) | Claude-specific integration guide |

## Summary

- The **Model Context Protocol (MCP) server** in OpenSEO exposes SEO tools via a standard HTTP endpoint at `/mcp`, enabling AI clients to invoke functions without custom integrations.
- **Request flow**: [`transport.ts`](https://github.com/every-app/open-seo/blob/main/transport.ts) validates → [`context.ts`](https://github.com/every-app/open-seo/blob/main/context.ts) scopes → auth modules authorize → tool handlers execute → [`formatters.ts`](https://github.com/every-app/open-seo/blob/main/formatters.ts) wraps responses.
- **Authentication** supports OAuth and API keys through dedicated modules in the MCP directory.
- **Tool implementations** reside in `src/server/mcp/tools/` and cover keyword research, SERP data, domain overview, backlink profiling, and project management.
- **Client options** include direct HTTP, Claude MCP CLI, and programmatic JavaScript using the `agents/mcp` package.

## Frequently Asked Questions

### What MCP clients can connect to OpenSEO's server?

Any client implementing the Model Context Protocol specification can connect. The repository explicitly documents **Claude**, **Cursor**, and **Codex** as verified compatible clients. The server exposes a standard HTTP transport, so other MCP-compatible agents should work provided they send proper `Mcp-Method` and `Mcp-Name` headers.

### How does authentication work for MCP requests?

Authentication occurs in **[`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts)** and **[`src/server/mcp/api-key-auth.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/api-key-auth.ts)**. Requests must include an `Authorization: Bearer <token>` header. The server validates OAuth tokens or API keys, then constructs a `ProjectMeta` context in **[`src/server/mcp/context.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/context.ts)** that scopes subsequent tool calls to authorized resources.

### What SEO data can AI agents access through the MCP server?

According to the tool implementations in `src/server/mcp/tools/`, agents can call functions for **keyword research**, **SERP result inspection**, **domain overview** (authority scores, backlink counts), **rank tracking**, **project context management**, and **Google Search Console data integration**. Each tool returns structured JSON via the `mcpResponse` formatter in **[`src/server/mcp/formatters.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/formatters.ts)**.

### Where is the MCP server endpoint mounted in the application?

The endpoint registers at **`/mcp`** on the main Fastify server. This occurs in **[`src/server/mcp/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/server.ts)**, which imports the transport configuration from **[`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts)** and attaches it to the application instance defined in the root [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) file.