kitchenowl-insights-mcp
KitchenOwl Insights MCP
KitchenOwl Insights MCP is a standalone, read-only Model Context Protocol server that estimates which ingredients may still be available in a KitchenOwl household and ranks recipes already saved in KitchenOwl.
It uses strict validation, stdio and Streamable HTTP transports, a hardened container, and automated GHCR publication. It runs alongside KitchenOwl without modifying or forking it, and every estimate includes its supporting evidence.
Navigation
Related MCP server: Mealie MCP Server
Use this server
Use the published container image for a standard HTTP deployment, or clone the repository for local stdio use and development. Both workflows are documented in Installation.
Fork this repository when you want to propose changes through a pull request. See Contributing before submitting changes.
If this server is useful to you, consider giving the repository a star. It helps other KitchenOwl users discover the integration.
About
KitchenOwl records when items are added to and removed from shopping lists, but it does not maintain a confirmed household inventory. This server uses that history to produce evidence-based estimates without writing back to KitchenOwl.
The TypeScript foundation is based on the MCP TypeScript Starter, adapted with KitchenOwl-specific database access, domain logic, tools, and tests.
The default stdio transport is intended for local clients that launch the server as a child process. Streamable HTTP is stateless and creates a fresh MCP server for each request while sharing the read-only application context, so it can be replicated without MCP session storage.
The server reads one existing SQLite or PostgreSQL KitchenOwl database. It does not perform migrations, persist its own data, modify KitchenOwl records, provide telemetry, or authenticate HTTP callers.
Features
Registers tools with strict Zod input and output schemas.
Returns both human-readable content and typed structured content.
Includes accurate read-only MCP safety annotations.
Supports stdio and stateless Streamable HTTP.
Connects through read-only SQLite or PostgreSQL sessions.
Validates the required KitchenOwl schema before accepting MCP traffic.
Reconstructs item-consumption cycles from shopping-list history.
Reports probability, confidence, evidence, and warnings for every estimate.
Ranks recipes already saved in the selected KitchenOwl household.
Associates recipes and inventory by KitchenOwl item ID rather than item name.
Uses Hono with Host and Origin validation against DNS rebinding.
Limits tool inputs and HTTP request bodies.
Keeps stdout exclusive to MCP protocol messages in stdio mode.
Handles SIGINT and SIGTERM with idempotent graceful shutdown.
Runs as a non-root container with read-only-root-filesystem support.
Tests configuration, database behavior, MCP behavior, Hono routes, and real traffic.
Publishes multi-architecture images only after quality checks pass.
MCP tools
get_inventory_estimate
Returns estimated inventory states for a household, optionally filtered by shopping list or item IDs.
Example input:
{
"household_id": 1,
"list_id": 1,
"item_ids": [225, 469],
"include_unknown": true
}Example structured output:
{
"household_id": 1,
"as_of": "2026-07-19T18:00:00Z",
"items": [
{
"item_id": 225,
"name": "Eggs",
"state": "uncertain",
"availability_probability": 0.5,
"confidence": "low",
"typical_duration_days": 10,
"completed_cycles": 2,
"currently_on_list": false,
"last_dropped_at": "2026-07-15T12:00:00Z",
"evidence": [
{
"kind": "legacy_drop",
"occurred_at": "2026-07-15T12:00:00Z",
"interpretation": "Removed from the shopping list; possible purchase"
}
],
"warnings": [
"KitchenOwl does not distinguish a purchase from deletion in legacy history"
]
}
]
}Possible states are probably_available, uncertain, probably_missing, and
unknown.
recommend_available_recipes
Ranks recipes saved in a household according to estimated ingredient availability.
Example input:
{
"household_id": 1,
"list_id": 1,
"top_k": 5,
"include_optional": false
}Example structured output:
{
"household_id": 1,
"as_of": "2026-07-19T18:00:00Z",
"recommendations": [
{
"recipe_id": 100,
"name": "Omelette",
"score": 0.75,
"classification": "possible_with_uncertainty",
"likely_available": ["Eggs"],
"uncertain": ["Cheese"],
"likely_missing": [],
"unknown": [],
"ignored_optional": ["Parsley"],
"evidence": {
"Eggs": "Removed from the shopping list; possible purchase"
},
"warnings": [
"Estimated availability; it does not represent food safety or expiry."
]
}
]
}Possible classifications are probably_possible, possible_with_uncertainty,
probably_missing_ingredients, and insufficient_data.
How estimates work
ADDEDmeans an item entered a shopping list and likely needs replenishment.DROPPEDmeans it left a shopping list and may have been purchased, deleted, or corrected.A complete consumption cycle starts at
DROPPEDand ends at the nextADDEDevent for the same item.Typical duration is the median of complete cycles.
One or two complete cycles produce low confidence; three or more produce medium confidence.
An item currently on a shopping list is treated as probably missing.
Recipe scores use these weights:
Ingredient state | Weight |
| 1.00 |
| 0.50 |
| 0.25 |
| 0.00 |
Optional ingredients are excluded by default.
Tech stack
TypeScript with strict project rules
Kysely with
better-sqlite3andpg
Installation
Prerequisites
A running KitchenOwl installation.
Read-only access to its SQLite or PostgreSQL database.
Node.js 24+ and pnpm 11 for local development.
Docker and Docker Compose for container deployment.
Docker Compose
The recommended HTTP deployment uses the published multi-architecture image:
ghcr.io/lukegskw/kitchenowl-insights-mcp:latestDownload the Compose example and provide the database path and hostname clients will use:
curl -O https://raw.githubusercontent.com/lukegskw/kitchenowl-insights-mcp/main/compose.example.yaml
export KITCHENOWL_DATABASE_PATH=/path/to/kitchenowl/database.db
export KITCHENOWL_INSIGHTS_ALLOWED_HOSTS='mcp.example.internal'
docker compose -f compose.example.yaml up -dThe Streamable HTTP and health endpoints will be available at:
http://<host>:8099/mcp
http://<host>:8099/healthzThe database file must be readable by UID/GID 10001:10001. To use another identity
that already has read access, set KITCHENOWL_INSIGHTS_UID_GID. To publish a different
host port, set KITCHENOWL_INSIGHTS_PUBLISHED_PORT; the application still uses port
8099 inside the container.
The latest tag follows the newest successful build from the default branch. Use a
version or immutable sha-* tag for controlled deployment and rollback.
Docker run
docker run -d \
--name kitchenowl-insights \
--restart unless-stopped \
--read-only \
--user 10001:10001 \
--cap-drop ALL \
--security-opt no-new-privileges:true \
--tmpfs /tmp:size=16m,mode=1777 \
-v /path/to/kitchenowl/database.db:/kitchenowl/database.db:ro \
-e 'KITCHENOWL_INSIGHTS_DATABASE_URL=sqlite+pysqlite:///file:/kitchenowl/database.db?mode=ro&uri=true' \
-e KITCHENOWL_INSIGHTS_TRANSPORT=streamable-http \
-e KITCHENOWL_INSIGHTS_HOST=0.0.0.0 \
-e KITCHENOWL_INSIGHTS_ALLOWED_HOSTS=127.0.0.1,localhost,mcp.example.internal \
-p 8099:8099 \
ghcr.io/lukegskw/kitchenowl-insights-mcp:latestBuild the container from source
git clone https://github.com/lukegskw/kitchenowl-insights-mcp.git
cd kitchenowl-insights-mcp
docker buildx build --load -t kitchenowl-insights-mcp:local .Local Node.js installation
git clone https://github.com/lukegskw/kitchenowl-insights-mcp.git
cd kitchenowl-insights-mcp
pnpm install --frozen-lockfile
pnpm build
export KITCHENOWL_INSIGHTS_DATABASE_URL='sqlite+pysqlite:///file:/path/to/database.db?mode=ro&uri=true'
pnpm start -- --transport stdioFor local Streamable HTTP development:
KITCHENOWL_INSIGHTS_DATABASE_URL='sqlite:////path/to/database.db' \
KITCHENOWL_INSIGHTS_TRANSPORT=streamable-http \
KITCHENOWL_INSIGHTS_HOST=127.0.0.1 \
pnpm devPostgreSQL
Use a dedicated PostgreSQL role with only CONNECT, schema USAGE, and table SELECT
permissions, and set default_transaction_read_only=on. Both native and existing
SQLAlchemy-style URLs are accepted:
postgresql://<user>:<password>@<host>:5432/<database>
postgresql+psycopg://<user>:<password>@<host>:5432/<database>Do not reuse an administrative KitchenOwl credential. The standard image contains both database drivers; no alternative image is required.
Configuration
All settings use the KITCHENOWL_INSIGHTS_ prefix. A local .env file is loaded when
present.
Variable | Required | Default | Description |
| Yes | None | SQLite or PostgreSQL database URL. |
| No |
|
|
| No |
| HTTP bind address. |
| No |
| HTTP listening port. |
| External HTTP | None | Comma-separated Host and Origin hostname list. |
| No |
| Application log-level contract. |
| No |
| Maximum history events loaded per request. |
| No |
| Default number of recommendations. |
| No |
| Maximum allowed recommendations. |
| No | None | Deterministic clock override intended for tests. |
The --transport command-line option overrides KITCHENOWL_INSIGHTS_TRANSPORT.
KITCHENOWL_INSIGHTS_ALLOWED_HOSTS contains hostnames, not URLs; include every hostname
legitimate clients and health checks use.
The database URL is a secret. Supply it through the deployment platform or environment, never as an MCP tool argument or committed file.
MCP client setup
For a client that accepts Streamable HTTP server definitions:
mcp_servers:
kitchenowl_insights:
url: http://127.0.0.1:8099/mcpFor a client that launches a local stdio server:
{
"mcpServers": {
"kitchenowl_insights": {
"command": "node",
"args": [
"/absolute/path/to/kitchenowl-insights-mcp/dist/main.js",
"--transport",
"stdio"
],
"env": {
"KITCHENOWL_INSIGHTS_DATABASE_URL": "sqlite:////absolute/path/to/database.db"
}
}
}
}To let a local client launch the container over stdio, use docker run -i --rm, mount
the database read-only, supply KITCHENOWL_INSIGHTS_DATABASE_URL, and pass --transport stdio after the image name. -i is required so the client can exchange MCP messages
through standard input and output.
Client configuration formats differ. Consult the client's documentation for its exact schema and restart or reload the client after changing its server definition.
Architecture and development
The main extension points remain intentionally direct:
Define domain models and output contracts in
src/models/index.ts.Keep database access in
src/repository/index.ts.Coordinate domain behavior in
src/service/index.ts.Define strict input and output schemas in
src/tools/index.ts.Register tool behavior through
src/server.ts.Add MCP behavior tests and database integration tests for every visible change.
The application creates one read-only database context and service at startup. Stdio uses one MCP server for the process; stateless HTTP creates request-scoped MCP servers that share the application context. Transport modules remain independent from domain logic, and shutdown closes transports before the database context.
Verification
Run the complete repository suite:
pnpm install --frozen-lockfile
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test:unit
pnpm test:integration
pnpm buildThe PostgreSQL integration test runs when KITCHENOWL_TEST_POSTGRES_URL points to a
disposable database named kitchenowl_insights_test; CI supplies this automatically.
Verify schema compatibility and write protection against a database:
pnpm verify:read-only \
'sqlite+pysqlite:///file:/path/to/database.db?mode=ro&uri=true'For container changes:
docker buildx build --load -t kitchenowl-insights-mcp:test .Finally, connect an MCP client and confirm that both tools are listed and return text
and structured content. In HTTP mode, confirm /healthz reports {"status":"ok"}.
Limitations
KitchenOwl legacy history does not distinguish purchases from deletions.
Estimates do not account for free-text quantities, freshness, expiry, or food safety.
Only recipes already saved in KitchenOwl are ranked.
Sparse history produces low confidence or unknown states.
The server fails closed when required KitchenOwl tables or columns are missing.
A live SQLite database in WAL mode may require access to its sidecar files. Use a consistent read-only snapshot if live reads are unstable.
Streamable HTTP has no authentication. Restrict it to loopback, a trusted LAN, a VPN, a private container network, or an authenticated reverse proxy.
Host and Origin allowlists prevent classes of DNS rebinding attacks but do not authenticate callers.
The HTTP transport is stateless and contains no MCP session storage.
Rate limiting, tracing, and metrics are not included.
Review SECURITY.md before exposing the HTTP transport or reporting a security issue.
Contributing
Contributions are welcome. Before opening a pull request:
pnpm install --frozen-lockfile
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test
pnpm build
docker buildx build --load -t kitchenowl-insights-mcp:test .Changes must preserve strict typing, bounded validation, structured MCP results, stdout protocol purity, secure HTTP defaults, deterministic tests, household isolation, database URL redaction, SQLite and PostgreSQL support, layered read-only enforcement, and documentation for user-visible behavior. Do not add abstractions without a concrete use case for them.
License
This repository does not currently declare a software license.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Related MCP Connectors
MCP server exposing Kettle Logic insight articles & industry guidance as tools + resources.
An MCP server for deep research or task groups
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server that enables AI-powered recipe generation and transformation using natural language, supporting dietary restrictions, allergies, and nutritional goals.222MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server for managing recipes, meal plans, shopping lists, and more through a self-hosted Mealie instance.1MIT
- AlicenseNot gradedqualityFmaintenanceMCP server for MealMastery AI meal planning that enables users to manage meal plans, recipes, and grocery lists through natural language conversation with AI agents like Claude.52MIT
- AlicenseBqualityDmaintenanceMCP server for meal planning and grocery list generation, enabling recipe storage, meal plan creation, and automated grocery lists with ignored ingredients.82MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/lukegskw/kitchenowl-insights-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server