Skip to main content
Legalai.guide
Expert

Tutorial 09: Custom Legal Skills, Hooks & Agents

Build custom skills for your firm's workflows, create compliance hooks, and deploy multi-agent systems for complex legal tasks.

Expert Level

Developer skills recommended. Estimated time: 120 minutes.

Learning Objectives

By the end of this tutorial, you will:

  • Understand Claude Code's architecture (Skills, Hooks, Sub-agents)
  • Build custom legal skills for your firm's workflows
  • Create hooks for quality control and compliance
  • Deploy multi-agent systems for complex legal tasks

Part 1: Understanding the Claude Code Stack

Architecture Overview

CLAUDE CODE STACK

├── SKILLS
│   └── Specialized instructions and best practices
│       stored in files Claude reads based on context

├── HOOKS
│   └── Scripts that run at specific points in
│       Claude's execution lifecycle

├── SUB-AGENTS
│   └── Autonomous agents spawned to handle
│       specific subtasks

├── MCP SERVERS
│   └── External tool connections (covered in Tutorial 07)

└── PLUGINS
    └── Packaged bundles of Skills + Hooks + MCP
ComponentLegal Application
SkillsEncode playbooks, review procedures, drafting standards
HooksEnforce compliance, prevent unauthorized actions, audit logging
Sub-agentsParallelize document review, research tasks
PluginsPackage firm workflows for distribution

What Are Skills?

Skills are specialized instructions stored in files that Claude reads based on context. Unlike prompts (one-time), Skills persist and activate automatically.

Skill File Structure

your-skill/
├── SKILL.md          # Main instructions (required)
├── examples/         # Example inputs/outputs
│   ├── good-review.md
│   └── bad-review.md
├── templates/        # Document templates
│   ├── nda-template.docx
│   └── redline-template.docx
└── resources/        # Reference materials
    ├── playbook.json
    └── clause-library.md

Creating a Contract Review Skill

Step 1: Create Skill Directory

mkdir -p ~/.claude/skills/contract-review
cd ~/.claude/skills/contract-review

Step 2: Write SKILL.md

# Contract Review Skill
 
## Purpose
This skill provides comprehensive contract review capabilities
aligned with [Firm Name]'s standard practices.
 
## Activation
Activate this skill when:
- User uploads a contract document
- User mentions "contract review" or similar
- User references specific contract types (NDA, MSA, SaaS, etc.)
 
## Process
 
### Step 1: Classification
Before analyzing, identify:
1. **Contract Type**: NDA, MSA, SaaS, License, Services, etc.
2. **Our Role**: Which party do we represent?
3. **Counterparty Profile**: Enterprise, mid-market, startup?
4. **Deal Tier**: Estimated value and strategic importance
 
### Step 2: Document Processing
- Read entire contract before providing analysis
- Note all defined terms and their definitions
- Identify governing law and dispute resolution
- Map clause structure and cross-references
 
### Step 3: Playbook Application
Apply positions from `resources/playbook.json`:
- Compare each clause to standard position
- Identify deviations and assess severity
- Note missing required provisions
 
### Step 4: Risk Assessment
For each issue:
- Assign severity: RED | YELLOW | GREEN
- Explain practical business impact
- Consider interaction with other clauses
 
### Step 5: Redline Generation
For RED and YELLOW issues:
- Provide specific alternative language
- Reference clause library when applicable
- Explain rationale for changes
 
### Step 6: Output Generation
Structure response as:
1. Executive Summary (3-5 sentences)
2. Deal Parameters Table
3. Clause-by-Clause Analysis
4. Risk Score and Escalation Recommendation
5. Negotiation Priorities
6. Questions for Business Team
 
## Clause Library
Reference `resources/clause-library.md` for approved language.
 
## Examples
See `examples/` directory for good and bad review examples.
 
## Calibration Notes
- Liability cap thresholds updated January 2026
- New data processing requirements per GDPR changes
- Updated AI/ML clause language required
 
## Quality Requirements
- Never provide legal advice without qualification
- Flag any clause requiring jurisdictional verification
- Note when playbook doesn't cover specific terms
- Recommend escalation for deals over $500K

Step 3: Create Playbook Resource

resources/playbook.json:

