nanomcp
nanomcp
Это минималистичный демо-пример MCP, написанный вручную без использования MCP Python SDK. Он содержит полный цикл:
nanomcp.serverв качестве MCP-сервера, отправляющего и принимающего JSON-RPC через stdio.nanomcp.cliв качестве MCP-клиента/хоста, который запускает сервер и выполняетinitialize,tools/listиtools/call.Команда
chatвызывает OpenAI Chat Completions. После того как модель возвращает вызов функции/инструмента (function/tool call), CLI преобразует его в MCPtools/call, а затем отправляет результат работы инструмента обратно модели для генерации итогового ответа.
Связь между MCP и function call
В двух словах: function call — это возможность API модели, при которой «модель сообщает вашему приложению, какую функцию она хочет вызвать»; MCP — это протокол соединения, который определяет, «как ваше приложение использует единый протокол для обнаружения и вызова внешних инструментов или сервисов контекста».
Более конкретно:
Function/tool calling происходит между
LLM API <-> вашим приложением. Модель не выполняет функцию на самом деле, она лишь возвращает намерение вызова, например{"name":"get_weather","arguments":{...}}.MCP происходит между
вашим приложением <-> MCP-сервером. MCP-сервер предоставляет список инструментов и точку входа для их выполнения, напримерtools/listиtools/call.Хост/клиент выступает посредником. Сначала он получает схему инструментов от MCP-сервера и преобразует эти схемы в инструменты API модели; после того как модель выбирает инструмент, хост/клиент вызывает MCP-сервер.
Цепочка в данном проекте выглядит так:
用户问题
-> nanomcp.cli
-> OpenAI Chat Completions tools=function schemas
<- 模型返回 tool_calls
-> nanomcp.cli 把 tool_call 映射为 MCP tools/call
-> nanomcp.server 执行 get_weather 或 find_files
<- MCP tool result
-> nanomcp.cli 把结果发回模型
<- 模型最终回答Поэтому они находятся на разных уровнях:
Function call: 模型 API 的工具选择/参数生成机制
MCP: 应用连接工具服务器的标准协议Related MCP server: MCP Server Demo
Структура файлов
nanomcp/
nanomcp/
cli.py # MCP client + model caller
server.py # hand-written MCP server over stdio
tests/
test_protocol.py
pyproject.toml
README.mdЗапуск MCP напрямую, без вызова модели
Запустите в директории проекта:
cd ~/Desktop/nanomcp
python3 -m nanomcp.cli list-toolsПрямой вызов инструмента погоды:
python3 -m nanomcp.cli call get_weather '{"location":"Shanghai","unit":"celsius"}'Прямой вызов инструмента текущей даты и времени:
python3 -m nanomcp.cli call get_current_datetime '{"timezone":"Asia/Shanghai"}'Прямой вызов инструмента поиска файлов:
python3 -m nanomcp.cli call find_files '{"query":"*.pdf","max_results":5}'По умолчанию поиск ведется только в ~/Desktop. Вы можете временно расширить или сузить корневую директорию поиска:
NANOMCP_FILE_ROOT=~/Desktop/nanomcp python3 -m nanomcp.cli call find_files '{"query":"*.py"}'Запуск полной цепочки модель + MCP
Требуется API-ключ OpenAI. Здесь не используется OpenAI Python SDK, вместо этого для отправки HTTP-запросов используется стандартная библиотека urllib.
Рекомендуется записать локальную конфигурацию в .env:
cd ~/Desktop/nanomcp
cp .envtemplate .envЗатем отредактируйте .env:
OPENAI_API_KEY=你的 key
OPENAI_BASE_URL=https://api.openai.com/v1
NANOMCP_MODEL=gpt-4.1-mini
NANOMCP_TIMEZONE=Asia/ShanghaiФайл .env автоматически считывается CLI и уже добавлен в .gitignore.
cd ~/Desktop/nanomcp
python3 -m nanomcp.cli chat "上海今天天气怎么样?顺便帮我找桌面上的 PDF 文件"Модель по умолчанию — gpt-4.1-mini. Вы можете изменить её:
NANOMCP_MODEL=gpt-5-mini python3 -m nanomcp.cli chat "找一下这个项目里的 py 文件"Если вы используете шлюз, совместимый с OpenAI:
OPENAI_BASE_URL=http://localhost:8000/v1 python3 -m nanomcp.cli chat "上海天气怎么样?"Легкая проверка локальной конфигурации и MCP-сервера:
python3 -m nanomcp.cli doctorУстранение неполадок
Если chat выводит OpenAI API quota is exhausted (429 insufficient_quota), это означает, что API модели отклонило запрос: у проекта, к которому относится OPENAI_API_KEY, нет доступных квот или не настроен биллинг. Это не ошибка MCP-сервера, так как запрос был отклонен еще до того, как модель вернула вызов инструмента.
Порядок проверки:
python3 -m nanomcp.cli doctor
echo "$OPENAI_API_KEY"
cat .env
python3 -m nanomcp.cli call get_weather '{"location":"Shanghai"}'
OPENAI_BASE_URL=http://localhost:8000/v1 python3 -m nanomcp.cli chat "上海天气怎么样?"Первая команда отображает (без чувствительных данных) эффективную конфигурацию, проверяет, переопределяет ли shell файл
.env, и может ли MCP-сервер перечислить инструменты.Вторая команда подтверждает, установлен ли ключ в shell.
Третья команда подтверждает локальную конфигурацию в
.env.Четвертая команда проверяет, работает ли локальная цепочка MCP без зависимости от API модели.
Пятая команда демонстрирует, как переключиться на шлюз, совместимый с OpenAI.
Если вы по-прежнему используете официальный API OpenAI, вам нужно сменить ключ/проект, у которого есть квоты, или проверить биллинг и права доступа к модели.
Опциональная реальная погода
По умолчанию погода — это детерминированные демо-данные, что удобно для изучения протокола без сети или сторонних ключей. Чтобы попробовать реальный запрос:
NANOMCP_LIVE_WEATHER=1 python3 -m nanomcp.cli call get_weather '{"location":"Shanghai"}'Реальная погода использует https://wttr.in, при сбое автоматически происходит откат к демо-данным.
Тестирование
cd ~/Desktop/nanomcp
python3 -m unittest discover -s testsТестирование охватывает:
MCP
initializeMCP
tools/listMCP
tools/call get_weatherMCP
tools/call find_filesMCP
tools/call get_current_datetime
Ключевые наблюдения
Посмотрите на openai_tools_from_mcp() в nanomcp/cli.py: она преобразует схему инструментов MCP в схему инструментов функций OpenAI.
Посмотрите на run_chat(): после получения tool_calls от модели она вызывает mcp.call_tool(). Это и есть точка сопряжения MCP и function call.
Посмотрите на main() в nanomcp/server.py: он только читает stdin и пишет в stdout, каждая строка — это JSON-RPC. Сервер ничего не знает об OpenAI и не взаимодействует с моделью напрямую.
Available Tools
3 toolsfind_filesLocal file finderB
Find local files by name under the allowed root. The default root is ~/Desktop. Set NANOMCP_FILE_ROOT to change it.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Filename substring or glob pattern, such as *.pdf. | |
| root | No | Optional subdirectory under NANOMCP_FILE_ROOT. | |
| max_results | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It mentions the root directory and default, but it does not disclose important behaviors such as case sensitivity, recursion depth, glob pattern handling, permissions, or the structure of returned results.
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 extremely concise: two sentences. The first sentence states purpose and scope, the second provides configuration info. Every sentence adds value with no redundancy.
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 there is no output schema, the description should hint at return format or behavior. It does not mention what is returned (file paths, metadata), sorting, recursion, or error handling. The tool is simple but the agent may need more context for correct invocation.
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 input schema already describes two of three parameters (query and root). The description adds context about the root default and environment variable configuration, but does not enhance understanding of max_results or clarify glob pattern syntax beyond what the schema provides.
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 clearly states the tool's function: 'Find local files by name under the allowed root.' It specifies the scope (local files) and the constraint (under a root). The siblings are unrelated (datetime and weather), so there is no ambiguity.
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?
The description provides no explicit guidance on when to use this tool versus alternatives. It does not mention when not to use it or any prerequisites. Given that siblings are unrelated, implicit guidance is minimal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_current_datetimeCurrent date and timeA
Get the current date, time, and weekday. Use this for questions about today, current time, current date, or weekday.
| Name | Required | Description | Default |
|---|---|---|---|
| timezone | No | IANA timezone name, such as Asia/Shanghai or America/New_York. Defaults to NANOMCP_TIMEZONE or Asia/Shanghai. | Asia/Shanghai |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full burden. It adequately describes the output (date, time, weekday) and timezone parameter. However, it does not mention that the operation is read-only, instantaneous, or any potential dependencies, leaving some behavioral details implicit.
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 two sentences, concise and front-loaded with the core function. Every sentence serves a purpose without redundancy.
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 the tool's simplicity (one optional parameter, no output schema), the description fully covers what the tool does, its possible output, and appropriate use cases. No gaps remain.
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?
With full schema coverage (100%), the description adds no new parameter details beyond the schema. The schema already describes the timezone parameter well, so the description provides minimal added value, meeting the baseline of 3.
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 clearly states the tool retrieves current date, time, and weekday. It explicitly lists use cases like 'today, current time, current date, or weekday', and siblings are unrelated, making purpose unambiguous.
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?
The description directly states when to use the tool ('for questions about today, current time, current date, or weekday'). It does not provide exclusions or alternatives, but given the simplicity and distinct siblings, this is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_weatherWeather lookupA
Get current weather for a city. By default this returns deterministic demo data. Set NANOMCP_LIVE_WEATHER=1 to try wttr.in.
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | City or place name, for example Shanghai. | |
| unit | No | Temperature unit. | celsius |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the burden. It discloses the demo/live behavior and environment variable, but lacks details on return format, error handling, or external API dependencies.
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?
Two sentences efficiently define purpose and critical behavioral context. No superfluous text.
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 simple weather tool, the description covers core purpose and key behavioral nuance. However, it omits return value structure or typical properties, which would help the agent understand the output.
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?
Input schema covers 100% of parameters with descriptions. The description adds no additional parameter meaning beyond what the schema provides, meeting baseline.
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 clearly states 'Get current weather for a city,' using a specific verb and resource, and distinguishes from siblings like find_files and get_current_datetime.
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 explains the default demo mode and how to switch to live data, providing context for when to expect real or synthetic data. No explicit alternatives or exclusions but sufficient for this tool.
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.
3 tool updates
v0.1.0- First observed
find_files - First observed
get_current_datetime - First observed
get_weather
TDQS
Scored across 3 tools
Each tool has a clear, distinct purpose: file search, datetime, and weather. No overlap or ambiguity.
All tool names follow the verb_noun snake_case pattern consistently: find_files, get_current_datetime, get_weather.
Three tools is small but appropriate for a 'nano' server intended as a minimal utility collection. Not too few given its scope.
The tools cover only three disparate areas with no clear domain. As a general utility set, common operations like calculations or text processing are missing, but it may be intentionally limited.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Related MCP Servers
- AlicenseBqualityDmaintenanceA demonstration MCP server that provides example tools for weather queries, time retrieval, and request handling, along with advice prompts. Supports both HTTP and stdio modes for testing MCP client integrations.4MIT
- AlicenseNot gradedqualityDmaintenanceA minimal Model Context Protocol server demo that exposes tools through HTTP API, including greeting, weather lookup, and HTTP request capabilities. Demonstrates MCP server implementation with stdio communication and HTTP gateway functionality.7 npmISC
- FlicenseNot gradedqualityDmaintenanceA minimal MCP server demo in Python that exposes five tools for arithmetic and a simulated long-running process.-
- FlicenseNot gradedqualityDmaintenanceA basic MCP server demonstrating tool registration and SSE transport, enabling AI clients to call greeting, arithmetic, and time tools.-