Homestead MCP
Integrates with Google services for optional pollen data via the Google Pollen API and for OAuth sign-in restricted to an allowlisted Google account.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Homestead MCPCan I kayak tomorrow morning around 9?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Homestead MCP
A personal household-ops MCP server that lets an AI assistant help run a home: deciding whether conditions are right for a kayak trip or a dog walk (weather, river, tides, air quality, daylight, and how hot the pavement is for paws), tracking pet care, vaccines, weight and supplies, handing off to the pet sitter, planning the garden, and keeping a horror watchlist for October.
The interesting part isn't the features. It's the guardrails: every tool runs at an explicit permission tier, anything that reaches outside the system waits for a human, every call is audited, and the whole thing is managed like production infrastructure (config-as-code, policy that CI enforces, Terraform, keyless deploys).
You: Can I kayak tomorrow morning around 9?
Claude: CAUTION. Weather is fine (64°F, wind 6 mph, 10% rain), but the Potomac
at Little Falls is elevated at 18,400 ft³/s (your caution line is 15,000).
You: OK, skip it. Ask the sitter if she can do Saturday instead.
Claude: I've queued that message (request 3f9a1c2e). Nothing is sent until you
run `homestead approve 3f9a1c2e`.Why it's built this way
Agentic tools are only as trustworthy as the boundaries around them. Homestead treats "what may the agent do on its own?" as a first-class, testable design decision:
Tier | What it means | Tools |
READ | No side effects. Runs freely. | Outdoor: |
WRITE | Local, reversible changes. Runs autonomously, always audited. |
|
APPROVAL | Reaches outside the system. Queued; a human must approve. |
|
Rules the code enforces, each with tests:
Tiers are declared in code; config can only tighten them.
policy: {log_care: approval}works.policy: {notify_sitter: read}fails at startup and in CI. A config PR can't quietly grant more autonomy.The agent has no approval path. There is no
approvetool. Approval happens only through thehomesteadCLI, run by a person. A test fails if anyone adds one.Requests expire after 24 hours and can't be approved twice.
Every tool call is audited (agent and human actions alike) to an append-only JSONL log, with credential-looking fields redacted.
Expected errors reach the model; crashes don't. Bad input becomes a readable
ToolErrorthe assistant can correct. Anything unexpected stays server-side.New tools need a deliberate tier. A test pins the full tool→tier inventory, so adding a tool forces the decision into code review.
When data is missing, it says so. If the river gauge or AirNow is unreachable or stale, the verdict degrades to CAUTION rather than a false GO.
OAuth admits one allowlisted Google account. Clients may only register Claude's callback or a localhost redirect. Codes are single-use and need PKCE. Access tokens last an hour and refresh tokens rotate. Only token hashes are stored, and removing an email cuts off its tokens immediately.
API keys stay out of URLs and logs where possible. TMDB's token goes in a header. AirNow and Google take keys as query parameters, so HTTP errors drop the query string before the message reaches the model or the audit log.
Related MCP server: toolgate
Architecture
flowchart LR
subgraph Client
A[Claude Desktop / Claude Code]
end
subgraph Homestead MCP server
R[ToolRegistry<br/>tier check + audit]
O[Outdoor module]
P[Pet modules<br/>care, vet, supplies,<br/>homecoming, sitter]
G[Garden module]
M[Movies module]
Q[(Approval queue)]
L[(Audit log)]
end
H[You, at the CLI<br/>homestead approve id]
A -- MCP stdio / HTTP --> R
R --> O & P & G & M
R -- APPROVAL tier --> Q
R --> L
O --> NWS[NOAA weather.gov]
O --> USGS[USGS Water Data API]
O --> COOPS[NOAA Tides & Currents]
O --> AIR[EPA AirNow + Google Pollen]
G --> OM[Open-Meteo]
M --> TMDB[TMDB]
H --> Q
Q -- executes approved request --> PData sources. No key needed:
the NOAA National Weather Service hourly forecast
the USGS Water Data API (
api.waterdata.usgs.gov), the modern OGC API that replaces the legacywaterservices.usgs.gov, which USGS is retiring in early 2027NOAA CO-OPS tide and current predictions
Open-Meteo daily rain and evapotranspiration for the garden (free for non-commercial use)
sunrise, sunset and the pavement-temperature estimate, computed locally
Optional, each with a free key (the feature is skipped without one):
EPA AirNow for air quality:
HOMESTEAD_AIRNOW_API_KEYthe Google Pollen API for pollen (AirNow has no pollen data):
HOMESTEAD_POLLEN_API_KEYTMDB for movies:
HOMESTEAD_TMDB_TOKEN, the API Read Access Token. This product uses the TMDB API but is not endorsed or certified by TMDB. Streaming availability comes from JustWatch via TMDB.
The pavement temperature is a rule-of-thumb estimate: air temperature plus up to 60°F, scaled by sun height and cloud cover. Trails come from your config, because there's no good free trails API.
Production shape on GCP (infra/terraform):
Cloud Run (gen2), max 1 instance. Two ways in:
IAM-gated (default): no public invoker; you connect through
gcloud run services proxy.OAuth (optional, for Claude's web, desktop and phone apps): the server runs its own OAuth authorization server, with sign-in delegated to Google and an email allowlist. See Connecting Claude's apps.
Household config stored in Secret Manager and mounted as a file; it never touches git or the image
State (audit log, approvals, care log) on a versioned, private GCS bucket mounted into the container
Dedicated runtime service account with only bucket and secret access
GitHub Actions deploys through Workload Identity Federation, restricted to this repo's
mainbranch. No service-account keys exist.Artifact Registry with image cleanup policies
CI (.github/workflows): ruff, the test suite on Python 3.12 and 3.13, a check that the real config is never committed, terraform fmt/validate, and a Docker build. Deploys run only after CI passes on main. Dependabot keeps actions, pip, Docker, and Terraform current.
Quick start (local)
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest # 127 tests, no network needed
cp config/household.example.yaml config/household.yaml # git-ignored; make it yours
export HOMESTEAD_USER_AGENT="homestead-mcp (github.com/alammers83/homestead-mcp)" # NOAA asks clients to identify themselvesClaude Code:
claude mcp add homestead \
-e HOMESTEAD_CONFIG="$PWD/config/household.yaml" \
-e HOMESTEAD_STATE_DIR="$PWD/.state" \
-- "$PWD/.venv/bin/homestead" serveClaude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"homestead": {
"command": "/absolute/path/to/homestead-mcp/.venv/bin/homestead",
"args": ["serve"],
"env": {
"HOMESTEAD_CONFIG": "/absolute/path/to/homestead-mcp/config/household.yaml",
"HOMESTEAD_STATE_DIR": "/absolute/path/to/homestead-mcp/.state"
}
}
}
}Approving things:
homestead approvals # what's waiting
homestead approve 3f9a1c2e # run it
homestead deny 3f9a1c2e --reason "already texted her"
homestead audit -n 20 # what happened, and who did itDeploying to GCP
cd infra/terraform
cp terraform.tfvars.example terraform.tfvars # set project, repo, your account
terraform init
# 1. Create the config secret, then upload your real config as its first version
terraform apply -target=google_secret_manager_secret.household_config
gcloud secrets versions add homestead-household-config --data-file=../../config/household.yaml
# 2. Everything else (first revision runs a placeholder image)
terraform applyOptional API keys (air quality, pollen, movies). Each has its own secret. Add a version, then list it in enabled_api_keys in terraform.tfvars and run terraform apply again:
printf %s "$AIRNOW_KEY" | gcloud secrets versions add homestead-airnow-key --data-file=-
printf %s "$POLLEN_KEY" | gcloud secrets versions add homestead-pollen-key --data-file=-
printf %s "$TMDB_TOKEN" | gcloud secrets versions add homestead-tmdb-key --data-file=-After editing your real household.yaml, upload it as a new secret version with the same gcloud secrets versions add homestead-household-config command. New Cloud Run instances read the latest version.
Then in GitHub → Settings → Secrets and variables → Actions → Variables, add GCP_REGION, plus IMAGE_REPO, WIF_PROVIDER, and DEPLOYER_SA from terraform output. Create a production environment (add yourself as a required reviewer if you want a manual gate). The next green CI run on main deploys.
To connect a client to the private service:
gcloud run services proxy homestead --region us-east4 --port 8080
claude mcp add --transport http homestead http://localhost:8080/mcpConnecting Claude's apps (OAuth)
Claude's custom connectors (claude.ai, the desktop app, and the iPhone and Android apps) connect from Anthropic's servers, so they can't use the gcloud proxy. Turning on OAuth lets them in. The service opens to the internet, and every MCP request must carry a token that only your Google account can get.
Deploy the OAuth-capable code first. Without it, step 4 would make the old, unauthenticated server public.
Google OAuth client. In Google Cloud console → Google Auth Platform:
Branding: app name "Homestead" and your email.
Audience: External, publishing status Testing, and add your Gmail as a test user. Only test users can sign in, which is a second lock.
Clients → Create client → Web application. Add the authorized redirect URI
https://<your service URL>/oauth/google/callback(terraform output oauth_redirect_uriprints it oncepublic_urlis set). Copy the client ID and secret.
Store the client secret. The
homestead-google-oauth-keysecret exists after anyterraform applyon this version:printf %s "$GOOGLE_CLIENT_SECRET" | gcloud secrets versions add homestead-google-oauth-key --data-file=-Settings in
terraform.tfvars:public_url = "https://homestead-xxxxxxxxxx-uk.a.run.app" # terraform output service_url google_oauth_client_id = "1234-abc.apps.googleusercontent.com" allowed_emails = ["you@gmail.com"] enabled_api_keys = ["google-oauth"] # plus airnow, tmdb, ... if you use themterraform apply. The new revision with OAuth settings rolls out first, then the public invoker is added.Add the connector. In claude.ai, go to Settings → Connectors → Add custom connector, enter
https://<your service URL>/mcp, and sign in with Google. It then shows up in the phone app's connectors too.Claude Code connects directly; the proxy isn't needed:
claude mcp add --transport http homestead https://<your service URL>/mcpIn Claude Desktop, use the claude.ai connector and remove any
mcp-remoteentry fromclaude_desktop_config.json.
To turn it off, clear public_url and apply. The public invoker goes away, and the service is IAM-only again.
Approvals still happen only at the CLI, so from your phone you can queue a sitter message or a reorder, but not approve it.
To approve requests made against the cloud deployment, mount the state bucket locally (for example with gcsfuse) and point HOMESTEAD_STATE_DIR at it.
Privacy
This repo is public, so everything in it is fictional sample data. Real details live in a git-ignored household.yaml locally and in Secret Manager in the cloud. CI fails if the real file is ever committed. Weather is checked for a configured public location (a park or trailhead), not a home address.
Roadmap
Approval from my phone: a Slack message with Approve/Deny buttons, verified by signed request
Garden module: planting calendar and "water today?" from recent rainfall
Horror watchlist module (TMDB) for October
Air quality, pollen, tides, daylight, paw-safe pavement, and trail suggestions
Vet records, weight, supplies, new-dog homecoming plan, sitter handoff packet
OAuth in front of the HTTP transport for clients that can't use the gcloud proxy
Eval suite: scripted conversations checking that the model picks the right tool and relays the request ID for approval-tier tools
Project layout
src/homestead/
policy.py tiers and the only-tighten rule
server.py ToolRegistry: every tool goes through tier check + audit
approvals.py approval queue (create from MCP; decide from CLI only)
audit.py append-only JSONL with redaction
auth.py OAuth server for the HTTP transport, Google sign-in, email allowlist
config.py typed, validated YAML config
store.py append-only JSONL records in the state directory
dates.py "today" / "tomorrow" / YYYY-MM-DD parsing
modules/
outdoor.py weather, river, air, sun, paws -> GO / CAUTION / NO_GO
solar.py sunrise/sunset and sun height (local math), pavement estimate
airquality.py EPA AirNow + Google Pollen
tides.py NOAA CO-OPS tides and currents
trails.py shade- and dog-aware trail ranking
pack.py care schedule, care log, sitter messages
vet.py vaccines and due dates, vet visits, weight trends
supplies.py food and med inventory; approval-gated reorders
homecoming.py new-dog gear checklist and introduction plan
sitter.py sitter handoff packet and household reminders
garden.py planting calendar and "water today?" (Open-Meteo)
movies.py TMDB horror picks and watchlist
tests/ guardrail, decision-logic, and end-to-end MCP tests
infra/terraform/ Cloud Run, GCS, Secret Manager, WIF, Artifact RegistryLicense
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
AI life manager: tasks, home, health, wealth, childcare, pets & more — on your own data.
Context and control for any AI. Agent identity, scoped access, and proof across tools.
Runtime permission, approval, and audit layer for AI agent tool execution.
Every AI tool call runs as the person who asked, under your rules, fully audited.
Related MCP Servers
- AlicenseAqualityFmaintenanceEnables household management through natural language, covering bills, chores, shopping, reminders, budget, and smart-home devices, with every mutating action dry-run, confirmed, and audited.31MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to call backend tools under per-agent policy, deciding which tools each agent can see, what arguments it may pass, how often it may call, and which writes wait for human approval. It also redacts secrets and PII from tool results, fences untrusted output against injection, and records every call in a hash-chained audit log.25 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables natural-language household planning by exposing 18 stateful tools that read a household profile and pantry, fetch live weather, plan meals under diet, allergy, time, and budget constraints, compute missing ingredients, and draft shopping lists and tasks — all pending explicit confirmation before any mutation is applied. Supports a full auditable workflow with real persistence, honest fallback behavior, and optional advisory AI and snapshot mirroring.MIT
- AlicenseNot gradedqualityBmaintenanceEnables an AI assistant to manage a shared household state through nine MCP tools covering pantry lookups, grocery lists, meal plans, chore logging, morning briefs, and a single-call atomic restock workflow that checks the meal plan and pantry, skips items already listed, and adds what's missing.MIT