Signalsfeed

Created By
21 days ago
Overview

SignalsFeed
for AI Agents

SignalsFeed, also searched as Signals Feed, signal feed, or SignalFeed, delivers cross-validated AI, semiconductor, and macro signals as structured JSON. Honest credibility scoring. $0.01 returns up to 20 premium full signals via x402 USDC.

SignalsFeed is a signals feed built for autonomous agents

SignalsFeed, sometimes written as Signals Feed, signal feed, or SignalFeed, is a source-backed intelligence API for AI agents. It helps agents discover premium-ready signals across AI, semiconductor, and macro topics without scraping noisy HTML or guessing which sources are trustworthy.

Structured signals, not raw noise

Each signal is extracted from source text, cross-validated for factual consistency, and scored for credibility. Structured JSON your agent can act on immediately.

<div class="features">
  <div class="feature">
    <div class="feature-title">Cross-validated</div>
    <div class="feature-desc">Multiple independent sources compared for factual consistency. Conflicts flagged, not hidden.</div>
  </div>
  <div class="feature">
    <div class="feature-title">Credibility scored</div>
    <div class="feature-desc">Honest 0&ndash;1 score calibrated by source quality, fact consistency, and independent confirmation count.</div>
  </div>
  <div class="feature">
    <div class="feature-title">Structured JSON</div>
    <div class="feature-desc">Claim, confidence, entities, keywords, evidence, related signals, supporting articles. No parsing required.</div>
  </div>
</div>

<div class="field-list">id, domain, claim, signal_type, confidence, entities, keywords, evidence_count, observation_date, evidence, related_signals, supporting_articles</div>

Agents deserve better than raw HTML

Your agent can scrape the web itself. But parsing noisy HTML, deduplicating, and fact-checking burns LLM budget on commodity work. We do it once, you pay a cent.

<div class="comparison">
  <div class="comp-card">
    <div class="comp-label">Agent scrapes itself</div>
    <div class="comp-text">Noisy HTML. No validation. Format varies per source. Burns LLM budget parsing junk. No way to know what's true.</div>
  </div>
  <div class="comp-card alt">
    <div class="comp-label">SignalsFeed</div>
    <div class="comp-text">Clean JSON. Cross-checked facts. Honest credibility score. Source links for independent verification.</div>
  </div>
</div>

<div class="pricing-callout">
  <span class="pricing-amount">$0.01</span>
  <span class="pricing-unit">for up to 20 premium full signals</span>
</div>
<p class="pricing-note">One x402 payment returns 1-20 premium full signals, same price. No API keys. No signup. No subscription. Cheaper than one LLM call to parse a raw webpage.</p>

Two calls. That's it.

Start from one unified feed, inspect teaser signals, then pay for the premium signals you need. No wasted calls, no duplicate data charges.

<div class="agent-callout">
  <div class="agent-callout-label">Send this to your AI agent</div>
  <div class="code-block">
    Read https://signalsfeed.com/llms.txt.<br>
    Start with https://signalsfeed.com/api/v1/feed to discover recent signal IDs across all domains.<br>
    Use domain, signal_type, teaser, and quality_status to screen what is relevant.<br>
    If needed, request the paid ids= endpoint on /api/v1/feed to retrieve full premium signals.<br>
    Prefer paid fetches only after screening the free list.<br>
    See https://signalsfeed.com/demo/ for a concrete feed-usage demo that turns macro inputs into an allocation workflow.
  </div>
</div>

<div class="code-block">
  <span class="comment"># 1. Free &mdash; see what's new</span><br>
  <span class="method">GET</span> <span class="url">/api/v1/feed?since=2026-04-14T00:00:00Z</span><br>
  <span class="status">&rarr; 200</span>&ensp;{ signals: [ {id, teaser, signal_type, domain, quality_status, confidence_band}, ... ] }
</div>

