
HammerTime
io.github.WentTheFox由 GitHub 帳號 WentTheFox 發布v0.1.0更新於 Oct 30, 2026
Generate Discord timestamps and manage your HammerTime bot settings.
概覽
遠端 HammerTime MCP 伺服器,可產生 Discord 時間戳記,並讀取或修改所綁定 HammerTime 機器人帳號的設定。
- 可以做什麼
- 產生多種格式的 Discord 時間戳記(at、at12、iso、unix、in、ago、add、subtract、snowflake),並依帳號已儲存的設定解析
- 讀取和修改所綁定 Discord 帳號的機器人設定
- 查詢目前使用的 API 金鑰以及服務狀態
- 適用情境
- 適合讓助理為訊息、活動或嵌入內容產生 Discord 格式的時間戳記,或在不離開對話的情況下檢視和調整所綁定 Discord 帳號的 HammerTime 機器人設定。
- 執行需求
- 遠端 Streamable HTTP 端點,無需本機安裝套件。需要 HammerTime 網站個人資料頁建立的 API 金鑰,透過 Authorization 標頭以 Bearer 方式傳送。每個金鑰對應一個已綁定的 Discord 帳號。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 HammerTime,將其新增到工作區。
- 連接 Authorization token 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
- 為需要使用其工具的對話啟用該服務。
Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。
交給代理程式安裝
把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。
閱讀 https://sourceweft.com/mcp/io.github.WentTheFox%2Fhammertime/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。其他 MCP 客戶端
把它新增到你客戶端的 mcpServers 設定中。
{
"mcpServers": {
"hammertime": {
"type": "http",
"url": "https://api.hammertime.cyou/mcp",
"headers": {
"Authorization": "Bearer <YOUR_TOKEN>"
}
}
}
}README
HammerTime API
The public REST API and the MCP server of HammerTime. Every endpoint, and every MCP tool, is the bot command of the same
name, and every input is the command's option with the same name, so POST /at takes year, month, day, hour,
minute, timezone, format and so on, resolved against the saved settings of the account exactly as the bot does it.
The logic is @went.tf/hammertime-core, which the bot uses too.
Usage is recorded as the bot's is (same counters, with the source api or mcp) unless the account turned telemetry
off, and the replies carry the run count the way the bot's do.
Keys
Users create them on the HammerTime website (profile page), each acts as one linked Discord account. Send one as
Authorization: Bearer htk_.... The bot has a service key of its own that names the account per request in
X-Discord-User-Id; it is accepted by the REST endpoints for the commands only, not by /mcp.
An MCP client is configured with the URL of /mcp and the header, for example:
The bot as a client
The bot can ask this API to handle its timestamp commands (COMMANDS_API_URL and COMMANDS_API_KEY in the bot's .env, see
.env.example). It sends the options the user gave, as the service key with X-Discord-User-Id, and turns the answer into the
Discord reply. The API has recorded the run by then and the reply carries the note about it, so the bot does not record it a
second time. When the API is down, slow (COMMANDS_API_TIMEOUT_MS), refuses the bot or limits it, the bot handles the
command itself exactly as it did before, including recording the run, so an outage of this service costs nothing but
the logged warning. Input the API rejects is worded by the bot and recorded as it always was.
Rate limits
Each key may make RATE_LIMIT_PER_MINUTE requests (60) on average, with a burst of half of that, across the REST endpoints
and /mcp together. The bot's service key is limited per Discord account it acts for, so one noisy user cannot use up what
the others get. Every response of an authenticated request carries RateLimit-Limit, RateLimit-Remaining and
RateLimit-Reset, and a refused one is a 429 with Retry-After (seconds). /health and the documentation are not limited.
A client address that fails to authenticate AUTH_FAILURES_PER_MINUTE times (20) is turned away with a 429 until it has waited,
before anything is looked up, so a flood of made-up keys does not each cost the Laravel app a lookup. Even a good key from that
address waits, which can catch innocent users behind a shared address, so keep the number generous.
Behind a reverse proxy every client has the proxy's address, so they would all count as one. Set CLIENT_IP_HEADER to a header
the proxy sets to the client's address and overwrites (nginx: proxy_set_header X-Real-IP $remote_addr;), otherwise anyone
could pick the address they are counted under. Nothing runs in the background to clean up after the limits: a bucket is only brought up to date when it is used, and Redis forgets
one by itself when it has filled up again.
Counting in Redis
pm2.json runs two workers (see below). Left alone, each counts for itself, so a key can make up to the number of workers times
RATE_LIMIT_PER_MINUTE requests, and the same goes for the failed authentications of an address. Set up Redis to count them as one:
either REDIS_URL, or REDIS_HOST with REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD, REDIS_DB and REDIS_TLS (see
.env.example), and the limits are shared by every worker.
- One Lua script refills the bucket, checks it and spends from it, so two workers can not both take the last token. The keys are
<REDIS_KEY_PREFIX><kind>:<key or address>(hammertime-api:requests:key:42) and expire by themselves. Give the API a database of its own (REDIS_DB), the prefix keeps the keys of the Laravel app, which may share the Redis, safe in any case. - A request never waits for Redis for more than 150 ms. When it does not answer, that request is counted in memory, per worker, as it is without Redis: a limit that is a little looser is better than an API that is down because its rate limiter is. It says so in the log, once a minute at most, and counts in Redis again when Redis is back.
REDIS_TLS=trueis for a Redis on another machine, on this one it is not needed.
Running as a cluster
pm2 runs the server as two workers that share the port (exec_mode, instances, wait_ready and kill_timeout in pm2.json). A
worker sends ready once it listens and stops on SIGINT by finishing the requests in flight, which is what lets a deploy replace
them one at a time without dropping any (src/graceful-shutdown.ts, the bot has the same one). Nothing a request needs is
kept from the one before. The key cache is per worker, so each of them validates a key against the Laravel app once per
KEY_CACHE_TTL_SECONDS, and the rate limits are per worker too unless Redis is set up.
Where the data lives
Nothing is stored here. The Laravel app (SledgeHammerTime) owns keys, settings and telemetry, and this service talks to its
/internal endpoints with INTERNAL_API_SECRET (see docs/api.md in that repository). Validated keys are remembered for
KEY_CACHE_TTL_SECONDS, so a revoked key keeps working for that long.
Generated parts
src/generated/commands.ts (the request schemas, option types and English texts) is generated from the bot's
src/commands.json and its en-US locale, and docs/openapi/api-docs.json (in the repository root) from the routes.
Both are committed, and the tests fail when they are stale:
Running it
On the server pm2 runs it (HammerTimeBot:Api in pm2.json), but only when packages/api/.env exists, see deploy.conf. (It used to be .env.api in the root of the repository, the deploy moves such a file by itself.) Deploy the
Laravel app first, since this service calls its internal endpoints. It listens on 127.0.0.1:3010 only, so nginx has to proxy it
to a hostname: nginx/api.hammertime.cyou.conf is the vhost, with the one-time setup in its header.
Tests
pnpm run test:packages from the root (core and API). They run the app in-process against an in-memory backend, the MCP
tests use the real MCP SDK client.
Listing in the MCP Registry
server.json is what the MCP Registry lists: the endpoint of the MCP server and
that it wants the API key as a bearer token. The registry only keeps metadata, so there is no package to publish.
The name is io.github.WentTheFox/hammertime. The workflow in .github/workflows/publish-mcp.yml authenticates with the
OIDC token of GitHub Actions, which proves that the repository belongs to that owner, so no secret is stored anywhere.
To publish a version:
- Raise
versionin bothpackages/api/package.jsonandpackages/api/server.json. A test fails when they differ. - Merge it, then tag it:
git tag mcp-v0.2.0 && git push origin mcp-v0.2.0.
The workflow tests the packages, checks that the tag matches server.json, validates it with mcp-publisher validate and publishes.
A version can be published once. To try the file without publishing, run mcp-publisher validate in packages/api.
來源:packages/api/README.md,提交 ca851be
工具
0版本歷史
1- v0.1.0最新Oct 23, 2026
評分
已滿足適用檢查項的 85%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通必需25 分
- 已宣告認證方式必需10 分
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分