<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Siong Yuen Cheah</title>
    <description>The latest articles on DEV Community by Siong Yuen Cheah (@siongyuen).</description>
    <link>https://dev.to/siongyuen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3886962%2Fd5240f5f-b63b-4399-9ef2-7c5c32af27c5.png</url>
      <title>DEV Community: Siong Yuen Cheah</title>
      <link>https://dev.to/siongyuen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siongyuen"/>
    <language>en</language>
    <item>
      <title>Your AI Agent Is Flying Blind. Here's How to Fix It.</title>
      <dc:creator>Siong Yuen Cheah</dc:creator>
      <pubDate>Tue, 21 Apr 2026 14:26:09 +0000</pubDate>
      <link>https://dev.to/siongyuen/your-ai-agent-is-flying-blind-heres-how-to-fix-it-34de</link>
      <guid>https://dev.to/siongyuen/your-ai-agent-is-flying-blind-heres-how-to-fix-it-34de</guid>
      <description>&lt;h2&gt;
  
  
  tags: mcp, ai, devtools, webdev, 
&lt;/h2&gt;

&lt;p&gt;You've spent months building the perfect AI coding assistant. It writes clean TypeScript, refactors legacy code, generates tests. But ask it something simple like &lt;em&gt;"Is my project healthy right now?"&lt;/em&gt; and watch it stumble.&lt;/p&gt;

&lt;p&gt;The agent fires off a GitHub MCP call. Gets back a wall of JSON. Fires off another. Different schema. By call five, it's lost context. By call ten, you've burned through your context window and still don't know if you should deploy.&lt;/p&gt;

&lt;p&gt;This is the dirty secret of AI-assisted development: &lt;strong&gt;agents are blind to project health&lt;/strong&gt;. They can manipulate code but cannot perceive the living system behind it.&lt;/p&gt;

&lt;p&gt;I built PulseTel to solve exactly this.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Raw APIs vs. Agent-Ready Intelligence
&lt;/h2&gt;

&lt;p&gt;Let's be concrete. Say you want to know if your project is safe to deploy right now. Here's what happens with raw MCP tools:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Raw GitHub MCP Approach
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Call 1: Check CI status&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mcp_github_get_workflow_run &lt;span class="nt"&gt;--repo&lt;/span&gt; myapp &lt;span class="nt"&gt;--run-id&lt;/span&gt; 12345
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;: 12345, &lt;span class="s2"&gt;"status"&lt;/span&gt;: &lt;span class="s2"&gt;"completed"&lt;/span&gt;, &lt;span class="s2"&gt;"conclusion"&lt;/span&gt;: &lt;span class="s2"&gt;"failure"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Call 2: Check for open issues&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mcp_github_search_issues &lt;span class="nt"&gt;--repo&lt;/span&gt; myapp &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"is:open label:bug"&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"total_count"&lt;/span&gt;: 47, &lt;span class="s2"&gt;"items"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;...]&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Call 3: Check PRs&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mcp_github_list_pull_requests &lt;span class="nt"&gt;--repo&lt;/span&gt; myapp &lt;span class="nt"&gt;--state&lt;/span&gt; open
&lt;span class="o"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"Fix auth bug"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"title"&lt;/span&gt;: &lt;span class="s2"&gt;"WIP: refactor"&lt;/span&gt;&lt;span class="o"&gt;}]&lt;/span&gt;

&lt;span class="c"&gt;# Call 4: Check dependencies (different tool entirely)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mcp_datadog_dependency_metrics &lt;span class="nt"&gt;--service&lt;/span&gt; myapp
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;: &lt;span class="s2"&gt;"API key not configured"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Call 5: Realize you need deployment status&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production
error: Unable to connect to the server: Forbidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five calls. Three different authentication methods. Inconsistent schemas. No prioritization. The agent has a pile of data but zero insight into what actually matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  The PulseTel Approach
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx pulsetel-cli check