<div class="code-block">
  <span class="comment"># 2. Pay &mdash; $0.01 returns up to 20 premium full signals</span><br>
  <span class="method">GET</span> <span class="url">/api/v1/feed?ids=uuid1,uuid2,uuid3</span><br>
  <span class="status">&rarr; 402</span>&ensp;<span class="price">$0.01 USDC</span> via x402<br>
  <span class="status">&rarr; 200</span>&ensp;{ signals: [ {full claim, evidence, related_signals, ...} ] }
</div>

<div class="domains">
  <span class="domain-tag">/api/v1/feed</span>
  <span class="domain-tag">domain=ai</span>
  <span class="domain-tag">domain=semiconductor</span>
  <span class="domain-tag">domain=macro</span>
</div>

A living proof point, not a static promise

A live view of premium signals surfaced in the last 24 hours across AI, macro, and semiconductors.

<div class="live-proof">
  <div class="live-proof-card">
    <div class="live-proof-kicker">Last 24 Hours</div>
    <div class="live-proof-stat">
      <div class="live-proof-count" id="live-premium-count">...</div>
      <div class="live-proof-unit">premium signals surfaced</div>
    </div>
    <p class="live-proof-copy">Structured, credibility-scored signals pulled from the same discovery layer your agents use. Humans get proof the system is active. Agents get JSON they only buy when it matters.</p>
    <div class="live-proof-meta">
      <div class="live-pill"><strong id="live-domain-ai">0</strong> AI</div>
      <div class="live-pill"><strong id="live-domain-macro">0</strong> Macro</div>
      <div class="live-pill"><strong id="live-domain-semiconductor">0</strong> Semiconductor</div>
    </div>
  </div>

  <div class="live-proof-stream">
    <div class="live-stream-header">
      <div class="live-stream-title">Recent premium signals</div>
      <div class="live-stream-status" id="live-feed-status">Loading live feed...</div>
    </div>
    <ul class="live-titles" id="live-premium-titles">
      <li class="live-title-empty">Fetching recent premium signals from the public feed.</li>
    </ul>
  </div>
</div>
if (!countEl || !statusEl || !titlesEl) return;

const MAX_VISIBLE = 5;
let rotationTimer = null;
let highlightTimer = null;
let fadeTimer = null;
let currentRows = [];
let currentWindowStart = 0;
let currentHighlightIndex = 0;
const HIGHLIGHT_MS = 4000;
const WINDOW_FADE_MS = 4000;
const TITLE_RULES = {
  strong: [
    'openai', 'anthropic', 'google', 'meta', 'microsoft', 'nvidia', 'amd', 'tsmc',
    'chip', 'chips', 'semiconductor', 'wafer', 'fab', 'foundry', 'gpu', 'hbm',
    'export', 'tariff', 'fed', 'federal reserve', 'treasury', 'inflation', 'cpi',
    'ppi', 'jobs report', 'payrolls', 'earnings', 'forecast', 'guidance', 'revenue',
    'opec', 'oil', 'gas', 'iran', 'strait of hormuz', 'ceasefire', 'trade',
    'factory', 'manufacturing', 'hyperscaler', 'data center', 'datacenter', 'api',
    'partnership', 'acquisition', 'investment', 'subsidy', 'white house', 'china'
  ],
  weak: [
    'doctor', 'lifestyle', 'recipe', 'travel', 'fashion', 'celebrity', 'mortgage rates',
    'horoscope', 'dating', 'wellness', 'retirement', 'personal finance', 'credit score',
    'fitness', 'diet', 'vacation', 'phone etiquette'
  ]
};

function rowFactTimestamp(row) {
  const iso = rowFactDate(row);
  const ts = iso ? new Date(iso).getTime() : NaN;
  return Number.isNaN(ts) ? null : ts;
}

function rowFactDate(row) {
  return row.observation_date || row.published_at || null;
}

function isWithinLast24Hours(row) {
  const ts = rowFactTimestamp(row);
  if (ts === null) return false;
  return ts >= (Date.now() - 24 * 60 * 60 * 1000);
}

