Skip to content

MCP Integration

Cognitive Companion treats the home as something an AI agent can safely operate. A built-in Model Context Protocol (MCP) server, built on the official MCP Python SDK, exposes 59 tools for AI agent integration: agents can discover system state, query sensor data, inspect enrollment and e-ink status, check person locations, review activity timelines and daily reports, explore semantic memory, read the unified signals feed, acknowledge behavioral signals with feedback, drive and analyze guided routine sessions, propose identity corrections, trigger rule executions, author new rules, and inspect plugin metadata. The same tools are shared with the Gemini Live voice companion for function calling during conversations.

This makes Cognitive Companion agent-native: household state has one governed, authenticated tool surface, and every agent, whether Claude Desktop, a custom orchestrator, or the internal voice companion, goes through it. There is no separate integration to audit per client, and tools stay in lockstep with the UI because both read the same service layer.

What is MCP?

The Model Context Protocol is an open standard for connecting AI models to external tools and data sources. It provides a structured way for AI agents to:

  • Discover available tools and their parameters
  • Execute tools with validated inputs
  • Receive structured responses

Cognitive Companion's MCP server allows external AI agents (Claude, GPT, custom agents) to interact with the senior care system as part of their tool-calling workflows.

MCP and BFF parity guarantee

MCP tools and BFF router endpoints share one service layer (design rule D6). Any data exposed to the Vue UI through a router is exposed to MCP by reading the same service function, never a parallel query. Consequences:

  • MCP tools contain no query logic of their own; they call service methods.
  • Import-linter contracts enforce that mcp/ may not import a repository directly.
  • When a service response envelope changes, both the router and the MCP tool reflect the change automatically.
  • Smoke tests in backend/tests/mcp/ assert that every registered tool name resolves to a callable.

Architecture

The MCP server is implemented using the official mcp Python SDK's FastMCP class. Tools are defined as decorated async functions with type hints that auto-generate JSON schemas. The server is mounted as an ASGI sub-application on FastAPI at /mcp, serving the standard MCP protocol via streamable HTTP transport.

A GeminiToolAdapter reads the same tool definitions and converts them to Gemini FunctionDeclaration format, so the voice companion can call tools during conversations without duplicating implementations.

Available Tools

ToolDescriptionParameters
get_roomsList all configured roomsNone
get_sensorsList sensorsroom_name, sensor_type (optional filters)
get_room_occupancyCurrent occupancy from presence sensorsroom_name (optional)
get_recent_imagesRecent camera images for a sensorsensor_id, limit
get_light_levelIlluminance from a HA sensorentity_id
get_signals_feedUnified caregiver signals feed (CTS signals plus rule alerts)source, severity_min, room_name, limit (optional)
get_event_logsRule execution event logsrule_name, status, limit (optional)
get_rulesConfigured automation rulesenabled_only (default true)
get_conversation_historyRecent conversation turnssession_id, limit (optional)
get_person_locationsCurrent location of all tracked membersNone
get_enrolled_personsHousehold members with face enrollment dataNone
get_person_sightingsCamera sighting history for a personperson_id, limit
get_person_activitiesRecent detected activities (eating, sleeping, etc.)person_id, activity_type, minutes
get_workflow_executionsRecent pipeline workflow executionsrule_name, status, limit (optional)
get_rule_pipelinePipeline step definitions for a rulerule_id
trigger_ruleManually trigger a rule's pipeline executionrule_id
get_eink_display_statusActive e-ink image state for one or all displayssensor_id (optional)
get_local_datetimeCurrent local date and time for the household's timezoneNone
get_weatherCurrent weather from Home AssistantNone
get_person_timelineChronological timeline of activities and sightings for a personperson_id, minutes (optional)
get_daily_reportEnd-of-day wellness report for one or all membersperson_id, report_date (optional)
get_open_sessionsCurrently open activity sessions (meals, bathroom, etc.)person_id, activity_type (optional)
submit_user_responseRecord user response to an interactive prompt stepexecution_id, step_id, action
get_recent_scene_objectsRecent object presence in a roomroom_id, since_minutes
get_scene_observationsSearch scene observations with vector similarityquery_text, room_id, limit (optional)
get_person_movementsMovement transitions for a person between roomsperson_id, semantic, since_minutes (optional)
get_room_trendRoom-level trend state from object presence dataroom_id, since_hours (optional)
search_similar_scenesVector search across scene embeddingsquery_embedding, room_id, limit (optional)
get_tracking_statusOverall CTS tracking status and active PH count(none)
get_person_locationCurrent location envelope for one person (with quality/staleness)person_id
get_recent_dementia_signalsRecent dementia signals for a person with signal envelopesperson_id, limit (optional)
acknowledge_dementia_signalAcknowledge a dementia signal, optionally with caregiver feedbacksignal_id, feedback (optional)
get_gait_trendGait speed trend envelope for a residentperson_id, days (default 56)
get_heatmapAggregated floor-plan heatmap bins for a person over a time rangeperson_id, start_time, end_time, start_minute, end_minute (optional)
list_keyframe_framesKeyframes grouped per physical source frame for identity reviewperson_id, camera_id, tag_reason, conflict_only, pending_review_only, limit, offset (all optional)
propose_identity_correctionPropose an observation-bounded identity correction segment for a PHph_id, observation_id, at (optional)
get_identity_correction_jobStatus of an identity correction jobrevision_id
get_active_guided_stepCurrent step of an active guided sessionsession_id
mark_guided_step_completePropose that the resident completed the current guided stepsession_id, step_ord, note (optional)
repeat_guided_stepRephrase and repeat the current guided stepsession_id
report_step_blockedRecord that the resident is stuck on the current stepsession_id, reason
request_caregiver_helpEscalate a guided session to the caregiversession_id, reason (optional)
record_resident_preferenceRecord a stable resident preference (not a transient fact) to the knowledge repositoryperson_id, preference, context (optional)
get_guided_completion_summaryGuided-task completion outcomesperson_id, routine_id, since, until (optional)
get_guided_attempts_per_stepRetry pressure by guided routine stepperson_id, routine_id, since, until (optional)
get_guided_time_to_completeGuided routine completion durationsperson_id, routine_id, since, until (optional)
get_guided_abandonmentGuided-task abandonment rate and reasonsperson_id, routine_id, since, until (optional)
get_guided_escalation_breakdownGuided-task escalation reasonsperson_id, routine_id, since, until (optional)
get_guided_vision_agreementGuided-task vision agreement qualityperson_id, routine_id, since, until (optional)
get_guided_time_of_dayGuided outcomes bucketed by local hourperson_id, routine_id, since, until (optional)
get_guided_watch_summaryGuided-task watch runs and agreementperson_id, routine_id, since, until (optional)
get_guided_gate_cost_summaryGuided-task vision gate execution costsperson_id, routine_id, since, until (optional)
query_knowledge_baseSemantic search over the knowledge repositoryquery
get_current_quiz_questionCurrent question in an active quiz sessionsession_id
submit_quiz_answerRecord an answer to a quiz questionsession_id, answer
complete_quiz_sessionClose a quiz sessionsession_id
list_rulesList all rules with summary info(none)
list_plugin_metadataMetadata for all registered steps, filters, and channelskind (optional: "step", "filter", "channel")
get_rule_bundleExport a rule as a portable bundlerule_id
import_rule_bundleValidate or commit a rule bundlebundle (RuleBundle dict), mode ("preview" or "commit")

