Skip to main content
Glama

revloop

A shared context store for GTM teams and their AI agents, with outcome measurement built in.

CI License: MIT Python 3.12 MCP


Your CRM says the deal is in negotiation. The call from Tuesday says it is dead. Your agent just wrote a follow-up based on the CRM.

What a team knows about a deal sits in calls, emails, and the CRM, and it changes every week. An agent drafting from last month's context writes the wrong email. Separately, teams are adding agents that propose follow-ups without checking whether those follow-ups changed anything.

revloop handles both halves: one current view of each account where every fact carries its source, and a comparison that shows whether approved actions moved pipeline.

See it

Three sources disagree about Northwind Robotics. revloop keeps the newest and records the rest:

$ revloop context "Northwind Robotics" --history

next_step   Send security questionnaire responses by Friday
            emails/2026-09-15-northwind-robotics.eml:12   2026-09-15
  superseded  Legal review of the MSA
              crm/salesforce-opportunities.csv:3          2026-09-10
  superseded  Loop in their CISO for the security review
              calls/2026-09-08-northwind-robotics.txt:24  2026-09-08

stage       negotiation      crm/salesforce-opportunities.csv:3
competitor  Vantage          calls/2026-09-08-northwind-robotics.txt:18
pain        Manual reconciliation eats two days a month
objection   Procurement needs SOC 2 before signing

Every fact carries the file and line it came from, so an agent reading this can cite its source.

Later, once the deals have had time to move:

$ revloop report

Share of matched accounts that advanced stage within 30 days of the match

stalled-deal
  approved action : 1/1 advanced (100%)
  holdout         : 0/1 advanced (0%)
  uplift          : not enough data (need >= 10 accounts per group)

Not a randomised test: a human chose which actions to approve, so selection bias is likely.

Related MCP server: Volterra Knowledge Engine

Who this is for

  • You are wiring agents into a GTM stack and want them reading something better than a stale CRM field.

  • You have agents proposing follow-ups and no way to tell whether they help.

  • You want the context layer on your own machine, in SQLite, in files you can read.

Not for you if you want lead enrichment or an outbound sender. revloop does neither.

What it does

Extract

Call transcripts, .eml emails, and CRM CSVs become structured facts: pain, objection, competitor, next_step, stakeholder, stage, amount. HubSpot and Salesforce column names are both recognised. Offline rules by default, Claude with schema-constrained JSON when you want it.

Remember

SQLite. A newer stage, amount, or next_step supersedes the old one, so the current view stays current and the old fact is kept as history. Pains, objections, competitors, and stakeholders accumulate and dedupe.

Propose

YAML playbooks match conditions over the store and fill templates from real facts. Actions are only proposed. A person approves them, and revloop does not send anything.

Measure

Import later CRM stage snapshots. Per playbook, accounts with an approved action are compared against accounts that matched the same trigger and got none.

Serve

An MCP server exposes the store to Claude Code, Cursor, or any MCP client through five tools.

Quickstart

Needs uv and Python 3.12. The --now flags pin the date so the fictional sample data gives the same answer whenever you run it.

uv sync
uv run revloop init
uv run revloop ingest examples/artifacts
uv run revloop context "Northwind Robotics" --history

uv run revloop run stalled-deal --now 2026-09-30
uv run revloop run competitor-mentioned --now 2026-09-30
uv run revloop actions

uv run revloop approve 1    # re-engagement email for Acme Freight
uv run revloop reject 2     # Harbor Health has no call or email facts, so the draft is empty
uv run revloop approve 3    # CRM note about the competitor at Northwind Robotics

uv run revloop outcomes import examples/outcomes.csv
uv run revloop report --now 2026-11-01

Every command takes --db PATH (default ./revloop.db). Tests: uv run pytest.

Use it from an agent

claude mcp add revloop -- uv run --directory /path/to/revloop revloop --db /path/to/revloop/revloop.db mcp

Or in a project .mcp.json:

{
  "mcpServers": {
    "revloop": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/revloop", "revloop", "--db", "/path/to/revloop/revloop.db", "mcp"]
    }
  }
}

Tools: get_account_context, search_facts, propose_action, list_pending_actions, outcome_report.

propose_action records a proposal with status proposed. A person still runs revloop approve <id>, so an agent cannot approve its own work.

Architecture

flowchart LR
    T[Call transcripts .txt] --> X
    E[Emails .eml] --> X
    C[CRM export .csv] --> M
    X{Extractor<br/>rules or LLM} --> M[(SQLite store<br/>accounts, facts,<br/>actions, outcomes)]
    M --> P[Playbooks YAML]
    P -->|proposed actions| H[Human: approve / reject]
    H --> M
    S[Later CRM stage snapshots] --> M
    M --> R[Outcome report<br/>approved vs holdout]
    M <--> MCP[MCP server] <--> A[Agents: Claude Code, Cursor]

Module

Role

facts.py

