diff --git a/packages/spec/PROTOCOL_MAP.md b/packages/spec/PROTOCOL_MAP.md index 09d912324..71dab767c 100644 --- a/packages/spec/PROTOCOL_MAP.md +++ b/packages/spec/PROTOCOL_MAP.md @@ -75,6 +75,7 @@ This document serves as the **Grand Map** of the ObjectStack specification. It l | :--- | :--- | :--- | | [`agent.zod.ts`](src/ai/agent.zod.ts) | ⭐ | **AI Agent**. Attributes of an AI assistant (role, personality, model). | | [`agent-action.zod.ts`](src/ai/agent-action.zod.ts) | ⭐ | **Tools & Actions**. Capabilities exposed to the AI (Function Calling). | +| [`mcp.zod.ts`](src/ai/mcp.zod.ts) | ⭐ | **Model Context Protocol (MCP)**. Standard protocol for connecting AI to tools, resources, and data sources. | | [`rag-pipeline.zod.ts`](src/ai/rag-pipeline.zod.ts) | ⭐ | **RAG**. Retrieval Augmented Generation configurations. | | [`model-registry.zod.ts`](src/ai/model-registry.zod.ts) | | **LLM Registry**. Configuration for model providers (OpenAI, Anthropic). | | [`conversation.zod.ts`](src/ai/conversation.zod.ts) | | **Chat Session**. History and context management for AI chats. | diff --git a/packages/spec/README.md b/packages/spec/README.md index e591d3b1f..82108ceb9 100644 --- a/packages/spec/README.md +++ b/packages/spec/README.md @@ -8,7 +8,7 @@ The **Source of Truth** for the ObjectStack Protocol. Contains strictly typed Zo - **Data**: Objects, Fields, Validation Rules. - **UI**: Views, Layouts, Dashboards. - **Automation**: Flows, Workflows, Triggers. -- **AI**: Agents, RAG Pipelines, Models. +- **AI**: Agents, RAG Pipelines, Models, MCP Servers. ## Usage @@ -58,3 +58,133 @@ if (result.success) { console.log('Valid object:', result.data); } ``` + +## MCP (Model Context Protocol) Integration + +Define MCP servers to connect AI agents to your ObjectStack data and tools: + +```typescript +import { MCPServerConfigSchema } from '@objectstack/spec/ai'; + +// Define an MCP server exposing ObjectStack data +export const objectStackMCP = MCPServerConfigSchema.parse({ + name: 'objectstack_mcp', + label: 'ObjectStack MCP Server', + description: 'Connects AI agents to ObjectStack data and workflows', + + serverInfo: { + name: 'ObjectStack MCP', + version: '1.0.0', + capabilities: { + resources: true, + resourceTemplates: true, + tools: true, + prompts: true, + }, + }, + + transport: { + type: 'http', + url: 'https://api.objectstack.ai/mcp', + auth: { + type: 'bearer', + secretRef: 'system:mcp_api_key', + }, + }, + + // Expose data as resources + resourceTemplates: [ + { + uriPattern: 'objectstack://objects/{objectName}', + name: 'Object Data', + description: 'Access object records', + parameters: [ + { + name: 'objectName', + type: 'string', + required: true, + description: 'Name of the object to access', + }, + ], + handler: 'resources.getObjectData', + }, + ], + + // Expose workflows as tools + tools: [ + { + name: 'create_record', + description: 'Create a new record in any object', + parameters: [ + { + name: 'object', + type: 'string', + description: 'Object name (e.g., "account", "contact")', + required: true, + }, + { + name: 'data', + type: 'object', + description: 'Record data as key-value pairs', + required: true, + }, + ], + handler: 'flows.create_record', + sideEffects: 'write', + requiresConfirmation: true, + }, + { + name: 'search_records', + description: 'Search for records using natural language or filters', + parameters: [ + { + name: 'object', + type: 'string', + description: 'Object to search in', + required: true, + }, + { + name: 'query', + type: 'string', + description: 'Search query', + required: true, + }, + ], + handler: 'data.search', + sideEffects: 'read', + }, + ], + + // Provide prompt templates + prompts: [ + { + name: 'analyze_customer_data', + description: 'Analyze customer data and generate insights', + messages: [ + { + role: 'system', + content: 'You are a data analyst specializing in customer insights.', + }, + { + role: 'user', + content: 'Analyze the following customer data and provide insights: {{customer_data}}', + }, + ], + arguments: [ + { + name: 'customer_data', + type: 'string', + required: true, + description: 'Customer data in JSON format', + }, + ], + }, + ], + + autoStart: true, + healthCheck: { + enabled: true, + interval: 60000, + }, +}); +``` diff --git a/packages/spec/docs/MCP_GUIDE.md b/packages/spec/docs/MCP_GUIDE.md new file mode 100644 index 000000000..693c0157e --- /dev/null +++ b/packages/spec/docs/MCP_GUIDE.md @@ -0,0 +1,454 @@ +# MCP (Model Context Protocol) Integration Guide + +## Overview + +The Model Context Protocol (MCP) is a standardized protocol for connecting AI assistants to external tools, data sources, and resources. ObjectStack implements MCP to enable seamless integration between AI agents and business data, workflows, and services. + +## Core Concepts + +### 1. MCP Server + +An MCP server is a service endpoint that exposes capabilities to AI agents. Each server can provide: + +- **Resources**: Contextual information (data, documents, records) +- **Tools**: Callable functions and operations +- **Prompts**: Predefined prompt templates + +### 2. Transport + +Multiple transport protocols are supported: + +- **stdio**: Standard input/output (local processes) +- **http**: HTTP REST API +- **websocket**: Bidirectional WebSocket communication +- **grpc**: High-performance gRPC communication + +### 3. Capabilities + +MCP servers declare their supported features: + +- `resources`: Supports resource listing and retrieval +- `resourceTemplates`: Supports dynamic resource templates +- `tools`: Supports tool/function calling +- `prompts`: Supports prompt templates +- `sampling`: Supports LLM sampling +- `logging`: Supports logging and debugging + +## Quick Start + +### Define an MCP Server + +```typescript +import { MCPServerConfigSchema } from '@objectstack/spec/ai'; + +export const objectStackMCP = MCPServerConfigSchema.parse({ + // Server Identity + name: 'objectstack_mcp', + label: 'ObjectStack MCP Server', + description: 'Connects AI agents to ObjectStack data and workflows', + + // Server Info + serverInfo: { + name: 'ObjectStack MCP', + version: '1.0.0', + capabilities: { + resources: true, + resourceTemplates: true, + tools: true, + prompts: true, + }, + }, + + // Transport Configuration + transport: { + type: 'http', + url: 'https://api.objectstack.ai/mcp', + auth: { + type: 'bearer', + secretRef: 'system:mcp_api_key', + }, + }, + + // Expose business data as resources + resourceTemplates: [ + { + uriPattern: 'objectstack://objects/{objectName}', + name: 'Object Data', + description: 'Access object records', + parameters: [ + { + name: 'objectName', + type: 'string', + required: true, + description: 'Name of the object to access', + }, + ], + handler: 'resources.getObjectData', + }, + ], + + // Expose business operations as tools + tools: [ + { + name: 'create_record', + description: 'Create a new record in any object', + parameters: [ + { + name: 'object', + type: 'string', + description: 'Object name (e.g., "account", "contact")', + required: true, + }, + { + name: 'data', + type: 'object', + description: 'Record data as key-value pairs', + required: true, + }, + ], + handler: 'flows.create_record', + sideEffects: 'write', + requiresConfirmation: true, + }, + ], + + // Provide prompt templates + prompts: [ + { + name: 'analyze_customer_data', + description: 'Analyze customer data and generate insights', + messages: [ + { + role: 'system', + content: 'You are a data analyst specializing in customer insights.', + }, + { + role: 'user', + content: 'Analyze the following customer data and provide insights: {{customer_data}}', + }, + ], + arguments: [ + { + name: 'customer_data', + type: 'string', + required: true, + description: 'Customer data in JSON format', + }, + ], + }, + ], +}); +``` + +## Architecture + +``` +┌─────────────┐ ┌─────────────┐ ┌──────────────┐ +│ AI Agent │ ◄─MCP──►│ MCP Server │ ◄─────► │ ObjectStack │ +│ │ │ │ │ Data & Logic │ +└─────────────┘ └─────────────┘ └──────────────┘ + │ │ + │ ├─ Resources (Data) + │ ├─ Tools (Actions) + │ └─ Prompts (Templates) + │ + └─ Uses resources & tools to accomplish tasks +``` + +## Use Cases + +### 1. Expose ObjectStack Objects as MCP Resources + +Make your business data accessible to AI agents: + +```typescript +const resourceTemplates = [ + { + uriPattern: 'objectstack://objects/{objectName}/{recordId}', + name: 'Object Record Detail', + description: 'Get a single record from a specific object', + parameters: [ + { + name: 'objectName', + type: 'string', + required: true, + description: 'Object name (e.g., account, contact, task)', + }, + { + name: 'recordId', + type: 'string', + required: true, + description: 'Record ID', + }, + ], + handler: 'resources.getRecordDetail', + mimeType: 'application/json', + resourceType: 'json', + }, +]; +``` + +### 2. Expose Business Logic as MCP Tools + +Enable AI agents to execute business operations: + +```typescript +const tools = [ + { + name: 'search_records', + description: 'Search for records using natural language or filters', + parameters: [ + { + name: 'object', + type: 'string', + description: 'Object to search in', + required: true, + }, + { + name: 'query', + type: 'string', + description: 'Search query', + required: true, + }, + { + name: 'limit', + type: 'number', + description: 'Maximum number of results', + default: 10, + minimum: 1, + maximum: 100, + }, + ], + handler: 'data.search', + sideEffects: 'read', + }, + + { + name: 'trigger_workflow', + description: 'Trigger a business workflow', + parameters: [ + { + name: 'workflow_name', + type: 'string', + description: 'Workflow to trigger', + required: true, + }, + { + name: 'context_data', + type: 'object', + description: 'Context data for the workflow', + required: true, + }, + ], + handler: 'workflows.trigger', + sideEffects: 'write', + requiresConfirmation: true, + }, +]; +``` + +### 3. Provide Domain-Specific Prompt Templates + +Create specialized prompts for common business tasks: + +```typescript +const prompts = [ + { + name: 'analyze_sales_pipeline', + description: 'Analyze sales pipeline and provide recommendations', + messages: [ + { + role: 'system', + content: 'You are a sales analytics expert.', + }, + { + role: 'user', + content: `Analyze the following sales pipeline data: +Pipeline: {{pipeline_data}} +Time Period: {{time_period}} + +Provide: +1. Current pipeline health +2. Conversion rate analysis +3. Bottleneck identification +4. Recommended actions`, + }, + ], + arguments: [ + { + name: 'pipeline_data', + type: 'string', + required: true, + description: 'Sales pipeline data in JSON format', + }, + { + name: 'time_period', + type: 'string', + required: true, + description: 'Time period for analysis', + }, + ], + category: 'sales', + }, +]; +``` + +## Integration with AI Agents + +### Using MCP Tools in an Agent + +```typescript +import { AgentSchema } from '@objectstack/spec/ai'; + +export const salesAgent = AgentSchema.parse({ + name: 'sales_assistant', + label: 'Sales Assistant', + role: 'Sales Support Agent', + instructions: 'You help sales team with customer data and pipeline management.', + + model: { + provider: 'openai', + model: 'gpt-4-turbo', + temperature: 0.3, + }, + + // Reference MCP tools + tools: [ + { + type: 'action', + name: 'search_records', + description: 'Search for customer records', + }, + { + type: 'flow', + name: 'create_opportunity', + description: 'Create a new sales opportunity', + }, + ], + + knowledge: { + topics: ['sales_playbook', 'product_catalog'], + indexes: ['sales_knowledge_base'], + }, +}); +``` + +## Best Practices + +### 1. Tool Naming + +- Use `snake_case` naming +- Start with verbs (`create_`, `update_`, `search_`, `trigger_`) +- Make names descriptive and clear + +### 2. Parameter Design + +- Provide detailed descriptions to help AI understand usage +- Use appropriate types and validation rules +- Provide sensible defaults +- Use `enum` to constrain valid values + +### 3. Side Effects + +- `none`: No side effects (pure queries) +- `read`: Read-only operations +- `write`: Modifies data +- `delete`: Deletes data + +For operations with side effects, consider setting `requiresConfirmation: true` + +### 4. Security + +1. Use authentication (Bearer Token, API Key) +2. Implement access control (`allowedAgents`, `allowedUsers`) +3. Enable rate limiting (`rateLimit`) +4. Use HTTPS transport +5. Rotate keys regularly + +### 5. Performance + +- Use resource caching (`cacheable: true`) +- Set reasonable `cacheMaxAge` +- Implement rate limiting +- Monitor and log performance metrics + +## Advanced Configuration + +### Transport Examples + +#### HTTP Transport +```typescript +{ + type: 'http', + url: 'https://api.objectstack.ai/mcp', + auth: { + type: 'bearer', + secretRef: 'system:mcp_api_key', + }, + timeout: 30000, + retryAttempts: 3, +} +``` + +#### WebSocket Transport +```typescript +{ + type: 'websocket', + url: 'wss://api.objectstack.ai/mcp', + auth: { + type: 'bearer', + token: 'your-token', + }, + timeout: 60000, +} +``` + +#### stdio Transport +```typescript +{ + type: 'stdio', + command: 'node', + args: ['./mcp-server.js'], + env: { + NODE_ENV: 'production', + }, +} +``` + +### Health Checks + +```typescript +{ + healthCheck: { + enabled: true, + interval: 60000, + timeout: 5000, + endpoint: '/health', + }, + autoStart: true, + restartOnFailure: true, +} +``` + +### Access Control + +```typescript +{ + permissions: { + allowedAgents: ['support_agent', 'sales_agent'], + allowedUsers: ['admin@example.com'], + requireAuth: true, + }, + rateLimit: { + enabled: true, + requestsPerMinute: 100, + requestsPerHour: 5000, + }, +} +``` + +## Reference + +- [Model Context Protocol Official Docs](https://modelcontextprotocol.io) +- [ObjectStack Agent Configuration](./agent.zod.ts) +- [ObjectStack API Protocol](../api/protocol.zod.ts) diff --git a/packages/spec/json-schema/ai/MCPCapability.json b/packages/spec/json-schema/ai/MCPCapability.json new file mode 100644 index 000000000..4078261ec --- /dev/null +++ b/packages/spec/json-schema/ai/MCPCapability.json @@ -0,0 +1,42 @@ +{ + "$ref": "#/definitions/MCPCapability", + "definitions": { + "MCPCapability": { + "type": "object", + "properties": { + "resources": { + "type": "boolean", + "default": false, + "description": "Supports resource listing and retrieval" + }, + "resourceTemplates": { + "type": "boolean", + "default": false, + "description": "Supports dynamic resource templates" + }, + "tools": { + "type": "boolean", + "default": false, + "description": "Supports tool/function calling" + }, + "prompts": { + "type": "boolean", + "default": false, + "description": "Supports prompt templates" + }, + "sampling": { + "type": "boolean", + "default": false, + "description": "Supports sampling from LLMs" + }, + "logging": { + "type": "boolean", + "default": false, + "description": "Supports logging and debugging" + } + }, + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPClientConfig.json b/packages/spec/json-schema/ai/MCPClientConfig.json new file mode 100644 index 000000000..8be682bc0 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPClientConfig.json @@ -0,0 +1,906 @@ +{ + "$ref": "#/definitions/MCPClientConfig", + "definitions": { + "MCPClientConfig": { + "type": "object", + "properties": { + "servers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Server unique identifier (snake_case)" + }, + "label": { + "type": "string", + "description": "Display name" + }, + "description": { + "type": "string" + }, + "serverInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Server name" + }, + "version": { + "type": "string", + "description": "Server version (semver)" + }, + "description": { + "type": "string" + }, + "capabilities": { + "type": "object", + "properties": { + "resources": { + "type": "boolean", + "default": false, + "description": "Supports resource listing and retrieval" + }, + "resourceTemplates": { + "type": "boolean", + "default": false, + "description": "Supports dynamic resource templates" + }, + "tools": { + "type": "boolean", + "default": false, + "description": "Supports tool/function calling" + }, + "prompts": { + "type": "boolean", + "default": false, + "description": "Supports prompt templates" + }, + "sampling": { + "type": "boolean", + "default": false, + "description": "Supports sampling from LLMs" + }, + "logging": { + "type": "boolean", + "default": false, + "description": "Supports logging and debugging" + } + }, + "additionalProperties": false + }, + "protocolVersion": { + "type": "string", + "default": "2024-11-05", + "description": "MCP protocol version" + }, + "vendor": { + "type": "string", + "description": "Server vendor/provider" + }, + "homepage": { + "type": "string", + "format": "uri", + "description": "Server homepage URL" + }, + "documentation": { + "type": "string", + "format": "uri", + "description": "Documentation URL" + } + }, + "required": [ + "name", + "version", + "capabilities" + ], + "additionalProperties": false + }, + "transport": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "stdio", + "http", + "websocket", + "grpc" + ] + }, + "url": { + "type": "string", + "format": "uri", + "description": "Server URL (for HTTP/WebSocket/gRPC)" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom headers for requests" + }, + "auth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "none", + "bearer", + "api_key", + "oauth2", + "custom" + ], + "default": "none" + }, + "token": { + "type": "string", + "description": "Bearer token or API key" + }, + "secretRef": { + "type": "string", + "description": "Reference to stored secret" + }, + "headerName": { + "type": "string", + "description": "Custom auth header name" + } + }, + "additionalProperties": false + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 30000, + "description": "Request timeout in milliseconds" + }, + "retryAttempts": { + "type": "integer", + "minimum": 0, + "maximum": 5, + "default": 3 + }, + "retryDelay": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 1000, + "description": "Delay between retries in milliseconds" + }, + "command": { + "type": "string", + "description": "Command to execute (for stdio transport)" + }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Command arguments" + }, + "env": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables" + }, + "workingDirectory": { + "type": "string", + "description": "Working directory for the process" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "resources": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "Unique resource identifier (e.g., \"objectstack://objects/account/ABC123\")" + }, + "name": { + "type": "string", + "description": "Human-readable resource name" + }, + "description": { + "type": "string", + "description": "Resource description for AI consumption" + }, + "mimeType": { + "type": "string", + "description": "MIME type (e.g., \"application/json\", \"text/plain\")" + }, + "resourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ], + "default": "json" + }, + "content": { + "description": "Resource content (for static resources)" + }, + "contentUrl": { + "type": "string", + "format": "uri", + "description": "URL to fetch content dynamically" + }, + "size": { + "type": "integer", + "minimum": 0, + "description": "Resource size in bytes" + }, + "lastModified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp (ISO 8601)" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Tags for resource categorization" + }, + "permissions": { + "type": "object", + "properties": { + "read": { + "type": "boolean", + "default": true + }, + "write": { + "type": "boolean", + "default": false + }, + "delete": { + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "cacheable": { + "type": "boolean", + "default": true, + "description": "Whether this resource can be cached" + }, + "cacheMaxAge": { + "type": "integer", + "minimum": 0, + "description": "Cache max age in seconds" + } + }, + "required": [ + "uri", + "name" + ], + "additionalProperties": false + }, + "description": "Static resources" + }, + "resourceTemplates": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uriPattern": { + "type": "string", + "description": "URI pattern with variables (e.g., \"objectstack://objects/{objectName}/{recordId}\")" + }, + "name": { + "type": "string", + "description": "Template name" + }, + "description": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean" + ], + "default": "string" + }, + "required": { + "type": "boolean", + "default": true + }, + "description": { + "type": "string" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern" + }, + "default": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "description": "URI parameters" + }, + "handler": { + "type": "string", + "description": "Handler function name for dynamic generation" + }, + "mimeType": { + "type": "string" + }, + "resourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ], + "default": "json" + } + }, + "required": [ + "uriPattern", + "name", + "parameters" + ], + "additionalProperties": false + }, + "description": "Dynamic resource templates" + }, + "tools": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Tool function name (snake_case)" + }, + "description": { + "type": "string", + "description": "Tool description for AI consumption (be detailed and specific)" + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array" + ] + }, + "description": { + "type": "string", + "description": "Parameter description for AI consumption" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {}, + "enum": { + "type": "array", + "items": {}, + "description": "Allowed values" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern (for strings)" + }, + "minimum": { + "type": "number", + "description": "Minimum value (for numbers)" + }, + "maximum": { + "type": "number", + "description": "Maximum value (for numbers)" + }, + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length (for strings/arrays)" + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length (for strings/arrays)" + }, + "properties": { + "type": "object", + "additionalProperties": {}, + "description": "Properties for object types" + }, + "items": { + "description": "Item schema for array types" + } + }, + "required": [ + "name", + "type", + "description" + ], + "additionalProperties": false + }, + "description": "Tool parameters" + }, + "returns": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array", + "void" + ] + }, + "description": { + "type": "string" + }, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array" + ] + }, + "description": { + "type": "string", + "description": "Parameter description for AI consumption" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {}, + "enum": { + "type": "array", + "items": {}, + "description": "Allowed values" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern (for strings)" + }, + "minimum": { + "type": "number", + "description": "Minimum value (for numbers)" + }, + "maximum": { + "type": "number", + "description": "Maximum value (for numbers)" + }, + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length (for strings/arrays)" + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length (for strings/arrays)" + }, + "properties": { + "type": "object", + "additionalProperties": {}, + "description": "Properties for object types" + }, + "items": { + "description": "Item schema for array types" + } + }, + "required": [ + "name", + "type", + "description" + ], + "additionalProperties": false, + "description": "Return value schema" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "handler": { + "type": "string", + "description": "Handler function or endpoint reference" + }, + "async": { + "type": "boolean", + "default": true, + "description": "Whether the tool executes asynchronously" + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "description": "Execution timeout in milliseconds" + }, + "sideEffects": { + "type": "string", + "enum": [ + "none", + "read", + "write", + "delete" + ], + "default": "read", + "description": "Tool side effects" + }, + "requiresConfirmation": { + "type": "boolean", + "default": false, + "description": "Require user confirmation before execution" + }, + "confirmationMessage": { + "type": "string" + }, + "examples": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "parameters": { + "type": "object", + "additionalProperties": {} + }, + "result": {} + }, + "required": [ + "description", + "parameters" + ], + "additionalProperties": false + }, + "description": "Usage examples for AI learning" + }, + "category": { + "type": "string", + "description": "Tool category (e.g., \"data\", \"workflow\", \"analytics\")" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "deprecated": { + "type": "boolean", + "default": false + }, + "version": { + "type": "string", + "default": "1.0.0" + } + }, + "required": [ + "name", + "description", + "parameters", + "handler" + ], + "additionalProperties": false + }, + "description": "Available tools" + }, + "prompts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Prompt template name (snake_case)" + }, + "description": { + "type": "string", + "description": "Prompt description" + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "system", + "user", + "assistant" + ], + "description": "Message role" + }, + "content": { + "type": "string", + "description": "Message content (can include {{variable}} placeholders)" + } + }, + "required": [ + "role", + "content" + ], + "additionalProperties": false + }, + "description": "Prompt message sequence" + }, + "arguments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Argument name" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean" + ], + "default": "string" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "description": "Dynamic arguments for the prompt" + }, + "category": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "version": { + "type": "string", + "default": "1.0.0" + } + }, + "required": [ + "name", + "messages" + ], + "additionalProperties": false + }, + "description": "Prompt templates" + }, + "autoStart": { + "type": "boolean", + "default": false, + "description": "Auto-start server on system boot" + }, + "restartOnFailure": { + "type": "boolean", + "default": true, + "description": "Auto-restart on failure" + }, + "healthCheck": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "interval": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 60000, + "description": "Health check interval in milliseconds" + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 5000, + "description": "Health check timeout in milliseconds" + }, + "endpoint": { + "type": "string", + "description": "Health check endpoint (for HTTP servers)" + } + }, + "additionalProperties": false + }, + "permissions": { + "type": "object", + "properties": { + "allowedAgents": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Agent names allowed to use this server" + }, + "allowedUsers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "User IDs allowed to use this server" + }, + "requireAuth": { + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + }, + "rateLimit": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "requestsPerMinute": { + "type": "integer", + "exclusiveMinimum": 0 + }, + "requestsPerHour": { + "type": "integer", + "exclusiveMinimum": 0 + }, + "burstSize": { + "type": "integer", + "exclusiveMinimum": 0 + } + }, + "additionalProperties": false + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "maintenance", + "deprecated" + ], + "default": "active" + }, + "version": { + "type": "string", + "default": "1.0.0" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "name", + "label", + "serverInfo", + "transport" + ], + "additionalProperties": false + }, + "description": "MCP servers to connect to" + }, + "defaultTimeout": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 30000, + "description": "Default timeout for requests" + }, + "enableCaching": { + "type": "boolean", + "default": true, + "description": "Enable client-side caching" + }, + "cacheMaxAge": { + "type": "integer", + "minimum": 0, + "default": 300, + "description": "Cache max age in seconds" + }, + "retryAttempts": { + "type": "integer", + "minimum": 0, + "maximum": 5, + "default": 3 + }, + "retryDelay": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 1000 + }, + "enableLogging": { + "type": "boolean", + "default": true + }, + "logLevel": { + "type": "string", + "enum": [ + "debug", + "info", + "warn", + "error" + ], + "default": "info" + } + }, + "required": [ + "servers" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPPrompt.json b/packages/spec/json-schema/ai/MCPPrompt.json new file mode 100644 index 000000000..ef1af53fb --- /dev/null +++ b/packages/spec/json-schema/ai/MCPPrompt.json @@ -0,0 +1,99 @@ +{ + "$ref": "#/definitions/MCPPrompt", + "definitions": { + "MCPPrompt": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Prompt template name (snake_case)" + }, + "description": { + "type": "string", + "description": "Prompt description" + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "system", + "user", + "assistant" + ], + "description": "Message role" + }, + "content": { + "type": "string", + "description": "Message content (can include {{variable}} placeholders)" + } + }, + "required": [ + "role", + "content" + ], + "additionalProperties": false + }, + "description": "Prompt message sequence" + }, + "arguments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Argument name" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean" + ], + "default": "string" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "description": "Dynamic arguments for the prompt" + }, + "category": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "version": { + "type": "string", + "default": "1.0.0" + } + }, + "required": [ + "name", + "messages" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPPromptArgument.json b/packages/spec/json-schema/ai/MCPPromptArgument.json new file mode 100644 index 000000000..36290a870 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPPromptArgument.json @@ -0,0 +1,36 @@ +{ + "$ref": "#/definitions/MCPPromptArgument", + "definitions": { + "MCPPromptArgument": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Argument name" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean" + ], + "default": "string" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPPromptMessage.json b/packages/spec/json-schema/ai/MCPPromptMessage.json new file mode 100644 index 000000000..9d40eacdf --- /dev/null +++ b/packages/spec/json-schema/ai/MCPPromptMessage.json @@ -0,0 +1,29 @@ +{ + "$ref": "#/definitions/MCPPromptMessage", + "definitions": { + "MCPPromptMessage": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "system", + "user", + "assistant" + ], + "description": "Message role" + }, + "content": { + "type": "string", + "description": "Message content (can include {{variable}} placeholders)" + } + }, + "required": [ + "role", + "content" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPPromptRequest.json b/packages/spec/json-schema/ai/MCPPromptRequest.json new file mode 100644 index 000000000..5701f9459 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPPromptRequest.json @@ -0,0 +1,24 @@ +{ + "$ref": "#/definitions/MCPPromptRequest", + "definitions": { + "MCPPromptRequest": { + "type": "object", + "properties": { + "promptName": { + "type": "string", + "description": "Prompt template to use" + }, + "arguments": { + "type": "object", + "additionalProperties": {}, + "description": "Prompt arguments" + } + }, + "required": [ + "promptName" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPPromptResponse.json b/packages/spec/json-schema/ai/MCPPromptResponse.json new file mode 100644 index 000000000..5263f49c4 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPPromptResponse.json @@ -0,0 +1,46 @@ +{ + "$ref": "#/definitions/MCPPromptResponse", + "definitions": { + "MCPPromptResponse": { + "type": "object", + "properties": { + "promptName": { + "type": "string" + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "system", + "user", + "assistant" + ], + "description": "Message role" + }, + "content": { + "type": "string", + "description": "Message content (can include {{variable}} placeholders)" + } + }, + "required": [ + "role", + "content" + ], + "additionalProperties": false + }, + "description": "Rendered prompt messages" + } + }, + "required": [ + "promptName", + "messages" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPResource.json b/packages/spec/json-schema/ai/MCPResource.json new file mode 100644 index 000000000..9e8a3b095 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPResource.json @@ -0,0 +1,95 @@ +{ + "$ref": "#/definitions/MCPResource", + "definitions": { + "MCPResource": { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "Unique resource identifier (e.g., \"objectstack://objects/account/ABC123\")" + }, + "name": { + "type": "string", + "description": "Human-readable resource name" + }, + "description": { + "type": "string", + "description": "Resource description for AI consumption" + }, + "mimeType": { + "type": "string", + "description": "MIME type (e.g., \"application/json\", \"text/plain\")" + }, + "resourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ], + "default": "json" + }, + "content": { + "description": "Resource content (for static resources)" + }, + "contentUrl": { + "type": "string", + "format": "uri", + "description": "URL to fetch content dynamically" + }, + "size": { + "type": "integer", + "minimum": 0, + "description": "Resource size in bytes" + }, + "lastModified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp (ISO 8601)" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Tags for resource categorization" + }, + "permissions": { + "type": "object", + "properties": { + "read": { + "type": "boolean", + "default": true + }, + "write": { + "type": "boolean", + "default": false + }, + "delete": { + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "cacheable": { + "type": "boolean", + "default": true, + "description": "Whether this resource can be cached" + }, + "cacheMaxAge": { + "type": "integer", + "minimum": 0, + "description": "Cache max age in seconds" + } + }, + "required": [ + "uri", + "name" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPResourceRequest.json b/packages/spec/json-schema/ai/MCPResourceRequest.json new file mode 100644 index 000000000..56ab9b84f --- /dev/null +++ b/packages/spec/json-schema/ai/MCPResourceRequest.json @@ -0,0 +1,24 @@ +{ + "$ref": "#/definitions/MCPResourceRequest", + "definitions": { + "MCPResourceRequest": { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "Resource URI to fetch" + }, + "parameters": { + "type": "object", + "additionalProperties": {}, + "description": "URI template parameters" + } + }, + "required": [ + "uri" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPResourceResponse.json b/packages/spec/json-schema/ai/MCPResourceResponse.json new file mode 100644 index 000000000..ee8131ea7 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPResourceResponse.json @@ -0,0 +1,107 @@ +{ + "$ref": "#/definitions/MCPResourceResponse", + "definitions": { + "MCPResourceResponse": { + "type": "object", + "properties": { + "resource": { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "Unique resource identifier (e.g., \"objectstack://objects/account/ABC123\")" + }, + "name": { + "type": "string", + "description": "Human-readable resource name" + }, + "description": { + "type": "string", + "description": "Resource description for AI consumption" + }, + "mimeType": { + "type": "string", + "description": "MIME type (e.g., \"application/json\", \"text/plain\")" + }, + "resourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ], + "default": "json" + }, + "content": { + "description": "Resource content (for static resources)" + }, + "contentUrl": { + "type": "string", + "format": "uri", + "description": "URL to fetch content dynamically" + }, + "size": { + "type": "integer", + "minimum": 0, + "description": "Resource size in bytes" + }, + "lastModified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp (ISO 8601)" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Tags for resource categorization" + }, + "permissions": { + "type": "object", + "properties": { + "read": { + "type": "boolean", + "default": true + }, + "write": { + "type": "boolean", + "default": false + }, + "delete": { + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "cacheable": { + "type": "boolean", + "default": true, + "description": "Whether this resource can be cached" + }, + "cacheMaxAge": { + "type": "integer", + "minimum": 0, + "description": "Cache max age in seconds" + } + }, + "required": [ + "uri", + "name" + ], + "additionalProperties": false + }, + "content": { + "description": "Resource content" + } + }, + "required": [ + "resource" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPResourceTemplate.json b/packages/spec/json-schema/ai/MCPResourceTemplate.json new file mode 100644 index 000000000..4715fadc4 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPResourceTemplate.json @@ -0,0 +1,83 @@ +{ + "$ref": "#/definitions/MCPResourceTemplate", + "definitions": { + "MCPResourceTemplate": { + "type": "object", + "properties": { + "uriPattern": { + "type": "string", + "description": "URI pattern with variables (e.g., \"objectstack://objects/{objectName}/{recordId}\")" + }, + "name": { + "type": "string", + "description": "Template name" + }, + "description": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean" + ], + "default": "string" + }, + "required": { + "type": "boolean", + "default": true + }, + "description": { + "type": "string" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern" + }, + "default": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "description": "URI parameters" + }, + "handler": { + "type": "string", + "description": "Handler function name for dynamic generation" + }, + "mimeType": { + "type": "string" + }, + "resourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ], + "default": "json" + } + }, + "required": [ + "uriPattern", + "name", + "parameters" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPResourceType.json b/packages/spec/json-schema/ai/MCPResourceType.json new file mode 100644 index 000000000..812311b3e --- /dev/null +++ b/packages/spec/json-schema/ai/MCPResourceType.json @@ -0,0 +1,15 @@ +{ + "$ref": "#/definitions/MCPResourceType", + "definitions": { + "MCPResourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPServerConfig.json b/packages/spec/json-schema/ai/MCPServerConfig.json new file mode 100644 index 000000000..6552cb495 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPServerConfig.json @@ -0,0 +1,851 @@ +{ + "$ref": "#/definitions/MCPServerConfig", + "definitions": { + "MCPServerConfig": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Server unique identifier (snake_case)" + }, + "label": { + "type": "string", + "description": "Display name" + }, + "description": { + "type": "string" + }, + "serverInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Server name" + }, + "version": { + "type": "string", + "description": "Server version (semver)" + }, + "description": { + "type": "string" + }, + "capabilities": { + "type": "object", + "properties": { + "resources": { + "type": "boolean", + "default": false, + "description": "Supports resource listing and retrieval" + }, + "resourceTemplates": { + "type": "boolean", + "default": false, + "description": "Supports dynamic resource templates" + }, + "tools": { + "type": "boolean", + "default": false, + "description": "Supports tool/function calling" + }, + "prompts": { + "type": "boolean", + "default": false, + "description": "Supports prompt templates" + }, + "sampling": { + "type": "boolean", + "default": false, + "description": "Supports sampling from LLMs" + }, + "logging": { + "type": "boolean", + "default": false, + "description": "Supports logging and debugging" + } + }, + "additionalProperties": false + }, + "protocolVersion": { + "type": "string", + "default": "2024-11-05", + "description": "MCP protocol version" + }, + "vendor": { + "type": "string", + "description": "Server vendor/provider" + }, + "homepage": { + "type": "string", + "format": "uri", + "description": "Server homepage URL" + }, + "documentation": { + "type": "string", + "format": "uri", + "description": "Documentation URL" + } + }, + "required": [ + "name", + "version", + "capabilities" + ], + "additionalProperties": false + }, + "transport": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "stdio", + "http", + "websocket", + "grpc" + ] + }, + "url": { + "type": "string", + "format": "uri", + "description": "Server URL (for HTTP/WebSocket/gRPC)" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom headers for requests" + }, + "auth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "none", + "bearer", + "api_key", + "oauth2", + "custom" + ], + "default": "none" + }, + "token": { + "type": "string", + "description": "Bearer token or API key" + }, + "secretRef": { + "type": "string", + "description": "Reference to stored secret" + }, + "headerName": { + "type": "string", + "description": "Custom auth header name" + } + }, + "additionalProperties": false + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 30000, + "description": "Request timeout in milliseconds" + }, + "retryAttempts": { + "type": "integer", + "minimum": 0, + "maximum": 5, + "default": 3 + }, + "retryDelay": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 1000, + "description": "Delay between retries in milliseconds" + }, + "command": { + "type": "string", + "description": "Command to execute (for stdio transport)" + }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Command arguments" + }, + "env": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables" + }, + "workingDirectory": { + "type": "string", + "description": "Working directory for the process" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "resources": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uri": { + "type": "string", + "description": "Unique resource identifier (e.g., \"objectstack://objects/account/ABC123\")" + }, + "name": { + "type": "string", + "description": "Human-readable resource name" + }, + "description": { + "type": "string", + "description": "Resource description for AI consumption" + }, + "mimeType": { + "type": "string", + "description": "MIME type (e.g., \"application/json\", \"text/plain\")" + }, + "resourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ], + "default": "json" + }, + "content": { + "description": "Resource content (for static resources)" + }, + "contentUrl": { + "type": "string", + "format": "uri", + "description": "URL to fetch content dynamically" + }, + "size": { + "type": "integer", + "minimum": 0, + "description": "Resource size in bytes" + }, + "lastModified": { + "type": "string", + "format": "date-time", + "description": "Last modification timestamp (ISO 8601)" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Tags for resource categorization" + }, + "permissions": { + "type": "object", + "properties": { + "read": { + "type": "boolean", + "default": true + }, + "write": { + "type": "boolean", + "default": false + }, + "delete": { + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "cacheable": { + "type": "boolean", + "default": true, + "description": "Whether this resource can be cached" + }, + "cacheMaxAge": { + "type": "integer", + "minimum": 0, + "description": "Cache max age in seconds" + } + }, + "required": [ + "uri", + "name" + ], + "additionalProperties": false + }, + "description": "Static resources" + }, + "resourceTemplates": { + "type": "array", + "items": { + "type": "object", + "properties": { + "uriPattern": { + "type": "string", + "description": "URI pattern with variables (e.g., \"objectstack://objects/{objectName}/{recordId}\")" + }, + "name": { + "type": "string", + "description": "Template name" + }, + "description": { + "type": "string" + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean" + ], + "default": "string" + }, + "required": { + "type": "boolean", + "default": true + }, + "description": { + "type": "string" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern" + }, + "default": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "description": "URI parameters" + }, + "handler": { + "type": "string", + "description": "Handler function name for dynamic generation" + }, + "mimeType": { + "type": "string" + }, + "resourceType": { + "type": "string", + "enum": [ + "text", + "json", + "binary", + "stream" + ], + "default": "json" + } + }, + "required": [ + "uriPattern", + "name", + "parameters" + ], + "additionalProperties": false + }, + "description": "Dynamic resource templates" + }, + "tools": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Tool function name (snake_case)" + }, + "description": { + "type": "string", + "description": "Tool description for AI consumption (be detailed and specific)" + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array" + ] + }, + "description": { + "type": "string", + "description": "Parameter description for AI consumption" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {}, + "enum": { + "type": "array", + "items": {}, + "description": "Allowed values" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern (for strings)" + }, + "minimum": { + "type": "number", + "description": "Minimum value (for numbers)" + }, + "maximum": { + "type": "number", + "description": "Maximum value (for numbers)" + }, + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length (for strings/arrays)" + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length (for strings/arrays)" + }, + "properties": { + "type": "object", + "additionalProperties": {}, + "description": "Properties for object types" + }, + "items": { + "description": "Item schema for array types" + } + }, + "required": [ + "name", + "type", + "description" + ], + "additionalProperties": false + }, + "description": "Tool parameters" + }, + "returns": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array", + "void" + ] + }, + "description": { + "type": "string" + }, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array" + ] + }, + "description": { + "type": "string", + "description": "Parameter description for AI consumption" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {}, + "enum": { + "type": "array", + "items": {}, + "description": "Allowed values" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern (for strings)" + }, + "minimum": { + "type": "number", + "description": "Minimum value (for numbers)" + }, + "maximum": { + "type": "number", + "description": "Maximum value (for numbers)" + }, + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length (for strings/arrays)" + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length (for strings/arrays)" + }, + "properties": { + "type": "object", + "additionalProperties": {}, + "description": "Properties for object types" + }, + "items": { + "description": "Item schema for array types" + } + }, + "required": [ + "name", + "type", + "description" + ], + "additionalProperties": false, + "description": "Return value schema" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "handler": { + "type": "string", + "description": "Handler function or endpoint reference" + }, + "async": { + "type": "boolean", + "default": true, + "description": "Whether the tool executes asynchronously" + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "description": "Execution timeout in milliseconds" + }, + "sideEffects": { + "type": "string", + "enum": [ + "none", + "read", + "write", + "delete" + ], + "default": "read", + "description": "Tool side effects" + }, + "requiresConfirmation": { + "type": "boolean", + "default": false, + "description": "Require user confirmation before execution" + }, + "confirmationMessage": { + "type": "string" + }, + "examples": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "parameters": { + "type": "object", + "additionalProperties": {} + }, + "result": {} + }, + "required": [ + "description", + "parameters" + ], + "additionalProperties": false + }, + "description": "Usage examples for AI learning" + }, + "category": { + "type": "string", + "description": "Tool category (e.g., \"data\", \"workflow\", \"analytics\")" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "deprecated": { + "type": "boolean", + "default": false + }, + "version": { + "type": "string", + "default": "1.0.0" + } + }, + "required": [ + "name", + "description", + "parameters", + "handler" + ], + "additionalProperties": false + }, + "description": "Available tools" + }, + "prompts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Prompt template name (snake_case)" + }, + "description": { + "type": "string", + "description": "Prompt description" + }, + "messages": { + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "type": "string", + "enum": [ + "system", + "user", + "assistant" + ], + "description": "Message role" + }, + "content": { + "type": "string", + "description": "Message content (can include {{variable}} placeholders)" + } + }, + "required": [ + "role", + "content" + ], + "additionalProperties": false + }, + "description": "Prompt message sequence" + }, + "arguments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Argument name" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean" + ], + "default": "string" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "description": "Dynamic arguments for the prompt" + }, + "category": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "version": { + "type": "string", + "default": "1.0.0" + } + }, + "required": [ + "name", + "messages" + ], + "additionalProperties": false + }, + "description": "Prompt templates" + }, + "autoStart": { + "type": "boolean", + "default": false, + "description": "Auto-start server on system boot" + }, + "restartOnFailure": { + "type": "boolean", + "default": true, + "description": "Auto-restart on failure" + }, + "healthCheck": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "interval": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 60000, + "description": "Health check interval in milliseconds" + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 5000, + "description": "Health check timeout in milliseconds" + }, + "endpoint": { + "type": "string", + "description": "Health check endpoint (for HTTP servers)" + } + }, + "additionalProperties": false + }, + "permissions": { + "type": "object", + "properties": { + "allowedAgents": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Agent names allowed to use this server" + }, + "allowedUsers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "User IDs allowed to use this server" + }, + "requireAuth": { + "type": "boolean", + "default": true + } + }, + "additionalProperties": false + }, + "rateLimit": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "requestsPerMinute": { + "type": "integer", + "exclusiveMinimum": 0 + }, + "requestsPerHour": { + "type": "integer", + "exclusiveMinimum": 0 + }, + "burstSize": { + "type": "integer", + "exclusiveMinimum": 0 + } + }, + "additionalProperties": false + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "status": { + "type": "string", + "enum": [ + "active", + "inactive", + "maintenance", + "deprecated" + ], + "default": "active" + }, + "version": { + "type": "string", + "default": "1.0.0" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "name", + "label", + "serverInfo", + "transport" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPServerInfo.json b/packages/spec/json-schema/ai/MCPServerInfo.json new file mode 100644 index 000000000..480211b50 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPServerInfo.json @@ -0,0 +1,83 @@ +{ + "$ref": "#/definitions/MCPServerInfo", + "definitions": { + "MCPServerInfo": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Server name" + }, + "version": { + "type": "string", + "description": "Server version (semver)" + }, + "description": { + "type": "string" + }, + "capabilities": { + "type": "object", + "properties": { + "resources": { + "type": "boolean", + "default": false, + "description": "Supports resource listing and retrieval" + }, + "resourceTemplates": { + "type": "boolean", + "default": false, + "description": "Supports dynamic resource templates" + }, + "tools": { + "type": "boolean", + "default": false, + "description": "Supports tool/function calling" + }, + "prompts": { + "type": "boolean", + "default": false, + "description": "Supports prompt templates" + }, + "sampling": { + "type": "boolean", + "default": false, + "description": "Supports sampling from LLMs" + }, + "logging": { + "type": "boolean", + "default": false, + "description": "Supports logging and debugging" + } + }, + "additionalProperties": false + }, + "protocolVersion": { + "type": "string", + "default": "2024-11-05", + "description": "MCP protocol version" + }, + "vendor": { + "type": "string", + "description": "Server vendor/provider" + }, + "homepage": { + "type": "string", + "format": "uri", + "description": "Server homepage URL" + }, + "documentation": { + "type": "string", + "format": "uri", + "description": "Documentation URL" + } + }, + "required": [ + "name", + "version", + "capabilities" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPTool.json b/packages/spec/json-schema/ai/MCPTool.json new file mode 100644 index 000000000..c14b528b0 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPTool.json @@ -0,0 +1,266 @@ +{ + "$ref": "#/definitions/MCPTool", + "definitions": { + "MCPTool": { + "type": "object", + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z_][a-z0-9_]*$", + "description": "Tool function name (snake_case)" + }, + "description": { + "type": "string", + "description": "Tool description for AI consumption (be detailed and specific)" + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array" + ] + }, + "description": { + "type": "string", + "description": "Parameter description for AI consumption" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {}, + "enum": { + "type": "array", + "items": {}, + "description": "Allowed values" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern (for strings)" + }, + "minimum": { + "type": "number", + "description": "Minimum value (for numbers)" + }, + "maximum": { + "type": "number", + "description": "Maximum value (for numbers)" + }, + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length (for strings/arrays)" + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length (for strings/arrays)" + }, + "properties": { + "type": "object", + "additionalProperties": {}, + "description": "Properties for object types" + }, + "items": { + "description": "Item schema for array types" + } + }, + "required": [ + "name", + "type", + "description" + ], + "additionalProperties": false + }, + "description": "Tool parameters" + }, + "returns": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array", + "void" + ] + }, + "description": { + "type": "string" + }, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array" + ] + }, + "description": { + "type": "string", + "description": "Parameter description for AI consumption" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {}, + "enum": { + "type": "array", + "items": {}, + "description": "Allowed values" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern (for strings)" + }, + "minimum": { + "type": "number", + "description": "Minimum value (for numbers)" + }, + "maximum": { + "type": "number", + "description": "Maximum value (for numbers)" + }, + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length (for strings/arrays)" + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length (for strings/arrays)" + }, + "properties": { + "type": "object", + "additionalProperties": {}, + "description": "Properties for object types" + }, + "items": { + "description": "Item schema for array types" + } + }, + "required": [ + "name", + "type", + "description" + ], + "additionalProperties": false, + "description": "Return value schema" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "handler": { + "type": "string", + "description": "Handler function or endpoint reference" + }, + "async": { + "type": "boolean", + "default": true, + "description": "Whether the tool executes asynchronously" + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "description": "Execution timeout in milliseconds" + }, + "sideEffects": { + "type": "string", + "enum": [ + "none", + "read", + "write", + "delete" + ], + "default": "read", + "description": "Tool side effects" + }, + "requiresConfirmation": { + "type": "boolean", + "default": false, + "description": "Require user confirmation before execution" + }, + "confirmationMessage": { + "type": "string" + }, + "examples": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "parameters": { + "type": "object", + "additionalProperties": {} + }, + "result": {} + }, + "required": [ + "description", + "parameters" + ], + "additionalProperties": false + }, + "description": "Usage examples for AI learning" + }, + "category": { + "type": "string", + "description": "Tool category (e.g., \"data\", \"workflow\", \"analytics\")" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "deprecated": { + "type": "boolean", + "default": false + }, + "version": { + "type": "string", + "default": "1.0.0" + } + }, + "required": [ + "name", + "description", + "parameters", + "handler" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPToolCallRequest.json b/packages/spec/json-schema/ai/MCPToolCallRequest.json new file mode 100644 index 000000000..1e5628846 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPToolCallRequest.json @@ -0,0 +1,52 @@ +{ + "$ref": "#/definitions/MCPToolCallRequest", + "definitions": { + "MCPToolCallRequest": { + "type": "object", + "properties": { + "toolName": { + "type": "string", + "description": "Tool to invoke" + }, + "parameters": { + "type": "object", + "additionalProperties": {}, + "description": "Tool parameters" + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0 + }, + "confirmationProvided": { + "type": "boolean", + "description": "User confirmation for tools that require it" + }, + "context": { + "type": "object", + "properties": { + "userId": { + "type": "string" + }, + "sessionId": { + "type": "string" + }, + "agentName": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": {} + } + }, + "additionalProperties": false + } + }, + "required": [ + "toolName", + "parameters" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPToolCallResponse.json b/packages/spec/json-schema/ai/MCPToolCallResponse.json new file mode 100644 index 000000000..de5a1e07b --- /dev/null +++ b/packages/spec/json-schema/ai/MCPToolCallResponse.json @@ -0,0 +1,57 @@ +{ + "$ref": "#/definitions/MCPToolCallResponse", + "definitions": { + "MCPToolCallResponse": { + "type": "object", + "properties": { + "toolName": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "success", + "error", + "timeout", + "cancelled" + ] + }, + "result": { + "description": "Tool execution result" + }, + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "details": {} + }, + "required": [ + "code", + "message" + ], + "additionalProperties": false + }, + "executionTime": { + "type": "number", + "minimum": 0, + "description": "Execution time in milliseconds" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "toolName", + "status" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPToolParameter.json b/packages/spec/json-schema/ai/MCPToolParameter.json new file mode 100644 index 000000000..edf77c921 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPToolParameter.json @@ -0,0 +1,75 @@ +{ + "$ref": "#/definitions/MCPToolParameter", + "definitions": { + "MCPToolParameter": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Parameter name" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "object", + "array" + ] + }, + "description": { + "type": "string", + "description": "Parameter description for AI consumption" + }, + "required": { + "type": "boolean", + "default": false + }, + "default": {}, + "enum": { + "type": "array", + "items": {}, + "description": "Allowed values" + }, + "pattern": { + "type": "string", + "description": "Regex validation pattern (for strings)" + }, + "minimum": { + "type": "number", + "description": "Minimum value (for numbers)" + }, + "maximum": { + "type": "number", + "description": "Maximum value (for numbers)" + }, + "minLength": { + "type": "integer", + "minimum": 0, + "description": "Minimum length (for strings/arrays)" + }, + "maxLength": { + "type": "integer", + "minimum": 0, + "description": "Maximum length (for strings/arrays)" + }, + "properties": { + "type": "object", + "additionalProperties": {}, + "description": "Properties for object types" + }, + "items": { + "description": "Item schema for array types" + } + }, + "required": [ + "name", + "type", + "description" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPTransportConfig.json b/packages/spec/json-schema/ai/MCPTransportConfig.json new file mode 100644 index 000000000..3f84ff025 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPTransportConfig.json @@ -0,0 +1,105 @@ +{ + "$ref": "#/definitions/MCPTransportConfig", + "definitions": { + "MCPTransportConfig": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "stdio", + "http", + "websocket", + "grpc" + ] + }, + "url": { + "type": "string", + "format": "uri", + "description": "Server URL (for HTTP/WebSocket/gRPC)" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Custom headers for requests" + }, + "auth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "none", + "bearer", + "api_key", + "oauth2", + "custom" + ], + "default": "none" + }, + "token": { + "type": "string", + "description": "Bearer token or API key" + }, + "secretRef": { + "type": "string", + "description": "Reference to stored secret" + }, + "headerName": { + "type": "string", + "description": "Custom auth header name" + } + }, + "additionalProperties": false + }, + "timeout": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 30000, + "description": "Request timeout in milliseconds" + }, + "retryAttempts": { + "type": "integer", + "minimum": 0, + "maximum": 5, + "default": 3 + }, + "retryDelay": { + "type": "integer", + "exclusiveMinimum": 0, + "default": 1000, + "description": "Delay between retries in milliseconds" + }, + "command": { + "type": "string", + "description": "Command to execute (for stdio transport)" + }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Command arguments" + }, + "env": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables" + }, + "workingDirectory": { + "type": "string", + "description": "Working directory for the process" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/ai/MCPTransportType.json b/packages/spec/json-schema/ai/MCPTransportType.json new file mode 100644 index 000000000..ac71ee977 --- /dev/null +++ b/packages/spec/json-schema/ai/MCPTransportType.json @@ -0,0 +1,15 @@ +{ + "$ref": "#/definitions/MCPTransportType", + "definitions": { + "MCPTransportType": { + "type": "string", + "enum": [ + "stdio", + "http", + "websocket", + "grpc" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/api/ApiCapabilities.json b/packages/spec/json-schema/api/ApiCapabilities.json index 106516172..359a684ce 100644 --- a/packages/spec/json-schema/api/ApiCapabilities.json +++ b/packages/spec/json-schema/api/ApiCapabilities.json @@ -29,6 +29,26 @@ "type": "boolean", "default": false, "description": "Is Hub management enabled?" + }, + "ai": { + "type": "boolean", + "default": false, + "description": "Is the AI engine enabled?" + }, + "workflow": { + "type": "boolean", + "default": false, + "description": "Is the Workflow engine enabled?" + }, + "notifications": { + "type": "boolean", + "default": false, + "description": "Is the Notification service enabled?" + }, + "i18n": { + "type": "boolean", + "default": false, + "description": "Is the i18n service enabled?" } }, "additionalProperties": false diff --git a/packages/spec/json-schema/api/ApiRoutes.json b/packages/spec/json-schema/api/ApiRoutes.json index b0f62b890..081cf3c87 100644 --- a/packages/spec/json-schema/api/ApiRoutes.json +++ b/packages/spec/json-schema/api/ApiRoutes.json @@ -6,39 +6,63 @@ "properties": { "data": { "type": "string", - "description": "e.g. /api/data" + "description": "e.g. /api/v1/data" }, "metadata": { "type": "string", - "description": "e.g. /api/meta" + "description": "e.g. /api/v1/meta" }, "ui": { "type": "string", - "description": "e.g. /api/ui" + "description": "e.g. /api/v1/ui" }, "auth": { "type": "string", - "description": "e.g. /api/auth" + "description": "e.g. /api/v1/auth" }, "automation": { "type": "string", - "description": "e.g. /api/automation" + "description": "e.g. /api/v1/automation" }, "storage": { "type": "string", - "description": "e.g. /api/storage" + "description": "e.g. /api/v1/storage" }, "analytics": { "type": "string", - "description": "e.g. /api/analytics" + "description": "e.g. /api/v1/analytics" }, "hub": { "type": "string", - "description": "e.g. /api/hub" + "description": "e.g. /api/v1/hub" }, "graphql": { "type": "string", "description": "e.g. /graphql" + }, + "packages": { + "type": "string", + "description": "e.g. /api/v1/packages" + }, + "workflow": { + "type": "string", + "description": "e.g. /api/v1/workflow" + }, + "realtime": { + "type": "string", + "description": "e.g. /api/v1/realtime" + }, + "notifications": { + "type": "string", + "description": "e.g. /api/v1/notifications" + }, + "ai": { + "type": "string", + "description": "e.g. /api/v1/ai" + }, + "i18n": { + "type": "string", + "description": "e.g. /api/v1/i18n" } }, "required": [ diff --git a/packages/spec/json-schema/api/CompileManifestResponse.json b/packages/spec/json-schema/api/CompileManifestResponse.json index 491da6630..0c48c423d 100644 --- a/packages/spec/json-schema/api/CompileManifestResponse.json +++ b/packages/spec/json-schema/api/CompileManifestResponse.json @@ -412,6 +412,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/api/DisablePackageResponse.json b/packages/spec/json-schema/api/DisablePackageResponse.json index e1210367b..619d469a7 100644 --- a/packages/spec/json-schema/api/DisablePackageResponse.json +++ b/packages/spec/json-schema/api/DisablePackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/api/Discovery.json b/packages/spec/json-schema/api/Discovery.json index b7a62fa46..90d5f255a 100644 --- a/packages/spec/json-schema/api/Discovery.json +++ b/packages/spec/json-schema/api/Discovery.json @@ -23,39 +23,63 @@ "properties": { "data": { "type": "string", - "description": "e.g. /api/data" + "description": "e.g. /api/v1/data" }, "metadata": { "type": "string", - "description": "e.g. /api/meta" + "description": "e.g. /api/v1/meta" }, "ui": { "type": "string", - "description": "e.g. /api/ui" + "description": "e.g. /api/v1/ui" }, "auth": { "type": "string", - "description": "e.g. /api/auth" + "description": "e.g. /api/v1/auth" }, "automation": { "type": "string", - "description": "e.g. /api/automation" + "description": "e.g. /api/v1/automation" }, "storage": { "type": "string", - "description": "e.g. /api/storage" + "description": "e.g. /api/v1/storage" }, "analytics": { "type": "string", - "description": "e.g. /api/analytics" + "description": "e.g. /api/v1/analytics" }, "hub": { "type": "string", - "description": "e.g. /api/hub" + "description": "e.g. /api/v1/hub" }, "graphql": { "type": "string", "description": "e.g. /graphql" + }, + "packages": { + "type": "string", + "description": "e.g. /api/v1/packages" + }, + "workflow": { + "type": "string", + "description": "e.g. /api/v1/workflow" + }, + "realtime": { + "type": "string", + "description": "e.g. /api/v1/realtime" + }, + "notifications": { + "type": "string", + "description": "e.g. /api/v1/notifications" + }, + "ai": { + "type": "string", + "description": "e.g. /api/v1/ai" + }, + "i18n": { + "type": "string", + "description": "e.g. /api/v1/i18n" } }, "required": [ @@ -93,6 +117,26 @@ "type": "boolean", "default": false, "description": "Is Hub management enabled?" + }, + "ai": { + "type": "boolean", + "default": false, + "description": "Is the AI engine enabled?" + }, + "workflow": { + "type": "boolean", + "default": false, + "description": "Is the Workflow engine enabled?" + }, + "notifications": { + "type": "boolean", + "default": false, + "description": "Is the Notification service enabled?" + }, + "i18n": { + "type": "boolean", + "default": false, + "description": "Is the i18n service enabled?" } }, "additionalProperties": false diff --git a/packages/spec/json-schema/api/DispatcherConfig.json b/packages/spec/json-schema/api/DispatcherConfig.json new file mode 100644 index 000000000..58b821b73 --- /dev/null +++ b/packages/spec/json-schema/api/DispatcherConfig.json @@ -0,0 +1,95 @@ +{ + "$ref": "#/definitions/DispatcherConfig", + "definitions": { + "DispatcherConfig": { + "type": "object", + "properties": { + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "URL path prefix for routing (e.g. /api/v1/data)" + }, + "service": { + "type": "string", + "enum": [ + "metadata", + "data", + "auth", + "file-storage", + "search", + "cache", + "queue", + "automation", + "graphql", + "analytics", + "hub", + "realtime", + "job", + "notification", + "ai", + "i18n", + "ui", + "workflow" + ], + "description": "Target core service name" + }, + "authRequired": { + "type": "boolean", + "default": true, + "description": "Whether authentication is required" + }, + "criticality": { + "type": "string", + "enum": [ + "required", + "core", + "optional" + ], + "default": "optional", + "description": "Service criticality level for unavailability handling" + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Required permissions for this route namespace" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "Route-to-service mappings" + }, + "fallback": { + "type": "string", + "enum": [ + "404", + "proxy", + "custom" + ], + "default": "404", + "description": "Behavior when no route matches" + }, + "proxyTarget": { + "type": "string", + "format": "uri", + "description": "Proxy target URL when fallback is \"proxy\"" + } + }, + "required": [ + "routes" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/api/DispatcherRoute.json b/packages/spec/json-schema/api/DispatcherRoute.json new file mode 100644 index 000000000..2bbd85ff3 --- /dev/null +++ b/packages/spec/json-schema/api/DispatcherRoute.json @@ -0,0 +1,67 @@ +{ + "$ref": "#/definitions/DispatcherRoute", + "definitions": { + "DispatcherRoute": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "URL path prefix for routing (e.g. /api/v1/data)" + }, + "service": { + "type": "string", + "enum": [ + "metadata", + "data", + "auth", + "file-storage", + "search", + "cache", + "queue", + "automation", + "graphql", + "analytics", + "hub", + "realtime", + "job", + "notification", + "ai", + "i18n", + "ui", + "workflow" + ], + "description": "Target core service name" + }, + "authRequired": { + "type": "boolean", + "default": true, + "description": "Whether authentication is required" + }, + "criticality": { + "type": "string", + "enum": [ + "required", + "core", + "optional" + ], + "default": "optional", + "description": "Service criticality level for unavailability handling" + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Required permissions for this route namespace" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/packages/spec/json-schema/api/EnablePackageResponse.json b/packages/spec/json-schema/api/EnablePackageResponse.json index 2c0f74757..10c295192 100644 --- a/packages/spec/json-schema/api/EnablePackageResponse.json +++ b/packages/spec/json-schema/api/EnablePackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/api/GetDiscoveryResponse.json b/packages/spec/json-schema/api/GetDiscoveryResponse.json index 2ec6284f2..b573f32fa 100644 --- a/packages/spec/json-schema/api/GetDiscoveryResponse.json +++ b/packages/spec/json-schema/api/GetDiscoveryResponse.json @@ -40,6 +40,26 @@ "type": "boolean", "default": false, "description": "Is Hub management enabled?" + }, + "ai": { + "type": "boolean", + "default": false, + "description": "Is the AI engine enabled?" + }, + "workflow": { + "type": "boolean", + "default": false, + "description": "Is the Workflow engine enabled?" + }, + "notifications": { + "type": "boolean", + "default": false, + "description": "Is the Notification service enabled?" + }, + "i18n": { + "type": "boolean", + "default": false, + "description": "Is the i18n service enabled?" } }, "additionalProperties": false, @@ -50,39 +70,63 @@ "properties": { "data": { "type": "string", - "description": "e.g. /api/data" + "description": "e.g. /api/v1/data" }, "metadata": { "type": "string", - "description": "e.g. /api/meta" + "description": "e.g. /api/v1/meta" }, "ui": { "type": "string", - "description": "e.g. /api/ui" + "description": "e.g. /api/v1/ui" }, "auth": { "type": "string", - "description": "e.g. /api/auth" + "description": "e.g. /api/v1/auth" }, "automation": { "type": "string", - "description": "e.g. /api/automation" + "description": "e.g. /api/v1/automation" }, "storage": { "type": "string", - "description": "e.g. /api/storage" + "description": "e.g. /api/v1/storage" }, "analytics": { "type": "string", - "description": "e.g. /api/analytics" + "description": "e.g. /api/v1/analytics" }, "hub": { "type": "string", - "description": "e.g. /api/hub" + "description": "e.g. /api/v1/hub" }, "graphql": { "type": "string", "description": "e.g. /graphql" + }, + "packages": { + "type": "string", + "description": "e.g. /api/v1/packages" + }, + "workflow": { + "type": "string", + "description": "e.g. /api/v1/workflow" + }, + "realtime": { + "type": "string", + "description": "e.g. /api/v1/realtime" + }, + "notifications": { + "type": "string", + "description": "e.g. /api/v1/notifications" + }, + "ai": { + "type": "string", + "description": "e.g. /api/v1/ai" + }, + "i18n": { + "type": "string", + "description": "e.g. /api/v1/i18n" } }, "required": [ diff --git a/packages/spec/json-schema/api/GetPackageResponse.json b/packages/spec/json-schema/api/GetPackageResponse.json index e01ec941c..ed2321f39 100644 --- a/packages/spec/json-schema/api/GetPackageResponse.json +++ b/packages/spec/json-schema/api/GetPackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/api/InstallPackageRequest.json b/packages/spec/json-schema/api/InstallPackageRequest.json index f59a63903..dd5703724 100644 --- a/packages/spec/json-schema/api/InstallPackageRequest.json +++ b/packages/spec/json-schema/api/InstallPackageRequest.json @@ -350,6 +350,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/api/InstallPackageResponse.json b/packages/spec/json-schema/api/InstallPackageResponse.json index 5ecbbce5d..543ffd95a 100644 --- a/packages/spec/json-schema/api/InstallPackageResponse.json +++ b/packages/spec/json-schema/api/InstallPackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/api/ListPackagesResponse.json b/packages/spec/json-schema/api/ListPackagesResponse.json index ef65e9e5b..bd7e8c8e6 100644 --- a/packages/spec/json-schema/api/ListPackagesResponse.json +++ b/packages/spec/json-schema/api/ListPackagesResponse.json @@ -355,6 +355,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/hub/ComposerResponse.json b/packages/spec/json-schema/hub/ComposerResponse.json index 8312bc5c6..148eba506 100644 --- a/packages/spec/json-schema/hub/ComposerResponse.json +++ b/packages/spec/json-schema/hub/ComposerResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/DisablePackageResponse.json b/packages/spec/json-schema/kernel/DisablePackageResponse.json index e1210367b..619d469a7 100644 --- a/packages/spec/json-schema/kernel/DisablePackageResponse.json +++ b/packages/spec/json-schema/kernel/DisablePackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/EnablePackageResponse.json b/packages/spec/json-schema/kernel/EnablePackageResponse.json index 2c0f74757..10c295192 100644 --- a/packages/spec/json-schema/kernel/EnablePackageResponse.json +++ b/packages/spec/json-schema/kernel/EnablePackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/GetPackageResponse.json b/packages/spec/json-schema/kernel/GetPackageResponse.json index e01ec941c..ed2321f39 100644 --- a/packages/spec/json-schema/kernel/GetPackageResponse.json +++ b/packages/spec/json-schema/kernel/GetPackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/InstallPackageRequest.json b/packages/spec/json-schema/kernel/InstallPackageRequest.json index f59a63903..dd5703724 100644 --- a/packages/spec/json-schema/kernel/InstallPackageRequest.json +++ b/packages/spec/json-schema/kernel/InstallPackageRequest.json @@ -350,6 +350,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/InstallPackageResponse.json b/packages/spec/json-schema/kernel/InstallPackageResponse.json index 5ecbbce5d..543ffd95a 100644 --- a/packages/spec/json-schema/kernel/InstallPackageResponse.json +++ b/packages/spec/json-schema/kernel/InstallPackageResponse.json @@ -353,6 +353,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/InstalledPackage.json b/packages/spec/json-schema/kernel/InstalledPackage.json index f12e13a71..aeba69477 100644 --- a/packages/spec/json-schema/kernel/InstalledPackage.json +++ b/packages/spec/json-schema/kernel/InstalledPackage.json @@ -350,6 +350,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/ListPackagesResponse.json b/packages/spec/json-schema/kernel/ListPackagesResponse.json index ef65e9e5b..bd7e8c8e6 100644 --- a/packages/spec/json-schema/kernel/ListPackagesResponse.json +++ b/packages/spec/json-schema/kernel/ListPackagesResponse.json @@ -355,6 +355,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/kernel/Manifest.json b/packages/spec/json-schema/kernel/Manifest.json index c9a922ebc..d1b64439a 100644 --- a/packages/spec/json-schema/kernel/Manifest.json +++ b/packages/spec/json-schema/kernel/Manifest.json @@ -347,6 +347,36 @@ "additionalProperties": false }, "description": "Query Function contributions" + }, + "routes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "pattern": "^\\/", + "description": "API path prefix" + }, + "service": { + "type": "string", + "description": "Service name this plugin provides" + }, + "methods": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Protocol method names implemented (e.g. [\"aiNlq\", \"aiChat\"])" + } + }, + "required": [ + "prefix", + "service" + ], + "additionalProperties": false + }, + "description": "API route contributions to HttpDispatcher" } }, "additionalProperties": false, diff --git a/packages/spec/json-schema/system/CoreServiceName.json b/packages/spec/json-schema/system/CoreServiceName.json index e61294170..8b46866f4 100644 --- a/packages/spec/json-schema/system/CoreServiceName.json +++ b/packages/spec/json-schema/system/CoreServiceName.json @@ -17,7 +17,11 @@ "hub", "realtime", "job", - "notification" + "notification", + "ai", + "i18n", + "ui", + "workflow" ] } }, diff --git a/packages/spec/json-schema/system/KernelServiceMap.json b/packages/spec/json-schema/system/KernelServiceMap.json index 2a8a6717a..27b879515 100644 --- a/packages/spec/json-schema/system/KernelServiceMap.json +++ b/packages/spec/json-schema/system/KernelServiceMap.json @@ -21,7 +21,11 @@ "hub", "realtime", "job", - "notification" + "notification", + "ai", + "i18n", + "ui", + "workflow" ] } } diff --git a/packages/spec/json-schema/system/ServiceConfig.json b/packages/spec/json-schema/system/ServiceConfig.json index f425cb9f2..c2e81bafb 100644 --- a/packages/spec/json-schema/system/ServiceConfig.json +++ b/packages/spec/json-schema/system/ServiceConfig.json @@ -23,7 +23,11 @@ "hub", "realtime", "job", - "notification" + "notification", + "ai", + "i18n", + "ui", + "workflow" ] }, "options": { diff --git a/packages/spec/json-schema/system/ServiceStatus.json b/packages/spec/json-schema/system/ServiceStatus.json index 2e30cfc76..ed6dc3988 100644 --- a/packages/spec/json-schema/system/ServiceStatus.json +++ b/packages/spec/json-schema/system/ServiceStatus.json @@ -20,7 +20,11 @@ "hub", "realtime", "job", - "notification" + "notification", + "ai", + "i18n", + "ui", + "workflow" ] }, "enabled": { diff --git a/packages/spec/src/ai/index.ts b/packages/spec/src/ai/index.ts index 8350c0044..5be304e2c 100644 --- a/packages/spec/src/ai/index.ts +++ b/packages/spec/src/ai/index.ts @@ -5,6 +5,7 @@ * - Agent Configuration * - DevOps Agent (Self-iterating Development) * - Model Registry & Selection + * - Model Context Protocol (MCP) * - RAG Pipeline * - Natural Language Query (NLQ) * - Workflow Automation @@ -21,6 +22,7 @@ export * from './devops-agent.zod'; export * from './plugin-development.zod'; export * from './runtime-ops.zod'; export * from './model-registry.zod'; +export * from './mcp.zod'; export * from './rag-pipeline.zod'; export * from './nlq.zod'; export * from './orchestration.zod'; diff --git a/packages/spec/src/ai/mcp.test.ts b/packages/spec/src/ai/mcp.test.ts new file mode 100644 index 000000000..4a73e3124 --- /dev/null +++ b/packages/spec/src/ai/mcp.test.ts @@ -0,0 +1,594 @@ +import { describe, it, expect } from 'vitest'; +import { + MCPServerConfigSchema, + MCPToolSchema, + MCPResourceSchema, + MCPPromptSchema, + MCPTransportConfigSchema, + MCPServerInfoSchema, + MCPToolCallRequestSchema, + MCPToolCallResponseSchema, + MCPResourceRequestSchema, + MCPPromptRequestSchema, + type MCPServerConfig, + type MCPTool, + type MCPResource, +} from './mcp.zod'; + +describe('MCPTransportConfigSchema', () => { + it('should accept stdio transport', () => { + const transport = { + type: 'stdio' as const, + command: 'node', + args: ['mcp-server.js'], + }; + + const result = MCPTransportConfigSchema.parse(transport); + expect(result.type).toBe('stdio'); + expect(result.timeout).toBe(30000); + expect(result.retryAttempts).toBe(3); + }); + + it('should accept HTTP transport with auth', () => { + const transport = { + type: 'http' as const, + url: 'https://api.example.com/mcp', + auth: { + type: 'bearer' as const, + token: 'secret-token', + }, + headers: { + 'X-Custom-Header': 'value', + }, + }; + + expect(() => MCPTransportConfigSchema.parse(transport)).not.toThrow(); + }); + + it('should accept websocket transport', () => { + const transport = { + type: 'websocket' as const, + url: 'wss://api.example.com/mcp', + timeout: 60000, + }; + + expect(() => MCPTransportConfigSchema.parse(transport)).not.toThrow(); + }); + + it('should enforce URL for HTTP/WebSocket transport', () => { + const transport = { + type: 'http' as const, + url: 'https://api.example.com/mcp', + }; + + expect(() => MCPTransportConfigSchema.parse(transport)).not.toThrow(); + }); +}); + +describe('MCPResourceSchema', () => { + it('should accept minimal resource', () => { + const resource = { + uri: 'objectstack://objects/account', + name: 'Account List', + }; + + const result = MCPResourceSchema.parse(resource); + expect(result.resourceType).toBe('json'); + expect(result.cacheable).toBe(true); + }); + + it('should accept full resource definition', () => { + const resource = { + uri: 'objectstack://objects/account/ABC123', + name: 'Account ABC123', + description: 'Details for account ABC123', + mimeType: 'application/json', + resourceType: 'json' as const, + content: { + id: 'ABC123', + name: 'Acme Corp', + }, + size: 256, + lastModified: '2024-01-01T00:00:00Z', + tags: ['account', 'customer'], + permissions: { + read: true, + write: false, + delete: false, + }, + cacheable: true, + cacheMaxAge: 300, + }; + + expect(() => MCPResourceSchema.parse(resource)).not.toThrow(); + }); + + it('should accept all resource types', () => { + const types = ['text', 'json', 'binary', 'stream'] as const; + + types.forEach(resourceType => { + const resource = { + uri: `test://resource/${resourceType}`, + name: `Test ${resourceType}`, + resourceType, + }; + expect(() => MCPResourceSchema.parse(resource)).not.toThrow(); + }); + }); +}); + +describe('MCPToolSchema', () => { + it('should accept minimal tool', () => { + const tool = { + name: 'create_account', + description: 'Creates a new account in the system', + parameters: [], + handler: 'flows.create_account', + }; + + const result = MCPToolSchema.parse(tool); + expect(result.async).toBe(true); + expect(result.sideEffects).toBe('read'); + expect(result.requiresConfirmation).toBe(false); + expect(result.deprecated).toBe(false); + expect(result.version).toBe('1.0.0'); + }); + + it('should accept tool with parameters', () => { + const tool = { + name: 'search_records', + description: 'Search for records in an object', + parameters: [ + { + name: 'object_name', + type: 'string' as const, + description: 'Name of the object to search', + required: true, + }, + { + name: 'query', + type: 'string' as const, + description: 'Search query', + required: true, + minLength: 1, + maxLength: 500, + }, + { + name: 'limit', + type: 'number' as const, + description: 'Maximum number of results', + required: false, + default: 10, + minimum: 1, + maximum: 100, + }, + ], + handler: 'data.search', + sideEffects: 'read' as const, + }; + + expect(() => MCPToolSchema.parse(tool)).not.toThrow(); + }); + + it('should accept tool with return type', () => { + const tool = { + name: 'get_total_count', + description: 'Get total count of records', + parameters: [ + { + name: 'object_name', + type: 'string' as const, + description: 'Object name', + required: true, + }, + ], + returns: { + type: 'number' as const, + description: 'Total count of records', + }, + handler: 'data.count', + }; + + expect(() => MCPToolSchema.parse(tool)).not.toThrow(); + }); + + it('should accept tool with examples', () => { + const tool = { + name: 'create_task', + description: 'Create a new task', + parameters: [ + { + name: 'title', + type: 'string' as const, + description: 'Task title', + required: true, + }, + { + name: 'priority', + type: 'string' as const, + description: 'Task priority', + required: false, + enum: ['low', 'medium', 'high'], + default: 'medium', + }, + ], + handler: 'flows.create_task', + sideEffects: 'write' as const, + requiresConfirmation: true, + examples: [ + { + description: 'Create a high priority task', + parameters: { + title: 'Fix critical bug', + priority: 'high', + }, + result: { id: 'TASK-001', status: 'created' }, + }, + ], + }; + + expect(() => MCPToolSchema.parse(tool)).not.toThrow(); + }); + + it('should enforce snake_case naming', () => { + expect(() => MCPToolSchema.parse({ + name: 'CreateAccount', + description: 'Test', + parameters: [], + handler: 'test', + })).toThrow(); + + expect(() => MCPToolSchema.parse({ + name: 'create-account', + description: 'Test', + parameters: [], + handler: 'test', + })).toThrow(); + + expect(() => MCPToolSchema.parse({ + name: 'create_account', + description: 'Test', + parameters: [], + handler: 'test', + })).not.toThrow(); + }); + + it('should accept all side effect types', () => { + const sideEffects = ['none', 'read', 'write', 'delete'] as const; + + sideEffects.forEach(effect => { + const tool = { + name: 'test_tool', + description: 'Test tool', + parameters: [], + handler: 'test', + sideEffects: effect, + }; + expect(() => MCPToolSchema.parse(tool)).not.toThrow(); + }); + }); +}); + +describe('MCPPromptSchema', () => { + it('should accept minimal prompt', () => { + const prompt = { + name: 'summarize_ticket', + messages: [ + { + role: 'system' as const, + content: 'You are a helpful assistant that summarizes support tickets.', + }, + { + role: 'user' as const, + content: 'Please summarize this ticket: {{ticket_content}}', + }, + ], + }; + + const result = MCPPromptSchema.parse(prompt); + expect(result.version).toBe('1.0.0'); + }); + + it('should accept prompt with arguments', () => { + const prompt = { + name: 'generate_report', + description: 'Generate a report based on data', + messages: [ + { + role: 'system' as const, + content: 'You are a report generator.', + }, + { + role: 'user' as const, + content: 'Generate a {{report_type}} report for {{time_period}}', + }, + ], + arguments: [ + { + name: 'report_type', + type: 'string' as const, + required: true, + description: 'Type of report to generate', + }, + { + name: 'time_period', + type: 'string' as const, + required: true, + description: 'Time period for the report', + }, + ], + }; + + expect(() => MCPPromptSchema.parse(prompt)).not.toThrow(); + }); + + it('should enforce snake_case naming', () => { + expect(() => MCPPromptSchema.parse({ + name: 'GenerateReport', + messages: [{ role: 'user', content: 'test' }], + })).toThrow(); + + expect(() => MCPPromptSchema.parse({ + name: 'generate_report', + messages: [{ role: 'user', content: 'test' }], + })).not.toThrow(); + }); +}); + +describe('MCPServerInfoSchema', () => { + it('should accept minimal server info', () => { + const info = { + name: 'ObjectStack MCP Server', + version: '1.0.0', + capabilities: { + resources: true, + tools: true, + }, + }; + + const result = MCPServerInfoSchema.parse(info); + expect(result.protocolVersion).toBe('2024-11-05'); + }); + + it('should accept full server info', () => { + const info = { + name: 'ObjectStack MCP Server', + version: '1.2.3', + description: 'MCP server for ObjectStack integration', + capabilities: { + resources: true, + resourceTemplates: true, + tools: true, + prompts: true, + sampling: false, + logging: true, + }, + protocolVersion: '2024-11-05', + vendor: 'ObjectStack AI', + homepage: 'https://objectstack.ai', + documentation: 'https://docs.objectstack.ai/mcp', + }; + + expect(() => MCPServerInfoSchema.parse(info)).not.toThrow(); + }); +}); + +describe('MCPServerConfigSchema', () => { + it('should accept minimal server config', () => { + const config = { + name: 'objectstack_mcp', + label: 'ObjectStack MCP Server', + serverInfo: { + name: 'ObjectStack MCP', + version: '1.0.0', + capabilities: { + resources: true, + tools: true, + }, + }, + transport: { + type: 'stdio' as const, + command: 'node', + args: ['server.js'], + }, + }; + + const result = MCPServerConfigSchema.parse(config); + expect(result.autoStart).toBe(false); + expect(result.restartOnFailure).toBe(true); + expect(result.status).toBe('active'); + expect(result.version).toBe('1.0.0'); + }); + + it('should accept full server config', () => { + const config: MCPServerConfig = { + name: 'objectstack_mcp', + label: 'ObjectStack MCP Server', + description: 'MCP server exposing ObjectStack data and tools', + serverInfo: { + name: 'ObjectStack MCP', + version: '2.0.0', + description: 'Full-featured MCP server', + capabilities: { + resources: true, + resourceTemplates: true, + tools: true, + prompts: true, + sampling: true, + logging: true, + }, + vendor: 'ObjectStack AI', + }, + transport: { + type: 'http' as const, + url: 'https://mcp.objectstack.ai', + auth: { + type: 'bearer', + secretRef: 'system:mcp_api_key', + }, + timeout: 45000, + }, + resources: [ + { + uri: 'objectstack://metadata/objects', + name: 'Object Definitions', + description: 'List of all object definitions', + resourceType: 'json', + }, + ], + tools: [ + { + name: 'search_records', + description: 'Search for records', + parameters: [ + { + name: 'object', + type: 'string', + description: 'Object name', + required: true, + }, + ], + handler: 'data.search', + }, + ], + prompts: [ + { + name: 'analyze_data', + messages: [ + { + role: 'system', + content: 'You are a data analyst.', + }, + { + role: 'user', + content: 'Analyze this data: {{data}}', + }, + ], + }, + ], + autoStart: true, + restartOnFailure: true, + healthCheck: { + enabled: true, + interval: 30000, + timeout: 5000, + }, + permissions: { + allowedAgents: ['support_agent', 'data_analyst'], + requireAuth: true, + }, + rateLimit: { + enabled: true, + requestsPerMinute: 100, + requestsPerHour: 5000, + }, + tags: ['production', 'data'], + status: 'active', + version: '2.0.0', + }; + + expect(() => MCPServerConfigSchema.parse(config)).not.toThrow(); + }); +}); + +describe('MCPToolCallRequestSchema', () => { + it('should accept minimal tool call request', () => { + const request = { + toolName: 'search_records', + parameters: { + object: 'account', + query: 'name contains "Acme"', + }, + }; + + expect(() => MCPToolCallRequestSchema.parse(request)).not.toThrow(); + }); + + it('should accept tool call with context', () => { + const request = { + toolName: 'create_record', + parameters: { + object: 'task', + data: { title: 'New task' }, + }, + confirmationProvided: true, + context: { + userId: 'user123', + sessionId: 'session456', + agentName: 'support_agent', + metadata: { + source: 'chat', + }, + }, + }; + + expect(() => MCPToolCallRequestSchema.parse(request)).not.toThrow(); + }); +}); + +describe('MCPToolCallResponseSchema', () => { + it('should accept success response', () => { + const response = { + toolName: 'search_records', + status: 'success' as const, + result: [ + { id: '1', name: 'Record 1' }, + { id: '2', name: 'Record 2' }, + ], + executionTime: 125, + timestamp: '2024-01-01T00:00:00Z', + }; + + expect(() => MCPToolCallResponseSchema.parse(response)).not.toThrow(); + }); + + it('should accept error response', () => { + const response = { + toolName: 'create_record', + status: 'error' as const, + error: { + code: 'VALIDATION_ERROR', + message: 'Required field "title" is missing', + details: { field: 'title' }, + }, + executionTime: 50, + }; + + expect(() => MCPToolCallResponseSchema.parse(response)).not.toThrow(); + }); +}); + +describe('MCPResourceRequestSchema', () => { + it('should accept resource request', () => { + const request = { + uri: 'objectstack://objects/account/ABC123', + }; + + expect(() => MCPResourceRequestSchema.parse(request)).not.toThrow(); + }); + + it('should accept resource request with parameters', () => { + const request = { + uri: 'objectstack://objects/{objectName}/{recordId}', + parameters: { + objectName: 'account', + recordId: 'ABC123', + }, + }; + + expect(() => MCPResourceRequestSchema.parse(request)).not.toThrow(); + }); +}); + +describe('MCPPromptRequestSchema', () => { + it('should accept prompt request', () => { + const request = { + promptName: 'summarize_ticket', + arguments: { + ticket_content: 'User reports an issue with login', + }, + }; + + expect(() => MCPPromptRequestSchema.parse(request)).not.toThrow(); + }); +}); diff --git a/packages/spec/src/ai/mcp.zod.ts b/packages/spec/src/ai/mcp.zod.ts new file mode 100644 index 000000000..4036de354 --- /dev/null +++ b/packages/spec/src/ai/mcp.zod.ts @@ -0,0 +1,502 @@ +import { z } from 'zod'; + +/** + * Model Context Protocol (MCP) + * + * Defines the protocol for connecting AI assistants to external tools, data sources, + * and resources. MCP enables AI models to access contextual information, invoke + * functions, and interact with external systems in a standardized way. + * + * Architecture Alignment: + * - Anthropic Model Context Protocol (MCP) + * - OpenAI Function Calling / Tools + * - LangChain Tool Interface + * - Microsoft Semantic Kernel Plugins + * + * Use Cases: + * - Connect AI agents to ObjectStack data (Objects, Views, Reports) + * - Expose business logic as callable tools (Workflows, Flows, Actions) + * - Provide dynamic context to AI models (User profile, Recent activity) + * - Enable AI to read and modify data through standardized interfaces + */ + +// ========================================== +// MCP Transport Configuration +// ========================================== + +/** + * MCP Transport Type + * Defines how the MCP server communicates + */ +export const MCPTransportTypeSchema = z.enum([ + 'stdio', // Standard input/output (for local processes) + 'http', // HTTP REST API + 'websocket', // WebSocket bidirectional communication + 'grpc', // gRPC for high-performance communication +]); + +/** + * MCP Transport Configuration + */ +export const MCPTransportConfigSchema = z.object({ + type: MCPTransportTypeSchema, + + /** HTTP/WebSocket Configuration */ + url: z.string().url().optional().describe('Server URL (for HTTP/WebSocket/gRPC)'), + headers: z.record(z.string(), z.string()).optional().describe('Custom headers for requests'), + + /** Authentication */ + auth: z.object({ + type: z.enum(['none', 'bearer', 'api_key', 'oauth2', 'custom']).default('none'), + token: z.string().optional().describe('Bearer token or API key'), + secretRef: z.string().optional().describe('Reference to stored secret'), + headerName: z.string().optional().describe('Custom auth header name'), + }).optional(), + + /** Connection Options */ + timeout: z.number().int().positive().optional().default(30000).describe('Request timeout in milliseconds'), + retryAttempts: z.number().int().min(0).max(5).optional().default(3), + retryDelay: z.number().int().positive().optional().default(1000).describe('Delay between retries in milliseconds'), + + /** STDIO Configuration */ + command: z.string().optional().describe('Command to execute (for stdio transport)'), + args: z.array(z.string()).optional().describe('Command arguments'), + env: z.record(z.string(), z.string()).optional().describe('Environment variables'), + workingDirectory: z.string().optional().describe('Working directory for the process'), +}); + +// ========================================== +// MCP Resource Protocol +// ========================================== + +/** + * MCP Resource Type + * Types of resources that can be exposed through MCP + */ +export const MCPResourceTypeSchema = z.enum([ + 'text', // Plain text or markdown content + 'json', // Structured JSON data + 'binary', // Binary data (files, images, etc.) + 'stream', // Streaming data +]); + +/** + * MCP Resource Schema + * Represents a piece of contextual information available to the AI + */ +export const MCPResourceSchema = z.object({ + /** Identity */ + uri: z.string().describe('Unique resource identifier (e.g., "objectstack://objects/account/ABC123")'), + name: z.string().describe('Human-readable resource name'), + description: z.string().optional().describe('Resource description for AI consumption'), + + /** Resource Type */ + mimeType: z.string().optional().describe('MIME type (e.g., "application/json", "text/plain")'), + resourceType: MCPResourceTypeSchema.default('json'), + + /** Content */ + content: z.unknown().optional().describe('Resource content (for static resources)'), + contentUrl: z.string().url().optional().describe('URL to fetch content dynamically'), + + /** Metadata */ + size: z.number().int().nonnegative().optional().describe('Resource size in bytes'), + lastModified: z.string().datetime().optional().describe('Last modification timestamp (ISO 8601)'), + tags: z.array(z.string()).optional().describe('Tags for resource categorization'), + + /** Access Control */ + permissions: z.object({ + read: z.boolean().default(true), + write: z.boolean().default(false), + delete: z.boolean().default(false), + }).optional(), + + /** Caching */ + cacheable: z.boolean().default(true).describe('Whether this resource can be cached'), + cacheMaxAge: z.number().int().nonnegative().optional().describe('Cache max age in seconds'), +}); + +/** + * MCP Resource Template + * Dynamic resource generation pattern + */ +export const MCPResourceTemplateSchema = z.object({ + uriPattern: z.string().describe('URI pattern with variables (e.g., "objectstack://objects/{objectName}/{recordId}")'), + name: z.string().describe('Template name'), + description: z.string().optional(), + + /** Parameters */ + parameters: z.array(z.object({ + name: z.string().describe('Parameter name'), + type: z.enum(['string', 'number', 'boolean']).default('string'), + required: z.boolean().default(true), + description: z.string().optional(), + pattern: z.string().optional().describe('Regex validation pattern'), + default: z.unknown().optional(), + })).describe('URI parameters'), + + /** Generation Logic */ + handler: z.string().optional().describe('Handler function name for dynamic generation'), + + mimeType: z.string().optional(), + resourceType: MCPResourceTypeSchema.default('json'), +}); + +// ========================================== +// MCP Tool Protocol +// ========================================== + +/** + * MCP Tool Parameter Schema + * Defines parameters for MCP tool functions + */ +export const MCPToolParameterSchema: z.ZodType = z.object({ + name: z.string().describe('Parameter name'), + type: z.enum(['string', 'number', 'boolean', 'object', 'array']), + description: z.string().describe('Parameter description for AI consumption'), + required: z.boolean().default(false), + default: z.unknown().optional(), + + /** Validation */ + enum: z.array(z.unknown()).optional().describe('Allowed values'), + pattern: z.string().optional().describe('Regex validation pattern (for strings)'), + minimum: z.number().optional().describe('Minimum value (for numbers)'), + maximum: z.number().optional().describe('Maximum value (for numbers)'), + minLength: z.number().int().nonnegative().optional().describe('Minimum length (for strings/arrays)'), + maxLength: z.number().int().nonnegative().optional().describe('Maximum length (for strings/arrays)'), + + /** Nested Schema */ + properties: z.record(z.string(), z.lazy(() => MCPToolParameterSchema)).optional().describe('Properties for object types'), + items: z.lazy(() => MCPToolParameterSchema).optional().describe('Item schema for array types'), +}); + +/** + * MCP Tool Parameter Type (inferred before schema to avoid circular reference) + */ +export type MCPToolParameter = { + name: string; + type: 'string' | 'number' | 'boolean' | 'object' | 'array'; + description: string; + required?: boolean; + default?: unknown; + enum?: unknown[]; + pattern?: string; + minimum?: number; + maximum?: number; + minLength?: number; + maxLength?: number; + properties?: Record; + items?: MCPToolParameter; +}; + +/** + * MCP Tool Schema + * Represents a callable function or action available to the AI + */ +export const MCPToolSchema = z.object({ + /** Identity */ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Tool function name (snake_case)'), + description: z.string().describe('Tool description for AI consumption (be detailed and specific)'), + + /** Parameters */ + parameters: z.array(MCPToolParameterSchema).describe('Tool parameters'), + + /** Return Type */ + returns: z.object({ + type: z.enum(['string', 'number', 'boolean', 'object', 'array', 'void']), + description: z.string().optional(), + schema: MCPToolParameterSchema.optional().describe('Return value schema'), + }).optional(), + + /** Execution Configuration */ + handler: z.string().describe('Handler function or endpoint reference'), + async: z.boolean().default(true).describe('Whether the tool executes asynchronously'), + timeout: z.number().int().positive().optional().describe('Execution timeout in milliseconds'), + + /** Side Effects */ + sideEffects: z.enum(['none', 'read', 'write', 'delete']).default('read').describe('Tool side effects'), + requiresConfirmation: z.boolean().default(false).describe('Require user confirmation before execution'), + confirmationMessage: z.string().optional(), + + /** Examples */ + examples: z.array(z.object({ + description: z.string(), + parameters: z.record(z.string(), z.unknown()), + result: z.unknown().optional(), + })).optional().describe('Usage examples for AI learning'), + + /** Metadata */ + category: z.string().optional().describe('Tool category (e.g., "data", "workflow", "analytics")'), + tags: z.array(z.string()).optional(), + deprecated: z.boolean().default(false), + version: z.string().optional().default('1.0.0'), +}); + +// ========================================== +// MCP Prompt Protocol +// ========================================== + +/** + * MCP Prompt Argument + * Dynamic arguments for prompt templates + */ +export const MCPPromptArgumentSchema = z.object({ + name: z.string().describe('Argument name'), + description: z.string().optional(), + type: z.enum(['string', 'number', 'boolean']).default('string'), + required: z.boolean().default(false), + default: z.unknown().optional(), +}); + +/** + * MCP Prompt Message + * Individual message in a prompt template + */ +export const MCPPromptMessageSchema = z.object({ + role: z.enum(['system', 'user', 'assistant']).describe('Message role'), + content: z.string().describe('Message content (can include {{variable}} placeholders)'), +}); + +/** + * MCP Prompt Schema + * Predefined prompt templates available to the AI + */ +export const MCPPromptSchema = z.object({ + /** Identity */ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Prompt template name (snake_case)'), + description: z.string().optional().describe('Prompt description'), + + /** Template */ + messages: z.array(MCPPromptMessageSchema).describe('Prompt message sequence'), + + /** Arguments */ + arguments: z.array(MCPPromptArgumentSchema).optional().describe('Dynamic arguments for the prompt'), + + /** Metadata */ + category: z.string().optional(), + tags: z.array(z.string()).optional(), + version: z.string().optional().default('1.0.0'), +}); + +// ========================================== +// MCP Server Configuration +// ========================================== + +/** + * MCP Capability + * Features supported by the MCP server + */ +export const MCPCapabilitySchema = z.object({ + resources: z.boolean().default(false).describe('Supports resource listing and retrieval'), + resourceTemplates: z.boolean().default(false).describe('Supports dynamic resource templates'), + tools: z.boolean().default(false).describe('Supports tool/function calling'), + prompts: z.boolean().default(false).describe('Supports prompt templates'), + sampling: z.boolean().default(false).describe('Supports sampling from LLMs'), + logging: z.boolean().default(false).describe('Supports logging and debugging'), +}); + +/** + * MCP Server Info + * Server metadata and capabilities + */ +export const MCPServerInfoSchema = z.object({ + name: z.string().describe('Server name'), + version: z.string().describe('Server version (semver)'), + description: z.string().optional(), + capabilities: MCPCapabilitySchema, + + /** Protocol Version */ + protocolVersion: z.string().default('2024-11-05').describe('MCP protocol version'), + + /** Metadata */ + vendor: z.string().optional().describe('Server vendor/provider'), + homepage: z.string().url().optional().describe('Server homepage URL'), + documentation: z.string().url().optional().describe('Documentation URL'), +}); + +/** + * MCP Server Configuration + * Complete MCP server definition + */ +export const MCPServerConfigSchema = z.object({ + /** Identity */ + name: z.string().regex(/^[a-z_][a-z0-9_]*$/).describe('Server unique identifier (snake_case)'), + label: z.string().describe('Display name'), + description: z.string().optional(), + + /** Server Info */ + serverInfo: MCPServerInfoSchema, + + /** Transport */ + transport: MCPTransportConfigSchema, + + /** Resources */ + resources: z.array(MCPResourceSchema).optional().describe('Static resources'), + resourceTemplates: z.array(MCPResourceTemplateSchema).optional().describe('Dynamic resource templates'), + + /** Tools */ + tools: z.array(MCPToolSchema).optional().describe('Available tools'), + + /** Prompts */ + prompts: z.array(MCPPromptSchema).optional().describe('Prompt templates'), + + /** Lifecycle */ + autoStart: z.boolean().default(false).describe('Auto-start server on system boot'), + restartOnFailure: z.boolean().default(true).describe('Auto-restart on failure'), + healthCheck: z.object({ + enabled: z.boolean().default(true), + interval: z.number().int().positive().default(60000).describe('Health check interval in milliseconds'), + timeout: z.number().int().positive().default(5000).describe('Health check timeout in milliseconds'), + endpoint: z.string().optional().describe('Health check endpoint (for HTTP servers)'), + }).optional(), + + /** Access Control */ + permissions: z.object({ + allowedAgents: z.array(z.string()).optional().describe('Agent names allowed to use this server'), + allowedUsers: z.array(z.string()).optional().describe('User IDs allowed to use this server'), + requireAuth: z.boolean().default(true), + }).optional(), + + /** Rate Limiting */ + rateLimit: z.object({ + enabled: z.boolean().default(false), + requestsPerMinute: z.number().int().positive().optional(), + requestsPerHour: z.number().int().positive().optional(), + burstSize: z.number().int().positive().optional(), + }).optional(), + + /** Metadata */ + tags: z.array(z.string()).optional(), + status: z.enum(['active', 'inactive', 'maintenance', 'deprecated']).default('active'), + version: z.string().optional().default('1.0.0'), + createdAt: z.string().datetime().optional(), + updatedAt: z.string().datetime().optional(), +}); + +// ========================================== +// MCP Request/Response Schemas +// ========================================== + +/** + * MCP Resource Request + */ +export const MCPResourceRequestSchema = z.object({ + uri: z.string().describe('Resource URI to fetch'), + parameters: z.record(z.string(), z.unknown()).optional().describe('URI template parameters'), +}); + +/** + * MCP Resource Response + */ +export const MCPResourceResponseSchema = z.object({ + resource: MCPResourceSchema, + content: z.unknown().describe('Resource content'), +}); + +/** + * MCP Tool Call Request + */ +export const MCPToolCallRequestSchema = z.object({ + toolName: z.string().describe('Tool to invoke'), + parameters: z.record(z.string(), z.unknown()).describe('Tool parameters'), + + /** Execution Options */ + timeout: z.number().int().positive().optional(), + confirmationProvided: z.boolean().optional().describe('User confirmation for tools that require it'), + + /** Context */ + context: z.object({ + userId: z.string().optional(), + sessionId: z.string().optional(), + agentName: z.string().optional(), + metadata: z.record(z.string(), z.unknown()).optional(), + }).optional(), +}); + +/** + * MCP Tool Call Response + */ +export const MCPToolCallResponseSchema = z.object({ + toolName: z.string(), + status: z.enum(['success', 'error', 'timeout', 'cancelled']), + + /** Result */ + result: z.unknown().optional().describe('Tool execution result'), + + /** Error */ + error: z.object({ + code: z.string(), + message: z.string(), + details: z.unknown().optional(), + }).optional(), + + /** Metrics */ + executionTime: z.number().nonnegative().optional().describe('Execution time in milliseconds'), + timestamp: z.string().datetime().optional(), +}); + +/** + * MCP Prompt Request + */ +export const MCPPromptRequestSchema = z.object({ + promptName: z.string().describe('Prompt template to use'), + arguments: z.record(z.string(), z.unknown()).optional().describe('Prompt arguments'), +}); + +/** + * MCP Prompt Response + */ +export const MCPPromptResponseSchema = z.object({ + promptName: z.string(), + messages: z.array(MCPPromptMessageSchema).describe('Rendered prompt messages'), +}); + +// ========================================== +// MCP Client Configuration +// ========================================== + +/** + * MCP Client Configuration + * Configuration for AI clients connecting to MCP servers + */ +export const MCPClientConfigSchema = z.object({ + /** Server Connection */ + servers: z.array(MCPServerConfigSchema).describe('MCP servers to connect to'), + + /** Client Settings */ + defaultTimeout: z.number().int().positive().default(30000).describe('Default timeout for requests'), + enableCaching: z.boolean().default(true).describe('Enable client-side caching'), + cacheMaxAge: z.number().int().nonnegative().default(300).describe('Cache max age in seconds'), + + /** Retry Logic */ + retryAttempts: z.number().int().min(0).max(5).default(3), + retryDelay: z.number().int().positive().default(1000), + + /** Logging */ + enableLogging: z.boolean().default(true), + logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'), +}); + +// ========================================== +// Type Exports +// ========================================== + +export type MCPTransportType = z.infer; +export type MCPTransportConfig = z.infer; +export type MCPResourceType = z.infer; +export type MCPResource = z.infer; +export type MCPResourceTemplate = z.infer; +// MCPToolParameter type is exported above with the schema +export type MCPTool = z.infer; +export type MCPPromptArgument = z.infer; +export type MCPPromptMessage = z.infer; +export type MCPPrompt = z.infer; +export type MCPCapability = z.infer; +export type MCPServerInfo = z.infer; +export type MCPServerConfig = z.infer; +export type MCPResourceRequest = z.infer; +export type MCPResourceResponse = z.infer; +export type MCPToolCallRequest = z.infer; +export type MCPToolCallResponse = z.infer; +export type MCPPromptRequest = z.infer; +export type MCPPromptResponse = z.infer; +export type MCPClientConfig = z.infer;