@cpenned/growing-kids-mcp
v0.3.0
Published
MCP server for managing Growing Kids reading plans, passages, and questions
Readme
@cpenned/growing-kids-mcp
A local stdio MCP server for administering Growing Kids reading plans conversationally. It wraps the Growing Kids admin HTTP API so an MCP client (Claude Code, Claude Desktop, etc.) can create reading plans, add passages and questions, and manage the plan lifecycle.
Environment variables
| Variable | Required | Description |
| --- | --- | --- |
| GROWING_KIDS_API_KEY | Yes | Admin API key. Sent as Authorization: Bearer <key>. The server exits immediately with an error if this is unset. |
| GROWING_KIDS_API_URL | No | Base URL of the API. Defaults to https://ceaseless-porpoise-493.convex.site. |
Install and run
GROWING_KIDS_API_KEY=gk_... npx @cpenned/growing-kids-mcpClaude Code
claude mcp add growing-kids -e GROWING_KIDS_API_KEY=gk_... -- npx @cpenned/growing-kids-mcpClaude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"growing-kids": {
"command": "npx",
"args": ["@cpenned/growing-kids-mcp"],
"env": {
"GROWING_KIDS_API_KEY": "gk_..."
}
}
}
}Tools
| Tool | Description |
| --- | --- |
| list_plans | List plans with id, title, grade levels, length, status, and day count. Optional status and gradeLevel args filter the list. |
| get_plan | Full plan detail including day and question ids (needed for edits). |
| create_plan | Create a plan, optionally with days and questions, optionally published. |
| update_plan | Patch a plan in place (typo-level fixes; see edit policy below). |
| add_plan_day | Add or fill in a single day (passage, title, questions). |
| update_question | Rewrite one question's prompt or sample answer. |
| remove_question | Remove a question (refused once a child has answered it). |
| publish_plan | Publish a draft (requires all days present). |
| unpublish_plan | Return a plan to draft (never-enrolled plans only). |
| archive_plan | Hide from new enrollments; enrolled children can finish. |
| unarchive_plan | Restore an archived plan to published. |
| delete_plan | Permanently delete (draft plans with no enrollments only). |
| list_users | List all accounts (parents, children, superadmins) with summary stats. Read-only. |
| get_user | One account in full detail: family graph, enrollments, email delivery history. Read-only. |
| email_health | Aggregate deliverability for the last 7/30 days; no recipient addresses. Read-only. |
| list_recent_emails | The 50 most recent sends with delivery statuses and bounce details. Read-only. |
| get_usage_overview | Aggregate usage totals plus the latest nightly snapshot (digest opt-in, grades, streaks). Anonymous, read-only. |
| get_metric_timeseries | Daily values for one analytics metric over a date range (max 366 days). Anonymous, read-only. |
| get_plan_funnel | Per-day completion counts and enrollment outcomes for one plan. Anonymous, read-only. |
Passage references are plain text ("Psalm 23", "John 3:1-16", cross-chapter ranges, comma lists). The server normalizes them and computes verse counts; clients never send verse counts.
Key scopes
API keys carry scopes; a key missing a tool's scope gets a 403 that the tool relays. Plan tools need plans:write. list_users, get_user, and list_recent_emails need users:read (they expose names and addresses). email_health, get_usage_overview, get_metric_timeseries, and get_plan_funnel need only stats:read (aggregates, PII-free; stats reads are rate limited per key). Account actions (ban, delete, role changes) are deliberately NOT exposed through the API: they are session-only in the admin UI, so a leaked long-lived key can never delete accounts.
Edit policy
Children may be mid-plan when you edit, so in-place updates are for typo-level corrections and small additions only. The API refuses unsafe changes with a 409 and a clear message, for example shortening a plan past a child's progress or removing a question a child has already answered; the tools surface these as API refused: ... so the assistant can explain and adapt. Meaning-level rewrites of a published plan belong in archive_plan followed by create_plan.
Development
cd mcp
npm install
npm run build # tsc -> dist/
npm test # vitestPublishing
From the mcp/ directory, logged in to npm as cpenned:
npm login # if not already logged in as cpenned
npm publish --access publicprepublishOnly runs the build, so dist/ is always fresh in the published package.
