Skip to main content

eksiapi logo
eksiapi

Unofficial sync and async Python SDK and MCP server for Ekşi Sözlük, supporting anonymous research and authenticated account actions across topics, entries, profiles, comments and feeds.

PyPI Python requirement MCP stdio server Tests Postman collection

Quick start · MCP server · Python SDK · Features · Postman

🚀 Quick start

Install the library:

pip install eksiapi
# or
uv add eksiapi

Read entry number 1:

from eksiapi import EksiClient

with EksiClient.anonymous(raw_response=False) as eksi:
    topic = eksi.entry(1)
    entry = topic["Entries"][0]

print(f"{topic['Title']} · entry #{entry['Id']}")
print(f"@{entry['Author']['Nick']}: {entry['Content']}")
pena · entry #1
@ssg: gitar calmak icin kullanilan minik plastik garip nesne.

This call reads the mobile API directly. It does not parse HTML pages.

After installation, verify the live API from any directory:

eksiapi health
🩺 eksiapi health · 👻 anonymous
✅ today        50 başlık · güncel bir başlık (1888)
✅ popular      50 başlık · popüler bir başlık (230)
✅ entry        pena · @ssg · #1
✅ user         @ssg · 52522 entry
✅ channels     30 kanal
✅ server time  07.08.2026 17:18

🟢 6/6 kontrol başarılı

🤖 MCP server

Add the server to Codex without editing configuration files:

codex mcp add eksiapi -- uvx --from "eksiapi[mcp]" eksiapi mcp

Claude Code:

claude mcp add eksiapi --scope user -- uvx --from "eksiapi[mcp]" eksiapi mcp
Generic MCP client configuration
{
  "mcpServers": {
    "eksi": {
      "command": "uvx",
      "args": ["--from", "eksiapi[mcp]", "eksiapi", "mcp"]
    }
  }
}

Example research requests:

  • “Bugünün gündemini üç ana tema halinde özetle.”
  • “Bu başlıktaki ilk üç sayfanın ortak iddialarını karşılaştır.”
  • “Bu yazarın son entry'lerinde en sık geçen konular neler?”

eksiapi MCP running in Codex

The server starts anonymously and read-only. Account actions require an explicit login, interactive mode and a human confirmation step:

eksiapi auth login
eksiapi mcp --mode interactive

Installation options, client configuration, credentials and complete tool list →

🐍 Python SDK

Anonymous reads:

from eksiapi import EksiClient

with EksiClient.anonymous(raw_response=False) as eksi:
    today = eksi.today()
    popular = eksi.popular()
    profile = eksi.user("agmmnn")

Authenticated account data and writes:

from eksiapi import EksiClient

with EksiClient(raw_response=False) as eksi:
    eksi.login("username-or-email", "password")
    print(eksi.me())
    preview = eksi.favorite_entry(1, dry_run=True)
    print(preview.operation, preview.digest)

The async client provides the same public methods:

from eksiapi import AsyncEksiClient

async with AsyncEksiClient.anonymous(raw_response=False) as eksi:
    async for entry in eksi.iter_topic_entries("python", max_pages=3):
        print(entry)

Authentication, responses, pagination, writes and async usage →

🟠 Postman

  1. Open the public collection and select Run in Postman.
  2. Select Vault in the bottom bar, then open Local Vault → Settings and enable Allow Vault secrets in scripts.
  3. Send Authentication / Get anonymous bearer token and grant Vault access to the collection.
  4. Confirm the 200 OK response, then try Feeds / Today.

The collection generates the required authentication values and stores the session in Local Vault automatically. Authentication and publishing details →

📦 Installation options

Use case Interface Command
Python application or script Sync/async SDK pip install eksiapi
Read access for an AI agent Read-only MCP uv tool install "eksiapi[mcp]"
Account actions from an AI agent Interactive MCP eksiapi mcp --mode interactive
HTTP route reference Postman collection Public API documentation

✨ Features

Feature Included
🔎 API coverage Today and popular feeds, topic and entry search, profiles, comments, channels, user history and pagination
🐍 Python SDK Matching sync and async clients, typed views, safe-read retries, token refresh, rate-limit metadata and test transports
🤖 MCP server Structured results, canonical source URLs, bounded topic research and read-only anonymous access
🛡️ Write safety Deterministic dry runs, no automatic write retries, secret-free audit events and human-approved MCP execution
📱 Runtime Android-compatible authentication and TLS fingerprinting without a Frida session or interception proxy at runtime