Fact model, kinds, stage normalisation

extract.py

Transcript, email, and CRM parsing; rule-based extractor

llm.py

Optional Claude extractor with JSON schema output

store.py

SQLite schema, supersede and dedupe logic

playbooks.py

YAML loading, trigger evaluation, template rendering

outcomes.py

Snapshot import, approved vs holdout comparison

server.py

MCP tools

cli.py

revloop command

894 lines of source, 36 tests, two dependencies. It runs locally and there is no service to sign up for.

Writing a playbook

name: stalled-deal
description: A late-stage deal has gone quiet.
trigger:
  stage_in: [proposal, negotiation]   # current stage is one of these
  no_new_facts_days: 21               # no fact of any kind in the last 21 days
  # has_kind: [competitor]            # every listed kind has at least one current fact
actions:
  - type: email_draft
    template: |
      Hi {stakeholder}, you mentioned "{pain}" and raised "{objection}".

All trigger conditions must hold. Templates take {account} and any fact kind. Each placeholder gets the most recent current value, or (none recorded) if there is none, so a reviewer sees the gap rather than an invented detail. A playbook handles each account once.

Stages normalise to prospecting, qualification, discovery, demo, proposal, negotiation, closed_won, with common HubSpot and Salesforce names mapped on (contractsent and Negotiation/Review both become negotiation).

How the measurement works

  • When a playbook matches an account, revloop records the match time and the stage at that moment.

  • An account advanced if any imported snapshot within the window (default 30 days, --window) shows a later stage. closed_lost never counts.

  • Approved group: matches where at least one action was approved. Holdout group: matches where nothing was approved, whether rejected or never reviewed.

  • Matches whose window is still open, or whose starting stage is unknown, are excluded and counted separately.

  • With at least 10 accounts per group it prints the uplift and a pooled two-proportion z-test. Below that it says there is not enough data.

Limits

  • This is not a controlled experiment. People choose what to approve, and they tend to approve actions for deals that already look healthy. Treat uplift as a signal to investigate, not proof. A proper test randomly holds out some matches before review.

  • The rule extractor is keyword matching. It is predictable and testable, but it misses paraphrases and produces false positives: any capitalised name after "evaluating" is read as a competitor. The LLM extractor reads text better and is not deterministic.

  • A playbook handles each account once, so an account that stalls a second time is not proposed again.

  • No enrichment and no sending. revloop does not find leads, enrich records, or deliver messages. Pair it with whatever you use to start conversations.

  • Timestamps are taken on trust. If your CRM dates are wrong, the report is wrong.

License

MIT. See LICENSE.

Available Tools

5 tools
get_account_contextB

Current facts (stage, amount, pains, objections, competitors, ...) for one account, with sources.

NameRequiredDescriptionDefault
accountYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full behavioral burden. It does disclose useful context that results are 'current' facts and include sources, but it does not explain account-matching behavior, error handling, or response structure beyond the field examples.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no wasted words. The field examples are compact and immediately clarify what 'facts' means.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations, no output schema, and 0% parameter description coverage, the description needs to compensate but does not. It omits account identifier semantics, usage relative to search_facts, and return-shape details, leaving important gaps for a retrieval tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter is 'account', and schema description coverage is 0%. The description confirms the tool operates on one account but adds no identifier format, matching rules, or other meaning beyond the bare schema property name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource: current facts for one account, including example fields and source provenance. It is clearly distinguishable from a general search tool by the 'one account' scope, though it does not explicitly name or contrast with the sibling search_facts tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit when-to-use guidance, prerequisites, or exclusions. With a sibling named search_facts, an agent must infer whether to call this account-scoped tool or the search tool, and the description does not help make that choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pending_actionsB

Actions waiting for human approval.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden and discloses almost nothing: not that this is a read-only operation, not whether it returns all pending items or a page, not whose actions are visible. The only behavioral fact conveyed is the approval-waiting filter, which already follows from the name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short fragment with zero filler, front-loaded and unambiguous. It is arguably too terse rather than too long, but nothing in it is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and an output schema present, return-value detail is legitimately out of scope. Still, for a queue-inspection tool with no annotations, the description should note that it is a safe read and how it relates to propose_action/outcome_report; as written it is minimally usable but incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to elaborate on. Baseline 4 applies; no parameter-related gap exists.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The phrase 'Actions waiting for human approval' defines the resource precisely and disambiguates what 'pending' means, which the bare name 'list_pending_actions' does not. It is clear but never differentiates itself from siblings such as propose_action, which is what generates these pending items.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to call this versus propose_action or outcome_report, and no mention of prerequisites, polling cadence, or after-approval follow-up. The agent must infer that this is a read of the approval queue from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outcome_reportC

Per playbook: share of accounts that advanced stage with an approved action vs a holdout.