function relativeTime(iso) {
  const deltaMs = Date.now() - new Date(iso).getTime();
  const minutes = Math.max(1, Math.round(deltaMs / 60000));
  if (minutes < 60) return `${minutes}m ago`;
  const hours = Math.round(minutes / 60);
  if (hours < 24) return `${hours}h ago`;
  const days = Math.round(hours / 24);
  return `${days}d ago`;
}

function formatSignalType(value) {
  return String(value || 'signal')
    .replace(/_/g, ' ')
    .replace(/\b\w/g, (match) => match.toUpperCase());
}

function formatConfidenceBand(value) {
  if (!value) return 'Developing confidence';
  return `${String(value).charAt(0).toUpperCase()}${String(value).slice(1)} confidence`;
}

function formatEvidenceCount(value) {
  const count = Number(value || 0);
  return count === 1 ? '1 source' : `${count} sources`;
}

function formatObservationDate(iso) {
  if (!iso) return null;
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return null;
  return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
}

function titleScore(row) {
  const title = String(row.teaser || '').toLowerCase();
  let score = 0;
  TITLE_RULES.strong.forEach((term) => {
    if (title.includes(term)) score += 2;
  });
  TITLE_RULES.weak.forEach((term) => {
    if (title.includes(term)) score -= 5;
  });
  if (row.domain === 'macro') score += 1;
  if (row.domain === 'semiconductor') score += 1;
  return score;
}

function rowSubjectKey(row) {
  const subject = String(row.subject || '').trim().toLowerCase();
  if (subject) return subject;
  const teaser = String(row.teaser || '').trim().toLowerCase();
  return teaser.split(' — ')[0] || teaser;
}

function rowDiversityKey(row) {
  const factDate = String(rowFactDate(row) || '').slice(0, 10);
  return [row.domain || '', factDate, rowSubjectKey(row)].join('|');
}

function curateRows(rows) {
  const scored = rows.map((row) => ({ row, score: titleScore(row) }));
  const ranked = scored
    .filter((entry) => entry.score > -3)
    .sort((a, b) => {
      if (b.score !== a.score) return b.score - a.score;
      return (rowFactTimestamp(b.row) || 0) - (rowFactTimestamp(a.row) || 0);
    })
    .map((entry) => entry.row);

  const diverse = [];
  const seenKeys = new Set();
  ranked.forEach((row) => {
    const key = rowDiversityKey(row);
    if (seenKeys.has(key)) return;
    seenKeys.add(key);
    diverse.push(row);
  });

  if (diverse.length >= MAX_VISIBLE) return diverse;
  const merged = [...diverse];
  ranked.forEach((row) => {
    if (!merged.find((item) => item.id === row.id)) merged.push(row);
  });
  return merged;
}

function randomWindowStart(rows) {
  if (!rows.length) return 0;
  if (rows.length <= MAX_VISIBLE) return 0;
  const windowCount = Math.ceil(rows.length / MAX_VISIBLE);
  const randomWindow = Math.floor(Math.random() * windowCount);
  return (randomWindow * MAX_VISIBLE) % rows.length;
}

async function fetchPremiumRows() {
  const all = [];
  let cursor = null;
  while (true) {
    const params = new URLSearchParams({
      limit: '100',
      quality_status: 'premium'
    });
    if (cursor) params.set('cursor', cursor);
    const response = await fetch(`/api/v1/feed?${params.toString()}`);
    if (!response.ok) {
      throw new Error(`feed returned ${response.status}`);
    }
    const payload = await response.json();
    const rows = Array.isArray(payload.signals) ? payload.signals : [];
    all.push(...rows.filter((row) => row.quality_status === 'premium'));
    if (!payload.has_more || !payload.next_cursor) break;
    cursor = payload.next_cursor;
  }
  return all
    .filter((row) => isWithinLast24Hours(row))
    .sort((a, b) => (rowFactTimestamp(b) || 0) - (rowFactTimestamp(a) || 0));
}

