Nexus AI News

Registre officiel Recherche et web

Deduplicated, classified AI industry news: search, browse, and filter by vertical and event type.

Installation

Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).

Remote (streamable-http)
Claude Code
claude mcp add --transport http nexus-ai-news 'https://nexus.carapace.bot/mcp'
Configuration JSON (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "nexus-ai-news": {
            "type": "http",
            "url": "https://nexus.carapace.bot/mcp"
        }
    }
}

Documentation

Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.

Sommaire
  1. Nexus
  2. Quick Start
  3. Monorepo Layout
  4. Adding a Source Adapter
  5. Jev Enrichment
  6. Chat Search
  7. MCP Server
  8. Data Model
  9. Contributing
  10. Environment Variables
  11. Tech Stack
  12. Cost
  13. License

Nexus

A Jev-powered AI news feed.

Nexus ingests AI news from multiple sources, dedupes it, classifies each item with a single Jev (TypeSafe System One) call, and serves the result as a reverse-chronological feed with filters and a guarded, extractive chat search. No graph database, no generative LLM in the request path.

Sources (arxiv, hackernews, github, twitter, rss)
   │
   ▼
dedup.ts (URL → title → arXiv-id → Jaccard + entity fingerprints)
   │
   ▼
PostgreSQL raw_items
   │
   ▼
Jev enrichment (TypeSafe System One, model jev-latest, 1 call/item)
   relevant? (Noul) · vertical (Choice) · event_type (Choice) · significance (Score)
   │
   ▼
PostgreSQL feed_items (reverse-chron, indexed)
   │
   ▼
Fastify API — GET /api/feed · GET /api/feed/meta · POST /api/chat
   │
   ▼
React feed client — ActivityFeed, FilterBar, HotCards, guarded ChatBox

Quick Start

# 1. Start infrastructure (PostgreSQL)
docker compose up -d

# 2. Install dependencies
pnpm install

# 3. Build all packages
pnpm build

# 4. Start API and client dev servers (separate terminals)
pnpm dev:api
pnpm dev:client

# 5. Run the agent (source polling + Jev enrichment) separately
pnpm --filter @nexus/agent start

The client opens at http://localhost:5173 and the API serves at http://localhost:3001.

Monorepo Layout

PackagePathDescription
@nexus/sharedpackages/sharedTypeScript interfaces, enums, constants, validation — imported by all packages
@nexus/agentpackages/agentSource adapters + dedup + Jev enrichment
@nexus/apipackages/apiFastify REST server for the feed and chat search
@nexus/clientpackages/clientReact feed UI (Vite)

Adding a Source Adapter

The primary contribution path is adding new data sources. Every adapter feeds raw items into the dedup + Jev enrichment pipeline, which classifies and inserts them into the feed automatically.

The RawItem Interface
// packages/agent/src/sources/types.ts
interface RawItem {
  source: string;        // adapter name, e.g. "arxiv"
  source_url: string;    // canonical URL for deduplication
  title: string;         // headline / paper title
  content: string;       // body text (Jev classifies, excerpt is sliced from here)
  published_at: string;  // ISO 8601 timestamp
  raw_metadata: Record<string, unknown>; // source-specific fields
}
Write Your Adapter

Extend BaseAdapter and implement fetchItems(). You get rate limiting, exponential retry with backoff, and URL-based deduplication for free.

// packages/agent/src/sources/my-source.ts
import type { RawItem } from "./types.js";
import { BaseAdapter } from "./base-adapter.js";

export class MySourceAdapter extends BaseAdapter {
  name = "my-source";
  priority = "P1" as const;

  constructor() {
    super({
      pollIntervalMs: 30 * 60 * 1000, // how often to poll
      rateLimitMs: 2000,               // min delay between requests
    });
  }

  protected async fetchItems(): Promise<RawItem[]> {
    const response = await fetch("https://api.example.com/items");
    if (!response.ok) throw new Error(`Fetch failed: ${response.status}`);

    const data = await response.json();
    return this.dedupeByUrl(
      data.map((item: any) => ({
        source: this.name,
        source_url: item.url,
        title: item.title,
        content: item.body,
        published_at: new Date(item.date).toISOString(),
        raw_metadata: { id: item.id },
      }))
    );
  }
}
Existing Adapters
AdapterSourcePriorityPoll IntervalAuth
ArxivAdapterarXiv RSS (cs.AI, cs.CL, cs.LG)P030 minNone
HackerNewsAdapterHN Algolia APIP015 minNone
GitHubTrendingAdapterGitHub Search APIP060 minOptional GITHUB_TOKEN
TwitterAdapterX/Twitter API v2P115 minX_BEARER_TOKEN required
RssAdapterCompany blogs, TechCrunch AI, The Verge AI, Simon WillisonP12h (default)None
Register Your Adapter
  1. Add your adapter to the adapter list in packages/agent/src/start.ts:
import { MySourceAdapter } from "./sources/my-source.js";

