Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Mike Ai Legal Platform

ASecurity

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection. Mike is an open-source AI legal platform consisting of a Next.js frontend and an Express backend. It supports document processing (including DOC/DOCX to PDF via LibreOffice), Supabase Auth and Postgres, S3-compatible object storage, and multiple AI model providers. ---

81 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmenttypescriptbashsqlnextjsexpressawsgitapidatabasefrontend

Works with

cliapi

Security Analysis

A92/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add reason-machines/trending-skills --skill mike-ai-legal-platform --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mike Ai Legal Platform?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Mike Ai Legal Platform
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/reason-machines-mike-ai-legal-platform/badge)](https://www.skillsdirectory.com/skills/reason-machines-mike-ai-legal-platform)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
```markdown
---
name: mike-ai-legal-platform
description: OSS AI legal platform with Next.js frontend and Express backend for document processing and legal workflows
triggers:
  - set up mike legal platform
  - add mike to my project
  - configure mike backend
  - mike document processing
  - mike supabase integration
  - mike frontend setup
  - deploy mike legal AI
  - mike API endpoints
---

# Mike AI Legal Platform

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

Mike is an open-source AI legal platform consisting of a Next.js frontend and an Express backend. It supports document processing (including DOC/DOCX to PDF via LibreOffice), Supabase Auth and Postgres, S3-compatible object storage, and multiple AI model providers.

---

## Project Structure

```
mike/
├── frontend/          # Next.js application
├── backend/           # Express API, Supabase access, document processing
│   └── migrations/
│       └── 000_one_shot_schema.sql  # Fresh DB schema
```

---

## Installation

```bash
# Clone the repository
git clone https://github.com/willchen96/mike.git
cd mike

# Install dependencies for both services
npm install --prefix backend
npm install --prefix frontend

# Copy environment files
cp backend/.env.example backend/.env
cp frontend/.env.local.example frontend/.env.local
```

### Database Setup

Run the one-shot schema in the Supabase SQL editor:

```
backend/migrations/000_one_shot_schema.sql
```

---

## Environment Configuration

### Backend (`backend/.env`)

```env
# Supabase
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=$SUPABASE_SERVICE_ROLE_KEY

# S3-compatible storage (e.g. Cloudflare R2)
S3_ENDPOINT=$S3_ENDPOINT
S3_BUCKET=$S3_BUCKET
S3_ACCESS_KEY_ID=$S3_ACCESS_KEY_ID
S3_SECRET_ACCESS_KEY=$S3_SECRET_ACCESS_KEY
S3_REGION=$S3_REGION

# AI Model Provider(s) — enable at least one
OPENAI_API_KEY=$OPENAI_API_KEY
ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY

# Server
PORT=4000
```

### Frontend (`frontend/.env.local`)

```env
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY
NEXT_PUBLIC_API_URL=http://localhost:4000
```

---

## Running the Platform

```bash
# Start backend (Express API on port 4000)
npm run dev --prefix backend

# Start frontend (Next.js on port 3000)
npm run dev --prefix frontend
```

Open `http://localhost:3000`.

---

## Key Commands

```bash
# Build checks
npm run build --prefix backend
npm run build --prefix frontend

# Lint
npm run lint --prefix frontend
```

---

## Required Services

| Service | Purpose |
|---|---|
| Supabase | Auth + Postgres database |
| S3-compatible storage | Document/file storage (e.g. Cloudflare R2) |
| AI model provider | At least one (OpenAI, Anthropic, etc.) |
| LibreOffice | DOC/DOCX → PDF conversion |

### Installing LibreOffice (Ubuntu/Debian)

```bash
sudo apt-get install -y libreoffice
```

---

## Common Patterns

### Supabase Client (Backend)

```typescript
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!
);

// Fetch documents for a user
const { data, error } = await supabase
  .from('documents')
  .select('*')
  .eq('user_id', userId);
```

### Supabase Auth (Frontend)

```typescript
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs';

const supabase = createClientComponentClient();

// Sign in
const { data, error } = await supabase.auth.signInWithPassword({
  email: process.env.NEXT_PUBLIC_USER_EMAIL,
  password: process.env.NEXT_PUBLIC_USER_PASSWORD,
});

// Get current session
const { data: { session } } = await supabase.auth.getSession();
```

### Uploading a Document (Frontend → Backend)

```typescript
// frontend/lib/api.ts
export async function uploadDocument(file: File, token: string) {
  const formData = new FormData();
  formData.append('file', file);

  const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/documents/upload`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
    },
    body: formData,
  });

  if (!res.ok) throw new Error(await res.text());
  return res.json();
}
```

### Express Route with Auth Middleware (Backend)

```typescript
// backend/src/routes/documents.ts
import { Router, Request, Response } from 'express';
import { requireAuth } from '../middleware/auth';
import { supabase } from '../lib/supabase';

const router = Router();

router.get('/', requireAuth, async (req: Request, res: Response) => {
  const userId = (req as any).user.id;

  const { data, error } = await supabase
    .from('documents')
    .select('id, name, created_at, status')
    .eq('user_id', userId)
    .order('created_at', { ascending: false });

  if (error) return res.status(500).json({ error: error.message });
  return res.json(data);
});

export default router;
```

### S3 File Upload (Backend)

```typescript
// backend/src/lib/storage.ts
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { randomUUID } from 'crypto';

const s3 = new S3Client({
  endpoint: process.env.S3_ENDPOINT,
  region: process.env.S3_REGION,
  credentials: {
    accessKeyId: process.env.S3_ACCESS_KEY_ID!,
    secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
  },
});

export async function uploadToStorage(
  buffer: Buffer,
  mimeType: string,
  originalName: string
): Promise<string> {
  const key = `documents/${randomUUID()}/${originalName}`;

  await s3.send(
    new PutObjectCommand({
      Bucket: process.env.S3_BUCKET!,
      Key: key,
      Body: buffer,
      ContentType: mimeType,
    })
  );

  return key;
}
```

### DOC/DOCX to PDF Conversion (Backend)

```typescript
// backend/src/lib/convert.ts
import { exec } from 'child_process';
import { promisify } from 'util';
import path from 'path';
import fs from 'fs/promises';

const execAsync = promisify(exec);

export async function convertDocToPdf(inputPath: string): Promise<string> {
  const dir = path.dirname(inputPath);

  await execAsync(
    `libreoffice --headless --convert-to pdf --outdir ${dir} ${inputPath}`
  );

  const baseName = path.basename(inputPath, path.extname(inputPath));
  const outputPath = path.join(dir, `${baseName}.pdf`);

  // Verify output exists
  await fs.access(outputPath);
  return outputPath;
}
```

### Calling an AI Model (Backend)

```typescript
// backend/src/lib/ai.ts
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

export async function summarizeDocument(text: string): Promise<string> {
  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      {
        role: 'system',
        content: 'You are a legal assistant. Summarize the following document concisely.',
      },
      { role: 'user', content: text },
    ],
  });

  return response.choices[0].message.content ?? '';
}
```

---

## Next.js API Route Pattern (Frontend)

```typescript
// frontend/app/api/documents/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';

export async function GET() {
  const supabase = createRouteHandlerClient({ cookies });

  const {
    data: { session },
  } = await supabase.auth.getSession();

  if (!session) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/documents`, {
    headers: { Authorization: `Bearer ${session.access_token}` },
  });

  const data = await res.json();
  return NextResponse.json(data);
}
```

---

## Troubleshooting

### LibreOffice not found
```bash
which libreoffice
# If missing:
sudo apt-get install -y libreoffice   # Debian/Ubuntu
brew install --cask libreoffice       # macOS
```

### Supabase connection errors
- Verify `SUPABASE_URL` includes `https://` prefix.
- Service role key must be used on the backend (never expose it in the frontend).
- Run `000_one_shot_schema.sql` via the Supabase SQL editor before first launch.

### S3 upload failures with Cloudflare R2
- Set `S3_REGION` to `auto` for R2.
- Ensure `S3_ENDPOINT` is the full R2 endpoint: `https://<account-id>.r2.cloudflarestorage.com`.

### Port conflicts
- Backend defaults to port `4000`. Override with `PORT=XXXX` in `backend/.env`.
- Frontend defaults to port `3000`. Override with `next dev -p XXXX`.

### Build errors
```bash
# Check TypeScript errors
npm run build --prefix backend
npm run build --prefix frontend

# Lint issues
npm run lint --prefix frontend
```

### CORS errors between frontend and backend
Add the frontend origin to your Express CORS config:

```typescript
import cors from 'cors';
app.use(cors({ origin: process.env.FRONTEND_URL || 'http://localhost:3000' }));
```
```

Attribution

reason-machinesreason-machines
View sourceMore from reason-machines →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →