内容
# 厨房猫洞察MCP
[](https://www.python.org/)
[](https://www.docker.com/)
[](https://modelcontextprotocol.io/)
[](https://www.sqlalchemy.org/)
**厨房猫洞察MCP** 是一个独立的、只读的模型上下文协议服务器,用于估算厨房猫家庭中可能仍可用的食材,并对厨房猫中已保存的食谱进行排名。
它与厨房猫一起运行,不会修改或分叉厨房猫。所有估计都包含其支持证据,并且明确是概率性的。
## 导航
- [关于](#关于)
- [功能](#功能)
- [MCP工具](#mcp工具)
- [技术栈](#技术栈)
- [安装](#安装)
- [配置](#配置)
- [MCP客户端设置](#mcp客户端设置)
- [验证](#验证)
- [估计工作原理](#估计工作原理)
- [限制](#限制)
- [贡献](#贡献)
## 关于
厨房猫记录了物品添加到购物清单和从购物清单中移除的时间,但它不维护一个确认的家庭库存。该服务使用该历史记录来生成基于证据的估计,而不写入厨房猫。
`已丢弃`事件意味着物品从购物清单中移除了。它可能代表购买、删除或更正,因此服务永远不会将其视为确认购买。同样,供应估计也不代表新鲜度、保质期或食品安全。
## 功能
- 通过只读数据库连接与厨房猫连接。
- 在启动前验证所需的厨房猫模式。
- 通过SQLAlchemy支持SQLite和PostgreSQL。
- 从购物清单历史中重建物品消费周期。
- 使用确定性、可解释的计算来估计供应情况。
- 为每个估计报告概率、置信度、证据和警告。
- 对选定的厨房猫家庭中已保存的食谱进行排名。
- 将食材分为可能可用、不确定、可能缺失和未知。
- 通过厨房猫物品ID而非物品名称关联食谱和库存。
- 以只读根文件系统配置运行为非root容器。
- 支持`stdio`和Streamable HTTP MCP传输。
## MCP工具
### `获取库存估计`
返回家庭的估计库存状态,可选地按购物清单或物品ID过滤。
示例输入:
```json
{
"household_id": 1,
"list_id": 1,
"item_ids": [225, 469],
"include_unknown": true
}
```
可能的状态是:
- `可能可用`
- `不确定`
- `可能缺失`
- `未知`
### `推荐可用食谱`
根据食材的估计可用性对家庭中保存的食谱进行排名。
示例输入:
```json
{
"household_id": 1,
"list_id": 1,
"top_k": 5,
"include_optional": false
}
```
可能的分类是:
- `可能可能`
- `可能不确定`
- `可能缺少食材`
- `数据不足`
## 估计工作原理
服务解释厨房猫历史如下:
- `已添加`:物品进入购物清单,可能需要补充。
- `已丢弃`:物品离开购物清单,可能已购买、删除或更正。
- 完整的消费周期从`已丢弃`开始,到同一物品的下一个`已添加`事件结束。
- 典型持续时间是完整周期的中位数。
- 一个或两个完整周期产生低置信度。
- 三个或更多完整周期产生中等置信度。
- 旧清单历史永远不会产生高置信度。
- 当前在购物清单上的物品被视为可能缺失。
食谱分数使用以下权重:
| 食材状态 | 权重 |
| -------------------- | -----: |
| `可能可用` | 1.00 |
| `不确定` | 0.50 |
| `未知` | 0.25 |
| `可能缺失` | 0.00 |
默认情况下,可选食材不包含在分数中。
## 限制
- 厨房猫不区分旧历史中购买与其他清单项删除。
- 估计不考虑自由文本数量。
- 估计不表示新鲜度、保质期或食品安全。
- 只有厨房猫中已保存的食谱被排名。
- 历史记录不足导致置信度低或状态未知。
- 厨房猫模式更改可能需要兼容性更新。当需要表格或列时,服务会关闭。
- WAL模式下的SQLite实时数据库可能需要访问其边车文件。如果实时读取不稳定,请使用一致的只读快照。
参见[模式兼容性](docs/schema-compatibility.md)、
[观察到的模式](docs/observed-kitchenowl-schema.md)和
[故障排除](docs/troubleshooting.md)以获取更多详细信息。
## 技术栈
- [Python 3.12+](https://www.python.org/)
- [模型上下文协议Python SDK](https://github.com/modelcontextprotocol/python-sdk)
- [FastMCP](https://github.com/modelcontextprotocol/python-sdk)
- [SQLAlchemy 2](https://www.sqlalchemy.org/)
- [Pydantic 设置](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)
- [uv](https://docs.astral.sh/uv/)
- [pytest](https://pytest.org/)
- [Ruff](https://docs.astral.sh/ruff/)
- [Docker](https://www.docker.com/)
## 安装
### 先决条件
- 运行中的厨房猫安装。
- 对其SQLite或PostgreSQL数据库的只读访问权限。
- 用于容器部署的Docker和Docker Compose,或用于本地安装的Python 3.12+和`uv`。
### 使用SQLite的Docker Compose
推荐的安装使用已发布的跨架构镜像:
```text
ghcr.io/lukegskw/kitchenowl-insights-mcp:latest
```
下载Compose示例:
```sh
curl -O https://raw.githubusercontent.com/lukegskw/kitchenowl-insights-mcp/main/compose.example.yaml
```
在Docker主机上设置厨房猫SQLite数据库的路径并启动服务:
```sh
export KITCHENOWL_DATABASE_PATH=/path/to/kitchenowl/database.db
docker compose -f compose.example.yaml up -d
```
数据库文件必须可被UID/GID `10001:10001` 读取。如果厨房猫文件由其他帐户所有,请提供具有读取权限的UID/GID,而不授予写入权限:
```sh
export KITCHENOWL_INSIGHTS_UID_GID=1000:1000
docker compose -f compose.example.yaml up -d
```
要发布不同的主机端口,请设置:
```sh
export KITCHENOWL_INSIGHTS_PUBLISHED_PORT=18099
docker compose -f compose.example.yaml up -d
```
Streamable HTTP端点将在以下位置可用:
```text
http://<host>:8099/mcp
```
可以通过更改主机端口而不更改内部服务器端口来更改主机端口。例如,`18099:8099` 在主机端口 `18099` 上发布服务,同时在容器内继续侦听端口 `8099`。
### 从源代码构建容器
本地构建是可选的。如果您需要修改或审计容器构建,请优先使用上述发布的镜像。
```sh
git clone https://github.com/lukegskw/kitchenowl-insights-mcp.git
cd kitchenowl-insights-mcp
docker build -t kitchenowl-insights-mcp:local .
docker run --rm --read-only kitchenowl-insights-mcp:local --help
```
### 本地Python安装
```sh
git clone https://github.com/lukegskw/kitchenowl-insights-mcp.git
cd kitchenowl-insights-mcp
uv sync --frozen
```
针对只读SQLite数据库运行:
```sh
export KITCHENOWL_INSIGHTS_DATABASE_URL='sqlite+pysqlite:///file:/path/to/database.db?mode=ro&uri=true'
uv run kitchenowl-insights
```
### PostgreSQL
安装可选的PostgreSQL驱动程序:
```sh
uv sync --frozen --extra postgres
```
创建一个专用的PostgreSQL角色,只有:
- 数据库上的`CONNECT`。
- 所需模式上的`USAGE`。
- 所需表格上的`SELECT`。
- `default_transaction_read_only=on`。
然后通过秘密提供SQLAlchemy URL:
```text
postgresql+psycopg://<user>:<password>@<database-host>:5432/<database>
```
不要重用管理厨房猫的凭证。默认容器镜像是为SQLite构建的;PostgreSQL部署必须在构建镜像时包含可选的`postgres`包。
## 配置
所有设置都使用前缀`KITCHENOWL_INSIGHTS_`。
| 变量 | 必需 | 默认 | 描述 |
| ---------------------------------------- | -------- | --------- | ------------------------------------------------ |
| `KITCHENOWL_INSIGHTS_DATABASE_URL` | 是 | 无 | 只读SQLAlchemy数据库URL。 |
| `KITCHENOWL_INSIGHTS_TRANSPORT` | 否 | `stdio` | `stdio`或`streamable-http`。 |
| `KITCHENOWL_INSIGHTS_HOST` | 否 | `0.0.0.0` | HTTP绑定地址。 |
| `KITCHENOWL_INSIGHTS_PORT` | 否 | `8099` | 内部HTTP监听端口。 |
| `KITCHENOWL_INSIGHTS_LOG_LEVEL` | 否 | `INFO` | 应用程序日志级别。 |
| `KITCHENOWL_INSIGHTS_MAX_HISTORY_EVENTS` | 否 | `5000` | 每个请求加载的最大历史事件数。 |
| `KITCHENOWL_INSIGHTS_DEFAULT_TOP_K` | 否 | `5` | 默认食谱推荐数量。 |
| `KITCHENOWL_INSIGHTS_MAX_TOP_K` | 否 | `20` | 每个请求的最大推荐食谱数量。 |
| `KITCHENOWL_INSIGHTS_NOW_OVERRIDE` | 否 | 无 | 用于测试的确定性时钟覆盖。 |
秘密必须通过部署平台或环境提供,不得提交到存储库或包含在容器镜像中。
## MCP客户端设置
对于接受Streamable HTTP服务器定义的MCP客户端,请配置:
```yaml
mcp_servers:
kitchenowl_insights:
url: http://<host>:8099/mcp
```
如果MCP客户端在同一Docker网络上运行,请使用服务名称和内部端口代替发布主机端口:
```yaml
mcp_servers:
kitchenowl_insights:
url: http://kitchenowl-insights:8099/mcp
```
MCP客户端之间的配置格式不同。请参阅客户端文档以获取确切的属性名称,并在更改设置后重新加载或重启客户端。
## 验证
检查容器状态和日志:
```sh
docker compose ps
docker compose logs kitchenowl-insights
```
容器应报告`healthy`,并且不应记录模式、权限或数据库路径错误。
运行存储库验证套件:
```sh
uv sync --frozen
uv run ruff check .
uv run ruff format --check .
uv run pytest -v
```
验证本地数据库连接和应用程序级写保护:
```sh
uv run python scripts/verify_read_only.py \
'sqlite+pysqlite:///file:/path/to/database.db?mode=ro&uri=true'
```
最后,与MCP客户端连接并确认它列出两个工具。基本食谱测试应首先调用`recommend_available_recipes`,然后在需要食谱详细信息或正常厨房猫操作时使用另一个厨房猫集成。
## 贡献
欢迎贡献。在打开拉取请求之前:
```sh
uv sync --frozen
uv run ruff check .
uv run ruff format --check .
uv run pytest -v
docker build -t kitchenowl-insights-mcp:test .
```
对数据库查询的更改必须保留家庭隔离、模式验证、DSN重定向和两个独立的只读保护:数据库或卷权限和应用程序级拒绝可变SQL。