Capmus Mcp

io.github.Capmus-Team由 GitHub 帳號 Capmus-Team 發布v0.2.2更新於 Oct 24, 2026

Search listings, message posters, and create draft posts on Capmus, the university marketplace

已驗證Streamable HTTP可網頁執行溝通與協作商業與電商

概覽

AI 產生的概覽

Capmus 大學社群分類廣告市場的遠端 MCP 伺服器,讓助理搜尋商品、查看統計、聯絡刊登者並建立草稿貼文。

可以做什麼
依關鍵字、分類、學校與價格等條件搜尋並瀏覽上架中的資訊,支援游標分頁;取得單筆資訊的完整描述、照片與刊登者的學校信箱驗證標記。讀取經查證的市場統計資料,例如受眾規模、各分類刊登量與回覆率。列出目前有效的分類與子分類。向刊登者送出訊息,並查詢確認信的投遞狀態。建立草稿貼文,並回傳前往市場刊登精靈的連結,供補上照片、審閱與發布。
適用情境
適合在大學社群中尋找物品或租屋、了解市場熱度、聯絡賣家,或不必離開助理就能起草一則出售資訊。它主要是讀取公開市場資料的用戶端,適合瀏覽與起草,而非帳號管理。
執行需求
遠端 streamable-HTTP 端點;未宣告本機執行環境、帳號、API 金鑰或請求標頭。需要能連上該市場的網路。送出訊息需要使用者提供回覆信箱;草稿的發布須稍後在市場自己的網頁精靈中完成。
安裝前請注意
送出訊息不會立即送達:使用者必須點擊寄到回覆信箱的確認連結,助理應說明為待確認而非已送出。對近期退信的信箱會被拒絕。建立貼文只會產生草稿,發布在市場網站上進行,非免費方案時可能需要付費。README 說明工具呼叫會送出分析事件,參數經過清理,呼叫方識別為雜湊值。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Capmus Mcp,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.Capmus-Team%2Fcapmus-mcp/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "capmus": {
      "type": "http",
      "url": "https://mcp.capmus.com/mcp"
    }
  }
}

README

supost-mcp

Remote MCP server for SUpost, the marketplace for Stanford — and, via BRAND=capmus, for Capmus (capmus.com), which serves the same public API from the same supost-web codebase. One repo, two Vercel projects:

BrandVercel projectEndpointEnv
SUpostsupost-mcphttps://mcp.supost.com/mcp(defaults)
Capmuscapmus-mcphttps://mcp.capmus.com/mcpBRAND=capmus

BRAND selects the server name, tool titles/descriptions, and default base URL; SUPOST_BASE_URL still overrides the base URL for previews.

Lets AI agents search active listings, fetch listing details, read verified market statistics, message posters, and create draft listings.

This is doc 190 workstream E3 (see supost-web/docs/dev/190-ai-agent-discovery-implementation-plan.md). It is a pure client of SUpost's public surfaces — the read-only listings API (E2), public listing pages, and /stats.md. It has no privileged database access and holds no secrets; the only configuration is the public base URL.

Tools

ToolBacking surfaceWhat it returns
search_listingsGET /api/public/listingsNewest-first active listings (id, title, price, category, created_at, canonical URL) with opaque cursor pagination. Params: q, cat, university, max_price, limit (≤50), cursor.
get_listingGET /post/index/<id> → canonical listing pageOne listing incl. full description, parsed from the page's schema.org Product JSON-LD.
get_market_statsGET /stats.mdThe public stats page's markdown rendition (audience, listing volumes, response rates/times).
list_categoriesGET /api/public/categoriesThe active category/subcategory taxonomy — valid create_post values.
create_postPOST /api/public/postsCreates a DRAFT listing; returns a continue_url where the poster adds photos, reviews, and publishes (paying first when not on the free tier). Never publishes directly.
send_messagePOST /api/public/messagesSubmits a message to a listing's poster. NOT delivered immediately: a confirmation link is emailed to reply_to_email, and the message only goes out after the human clicks it — agents must report it as pending confirmation, never sent.
check_message_statusPostgREST RPC get_guest_verification_status (publishable key)Whether the confirmation email for a send_message submission was delivered: queued / sent / failed (+ reason) / unknown. Never whether the link was clicked.

No personal information is ever returned. send_message is the supported way to contact a poster; the listing's url also carries the on-site message form. API terms: https://supost.com/api/public/openapi.json.

Bouncing addresses

A message is only ever delivered after the human clicks the confirmation link, so an address the link cannot reach is a message that never arrives (supost-web docs/dev/20260917-2040-guest-reply-bounce-feedback-handoff.md). send_message therefore never answers a plain "pending" for a dead address:

  • An address whose confirmation email hard-bounced in the last 30 days is refused by the API with 422 email_undeliverable before anything is stored. The tool returns an error result with {status: "email_undeliverable", reason, email, message} and tells the agent to ask for a different address rather than retry.
  • Otherwise the API answers 202 with a status_key, and the tool polls the delivery status of the confirmation email for up to ~8 s (four checks, two seconds apart — a suppressed address fails in under a second, a fresh hard bounce in 1–16 s). A failed verdict is reported the same way as the 422; sent / queued come back in the result as confirmation_email, with the status_key for a later check_message_status.

