```php title="PHP" app->singleton(KreuzbergMcpService::class); * * Then inject in controllers or jobs. */ final class KreuzbergMcpService { private Client $http; public function __construct( private readonly LoggerInterface $logger, private readonly string $mcpUrl = 'http://localhost:3000', ) { $this->http = new Client([ 'base_uri' => $this->mcpUrl, 'timeout' => config('kreuzberg.timeout', 30), 'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json', ], ]); } /** * Extract content from a file via MCP server. * * @param array|null $config * @return array{content: string, mimeType: string, metadata: array} * @throws GuzzleException */ public function extractFile(string $path, ?array $config = null): array { $cacheKey = 'kreuzberg_extract_' . md5($path . json_encode($config)); return Cache::remember($cacheKey, now()->addHours(24), function () use ($path, $config): array { $this->logger->info('Extracting file via MCP', [ 'path' => $path, 'config' => $config, ]); try { $response = $this->http->post('/tools/call', [ 'json' => [ 'name' => 'extract_file', 'arguments' => [ 'path' => $path, 'config' => $config, ], ], ]); $result = json_decode( $response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR ); $this->logger->info('Extraction successful', [ 'path' => $path, 'content_length' => strlen($result['content'] ?? ''), ]); return $result; } catch (GuzzleException $e) { $this->logger->error('MCP extraction failed', [ 'path' => $path, 'error' => $e->getMessage(), ]); throw $e; } }); } /** * Extract multiple files in batch. * * @param array $paths * @param array|null $config * @return array * @throws GuzzleException */ public function batchExtractFiles(array $paths, ?array $config = null): array { $this->logger->info('Batch extracting files via MCP', [ 'count' => count($paths), ]); try { $response = $this->http->post('/tools/call', [ 'json' => [ 'name' => 'batch_extract_files', 'arguments' => [ 'paths' => $paths, 'config' => $config, ], ], ]); $results = json_decode( $response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR ); $this->logger->info('Batch extraction successful', [ 'count' => count($results), ]); return $results; } catch (GuzzleException $e) { $this->logger->error('MCP batch extraction failed', [ 'count' => count($paths), 'error' => $e->getMessage(), ]); throw $e; } } /** * Check if MCP server is healthy. */ public function healthCheck(): bool { try { $response = $this->http->get('/health', ['timeout' => 2]); return $response->getStatusCode() === 200; } catch (GuzzleException) { return false; } } } // Usage in a Laravel controller namespace App\Http\Controllers; use App\Services\KreuzbergMcpService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; final class DocumentController extends Controller { public function __construct( private readonly KreuzbergMcpService $kreuzberg, ) {} public function extract(Request $request): JsonResponse { $validated = $request->validate([ 'file_path' => 'required|string', 'extract_tables' => 'boolean', 'extract_images' => 'boolean', ]); $config = [ 'extractTables' => $validated['extract_tables'] ?? true, 'extractImages' => $validated['extract_images'] ?? false, ]; $result = $this->kreuzberg->extractFile( $validated['file_path'], $config ); return response()->json([ 'success' => true, 'data' => $result, ]); } public function batchExtract(Request $request): JsonResponse { $validated = $request->validate([ 'file_paths' => 'required|array', 'file_paths.*' => 'required|string', ]); $results = $this->kreuzberg->batchExtractFiles($validated['file_paths']); return response()->json([ 'success' => true, 'data' => $results, 'count' => count($results), ]); } public function health(): JsonResponse { $healthy = $this->kreuzberg->healthCheck(); return response()->json([ 'healthy' => $healthy, 'service' => 'kreuzberg-mcp', ], $healthy ? 200 : 503); } } ```