Added basic control for lights, climate, and covers
This commit is contained in:
22
package.json
22
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mcp",
|
"name": "@strandbrown/homeassistant-mcp",
|
||||||
"version": "1.0.0",
|
"version": "0.1.0",
|
||||||
"description": "MCP for HASS",
|
"description": "Home Assistant Model Context Protocol Server",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -13,7 +13,16 @@
|
|||||||
"build:start": "npm run build && npm run start"
|
"build:start": "npm run build && npm run start"
|
||||||
},
|
},
|
||||||
"author": "Tevon Strand-Brown",
|
"author": "Tevon Strand-Brown",
|
||||||
"license": "ISC",
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/tevonsb/homeassistant-mcp.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"home-assistant",
|
||||||
|
"mcp",
|
||||||
|
"model-context-protocol"
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@digital-alchemy/core": "^24.11.4",
|
"@digital-alchemy/core": "^24.11.4",
|
||||||
"@digital-alchemy/hass": "^24.11.4",
|
"@digital-alchemy/hass": "^24.11.4",
|
||||||
@@ -35,5 +44,8 @@
|
|||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module",
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
84
src/index.ts
84
src/index.ts
@@ -58,6 +58,46 @@ server.setRequestHandler(ListToolsRequestSchema, async (request) => {
|
|||||||
inputSchema: zodToJsonSchema(z.object({
|
inputSchema: zodToJsonSchema(z.object({
|
||||||
entity_ids: z.array(z.string())
|
entity_ids: z.array(z.string())
|
||||||
})),
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get_entity_history",
|
||||||
|
description: "Gets the history of an entity",
|
||||||
|
inputSchema: zodToJsonSchema(z.object({
|
||||||
|
entity_id: z.string()
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "get_entity_history_by_ids",
|
||||||
|
description: "Gets the history of a list of entities",
|
||||||
|
inputSchema: zodToJsonSchema(z.object({
|
||||||
|
entity_ids: z.array(z.string())
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "control_light",
|
||||||
|
description: "Controls a light",
|
||||||
|
inputSchema: zodToJsonSchema(z.object({
|
||||||
|
entity_id: z.string(),
|
||||||
|
state: z.enum(["on", "off"]),
|
||||||
|
brightness: z.number().min(0).max(255).optional(),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "control_climate",
|
||||||
|
description: "Controls a climate",
|
||||||
|
inputSchema: zodToJsonSchema(z.object({
|
||||||
|
entity_id: z.string(),
|
||||||
|
temperature: z.number(),
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "control_cover",
|
||||||
|
description: "Controls a cover",
|
||||||
|
inputSchema: zodToJsonSchema(z.object({
|
||||||
|
entity_id: z.string(),
|
||||||
|
state: z.string().optional(),
|
||||||
|
position: z.number().optional(),
|
||||||
|
})),
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -90,6 +130,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
return formatToolCall(getEntityHistory(request.params.arguments as { entity_id: TRawEntityIds, start_time: string, end_time?: string }));
|
return formatToolCall(getEntityHistory(request.params.arguments as { entity_id: TRawEntityIds, start_time: string, end_time?: string }));
|
||||||
case "get_entity_history_by_ids":
|
case "get_entity_history_by_ids":
|
||||||
return formatToolCall(getEntityHistoryByIds(request.params.arguments as { entity_ids: TRawEntityIds[], start_time: string, end_time?: string }));
|
return formatToolCall(getEntityHistoryByIds(request.params.arguments as { entity_ids: TRawEntityIds[], start_time: string, end_time?: string }));
|
||||||
|
case "control_light":
|
||||||
|
return formatToolCall(controlLight(request.params.arguments as { entity_id: TRawEntityIds, state: string, brightness?: number }));
|
||||||
|
case "control_climate":
|
||||||
|
return formatToolCall(controlClimate(request.params.arguments as { entity_id: TRawEntityIds, temperature: number }));
|
||||||
|
case "control_cover":
|
||||||
|
return formatToolCall(controlCover(request.params.arguments as { entity_id: TRawEntityIds, state: string, position?: number }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatToolCall({
|
return formatToolCall({
|
||||||
@@ -109,6 +155,44 @@ runServer().catch((error) => {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const controlLight = async (params: { entity_id: TRawEntityIds, state: string, brightness?: number }) => {
|
||||||
|
if (params.state === "on") {
|
||||||
|
return hass.hass.call.light.turn_on({
|
||||||
|
entity_id: params.entity_id,
|
||||||
|
brightness_pct: params.brightness,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return hass.hass.call.light.turn_off({
|
||||||
|
entity_id: params.entity_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const controlClimate = async (params: { entity_id: TRawEntityIds, temperature: number }) => {
|
||||||
|
return hass.hass.call.climate.set_temperature({
|
||||||
|
entity_id: params.entity_id,
|
||||||
|
temperature: params.temperature,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const controlCover = async (params: { entity_id: TRawEntityIds, state: string, position?: number }) => {
|
||||||
|
if (params.position) {
|
||||||
|
return hass.hass.call.cover.set_cover_position({
|
||||||
|
entity_id: params.entity_id,
|
||||||
|
position: params.position,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (params.state === "open") {
|
||||||
|
return hass.hass.call.cover.open_cover({
|
||||||
|
entity_id: params.entity_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (params.state === "close") {
|
||||||
|
return hass.hass.call.cover.close_cover({
|
||||||
|
entity_id: params.entity_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const listDomains = () => {
|
const listDomains = () => {
|
||||||
return ["light", "climate", "alarm_control_panel", "cover", "switch", "sensor", "button"];
|
return ["light", "climate", "alarm_control_panel", "cover", "switch", "sensor", "button"];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user