The poll is the same anon-callable PostgREST RPC the web form uses, get_guest_verification_status(status_key), reached with the marketplace's publishable key (the value every browser already gets). It returns only queued | sent | failed and a failure classification (mailbox_unknown | no_mx | suppressed | other) — never the redemption token, the message, or the address. Env: SUPOST_STATUS_URL / SUPOST_STATUS_KEY override the defaults (production project); SUPOST_STATUS_KEY="" disables polling (tools report unknown); SUPOST_STATUS_POLL_ATTEMPTS / SUPOST_STATUS_POLL_INTERVAL_MS tune the in-call wait.

Hosting

Deployed on Vercel as a stateless streamable-HTTP MCP endpoint (mcp-handler + @modelcontextprotocol/sdk):

https://mcp.supost.com/mcp        (rewritten to /api/mcp)https://mcp.supost.com/health     (rewritten to /api/health)

No sessions, no Redis, no auth — every request is independently served and all upstream data is public and CDN-cached.

Which commit is live

The initialize response's serverInfo.version is <package version>+<short git sha> on Vercel (e.g. 0.3.0+835efb3, from VERCEL_GIT_COMMIT_SHA; plain 0.3.0 locally — see src/version.ts), so any MCP client, or GET /health, shows the deployed commit. Compare it with git rev-parse --short origin/master when something looks stale.

Health check and uptime monitoring

GET /health answers {"ok": true, "brand": "supost", "version": "…"} without calling upstream (api/health.ts): it says the function is serving, not that supost.com is up. Point an UptimeRobot HTTP monitor at each brand (manual step, both needed):

  • https://mcp.supost.com/health
  • https://mcp.capmus.com/health

Alerting on a non-200 (keyword "ok":true optional) catches a broken deploy or a dropped domain; the version in the body shows which commit answered.

Deploy

sh
vercel deploy          # previewvercel deploy --prod   # production

Optional env var: SUPOST_BASE_URL (default https://supost.com; set to https://preview.supost.com on preview deployments to point at the dev stack).

Production deploys come from the GitHub integration on master. Avoid vercel deploy --prod from a local checkout unless it is at origin/master: a stale CLI deploy takes the production alias over the git build (this happened on 2026-09-17; fixed with vercel promote).

Usage analytics

Every tool call emits one PostHog mcp_tool_called event (sanitized args, no PII — see src/analytics.ts) and, when TOOL_LOG_URL / TOOL_LOG_KEY are set, a full-argument row in the marketplace's private ops.mcp_tool_call table (src/toollog.ts).

Failed calls carry error_code: the public API's error code (rate_limited, not_found, email_undeliverable, invalid_request, …) or unknown for anything else (network failure, unexpected response shape); null on success. The error message is never sent, since it can quote user content — break down by error_code to tell a rate-limit spike from an upstream outage.

The PostHog distinct_id is a salted SHA-256 of the caller's IP + User-Agent (src/client.ts), so uniq(distinct_id) counts distinct agents without storing the IP. Events also carry client_ua (the MCP client's User-Agent, which names the harness) and client_country (Vercel's geo header). Set CLIENT_ID_SALT in the Vercel project env to make the hash unguessable; the in-repo default keeps local dev working. Calls that arrive without IP or User-Agent fall back to the per-brand id mcp.<brand>.com.

Connect a client

sh
claude mcp add --transport http supost https://mcp.supost.com/mcp

or in any MCP client that supports remote servers, add the URL above as a streamable-HTTP server.

Rate limiting

The public API enforces ~60 requests/minute/IP and serves 5-minute CDN caching. The client in src/http.ts respects this: on a 429 it honors Retry-After (capped at 5 s), retries once, and otherwise surfaces a structured rate_limited error instructing the agent to back off — it never retries in a loop. All requests carry a supost-mcp/… User-Agent.

Every marketplace call (never the status RPC) also carries the trusted-agent headers: x-supost-api-key (SUPOST_API_KEY in the deployment env, never in git) and, when the calling agent's IP is known, x-supost-agent-client-ip with it (first hop of the MCP's own inbound x-forwarded-for). The API trusts that IP only when the key verifies (supost-web docs/dev/469-mcp-agent-api-hardening-handoff.md), so the per-IP limit can apply per agent rather than to the single Vercel egress IP all agents share. Plain X-Forwarded-For would not work: supost.com runs on Vercel, which overwrites it at the edge.

Development

