import dotenv from "dotenv";
dotenv.config();
const HA_URL = process.env.HA_URL;
const HA_TOKEN = process.env.HA_TOKEN;
const ENTITY_ID = process.env.ENTITY_ID;
if (!HA_URL || !HA_TOKEN || !ENTITY_ID) {
console.error("Missing required environment variables: HA_URL, HA_TOKEN, ENTITY_ID");
process.exit(1);
}
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ErrorCode,
ListToolsRequestSchema,
McpError
} from "@modelcontextprotocol/sdk/types.js";
async function callHAService(service) {
try {
const response = await fetch(
`${HA_URL}/api/services/media_player/${service}`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${HA_TOKEN}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ entity_id: ENTITY_ID })
}
);
if (!response.ok) {
const text = await response.text();
throw new Error(`HA service call failed: ${response.status} ${text}`);
}
} catch (error) {
console.error("Error calling Home Assistant service:", error);
throw error;
}
}
const PLAY_MEDIA_PLAYER_TOOL = {
name: "play_media_player",
description: "Play/resume the media player via Home Assistant.",
inputSchema: { type: "object", properties: {}, required: [] },
};
const PAUSE_MEDIA_PLAYER_TOOL = {
name: "pause_media_player",
description: "Pause the media player via Home Assistant.",
inputSchema: { type: "object", properties: {}, required: [] },
};
const server = new Server(
{
name: "media-player-mcp",
version: "0.1.0",
},
{
capabilities: {
resources: {},
tools: {},
logging: {},
},
}
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [PLAY_MEDIA_PLAYER_TOOL, PAUSE_MEDIA_PLAYER_TOOL],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === "play_media_player") {
await callHAService("media_play");
return { success: true, result: "Media player played" };
}
if (request.params.name === "pause_media_player") {
await callHAService("media_pause");
return { success: true, result: "Media player paused" };
}
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
});
server.onerror = (error) => {
console.error(error);
};
process.on("SIGINT", async () => {
await server.close();
process.exit(0);
});
async function runServer() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Media Player MCP Server running on stdio");
}
runServer().catch((error) => {
console.error("Fatal error running server:", error);
process.exit(1);
});