Verified 2026-05-03 against a real Chrome browser: POSTs to
/KararlarGenelKurul/DataTablesList consistently return HTTP 418
with the WAF block page "Bilgi Güvenliği Politikaları Gereği
Kısıtlanmıştır", regardless of headers, cookies, CSRF token, or
form payload. The block is server-side at sayistay.gov.tr and
cannot be worked around client-side. The Temyiz Kurulu and Daire
endpoints are unaffected (29k/22k records still return normally).
Detect the 418 + WAF marker in all three search methods and raise
a clear RuntimeError explaining it is an upstream restriction,
instead of the cryptic "Client error '418 I'm a teapot'" that
hides the real situation from MCP clients.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Token-optimization commit e34d81b tightened RekabetDecisionSummary
fields from Optional[str]/Optional[HttpUrl] to plain str with ""
defaults, but client.py kept passing None for unparsed cells and
HttpUrl(...) for URLs. Pydantic v2 rejected both, the broad
except Exception swallowed every row, and decisions came back []
while total_records_found stayed populated.
Default unparsed string fields to "" and pass URL strings directly
to the model. Verified against the live API for empty args,
PdfText filter, and KararTuru filter.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces two tools backed by the gib.gov.tr public JSON API
(reverse-engineered from the Next.js SPA chunks):
- search_gib_ozelge: keyword, ozelgeNo, kanunNo, date-range, paging
over 18k+ Revenue Administration tax rulings. Simple YYYY-MM-DD
dates are auto-expanded to ISO 8601 to satisfy the backend.
- get_gib_ozelge_document_markdown: fetch a single ruling by numeric
id and return 5000-char paginated Markdown with a metadata header
block (title, ozelgeNo, tarih, kanun, kaynak).
Also prunes stale auth/Fly.io-era entries from uv.lock.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add Insurance Arbitration Commission integration with Tavily search
and direct PDF download for 64 quarterly journal issues (2010-2025).
Tools:
- search_sigorta_tahkim_decisions: Search via Tavily API
- get_sigorta_tahkim_document_markdown: PDF download + paginated markdown
- search_within_sigorta_tahkim_issue: Keyword search within individual
decisions of a journal issue, with Turkish İ/I case folding support
Total tools: 25 (was 22)
Monkey-patch JSONRPCNotification to use extra="forbid" so that
requests with "id": null are no longer misclassified as notifications
(202 Accepted). They now correctly fail validation and return a
-32600 Invalid Request error.
Changed source_url from API endpoint (bedesten.adalet.gov.tr/document/{id})
to user-facing URL (mevzuat.adalet.gov.tr/ictihat/{id}) for direct browser access.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace EmbeddingGemma local model with OpenRouter API integration
- Use google/gemini-embedding-001 model via OpenRouter (3072 dimensions)
- Add conditional tool registration: auto-disable if OPENROUTER_API_KEY not set
- Add openai and numpy dependencies to pyproject.toml
- Update .env.example with OPENROUTER_API_KEY configuration
- Fix ruff lint issues in semantic_search module
Reverse engineered the AES-256-CBC encryption used by KİK's Angular web
application to generate document URL hashes from numeric IDs.
Key findings:
- Algorithm: AES-256-CBC with PKCS7 padding
- Key location: ekapv2.kik.gov.tr module 21554 (environment config)
- Output format: IV (16 bytes hex) + Ciphertext (16 bytes hex) = 64 chars
Changes:
- Added encrypt_document_id() static method to KikV2ApiClient
- Updated get_document_markdown() to auto-encrypt numeric gundemMaddesiId
- Added cryptography>=44.0.0 dependency for AES encryption
- Both primary and fallback URL paths now support encryption
This enables direct document retrieval from numeric search result IDs
without requiring the pre-encrypted hash from the web interface.
ImportError only catches import failures. Browser launch errors
(executable not found) are runtime exceptions. Changed to catch
all Exception types to properly fallback to curl.
- Add global _health_check_client variable for singleton pattern
- Define get_or_create_health_check_client() function for health checks
- Add cleanup for health check client in perform_cleanup()
Fixes Bedesten health check error: "name 'get_or_create_health_check_client' is not defined"
- Fixed 10 tools to avoid / patterns in JSON schemas
- All tools now return Dict[str, Any] with .model_dump() applied
- Affected tools:
* search_emsal_detailed_decisions
* get_emsal_document_markdown
* search_uyusmazlik_decisions
* get_uyusmazlik_document_markdown_from_url
* search_rekabet_kurumu_decisions
* get_rekabet_kurumu_document
* search_sayistay_unified
* get_sayistay_document_unified
* search_kvkk_decisions
* get_kvkk_document_markdown
- Gemini CLI should now be able to load and use all MCP tools without schema validation errors
- Add comprehensive KİK v2 MCP implementation
- Support for all three decision types: uyusmazlik, duzenleyici, mahkeme
- Tested with 826 total decisions across all types
- SSL legacy server support for compatibility
- Hash analysis and document ID encryption research completed
- Create fly-no-auth.toml configuration for free deployment
- Deploy to yargi-mcp-free.fly.dev with ENABLE_AUTH=false
- Single machine deployment for development/testing use
- Update CLAUDE.md with new deployment endpoints and usage info
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive null safety checks for document API response fields
to prevent null type errors when accessing doc_response.data properties.
- Check if doc_response.data exists before accessing
- Validate content and mimeType fields before processing
- Add error handling for base64 decoding failures
- Provide descriptive error messages for debugging
- Prevents 'null type' errors in get_bedesten_document_markdown
Resolves 'cannot convert undefined or null to object' error in search_bedesten_unified
by adding proper null checking for response.data.emsalKararList and response.data.total
fields before accessing them.
- Add hasattr() and null checks for response.data fields
- Provide safe defaults: empty list for emsalKararList, 0 for total
- Prevents TypeError when API returns undefined/null fields
- Matches null safety pattern used in other search tools
- Copy clean v0.1.6 version without extra endpoints
- Fix JSON syntax error in OAuth metadata
- Remove all complex additional endpoint logic
- Keep only core OAuth flow endpoints
Fixes startup crash with SyntaxError
- Disable issuer validation in BearerAuthProvider (issuer=None)
- Simplify authentication condition (remove auth_enabled check)
- Revert CORS middleware to simple configuration
- Fix OAuth metadata endpoint to match v0.1.6
- Apply conditional auth only to MCP server creation
Critical fixes for Claude AI tools discovery
- Remove Redis session store initialization from create_app()
- Revert to simple token counting middleware only
- Fix session management issue causing tools to appear then disappear
- This matches the exact v0.1.6 implementation that was working
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Use mcp_server.http_app(path='/') like v0.1.6
- Use redirect_to_slash function name like v0.1.6
- This should fix 'Not Found' error when accessing /mcp/ endpoint
- Use api_route with all methods instead of just GET
- Claude AI makes POST/HEAD requests to /mcp endpoint
- This should fix 405 Method Not Allowed error
- Mount MCP app at /mcp/ with trailing slash (not at root)
- Simple GET redirect from /mcp to /mcp/ (not api_route)
- Set lifespan context after mounting (not in FastAPI constructor)
- This should fix Claude AI connection drops after OAuth
- JWT tokens are issued by clerk.yargimcp.com not accounts.yargimcp.com
- Enable issuer validation with correct domain for FastMCP Bearer auth
- This fixes tools not being visible after successful OAuth authentication
- Revert asgi_app.py to v0.1.6 approach with path='/' for MCP app
- Fix uyusmazlik client: use individual httpx.AsyncClient instead of shared
- Fix health check: use individual httpx.AsyncClient instead of shared
- Remove shared_health_check_client that was causing connection drops