Borneo Sawit API 与 MCP 服务器:每日 TBS 价格,无需 API key
本站公布的每一个价格同时也以 JSON 形式提供,任何人都可以取用,不需要密钥,也不用注册。这一页先说明数据的含义,再说怎么获取,因为大家最常犯的错不在 HTTP,而在于把数字读错了。
你取到的究竟是什么
一行数据就是一个价格:一个日期、一家 PKS 或一家 RAM、一个报价人。它不是平均值,也不是指数。
同一天、同一家 PKS,两个报价人报出的价格可能不一样。我们把两条并排列出,不做平均,因为这个差价本身就是信息。
日期是 WITA(UTC+8)日历日期,不是时间点。早上七点报的价属于当天,而不是按 UTC 算的前一天。
更正是以新行追加的,不会覆盖旧数据。你读到的永远是当前生效的那一版。
PKS 厂门价和 RAM 收农户价是两种不同的说法,绝不能放在一起平均。前者是工厂在厂门付的价,后者是中间商在自己场地收农户的价,两者之差就是中间商的利润空间。
`change` 字段在该组合首次报价时为 null,在价格没有变动时为 0。这是两回事,别把 null 当成零。
我们的覆盖范围是南加里曼丹。这不是 CPO 价格,不是全国指数,也不是 Disbun 的官方公报,不过每块价格板都附上了最新的 Disbun 合作社参考价,供对照。
从这里开始
读取数据不需要 API key。不用注册,不用 token,也没有必须带的请求头。把下面这行复制过去,你就拿到了今天的价格板。
curl -s https://borneosawit.com/api/v1/prices/latest
返回结果会带上它实际描述的日期。如果今天还没有报价,返回的是最近有数据的那一天,并标明那一天的日期,而不是空数组。CORS 对所有来源开放,所以在浏览器里 `fetch` 也可以。基础地址是 `https://borneosawit.com/api/v1`。
接口一览
一共九个,全部是 GET,全部返回 JSON,全部匿名。所有错误使用同一个信封:`{ "error": { "code", "message", "hint", "docs" } }`,判断时请用 `code`,不要用 `message`。
- /api/v1/prices/latest
- 最新的价格板:WITA 的今天,或最近有数据的那一天。
- /api/v1/prices/{date}
- 指定某一天的价格板。当天没有数据时仍返回 200,数组为空。
- /api/v1/prices/history
- 某个「工厂 + 报价人」组合在连续若干天的价格。`millId` 和 `reporterId` 都是必填。
- /api/v1/mills
- 所有 PKS,含其名称的各种写法。
- /api/v1/rams
- 所有 loading ram,含所在区域与别名。
- /api/v1/reporters
- 所有报价人:自行公布价格的 PKS,以及负责报价的中间商。
- /api/v1/articles
- 文章列表,不含正文。加 `?locale=` 只取一种语言。
- /api/v1/articles/{slug}
- 单篇文章全文,正文以区块列表形式返回。
- /api/v1/status
- 数据库是否响应,以及最新的价格日期。从不缓存。
MCP:直接接到 Claude
同样的数据还提供匿名 MCP 服务器,共七个工具。不用登录,不走 OAuth,也不需要在任何地方粘贴 token。
claude mcp add --transport http borneo-sawit https://borneosawit.com/mcp
在 Claude Code 里执行上面这行命令。在 Claude 应用中,作为自定义连接器添加,URL 填 `https://borneosawit.com/mcp`,认证部分留空。
传输方式是基于 POST 的 Streamable HTTP,无状态,没有 session id,也没有 SSE。GET 请求返回 405,对一个从不主动发消息的服务器来说,这就是正确答复。
工具包括 `get_price_board`、`get_price_history`、`list_mills`、`list_rams`、`list_reporters`、`list_articles`、`get_article`。没有一个会写入数据。
机器可读的文档
除了上面的接口,本站每个页面都能响应 `Accept: text/markdown`,返回该页的 markdown 版本。
- /openapi.json
上述全部接口的 OpenAPI 3.1 规范
- /.well-known/mcp.json
MCP 清单,采用注册表的 server.json 格式
- /llms.txt
面向语言模型的站点摘要
- /sitemap.xml
我们希望被收录的全部 URL,三种语言
如果价格是你来报的
写入价格是另一套接口,且不对外开放。地址是 `https://borneosawit.com/api/mcp`,采用带 PKCE 的 OAuth 2.1,动态客户端注册在 `https://borneosawit.com/api/oauth/register` 开放,所以 Claude 可以自行注册。不开放的是账号:只有已登记的报价人才能批准连接,本页面上的任何接口都改不了任何一个数字。如果你是 PKS 或中间商,希望把价格发布在这里,请用 WhatsApp 联系我们。
命令行工具
本仓库的 `cli/` 目录下有一个零依赖的 Node 命令行工具。目前尚未发布到 npm,发布后本页会更新说明。在此之前请从代码检出直接运行,或者按上面的示例用 `curl`。
node cli/bin/borneo-sawit.mjs prices
数据里会出现的术语
字段名用英文,但字段值不做翻译。下面这六个词会原样出现在响应里,我们有意不去找对应的译法。
- TBS
- Tandan Buah Segar,鲜果串,农户按公斤出售的东西。本站定价的唯一对象。
- PKS
- Pabrik Kelapa Sawit,棕榈油厂。在自己厂门口收购鲜果串。
- RAM
- Loading ram:中间商的场地,直接从农户手里收购鲜果串,再运往工厂。它的价格是农户端的价格,不是厂门价。
- peron
- 中间商。同一个词涵盖了本数据刻意分开的两种角色:作为工厂价格报价人的 peron,和自行给农户定价的 RAM。同一家场地往往两者兼具。
- Disbun
- Dinas Perkebunan,省种植园管理局。定期公布合作社参考价;最新数值附在每块价格板上,供对照。
- kabupaten
- 印尼的县级行政区。名称从不翻译,因为名称本身也是用于匹配的字符串。