Add MCP Schema Endpoint for API Discovery
- Implemented `/mcp` endpoint to expose server capabilities - Created `src/mcp/schema.ts` with comprehensive tool and resource definitions - Updated README.md with MCP Schema documentation - Modified security middleware to allow unauthenticated access to schema endpoint - Included detailed tool descriptions for list_devices, control, and event subscription
This commit is contained in:
44
README.md
44
README.md
@@ -54,6 +54,7 @@ See [SSE_API.md](docs/SSE_API.md) for complete documentation of the SSE system.
|
||||
- [Configuration](#configuration)
|
||||
- [Development](#development)
|
||||
- [API Reference](#api-reference)
|
||||
- [MCP Schema](#mcp-schema-endpoint)
|
||||
- [Device Control](#device-control)
|
||||
- [Add-on Management](#add-on-management)
|
||||
- [Package Management](#package-management)
|
||||
@@ -248,6 +249,49 @@ TEST_HASS_TOKEN=test_token # Test token
|
||||
|
||||
## API Reference
|
||||
|
||||
### MCP Schema Endpoint
|
||||
|
||||
The server exposes an MCP (Model Context Protocol) schema endpoint that describes all available tools and their parameters:
|
||||
|
||||
```http
|
||||
GET /mcp
|
||||
```
|
||||
|
||||
This endpoint returns a JSON schema describing all available tools, their parameters, and documentation resources. The schema follows the MCP specification and can be used by LLM clients to understand the server's capabilities.
|
||||
|
||||
Example response:
|
||||
```json
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"name": "list_devices",
|
||||
"description": "List all devices connected to Home Assistant",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"domain": {
|
||||
"type": "string",
|
||||
"enum": ["light", "climate", "alarm_control_panel", ...]
|
||||
},
|
||||
"area": { "type": "string" },
|
||||
"floor": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
// ... other tools
|
||||
],
|
||||
"prompts": [],
|
||||
"resources": [
|
||||
{
|
||||
"name": "Home Assistant API",
|
||||
"url": "https://developers.home-assistant.io/docs/api/rest/"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Note: The `/mcp` endpoint is publicly accessible and does not require authentication, as it only provides schema information.
|
||||
|
||||
### Device Control
|
||||
|
||||
#### Common Entity Controls
|
||||
|
||||
@@ -6,6 +6,7 @@ import { sseManager } from './sse/index.js';
|
||||
import { ILogger } from "@digital-alchemy/core";
|
||||
import express from 'express';
|
||||
import { rateLimiter, securityHeaders, validateRequest, sanitizeInput, errorHandler } from './security/index.js';
|
||||
import { MCP_SCHEMA } from './mcp/schema.js';
|
||||
|
||||
// Load environment variables based on NODE_ENV
|
||||
const envFile = process.env.NODE_ENV === 'production'
|
||||
@@ -42,6 +43,12 @@ app.use(sanitizeInput);
|
||||
// Initialize LiteMCP
|
||||
const server = new LiteMCP('home-assistant', '0.1.0');
|
||||
|
||||
// MCP schema endpoint - no auth required as it's just the schema
|
||||
app.get('/mcp', (_req, res) => {
|
||||
// Return the MCP schema without requiring authentication
|
||||
res.json(MCP_SCHEMA);
|
||||
});
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({
|
||||
|
||||
118
src/mcp/schema.ts
Normal file
118
src/mcp/schema.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { z } from 'zod';
|
||||
import { DomainSchema } from '../schemas.js';
|
||||
|
||||
export const MCP_SCHEMA = {
|
||||
tools: [
|
||||
{
|
||||
name: "list_devices",
|
||||
description: "List all devices connected to Home Assistant",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
domain: {
|
||||
type: "string",
|
||||
enum: [
|
||||
"light",
|
||||
"climate",
|
||||
"alarm_control_panel",
|
||||
"cover",
|
||||
"switch",
|
||||
"contact",
|
||||
"media_player",
|
||||
"fan",
|
||||
"lock",
|
||||
"vacuum",
|
||||
"scene",
|
||||
"script",
|
||||
"camera"
|
||||
]
|
||||
},
|
||||
area: { type: "string" },
|
||||
floor: { type: "string" }
|
||||
},
|
||||
required: []
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "control",
|
||||
description: "Control Home Assistant entities (lights, climate, etc.)",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
command: {
|
||||
type: "string",
|
||||
enum: [
|
||||
"turn_on",
|
||||
"turn_off",
|
||||
"toggle",
|
||||
"open",
|
||||
"close",
|
||||
"stop",
|
||||
"set_position",
|
||||
"set_tilt_position",
|
||||
"set_temperature",
|
||||
"set_hvac_mode",
|
||||
"set_fan_mode",
|
||||
"set_humidity"
|
||||
]
|
||||
},
|
||||
entity_id: { type: "string" },
|
||||
state: { type: "string" },
|
||||
brightness: { type: "number" },
|
||||
color_temp: { type: "number" },
|
||||
rgb_color: {
|
||||
type: "array",
|
||||
items: { type: "number" },
|
||||
minItems: 3,
|
||||
maxItems: 3
|
||||
},
|
||||
position: { type: "number" },
|
||||
tilt_position: { type: "number" },
|
||||
temperature: { type: "number" },
|
||||
target_temp_high: { type: "number" },
|
||||
target_temp_low: { type: "number" },
|
||||
hvac_mode: { type: "string" },
|
||||
fan_mode: { type: "string" },
|
||||
humidity: { type: "number" }
|
||||
},
|
||||
required: ["command", "entity_id"]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "subscribe_events",
|
||||
description: "Subscribe to Home Assistant events via SSE",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
events: {
|
||||
type: "array",
|
||||
items: { type: "string" }
|
||||
},
|
||||
entity_id: { type: "string" },
|
||||
domain: { type: "string" }
|
||||
},
|
||||
required: []
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "get_sse_stats",
|
||||
description: "Get statistics about SSE connections",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {},
|
||||
required: []
|
||||
}
|
||||
}
|
||||
],
|
||||
prompts: [],
|
||||
resources: [
|
||||
{
|
||||
name: "Home Assistant API",
|
||||
url: "https://developers.home-assistant.io/docs/api/rest/"
|
||||
},
|
||||
{
|
||||
name: "Home Assistant WebSocket API",
|
||||
url: "https://developers.home-assistant.io/docs/api/websocket"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -127,8 +127,8 @@ export class TokenManager {
|
||||
|
||||
// Request validation middleware
|
||||
export function validateRequest(req: Request, res: Response, next: NextFunction) {
|
||||
// Skip validation for health endpoint
|
||||
if (req.path === '/health') {
|
||||
// Skip validation for health and MCP schema endpoints
|
||||
if (req.path === '/health' || req.path === '/mcp') {
|
||||
return next();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user