
Thingery
io.github.thingery由 GitHub 帳號 thingery 發布v0.1.3更新於 Oct 29, 2026
Open item database and MCP server for AI agents to list, find, and trade second-hand goods.
概覽
面向二手商品開放市場的 MCP 伺服器:可搜尋商品、帶圖刊登商品,並在買賣雙方之間完成訂單流程。
- 可以做什麼
- 檢視商品分類與屬性欄位結構,並以語意加關鍵字搜尋,支援價格、分類、狀況與屬性篩選
- 依 id 取得單一商品,包括仍待上傳照片的待刊登商品
- 刊登與管理自己的商品:建立、上傳照片、調整價格或狀態、依狀態列出
- 處理訂單:下單、查看狀態與物流、取消、確認付款或收貨、提出爭議、撥款
- 把搜尋儲存為買家意圖,並在之後的工作階段取得新的媒合結果
- 適用情境
- 適合讓助理協助出售二手物品(辨識物品、撰寫並定價商品資訊、刊登上架),或依預算尋找二手商品並追蹤後續訂單。
- 執行需求
- 可使用託管的遠端端點,也可在本機執行:透過 stdio 執行 npm 套件,或自行架設,需要 Node 20 以及已安裝 pgvector 擴充並匯入隨附 schema 的 Postgres 資料庫。刊登與訂單類工具需要帳號與憑證——OAuth 登入或 Bearer API 金鑰;搜尋可匿名使用。自行架設需設定 DATABASE_URL,以及選用的嵌入、Stripe、EasyPost 與管理員金鑰。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Thingery,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Thingery
Thingery is the open item database and MCP server for AI agents to list, find, and trade second-hand goods.
Say "sell this" to your AI assistant — it identifies the item, writes the listing, prices it, and publishes it. Say "find me a used camera under €300" — it searches every listing and proposes the best one. Thingery is the shared database and the MCP tools underneath those agents.
- Free for everyone. No take rate, no platform lock-in.
- Open source (Apache-2.0). Self-host the whole thing, or use the flagship instance.
- Agent-native: every capability is an MCP tool; any LLM can drive it.
- Self-hostable: Postgres + pgvector + Node 20.
Chinese-market name: 物坊 (Wùfāng).
MCP tools
Order flow
Orders close a deal on-platform. Stripe mode (buyer protection: platform charges the
buyer, holds funds, pays the seller after delivery + dispute window) runs when the deployment
has Stripe configured and the seller finished payout onboarding; otherwise orders run in
off-platform mode — Thingery tracks state and deadlines, parties settle payment themselves.
States: pending → sold → label_issued → in_transit → delivered → payout_pending → paid_out
with disputed/cancelled/refunded off-ramps; deadlines are enforced by a server-side sweep
(unpaid cancels 24h, dispute window 48h, never-shipped disputes auto-refund 72h — defaults,
env-tunable). Design record: ADR 0003.
Sellers authenticate with OAuth (one-click sign-in from any MCP host — see below) or a
thg_... API key (Authorization: Bearer); search is anonymous.
Buyer alerts (saved searches)
A buyer who finds nothing good can save the search as an intent; when a matching listing
publishes later, their agent reads it as a match on the next session — no email, the
buyer's agent pulls my_matches (design record: ADR 0006).
Fan-out is bounded: each match is inserted at most once per (intent, item), at most 10 new
matches per buyer per day, at most 100 per published listing, and a seller never matches
their own listing.
Photo-required publishing
New listings need at least one photo to be visible to buyers — browse, search_items, and
category counts all exclude photoless listings (a single derived predicate; design record:
ADR 0005). What that means in practice:
create_listingwith zero images succeeds — the listing is created but pending: hidden from feeds, its item page shows placeholder art and isnoindex. The result carriesphoto_required,visible: false, andnext_stepspointing atadd_item_image(or the item page, where the owner can snap a photo in two taps).- The first photo publishes it — no second call needed.
add_item_imagereturnsvisible: true; pending items carryneeds_photo: trueeverywhere items are returned (get_item,my_listings, …). - Deleting the last photo returns the listing to pending (hidden again); pre-rollout listings are grandfathered and stay live without photos — on thingery.dev that means created before 2026-10-27; a self-hosted instance grandfathers whatever exists when it first deploys this version.
- Owners manage photos on the item page (upload, delete, reorder) via the session-cookie routes documented in docs/item-images.md.
Two ways to use it
- Zero-config (everyone): open
/chat.htmlon any deployment and talk to the Thingery assistant — describe an item to sell or to find. Searching needs no account; publishing needs a free one (/login.html, email + password; your MCP API key is shown after signup). The chat uses an LLM configured on the server (LLM_*env vars) — you bring the key, any OpenAI-compatible endpoint works; without it, chat is disabled while MCP and signup still work. - Bring your own agent (power users): point any MCP client at
/mcpand sign in with OAuth — Claude Desktop, ChatGPT connectors, VS Code and Inspector discover the sign-in flow automatically (RFC 9728 resource metadata + RFC 7591 dynamic client registration); you approve once on a consent screen and the host gets a rotatingthgo_token, with revoke-anytime at/apps. Prefer a key? The manualthg_...API key still works, and self-hosting is below (npx thingeryover stdio).
Quickstart
Pick your mode first — hosted and self-hosted expose the same MCP tools but not the same data: listings you create on the hosted service are visible to everyone; listings on your self-hosted instance live only in your database.
Mode A — hosted: search in one minute
No install. Add https://thingery.dev/mcp as a remote HTTP server in your MCP client
(Claude Desktop, ChatGPT connectors, VS Code, Inspector — see Connect an MCP client
below) and sign in with OAuth, or grab an API key at /login.html
(free account; the thg_... key is shown after signup). Searching needs no account at all —
verify the wire format with curl:
Responses come back as Server-Sent Events; the JSON-RPC result is on the data: line.
Mode B — self-hosted: the npm package
The thingery npm package runs the whole server
against your own Postgres. No git clone needed:
The server boots at http://localhost:3000 — /mcp, /browse, /healthz, and the HTTP
API. Create your account by opening /login.html —
your thg_... MCP key is shown right after signup. (On the pre-fix 0.1.2 release the
page 404'd — a packaging gap fixed after it; there you can still create the account
through the API — the key is returned exactly once, in the signup response:)
Then point any MCP client at http://localhost:3000/mcp with
Authorization: Bearer thg_... — or spawn it over stdio with the
npx config below.
Note: the npm package publishes at release cadence and can lag
mainon thingery.dev by days —/healthzreports the running version. If you need today's features, self-host from source instead:
Self-hosted from source (development)
No Docker? Local Postgres
npm run db:migrate needs a Postgres with the vector extension — the schema creates it
unconditionally, even in keyword-only search mode. On macOS, Homebrew's pgvector bottle
supports PostgreSQL 17 and 18 (not 16, the version the Docker setup uses — any of them works
for Thingery):
The default DATABASE_URL in .env.example already matches this setup. On any other
Postgres, run the same two SQL statements as the superuser and point DATABASE_URL at it.
Connect an MCP client
Fastest path: the zero-dependency quickstart —
node examples/quickstart/quickstart.mjs runs the whole first
workflow against the hosted server (search → publish a photo'd listing → fetch its public page,
~3 minutes including signup). Client-by-client configs (Claude Desktop, Cursor, VS Code,
Inspector, stdio, raw curl) and troubleshooting live in docs/integrations.md.
Most hosts (Claude Desktop, ChatGPT connectors, VS Code, Inspector) can sign in with OAuth:
just add https://thingery.dev/mcp (or your self-hosted URL) as a remote HTTP server — the host
discovers the sign-in flow, you approve once, and tokens rotate automatically. On thingery.dev
you can review and revoke connected applications at /apps.
Hosts without OAuth support use a thg_... API key (from /login.html) as a static bearer
token instead:
Omit the Authorization header for buyer-only (public search) usage — anonymous access to the
public read tools is always available. Design note: the decision record for the OAuth flow is
docs/adr/0002-mcp-oauth-onboarding.md; set
OAUTH_DISABLED=1 to turn OAuth routes off entirely (hosts then fall back to keys).
Run locally over stdio (npx)
Self-host without any web server — the package is thingery on npm
and runs as a local stdio MCP server against your own Postgres, spawnable by Claude Desktop and
similar clients:
THINGERY_API_KEY is optional; without it the server runs read-only (search + get). The
stdio server needs the same prerequisites as Mode B: a Postgres with the schema applied
(psql -f node_modules/thingery/db/schema.sql) and, for write tools, a key that exists in
that database (from that deployment's /login.html or /api/signup).
Troubleshooting
Try it with curl or a 5-line script
No client needed — plain JSON-RPC over HTTP works (the quickstart is a single zero-dependency Node file built on this):
Responses come back as Server-Sent Events; the JSON-RPC result is on the data: line.
Use an agent framework (LangChain, LlamaIndex, Composio)
Framework toolkits reach the same /mcp endpoint over streamable HTTP — copy-paste
quickstarts with verified end-to-end tool calls live in
examples/integrations/. Client setup for Claude Desktop,
Cursor, VS Code, Inspector and plain HTTP is in docs/integrations.md.
Configuration
Copy .env.example to .env. Key variables:
Order-flow windows and abuse caps (PAYMENT_DEADLINE_HOURS, DISPUTE_WINDOW_HOURS,
PICKUP_AUTOCONFIRM_DAYS, MAX_PENDING_ORDERS_PER_BUYER, …) are documented inline in
.env.example with their defaults.
Agent skills
skills/sell-item— the seller pipeline: photos → identified item → priced listingskills/find-item— the buyer pipeline: intent → scored matches → one best proposal → saved-search alerts
Data conventions
- Prices are integer cents:
12500= EUR 125.00 - Conditions:
new,like_new,good,fair,poor - Shipping tiers:
locker(shoebox-sized),parcel(≤30kg),bulky(furniture),local(pickup) - Machine discovery:
llms.txt·agents.json
Flexible schema
No fixed column set can cover sneakers, cameras and sofas at once, so the Item Graph is a hybrid:
- Rigid core columns for what every item shares: identity, price, condition, status, category, shipping estimation, embedding. These drive indexing and business logic.
attributes JSONBfor category-specific fields (size_eu,colorway,shutter_count,ISBN...), GIN-indexed for containment filters ({"size_eu": 43}) and flattened into the semantic embedding so they're meaning-searchable too.- A
categoriesregistry that declares expected attribute definitions per category.create_listingvalidates declared keys (types, required, enums) but unknown keys pass through — flexible by design, and federation-friendly since instances can diverge on attributes without breaking sync. Agents self-serve the schema viadescribe_category. sellers.profile JSONBfor user-side flexibility (locale, currency, notification prefs, negotiation mandates) — reserved for upcoming features.
Growth path: when an attribute becomes a hot filter, promote it to a Postgres generated column + index — no API change needed.
Which undeclared keys are actually in use is discoverable too: describe_category returns undeclared_in_use — undeclared attribute keys observed on active listings from multiple sellers, with item and distinct-seller counts. These keys are never validated (they pass through as-is), so treat them as search hints, not contracts — a signal of what buyers can filter on today.
Reading undeclared_in_use as an agent:
- It lists at most 20 keys, and only keys carried by ≥2 active listings from ≥2 distinct sellers. The field is omitted entirely when no key qualifies.
- Values are free-form: the same undeclared key can hold different values (even different types) on each listing. Use the key in
search_itemsattribute filters — they match any key, declared or not — but never treat one listing's value as the category's contract. - Writes are shape-capped on
create_listingandupdate_listing: at most 64 attribute entries, keys up to 128 chars, string values up to 500 chars. Over the cap, the call fails withinvalid_attributes.
Roadmap
Order state machine— shipped: orders with Stripe Connect payouts, carrier webhooks, disputes, and deadline sweeps (ADR 0003). Next: live-mode Stripe after legal/ToS sign-off.- Seller skill upgrade — photo capture shipped: frictionless item-page capture, placeholder art, and photo-gated publishing (ADR 0005). Comparable-based pricing is deferred until listings are numerous enough to be real comparables.
- Buyer alerts — next up: "new match for your intent" event stream.
- Federation protocol — instance-to-instance sync so anyone can host a node of the Item Graph. Deferred.
- Agent-to-agent negotiation — bounded-mandate negotiation between buyer and seller agents. Deferred.
We'll revisit federation and negotiation when there's real traction: more than 10 new listings per week for 2 consecutive weeks, or concrete pull from self-host adopters.
Security
What's verified and what isn't: docs/security-note.md. To report a vulnerability privately, see SECURITY.md.
Contributing
Built by an agent team with a human architect — see AGENTS.md for the working
conventions. PRs welcome; CI (typecheck, build, tests) must pass. New here? Start with
docs/community.md — good first issues, dev setup in under 10 minutes,
and where to ask questions.
License
來源:README.md,提交 8c8872e
工具
0版本歷史
3- v0.1.3最新Oct 29, 2026
- v0.1.2Oct 25, 2026
- v0.1.1Oct 12, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分