┌─────────────────────────────────────────────────────────────┐
│  PulseTel Project Health Check                              │
│  myapp | main branch | Last checked: 2m ago                  │
├─────────────────────────────────────────────────────────────┤
│  🔴 CRITICAL &lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;                                             │
│  ├─ CI/CD: Build failing on main &lt;span class="o"&gt;(&lt;/span&gt;Node 20 incompatibility&lt;span class="o"&gt;)&lt;/span&gt;   │
│  │   └─ Action: Pin Node version &lt;span class="k"&gt;in&lt;/span&gt; .nvmrc                    │
│  │                                                            │
│  🟡 WARNINGS &lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt;                                             │
│  ├─ Dependencies: 3 high-severity vulnerabilities            │
│  ├─ Health: API latency p95 degraded &lt;span class="o"&gt;(&lt;/span&gt;420ms → 680ms&lt;span class="o"&gt;)&lt;/span&gt;         │
│  │                                                            │
│  🟢 HEALTHY &lt;span class="o"&gt;(&lt;/span&gt;5&lt;span class="o"&gt;)&lt;/span&gt;                                              │
│  ├─ Deploy: Last successful 3h ago                           │
│  ├─ Issues: 2 open &lt;span class="o"&gt;(&lt;/span&gt;down from 8 last week&lt;span class="o"&gt;)&lt;/span&gt;                   │
│  ├─ PRs: 1 ready &lt;span class="k"&gt;for &lt;/span&gt;review                                  │
│  ├─ Coverage: 84% &lt;span class="o"&gt;(&lt;/span&gt;stable&lt;span class="o"&gt;)&lt;/span&gt;                                   │
│  └─ Git: No uncommitted changes on main                      │
└─────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command. Eight dimensions of health. Prioritized actions. Exit codes for CI/CD gating.&lt;/p&gt;

&lt;p&gt;This is what agent-native telemetry looks like.&lt;/p&gt;




&lt;h2&gt;
  
  
  How PulseTel Works
&lt;/h2&gt;

&lt;p&gt;PulseTel is an MCP server that speaks "project health." It aggregates 8 check modules:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Module&lt;/th&gt;
&lt;th&gt;What It Checks&lt;/th&gt;
&lt;th&gt;Data Sources&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Workflow runs, flaky tests, build duration&lt;/td&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deploy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deployment status, rollback candidates&lt;/td&gt;
&lt;td&gt;Webhooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Health&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Endpoint latency, error rates, availability&lt;/td&gt;
&lt;td&gt;HTTP probes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vulnerabilities, outdated packages&lt;/td&gt;
&lt;td&gt;npm audit, OSV&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Test coverage trends&lt;/td&gt;
&lt;td&gt;lcov, Codecov&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Issues&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bug backlog, critical open issues&lt;/td&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pull Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Merge queue, review latency&lt;/td&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Commit hygiene, branch divergence&lt;/td&gt;
&lt;td&gt;Local git&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every check returns a structured response with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;status&lt;/code&gt;: success | warning | error | critical&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;severity&lt;/code&gt;: low | medium | high&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;confidence&lt;/code&gt;: 0.0–1.0 based on data freshness&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;actionable&lt;/code&gt;: specific recommendation if needed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;duration_ms&lt;/code&gt;: how long the check took&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Killer Feature: &lt;code&gt;pulsetel_recommend&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Here's where PulseTel gets interesting. Instead of making the agent sift through check results, you ask for recommendations via the &lt;code&gt;pulsetel_recommend&lt;/code&gt; MCP tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"recommendations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"rank"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"critical"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.94&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"check"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ci"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"finding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Build failing on main branch for 47 minutes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"impact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Blocking all deployments, 3 PRs queued"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pin Node.js to 18.19.0 in .nvmrc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"estimated_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5 minutes"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"rank"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.87&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"check"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"finding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lodash@4.17.20 has prototype pollution (CVE-2021-23337)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Run 'pulsetel fix --deps' or upgrade to lodash@4.17.21"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"estimated_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2 minutes"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rank 1 is what you fix &lt;strong&gt;right now&lt;/strong&gt;. The agent doesn't need to reason about what matters — PulseTel already did.&lt;/p&gt;




&lt;h2&gt;
  
  
  16 MCP Tools for Agent Integration
&lt;/h2&gt;

