2026-01-26 20:57:41 +00:00
|
|
|
# Core MCP Package
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
Model Context Protocol (MCP) tools and analytics for AI-powered automation and integrations.
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
## Installation
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
composer require host-uk/core-mcp
|
|
|
|
|
```
|
2026-01-26 20:49:02 +00:00
|
|
|
|
|
|
|
|
## Features
|
|
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
### MCP Tool Registry
|
|
|
|
|
Extensible tool system for AI integrations:
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
```php
|
|
|
|
|
use Core\Mcp\Tools\BaseTool;
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
class GetProductsTool extends BaseTool
|
|
|
|
|
{
|
|
|
|
|
public function name(): string
|
|
|
|
|
{
|
|
|
|
|
return 'get_products';
|
|
|
|
|
}
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
public function description(): string
|
|
|
|
|
{
|
|
|
|
|
return 'Retrieve a list of products from the workspace';
|
|
|
|
|
}
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
public function schema(JsonSchema $schema): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'limit' => $schema->integer('Maximum number of products to return'),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function handle(Request $request): Response
|
|
|
|
|
{
|
|
|
|
|
$products = Product::take($request->input('limit', 10))->get();
|
|
|
|
|
return Response::text(json_encode($products));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
### Workspace Context Security
|
|
|
|
|
Prevents cross-tenant data leakage:
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
```php
|
|
|
|
|
use Core\Mcp\Tools\Concerns\RequiresWorkspaceContext;
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
class MyTool extends BaseTool
|
|
|
|
|
{
|
|
|
|
|
use RequiresWorkspaceContext;
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
// Automatically validates workspace context
|
|
|
|
|
// Throws exception if context is missing
|
|
|
|
|
}
|
2026-01-26 20:49:02 +00:00
|
|
|
```
|
|
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
### SQL Query Validation
|
|
|
|
|
Multi-layer protection for database queries:
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
```php
|
|
|
|
|
use Core\Mcp\Services\SqlQueryValidator;
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
$validator = new SqlQueryValidator();
|
|
|
|
|
$validator->validate($query); // Throws if unsafe
|
|
|
|
|
|
|
|
|
|
// Features:
|
|
|
|
|
// - Blocked keywords (INSERT, UPDATE, DELETE, DROP)
|
|
|
|
|
// - Pattern detection (stacked queries, hex encoding)
|
|
|
|
|
// - Whitelist matching
|
|
|
|
|
// - Comment stripping
|
2026-01-26 20:49:02 +00:00
|
|
|
```
|
|
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
### Tool Analytics
|
|
|
|
|
Track tool usage and performance:
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
```php
|
|
|
|
|
use Core\Mcp\Services\ToolAnalyticsService;
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
$analytics = app(ToolAnalyticsService::class);
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
$stats = $analytics->getToolStats('get_products');
|
|
|
|
|
// Returns: calls, avg_duration, error_rate, etc.
|
|
|
|
|
```
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
**Admin dashboard:** `/admin/mcp/analytics`
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
### Tool Dependencies
|
|
|
|
|
Declare tool dependencies and validate at runtime:
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
```php
|
|
|
|
|
use Core\Mcp\Dependencies\{HasDependencies, ToolDependency};
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
class AdvancedTool extends BaseTool implements HasDependencies
|
2026-01-26 20:49:02 +00:00
|
|
|
{
|
2026-01-26 20:57:41 +00:00
|
|
|
public function dependencies(): array
|
2026-01-26 20:49:02 +00:00
|
|
|
{
|
2026-01-26 20:57:41 +00:00
|
|
|
return [
|
|
|
|
|
new ToolDependency('get_products', DependencyType::REQUIRED),
|
|
|
|
|
new ToolDependency('send_email', DependencyType::OPTIONAL),
|
|
|
|
|
];
|
2026-01-26 20:49:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
### MCP Playground
|
|
|
|
|
Interactive UI for testing tools:
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
**Route:** `/admin/mcp/playground`
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
**Features:**
|
|
|
|
|
- Tool browser with search
|
|
|
|
|
- Dynamic form generation
|
|
|
|
|
- JSON response viewer
|
|
|
|
|
- Conversation history
|
|
|
|
|
- Example pre-fill
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
### Query EXPLAIN Analysis
|
|
|
|
|
Performance insights for database queries:
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"query": "SELECT * FROM users WHERE email = ?",
|
|
|
|
|
"explain": true
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
- Raw EXPLAIN output
|
|
|
|
|
- Performance warnings
|
|
|
|
|
- Index usage analysis
|
|
|
|
|
- Optimization recommendations
|
|
|
|
|
|
|
|
|
|
### Usage Quotas
|
|
|
|
|
Workspace-level rate limiting:
|
|
|
|
|
|
|
|
|
|
```php
|
|
|
|
|
use Core\Mcp\Services\McpQuotaService;
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
$quota = app(McpQuotaService::class);
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
// Check if workspace can execute tool
|
|
|
|
|
if (!$quota->canExecute($workspace, 'expensive_tool')) {
|
|
|
|
|
throw new QuotaExceededException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Record execution
|
|
|
|
|
$quota->recordExecution($workspace, 'expensive_tool');
|
2026-01-26 20:49:02 +00:00
|
|
|
```
|
|
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
## Configuration
|
|
|
|
|
|
|
|
|
|
```php
|
|
|
|
|
// config/mcp.php
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'database' => [
|
|
|
|
|
'connection' => 'readonly', // Dedicated read-only connection
|
|
|
|
|
'use_whitelist' => true,
|
|
|
|
|
'blocked_tables' => ['users', 'api_keys'],
|
|
|
|
|
],
|
|
|
|
|
'analytics' => [
|
|
|
|
|
'enabled' => true,
|
|
|
|
|
'retention_days' => 90,
|
|
|
|
|
],
|
|
|
|
|
'quota' => [
|
|
|
|
|
'enabled' => true,
|
|
|
|
|
'default_limit' => 1000, // Per workspace per day
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Security
|
|
|
|
|
|
|
|
|
|
### Query Security (Defense in Depth)
|
|
|
|
|
1. **Read-only database user** (infrastructure)
|
|
|
|
|
2. **Blocked keywords** (application)
|
|
|
|
|
3. **Pattern validation** (application)
|
|
|
|
|
4. **Whitelist matching** (application)
|
|
|
|
|
5. **Table access controls** (application)
|
|
|
|
|
|
|
|
|
|
### Workspace Isolation
|
|
|
|
|
- Context MUST come from authentication
|
|
|
|
|
- Cross-tenant access prevented by design
|
|
|
|
|
- Tools throw exceptions without context
|
|
|
|
|
|
|
|
|
|
See [changelog/2026/jan/security.md](changelog/2026/jan/security.md) for security updates.
|
|
|
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
|
|
|
|
- PHP 8.2+
|
|
|
|
|
- Laravel 11+ or 12+
|
|
|
|
|
|
|
|
|
|
## Changelog
|
2026-01-26 20:49:02 +00:00
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
See [changelog/2026/jan/features.md](changelog/2026/jan/features.md) for recent changes.
|
2026-01-26 20:49:02 +00:00
|
|
|
|
|
|
|
|
## License
|
|
|
|
|
|
2026-01-26 20:57:41 +00:00
|
|
|
EUPL-1.2 - See [LICENSE](../../LICENSE) for details.
|