telehost/jarvis-client

Jarvis monitoring agent client for Laravel — expose health metrics to the Jarvis autonomous monitoring agent via a standardized /jarvis/health endpoint

Maintainers

Package info

github.com/telehostca/jarvis-client-php

pkg:composer/telehost/jarvis-client

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-04-19 14:08 UTC

This package is auto-updated.

Last update: 2026-04-19 22:50:04 UTC


README

Expose your Laravel app to Jarvis — the autonomous monitoring agent that watches your infrastructure and alerts you via WhatsApp when things go wrong.

Packagist Version License

What it does

Jarvis is an AI agent that polls your app every 15 minutes and asks "is everything OK?". If anything is off — queue backlog, dropped users, rising error rate, failed jobs — it sends you a WhatsApp message with evidence-based suggestions.

This package exposes a standardized /jarvis/health endpoint that Jarvis polls. You define what metrics to expose, the package handles the rest (auth, formatting, error isolation).

Why you want it

Without Jarvis With Jarvis
You SSH in to check if things are OK Jarvis tells you via WhatsApp when they're not
Errors pile up until users complain Jarvis catches trends before customers notice
You learn Grafana/Prometheus You define 5 closures and you're done
$50+/month for Datadog Free tier, $19/mo Pro, with WhatsApp alerts in Spanish

Installation

composer require telehost/jarvis-client

Publish the config:

php artisan vendor:publish --tag=jarvis-config

Quick Start

1. Get your token from https://jarvis.telehost.net/dashboard (register your app → copy token)

2. Set it in your .env:

JARVIS_TOKEN=jrv_app_abc123...

3. Edit config/jarvis.php:

return [
    'token' => env('JARVIS_TOKEN'),

    'metrics' => [
        'users_active' => fn () => \App\Models\User::where('suspended', false)->count(),
        'revenue_today' => fn () => \App\Models\Order::whereDate('created_at', today())->sum('total'),
        'queue' => fn () => [
            'pending' => \DB::table('jobs')->count(),
            'failed_1h' => \DB::table('failed_jobs')
                ->where('failed_at', '>=', now()->subHour())
                ->count(),
        ],
    ],

    'alerts' => [
        'disk_low' => fn () => disk_free_space('/') < 1_000_000_000
            ? ['severity' => 'critical', 'message' => 'Less than 1GB disk free']
            : null,
    ],
];

4. That's it. Jarvis will start monitoring within minutes.

Verify locally:

curl -H "Authorization: Bearer $JARVIS_TOKEN" http://localhost:8000/jarvis/health

You should see:

{
  "app": "My App",
  "version": "1.0",
  "timestamp": "2026-04-19T14:30:00Z",
  "status": "healthy",
  "metrics": {
    "users_active": 1247,
    "revenue_today": 82340.50,
    "queue": { "pending": 3, "failed_1h": 0 }
  },
  "alerts": [],
  "custom": []
}

Advanced

Custom route path

JARVIS_PATH=/internal/jarvis

Or disable auto-registration and define it yourself:

// config/jarvis.php
'auto_register_route' => false,

// routes/web.php
Route::get('/custom/health/path', \TeleHost\Jarvis\JarvisHealthController::class)
    ->middleware([\TeleHost\Jarvis\JarvisAuth::class]);

Per-request middleware

// config/jarvis.php
'middleware' => [
    'throttle:30,1', // 30 requests per minute from Jarvis
],

Dynamic metric registration

From a service provider:

use TeleHost\Jarvis\JarvisManager;

app(JarvisManager::class)
    ->metric('stripe_balance', fn () => \Stripe\Balance::retrieve()->available[0]->amount / 100)
    ->alert('subscription_renewal', function () {
        $expiring = Subscription::whereDate('expires_at', today()->addDays(7))->count();
        return $expiring > 10
            ? ['severity' => 'warning', 'message' => "{$expiring} subs expire this week"]
            : null;
    });

Error isolation

If any metric closure throws, only that metric fails — the rest continue:

{
  "metrics": {
    "users_active": 1247,
    "external_api_count": { "error": "Connection timeout" },
    "revenue_today": 82340.50
  }
}

Jarvis handles the error gracefully and reports it to you.

What Jarvis expects

Your closures can return:

  • Scalars: int, float, string, bool
  • Arrays (for grouped metrics):
    'whatsapp' => fn () => [
        'connected' => 15,
        'disconnected' => 2,
        'by_integration' => ['baileys' => 13, 'meta' => 4],
    ],
  • null (metric skipped this cycle)

For alerts, return:

  • ['severity' => 'info'|'warning'|'critical', 'message' => 'Human-readable text']
  • Or null (no alert)

Security

  • The endpoint is protected by a bearer token (NEVER commit it)
  • Only Jarvis has the token — anyone else gets 401
  • Use HTTPS in production (Laravel defaults to it behind most load balancers)
  • Rotate the token anytime from the dashboard

Common metrics to expose

Tailor to your business, but here are patterns that work well:

'metrics' => [
    // Business health
    'users_active' => fn () => User::where('last_login_at', '>=', now()->subWeek())->count(),
    'new_signups_24h' => fn () => User::where('created_at', '>=', now()->subDay())->count(),
    'revenue_today' => fn () => Transaction::whereDate('created_at', today())->sum('amount'),

    // Infrastructure
    'queue' => fn () => [
        'pending' => DB::table('jobs')->count(),
        'failed_1h' => DB::table('failed_jobs')->where('failed_at', '>=', now()->subHour())->count(),
    ],

    // External dependencies
    'db_latency_ms' => fn () => measureDbLatency(),
    'stripe_reachable' => fn () => pingStripe(),

    // Error rates
    'error_rate_pct' => fn () => calculateErrorRate(),
],

Testing

composer test

License

MIT. See LICENSE.md.

Who builds this

TeleHost C.A. — a Venezuelan infrastructure company that got tired of paying $50+/month for monitoring and built its own.