← All blueprints

Contract Redline LangGraph

blueprint · 4 agents · 3 MCP servers
1124★ stars
146forks
4.7rating

What it does

A reader opens the contract from the drive and extracts its clauses. A redliner proposes edits that move off-standard terms toward the company's negotiation playbook (read from disk), and a reviewer checks each edit against that playbook and flags residual risk. The two loop until the reviewer signs off or the round budget is reached. A risk memo is produced and the package pauses for a human lawyer to approve before it is shared. Replace the playbook file with your own standard positions.

The cast · 4 agents

Readerreaderfast

Open the contract and extract its clauses: label each by type (liability, term, indemnity, IP, payment, etc.) and capture its exact text. Do not judge yet.

docs.read_doc
Redlinerredlinerreasoning

Read the negotiation playbook from disk. Propose the minimal edits that bring off-standard clauses in line with it, quoting the exact replacement text. If you received a review, address every flag and try again. Never soften a position the playbook marks non-negotiable.

fs.read_file
Reviewerreviewerreasoning

Check the redline against the playbook. Flag any clause still off-standard, any edit that overreaches, and any risk a counterparty would reject. Return an object with a 'clean' boolean and specific notes. Sign off only when the redline is defensible and complete.

no tools · reasoning only
Memo WritermemoWriterfast

Write a short risk memo for the reviewing lawyer: what was changed, what still carries risk, and what to watch in negotiation. Post a pointer to the legal channel. Do not send anything to the counterparty.

chat.post_message

Flow

Readerclauses
↻ loop until review.clean == true · max 3
Redlinerdraft
Reviewerreview
Memo Writerredline
askredline

Interface

Inputs
contractRefstring
The contract to review, as a drive document id or path.
Outputs
redlinestring
The approved redline and risk memo, ready for a human to send.

Depends on · 3 MCP servers

Multi-account MCP for Gmail, Calendar, Drive, Docs, and Sheets — 61 tools, tokenio.github.adelaidasofia/google-workspace-mcpdocsAVerified
io.github.modelcontextprotocol/filesystemnot in the registry yetfs
io.github.slack/slack-mcpnot in the registry yetchat
⤓ Export runnable code
# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/contract-redline v1.0.0   schema: socketcat.dev/blueprint/v0
# This code is yours. Edit it freely. The socketcat_runtime helper is optional and can be vendored.

from typing import TypedDict
from langgraph.graph import StateGraph, START, END
import socketcat_runtime as _rt

class State(TypedDict, total=False):
    contractRef: object
    redline: object
    clauses: object
    __loop_1: object
    draft: object
    review: object

def node_AgentInvoke_0(state):
    return _rt.run_agent("reader", state, {"contractRef":"contractRef"}, "clauses")

def node_LoopHeader_1(state):
    return {}

def node_LoopTick_2(state):
    return {"__loop_1": state.get("__loop_1", 0) + 1}

def node_Nop_3(state):
    return {}

def node_AgentInvoke_4(state):
    return _rt.run_agent("redliner", state, {"review":"review","clauses":"clauses"}, "draft")

def node_AgentInvoke_5(state):
    return _rt.run_agent("reviewer", state, {"draft":"draft"}, "review")

def node_AgentInvoke_6(state):
    return _rt.run_agent("memoWriter", state, {"draft":"draft"}, "redline")

def node_Ask_7(state):
    return _rt.run_ask("Review the redline and risk memo. Approve to share with the counterparty, or send back with notes.", state, "redline")

def route_LoopHeader_1(state):
    count = state.get("__loop_1", 0)
    return "exit" if (_rt.cond("review.clean == true", state) or count >= 3) else "loop"

def build():
    b = StateGraph(State)
    b.add_node("AgentInvoke_0", node_AgentInvoke_0)
    b.add_node("LoopHeader_1", node_LoopHeader_1)
    b.add_node("LoopTick_2", node_LoopTick_2)
    b.add_node("Nop_3", node_Nop_3)
    b.add_node("AgentInvoke_4", node_AgentInvoke_4)
    b.add_node("AgentInvoke_5", node_AgentInvoke_5)
    b.add_node("AgentInvoke_6", node_AgentInvoke_6)
    b.add_node("Ask_7", node_Ask_7)
    b.add_edge(START, "AgentInvoke_0")
    b.add_edge("AgentInvoke_0", "AgentInvoke_4")
    b.add_conditional_edges("LoopHeader_1", route_LoopHeader_1, {"loop": "AgentInvoke_4", "exit": "Nop_3"})
    b.add_edge("LoopTick_2", "LoopHeader_1")
    b.add_edge("Nop_3", "AgentInvoke_6")
    b.add_edge("AgentInvoke_4", "AgentInvoke_5")
    b.add_edge("AgentInvoke_5", "LoopTick_2")
    b.add_edge("AgentInvoke_6", "Ask_7")
    b.add_edge("Ask_7", END)
    return b.compile()

INPUTS = ["contractRef"]
OUTPUTS = ["redline"]

if __name__ == "__main__":
    _rt.main(build, INPUTS, OUTPUTS)