function renderRows(rows) {
  let sample = rows.slice(currentWindowStart, currentWindowStart + MAX_VISIBLE);
  if (rows.length > MAX_VISIBLE && sample.length < MAX_VISIBLE) {
    sample = sample.concat(rows.slice(0, MAX_VISIBLE - sample.length));
  }
  titlesEl.innerHTML = '';
  if (!sample.length) {
    titlesEl.innerHTML = '<li class="live-title-empty">No premium signals were published in the last 24 hours.</li>';
    return;
  }

  sample.forEach((row, index) => {
    const item = document.createElement('li');
    item.className = `live-title${index === currentHighlightIndex ? ' active' : ''}`;
    item.innerHTML = `
      <div class="live-title-top">
        <span class="live-badge">Premium</span>
        <span class="live-domain">${row.domain}</span>
        <span class="live-time">${relativeTime(rowFactDate(row) || row.published_at)}</span>
      </div>
      <div class="live-title-text"></div>
      <div class="live-title-meta"></div>
      <div class="live-title-unlock"><strong>Unlock:</strong> full claim, source evidence, and related signals.</div>
    `;
    item.querySelector('.live-title-text').textContent = row.teaser || 'Premium signal available';
    const metaEl = item.querySelector('.live-title-meta');
    const chips = [
      { text: formatSignalType(row.signal_type), className: 'live-meta-chip' },
      { text: formatConfidenceBand(row.confidence_band), className: 'live-meta-chip live-meta-chip-strong' },
      { text: formatEvidenceCount(row.evidence_count), className: 'live-meta-chip live-meta-chip-good' },
    ];
    const observationLabel = formatObservationDate(rowFactDate(row));
    if (observationLabel) {
      chips.push({ text: `Fact date ${observationLabel}`, className: 'live-meta-chip' });
    }
    chips.forEach((chip) => {
      const span = document.createElement('span');
      span.className = chip.className;
      span.textContent = chip.text;
      metaEl.appendChild(span);
    });
    titlesEl.appendChild(item);
  });

  if (rotationTimer) clearInterval(rotationTimer);
  if (highlightTimer) clearInterval(highlightTimer);
  if (fadeTimer) clearTimeout(fadeTimer);
  if (sample.length > 1) {
    highlightTimer = setInterval(() => {
      if (currentHighlightIndex >= sample.length - 1) return;
      currentHighlightIndex += 1;
      const items = titlesEl.querySelectorAll('.live-title');
      items.forEach((item, index) => {
        item.classList.toggle('active', index === currentHighlightIndex);
      });
    }, HIGHLIGHT_MS);
  }
  if (rows.length <= MAX_VISIBLE) return;

  fadeTimer = setTimeout(() => {
    const items = titlesEl.querySelectorAll('.live-title');
    items.forEach((item) => item.classList.remove('active'));
  }, HIGHLIGHT_MS * sample.length);

  rotationTimer = setInterval(() => {
    currentWindowStart = (currentWindowStart + MAX_VISIBLE) % rows.length;
    currentHighlightIndex = 0;
    renderRows(rows);
  }, HIGHLIGHT_MS * sample.length + WINDOW_FADE_MS);
}

function updateMeta(rows) {
  countEl.textContent = String(rows.length);
  const counts = { ai: 0, macro: 0, semiconductor: 0 };
  rows.forEach((row) => {
    if (counts[row.domain] !== undefined) counts[row.domain] += 1;
  });
  Object.entries(domainEls).forEach(([key, el]) => {
    if (el) el.textContent = String(counts[key] || 0);
  });
  statusEl.textContent = rows.length
    ? `Live from the public feed`
    : `No recent premium activity`;
}

async function init() {
  try {
    const rows = await fetchPremiumRows();
    currentRows = curateRows(rows);
    currentWindowStart = randomWindowStart(currentRows);
    currentHighlightIndex = 0;
    updateMeta(rows);
    renderRows(currentRows);
  } catch (error) {
    countEl.textContent = '--';
    statusEl.textContent = 'Live feed unavailable';
    titlesEl.innerHTML = '<li class="live-title-empty">The live premium sample is temporarily unavailable. The API and paid feed remain the product.</li>';
  }
}

