Install
$ agentstack add mcp-numikel-law-scrapper-mcp ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Law Scrapper MCP
A comprehensive Model Context Protocol (MCP) server for accessing and analyzing Polish legal acts from the Sejm API, enabling AI-powered legal research and document analysis.
Features
- Comprehensive legal act access - Full access to Polish legal acts from Dziennik Ustaw (DU) and Monitor Polski (MP)
- Advanced search and filtering - Multi-criteria search by date, type, keywords, publisher, and status
- Result Store with chained filtering - Store search results and filter with regex, type/status/year match, date ranges, sorting
- Document Store pattern - Load acts into memory for efficient section-level navigation and search
- Detailed document analysis - Metadata, structure, references, and content retrieval
- Content processing - Automatic PDF-to-text and HTML-to-Markdown conversion
- Date calculations - Specialized date utilities for legal document analysis
- System metadata - Keywords, statuses, document types, and institution data
- FastMCP integration - Built with FastMCP framework, flexible transport options
- Async HTTP client - Efficient httpx client with retry logic and connection pooling
- TTL caching - Intelligent response caching with configurable TTL
- Structured logging - JSON and text log formats for easy debugging
- Docker support - Containerized deployment with docker-compose
- Comprehensive documentation - Examples and clear parameter descriptions
Requirements
- Python: 3.13 or higher
- Package manager: uv (recommended) or pip
- Internet connection: Required for accessing Sejm API endpoints
- MCP-compatible tool: Cursor IDE, Claude Code, or other MCP clients
Installation
Using uv (recommended)
# Clone the repository
git clone https://github.com/numikel/law-scrapper-mcp.git
cd law-scrapper-mcp
# Install dependencies
uv sync
# Install with dev dependencies
uv sync --extra dev
Using pip
# Clone the repository
git clone https://github.com/numikel/law-scrapper-mcp.git
cd law-scrapper-mcp
# Install dependencies
pip install -e .
Using uvx (no installation required)
For quick testing without cloning the repository:
# Run the server directly from GitHub
uvx --from git+https://github.com/numikel/law-scrapper-mcp law-scrapper
Quick start
STDIO transport (default)
STDIO is the default transport for MCP communication. Start the server and connect from your MCP client:
# Run the server
uv run python -m law_scrapper_mcp
# Or use the installed script
law-scrapper
Configure in your MCP client (e.g., Cursor .cursor/mcp.json):
{
"mcpServers": {
"law-scrapper-mcp": {
"command": "law-scrapper"
}
}
}
For Claude Code:
claude mcp add law-scrapper "uvx --from git+https://github.com/numikel/law-scrapper-mcp law-scrapper"
HTTP transport (streamable-http)
Run the server on HTTP with streamable-http transport:
# Run with HTTP transport on port 7683
LAW_MCP_TRANSPORT=streamable-http uv run python -m law_scrapper_mcp
# Or specify custom host and port
LAW_MCP_TRANSPORT=streamable-http LAW_MCP_HOST=0.0.0.0 LAW_MCP_PORT=8080 uv run python -m law_scrapper_mcp
Configure in your MCP client:
{
"mcpServers": {
"law-scrapper-mcp": {
"url": "http://localhost:7683/mcp",
"transport": "streamable-http"
}
}
}
Note: The URL must include the /mcp path. FastMCP exposes the streamable-http endpoint at /mcp, not at the root. Using http://localhost:7683 without /mcp results in 404 (Not Found).
Docker
Build and run with Docker:
# Build the image
docker build -t law-scrapper-mcp .
# Run with STDIO transport (default)
docker run -it law-scrapper-mcp
# Run with HTTP transport on port 7683
docker run -it -p 7683:7683 -e LAW_MCP_TRANSPORT=streamable-http law-scrapper-mcp
Or use docker-compose:
# Run with STDIO transport
docker compose up
# Run with HTTP transport (set TRANSPORT=streamable-http in docker-compose.yml)
docker compose -f docker-compose.yml up
Configuration
All settings are configured via environment variables with the LAW_MCP_ prefix:
| Variable | Default | Description | |----------|---------|-------------| | LAW_MCP_TRANSPORT | stdio | Transport: stdio or streamable-http | | LAW_MCP_HOST | 0.0.0.0 | HTTP server host (when using streamable-http) | | LAW_MCP_PORT | 7683 | HTTP server port (when using streamable-http) | | LAW_MCP_API_TIMEOUT | 30.0 | HTTP request timeout in seconds | | LAW_MCP_API_MAX_CONCURRENT | 10 | Maximum concurrent API requests | | LAW_MCP_API_MAX_RETRIES | 3 | Maximum API request retries | | LAW_MCP_CACHE_METADATA_TTL | 86400 | Metadata cache TTL (24 hours) | | LAW_MCP_CACHE_SEARCH_TTL | 600 | Search results cache TTL (10 minutes) | | LAW_MCP_CACHE_BROWSE_TTL | 3600 | Browse results cache TTL (1 hour) | | LAW_MCP_CACHE_DETAILS_TTL | 3600 | Act details cache TTL (1 hour) | | LAW_MCP_CACHE_CHANGES_TTL | 300 | Changes tracking cache TTL (5 minutes) | | LAW_MCP_CACHE_MAX_ENTRIES | 1000 | Maximum cache entries | | LAW_MCP_DOC_STORE_MAX_DOCUMENTS | 10 | Maximum documents in Document Store | | LAW_MCP_DOC_STORE_MAX_SIZE_BYTES | 5242880 | Maximum Document Store size (5 MB) | | LAW_MCP_DOC_STORE_TTL | 7200 | Document Store TTL (2 hours) | | LAW_MCP_CIRCUIT_BREAKER_THRESHOLD | 5 | Failures before circuit breaker opens | | LAW_MCP_CIRCUIT_BREAKER_RECOVERY_TIMEOUT | 60.0 | Seconds before trying recovery | | LAW_MCP_CIRCUIT_BREAKER_HALF_OPEN_MAX_CALLS | 3 | Test calls in half-open state | | LAW_MCP_LOG_LEVEL | INFO | Log level: DEBUG, INFO, WARNING, ERROR | | LAW_MCP_LOG_FORMAT | text | Log format: text or json |
Example environment configuration:
export LAW_MCP_TRANSPORT=streamable-http
export LAW_MCP_PORT=7683
export LAW_MCP_LOG_LEVEL=DEBUG
export LAW_MCP_CACHE_METADATA_TTL=86400
Tools reference
Law Scrapper MCP provides 13 tools for legal research and analysis:
1. getsystemmetadata(category)
Retrieve system metadata for filtering and searching legal acts.
Parameters:
category(string, default: "all") - Metadata category: "keywords", "publishers", "statuses", "types", "institutions", or "all"
Returns: Keywords, publishers, document types, statuses, and institutions available in the system
Examples:
- Get all available search keywords
- Retrieve all legal document types
- List all publishers (DU, MP)
- Get all document statuses
- Get complete system metadata
2. searchlegalacts(publisher, year, keywords, detail_level, status, type)
Search for legal acts with advanced filtering options.
Parameters:
publisher(string) - Publisher code: "DU" (Dziennik Ustaw) or "MP" (Monitor Polski)year(integer) - Publication year (e.g., 2024)keywords(string) - Search keywords (AND logic - use multiple searches for OR)detail_level(string, default: "standard") - Response detail: "minimal", "standard", or "full"status(string, optional) - Document status filtertype(string, optional) - Document type filter
Returns: List of matching legal acts with metadata
Search note: Multiple keywords use AND logic. Search one keyword at a time for OR behavior.
Examples:
- Search DU 2024 for "environment protection" acts
- Find all MP 2023 acts with status "active"
- Search for COVID-19 related legislation
- Find acts by specific type (e.g., "regulation")
- Get minimal detail results for quick scanning
3. browseacts(publisher, year, detaillevel)
Browse all legal acts published in a specific year by publisher.
Parameters:
publisher(string) - Publisher code: "DU" or "MP"year(integer) - Publication yeardetail_level(string, default: "standard") - Response detail: "minimal", "standard", or "full"
Returns: Complete list of acts published in the specified year
Examples:
- Browse all DU acts from 2024
- Get minimal details of all MP acts from 2023
- Browse full details of DU 2022 legislation
- Get an overview of acts by publisher and year
- Track legislation published in a specific year
4. filterresults(resultsetid, pattern, field, typeequals, ...)
Filter and narrow down previously retrieved search/browse/changes results.
Parameters:
result_set_id(string) - Result set ID from a previous search/browse/changes call (e.g., "rs_1")pattern(string, optional) - Regex pattern for text search (supports OR: "podatek|VAT|akcyza")field(string, default: "title") - Field to search: "title", "eli", "status", "type", "publisher"type_equals(string, optional) - Exact match on document type (e.g., "Ustawa", "Rozporządzenie")status_equals(string, optional) - Exact match on status (e.g., "akt obowiązujący", "akt uchylony")year_equals(integer, optional) - Exact match on publication yeardate_field(string, optional) - Date field for range filter: "promulgationdate" or "effectivedate"date_from/date_to(string, optional) - Date range (YYYY-MM-DD)sort_by(string, optional) - Sort field: "title", "year", "pos", "promulgation_date", etc.sort_desc(boolean, default: false) - Sort descendinglimit(integer, optional) - Maximum results to return
Returns: Filtered results with a new result_set_id for chained filtering
Examples:
- Filter search results to only "Rozporządzenie" type
- Search titles with regex "zdrow|apteka|lekar"
- Filter by date range and sort by promulgation date
- Chain filters: first by type, then by regex pattern
- Get top 10 most recent results
5. getactdetails(eli, loadcontent, detaillevel)
Retrieve detailed information about a specific legal act and optionally load its content.
Parameters:
eli(string) - Act identifier in format "PUBLISHER/YEAR/NUMBER" (e.g., "DU/2024/1")load_content(boolean, default: false) - Load act content into Document Store for section readingdetail_level(string, default: "standard") - Response detail: "minimal", "standard", or "full"
Returns: Act metadata (title, publication date, status, type, etc.), table of contents if load_content=true
Examples:
- Get metadata for act DU/2024/1
- Load act content for section-level reading
- Get full details including table of contents
- Retrieve act status and publication information
- Load multiple acts for comparison
6. readactcontent(eli, section)
Read content from a specific section of a loaded legal act.
Parameters:
eli(string) - Act identifier (must be loaded first via getactdetails with load_content=true)section(string) - Section to read (e.g., "Art. 1", "Chapter 2", "Preamble")
Returns: Content of the requested section
Workflow note: Must call getactdetails(eli="...", load_content=true) first, then use this tool.
Examples:
- Read Article 1 from loaded act
- Get Chapter 2 content
- Read the Preamble section
- Access specific numbered articles
- Navigate act by chapters
7. searchinact(eli, query)
Search for specific terms within a loaded legal act.
Parameters:
eli(string) - Act identifier (must be loaded first via getactdetails with load_content=true)query(string) - Search term or phrase
Returns: Matching sections with context and location
Examples:
- Find all mentions of "penalty" in loaded act
- Search for specific legal terms
- Locate articles containing "fine" or "punishment"
- Find definitional sections
- Search for specific references
8. analyzeactrelationships(eli, relationship_type)
Analyze legal relationships and references of an act (amendments, references, etc.).
Parameters:
eli(string) - Act identifierrelationship_type(string, default: "all") - Type: "amends", "amendedby", "references", "referencedby", or "all"
Returns: List of related acts and their relationships
Examples:
- Find which acts amend this legislation
- See what acts this legislation amends
- Get all legal references in the act
- Find acts that reference this legislation
- Analyze complete act relationship network
9. tracklegalchanges(datefrom, dateto, publisher, keywords)
Track legal changes and new acts within a date range.
Parameters:
date_from(string) - Start date (YYYY-MM-DD format)date_to(string) - End date (YYYY-MM-DD format)publisher(string, optional) - Filter by publisher: "DU" or "MP"keywords(string, optional) - Filter by keywords
Returns: Legal acts published in the date range
Examples:
- Track changes from 2024-01-01 to 2024-12-31
- Find new DU acts from last month
- Get changes published in past 7 days
- Track legislation on specific topics over time
- Monitor legal changes by publisher and date range
10. calculatelegaldate(days, months, years, base_date)
Calculate legal dates with intuitive sign convention.
Parameters:
days(integer, default: 0) - Days offset (+future, -past)months(integer, default: 0) - Months offset (+future, -past)years(integer, default: 0) - Years offset (+future, -past)base_date(string, optional) - Base date (YYYY, YYYY-MM, or YYYY-MM-DD format, defaults to today)
Returns: Calculated date and relative description
Sign convention: Positive = future, Negative = past
Examples:
- Get current date (call with no parameters)
- Calculate date 30 days in the future (+30)
- Calculate date 6 months in the past (-6 months)
- Calculate date 1 year from a specific date
- Calculate legal deadlines and periods
11. compareacts(elia, eli_b)
Compare metadata of two legal acts.
Parameters:
eli_a(string) - ELI identifier of the first act (e.g., "DU/2024/1692")eli_b(string) - ELI identifier of the second act (e.g., "DU/2024/1716")
Returns: Comparison of titles, types, statuses, dates, keywords overlap and differences
Examples:
- Compare two acts from the same year
- Compare old and new versions of legislation
- Identify metadata differences between related acts
12. listresultsets()
Display active result sets stored in memory.
Returns: List of result sets with IDs, query summaries, counts, and creation times
13. listloadeddocuments()
Display documents loaded into the Document Store.
Returns: List of loaded documents with ELIs, sizes, section counts, and timestamps
Document Store workflow
The Document Store pattern enables efficient content navigation and search within legal acts:
Workflow steps
- Load an act - Call
get_act_details(eli="DU/2024/1", load_content=true)to load the act into the Document Store - Read sections - Use
read_act_content(eli="DU/2024/1", section="Art. 1")to read specific sections - Search within act - Use
search_in_act(eli="DU/2024/1", query="penalty")to find terms
Benefits
- Efficient memory usage (configurable max documents and TTL)
- Fast section-level navigation without refetching
- Search within loaded acts without API calls
- Automatic content processing (PDF→text, HTML→Markdown)
Configuration
LAW_MCP_DOC_STORE_MAX_DOCUMENTS- How many acts to keep in memory (default: 10)LAW_MCP_DOC_STORE_MAX_SIZE_BYTES- Maximum memory usage (default: 5 MB)LAW_MCP_DOC_STORE_TTL- How long to keep acts in memory (default: 2 hours)
Project structure
law-scrapper-mcp/
├── src/law_scrapper_mcp/
│ ├── __init__.py
│ ├── __main__.py # Entry point for python -m
│ ├── server.py # FastMCP app, lifespan, transport config
│ ├── config.py # Pydantic settings (env vars)
│ ├── logging_config.py # Structured logging setup
│ ├── models/ # Pydantic models
│ │ ├── enums.py # Enumerations
│
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [numikel](https://github.com/numikel)
- **Source:** [numikel/law-scrapper-mcp](https://github.com/numikel/law-scrapper-mcp)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.