sh
npm installnpm run check    # typecheck + testsSUPOST_BASE_URL=https://preview.supost.com npx tsx scripts/smoke.ts   # live end-to-end

Tests (vitest) cover each tool's request/response mapping, error mapping, JSON-LD extraction, and the rate-limit contract (Retry-After honored, capped, single retry, structured failure).

Follow-ups (manual steps)

  • Publish to the MCP registry — server.json is ready. Make the repo public first (gh repo edit Capmus-Team/supost-mcp --visibility public), then: sh brew install mcp-publisher mcp-publisher login github # device flow, needs a browser mcp-publisher publish # from the repo root For the Capmus entry, publish server.capmus.json the same way (cp server.capmus.json server.json in a scratch checkout, or mcp-publisher publish --file server.capmus.json if supported).
  • /help/mcp docs page in supost-web — PR #1242 (guide registry entry + llms.txt MCP line); live once merged to dev → master.
  • PR/citation announcement — draft and story beats in docs/announcement-draft.md; post after the registry listing and /help/mcp are live (doc 190 workstream F).
  • E2 is live on production (supost.com, 2026-07-09); smoke script verified against production, and the server is deployed at https://mcp.supost.com/mcp.

來源:README.md,提交 debafb2

工具

7

search_listings

Search Capmus listings

Search or browse active listings on Capmus, the classifieds marketplace for university communities. Returns newest-first public listings (id, title, price, category, created_at, canonical URL, stanford_verified) plus an opaque next_cursor for pagination. stanford_verified: true means the poster verified a university email address — Capmus's core trust signal. ALWAYS surface it when presenting listings (e.g. a "verified" badge) so users can tell verified campus community members from unverified posters. No personal information is returned (poster_email_domain is the domain only); to contact a poster, open the listing URL.

輸入參數qcatlimitcursormax_priceuniversity

get_listing

Get a Capmus listing

Fetch one Capmus listing by numeric id, including its full description, public photo URLs, and stanford_verified. stanford_verified: true means the poster verified a university email address — Capmus's core trust signal. ALWAYS surface it when presenting listings (e.g. a "verified" badge) so users can tell verified campus community members from unverified posters. Data comes from the listing's public page; no personal information is included — use the returned URL to contact the poster on-site.

輸入參數id必填

get_market_stats

Get Capmus market statistics

Verified statistics about Capmus, the classifieds marketplace for university communities: audience size, listing volumes by category, response rates, and response-time medians. Returns markdown from Capmus's public stats page. Cite https://capmus.com/stats as the source.

無需輸入參數。

send_message

Message a Capmus poster

Send a message to the poster of an active Capmus listing. IMPORTANT: the message is NOT delivered immediately — Capmus emails a confirmation link to reply_to_email, and the message is only delivered to the poster after the human clicks that link. Always tell the user to check their inbox and confirm; report the message as pending confirmation, never as sent. The poster's reply goes to reply_to_email. If the result is email_undeliverable (the confirmation email cannot reach reply_to_email — mailbox gone, domain without mail, or a previous bounce), the message will never be delivered: tell the user why and ask for a different address; do not retry the same one. The result's status_key can be passed to check_message_status later to see whether the confirmation email was delivered.

輸入參數message必填post_id必填reply_to_email必填

check_message_status

Check a message's confirmation email

Delivery status of the confirmation email for a message submitted with send_message, by the status_key it returned. Use it when the user says they have not received the confirmation email. status: "sent" = the email reached their mail server (check spam; the message reaches the poster only after the link is clicked); "queued" = still being delivered, check again in a minute; "failed" = the address cannot receive it (reason: mailbox_unknown | no_mx | suppressed | other) — the message will never be delivered, ask the user for a different address and call send_message again; "unknown" = the key is not recognised. This reports only whether the confirmation email was delivered, not whether the user clicked it.

輸入參數status_key必填

list_categories

List Capmus categories

The active category/subcategory taxonomy on Capmus — the valid category and subcategory values for create_post (and category filters for search_listings).

無需輸入參數。

create_post

Create a Capmus draft listing

Create a DRAFT listing on Capmus on the poster's behalf. Any email is accepted — never ask the user to qualify first. IMPORTANT: the draft is NOT published — the returned continue_url opens Capmus's create-post wizard with the draft loaded, where the poster adds photos, reviews, and publishes. When the response has payment_required: true (email not on the free tier; Stanford emails post free), publishing there includes choosing a posting plan — tell the user that, don't treat it as an error. Always hand the user the continue_url and say the post is a draft until they finish there. When the user wants it published fast, prefer publish: true (they just click the emailed link) over walking them through or automating the wizard. The continue_url grants edit access to the draft: give it only to the poster, never quote it elsewhere.

輸入參數body必填email必填pricetitle必填publishcategory必填subcategory必填

版本歷史

1
  1. v0.2.2最新Sep 16, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

    請在儲存庫或註冊中心條目中宣告授權條款。