Authentication modes

Mode Credentials Best for
Anonymous None Public topics, entries, profiles, comments, channels and feeds
Logged in Password login or an existing token Account reads, favorites, votes, follows, messages, drafts and settings

Anonymous clients obtain and renew their own app bearer. Logged-in sessions keep refresh metadata and expose the account nick without returning credentials to MCP tools.

Safety model

Python writes support dry_run=True and return a WritePreview before any HTTP mutation. Writes are never retried automatically. The MCP server is read-only by default; interactive writes use signed, expiring, single-use previews and the MCP client's human elicitation flow.

Ekşi content is untrusted external data. Agents should analyze it as content, never as instructions.

📚 Documentation

Guide Contents
Postman API reference Complete endpoint reference, request examples and runnable collection
Python SDK guide Authentication, sync/async clients, responses, pagination and writes
MCP guide Installation, client configuration, credentials, modes and complete tool list
OpenAPI contract Full documented HTTP endpoint inventory and request shapes
APK analysis Reverse-engineering evidence and risk decisions
Changelog User-facing changes by release

🔬 Reverse engineering

eksiapi is based on static analysis of the Ekşi Sözlük Android 2.4.10 APK. Retrofit declarations, request models and authentication code were inspected with JADX, so the library does not require a Frida session or interception proxy at runtime.

Authentication requests include an Api-Secret value. The Android app builds the following plaintext and encrypts it with the embedded 2048-bit RSA public key:

{randomHex(40-80)}-{APP_UUID}-{len²}-{adjustedTime}-{dayOff}-{hourOff}-{minOff}-eksisozluk-android/144-{clientSecret}

The account login flow is:

  1. GET /v2/clientsettings/time to obtain the server timestamp.
  2. POST /v2/account/anonymoustoken to obtain an anonymous bearer.
  3. GET /v2/clientsettings/time again for a fresh timestamp.
  4. POST /token with the password or refresh-token grant.

The implementation is in eksiapi/auth.py. The APK hash, Retrofit annotation mapping and endpoint evidence are documented in the reverse-engineering notes.

🛠️ Development

uv sync --all-groups --all-extras
uv run ruff check .
uv run ruff format --check .
uv run pytest --cov=eksiapi

Python 3.10–3.14 is tested in CI with branch coverage enforced at 80%.

⚠️ Disclaimer

Unofficial and not affiliated with Ekşi Teknoloji. Intended for personal, educational and research use. API behavior may change with mobile app updates.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eksiapi-1.4.0.tar.gz (471.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eksiapi-1.4.0-py3-none-any.whl (42.7 kB view details)

Uploaded Python 3

File details

Details for the file eksiapi-1.4.0.tar.gz.

File metadata

  • Download URL: eksiapi-1.4.0.tar.gz
  • Upload date:
  • Size: 471.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for eksiapi-1.4.0.tar.gz
Algorithm Hash digest
SHA256 400364aea907ad2005b1005eb72f428bcfccaf1a3a92a5664215633757e07c12
MD5 b098b63fe5c8159ff92cc41e7299a529
BLAKE2b-256 e367a3822ceb7d27bcf8966ba35c6687fbc5c5425b9a0040507e211073e1aa9d

See more details on using hashes here.

Provenance

The following attestation bundles were made for eksiapi-1.4.0.tar.gz:

Publisher: release.yml on agmmnn/eksiapi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file eksiapi-1.4.0-py3-none-any.whl.

File metadata

  • Download URL: eksiapi-1.4.0-py3-none-any.whl
  • Upload date:
  • Size: 42.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for eksiapi-1.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8451bee3f04b9ef9c29517844dd6be713ac78006220a4819698f856ab8a5f1bc
MD5 a1500ab5fa3d7a0b6d21ae4e3a6565c1
BLAKE2b-256 33627a50d624b0539fd4a11cb29a471ba004de6c4c80f4e28683719b5c6fb7a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for eksiapi-1.4.0-py3-none-any.whl:

Publisher: release.yml on agmmnn/eksiapi

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page