{
  "contract_types": {
    "SaaS_Customer": {
      "liability": {
        "standard": "12 months fees",
        "minimum": "total contract value",
        "carve_outs": ["indemnification", "data_breach", "confidentiality", "IP", "gross_negligence", "willful_misconduct"]
      },
      "indemnification": {
        "required_vendor": ["IP_infringement", "data_breach", "security_failure"],
        "acceptable_exclusions": ["customer_modifications", "third_party_components_with_notice"]
      },
      "data": {
        "ownership": "customer",
        "vendor_rights": "service_delivery_only",
        "prohibited_uses": ["AI_training", "analytics", "marketing", "sale"],
        "retention_limit": "30_days_post_termination"
      }
    }
  },
  "severity_matrix": {
    "RED": [
      "unlimited_customer_liability",
      "no_vendor_indemnity",
      "data_used_for_AI_training",
      "no_termination_for_convenience"
    ],
    "YELLOW": [
      "liability_cap_below_12_months",
      "narrow_indemnity_carveouts",
      "60_plus_day_termination_notice"
    ]
  }
}

Step 4: Create Clause Library

resources/clause-library.md:

# Approved Clause Language Library
 
## Limitation of Liability
 
### Standard Mutual Cap
"EACH PARTY'S TOTAL LIABILITY ARISING OUT OF OR RELATED TO THIS
AGREEMENT SHALL NOT EXCEED THE FEES PAID OR PAYABLE BY CUSTOMER
IN THE TWELVE (12) MONTHS PRECEDING THE CLAIM."
 
### Uncapped Carve-Outs Addition
"THE FOREGOING LIMITATION SHALL NOT APPLY TO: (A) EITHER PARTY'S
INDEMNIFICATION OBLIGATIONS; (B) BREACH OF SECTION [DATA SECURITY];
(C) BREACH OF CONFIDENTIALITY OBLIGATIONS; (D) EITHER PARTY'S
GROSS NEGLIGENCE OR WILLFUL MISCONDUCT; OR (E) CUSTOMER'S PAYMENT
OBLIGATIONS."
 
## Data Ownership
 
### Customer Ownership Clause
"As between the parties, Customer retains all right, title, and
interest in and to Customer Data. Vendor acquires no rights in
Customer Data except the limited license granted herein."
 
### No AI Training Clause
"Vendor shall not use Customer Data or any derivatives thereof
to train, develop, or improve any machine learning model,
artificial intelligence system, or similar technology."
 
[Continue with additional clauses...]

Step 5: Install and Test

# Register skill
claude skill install ~/.claude/skills/contract-review
 
# Test
claude "I need to review a software agreement"
# Claude should load and apply the skill

Part 3: Building Compliance Hooks

What Are Hooks?

Hooks are scripts that execute at specific points in Claude's operation:

Hook TypeTrigger PointUse Case
PreToolUseBefore any tool runsBlock dangerous actions
PostToolUseAfter tool completesAudit logging
SessionStartWhen session beginsLoad context
PreInputBefore processing inputFilter content
PostOutputAfter generating outputQuality checks

Purpose: Prevent Claude from making unauthorized changes to privileged documents.

Step 1: Create Hook Directory

mkdir -p ~/.claude/hooks

Step 2: Create Hook Script

~/.claude/hooks/legal-compliance.js:

// Legal Compliance Hook
// Prevents unauthorized access to privileged documents
 
module.exports = {
  name: 'legal-compliance',
  hooks: {
    PreToolUse: async ({ tool, input }) => {
      // Block access to privileged folder without explicit permission
      if (tool === 'Read' || tool === 'Write' || tool === 'Edit') {
        const path = input.file_path || input.path || '';
 
        if (path.includes('/Privileged/') || path.includes('/Attorney-Client/')) {
          return {
            block: true,
            message: 'BLOCKED: Attempting to access privileged folder. ' +
                     'Explicit user confirmation required for privileged documents.',
            feedback: 'Privileged document access attempted - awaiting user confirmation'
          };
        }
      }
 
      // Warn on external sharing actions
      if (tool === 'SendEmail' || tool === 'ShareDocument') {
        return {
          feedback: 'Warning: External sharing action detected. Verify recipient authorization.',
          additionalContext: 'This action will share information externally. ' +
                            'Confirm this is appropriate before proceeding.'
        };
      }
 
      return { continue: true };
    },
 
    PostToolUse: async ({ tool, input, output }) => {
      // Audit logging for document access
      if (['Read', 'Write', 'Edit'].includes(tool)) {
        const logEntry = {
          timestamp: new Date().toISOString(),
          tool: tool,
          path: input.file_path || input.path,
          user: process.env.USER,
          session: process.env.CLAUDE_SESSION_ID
        };
 
        // Write to audit log
        const fs = require('fs');
        fs.appendFileSync(
          '~/.claude/logs/document-access.jsonl',
          JSON.stringify(logEntry) + '\n'
        );
      }
 
      return { continue: true };
    },
 
    PostOutput: async ({ output }) => {
      // Check for privilege warnings
      const privilegeKeywords = [
        'attorney-client',
        'work product',
        'privileged',
        'confidential communication'
      ];
 
      const outputLower = output.toLowerCase();
      const containsPrivilege = privilegeKeywords.some(kw =>
        outputLower.includes(kw)
      );
 
      if (containsPrivilege) {
        return {
          feedback: 'Warning: Output contains privilege-related content. ' +
                    'Review before sharing externally.',
          additionalContext: 'This output references privileged materials.'
        };
      }
 
      return { continue: true };
    }
  }
};

Step 3: Configure Hook

~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "command": "node",
        "args": ["~/.claude/hooks/legal-compliance.js", "PreToolUse"]
      }
    ],
    "PostToolUse": [
      {
        "command": "node",
        "args": ["~/.claude/hooks/legal-compliance.js", "PostToolUse"]
      }
    ],
    "PostOutput": [
      {
        "command": "node",
        "args": ["~/.claude/hooks/legal-compliance.js", "PostOutput"]
      }
    ]
  }
}

Additional Hook Use Cases

Citation Verification Hook:

PostOutput: async ({ output }) => {
  // Check for case citations
  const citePattern = /\d+\s+[A-Z][a-z]+\.?\s*\d*d?\s+\d+/g;
  const citations = output.match(citePattern) || [];
 
  if (citations.length > 0) {
    return {
      feedback: `Warning: ${citations.length} case citation(s) detected. ` +
                'Verify all citations before relying on this output.',
      additionalContext: `Citations found: ${citations.join(', ')}`
    };
  }
  return { continue: true };
}

Confidentiality Check Hook:

PreToolUse: async ({ tool, input }) => {
  if (tool === 'WebSearch' || tool === 'WebFetch') {
    // Check if query contains client names
    const clientList = require('./client-list.json');
    const query = input.query || input.url || '';
 
    const clientMention = clientList.find(c =>
      query.toLowerCase().includes(c.toLowerCase())
    );
 
    if (clientMention) {
      return {
        block: true,
        message: `BLOCKED: Query contains client name "${clientMention}". ` +
                 'Web searches must not include client-identifying information.'
      };
    }
  }
  return { continue: true };
}

Understanding Sub-Agents

Claude can spawn sub-agents to handle specific tasks:

  • Parallelization: Multiple documents reviewed simultaneously
  • Specialization: Different agents for different tasks
  • Isolation: Separate context for separate analyses

Example: Parallel Due Diligence Review

// Due Diligence Multi-Agent Workflow
 
const agents = [
  {
    name: 'contract-reviewer',
    task: 'Review all customer agreements',
    folder: '/DD/Contracts/Customers',
    instructions: 'Apply customer agreement playbook'
  },
  {
    name: 'ip-reviewer',
    task: 'Review all IP agreements',
    folder: '/DD/Contracts/IP',
    instructions: 'Apply IP agreement playbook'
  },
  {
    name: 'employment-reviewer',
    task: 'Review all employment agreements',
    folder: '/DD/Contracts/Employment',
    instructions: 'Apply employment agreement playbook'
  },
  {
    name: 'litigation-reviewer',
    task: 'Analyze all pending litigation',
    folder: '/DD/Litigation',
    instructions: 'Assess litigation exposure and reserves'
  }
];
 
// Spawn all agents in parallel
const results = await Promise.all(
  agents.map(agent =>
    claude.spawnAgent({
      name: agent.name,
      prompt: `${agent.task} in ${agent.folder}. ${agent.instructions}.
               Output findings in structured JSON format.`,
      timeout: 30 * 60 * 1000 // 30 minute timeout
    })
  )
);
 
// Synthesize results
const synthesis = await claude.prompt(`
  I've received due diligence findings from ${agents.length} specialized reviewers.
 
  ${results.map((r, i) => `
  ## ${agents[i].name} Findings:
  ${r.output}
  `).join('\n')}
 
  Please synthesize into:
  1. Executive Summary of DD findings
  2. Critical issues requiring immediate attention
  3. Risk matrix by category
  4. Recommended deal adjustments
  5. Items requiring seller disclosure
`);

Example: Research + Draft Workflow

// Legal Research + Drafting Multi-Agent Workflow
 
async function researchAndDraft(topic, jurisdiction, outputType) {
  // Stage 1: Research Agent
  const research = await claude.spawnAgent({
    name: 'legal-researcher',
    prompt: `Research ${topic} under ${jurisdiction} law.
             Use available legal research tools (Midpage, CourtListener).
             Provide comprehensive analysis with citations.
             Format as structured legal memorandum outline.`,
    tools: ['midpage', 'courtlistener', 'webSearch']
  });
 
  // Stage 2: Draft Agent (uses research output)
  const draft = await claude.spawnAgent({
    name: 'legal-drafter',
    prompt: `Based on this research:
             ${research.output}
 
             Draft a ${outputType} addressing ${topic}.
             Include all relevant citations.
             Follow firm style guide.`,
    context: research.output
  });
 
  // Stage 3: Review Agent
  const review = await claude.spawnAgent({
    name: 'quality-reviewer',
    prompt: `Review this draft for:
             1. Legal accuracy
             2. Citation completeness
             3. Style compliance
             4. Missing analysis
 
             Draft:
             ${draft.output}`,
    context: draft.output
  });
 
  return {
    research: research.output,
    draft: draft.output,
    review: review.output
  };
}

Part 5: Packaging Skills into Plugins

Plugin Structure

legal-contract-plugin/
├── plugin.json           # Plugin manifest
├── SKILL.md             # Main skill
├── .mcp.json            # MCP server config
├── hooks/
│   └── compliance.js    # Compliance hooks
├── commands/
│   └── review.md        # Slash command definitions
├── resources/
│   ├── playbook.json
│   └── clauses.md
└── README.md

Plugin Manifest

plugin.json:

{
  "name": "legal-contract-review",
  "version": "2.0.0",
  "description": "Comprehensive contract review for legal teams",
  "author": "Your Firm",
  "license": "proprietary",
 
  "skills": ["SKILL.md"],
 
  "commands": {
    "review-contract": "commands/review.md",
    "triage-nda": "commands/triage.md"
  },
 
  "hooks": {
    "PreToolUse": "hooks/compliance.js",
    "PostOutput": "hooks/citation-check.js"
  },
 
  "mcp": {
    "servers": [".mcp.json"]
  },
 
  "config": {
    "playbook_path": {
      "type": "string",
      "description": "Path to firm's negotiation playbook",
      "required": true
    },
    "escalation_threshold": {
      "type": "number",
      "default": 500000,
      "description": "Deal value requiring partner review"
    }
  }
}

Installing and Distributing

# Install locally
claude plugin install ./legal-contract-plugin
 
# Publish to marketplace (if approved)
claude plugin publish ./legal-contract-plugin
 
# Install from marketplace
claude plugin install @yourfirm/legal-contract-review

Part 6: Security Considerations

Skill Security

  • Source verification: Only install skills from trusted sources
  • Code review: Review all hook code before deployment
  • No client data: Never include client data in skill files
  • Version control: Track changes to skills
  • Access control: Limit who can modify firm skills

Data Protection

// Example: Data sanitization hook
PreInput: async ({ input }) => {
  // Remove potential client identifiers before processing
  const sanitized = input
    .replace(/\b\d{3}-\d{2}-\d{4}\b/g, '[SSN]')  // SSN
    .replace(/\b\d{9}\b/g, '[EIN]')              // EIN
    .replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, '[EMAIL]');
 
  return { input: sanitized, continue: true };
}

Compliance Requirements

  • Skills reviewed by IT security
  • Hooks tested in sandbox environment
  • Audit logging enabled
  • Client data segregation verified
  • Access controls configured
  • Backup procedures documented

Homework Before Tutorial 10

  1. Create a custom skill for one of your firm's review processes

  2. Implement at least one hook (compliance or audit logging)

  3. Test a multi-agent workflow for parallel document processing

  4. Document your skill for team adoption

  5. Consider packaging as a plugin for distribution



Quick Reference: Claude Code Commands

# Skills
claude skill install <path>
claude skill list
claude skill remove <name>
 
# Hooks
claude hook list
claude hook test <hook-file>
 
# Plugins
claude plugin install <path>
claude plugin list
claude plugin config <name>
 
# Debugging
claude --debug
claude logs

Sources