&lt;p&gt;PulseTel exposes 15 MCP tools via stdio transport — compatible with Claude Desktop, Cursor, and any MCP-compatible client:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_check&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full health assessment&lt;/td&gt;
&lt;td&gt;~10s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_quick&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;High-signal subset (skips deps/coverage)&lt;/td&gt;
&lt;td&gt;~1-2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_ci&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CI/CD status only&lt;/td&gt;
&lt;td&gt;~2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_health&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Endpoint health only&lt;/td&gt;
&lt;td&gt;~1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_deps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dependency status&lt;/td&gt;
&lt;td&gt;~5s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_summary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One-line status summary&lt;/td&gt;
&lt;td&gt;&amp;lt;10ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_trends&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Historical trends&lt;/td&gt;
&lt;td&gt;~1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_anomalies&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Statistical anomalies (2σ detection)&lt;/td&gt;
&lt;td&gt;~1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_telemetry&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenTelemetry config status&lt;/td&gt;
&lt;td&gt;&amp;lt;100ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_recommend&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prioritized action list&lt;/td&gt;
&lt;td&gt;~1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lightweight health ping&lt;/td&gt;
&lt;td&gt;&amp;lt;10ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_sentry&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sentry error tracking&lt;/td&gt;
&lt;td&gt;~2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_guidance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Agent reasoning assistance&lt;/td&gt;
&lt;td&gt;~500ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_diff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change intelligence (run vs. previous)&lt;/td&gt;
&lt;td&gt;~1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pulsetel_guard&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre/post checks around any command&lt;/td&gt;
&lt;td&gt;~15s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Add to Claude Desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pulsetel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pulsetel-cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp-stdio"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then ask: &lt;em&gt;"Should I deploy right now?"&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Guard: Drift Detection for Any Command
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;pulsetel_guard&lt;/code&gt; tool runs pre-check and post-check around any shell command and reports drift:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pulsetel guard &lt;span class="nt"&gt;--&lt;/span&gt; npm &lt;span class="nb"&gt;install

&lt;/span&gt;Running pre-checks...
Running: npm &lt;span class="nb"&gt;install
&lt;/span&gt;Running post-checks...

Drift detected! 3 checks changed &lt;span class="o"&gt;(&lt;/span&gt;max 100.0% change&lt;span class="o"&gt;)&lt;/span&gt;

Changed checks:
  - deps.vulnerabilities: before 0, after 2 &lt;span class="o"&gt;(&lt;/span&gt;+2 new&lt;span class="o"&gt;)&lt;/span&gt;
  - coverage: before 84%, after 79% &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-5&lt;/span&gt;%&lt;span class="o"&gt;)&lt;/span&gt;
  - health.api_latency: before 120ms, after 340ms &lt;span class="o"&gt;(&lt;/span&gt;+183%&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent now knows exactly what a command broke — no need to infer from separate API calls.&lt;/p&gt;




&lt;h2&gt;
  
  
  Trend Analysis &amp;amp; Anomaly Detection
&lt;/h2&gt;

&lt;p&gt;PulseTel tracks health over time and detects anomalies statistically (2σ from rolling mean):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx pulsetel-cli trends

📊 7-Day Trends

CI Success Rate
████████████████████░░░░ 89% &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-4&lt;/span&gt;%&lt;span class="o"&gt;)&lt;/span&gt; ↘ degrading

API Latency p95
████████████████████░░░ 680ms &lt;span class="o"&gt;(&lt;/span&gt;+260ms&lt;span class="o"&gt;)&lt;/span&gt; ↗ ANOMALY

Test Coverage
████████████████████░░░ 84% &lt;span class="o"&gt;(&lt;/span&gt;+1%&lt;span class="o"&gt;)&lt;/span&gt; → stable

Dependency Vulnerabilities
██░░░░░░░░░░░░░░░░░░░░░ 3 → stable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No arbitrary thresholds — a spike in latency for a high-variance service is treated differently than the same spike for a stable one.&lt;/p&gt;




&lt;h2&gt;
  
  
  OpenTelemetry Integration
&lt;/h2&gt;

&lt;p&gt;PulseTel v1.2+ exports project health as OTel-compliant telemetry:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traces&lt;/strong&gt;: Each check run emits a &lt;code&gt;pulsetel.check&lt;/code&gt; root span with child spans per module&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt;: Health scores, anomaly counts, vulnerability counters as gauges and counters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logs&lt;/strong&gt;: Anomaly events, degrading trends as structured log records
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# One-shot OTel export&lt;/span&gt;
pulsetel check &lt;span class="nt"&gt;--otel&lt;/span&gt;

&lt;span class="c"&gt;# Auto-enable in .pulsetel.yml&lt;/span&gt;
&lt;span class="c"&gt;# otel:&lt;/span&gt;
&lt;span class="c"&gt;#   enabled: true&lt;/span&gt;
&lt;span class="c"&gt;#   endpoint: http://localhost:4318&lt;/span&gt;
&lt;span class="c"&gt;#   protocol: http&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works with OTLP HTTP (port 4318) and file export (&lt;code&gt;.pulsetel/otel/&lt;/code&gt;) for offline ingestion.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sentry Error Tracking
&lt;/h2&gt;

&lt;p&gt;Configure once in &lt;code&gt;.pulsetel.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;sentry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;organization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-org&lt;/span&gt;
  &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-project&lt;/span&gt;
  &lt;span class="c1"&gt;# token via SENTRY_TOKEN env var&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pulsetel_sentry&lt;/code&gt; returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unresolved issue counts by severity&lt;/li&gt;
&lt;li&gt;Top 5 issues by frequency with direct links&lt;/li&gt;
&lt;li&gt;Affected user counts&lt;/li&gt;
&lt;li&gt;Release attribution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AI agents: one call instead of navigating the Sentry dashboard.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security You Can Verify
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSRF protection&lt;/strong&gt;: IPv4/IPv6 blocklists, DNS rebinding prevention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No shell injection&lt;/strong&gt;: All &lt;code&gt;child_process&lt;/code&gt; calls use &lt;code&gt;execFileSync&lt;/code&gt; (no shell)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No token leaks&lt;/strong&gt;: Secrets never logged, always via env vars&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured exit codes&lt;/strong&gt;: 0=healthy, 1=critical, 2=warnings, 3=partial&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fast triage (1-2s)&lt;/span&gt;
npx pulsetel-cli quick

&lt;span class="c"&gt;# Full check with all modules (~10s)&lt;/span&gt;
npx pulsetel-cli check

&lt;span class="c"&gt;# Automated dependency fixes&lt;/span&gt;
npx pulsetel-cli fix &lt;span class="nt"&gt;--deps&lt;/span&gt;

&lt;span class="c"&gt;# Start MCP server for AI agent integration&lt;/span&gt;
npx pulsetel-cli mcp-stdio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configuration is minimal. PulseTel auto-detects Git remote, &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;.github/workflows&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For custom endpoints, add a &lt;code&gt;.pulsetel.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;github&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;owner/repo&lt;/span&gt;

&lt;span class="na"&gt;health&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.myapp.com/health&lt;/span&gt;

&lt;span class="na"&gt;webhooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://hooks.slack.com/services/T00/B00/XXX&lt;/span&gt;
    &lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;anomaly&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;degrading&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;flaky&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;critical&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;I was tired of asking Claude "is it safe to deploy?" and watching it make 6 API calls, lose context, and hallucinate a status summary.&lt;/p&gt;

&lt;p&gt;AI agents need &lt;strong&gt;perception&lt;/strong&gt;. They need to see the system state, understand what's broken, and know what to fix first. Raw APIs give them eyes but no vision. PulseTel gives them both.&lt;/p&gt;

&lt;p&gt;Every response carries a schema contract (&lt;code&gt;schema_version&lt;/code&gt;, &lt;code&gt;schema_url&lt;/code&gt;) so consumers can validate without guessing. The architecture is modular — add a check module, wire in a new data source. It's built to be extended.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pulsetel-cli check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or star the repo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/siongyuen/pulsetel" rel="noopener noreferrer"&gt;github.com/siongyuen/pulsetel&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;code&gt;npm install pulsetel-cli&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://sycheah.com/pulsetel.html" rel="noopener noreferrer"&gt;sycheah.com/pulsetel.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Issues and PRs welcome. MIT licensed. Your AI agent has been flying blind long enough — give it eyes.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
