Skip to main content
Glama

Server Details

Buying-intent judgement for AI agents: a three-judge panel scores any text as buyer or not.

Ownership verified
Status
Healthy
Uptime
100.0% over the last 24 hours
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
Repository
AbYousef739/signalpipe
GitHub Stars
0
Server Listing
SignalPipe
ChatGPT
–
Claude
–

TDQS

A4.1/5.0

Scored across 24 tools

Disambiguation4/5

Most tools target clearly distinct entities (products, stations, missions, prospects) with distinct actions, and the descriptions do real disambiguation work (reject_mission vs delete_mission, mark_sent vs approve_mission). The weak spot is the outreach-writing cluster: draft_mission vs get_message_prompt vs score_signal all return drafting context, and approve_mission is explicitly documented as overlapping with mark_sent, which could cause misselection by a hurried agent.

Naming Consistency5/5

Every tool is snake_case, verb-first, and noun-second: add_product, update_station, get_missions, record_reply, reject_mission, etc. The verb vocabulary (add/get/list/update/remove/preview/record) is used predictably across the product, station, mission and prospect families, so intent is readable from the name alone.

Tool Count4/5

24 tools is on the heavy side, but the surface maps onto four genuinely distinct resource families (products, stations, missions, prospects) with real lifecycle steps, so most tools earn their place. A few are thin, notably reload_products (a cache-refresh that could be folded into add_product/update_product) and the five-way mission action split.

Completeness4/5

Coverage is strong: full CRUD-ish lifecycle for products (paused, never deleted, by design), stations, missions and prospects, plus preview, on-demand scouting and arbitrary-text scoring. Minor gaps are a lack of per-mission or per-prospect retrieval outside list payloads (get_missions/get_pipeline) and no outcome/analytics readout of what the RL loop has learned.

Publisher details

Operator
SignalPipe · Publisher source
Operator website
https://signalpipe.io
Vendor relationship
First-party · Publisher source
Trust center
Not available
Restrictions
Needs a paid SignalPipe plan. Connect with OAuth by pasting your operator key when asked, or send the key as a Bearer token. · Publisher source

Available Tools

24 tools
add_productAInspect

Register a new product to monitor for buying signals.

Call `suggest_anchors` FIRST and get the user's approval on the anchors —
do not invent them silently. Then `reload_products` to activate.

`anchor_sentences` (required, 3+, each 5-40 words) is the most important
field in the system: every incoming post is scored by similarity to these.
Write them as the BUYER describing their PROBLEM, not as the seller
describing the product:
  GOOD  "looking for an alternative to X, the pricing has gotten absurd"
  GOOD  "anyone know a tool that does Y? doing it by hand is killing me"
  BAD   "enterprise-grade Y automation platform"   <- matches sellers, not buyers

`target_audience` and `value_prop` — describe ONE buyer, narrowly: who they
are and the problem they would write about. The judges read both fields when
deciding whether a post's author is a buyer, so a broad audience (a list of
groups, "any operator") makes them keep weak leads. If the product has
clearly different buyers, add each as its own product.

`buy_signal_keywords` — LEAVE THIS EMPTY unless you have a specific reason.
It is an optional COST filter, not a quality one, and it is an AND-gate: a
post matching NONE of the keywords scores 0 before embedding, before the
swarm, with nothing logged. For example, the same sentence scored 0 when it
said "people" and highly when it said "leads" — one word. Nobody can list
every phrasing a buyer might use, so a keyword list silently deletes real
buyers in proportion to how badly you guessed.
The embedding floor, vertical gate and 3-judge swarm still filter without it.

`competitor_keywords` — direct SUBSTITUTES only (tools a buyer would pick
INSTEAD of this product). A buyer-intent mention of one floors the score so
switchers always surface. Do not list adjacent-category tools that merely
sound similar; you will surface people who were never in your market.

Inputs: name (required), anchor_sentences (required), value_prop, description, +3 more.

add_stationAInspect

Add a feed for a product to monitor. Add 3-5; station CHOICE decides results.

Valid `platform`: `rss`, `hn`, `reddit`, `twitter_search` (the last only
routes outreach to X — it does NOT monitor X; X has no feed to read).

URL patterns:
  HN:      https://hnrss.org/newest?q=KEYWORDS
  Forum:   https://FORUM/latest.rss
  Q&A:     https://softwarerecs.stackexchange.com/feeds/tag/TAG

Reddit ends its RSS feeds on 13 November 2026: do not suggest Reddit feeds.
From that date they are refused, and existing ones return nothing.

