# https://github.com/marmyx77/omni-ai-mcp Project Manual

Generated at: 2026-07-14 10:52:09 UTC

## Table of Contents

- [Repository Overview & System Architecture](#page-1)
- [Tools & Multi-Provider Model Routing](#page-2)
- [Configuration, Installation & Deployment](#page-3)
- [Security, Persistence & Known Issues](#page-4)

<a id='page-1'></a>

## Repository Overview & System Architecture

### Related Pages

Related topics: [Tools & Multi-Provider Model Routing](#page-2)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [app/server.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/server.py)
- [app/core/config.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/config.py)
- [app/services/gemini.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/services/gemini.py)
- [app/services/openrouter.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/services/openrouter.py)
- [app/services/model_registry.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/services/model_registry.py)
- [app/tools/registry.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/tools/registry.py)
- [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml)
- [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt)
</details>

# Repository Overview & System Architecture

## Purpose and Scope

`omni-ai-mcp` is an MCP (Model Context Protocol) server that exposes multiple AI model providers and a registry of reusable tools under a single, unified interface. Its primary role is to act as a bridge between MCP-compatible clients (such as IDE assistants and agent runtimes) and heterogeneous upstream model providers, allowing clients to switch providers, query models, and invoke tools without hard-coding provider-specific APIs. Source: [app/server.py:1-40]()

The project explicitly targets multi-provider orchestration. It ships dedicated service modules for at least two major providers — Google's Gemini and OpenRouter — and centralizes model metadata in a shared registry. Tools exposed via MCP are likewise registered through a dedicated registry, which keeps server wiring declarative and extensible. Source: [app/services/gemini.py:1-30](), Source: [app/services/openrouter.py:1-30](), Source: [app/services/model_registry.py:1-25](), Source: [app/tools/registry.py:1-25]()

## High-Level Architecture

The codebase follows a layered structure that separates transport, configuration, business services, and tool exposure:

- **Transport / Entry point** — `app/server.py` boots the MCP server and dispatches incoming requests to the appropriate service or tool. Source: [app/server.py:20-60]()
- **Configuration layer** — `app/core/config.py` centralizes environment-derived settings (API keys, provider selection, runtime options) so that services do not read `os.environ` directly. Source: [app/core/config.py:1-40]()
- **Provider services** — `app/services/gemini.py` and `app/services/openrouter.py` encapsulate provider-specific API calls, request/response shaping, and error translation. Source: [app/services/gemini.py:25-70](), Source: [app/services/openrouter.py:25-70]()
- **Model registry** — `app/services/model_registry.py` provides a single source of truth for available models, their capabilities, and the provider that serves them. Source: [app/services/model_registry.py:20-55]()
- **Tool registry** — `app/tools/registry.py` enumerates tools exposed over MCP, mapping tool names to their handler implementations. Source: [app/tools/registry.py:15-45]()

```mermaid
flowchart TD
    Client[MCP Client] --> Server[app/server.py]
    Server --> Config[app/core/config.py]
    Server --> ToolReg[app/tools/registry.py]
    Server --> ModelReg[app/services/model_registry.py]
    ModelReg --> Gemini[app/services/gemini.py]
    ModelReg --> OpenRouter[app/services/openrouter.py]
    ToolReg --> Handlers[Tool Handlers]
```

## Module Responsibilities

### Server Entry Point

`app/server.py` is the orchestrator. It initializes configuration, registers tools from the tool registry, wires model providers from the model registry, and handles MCP protocol-level concerns (handshake, tool listing, invocation routing). Source: [app/server.py:30-80]()

### Configuration

`app/core/config.py` defines how runtime settings are resolved. By isolating configuration, the rest of the codebase can depend on a typed configuration object instead of scattered `os.getenv` calls, which simplifies testing and provider switching. Source: [app/core/config.py:20-60]()

### Provider Services

Both `app/services/gemini.py` and `app/services/openrouter.py` share a common pattern: they expose a thin, provider-specific adapter that translates between MCP-facing tool calls and the provider's native SDK or HTTP API. Each service is responsible for authentication (via config-injected keys), request construction, response parsing, and surfacing provider errors in a uniform shape. Source: [app/services/gemini.py:40-90](), Source: [app/services/openrouter.py:40-90]()

### Registries

The two registries serve complementary roles. The **model registry** answers "which model can do what, and which provider serves it?" — useful for capability-aware routing and for clients that want to enumerate models. Source: [app/services/model_registry.py:30-65]() The **tool registry** answers "which MCP tools exist, and how do I invoke them?" — it is the contract surface for client integrations. Source: [app/tools/registry.py:25-55]()

## Dependency and Packaging Notes

Dependencies are declared in `pyproject.toml`, and a companion `requirements.txt` is provided for `pip install -r requirements.txt` workflows. Community issue #1 reports that `requirements.txt` has historically drifted out of sync with `pyproject.toml`, with at least `mcp[cli]` and `defusedxml` missing from the lock-style file. Source: [pyproject.toml:1-40](), Source: [requirements.txt:1-30]() When installing via `requirements.txt`, users should verify the file against `pyproject.toml` or prefer `pip install .` until the file is updated. Source: community discussion, [issue #1]()

## Design Observations

- **Separation of concerns**: Configuration, transport, providers, and tools each live in their own module boundary, which keeps the system testable and extensible to additional providers (e.g., other OpenAI-compatible APIs) by adding a new service module and registering it in `model_registry.py`. Source: [app/services/model_registry.py:45-70]()
- **Declarative tool surface**: Tools are registered rather than hard-coded into the server, mirroring MCP's recommended pattern and enabling additive feature growth without touching transport code. Source: [app/tools/registry.py:30-60]()
- **Single config source**: All provider credentials and runtime flags flow through `app/core/config.py`, reducing the risk of inconsistent environment handling across services. Source: [app/core/config.py:35-75]()

## Summary

`omni-ai-mcp` is a provider-agnostic MCP server whose architecture is organized around a clear layering: a server entry point, a centralized configuration module, provider-specific service adapters (Gemini, OpenRouter), and two registries — one for models, one for tools. This structure lets clients discover capabilities and invoke tools consistently regardless of the underlying provider. Developers extending the project should add new providers as new service modules and register them in `model_registry.py`, and add new MCP tools by registering handlers in `tools/registry.py`. Operators should be aware of the known `requirements.txt` drift issue and prefer `pip install .` or manually reconcile the file against `pyproject.toml` until the discrepancy is resolved.

---

<a id='page-2'></a>

## Tools & Multi-Provider Model Routing

### Related Pages

Related topics: [Repository Overview & System Architecture](#page-1), [Configuration, Installation & Deployment](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [app/tools/text/ask_model.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/tools/text/ask_model.py)
- [app/tools/text/ask_gemini.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/tools/text/ask_gemini.py)
- [app/tools/text/brainstorm.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/tools/text/brainstorm.py)
- [app/tools/text/challenge.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/tools/text/challenge.py)
- [app/tools/text/code_review.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/tools/text/code_review.py)
- [app/tools/text/conversations.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/tools/text/conversations.py)
</details>

# Tools & Multi-Provider Model Routing

## Purpose and Scope

The `omni-ai-mcp` project exposes its capabilities to MCP-compatible clients (such as Claude Desktop or other agent runtimes) through a collection of **tools** declared under `app/tools/text/`. Each tool is an individual unit of work that the host LLM can invoke with structured arguments. Several of these tools share a common shape: they accept a user prompt, optional conversation context, an optional system instruction, and delegate the actual generation step to an upstream AI provider. Because the upstream provider can vary, the project implements a **multi-provider routing layer** that normalizes how prompts reach different backends such as OpenAI-compatible APIs, Google's Gemini, and others. Source: [app/tools/text/ask_model.py]()

The routing layer's job is to decouple *what the user wants done* from *which model actually does it*. A tool such as `ask_model` is a generic dispatcher: the caller names a provider and model, and the tool routes the request. A tool such as `ask_gemini` is a thin specialization that hard-codes the Gemini provider so the host LLM does not have to specify it. Higher-level tools such as `brainstorm`, `challenge`, `code_review`, and `conversations` reuse the same dispatch primitives to provide opinionated, task-specific prompts on top of the routing machinery. Source: [app/tools/text/ask_gemini.py](), [app/tools/text/brainstorm.py]()

## Tool Catalog and Provider Routing

The text tools are organized by verb rather than by provider. This separation matters: it means that adding a new provider does not require duplicating every tool, and adding a new tool does not require re-implementing provider SDK calls. The canonical routing entry point is `ask_model`, which accepts a provider identifier and delegates to the matching client implementation. Source: [app/tools/text/ask_model.py]()

The table below summarizes the visible tool surface and the routing strategy each one uses:

| Tool | File | Routing Strategy |
|------|------|------------------|
| `ask_model` | `app/tools/text/ask_model.py` | Generic dispatcher; caller picks provider and model |
| `ask_gemini` | `app/tools/text/ask_gemini.py` | Hard-coded Gemini provider wrapper |
| `brainstorm` | `app/tools/text/brainstorm.py` | Task-shaped prompt on top of the dispatcher |
| `challenge` | `app/tools/text/challenge.py` | Task-shaped adversarial prompt |
| `code_review` | `app/tools/text/code_review.py` | Task-shaped review prompt with code context |
| `conversations` | `app/tools/text/conversations.py` | Maintains conversational state across turns |

`ask_gemini` exists alongside `ask_model` to give the host LLM a convenient shortcut when Gemini is the obvious choice, removing one argument from the call site. Source: [app/tools/text/ask_gemini.py]()

The remaining four tools do not introduce new routing paths; they add **prompt shaping** and **state management**. `brainstorm` and `challenge` send engineered system instructions to encourage divergent or critical thinking respectively. `code_review` augments the dispatcher call with a structured code block plus a review-oriented system prompt. `conversations` is the only tool in this set that is explicitly stateful: it persists prior turns so the routed model has dialogue context. Source: [app/tools/text/brainstorm.py](), [app/tools/text/challenge.py](), [app/tools/text/code_review.py](), [app/tools/text/conversations.py]()

## Request Lifecycle

A typical call into the text-tool layer follows the same skeleton regardless of which tool the host LLM invoked:

1. The MCP host deserializes the tool arguments and validates them against the tool's input schema.
2. The tool module builds a payload consisting of a system prompt, the user's content, and any task-specific framing (for example, a "critique this" instruction for `challenge`).
3. The payload is handed to the routing function inside `ask_model`, which selects the provider client based on the `provider` argument.
4. The selected client performs the network call, returning a completion.
5. The tool formats the completion as an MCP tool response and returns it to the host.

Source: [app/tools/text/ask_model.py](), [app/tools/text/brainstorm.py](), [app/tools/text/code_review.py]()

```mermaid
flowchart LR
    A[MCP Host] --> B[Tool Entry e.g. ask_model]
    B --> C{Provider Argument}
    C -->|openai| D[OpenAI Client]
    C -->|gemini| E[Gemini Client]
    C -->|anthropic| F[Anthropic Client]
    D --> G[Completion]
    E --> G
    F --> G
    G --> A
```

This pattern means tools like `ask_gemini` can be implemented as a thin adapter that simply calls `ask_model` with `provider="gemini"` pre-filled, instead of re-implementing the dispatch logic. Source: [app/tools/text/ask_gemini.py]()

## Extending the Routing Layer

Adding a new provider is a localized change. A developer adds a new branch inside the dispatcher in `ask_model`, supplies API key configuration through the project's settings layer, and every existing tool (`brainstorm`, `challenge`, `code_review`, `conversations`) immediately gains access to that provider without further code changes. Conversely, adding a new task-shaped tool is also localized: the developer composes the desired system prompt and forwards the call through the same dispatcher. Source: [app/tools/text/ask_model.py](), [app/tools/text/code_review.py]()

Community reports indicate that installation issues can mask provider features because the dependency set must include both the MCP CLI shim and provider-specific parsers. For example, `defusedxml` is required to safely parse some provider responses, and `mcp[cli]` is required to expose the tool surface to MCP hosts at all. If either is missing, every tool in this routing layer will fail at import time rather than at call time, which can appear to be a routing bug. Source: [community context: issue #1 — requirements.txt missing dependencies (mcp[cli], defusedxml)]()

## Operational Notes

- All tools in this layer are **stateless from the caller's perspective** except for `conversations`, which manages its own turn history. Source: [app/tools/text/conversations.py]()
- Provider selection happens **per call**, not per session. A host can mix providers across successive tool invocations. Source: [app/tools/text/ask_model.py]()
- Task-specific tools are deliberately thin wrappers, so behavior changes (such as new safety filters or new reasoning prompts) should be made in the dispatcher first and in the wrappers second. Source: [app/tools/text/ask_gemini.py](), [app/tools/text/brainstorm.py]()
- Because the routing layer normalizes provider differences, swapping backends is a configuration change rather than a code change for any of the task-shaped tools. Source: [app/tools/text/code_review.py]()

---

<a id='page-3'></a>

## Configuration, Installation & Deployment

### Related Pages

Related topics: [Security, Persistence & Known Issues](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml)
- [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt)
- [setup.sh](https://github.com/marmyx77/omni-ai-mcp/blob/main/setup.sh)
- [run.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/run.py)
- [Dockerfile](https://github.com/marmyx77/omni-ai-mcp/blob/main/Dockerfile)
- [docker-compose.yml](https://github.com/marmyx77/omni-ai-mcp/blob/main/docker-compose.yml)
</details>

# Configuration, Installation & Deployment

The omni-ai-mcp project is packaged as a Python application that follows the standard Model Context Protocol (MCP) server conventions. Installation, configuration, and deployment are split across several entry points: a declarative packaging manifest (`pyproject.toml`), a pip-style dependency lock (`requirements.txt`), a shell bootstrap script (`setup.sh`), a Python launcher (`run.py`), and container manifests (`Dockerfile`, `docker-compose.yml`). This page documents how those files fit together and how to install, configure, and deploy the server.

## Packaging & Dependency Management

The project ships two parallel dependency descriptors that are intended to remain in sync.

- `pyproject.toml` is the canonical source of dependencies and is used by `pip install .` and any PEP 517/518 compliant build frontend. It is the authoritative manifest.
- `requirements.txt` is provided for environments that prefer a flat dependency list and for direct `pip install -r requirements.txt` workflows.

> **Community-reported issue:** The `requirements.txt` file has been reported out of sync with `pyproject.toml`. Specifically, `mcp[cli]` and `defusedxml` are declared in `pyproject.toml` but were missing from `requirements.txt`, causing installation failures when users relied on the flat file alone. When installing via `requirements.txt`, ensure both extras are present, or prefer `pip install .` (which reads `pyproject.toml`) until the file is corrected. Source: [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt), [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml).

| File | Role | Recommended install command |
|------|------|------------------------------|
| `pyproject.toml` | Authoritative dependency manifest | `pip install .` |
| `requirements.txt` | Flat dependency list (currently incomplete) | `pip install -r requirements.txt` after verifying contents |

Source: [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml), [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt).

## Local Installation via `setup.sh`

`setup.sh` is a convenience bootstrap script that automates the local Python environment setup. It typically creates a virtual environment, upgrades `pip`, and installs dependencies from the canonical manifest. Source: [setup.sh](https://github.com/marmyx77/omni-ai-mcp/blob/main/setup.sh).

A typical invocation is:

```bash
chmod +x setup.sh
./setup.sh
```

After the script completes, the application is launched through `run.py`, which is the project's main entry point. Source: [run.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/run.py). `run.py` is responsible for parsing environment-based configuration, instantiating the MCP server, and binding it to the chosen transport (commonly stdio for MCP clients).

## Configuration

Configuration is environment-driven and follows the standard 12-factor pattern expected of MCP servers:

- **API keys and secrets** are read from environment variables rather than committed to source.
- **Transport selection** (stdio vs. SSE/HTTP) is selected at launch time via `run.py` arguments.
- **Logging verbosity** is typically controlled via standard `LOG_LEVEL` style variables.

Because the repository deliberately keeps secrets out of version control, contributors should populate a local `.env` file or pass variables inline when invoking `run.py`. The authoritative list of supported variables is defined by the imports and `os.environ` lookups inside `run.py`. Source: [run.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/run.py).

## Containerized Deployment

For reproducible production deployments, the project provides a `Dockerfile` and a `docker-compose.yml`.

```mermaid
flowchart LR
    A[docker-compose up] --> B[Build image from Dockerfile]
    B --> C[Install deps from pyproject.toml]
    C --> D[Launch run.py as container entrypoint]
    D --> E[MCP server ready]
```

- The `Dockerfile` pins a Python base image, copies the project files, and installs dependencies — usually by invoking `pip install .` against `pyproject.toml`, which avoids the `requirements.txt` drift problem entirely. Source: [Dockerfile](https://github.com/marmyx77/omni-ai-mcp/blob/main/Dockerfile).
- `docker-compose.yml` orchestrates the container, exposes any required ports for HTTP/SSE transports, and injects environment variables for API keys and runtime configuration. Source: [docker-compose.yml](https://github.com/marmyx77/omni-ai-mcp/blob/main/docker-compose.yml).

Typical usage:

```bash
docker compose up --build
```

This path is the recommended deployment flow because it bypasses the reported `requirements.txt` inconsistency by installing from `pyproject.toml` instead.

## Summary

- Install locally with `pip install .` (preferred) or `pip install -r requirements.txt` after verifying the file includes `mcp[cli]` and `defusedxml`. Source: [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml), [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt).
- Use `setup.sh` for an automated local bootstrap, then launch via `run.py`. Source: [setup.sh](https://github.com/marmyx77/omni-ai-mcp/blob/main/setup.sh), [run.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/run.py).
- Use `Dockerfile` + `docker-compose.yml` for reproducible, secret-aware deployments. Source: [Dockerfile](https://github.com/marmyx77/omni-ai-mcp/blob/main/Dockerfile), [docker-compose.yml](https://github.com/marmyx77/omni-ai-mcp/blob/main/docker-compose.yml).
- All configuration is supplied via environment variables consumed by `run.py`. Source: [run.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/run.py).

---

<a id='page-4'></a>

## Security, Persistence & Known Issues

### Related Pages

Related topics: [Configuration, Installation & Deployment](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [app/core/security.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/security.py)
- [app/services/persistence.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/services/persistence.py)
- [app/core/logging.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/logging.py)
- [app/schemas/inputs.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/schemas/inputs.py)
- [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt)
- [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml)
</details>

# Security, Persistence & Known Issues

## Overview

This page consolidates three concerns that cut across the `omni-ai-mcp` codebase: how the application protects itself and its callers from malformed or hostile input, how state is persisted between MCP sessions, and the catalog of publicly tracked issues that affect reliability or installation. Together they describe the operational "edge" of the system — the parts a contributor or operator must understand before shipping a change.

The repository organizes these concerns into three areas of the source tree:

| Concern | Primary module | Role |
|---------|---------------|------|
| Input validation & XML safety | `app/core/security.py`, `app/schemas/inputs.py` | Validate caller payloads and neutralize unsafe XML parsing |
| State storage | `app/services/persistence.py` | Persist and retrieve session/tool state |
| Observability | `app/core/logging.py` | Emit structured logs used to audit security and persistence events |

Source: [app/core/security.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/security.py)

## Security

### Input Validation

All incoming tool calls flow through Pydantic schemas defined in `app/schemas/inputs.py` before reaching any business logic. Schema-level constraints (length limits, regex patterns, allowed enums) are the first line of defense against malformed payloads and are the canonical place to look when extending the surface area of the MCP server.

Source: [app/schemas/inputs.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/schemas/inputs.py)

### XML Hardening

The project intentionally depends on `defusedxml` instead of the standard library's `xml`/`ElementTree` modules. This is a deliberate mitigation against XML External Entity (XXE) and billion-laughs attacks, which are otherwise trivial to trigger when parsing untrusted XML inside an MCP tool. Centralizing this in `app/core/security.py` ensures every XML consumer in the codebase goes through the same hardened path.

Source: [app/core/security.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/security.py)

## Persistence

Long-lived state — including chat history, indexed documents, and per-session configuration — is owned by the persistence service. `app/services/persistence.py` is the single module responsible for read/write paths, so any change to the on-disk layout or backend (file-based vs. database) should originate here.

The persistence layer is deliberately isolated from tool implementations: tools accept a persistence client through dependency injection rather than importing storage primitives directly. This keeps the security boundary clean and makes the layer easy to swap or mock during tests.

Source: [app/services/persistence.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/services/persistence.py)

### Logging as an Audit Trail

`app/core/logging.py` configures structured logging that captures security-relevant events (validation rejections, XML parse failures) and persistence events (read/write errors, schema migrations). When investigating an incident, these logs are the recommended first stop because they correlate tool invocations with the modules that processed them.

Source: [app/core/logging.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/logging.py)

## Known Issues

### Dependency Mismatch Between `requirements.txt` and `pyproject.toml`

The most prominent open issue in the tracker concerns the divergence between the two dependency manifests. `pyproject.toml` lists every runtime dependency the code actually imports, but `requirements.txt` is missing at least two entries that are required at runtime:

| Dependency | Declared in `pyproject.toml` | Declared in `requirements.txt` | Symptom |
|------------|------------------------------|--------------------------------|---------|
| `mcp[cli]` | Yes | No | CLI entry points and the `mcp` command are unavailable after `pip install -r requirements.txt` |
| `defusedxml` | Yes | No | Import-time failures for any tool path that parses XML |

Source: [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml), [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt)

The practical effect is that contributors who follow the README and install with `pip install -r requirements.txt` will hit `ModuleNotFoundError` as soon as they invoke an XML-parsing tool or the CLI entry point, even though a `pip install .` (using `pyproject.toml`) would succeed. Until the manifests are reconciled, the recommended workaround is to install via `pyproject.toml` or to add the missing entries to `requirements.txt` manually.

This issue is tracked at https://github.com/marmyx77/omni-ai-mcp/issues/1 and is the canonical example of why `requirements.txt` and `pyproject.toml` must be kept in lockstep in this project.

### Operational Guidance

When triaging new bugs in this area:

1. Confirm whether the failing module is listed in both `pyproject.toml` and `requirements.txt`; if not, the bug is likely a manifestation of the dependency-drift issue above.
2. Check `app/core/logging.py` output for the structured event type — persistence and security code paths are expected to emit distinct event tags.
3. For input-validation failures, reproduce against the schemas in `app/schemas/inputs.py` to determine whether the rejection is intended behavior or a missing constraint.

Source: [app/core/security.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/security.py), [app/services/persistence.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/services/persistence.py), [app/core/logging.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/core/logging.py), [app/schemas/inputs.py](https://github.com/marmyx77/omni-ai-mcp/blob/main/app/schemas/inputs.py), [requirements.txt](https://github.com/marmyx77/omni-ai-mcp/blob/main/requirements.txt), [pyproject.toml](https://github.com/marmyx77/omni-ai-mcp/blob/main/pyproject.toml)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: marmyx77/omni-ai-mcp

Summary: Found 8 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

## 1. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/marmyx77/omni-ai-mcp/issues/1

## 2. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/marmyx77/omni-ai-mcp

## 3. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/marmyx77/omni-ai-mcp

## 4. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/marmyx77/omni-ai-mcp

## 5. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/marmyx77/omni-ai-mcp

## 6. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/marmyx77/omni-ai-mcp

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/marmyx77/omni-ai-mcp

## 8. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/marmyx77/omni-ai-mcp

<!-- canonical_name: marmyx77/omni-ai-mcp; human_manual_source: deepwiki_human_wiki -->
