How to Manage Projects Using MCP Tools in OpenSEO: A Complete Guide
Use the list_projects, create_project, and project_context MCP tools via JSON-RPC POST requests to /mcp to programmatically manage OpenSEO projects and their shared memory.
Projects in OpenSEO serve as the core container for all SEO data, and the Model-Connect-Protocol (MCP) server exposes a unified interface for AI agents to manage them. According to the every-app/open-seo source code, these tools delegate to the same internal services used by the dashboard UI, ensuring consistent behavior across all clients.
MCP Architecture for Project Management
The MCP implementation follows a layered architecture that separates transport concerns from business logic. Understanding these components helps diagnose issues and extend functionality.
Transport and Authentication Layer
The MCP Transport Layer (src/server/mcp/transport.ts) handles request validation, CORS, and injects the authenticated user or organization scope into every request. This ensures that all subsequent tool executions respect the caller's permissions before reaching business logic.
Core Services
All MCP tools delegate to two primary services:
- Project Service (
src/server/features/projects/services/projects.ts) — Handles creation, listing, and metadata updates. Both the React dashboard and MCP tools callcreateProject()through this service. - Project-Context Service (
src/server/features/project-context/services/ProjectContextService.ts) — Manages the "shared memory" accessible to both the UI (SAM) and AI agents. This service guarantees that tags, notes, and saved keywords remain synchronized across interfaces.
Tool Registration
The MCP Tool Registry (src/server/mcp/server.ts) exposes the available methods to clients. Each tool is stateless: it receives a JSON-RPC request, delegates to the appropriate service, and returns a structured response containing human-readable text, metadata URLs, and machine-readable content.
Available MCP Tools for Project Operations
The OpenSEO MCP server exposes three primary tools for project management, each implemented in dedicated files under src/server/mcp/tools/.
list_projects
File: src/server/mcp/tools/list-projects.ts
Returns every project visible to the caller, scoped by organization or user. This tool accepts no arguments ({}) and returns an array of project objects containing id, name, domain, locationCode, languageCode, and url. When called with a user-scoped token, the response includes projects from all organizations the user belongs to, annotated with organization and organizationId fields.
create_project
File: src/server/mcp/tools/create-project.ts
Creates a new project within the caller's organization. The tool validates input using createProjectSchema, requiring name and optionally accepting domain, locationCode, and languageCode. The implementation mirrors the UI's server function exactly, ensuring data quality through shared validation logic.
project_context
File: src/server/mcp/tools/project-context.ts
Provides read/write access to per-project memory through two sub-operations:
get_project_context— Retrieves current context for a specifiedprojectIdupdate_project_context— Applies structured updates usingprojectContextUpdateSchema, supporting operations likeupserton sections such astags
Both operations route through ProjectContextService, maintaining consistency with the dashboard's state management.
Practical Implementation
All MCP calls follow JSON-RPC 2.0 over HTTP POST to the /mcp endpoint at https://app.openseo.so/mcp.
Request Format
Every request requires:
Authorization: Bearer <MCP-TOKEN>headerContent-Type: application/jsonheader- A JSON body with
jsonrpc: "2.0", a uniqueid, themethodname, and aparamsobject
The response always contains three keys:
text— Human-readable summary suitable for displaying to end usersmeta— Optional UI links, including dashboard URLsstructuredContent— Machine-parseable data for programmatic consumption
Listing Accessible Projects
Use list_projects to retrieve available project IDs before performing operations:
curl -X POST https://app.openseo.so/mcp \
-H "Authorization: Bearer <MCP-TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":"list-001",
"method":"list_projects",
"params":{}
}'
Sample response:
{
"jsonrpc":"2.0",
"id":"list-001",
"result":{
"text":"Projects (2):\n- proj_123 Acme (acme.com) market:2704/en",
"meta":{"url":"https://app.openseo.so/"},
"structuredContent":{
"projects":[
{
"id":"proj_123",
"name":"Acme",
"domain":"acme.com",
"locationCode":2704,
"languageCode":"en",
"url":"https://app.openseo.so/p/proj_123"
}
]
}
}
}
Creating a New Project
Invoke create_project with the required schema fields:
curl -X POST https://app.openseo.so/mcp \
-H "Authorization: Bearer <MCP-TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":"create-001",
"method":"create_project",
"params":{
"name":"New Brand",
"domain":"newbrand.com",
"locationCode":2704,
"languageCode":"en"
}
}'
The response includes the newly created project's ID and a direct dashboard URL in meta.url, allowing agents to immediately reference the project in the UI.
Managing Project Context
Read the current context state:
{
"jsonrpc":"2.0",
"id":"ctx-001",
"method":"get_project_context",
"params":{"projectId":"proj_123"}
}
Update the context by applying structured operations:
{
"jsonrpc":"2.0",
"id":"ctx-002",
"method":"update_project_context",
"params":{
"projectId":"proj_123",
"updates":[
{"section":"tags","operation":"upsert","payload":{"tag":"high-intent"}}
]
}
}
Both calls guarantee consistency with the SAM (Search Agent Manager) interface and dashboard UI because they share the ProjectContextService implementation.
Node.js Integration Example
The following snippet demonstrates production-ready patterns for managing projects using the MCP tools:
import fetch from 'node-fetch';
const MCP_ENDPOINT = 'https://app.openseo.so/mcp';
const TOKEN = process.env.MCP_TOKEN;
async function mcpCall(method, params = {}) {
const body = {
jsonrpc: '2.0',
id: `${method}-${Date.now()}`,
method,
params,
};
const res = await fetch(MCP_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${TOKEN}`,
},
body: JSON.stringify(body),
});
const json = await res.json();
return json.result;
}
// List all accessible projects
const list = await mcpCall('list_projects');
console.log('Projects:', list.structuredContent.projects);
// Create a project if none exist
if (list.structuredContent.projects.length === 0) {
const created = await mcpCall('create_project', {
name: 'Demo Project',
domain: 'demo.com',
locationCode: 2704,
languageCode: 'en',
});
console.log('Created:', created.structuredContent.project);
}
// Read project context
const ctx = await mcpCall('get_project_context', { projectId: 'proj_123' });
console.log('Context:', ctx.structuredContent);
This implementation references the same source files (src/server/mcp/tools/list-projects.ts, src/server/mcp/tools/create-project.ts, and src/server/mcp/tools/project-context.ts) that power the OpenSEO dashboard, ensuring that changes to server logic propagate immediately to MCP clients.
Summary
- MCP tools delegate to shared services —
list_projectsandcreate_projectusesrc/server/features/projects/services/projects.ts, while context operations useProjectContextService, ensuring UI and API consistency. - JSON-RPC 2.0 over HTTP POST — All interactions use the
/mcpendpoint with standard JSON-RPC framing and Bearer token authentication. - Three core operations — List existing projects, create new ones using
createProjectSchemavalidation, and read/write project memory viaget_project_contextandupdate_project_context. - Structured responses — Every tool returns
textfor humans,metafor UI links (built viasrc/server/mcp/urls.ts), andstructuredContentfor programmatic consumption. - Stateless architecture — The transport layer (
src/server/mcp/transport.ts) handles auth injection, while tools remain stateless and idempotent where possible.
Frequently Asked Questions
How does authentication work for MCP tools in OpenSEO?
The transport layer in src/server/mcp/transport.ts validates the Bearer token from the Authorization header and injects the authenticated user or organization scope into the request context. MCP tokens can be user-scoped (accessing projects across all organizations) or organization-scoped (restricted to a single organization), and this scope determines the visibility of projects in list_projects responses.
What data can be stored in project context?
The project_context tool stores arbitrary structured data defined by projectContextUpdateSchema, commonly including tags, saved keywords, research notes, and campaign configurations. Since ProjectContextService backs both the MCP tools and the SAM dashboard interface, any data written by an AI agent is immediately visible to human users in the UI, and vice versa.
Why do MCP tools return both text and structuredContent?
The dual-response format supports both human-in-the-loop workflows and fully automated pipelines. The text field provides a human-readable summary suitable for displaying in chat interfaces or logs, while structuredContent delivers machine-parseable JSON that clients can process without string parsing. The optional meta field contains dashboard URLs generated by src/server/mcp/urls.ts, allowing agents to link users directly to relevant UI views.
Can I use the same validation schemas as the OpenSEO UI?
Yes. The create_project tool explicitly uses createProjectSchema for input validation, ensuring that MCP-created projects meet the same data quality standards as those created through the dashboard. This shared validation layer prevents malformed entries and maintains database integrity across all entry points.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →