{"id":50412340,"url":"https://github.com/cskwork/ai-law-counsel","last_synced_at":"2026-05-31T04:04:56.703Z","repository":{"id":349554071,"uuid":"1201725028","full_name":"cskwork/ai-law-counsel","owner":"cskwork","description":"AI-powered Korean legal consultation chatbot. Searches statutes, precedents \u0026 admin rules via National Law Information Center API with LLM function calling + SSE streaming.","archived":false,"fork":false,"pushed_at":"2026-05-05T08:44:54.000Z","size":581,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T10:28:54.552Z","etag":null,"topics":["ai","chatbot","function-calling","korean-law","legal","nextjs","sse-streaming","tailwindcss","typescript","vercel"],"latest_commit_sha":null,"homepage":"https://ai-law-counsel.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cskwork.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-05T04:19:18.000Z","updated_at":"2026-05-05T08:44:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cskwork/ai-law-counsel","commit_stats":null,"previous_names":["cskwork/ai-law-counsel"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cskwork/ai-law-counsel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cskwork%2Fai-law-counsel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cskwork%2Fai-law-counsel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cskwork%2Fai-law-counsel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cskwork%2Fai-law-counsel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cskwork","download_url":"https://codeload.github.com/cskwork/ai-law-counsel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cskwork%2Fai-law-counsel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33718496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","chatbot","function-calling","korean-law","legal","nextjs","sse-streaming","tailwindcss","typescript","vercel"],"created_at":"2026-05-31T04:04:55.844Z","updated_at":"2026-05-31T04:04:56.691Z","avatar_url":"https://github.com/cskwork.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# AI Law Counsel\n\n**Korean Legal Consultation Chatbot**\n\nAI-powered legal Q\u0026A built on Korean National Law Information Center API + LLM function calling via MCP.\n\nAsk any legal question in Korean. The AI searches relevant statutes, precedents, and administrative rules in real time, then responds with verifiable, clickable citations. Upload contracts for risk analysis or generate legal document drafts through guided Q\u0026A.\n\n[Live Demo](https://ai-law-counsel.vercel.app) | [Report Bug](https://github.com/cskwork/ai-law-counsel/issues) | [Contributing](CONTRIBUTING.md)\n\n\u003c/div\u003e\n\n---\n\n## Features\n\n### Core Q\u0026A\n- **Real-time legal search** -- statutes, precedents, and administrative rules via National Law Information Center\n- **Autonomous function calling** -- LLM picks and chains tools (up to 5 rounds) without manual tool selection\n- **MCP integration** -- legal tools served by [korean-law-mcp](https://github.com/chrisryugj/korean-law-mcp) (Model Context Protocol). Host is configurable via `MCP_BASE_URL` (defaults to `https://korean-law-mcp.fly.dev`; production uses self-hosted HF Space `https://csk917-korean-law-mcp.hf.space`).\n- **SSE streaming** -- token-by-token response for natural reading\n- **Conversation history** -- persisted in browser, sidebar navigation, context windowing (last 10 turns)\n\n### Document Analysis (PDF / DOCX / TXT, up to 4.5MB)\n- Upload a contract or notice and the AI extracts key clauses, flags risks, and cites relevant laws\n- Output includes structured summary, risk markers, and legal grounds\n\n### Legal Document Templates (5 types)\nGuided Q\u0026A flow that produces a complete draft with cited legal basis:\n\n| Template | Legal Basis |\n|----------|-------------|\n| 임대차 계약서 (Lease) | 주택임대차보호법, 민법 §§618-654 |\n| 근로계약서 (Employment) | 근로기준법 §§17, 2 |\n| 내용증명 (Demand Letter) | 민법 §387, 우편법 |\n| 위임장 (Power of Attorney) | 민법 §§114-136 |\n| 비밀유지계약서 (NDA) | 부정경쟁방지 및 영업비밀보호에 관한 법률 |\n\n### Interactive Citations\n- Inline `cite:` protocol links (e.g. `[민법 제750조](cite:statute/민법/750)`)\n- Click any citation to view full article text and a verified deeplink to law.go.kr\n- All citations are MCP-verified against the official source\n\n### UI / UX\n- '변호사의 서재' design system, mobile-first responsive layout\n- Adjustable font size (A- / A+) for accessibility\n- Prominent legal disclaimer on every response\n\n## How It Works\n\n```\nUser asks a legal question\n        |\n   LLM analyzes the question\n        |\n   Calls MCP tools automatically (up to 5 rounds)\n   - search_law          : Search statutes by keyword\n   - get_law_detail      : Get specific articles\n   - search_precedent    : Search court cases\n   - get_precedent_detail: Get case details\n   - search_admin_rule   : Search administrative rules\n   - clarify_situation   : Ask follow-up questions\n        |\n   Streams answer with verified citations\n```\n\nThe LLM decides which laws and precedents to search based on the user's question. No manual tool selection needed.\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Framework | Next.js 14 (App Router) |\n| Language | TypeScript 5 |\n| Styling | Tailwind CSS 3 + @tailwindcss/typography |\n| LLM | Z.ai `glm-5-turbo` (function calling + SSE streaming) |\n| Legal Tools | korean-law-mcp (Streamable HTTP transport) |\n| Legal Data | Korean National Law Information Center Open API |\n| Doc Parsing | pdf-parse, mammoth |\n| Markdown | react-markdown + remark-gfm |\n| Testing | Vitest (unit/integration) + Playwright (E2E) |\n| Deployment | Vercel (serverless) |\n| Font | Geist (via next/font) |\n\n## Architecture\n\n```\nBrowser (SSE)\n    |\nNext.js on Vercel\n    |\n    +-- app/page.tsx                Chat UI (React)\n    +-- app/api/chat/route.ts       SSE streaming endpoint\n    +-- app/api/upload/route.ts     File upload + text extraction\n    +-- app/api/citation/route.ts   On-click citation lookup\n    |\n    +-- lib/chat/orchestrator.ts    Function calling loop (max 5 rounds)\n    +-- lib/chat/tool-executor.ts   Tool name -\u003e function dispatch\n    +-- lib/chat/context-window.ts  Last-10-turn windowing\n    +-- lib/chat/template-types.ts  5 legal document templates\n    |\n    +-- lib/zai/client.ts           LLM API client (streaming + non-streaming)\n    +-- lib/mcp/client.ts           MCP session (request-scoped, auto-reconnect)\n    +-- lib/mcp/tool-bridge.ts      MCP \u003c-\u003e Z.ai tool schema bridge\n    +-- lib/law/client.ts           Direct Law API fallback (XML parsing)\n    +-- lib/citation/builder.ts     Citation enrichment + verification\n    +-- lib/document/extractor.ts   PDF/DOCX/TXT text extraction\n    +-- lib/document/validator.ts   Type/size validation (4.5MB)\n    |\nExternal Services\n    +-- Z.ai GLM (api.z.ai)                LLM (reasoning + function calling)\n    +-- korean-law-mcp                     MCP server for legal tools (host via MCP_BASE_URL)\n    +-- open.law.go.kr                     Statutes, precedents, admin rules\n```\n\n## Quick Start\n\n```bash\n# Clone\ngit clone https://github.com/cskwork/ai-law-counsel.git\ncd ai-law-counsel\n\n# Install\nnpm install\n\n# Configure\ncp .env.example .env.local\n# Edit .env.local with your API keys:\n#   ZAI_API_KEY=your_key_here\n#   LAW_API_KEY=your_key_here\n\n# Run\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000).\n\n### API Keys\n\n| Key | Source | Required |\n|-----|--------|----------|\n| `ZAI_API_KEY` | [Z.ai](https://api.z.ai) | Yes |\n| `LAW_API_KEY` | [National Law Info Center](https://open.law.go.kr) | Yes (used as MCP `oc` parameter and for direct fallback calls) |\n| `MCP_BASE_URL` | korean-law-mcp host (e.g. `https://your-space.hf.space`) | No (defaults to `https://korean-law-mcp.fly.dev`) |\n\n## Testing\n\n```bash\nnpm run test:run        # All Vitest unit/integration tests\nnpm run test:coverage   # Coverage report\nnpm run test:e2e        # Playwright E2E tests\nnpm run test:e2e:report # Open last E2E HTML report\n```\n\n**223 test cases across 31 files** covering:\n- Law API client and 6 search/lookup functions (URL building, XML parsing, error handling)\n- MCP client (session lifecycle, reconnect, tool dispatch) and tool-bridge\n- Z.ai client (streaming, non-streaming, auth errors)\n- Chat orchestrator (tool loop, max rounds, clarify, context window)\n- Document extractor and validator (PDF, DOCX, TXT, size limits)\n- Citation builder and `/api/citation` endpoint\n- Template types (5 legal document templates)\n- React components (MessageBubble, CitationCard)\n- Playwright E2E (home page, upload flow, chat citation flow)\n\n## Project Structure\n\n```\napp/\n  api/\n    chat/route.ts                SSE streaming endpoint\n    citation/route.ts            Citation lookup endpoint\n    upload/route.ts              File upload + text extraction\n  components/\n    chat/                        ChatContainer, MessageList, MessageBubble,\n                                 ChatInput, Sidebar, FileUpload, CitationCard,\n                                 SourcesFooter, ToolCallIndicator,\n                                 DocumentDownload, CopyButton\n    common/                      Disclaimer, LoadingDots\n    law/                         LawArticleCard, PrecedentCard\n  hooks/                         useConversationHistory, useFontSize\n  types/                         conversation\nlib/\n  chat/                          Orchestrator, tool executor, system prompt,\n                                 context window, template types, validation\n  mcp/                           MCP client session + tool bridge\n  zai/                           LLM client + tool schemas\n  law/                           Direct Law API fallback (5 search functions)\n  citation/                      Citation builder + types\n  document/                      Extractor (pdf-parse, mammoth) + validator\n  utils/                         SSE encoding, stream parsing, sanitize, array\ntests/                           Vitest + Playwright (223 cases, 31 files)\n```\n\n## Limits and Constants\n\n- Max user message: 2,000 characters\n- Max conversation history sent to LLM: 50 messages / 20,000 characters / last 10 turns\n- Max upload size: 4.5 MB (Vercel payload limit)\n- Supported file types: `pdf`, `docx`, `txt`\n- Max extracted text per upload: 50,000 characters (LLM context guard)\n- Max tool-calling rounds per response: 5\n\n## Disclaimer\n\n\u003e This service provides AI-generated legal information, not legal advice. Always consult a licensed attorney for specific legal matters.\n\n## Contributing\n\nContributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding style, and PR guidelines.\n\n## License\n\n[MIT License](LICENSE) (c) 2026 cskwork\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcskwork%2Fai-law-counsel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcskwork%2Fai-law-counsel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcskwork%2Fai-law-counsel/lists"}