Prefer a newest-first listing over a front page or hot listing: scoring
rewards recency heavily, and the first helpful reply is the one that gets read.

CHOOSING STATIONS — this matters more than any setting:
  * Prefer BROAD communities where buyers describe PROBLEMS, over narrow
    keyword or tool-name searches. Broad community feeds consistently
    produce the overwhelming majority of real leads; narrow keyword-search
    feeds frequently produce none at all.
  * Go where your buyer complains, not where your industry talks shop.
    Vendor/founder communities are dense with people BUILDING things like
    yours (correctly filtered out as sellers) and thin on buyers.
  * 3-5 well-chosen feeds beat 20. Every feed costs a fetch each cycle and
    sources rate-limit; more stations mainly buys you more noise.
  * Ask the user where their customers actually hang out and complain. They
    know; a guessed subreddit list is the most common cause of an empty queue.

Inputs: name (required), platform (required), product_id (required), keyword, +1 more.

approve_missionA
Idempotent
Inspect

Approve a mission and queue it for outreach. Teaches the RL loop.

Approval is the operator's signal that this lead is worth pursuing.
Today (manual outreach phase) it doubles as the "I have replied or am
about to" confirmation — so approve also rewards the source feed,
treating the mission as a positive outcome (`replied`). When the
sidecar is wired for autonomous Reddit/Twitter sending, outcome
tracking will move to a separate feedback step and approval will only
mean "queue for outreach".

Pass `edited_draft` if the operator edited the wording — otherwise
the existing draft is used unchanged.

Inputs: mission_id (required), edited_draft.

delete_missionA
DestructiveIdempotent
Inspect

Hard-delete a mission from the queue — silent cleanup only.

Use this only when you want to clear the row without teaching the system
anything: duplicates, accidental scrapes, leads the operator doesn't
want surfaced again but doesn't have an opinion on.

Canonical case: the post is gone by the time you get there — deleted
by the poster, 404'd, removed by mods, or stale beyond your reply
window. The lead wasn't wrong, the opportunity just evaporated.
`delete_mission` is the right tool because there's nothing to learn
from the station — its `rl_weight` stays untouched. Using
`reject_mission` here would unfairly penalise a station for an event
it didn't cause.

When to use this vs `reject_mission`:
    - `delete_mission`: queue cleanup, no learning. The scoring weight
      for the source feed is untouched. Canonical uses: post deleted,
      duplicates, accidental scrapes.
    - `reject_mission`: the lead was a bad signal and you want the
      system to learn from it. Always prefer this when you have any
      opinion on WHY the lead was wrong — the RL loop can only sharpen
      if you give it the rejection reason.

Default: if a lead looks like noise but you can categorise WHY (spam,
not relevant, too vague, etc.), reach for `reject_mission` first.

Inputs: mission_id (required).

draft_missionAInspect

Get the drafting payload for a single mission so you can write the reply.

This is a working payload, not a display payload — it intentionally
contains the product positioning, lead text, scoring breakdown, and
response schema your draft must follow. Use it to write the draft;
do NOT dump the full payload back to the user.

Workflow:
    1. Call this with the mission_id.
    2. Compose a reply that fits the role/tone in `context.strategy`.
    3. Call `upload_draft(mission_id, draft, reasoning)` with your draft.
    4. If the lead is clearly not a buying signal, skip drafting and
       call `reject_mission(mission_id, rejection_reason)` instead.

Inputs: mission_id (required).

get_message_promptA
Read-onlyIdempotent
Inspect

Get the drafting payload for the next outreach message to a prospect.

This is a working payload, not a display payload — it contains the
full system prompt, recent conversation history, persona voice, and
response schema. Use it to write the message; do NOT dump the prompt
or conversation history back to the user.

Workflow:
    1. Call this with the prospect_id.
    2. Compose a message that fits the persona and follows the schema.
    3. Call `record_message(prospect_id, message, tactic, next_step)`.

Daily send cap is enforced — record_message will return a cap-hit
error if exceeded for the day.

Inputs: prospect_id (required).

get_missionsA
Read-onlyIdempotent
Inspect

List pending lead missions awaiting review.

Each mission includes: id, score, channel, lead snippet, prospect handle,
role (closer/advisor/educator), and the drafted reply if any.

Presentation: format the response as a numbered list inline. For each
mission show score, role, handle, snippet, and draft. Do NOT run shell
commands or write files to inspect this response — the data is already
structured. Read each mission directly from the JSON.

Inputs: sort_by, include_context.

get_pipelineA
Read-onlyIdempotent
Inspect

List the prospect pipeline sorted hottest-first.

Each prospect includes: id, handle, channel, temperature (0–100),
mode, last_signal, last_contact, and any recorded objections.

Modes (intent-based, not pure temperature):
  - nurture  — first-touch / no engagement yet. Educator persona,
               value-first messaging. Default for newly tracked
               prospects, regardless of starting temperature.
  - sales    — prospect has engaged (replied, clicked, asked).
               Consultant persona, qualify and build trust.
  - closing  — temperature ≥ 75 from sustained engagement. Closer
               persona, push for the concrete next step.
  - recovery — previously engaged and now cooled, OR explicit
               cooling signal (ghosted_*, not_interested, bad_timing).
               Re-engager persona, low-pressure re-open.
  - dead     — asked not to be contacted (a reply that opted out, or the
               opted_out signal). Never message them again;
               get_message_prompt refuses. Counted as do_not_contact.

Presentation: lead with the summary counts, then list the top
prospects as a numbered list with handle, temperature, mode, and
last signal. Do NOT introspect this response with shell commands —
the data is already structured and ready to summarise inline.

Inputs: no named parameters.

get_productsA
Read-onlyIdempotent
Inspect

List configured products being monitored for buying signals.

Each product includes: id, name, value_prop, target_audience, is_active,
created_at.

Presentation: list each product on its own line with name, status
(active/inactive), and a one-line value prop. Do NOT dump the raw
JSON — summarise inline.

Inputs: no named parameters.

list_stationsA
Read-onlyIdempotent
Inspect

List your stations (feeds) with a health readout for the last two weeks.

