2026-01-28 14:13:09 +00:00
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Package Overview
This is `host-uk/core-mcp` , a standalone Laravel package providing Model Context Protocol (MCP) tools for AI-powered automation. It implements the JSON-RPC MCP standard for AI agent integrations with security-focused database access.
**Namespaces:**
- `Core\Mcp\` - Main package code (tools, services, middleware)
- `Core\Website\Mcp\` - Web UI components (Livewire modals, controllers)
## Commands
```bash
./vendor/bin/pest # Run all tests
./vendor/bin/pest --filter=SqlQuery # Run specific tests
./vendor/bin/pint --dirty # Format changed files
php artisan mcp:agent-server # Run the MCP agent server (stdio)
php artisan mcp:prune-metrics # Prune old analytics data
php artisan mcp:verify-audit-log # Verify audit log integrity
```
2026-01-26 20:49:02 +00:00
## Architecture
2026-01-28 14:13:09 +00:00
### MCP Tool System
Tools extend `Laravel\Mcp\Server\Tool` and implement:
- `$description` property for tool purpose
- `schema(JsonSchema $schema): array` for input parameters
- `handle(Request $request): Response` for execution logic
2026-01-26 20:49:02 +00:00
```php
2026-01-28 14:13:09 +00:00
class QueryDatabase extends Tool
2026-01-26 20:49:02 +00:00
{
2026-01-28 14:13:09 +00:00
protected string $description = 'Execute a read-only SQL SELECT query';
public function schema(JsonSchema $schema): array
{
return [
'query' => $schema->string('SQL SELECT query'),
'explain' => $schema->boolean('Run EXPLAIN instead')->default(false),
];
}
public function handle(Request $request): Response
{
// Validate and execute
return Response::text(json_encode($results));
}
2026-01-26 20:49:02 +00:00
}
```
2026-01-28 14:13:09 +00:00
### Boot Class (Event-Driven Registration)
2026-01-26 20:49:02 +00:00
2026-01-28 14:13:09 +00:00
`src/Mcp/Boot.php` registers via Core framework events:
- `AdminPanelBooting` - Admin routes, views, Livewire components
- `ConsoleBooting` - Artisan commands
- `McpToolsRegistering` - MCP tool handlers
2026-01-26 20:49:02 +00:00
2026-01-28 14:13:09 +00:00
### Security Layers
2026-01-26 20:49:02 +00:00
2026-01-28 14:13:09 +00:00
**SQL Query Validation** (`SqlQueryValidator` ):
1. Blocked keywords (INSERT, UPDATE, DELETE, DROP, etc.)
2. Dangerous pattern detection (UNION injection, hex encoding, stacked queries)
3. Whitelist regex matching for allowed query structures
4. Comment stripping before validation
**Workspace Context Security**:
- `RequiresWorkspaceContext` trait enforces tenant isolation
- Tools throw `MissingWorkspaceContextException` without valid context
- `ValidateWorkspaceContext` middleware injects context from auth
2026-01-26 20:49:02 +00:00
2026-01-28 14:13:09 +00:00
### Key Services
2026-01-26 20:49:02 +00:00
2026-01-28 14:13:09 +00:00
| Service | Purpose |
2026-01-26 20:49:02 +00:00
|---------|---------|
2026-01-28 14:13:09 +00:00
| `ToolRegistry` | Discovers tools from YAML config, manages schemas |
| `SqlQueryValidator` | Multi-layer SQL injection protection |
| `ToolAnalyticsService` | Usage tracking and metrics |
| `McpQuotaService` | Workspace-level rate limiting |
| `AuditLogService` | Tamper-evident logging |
| `ToolDependencyService` | Validates tool dependencies at runtime |
### Tool Configuration
Tools are defined in `resources/mcp/servers/*.yaml` :
```yaml
id: workspace-tools
name: Workspace Tools
tools:
- name: query_database
description: Execute read-only SQL query
inputSchema:
type: object
properties:
query: { type: string }
```
## Testing
Tests use **Pest** and are located in:
- `tests/` - Integration tests (Laravel TestCase)
- `src/Mcp/Tests/` - Package unit tests
```php
describe('SqlQueryValidator', function () {
it('blocks INSERT statements', function () {
$validator = new SqlQueryValidator();
expect(fn () => $validator->validate('INSERT INTO users VALUES (1)'))
->toThrow(ForbiddenQueryException::class);
});
});
```
2026-01-26 20:49:02 +00:00
## Conventions
- UK English (colour, organisation, centre)
2026-01-28 14:13:09 +00:00
- `declare(strict_types=1);` in every PHP file
- PSR-12 via Laravel Pint
- Pest for testing (not PHPUnit syntax)
- All parameters and return types must have type hints
2026-01-26 20:49:02 +00:00
## License
2026-01-28 14:13:09 +00:00
EUPL-1.2 (copyleft applies to `Core\` namespace)