内容
center">
# Lulu 广告
### *代理经济的变现层。*
**通过一个标记的赞助行使您的服务器或代理现。**
[
[](https://www.npmjs.com/package/lulu-ads)
[](LICENSE)
](https://img.shields.io/badge/backend-live-brightgreen://ads.getlulu.dev/health)
[](https://getlulu.dev/publishers)
[](docs/contract.md)
[快速开始](#快速开始) · [集成](#框架集成) · [保证](#代码中强制执行的保证-而不仅仅是承诺) · [API 合同](docs/contract.md) · [托管文档](https://getlulu.dev/docs) · [博客](https://getlulu.dev/blog) · [成为发布者](https://getlulu.dev/publishers)
<img src="https://raw.githubusercontent.com/Lulu-The-Narwhulu-ads/master/assets/lulu-ads-hero.jpg" alt="Lulu, Lulu Ads 的北极鲸吉祥物,在特拉维夫的广告牌上庆祝 — 代理经济现在有了变现层" width="640" />
`70% 给发布者 · 按转化付费 · 150毫秒超时 · 0 次提示注入,设计如此`
</div>
Lulu 广告在您的工具结果中附加一个公开的、标记的数据字段。
主机模型 — Claude、Cursor、任何代理 — 根据自己的判断决定是否显示。
我们从不指示它。
<table>
<tr>
<th>SDK 附带的内容(数据字段)</th>
<th>的内容(由它选择)</th>
</tr>
<tr>
<td>
```json
{
"sponsored": {
"label": "赞助",
"text": "从 $412 起的 TLV-BKK 直飞航班",
"url": "https://ads.getlulu.dev/c/9f2a1c"
}
}
```
</td>
<td>
> **赞助** — 从 $412 起的 TLV-BKK 直飞航班
> [ads.getlulu.dev/c/9f2a1c](https://ads.getlulu.dev/c/9f2a1c)
</td>
</tr>
</table>
零摩擦开始 — 添加 MCP 服务器,让您的代理完成其余工作:
```bash
claude mcp add --transport http lulu-ads https://ads.getlulu.dev/mcp
```
> 使我的服务器变现
它将为您的堆栈获取正确的集成指南,注册发布者(需您同意),连接一行代码,并验证一个插槽上线。
**如果它渲染并被点击,您将获得 70% 的转化成本。如果它不渲染, nobody
付费,不会破坏任何东西。**
**无提示注入 — 我们提供一个数据字段;主机决定。**
## 快速开始
**Python**
```bash
pip install lulu-ads
# 或:uv add lulu-ads
# 或:poetry add lulu-ads
```
```python
from lulu_ads import LuluAds
ads = LuluAds(publisher_id="pub_123", api_key="lk_...")
result = search_flights("TLV", "BKK", dates)
result["sponsored"] = await ads.sponsored_slot(
context={"tool": "search_flights", "category": "travel.flights"},
timeout_ms=150,
)
return result
```
FastMCP 服务器通过一行代码获取它 — 凭证来自环境:
```bash
export LULU_ADS_PUBLISHER_ID=pub_123
export LULU_API_KEY=lk_...
```
```python
mcp.add_middleware(LuluAdsMiddleware())
```
**TypeScript**
```bash
npm install lulu-ads
# 或:pnpm add lulu-ads
# 或:yarn add lulu-ads
# 或:bun add lulu-ads
```
```ts
import { LuluAds } from "lulu-ads";
const ads = new LuluAds({ publisherId: "pub_123", apiKey: "lk_..." });
result.sponsored = await ads.sponsoredSlot({ context: { tool: "search_flights" } });
```
还没有发布者 ID?请参阅 [`docs/quickstart.md`](docs/quickstart.md) — 三种获取方式,无需其他条件。
## 框架集成
| 堆栈 | 一行代码 | 文档 |
|---|---|---|
| FastMCP(Python) | `mcp.add_middleware(LuluAdsMiddleware())` | [→](docs/integrations.md#fastmcp-python) |
| LangChain / LangGraph(Python) | `middleware=[LuluAdsAgentMiddleware()]` | [→](docs/integrations.md#langchain--langgraph-python) |
| CrewAI(Python) | `lulu_crewai.install()` | [→](docs/integrations.md#crewai-python) |
| MCP TS SDK | `withLuluAds(server)` | [→](docs/integrations.md#mcp-servers-typescript) |
| 运行时所有者(聊天机器人、WhatsApp/Telegram 代理) | `model_output + format_suffix(sponsored)` | [→](docs/integrations.md#runtime-owners-response-suffix) |
| 任何其他运行时/语言 | `sponsored_slot(context)` 通过原始合同 | [→](docs/integrations.md#any-agent-runtime) |
## 小部件渲染(MCP 应用 UI)
普通的 `sponsored` 字段始终可用,并且始终有效 — 一些主机
根据模型的自主判断将其渲染为卡片,无需任何指令
任何地方。对于支持 [MCP 应用](https://github.com/modelcontextprotocol/ext-apps)
扩展(`io.modelcontextprotocol/ui`)的主机,您可以另外注册一个
实际渲染的小部件,而不是依赖该判断调用:
```python
from fastmcp import FastMCP
from lulu_ads.widget import register_sponsored_widget
mcp = FastMCP("my-server")
sponsored_app = register_sponsored_widget(
mcp,
endpoint_url="https://my-server.example.com/mcp", # 您的公共 MCP 连接器 URL
text="结账时节省 15%",
url="https://example.com/deal",
)
@mcp.tool(app=sponsored_app)
def search(...): ...
```
相同的帮助程序,官方 TS SDK,用于在 Node 而不是 Python 中构建的 MCP 服务器:
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { registerSponsoredWidget } from "lulu-ads/widget";
const server = new McpServer({ name: "my-server", version: "1.0.0" });
const appMeta = registerSponsoredWidget(server, {
endpointUrl: "https://my-server.example.com/mcp", // 您的公共 MCP 连接器 URL
text: "结账时节省 15%",
url: "https://example.com/deal",
});
server.registerTool("search", { ...appMeta }, handler);
```
提供一个浮动、圆角、渐变卡片(与
[getlulu.dev](https://getlulu.dev) 相同的视觉系统),带有公开的 `赞助` 标签 —
仍然只是标记,而不是指令。两个主机特定的怪癖它
为您处理:Claude 需要一个从您的端点 URL 派生的未公开 `_meta.ui.domain` 值
(此处自行计算,而不是凭证),并且小部件必须发送 `ui/notifications/initialized`
加载时的握手,否则 Claude 保持 iframe 隐藏。针对生产环境进行实时验证
(`dali.getlulu.dev/mcp`,[ext-apps#671](https://github.com/modelcontextprotocol/ext-apps/issues/671)),
截至 2026-07-19 — Claude 自己的 MCP 应用小部件渲染在该修复程序落地之前在整个平台上都已损坏,因此
任何“应该渲染”的声明(包括此处和其他地方的声明)都是未经验证的,直到您
在自己的主机上实时检查过。
卡片内容在注册时固定 — 一个房屋广告层,与普通字段的房屋填充路径相同,暂不重新渲染每个调用。
## 保证(在代码中强制执行,而不仅仅是承诺)
| 保证 | 如何实现 |
|---|---|
| 广告调用永远不会因为广告而中断 | 每个失败路径都返回 `None`/`null`;硬 150 毫秒时钟超时 |
| 始终公开 | `label: "赞助"` 由 SDK 设置,永远不会从响应正文中获取 |
| 永远不会注入提示 | 我们提供一个数据字段;合同中没有任何显示指令 |
| 没有 PII 离开您的服务器 | `context` 在客户端根据允许,然后再构建任何请求 |
| 质量门控 | 每个创意在填充插槽之前都经过 [Dali](https://dali.getlulu.dev) 评分(≥70) |
| 意图,而不是身份 | 定位仅使用此调用的声明上下文 — 没有用户配置文件,没有跨会话 ID |
| 配置错误安全 | 缺少凭证 → 客户端惰性,返回 `None`/`null`,零网络调用 |
## 为什么不……
**……告诉模型在其回复中提及赞助商?**
显示指令会使 MCP 服务器在扫描注入指令的注册表中被删除。我们提供一个纯数据对象 — `label`、`text`、`url` —
合同中没有任何字段指示模型如何渲染或措辞任何内容。
**……计算印象并按视图收费?**
仅当模型实际渲染时,“印象”才存在,而从服务器端无法验证 — 容易被操纵,难以审计。我们仅按转化付费,点击兑换签名、服务器验证令牌。付款
映射到真实的用户操作,而不是声明。
**……扫描对话以更好地定位?**
读取记录以定位广告陷阱:用户句话
都成为广告定位数据。我们接受六个允许的上下文键 — `tool`、`category`、`、`route`、`locale`、`country` — 声明此调用的意图。没有记录,没有配置文件,没有 PII 字段存在于模式中。
## 工作原理
```
工具调用
│
▼
您的工具的自己的结果
│
▼
POST /slot (150毫秒上限,仅限允许的上下文)
│
▼
标记数据字段 { label: "赞助", text, url } ← 附加,永远不会注入
│
▼
主机/模型判断 → 渲染它,或不 — 不是我们的调用
│ 用户点击
▼
GET /c/{token} → 签名重定向,点击记录
│
▼
广告商的联盟轨道 → 转换后 POST /postback
│
▼
70% 发布者 / 30% L账本计算。从第一次开始,收益累您的余额 — 从 $100 开始提现。
```
完整的线路级别详细信息: [`docs/contract.md`](docs/contract.md)。
---
文档: https://getlulu.dev/docs · [快速开始](docs/quickstart.md) ·
[API 合同](docs/contract.md) · [集成](docs/integrations.md) ·
[发布者注册](https://getlulu.dev/publishers) · 质量门控:
[Dali](https://dali.getlulu.dev)MIT](LICENSE)
## 更新日志
-.2.0** — `register_sponsored_widget()` (Python:`lulu_ads.widget`,现已支持
TypeScript:`lulu/widget`,官方 MCP SDK):在您的服务器上注册一个真正渲染的
MCP 应用 UI 赞助卡(不仅仅是纯 JSON 字段),
处理 Claude 的未公开 iframe 域要求和
`ui/notifications/initialized` 握手。概括了在 `dali.getlulu.dev/mcp` 上验证的修复程序
反对 [ext-apps#671](https://github.com/modelcontextprotocol/ext-apps/issues/671)。
两个 SDK 为相同的端点 URL 生成字节相同的 `_meta.ui.domain` 值。
- **0.1.1** — Python SDK 中的持久 HTTP 客户端(每个调用的客户端
构造可能会在 CPU 受限的容器上烧掉整个槽预算;现在客户端
为每个 `LuluAds` 实例创建一次并重用,带有 keep-alive)。Fail-open 行为不变。
- **0.1.0** — 初始发布:Python + TypeScript 客户端,FastMCP /
LangChain / LangGraph / CrewAI / MCP-TS 适配器,后缀帮助程序,MCP
欢迎使用。