MCP Knowledge Assistant
MCP Knowledge Assistant
Сервер Model Context Protocol (MCP) только для чтения, который позволяет ИИ-клиенту выполнять поиск по базе знаний и получать полные исходные документы. Проект начинается с небольшого локального прототипа, а затем применяет тот же контракт инструментов к семантическому поиску в векторном хранилище OpenAI.
Что это демонстрирует
Проектирование MCP-инструментов с узкими обязанностями
searchиfetchСтруктурированные входные и выходные данные с использованием FastMCP и Pydantic
Семантический поиск по загруженным документам в векторном хранилище OpenAI
Дедупликация на уровне документов, когда векторный поиск возвращает несколько подходящих фрагментов
Потоковые транспорты MCP: Streamable HTTP и
stdioСквозное использование инструментов через OpenAI Responses API и защищённый MCP-туннель
Настройка через переменные окружения, без учётных данных в исходном коде
Модульные и протокольные тесты, не выполняющие платных вызовов API
Related MCP server: File AI
Архитектура
OpenAI Responses API
|
| MCP tool calls through an outbound secure tunnel
v
Local FastMCP server (Streamable HTTP)
|
| vector-store search and file retrieval
v
OpenAI vector store -> uploaded documentsРепозиторий также включает полностью локальный учебный путь:
Local demo client -> FastMCP server (stdio) -> data/documents.jsonОба сервера предоставляют один и тот же публичный контракт инструментов:
Инструмент | Входные данные | Назначение |
|
| Возвращает компактные релевантные ссылки на документы. |
|
| Получает один полный документ, выбранный через поиск. |
Разделение поиска и получения данных позволяет не отправлять полные документы до того, как они понадобятся, и даёт модели стабильные идентификаторы документов для последующих вызовов.
Структура проекта
.
├── data/documents.json # Sample local knowledge base
├── sample_data/cats.pdf # Public-domain vector-store sample
├── src/mcp_knowledge_assistant/
│ ├── knowledge_base.py # Local keyword retrieval
│ ├── models.py # Shared response schemas
│ ├── server.py # Local stdio MCP server
│ └── vector_store_server.py # OpenAI vector-store MCP server
├── tests/ # Offline unit and MCP tests
├── demo_client.py # Local stdio demonstration
├── vector_store_demo_client.py # Direct HTTP MCP demonstration
└── api_client.py # Responses API + secure tunnel demonstrationТребования
Python 3.11 или новее
Проект OpenAI API с включённой оплатой для пути через векторное хранилище
Включённый образец PDF или собственный документ, загруженный в векторное хранилище OpenAI
Клиент туннеля OpenAI только для демонстрации защищённого туннеля
Локальный JSON-сервер и полный набор тестов не требуют API-ключа.
Атрибуция образца документа
Демонстрация с векторным хранилищем использует Cats: Their Points and Characteristics У. Гордона Стэблса, электронная книга Project Gutenberg №43429. Образец PDF размещён OpenAI и создан на основе издания Project Gutenberg. См. PDF-файл с информацией о лицензии Project Gutenberg и применимых условиях повторного использования.
Настройка
Клонируйте репозиторий, создайте виртуальное окружение и установите проект:
python -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"Для примеров с OpenAI скопируйте шаблон окружения:
cp .env.example .env.localЗатем добавьте собственные значения в .env.local:
OPENAI_API_KEY=your_project_api_key
VECTOR_STORE_ID=vs_your_vector_store_id.env.local, настройки PyCharm, виртуальные окружения и локальные профили туннеля
исключены из Git.
1. Запуск локального прототипа
Первый сервер использует stdio, поэтому MCP-клиент запускает его как дочерний процесс
и взаимодействует через стандартный ввод и вывод:
python demo_client.pyДемо обнаруживает оба инструмента, выполняет поиск по образцовой JSON-базе знаний и получает выбранный документ.
Вы также можете запустить сервер через установленную команду:
mcp-knowledge-assistantМолчаливый ожидающий процесс — это нормально для stdio-сервера без подключённого
клиента.
2. Запуск сервера с векторным хранилищем
Загрузите sample_data/cats.pdf в векторное хранилище OpenAI, затем задайте
OPENAI_API_KEY и VECTOR_STORE_ID в .env.local. При желании вы можете
использовать собственный документ и запрос. Запустите сервер Streamable HTTP:
mcp-vector-store-assistantПо умолчанию его MCP-эндпоинт:
http://127.0.0.1:8000/mcpВо втором терминале проверьте эндпоинт напрямую:
python vector_store_demo_client.pyВекторный поиск работает с фрагментами, поэтому длинный документ может дать несколько
совпадений с одним и тем же идентификатором файла. MCP-инструмент search намеренно
сворачивает эти совпадения в один результат по документу. Затем инструмент fetch
получает и объединяет разобранное содержимое этого документа для модели.
3. Вызов через Responses API
Следуйте руководству OpenAI по защищённым MCP-туннелям,
чтобы создать туннель, настройте его игнорируемый локальный профиль на
http://127.0.0.1:8000/mcp и запустите клиент туннеля. Добавьте полученный ID в
.env.local:
MCP_TUNNEL_ID=tunnel_your_tunnel_idКлиент туннеля читает свои рабочие учётные данные из
CONTROL_PLANE_API_KEY. Храните это значение также локально. Когда векторный сервер
и клиент туннеля запущены, выполните:
python api_client.pyЗапрос к Responses API объявляет только инструменты MCP search и fetch для чтения.
Модель может выполнять поиск, получать выбранный источник и составлять ответ на основе
извлечённого содержимого.
Тесты
Запустите все тесты командой:
pytestТесты покрывают локальное ранжирование и получение данных, обнаружение MCP-инструментов, дедупликацию результатов векторного поиска, сборку содержимого и проверку входных данных. Вызовы OpenAI имитируются, поэтому набор тестов воспроизводим и не расходует API-кредиты.
Проектные решения и область применения
Только чтение: ни один MCP-инструмент не изменяет файлы или внешнее состояние.
Стабильный контракт совместимости:
search(query)возвращает ссылки на документы;fetch(id)возвращает полное содержимое и метаданные.Результаты по документам, а не по фрагментам: фрагменты — это доказательства поиска внутри векторного хранилища, а MCP-клиент получает стабильные идентификаторы файлов.
MCP — это уровень абстракции: для одного векторного хранилища, размещённого в OpenAI, встроенный инструмент File Search в Responses API проще. MCP становится полезным, когда один и тот же интерфейс поиска должен обслуживать несколько клиентов, скрывать детали бэкенда или в дальнейшем добавлять авторизацию и доменную логику.
Проверенная граница интеграции: локальные серверы, прямые MCP-клиенты и путь через Responses API с защищённым туннелем были опробованы в ходе разработки. Этот репозиторий не заявляет о развёрнутом публичном сервере или опубликованном приложении ChatGPT.
Замечания по безопасности
Никогда не коммитьте
.env.local, API-ключи, рабочие ключи туннеля или идентификаторы организаций.Используйте учётные данные с областью действия проекта и предоставляйте только необходимые разрешения.
Держите локальный MCP-сервер за защищённым исходящим туннелем, а не открывайте входящий порт в брандмауэре.
Проверяйте разрешения инструментов перед добавлением любых операций записи или действий с последствиями.
Ссылки
Available Tools
2 toolsfetchA
Retrieve one complete document using an ID returned by search.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| url | Yes | |
| text | Yes | |
| title | Yes | |
| metadata | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral disclosure burden. It reveals that this returns a complete document (not a summary) and that it depends on search-generated IDs, but doesn't mention error handling, permissions, or potential side effects. For a simple read operation this is adequate but has gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, no redundant details, and the key information (retrieve by ID) is front-loaded. Perfect conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema is present and there is only one parameter, the description sufficiently covers the essential context and its relationship to the sibling search tool. It could be improved by mentioning error cases or what happens if the ID is invalid, but for this simplicity it is complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'id' has no schema description, so the description's phrase 'returned by search' provides crucial semantic context, explaining where the ID comes from and how it should be used to retrieve the document.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Retrieve' with the resource 'one complete document' and the qualifier 'using an ID returned by search', which clearly defines the tool's scope and distinguishes it from the sibling tool 'search'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states that the ID must come from search, establishing a clear workflow (search first, then fetch). It doesn't explicitly mention alternatives, but the context is clear enough for an agent to know when to use this tool versus search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchC
Find documents relevant to a natural-language query.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that the tool does semantic matching over a natural-language query, but says nothing about how results are ranked, paginated, limited, scoped, or whether interactions are read-only or have side effects. It is not misleading, but it adds very little beyond what the name and schema already imply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with zero wasted words. It is appropriately brief for a minimal tool definition, though one could argue it is slightly under-specified—but the economy of expression is commendable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 1 parameter, no annotations, 0% schema coverage, and an unaddressed sibling 'fetch', one sentence is insufficient context. The description would be more complete by mentioning result limits, sort order, or any behavioral differences from fetch. The presence of an output schema helps explain return values, but the in/out behavior is still too thin for an agent to fully understand the tool's scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does add value by clarifying that 'query' accepts natural-language text rather than structured filters or keywords. However, it provides no examples, formatting hints, length limits, or syntax conventions—the description does the bare minimum to make the parameter actionable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
'Find documents relevant to a natural-language query' uses a clear verb ('find'), a resource ('documents'), and a scope qualifier ('natural-language query'). It is clear and specific, but it does not explicitly distinguish itself from its sibling 'fetch', so it earns a 4 rather than a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use search versus its sibling 'fetch', no exclusions, and no when-to-use context. The description implies usage through the term 'search', but a sibling tool with zero differentiator guidance means the agent is left without decision support. This is 'no guidance' and scores a 2.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
fetch - First observed
search
TDQS
Scored across 2 tools
search and fetch have clearly distinct purposes: one finds documents by query, the other retrieves a specific document by ID. There is no overlap or ambiguity.
Both tools use simple, consistent single-verb names ('search' and 'fetch') that clearly indicate their actions. The pattern is uniform.
With only 2 tools, the server is minimal but functionally complete for a simple search-and-retrieve pattern. It feels thin but is reasonable for a narrow purpose.
The two tools cover the core workflow of searching and retrieving documents. Minor gaps could include listing all documents or getting metadata, but the essential lifecycle is covered.
Maintenance
Related MCP Connectors
Read-only MCP server exposing a user ORANO library to their own AI agent.
Knowledge base MCP for AI agents on iknow.dev. Search, read, and maintain via OAuth.
Knowledge base for AI agents: search, read, tasks; write, correct, report outcomes via /mcp/write.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceAn MCP server that provides tools for retrieving and processing documentation through vector search, enabling AI assistants to augment their responses with relevant documentation context.24 npmMIT
- AlicenseBqualityDmaintenanceA read-only MCP server that provides document awareness for agents by parsing local files into structured profiles, blocks, chunks, and search results, enabling agents to understand and cite document content without dealing with raw file formats.543 npm3Apache 2.0
- FlicenseNot gradedqualityBmaintenanceAn MCP server that connects the Casio Plus knowledge base (playbooks, architecture, learning resources) to AI clients, offering read-only search and validation tools along with controlled feedback intake and review workflows.-
- AlicenseNot gradedqualityAmaintenanceMCP server that enables AI agents to search, fetch, and analyze a self-maintaining markdown knowledge base with provenance, drift detection, and canonical definitions.1MIT