Authentication

MCP tools require authentication via the API key. The key is configured in config/auth.yaml:

yaml
api_keys:
  - key: ${CC_MCP_API_KEY}
    name: mcp_agent
    permissions:
      - mcp_readonly

The mcp_readonly permission grants access to the /mcp endpoint. Pass the key via the X-API-Key header or Authorization: Bearer <key> header.

Endpoint

The MCP server is available at a single endpoint:

MethodPathDescription
POST/mcpMCP protocol endpoint (streamable HTTP, JSON-RPC)

Tool Discovery

bash
curl -X POST \
  -H "X-API-Key: $CC_MCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}' \
  http://localhost:8000/mcp

Tool Execution

bash
curl -X POST \
  -H "X-API-Key: $CC_MCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_person_sightings","arguments":{"person_id":"grandma"}},"id":2}' \
  http://localhost:8000/mcp

Integration Patterns

With Claude Desktop

Configure Claude Desktop's MCP settings to point to your Cognitive Companion instance:

json
{
  "mcpServers": {
    "cognitive-companion": {
      "url": "http://your-cc-host:8000/mcp",
      "headers": {
        "X-API-Key": "your_mcp_key"
      }
    }
  }
}

With Custom Agents

Any agent framework that supports the MCP protocol can integrate with Cognitive Companion by pointing to the /mcp endpoint. The standard JSON-RPC interface handles tool discovery and execution.

Example Agent Workflow

An AI agent monitoring the household might:

  1. Call get_person_locations to check where everyone is
  2. Call get_enrolled_persons to see which household members are tracked
  3. Call get_person_activities to check if lunch has been eaten
  4. If lunch has not been detected, call trigger_rule on the lunch reminder rule
  5. Call get_signals_feed to check for any unacknowledged signals

Voice Companion Integration

A configurable subset of MCP tools is also available to the Gemini Live voice companion via function calling. When the senior asks a question like "what's the weather?" or "where is everyone?", Gemini pauses audio generation, calls the appropriate tool, and incorporates the result into its spoken response. Tool results are never displayed raw to the user; they always flow through Gemini's natural language audio response.

The voice-enabled tool subset is configured in settings.yaml:

yaml
mcp:
  gemini_tools:
    - "get_rooms"
    - "get_room_occupancy"
    - "get_person_locations"
    - "get_signals_feed"
    - "get_weather"
    - "get_recent_scene_objects"
    - "get_room_trend"
    - "get_person_movements"
    - "get_local_datetime"
    - "get_person_activities"
    - "get_enrolled_persons"
    - "get_person_timeline"
    - "get_daily_report"
    - "get_open_sessions"
    - "submit_user_response"
    - "query_knowledge_base"
    - "submit_quiz_answer"
    - "get_current_quiz_question"
    - "complete_quiz_session"
    - "get_active_guided_step"
    - "mark_guided_step_complete"
    - "repeat_guided_step"
    - "report_step_blocked"
    - "request_caregiver_help"
    - "record_resident_preference"

Destructive tools like trigger_rule are excluded from the voice subset by default. The guided-session tools are voice-enabled by design: they are how the realtime agent proposes step completion, repeats a step, or escalates to a caregiver during a guided routine. get_person_timeline, get_daily_report, and get_open_sessions are the typed daily-living ledger tools: the agent answers countable questions ("has she had her medication today") by calling these, never by aggregating semantic-memory captions.

Network Considerations

The MCP server runs on the same backend instance, so no additional deployment is needed. Since Cognitive Companion runs on-premise without a public endpoint, MCP clients must be on the same local network. For remote agent access, consider:

  • VPN or tailnet for secure remote access
  • A reverse proxy with authentication for controlled exposure

Adding New Tools

  1. Add a @_register decorated async function in backend/mcp/server.py. Type hints on parameters auto-generate JSON schemas.
  2. Add the tool name to config/settings.yaml under mcp.tools.
  3. If the tool should be available in voice conversations, also add it to mcp.gemini_tools.

See the development guide for more details.

Released under the AGPL-3.0 License.