blueprint.json (the portable format)
{
  "id": "com.socketcat/contract-redline",
  "flow": {
    "type": "sequence",
    "blocks": [
      {
        "in": {
          "contractRef": "contractRef"
        },
        "out": "clauses",
        "use": "reader",
        "type": "agent"
      },
      {
        "max": 3,
        "type": "loop",
        "until": "review.clean == true",
        "blocks": [
          {
            "in": {
              "review": "review",
              "clauses": "clauses"
            },
            "out": "draft",
            "use": "redliner",
            "type": "agent"
          },
          {
            "in": {
              "draft": "draft"
            },
            "out": "review",
            "use": "reviewer",
            "type": "agent"
          }
        ]
      },
      {
        "in": {
          "draft": "draft"
        },
        "out": "redline",
        "use": "memoWriter",
        "type": "agent"
      },
      {
        "out": "redline",
        "type": "ask",
        "prompt": "Review the redline and risk memo. Approve to share with the counterparty, or send back with notes."
      }
    ]
  },
  "tags": [
    "legal",
    "contracts",
    "evaluator-optimizer",
    "human-in-the-loop"
  ],
  "title": "Contract Redline",
  "agents": {
    "reader": {
      "model": {
        "hint": "fast"
      },
      "title": "Reader",
      "tools": [
        "docs.read_doc"
      ],
      "instructions": "Open the contract and extract its clauses: label each by type (liability, term, indemnity, IP, payment, etc.) and capture its exact text. Do not judge yet."
    },
    "redliner": {
      "model": {
        "hint": "reasoning"
      },
      "title": "Redliner",
      "tools": [
        "fs.read_file"
      ],
      "instructions": "Read the negotiation playbook from disk. Propose the minimal edits that bring off-standard clauses in line with it, quoting the exact replacement text. If you received a review, address every flag and try again. Never soften a position the playbook marks non-negotiable."
    },
    "reviewer": {
      "model": {
        "hint": "reasoning"
      },
      "title": "Reviewer",
      "output": {
        "type": "object",
        "required": [
          "clean"
        ],
        "properties": {
          "clean": {
            "type": "boolean"
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "instructions": "Check the redline against the playbook. Flag any clause still off-standard, any edit that overreaches, and any risk a counterparty would reject. Return an object with a 'clean' boolean and specific notes. Sign off only when the redline is defensible and complete."
    },
    "memoWriter": {
      "model": {
        "hint": "fast"
      },
      "title": "Memo Writer",
      "tools": [
        "chat.post_message"
      ],
      "instructions": "Write a short risk memo for the reviewing lawyer: what was changed, what still carries risk, and what to watch in negotiation. Post a pointer to the legal channel. Do not send anything to the counterparty."
    }
  },
  "estate": {
    "draft": {
      "type": "object",
      "description": "The redliner's current proposed edits."
    },
    "review": {
      "type": "object",
      "description": "The reviewer's verdict, including a 'clean' flag."
    },
    "clauses": {
      "type": "array",
      "description": "The extracted clauses with their text and type."
    }
  },
  "$schema": "socketcat.dev/blueprint/v0",
  "authors": [
    {
      "url": "https://socketcat.com",
      "name": "SocketCat"
    }
  ],
  "license": "MIT",
  "servers": [
    {
      "ref": "io.github.adelaidasofia/google-workspace-mcp",
      "alias": "docs"
    },
    {
      "ref": "io.github.modelcontextprotocol/filesystem",
      "alias": "fs"
    },
    {
      "ref": "io.github.slack/slack-mcp",
      "alias": "chat"
    }
  ],
  "summary": "Extracts contract clauses, redlines them against your playbook in a review loop, and pauses for a lawyer to approve.",
  "targets": [
    "langgraph",
    "*"
  ],
  "version": "1.0.0",
  "interface": {
    "inputs": {
      "contractRef": {
        "type": "string",
        "description": "The contract to review, as a drive document id or path."
      }
    },
    "outputs": {
      "redline": {
        "type": "string",
        "description": "The approved redline and risk memo, ready for a human to send."
      }
    }
  },
  "extensions": {
    "dev.langgraph": {
      "checkpointer": "memory"
    }
  },
  "description": "A reader opens the contract from the drive and extracts its clauses. A redliner proposes edits that move off-standard terms toward the company's negotiation playbook (read from disk), and a reviewer checks each edit against that playbook and flags residual risk. The two loop until the reviewer signs off or the round budget is reached. A risk memo is produced and the package pauses for a human lawyer to approve before it is shared. Replace the playbook file with your own standard positions."
}

More in Finance & legal

Browse all →

Invoice Match

com.socketcat/invoice-match
Custom

Reads an incoming invoice, matches it against the purchase order and receipt in your database, and branches: clean ones queue for approval, mismatches get a written exception.

11453 servers
149

Revenue Reconciler

com.socketcat/revenue-reconciler
LangGraph

Pulls Stripe charges and your warehouse's invoice records for the period in parallel, reconciles them line by line, and reports only the discrepancies — with likely causes.

10684 servers
136

Dispute Responder

com.socketcat/dispute-responder
Autogen

A Stripe dispute goes to two agents who argue it out — advocate versus risk — then draft an evidence packet you approve before it's filed.

6882 servers
82