const adapters: SourceAdapter[] = [
  new HackerNewsAdapter(),
  new ArxivAdapter(),
  new GitHubTrendingAdapter(),
  new MySourceAdapter(),          // add here
];
  1. Write a test in packages/agent/src/sources/__tests__/ following existing patterns.
  2. Run tests: pnpm --filter @nexus/agent test

Jev Enrichment

Every deduped RawItem gets exactly one call to TypeSafe's System One API (POST https://api.typesafe.ai/v1/systemone, model jev-latest, Bearer TYPESAFE_API_KEY). Jev is a decision model — it answers typed questions (Noul, Choice, Score) against structured JSON, it does not generate text. One call answers all four questions for an item:

  • is_ai_relevant (Noul) — dropped if confidence < 0.6
  • vertical (Choice) — one of the 21 Vertical values, or none
  • event_type (Choice) — launch | funding | release | acquisition | paper | update | shutdown | other
  • significance (Score) — a 5-point rubric mapped to 0.2–1.0

The excerpt shown in the feed is the first 280 characters of the source content — never an LLM summary, so it can't hallucinate.

POST /api/chat is a guarded, extractive search box, not a chatbot. It classifies the query with one Jev call (on-topic check, vertical/event-type/timeframe extraction), then returns real rows from feed_items via Postgres trigram search. There is no generative model anywhere in the chat path — there's nothing for a prompt injection to talk to.

MCP Server

The feed is exposed to agents as a public, read-only Model Context Protocol server over Streamable HTTP:

https://nexus.carapace.bot/mcp
ToolWhat it does
search_newsFull-text search (phrases, OR, -exclude), filterable by vertical / event_type / source / since
get_latest_newsNewest items first, same filters, cursor-paginated via next_cursor
get_feed_statsTotal count plus counts per vertical and event_type

Add it to Claude Code with claude mcp add --transport http nexus https://nexus.carapace.bot/mcp. Stateless (no sessions), extractive only — same validation as GET /api/feed, no model calls. Registry manifest: server.json.

Data Model

feed_items

id (uuid) · title · url (unique) · source · published_at · excerpt · vertical · event_type · significance (0.0–1.0) · created_at

Verticals

21 spatial-cluster categories, defined in packages/shared/src/types.ts (e.g. foundation_models, agents, safety_alignment, consumer_products, ...).

Event Types

launch | funding | release | acquisition | paper | update | shutdown | other

Contributing

  1. Fork the repo and create a branch: feat/my-feature, fix/some-bug, or chore/cleanup
  2. Write conventional commit messages: feat: add devto adapter, fix: handle empty RSS feed
  3. Run checks before opening a PR:
pnpm test          # run all tests
pnpm lint          # eslint
pnpm typecheck     # tsc --noEmit
  1. Keep PRs focused — one adapter or feature per PR.

Environment Variables

VariableRequiredDefaultDescription
TYPESAFE_API_KEYYes—TypeSafe API key for Jev (System One) enrichment and chat classification
POSTGRES_HOSTNolocalhostPostgreSQL host
POSTGRES_PORTNo5432PostgreSQL port
POSTGRES_DBNonexusPostgreSQL database name
POSTGRES_USERNonexusPostgreSQL user
POSTGRES_PASSWORDYes—PostgreSQL password
X_BEARER_TOKENNo—X/Twitter API bearer token (enables Twitter adapter)
GITHUB_TOKENNo—GitHub PAT (raises rate limits for GitHub adapter)
API_KEYNo—API key for write/admin endpoints
API_PORTNo3001API server port
API_HOSTNo0.0.0.0API server bind address
CLIENT_PORTNo5173Client dev server port

Tech Stack

  • Database — PostgreSQL 16 (raw_items, feed_items, pg_trgm search)
  • API — Fastify
  • Client — Vite + React
  • Search — Fuse.js (client-side, loaded items), pg_trgm (server, chat + feed search)
  • Agent — TypeSafe Jev (System One) for enrichment and chat classification
  • Deploy — Railway (Postgres + API) + Vercel (client)

Cost

Enrichment is roughly 1 Jev call per new deduped item, at ~50–100 items/day across all sources, plus 1 Jev call per chat query. There is no Neo4j, no Redis, and no generative LLM anywhere in the pipeline — that's the entire compute bill.

License

MIT

Questions fréquentes

Qu'est-ce que Nexus AI News ?

Deduplicated, classified AI industry news: search, browse, and filter by vertical and event type.

Comment installer Nexus AI News ?

Il fonctionne comme serveur distant. Dans Claude Code : claude mcp add --transport http nexus-ai-news 'https://nexus.carapace.bot/mcp'. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.

Faut-il une clé API pour Nexus AI News ?

Son entrée au registre n'indique aucune clé ni secret obligatoire. Certaines fonctions peuvent tout de même demander un compte auprès du service auquel il se connecte.

Nexus AI News est-il open source ?

Oui. Son code est sur GitHub sous licence MIT.

Qui maintient Nexus AI News ?

Il est publié par 99darwin. AI.tn le référence sans le maintenir ni le recommander.

Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.