# How to Set Up and Configure MCP Servers with omp

> Learn to set up and configure MCP servers with omp by defining them in JSON files. This guide simplifies your agent setup for efficient server management with oh-my-pi.

- Repository: [Can Bölük/oh-my-pi](https://github.com/can1357/oh-my-pi)
- Tags: how-to-guide
- Published: 2026-05-21

---

**You set up and configure MCP servers with omp by defining them in JSON configuration files at `~/.omp/agent/mcp.json` (user-level) or [`.omp/mcp.json`](https://github.com/can1357/oh-my-pi/blob/main/.omp/mcp.json) (project-level), which the agent discovers, validates through `validateServerConfig`, and hydrates at runtime via `loadAllMCPConfigs`.**

The `can1357/oh-my-pi` repository implements a sophisticated Model-Context-Protocol (MCP) server management system in its coding agent. When you set up and configure MCP servers with omp, you interact with a layered architecture that handles multi-source discovery, atomic configuration writes, and transport-specific validation.

## Configuration File Locations and Schema

`omp` recognizes two OMP-owned configuration paths that take precedence over standalone fallback files:

- **`~/.omp/agent/mcp.json`** – User-level settings applied across all projects
- **[`.omp/mcp.json`](https://github.com/can1357/oh-my-pi/blob/main/.omp/mcp.json)** – Project-level settings scoped to the current working directory

Standalone fallbacks ([`mcp.json`](https://github.com/can1357/oh-my-pi/blob/main/mcp.json), [`.mcp.json`](https://github.com/can1357/oh-my-pi/blob/main/.mcp.json)) are supported but not OMP-owned. Every configuration file follows the `MCPConfigFile` interface defined in [`packages/coding-agent/src/mcp/types.ts`](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/mcp/types.ts):

```json
{
  "$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json",
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
    },
    "github-copilot": {
      "type": "http",
      "url": "https://api.githubcopilot.com/mcp/"
    }
  },
  "disabledServers": ["legacy-server"]
}

```

The `$schema` property enables IDE auto-completion and validates against [`packages/coding-agent/src/config/mcp-schema.json`](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/config/mcp-schema.json). The `disabledServers` array allows you to ignore specific servers discovered from third-party tools without deleting their definitions.

## Discovery and Loading Pipeline

The `loadAllMCPConfigs` function in [`packages/coding-agent/src/mcp/config.ts`](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/mcp/config.ts) orchestrates server discovery:

1. **Capability gathering** – Invokes `loadCapability<MCPServer>` to collect servers from VS Code settings, `.claude/`, `.cursor/`, and [`opencode.json`](https://github.com/can1357/oh-my-pi/blob/main/opencode.json) directories via the `mcpCapability` system
2. **Normalization** – Converts discovered `MCPServer` objects to the legacy configuration shape using `convertToLegacyConfig` (lines 38-86)
3. **Filtering** – Applies the `disabledServers` list from the user config and optionally filters native Exa or browser servers
4. **Return** – Provides a map of active server names to validated `MCPServerConfig` objects alongside source metadata

```ts
import { loadAllMCPConfigs } from "./packages/coding-agent/src/mcp/config";

const { configs, sources } = await loadAllMCPConfigs(process.cwd());
// configs['filesystem'] contains the validated server configuration

```

## Validation Rules

Before any configuration persists, `validateServerConfig` in [`packages/coding-agent/src/mcp/config.ts`](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/mcp/config.ts) enforces strict requirements:

- **Transport exclusivity** – A server cannot define both `command` (stdio) and `url` (http/sse) simultaneously
- **Required fields by type** – `stdio` requires `command`; `http` and `sse` require `url`
- **Supported types** – Only `stdio`, `http`, and `sse` are valid transport values

Any validation error aborts the operation, ensuring only well-formed configurations reach the runtime.

## Writing Configurations Atomically

The [`packages/coding-agent/src/mcp/config-writer.ts`](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/mcp/config-writer.ts) module provides atomic write operations that prevent corruption during simultaneous edits:

```ts
// packages/coding-agent/src/mcp/config-writer.ts
export async function addMCPServer(
  filePath: string,
  name: string,
  config: MCPServerConfig
): Promise<void> {
  const errors = validateServerConfig(name, config);
  if (errors.length) throw new Error(`Invalid server config: ${errors.join("; ")}`);

  const existing = await readMCPConfigFile(filePath);
  const updated: MCPConfigFile = {
    ...existing,
    mcpServers: { ...existing.mcpServers, [name]: config },
  };
  await writeMCPConfigFile(filePath, updated);
}

```

The `writeMCPConfigFile` helper creates parent directories recursively, writes to a temporary file, then performs an atomic rename. It automatically injects the `$schema` reference if missing via the `withSchema` utility.

## CLI Management Commands

Interact with the configuration system through the `/mcp` sub-commands implemented in `packages/coding-agent/src/commands/mcp/*.ts`:

- **`/mcp add`** – Launches an interactive wizard invoking `addMCPServer`
- **`/mcp reload`** – Re-runs `loadAllMCPConfigs` and reconnects changed servers
- **`/mcp list`** – Displays each server’s originating configuration file
- **`/mcp test <name>`** – Validates connectivity (executes stdio commands or HTTP probes)
- **`/mcp reconnect <name>`** – Forces a reconnection for a specific server

## Practical Configuration Examples

### Add a stdio Filesystem Server (Project Level)

```ts
import { addMCPServer } from "./packages/coding-agent/src/mcp/config-writer";
import { getMCPConfigPath } from "@oh-my-pi/pi-utils";

const projectConfig = getMCPConfigPath("project", process.cwd());

await addMCPServer(projectConfig, "filesystem", {
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/docs"],
});

```

### Add an HTTP Server (User Level)

```ts
import { addMCPServer } from "./packages/coding-agent/src/mcp/config-writer";
import { getMCPConfigPath } from "@oh-my-pi/pi-utils";

const userConfig = getMCPConfigPath("user", process.cwd());

await addMCPServer(userConfig, "github", {
  type: "http",
  url: "https://api.githubcopilot.com/mcp/",
});

```

### Disable a Third-Party Server

```ts
import { setServerDisabled } from "./packages/coding-agent/src/mcp/config-writer";
import { getMCPConfigPath } from "@oh-my-pi/pi-utils";

const userConfig = getMCPConfigPath("user", process.cwd());

await setServerDisabled(userConfig, "vscode-legacy", true);

```

### Reload Configuration After Manual Edit

```bash

# Edit directly

vim .omp/mcp.json

# Reload runtime

omp /mcp reload

```

## Summary

- **OMP-owned paths** – Use `~/.omp/agent/mcp.json` for global settings and [`.omp/mcp.json`](https://github.com/can1357/oh-my-pi/blob/main/.omp/mcp.json) for project-specific servers
- **Atomic writes** – All modifications use temp-file-and-rename patterns in [`config-writer.ts`](https://github.com/can1357/oh-my-pi/blob/main/config-writer.ts) to prevent corruption
- **Strict validation** – `validateServerConfig` enforces transport-specific requirements before persistence
- **Discovery layering** – `loadAllMCPConfigs` aggregates servers from omp files and third-party tools like VS Code settings
- **CLI integration** – The `/mcp` commands provide interactive and automated management without manual JSON editing

## Frequently Asked Questions

### What is the difference between user-level and project-level MCP configuration in omp?

User-level configuration resides at `~/.omp/agent/mcp.json` and applies globally across all projects, while project-level configuration at [`.omp/mcp.json`](https://github.com/can1357/oh-my-pi/blob/main/.omp/mcp.json) is scoped to the specific directory. The system merges these hierarchically, with project settings taking precedence for overlapping server names, and also respects standalone fallbacks like [`mcp.json`](https://github.com/can1357/oh-my-pi/blob/main/mcp.json) that are not OMP-owned.

### How does omp validate MCP server configurations before saving them?

The `validateServerConfig` function in [`packages/coding-agent/src/mcp/config.ts`](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/mcp/config.ts) checks for mutually exclusive `command` and `url` fields, ensures `stdio` transports include a `command` property, requires `url` for `http` or `sse` types, and validates that the `type` field contains only supported values (`stdio`, `http`, `sse`). Any violation returns an error array that prevents the write operation.

### Can I disable an MCP server without deleting its configuration?

Yes. Add the server name to the `disabledServers` array in your user-level configuration using `setServerDisabled` from [`config-writer.ts`](https://github.com/can1357/oh-my-pi/blob/main/config-writer.ts), or manually edit `~/.omp/agent/mcp.json`. During `loadAllMCPConfigs`, the system filters out disabled servers even if they are discovered from external sources like [`.vscode/settings.json`](https://github.com/can1357/oh-my-pi/blob/main/.vscode/settings.json) or `.cursor/` directories.

### What transport types are supported when configuring MCP servers?

The system supports three transport types defined in [`packages/coding-agent/src/mcp/types.ts`](https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/mcp/types.ts): `stdio` for local process execution, `http` for standard HTTP endpoints, and `sse` for Server-Sent Events connections. Each type has specific required fields—`command` for stdio and `url` for http/sse—which are strictly enforced during validation.