NameRequiredDescriptionDefault
window_daysNo

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It reveals that the metric compares approved actions against a holdout, but does not state whether the operation is read-only, what permissions are needed, how the holdout is defined, or how fresh the data is.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single efficient sentence with no filler. It is front-loaded with the metric definition, though the vague 'Per playbook' prefix is less useful than the concrete comparison that follows.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values do not need full explanation. However, the description leaves the sole input parameter undocumented, provides no usage context, and does not clarify key behavioral aspects like data freshness or what constitutes an approved action versus a holdout.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter, window_days, has 0% schema description coverage and is never mentioned in the description. Its name is somewhat self-explanatory, but the description adds no meaning about what the window controls or how the default of 30 days is used.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific metric: the share of accounts that advanced stage with an approved action versus a holdout. This is distinguishable from sibling tools like propose_action or search_facts. However, it lacks a clear verb such as 'compute' or 'generate' and the 'Per playbook' prefix is vague jargon.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance on when to use this tool, when not to use it, or which sibling it replaces. 'Per playbook' implies some context but does not tell the agent how to decide between this report and alternatives like list_pending_actions or get_account_context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

propose_actionB

Propose an action (e.g. kind 'email_draft', 'crm_note', 'task'). Nothing is sent; a human approves.

NameRequiredDescriptionDefault
bodyYes
kindYes
accountYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose the single most important trait: nothing is sent and a human approves. It says nothing about whether the account must exist, what a proposal returns (an id? a pending record?), idempotency, or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short clauses, no filler, with the human-approval caveat front-loaded where it matters most for agent behavior. It is arguably too terse given the undocumented parameters, but nothing in it is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation-style tool with no annotations, no output schema, and three fully undocumented required parameters, the description leaves too much open — notably what a 'proposal' produces and how it relates to list_pending_actions. Only the safety framing is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% with three required free-form string params. The description only illuminates 'kind' via examples; 'account' (what identifier format?) and 'body' (what content/structure?) remain completely undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (propose) and resource (an action), and the examples of 'kind' values ('email_draft', 'crm_note', 'task') make the scope concrete. It does not explicitly contrast with siblings like list_pending_actions, though the approval framing implies where proposals end up.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Nothing is sent; a human approves' implies this is the pre-approval staging step rather than a direct send, which is useful context. However, no alternative tool is named and no conditions for choosing this over outcome_report or another sibling are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_factsA

Search current facts by text across all accounts. Optional kind filter, e.g. 'competitor'.

NameRequiredDescriptionDefault
kindNo
queryYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose one real trait: results are limited to "current" facts, implying stale/superseded facts are excluded. It says nothing about matching semantics (substring vs exact, case sensitivity), result caps or ranking, or required permissions — meaningful gaps for a search tool with zero annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and scope, then the optional filter. Every clause carries information; nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and both parameters are addressed. For a two-parameter search, the only missing pieces an agent would want are result limits/pagination and kind vocabulary, which are secondary.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does: it establishes that the required parameter is free text matched against fact content and that `kind` is an optional filter with an example value ('competitor'). It stops short of enumerating valid kind values or describing match behavior, which keeps it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ("Search current facts") plus the search field ("by text") and scope ("across all accounts"). Siblings (list_pending_actions, propose_action, get_account_context) are unrelated enough that no explicit differentiation is needed, so a 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: reach for this when you need to find facts matching text rather than pull account context or pending actions. There is no explicit when-not guidance, no mention of how this relates to get_account_context, and no statement about what to do if the query returns nothing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 5 tool updatesv0.1.0
    • First observedget_account_context
    • First observedlist_pending_actions
    • First observedoutcome_report
    • First observedpropose_action
    • First observedsearch_facts

TDQS

B3.2/5.0

Scored across 5 tools

Disambiguation4/5

list_pending_actions, propose_action, and outcome_report are clearly separated by purpose. get_account_context and search_facts both retrieve facts, but one is account-scoped and the other is cross-account text search, so the overlap is minor and descriptions help.

Naming Consistency4/5

All names use snake_case and most follow a verb_noun pattern (list_pending_actions, get_account_context, search_facts, propose_action). outcome_report breaks the pattern as a noun phrase, but the overall convention is still readable and mostly consistent.

Tool Count5/5

Five tools is well-scoped for a focused approval-loop server. Each tool covers a distinct part of the workflow: context lookup, fact search, action proposal, pending-action listing, and outcome reporting.

Completeness3/5

The set covers context retrieval, fact search, proposal, pending listing, and outcome reporting, but lacks approve/reject or action-detail operations. This leaves a notable gap in the approval lifecycle, even if human approval happens outside the MCP surface.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that provides database interaction capabilities through SQLite, enabling users to run SQL queries, analyze business data, and automatically generate business insight memos.
    19
    MIT
  • F
    license
    B
    quality
    D
    maintenance
    A Model Context Protocol server that provides database interaction and business intelligence capabilities through SQLite, enabling SQL queries, data analysis, and automatic generation of business insight memos.
    6
    -