feat: get_seller_listings — list another seller's other listings - #13
Open
asklepios-png wants to merge 7 commits into
Open
feat: get_seller_listings — list another seller's other listings#13asklepios-png wants to merge 7 commits into
asklepios-png wants to merge 7 commits into
Conversation
The adinput API is two-phase: PUT .../update only stores a draft revision; the live ad changes only after the commit step (productcontext + POST /order/choices — the same sequence create() uses). edit_listing stopped after the PUT and inferred success from the returned ETag, so edits were never published while the tool reported success. - ListingsAPI.edit(): update → publish (Basic) → read-back verification against adview (staggered ~5.5 min window; propagation takes minutes). Raises instead of ever reporting an unverified success. - update() now raises on meta-data validation violations (the API returns them with HTTP 200). - MCP edit_listing and CLI listings edit routed through edit(); set_price() too. CLI checkmark output made cp1252-safe. - Regression tests (mocked client): publish ordering, read-back mismatch, violation handling. Red-green verified. - CONTEXT.md added: root cause, live findings (order/choices is the commit; publish_free_ad POSTs 404; edited timestamp = revision time). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # README.md
…elivery/mcp-tool)
The adview response carries the seller only in `meta` (ownerId / ownerUrn);
the `ad` body has no seller field, and the MCP get_listing wrapper dropped
meta entirely. That made it impossible to tell whether two listings belong
to the same person.
- owner_from_adview(): pure extraction, shared by library and MCP wrapper
- ListingsAPI.owner(ad_id) -> {"owner_id", "owner_urn"}
- MCP get_listing now returns owner_id
Groundwork for a "seller's other listings" lookup. CONTEXT.md records the
recon behind the next phases: the tori.fi profile page renders its ad list
server-side (podlet trust-public-profile-layout) with no JSON endpoint, so
the remaining routes are a SPiD web session inside torium, a browser
adapter, or a mobile capture to find the native gateway path.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… adapter recommended Findings from the 2026-08-10 investigation into "seller's other listings": - Headless SPiD web session: dead end. type=session exchange yields identity cookies but not an interactive SSO session; OAuth authorize bounces to OTP email-login, and login initiation is client-side JS. - Native gateway: TRUST-PROFILE-API exists and its X-Client-Id filter is satisfiable, but the ads sub-resource path is not discoverable by guessing (service double-prefixes /public; all guesses 404). Needs mobile capture. - Dead: AD-SUMMARIES ?ownerId is ignored (always own listings); SEARCH-QUEST seller/owner/user_id params -> 400. - Profile ad list is pure SSR (podlet trust-public-profile-layout), no client-side JSON endpoint. Browser adapter is the shippable route. - Pagination: seller 451218839 (28 active) renders all cards at once, no load-more / infinite scroll / page param. 50+ still unverified. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lla endpointilla
Kaapattiin Android-appin liikenteestä oikea gateway-endpoint (emulaattori API 33
+ HTTP Toolkit): GET /org/SEARCH_ID_BAP_COMMON?client=…&orgId={owner_id}&include_anonymous=false,
finn-gw-service SEARCH-QUEST-RC, ei X-Client-Id:tä. orgId == adview'n meta.ownerId,
joten olemassa oleva owner() syöttää suoraan. Vastaus = päähaun docs-muoto; sivutus
page-parametrilla metadata.paging.last:iin asti.
Recon-oletus (TRUST-PROFILE-API + X-Client-Id) oli väärä — oikea on hakuperheen
/org/{searchKey}?orgId=, sama palvelu jonka torium jo osaa allekirjoittaa, joten
_request-koneistoa ei tarvinnut laajentaa.
- listings.seller_ads(owner_id, max_results=None): sivuttava haku
- MCP-työkalu get_seller_listings(ad_id): owner -> seller_ads -> kompakti lista
- tests/test_seller_ads.py (4 kpl, mock-client)
Live-vahvistettu 2026-08-11: myyjä 451218839 -> 28 ilmoitusta, otsikot/hinnat täsmäävät.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Personal note: this one scratches an itch I've been chasing for weeks — reliably pulling up another seller's other listings from just one of their ads. I'd tried a few dead ends (a profile-API path that always 404'd, the SSR web profile with no JSON endpoint, a headless SPiD session that needed OTP) before capturing the app's actual traffic finally revealed it was hiding in the search family all along ( |
Pinnaamaton mcp veti tuoreessa asennuksessa mcp 2.0.0:n, josta mcp.server.fastmcp on poistettu, joten mcp_server.py:n import kaatuu eikä torium-mcp käynnisty. uv.lock on .gitignoressa, joten tuore asennus ei saa toimivaa lukitustakaan. Pinni pitää serverin käynnistyskelpoisena myös puhtaassa asennuksessa (esim. PR:n arviointi). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
get_seller_listings(ad_id)— list the other active listings by the same seller as a given ad. This completes the "who else is this seller selling?" flow that began withowner_idextraction from the adviewmetablock.How the endpoint was found
The seller-listings gateway endpoint is not visible from the website — the public profile page is fully server-rendered (the browser never sees the upstream call, and there's no client-side JSON endpoint). It was captured from the Android app's own traffic (emulator + HTTP Toolkit TLS interception):
Key points that made this small:
orgIdis exactly theownerIdalready carried in an adview'smetablock, solistings.owner(ad_id)feeds straight in — no new identifier needed.SEARCH-QUEST-RCservice and BAP search key as the public search, so the existingfinn-gw-keysigning works unchanged — no changes to_request.docs, so mapping is trivial.Changes
listings.seller_ads(owner_id, max_results=None)— paginates via thepageparam untilmetadata.paging.lastget_seller_listings(ad_id)— resolves owner → seller_ads → compact listtests/test_seller_ads.py— 4 tests (mock client, no network): single page, pagination,max_resultscap, empty sellerVerification
owner(ad_id)→owner_id→ 28 listings returned, titles and prices matching the app🤖 Generated with Claude Code