Each station: id, name, platform, rss_url, read_by (server = SignalPipe
reads it, client = your plugin or daemon reads it), active, posts captured,
how many reached your queue, empty or rate-limited fetches, and a
plain-language verdict (for example "Posts are arriving but none matched
your product: change the anchor sentences").

Presentation: one line per station with name, active or paused, and the
verdict. Use the ids with update_station / remove_station.

Inputs: product_id.

mark_sentA
Idempotent
Inspect

Mark a mission as sent by hand — "I already messaged this person myself."

Use this when YOU sent the outreach manually (via the Reddit/X UI, a
public comment, or a DM) instead of letting an autonomous sender do it.
Many leads are surfaced on the `manual` channel precisely so the operator
reviews and sends them personally — and first contact is often a public
reply rather than a DM. Without telling the system the send happened, the
mission sits unfinished, no prospect is created, and a later follow-up
draft has no record of what you already said.

What this does:
    - marks the mission as sent,
    - records the outreach so follow-up drafts know the conversation
      history (creates/updates the prospect and starts its lifecycle),
    - counts as a positive endorsement for the source feed (same learning
      signal as `approve_mission`).

When to use this vs the others:
    - `mark_sent`: you sent it yourself, by hand. Records the send +
      starts the prospect. Use this the moment you've actually messaged
      or replied to the person.
    - `approve_mission`: queue it for an autonomous sender to deliver
      (you are NOT sending it yourself right now).
    - `reject_mission` / `delete_mission`: you are NOT reaching out.

Idempotent: if you already called `approve_mission` on this lead, calling
`mark_sent` afterwards will not double-count anything — it just records
the actual send.

Inputs: mission_id (required).

preview_stationAInspect

Check whether a feed has buyers for a product BEFORE adding it as a station.

Which communities you listen to decides results more than any setting, and
a feed full of people talking about your topic can still contain no one
asking to buy. This reads the feed, scores its fresh posts and has the panel
judge the best-matching ones (default 8, one judgement each). Nothing is
saved.

Pass `rss_url`, or `entries` (up to 50 {link, title, summary, author,
published}) that you fetched yourself. Feeds read on the operator's own
machine (read_by: client) must be sent as entries.

Returns a verdict fixed by pre-set thresholds: VIABLE (worth adding),
MARGINAL (a trickle), ON-TOPIC, NOT IN-MARKET (topic talk, no buyers: a
different community will do better), NO BUYERS, or NO DATA (nothing could
be judged; the explanation says why, such as an empty or stale feed or
keywords that blocked every post). Plus a sample of judged posts, each kept
or rejected with the judges' stances.

Presentation: lead with the verdict and its one-line explanation, then how
many of the judged posts were kept. Only suggest add_station for VIABLE or
MARGINAL.

Inputs: product_id (required), sample, entries, rss_url.

record_messageAInspect

Record a message you drafted as sent to the prospect.

Use after `get_message_prompt`. Daily send cap still applies.

Inputs: message (required), prospect_id (required), tactic, next_step.

record_replyAInspect

Record what a prospect wrote back, and let the brain read it.

Call this whenever a tracked prospect replies (a comment reply, a DM, an
email). The brain reads the reply and updates their temperature, mode and
objections, and returns:
  - intent: buy / interested / objection / not_now / unsubscribe / neutral ...
  - mode: the prospect's new stage (nurture / sales / closing / recovery / dead)
  - do_not_contact: true when they asked not to be contacted. Stop: never
    message them again (get_message_prompt will refuse).
  - invites_private_contact: true only when THIS reply explicitly asks to
    continue in private ("DM me"). Reddit and X require that consent before
    an app sends a private message, so never suggest a DM without it.

Presentation: tell the operator the intent, the new mode, and any new
objection in one line. If do_not_contact is true, say so plainly.

Inputs: reply_text (required), prospect_id (required), channel.

reject_missionAInspect

Reject a mission — it was not a real buying signal.

Use this when you want the system to LEARN from the rejection. Each
reason maps to a different RL penalty applied to the source feed's
scoring weight, so the swarm gets smarter about that product's leads
over time.

When to use this vs `delete_mission`:
    - `reject_mission`: the lead was a bad signal — feed it back so the
      scoring weight adjusts. Always prefer this when you have any
      opinion on why the lead was wrong.
    - `delete_mission`: queue cleanup only (duplicates, stale leads,
      things you don't want to teach the system about). NO learning.

DON'T use `reject_mission` when the post is gone (deleted by the
poster, 404'd, removed by mods, or stale beyond your reply window).
The lead wasn't bad — it just disappeared. Use `delete_mission`
instead, which leaves the source station's `rl_weight` untouched.
Reaching for `reject_mission(not_relevant)` here penalises a station
that did nothing wrong.

Valid `rejection_reason` values:
    - `spam`             — bot/promoted/automated post (heaviest penalty)
    - `not_relevant`     — wrong audience or topic
    - `wrong_product`    — relevant signal but wrong product matched it
    - `too_vague`        — signal too weak to act on
    - `sarcasm`          — venting/ironic, not a real buyer
    - `already_customer` — they already bought (no penalty)
    - `no_reason`        — default if you don't have a strong opinion

Pick the most accurate reason — they apply different penalty sizes,
so accuracy directly improves how the system learns.

Inputs: mission_id (required), rejection_reason.

reload_productsA
Idempotent
Inspect

Reload the product cache after adding or editing products.

Inputs: no named parameters.

remove_stationA
DestructiveIdempotent
Inspect

Remove a station. Confirm with the operator first.

A station that never produced a lead is deleted. One that already produced
leads is switched off instead, to keep that history; the reply says which
("deleted", or "paused" with reason "has_history").

Inputs: station_id (required).

score_signalAInspect

Score arbitrary text for buying-intent / competitor-mention / churn / noise.

Use this when your agent encounters content from any channel it has
access to — email, Slack, Discord, Telegram, LinkedIn, WhatsApp, a
YouTube comment, a blog post — and you want to know whether it's a
real signal worth acting on, before drafting a reply.

SignalPipe doesn't connect to the source channel. Your agent reads
the text (via whatever plugin gives it that access) and passes the
text here. We run the same scoring engine the scout uses on Reddit
and HN: keyword gate, multilingual semantic scoring (EN/ES/FR/DE/PT/FI),
3-judge swarm pattern, sarcasm detection, and competitor-intent
classification.

Returns: score (0-100), role (closer/advisor/educator), classification
(buying_intent / competitor_mention / borderline / noise), sub-scores
(urgency, specificity, keyword_density), competitor info if matched,
and a `drafting_context` block when the score is high enough to act
on.

When the borderline band triggers a panel review you also get
`swarm_ran: true` and a `swarm` block: each judge's stance
("convinced" / "on the fence" / "unconvinced") and `split: true` when
they disagreed materially. A split panel is worth flagging to the
operator — it usually means the post is genuinely ambiguous rather
than clearly a lead or clearly noise. You write the reply yourself using the context — same pattern as
`draft_mission`, no server-side LLM call required.

⚠️ CHECK `degraded` BEFORE YOU TRUST A LOW SCORE. There is a per-tenant
daily budget for panel reviews. `degraded: true` means this text WAS
borderline but the panel did not get to judge it — either the budget ran
out (`swarm_skipped: "daily_cap_reached"`) or the panel errored
(`"panel_failed"`). The score you are holding is the content-only score,
which is exactly the score the panel exists to correct: it under-reads
real buyers as `noise`. Do NOT tell the operator a `degraded` post is not
a lead. Say the verdict is provisional and offer to re-score it later.

`degraded: false` with `swarm_skipped: "not_borderline"` is the normal,
healthy case — the text was clear-cut and did not need a panel. That
verdict is trustworthy.

`swarm_budget_remaining` tells you how many panel reviews are left today.
If you are scoring in bulk, watch it and pace yourself rather than
spending the budget on obvious noise.

`panel_verdict` says what the judges concluded: "kept", "rejected", or
"not_run". The judges can raise a score but never lower it, so a post they
rejected can still read "borderline". Treat `panel_verdict: "rejected"` as
not a lead, whatever the score.

Scoring a reply or comment? Pass the post or thread it answers as
`context`. The judges see it as background, and the score stays about the
reply's own author.

Presentation: if classification is `buying_intent` or
`competitor_mention`, surface the lead to the operator with score,
role, classification, and the drafting context. If classification is
`noise` or `borderline`, mention it briefly so the operator knows you
looked but don't bother them with a draft.

Inputs: text (required), product_id (required), context, source_hint.

scout_nowAInspect

Trigger an on-demand scouting run across YOUR active products.

Scouts run automatically every 30 minutes. Use this when the operator wants
a fresh scan now. At most one on-demand scan per tenant every 15 minutes;
returns status "skipped" with a reason (cooldown / batch_in_progress) when
a scan is not started.

Inputs: no named parameters.

suggest_anchorsA
Read-only
Inspect

Generate candidate anchor sentences for a product. CALL THIS BEFORE add_product.

Anchors are the single highest-leverage field in the whole system — they
are what every incoming post is compared against, so they decide what the
user does and doesn't get shown. Writing them well is hard and most people
write marketing copy by mistake, so use this and then let the user edit.

Recommended setup flow:
  1. Ask the user three things: what the product is, who buys it, and what
     it does for them.
  2. Call this tool.
  3. SHOW the returned anchors to the user and invite edits — they know
     their buyers' words better than any model does.
  4. Call `add_product` with the approved list, then `reload_products`.

A good anchor is the BUYER speaking about their PROBLEM, moments before
they'd want this product ("my stream background is just a static image and
looks boring", "we're paying for seats nobody uses"). A bad anchor is the
seller describing the product ("premium audio-reactive visual engine").
Product-voice anchors match other sellers; buyer-voice anchors match buyers.

Returns: {"anchors": [str, ...]}

Inputs: name (required), value_prop (required), count, description, +1 more.

track_prospectAInspect

Log a signal from a prospect and update their temperature.

`signal` examples: booked_demo, asked_pricing, viewed_content, replied,
not_interested, too_expensive, no_time, competitor, ghosted_3_days,
ghosted_7_days, opted_out (they asked not to be contacted: ends the
relationship). Creates the prospect if new.

When you have the prospect's actual reply text, use `record_reply`
instead: it reads the reply and updates temperature, mode, objections and
do-not-contact for you.

Inputs: handle (required), signal (required), channel (required), mission_id, +1 more.

update_productA
Idempotent
Inspect

Edit a product, or pause and resume it. Only the fields you pass change.

anchor_sentences follow the add_product rules (3+, each 5-40 words, the
BUYER describing their problem); the previous set is kept so a bad edit can
be undone. active=false pauses the product: its stations stop being read and
score_signal stops accepting it until you set active=true. Products are
paused, never deleted, so their history stays.

Confirm with the operator before changing anchors or pausing.

Inputs: product_id (required), name, active, value_prop, +5 more.

update_stationA
Idempotent
Inspect

Pause, resume, rename or re-point a station. Only the fields you pass change.

Get station ids from list_stations. A new rss_url is checked (http or https,
a public host) before it is saved.

Inputs: station_id (required), name, active, keyword, +1 more.

upload_draftA
Idempotent
Inspect

Upload a reply draft you wrote for a mission.

The mission moves to pending_approval and surfaces for the operator to
approve or edit. `reasoning` is optional, one-sentence justification for
the audit log.

Inputs: draft (required), mission_id (required), reasoning.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    Try in Browser

    Glama MCP Gateway

    Add one secure layer between your agents and this server.