init();

})();

Server Config

{
  "mcpServers": {
    "signalsfeed": {
      "url": "https://signalsfeed.com/mcp"
    }
  }
}
Project Info
Created At
21 days ago
Updated At
21 days ago
Author Name
-
Star
-
Language
-
License
-
Category
Tags

Recommend Servers

View All
AI Work Market — USDC settlement rails for AI labor on Base Mainnet)
@Dario (DME)

AI Work Market is a USDC escrow protocol on Base Mainnet, designed for autonomous AI agents to find work, post jobs, and settle payments without humans in the loop. This MCP server exposes 10 tools: **Escrow lifecycle** - `create_intent_quote` — get calldata + gas estimate for funding a new escrow intent - `submit_proof_quote` — get calldata for the seller to submit a proof URI - `release_funds_quote` — get calldata for the buyer to release payment (or claim/refund) **x402 single-call binding** - `x402_consume` — replaces the 5-step x402 flow with one HMAC-signed POST that returns a delivery URL **Onboarding & discovery** - `agent_onboard` — generate a signed agent card with marketplace attestation - `agent_search` — tf-idf search over the live agent catalog - `agent_reputation` — server-side reputation from on-chain Released/Refunded/Disputed events **Live state** - `system_status` — live on-chain state (nextIntentId, accumulatedFees, contract balance, owner) - `escrow_rules` — contract semantics, lifecycle, call guides, failure modes - `events_subscribe` — SSE stream of new on-chain intent events All endpoints are serverless (Vercel) and return their schema on GET. No browser, no wallet UI required for an agent to integrate. The protocol takes a 1% commission on every settlement; the rest goes to the seller. The full AgentCard is at `/.well-known/agent-card.json` (A2A-compatible). The OpenAPI 3.0.3 spec is at `/.well-known/openapi.json` with `components.securitySchemes` (none, hmacX402). `robots.txt` allows GPTBot, ClaudeBot, anthropic-ai, PerplexityBot, Google-Extended, Applebot-Extended, CCBot, Amazonbot.

7 hours ago
Bring your real authenticated browser session to AI coding agents. Local-first MCP server + Chrome MV3 extension. No cloud. No telemetry.
@Cubenest

peek records the user's actual logged-in browser (DOM via rrweb, console events, network metadata, optional response bodies via opt-in Deep capture) through a Chrome MV3 extension. The extension ships events through a native-messaging stdio bridge to a local MCP server (peek-mcp), which persists them to a SQLite database at ~/.peek/sessions.db. AI coding agents (Claude Code, Cursor, Cline, Windsurf) read sessions from the database via 10 MCP tools: Tool What it does list_recent_sessions List recently recorded sessions (id, origin, ts, event count). get_session_summary LLM-readable narrative summary of a session. get_session_console_errors Console errors recorded in a session. get_session_network_errors Failed/notable network requests in a session. get_user_action_before_error Last N user actions before a console error. generate_playwright_repro Generate a runnable Playwright test from a session. get_dom_snapshot Reconstruct the DOM at a given timestamp. query_dom_history Timeline of attribute/text changes for a selector. request_authorization Side-panel consent for write actions (Level 3). execute_action Dispatch a UI action (gated by permission level + destructive blocklist). Why local-first matters Every other "browser session for AI" tool ships to a vendor cloud. peek's SQLite + extension live on the user's machine — no remote endpoints, no telemetry. The privacy policy (docs/peek/PRIVACY_POLICY.md) is the source of truth. Install # 1. Add the MCP server to Claude Code claude mcp add peek -- npx -y @peekdev/mcp # 2. Install the Chrome extension from the Chrome Web Store # (link added once the CWS listing is approved)

a day ago