Token导航 LogoToken导航

MCP Server · 运维云端

Simple Ads As A Server

AdKit 是一个轻量级的语义广告匹配引擎,专为LLM应用设计,通过MCP提供安全工具界面,使代理能够使用自然语言上下文请求相关广告。

stdio官方级别未说明来源级核验工具 11
PythonLLM应用本地部署

快速开始

作者 / 组织
Exorust
提供方
Exorust

工具数量

11

来源目录标注

资源数量

0

来源目录标注

提示词数量

0

来源目录标注

GitHub Star

44

仓库热度

收录来源

1 个

MCP World

选型结论

Simple Ads As A Server 属于运维云端类 MCP Server,公开资料标注 11 个工具,通过stdio 本地进程接入,客户端适配情况以官方文档为准,有可以直接复制的安装命令;接入前先确认权限范围。

分类

运维云端

传输方式

stdio

认证方式

无需认证

部署方式

公开资料未说明

安装与配置

安装命令

pip install uv

公开命令不是通用的启动方式,拼不出可靠配置示例;请在客户端 MCP 配置里按官方文档填写 command 和 args。

上手步骤

  1. 1

    准备运行环境

    stdio 服务在本地起进程,需要先装好 对应的运行时,再按安装命令拉取依赖。

  2. 2

    安装服务

    复制下面的安装命令执行;命令里带占位符的位置换成自己的密钥或路径。

  3. 3

    写入客户端配置

    在客户端的 MCP 配置里填启动命令和参数,保存后完全退出客户端再打开,让新配置生效。

  4. 4

    验证是否可用

    连接成功后客户端会列出 11 个工具,随便调一个只读工具确认能返回结果。

接入前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

详细介绍

A lightweight, semantic ad-engine for the LLMs, available through MCP

🐦 Follow Updates • 📧 Contact & Feedback

一个向LLM提供广告的简单MCP服务器!使用此功能在法学硕士课程中注入赞助商的广告。

介绍

AdKit 是一个轻量级的语义广告匹配引擎,专为 LLM应用。它通过以下方式暴露出一个小而安全的工具表面 主控程序 因此,代理可以使用自然语言上下文(聊天轮次、页面内容、搜索查询)请求相关广告,而无需脆弱的关键字规则。

在幕后,AdKit在本地嵌入您的上下文(FastEmbed),并从以下位置检索候选人 Qdrant 使用向量相似度加 类型化约束 (主题、区域设置、垂直领域、排除项、策略标志)。它的设计有一个硬安全边界: 数据平面 是只读和分配的,而 控制平面 分别处理摄取和管理操作。

当您希望“原生”赞助商插入或产品推荐与含义相匹配,而不是字符串时,请使用它——并且您希望架构在交付生产时保持理智。

你在哪里可以使用这个?

  • 人工智能代理和助理:无缝地将相关的产品推荐或赞助信息注入聊天界面(例如,客户支持机器人、购物助理)。
  • RAG(检索增强代)管道:在有机检索结果旁边提供“赞助上下文”,允许在搜索或问答工具中提供高相关性的原生广告。
  • 内容发现平台:基于所消费内容的语义含义,而不是脆弱的关键字匹配,增强“您可能也喜欢”功能或联盟链接插入。

或 从建筑中汲取灵感

先决条件

设置

安装uv

# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# Or with pip
pip install uv

在本地启动Qdrant

# Using Docker
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant

# Or download binary from https://github.com/qdrant/qdrant/releases

安装依赖项

# Install all dependencies and create virtual environment
uv sync

配置环境(可选)

# Copy example env file (defaults work for local Qdrant)
cp .env.example .env

演示广告设置(分步)

按照以下步骤加载演示广告并确认一切正常。演示广告定义见 data/test_ads.json;重新运行 seed 打乱它们,使商店与文件匹配。

步骤1。 启动Qdrant(在终端中):

docker run -d --name qdrant \
  -p 6333:6333 -p 6334:6334 \
  qdrant/qdrant

docker ps --filter name=qdrant

步骤2。 在项目目录中,安装依赖项:

uv sync

步骤3。 (可选)复制环境:

cp .env.example .env

步骤4。 创建集合:

uv run ad-index create 

如果存在(uv运行广告索引删除)

步骤5。 从文件加载演示广告:

uv run ad-index seed

要使用其他文件,请执行以下操作: uv run ad-index seed --file path/to/ads.json

步骤6。 验证它是否有效:

  • 运行:
  uv run ad-index info

确认 积分计数 是5(或JSON文件中的广告数量)。

  • 可选地,从Python查询广告以确认它们正在被提供:
  uv run python -c "
  from ad_injector.wiring import build_match_service
  from ad_injector.models.mcp_requests import MatchRequest
  r, _ = build_match_service().match(MatchRequest(context_text='python', top_k=2))
  print(r.model_dump_json(indent=2))
  "

您应该在输出中看到匹配的广告(例如Python/编码广告)。

建筑

该系统分为两个MCP服务器平面:

飞机目的谁叫它入口点
数据平面广告匹配、只读检索LLM/代理uv run ad-mcp-data 或 uv run ad-data-plane
控制平面配置、接收、管理操作人员、CI/CD、后台uv run ad-mcp-control 或 uv run ad-index (CLI)

为生产运行两个单独的进程:一个控制平面(管理)和一个数据平面(运行时)。每个都有自己的身份验证范围(可选 MCP_ADMIN_KEY / MCP_DATA_KEY).

数据平面工具(运行时,面向LLM)

  • ads_match --语义广告匹配(上下文文本、位置、约束、top_k);返回候选项和match_id进行解释
  • ads_explain --先前匹配的审计跟踪(match_id)
  • ads_health --活性/准备就绪(Qdrant+嵌入)
  • ads_capabilities --支持的布局、约束键、嵌入模型、模式版本

数据平面使用显式的allowlist(DATA_PLANE_ALLOWED_TOOLS).无法注册任何破坏性或管理工具。

控制平面工具(管理员)

  • collection_ensure --创建/对齐集合(维度、嵌入模型id、模式版本)
  • collection_info --集合元数据(点数、维度、嵌入模型id、模式版本)
  • collection_migrate --可选的模式迁移(从版本到版本)
  • ads_upsert_batch --批量广告摄取(JSON数组)
  • ads_delete --按id删除广告
  • ads_bulk_disable --set enabled=false,用于匹配过滤器(JSON过滤器)的广告
  • ads_get --获取单个广告(调试)

回购结构

src/ad_injector/
  models/           # Ad, Targeting, Policy; MCP request/response DTOs
  services/         # MatchService, PolicyEngine, TargetingEngine, IndexService
  adapters/         # QdrantVectorStore, FastEmbedProvider
  mcp/              # server, tools, auth, observability
  config/           # RuntimeSettings, env vars
  ops/              # smoke_check, migrations

配置

运行时设置通过环境变量(或 .env),在启动时由Pydantic验证:

变量默认值描述
QDRANT_HOSTlocalhostQdrant服务器主机
QDRANT_PORT6333Qdrant服务器端口
QDRANT_COLLECTION_NAMEads收藏名称
EMBEDDING_MODEL_IDBAAI/bge-small-en-v1.5嵌入模型
EMBEDDING_DIMENSION384矢量维度
MAX_TOP_K100每次匹配查询的最大结果数
MAX_BATCH_SIZE500每个追加销售批次的最大广告数
REQUEST_TIMEOUT_SECONDS30.0每次请求超时
REQUIRE_ADMIN_KEYfalse如果为真,控制平面需要 MCP_ADMIN_KEY env
REQUIRE_DATA_KEYfalse如果为真,数据平面需要 MCP_DATA_KEY env

用紫外线跑步

运行脚本

# Data Plane MCP server (LLM-facing, read-only): ads_match, ads_explain, ads_health, ads_capabilities
uv run ad-mcp-data
# or: uv run ad-data-plane

# Control Plane MCP server (admin): collection.*, ads.upsert_batch, ads.delete, ads.bulk_disable, ads.get
uv run ad-mcp-control

# CLI (Control Plane): create collection, seed ads, info, delete
uv run ad-index create          # Create the collection
uv run ad-index seed            # Add sample ads for testing
uv run ad-index info            # Show collection info
uv run ad-index delete          # Delete the collection

直接运行Python文件

uv run python -m ad_injector.main_runtime   # Data Plane MCP
uv run python -m ad_injector.main_control   # Control Plane MCP
uv run python -m ad_injector.cli create     # Control Plane CLI
uv run python -m ad_injector.cli seed

备注:The seed 命令从加载演示广告 data/test_ads.json (或 --file )并将它们加入收藏。跑 create 首先设置集合,然后 seed 加载测试数据。

正在验证MCP服务器

1.运行测试套件

uv run pytest tests/ -v

这将运行数据平面护栏测试,该测试断言:

  • 数据平面仅公开已分配的工具(ads_match, ads_explain, ads_health, ads_capabilities)
  • 数据平面上没有禁用/破坏性工具
  • Control Plane有管理工具 不 暴露数据平面–仅限工具

2.验证数据平面是否公开了分配的工具

uv run python -c "
from ad_injector.mcp.server import create_server
from ad_injector.mcp.tools import DATA_PLANE_ALLOWED_TOOLS
s = create_server('data')
tools = set(s._tool_manager._tools.keys())
print(f'Server: {s.name}')
print(f'Tools:  {tools}')
assert tools == DATA_PLANE_ALLOWED_TOOLS, f'FAIL: expected {DATA_PLANE_ALLOWED_TOOLS}'
print('PASS: Data Plane allowlist registered')
"

3.使用管理工具验证控制平面是否启动

uv run python -c "
from ad_injector.mcp.server import create_server
s = create_server('admin')
tools = set(s._tool_manager._tools.keys())
print(f'Server: {s.name}')
print(f'Tools:  {tools}')
assert 'ads_match' not in tools, 'FAIL: ads_match on admin plane'
assert 'collection_ensure' in tools
print('PASS: admin tools registered, no ads_match')
"

4.验证ads_match DTO验证

uv run python -c "
from ad_injector.models import MatchRequest, MatchConstraints, PlacementContext, MatchResponse, AdCandidate

# Valid request
req = MatchRequest(
    context_text='I want to learn Python',
    top_k=5,
    placement=PlacementContext(placement='sidebar', surface='chat'),
    constraints=MatchConstraints(topics=['python'], locale='en-US', sensitive_ok=False),
)
print(f'MatchRequest OK: context_text={req.context_text!r}, top_k={req.top_k}')
print(f'  constraints.topics={req.constraints.topics}, locale={req.constraints.locale}')

# Valid response
resp = MatchResponse(
    candidates=[AdCandidate(ad_id='ad-001', advertiser_id='adv-1', title='Learn Python',
        body='Courses', cta_text='Go', landing_url='https://example.com', score=0.95, match_id='m-1')],
    request_id='req-xyz', placement='sidebar',
)
print(f'MatchResponse OK: {len(resp.candidates)} candidate(s)')

# Invalid request (empty context) fails
try:
    MatchRequest(context_text='', top_k=5)
    print('FAIL: empty context_text should be rejected')
except Exception:
    print('PASS: empty context_text rejected')
"

5.验证配置加载和验证

# Defaults
uv run python -c "
from ad_injector.config import get_settings
s = get_settings()
print(f'host={s.qdrant_host} port={s.qdrant_port} model={s.embedding_model_id}')
"

# Invalid port fails fast
QDRANT_PORT=99999 uv run python -c "from ad_injector.config.runtime import RuntimeSettings; RuntimeSettings()" 2>&1 | head -3

6.验证导入隔离(数据平面不加载管理代码)

uv run python -c "
import sys
from ad_injector.main_runtime import main
mods = [m for m in sys.modules if m.startswith('ad_injector')]
assert 'ad_injector.cli' not in mods, 'FAIL: cli imported'
print('PASS: main_runtime has clean import graph (no admin modules)')
"

添加依赖关系

uv add 
           # Add a dependency
uv add --dev 
     # Add a dev dependency

广告模式

Qdrant中存储的每个广告都包含:

字段类型描述
ad_idstring广告的唯一标识符
advertiser_idstring广告商的标识符
titlestring广告标题
bodystring广告正文
cta_textstring行动呼吁文本
landing_urlstring重定向URL
targeting.topicsstring\[\]要定位的主题
targeting.locale字符串\[\]本地代码(例如,“en-us”)
targeting.verticalsstring\[\]垂直行业
targeting.blocked_keywordsstring\[\]要排除的关键字
policy.sensitiveboolean敏感内容标志
policy.age_restrictedboolean年龄限制标志
enabledboolean广告是否符合匹配条件(默认 true; ads_bulk_disable 套 false)

嵌入文本:向量嵌入是从以下内容生成的 title + body + topics.

用法示例

from ad_injector.models import Ad, AdTargeting, AdPolicy
from ad_injector.wiring import build_index_service, build_match_service
from ad_injector.models.mcp_requests import MatchRequest

# Create the collection (once) and seed ads via IndexService
index_svc = build_index_service()
index_svc.ensure_collection()
ad = Ad(
    ad_id="ad-001",
    advertiser_id="adv-123",
    title="Learn Python Today",
    body="Master Python programming with our interactive courses.",
    cta_text="Start Learning",
    landing_url="https://example.com/python",
    targeting=AdTargeting(
        topics=["programming", "python", "education"],
        locale=["en-US"],
        verticals=["education", "technology"],
    ),
    policy=AdPolicy(sensitive=False, age_restricted=False),
)
index_svc.upsert_ads([ad])

# Match ads via MatchService (Data Plane logic)
match_svc = build_match_service()
response, audit_trace = match_svc.match(
    MatchRequest(context_text="python tutorial", top_k=5)
)
for c in response.candidates:
    print(f"{c.ad_id}: {c.title} (score={c.score}, match_id={c.match_id})")

ads_match 请求/响应模式

数据平面 ads_match 该工具使用类型化的DTO——不接受原始字典过滤器。

请求参数

参数类型默认值说明
context_text字符串(1-10000个字符)*必需的*要匹配的对话/页面上下文
top_k整数(1-100)5返回的候选人数量
placement字符串"inline"放置槽(例如。 inline, sidebar, banner)
surface字符串"chat"表面类型(例如。 chat, search, feed)
topicsstring\[\]空null仅限于这些主题
localestring空null所需的区域设置(例如。 en-US)
verticalsstring\[\]空null仅限于这些垂直领域
exclude_advertiser_idsstring\[\]空null要排除的广告商ID
exclude_ad_idsstring\[\]空null要排除的广告ID
age_restricted_ok bool的。 false允许年龄限制广告
sensitive_ok bool的。 false允许敏感内容广告

响应形状

{
  "candidates": [
    {
      "ad_id": "ad-001",
      "advertiser_id": "adv-123",
      "title": "Learn Python Today",
      "body": "Master Python programming...",
      "cta_text": "Start Learning",
      "landing_url": "https://example.com/python",
      "score": 0.95,
      "match_id": "m-abc123"
    }
  ],
  "request_id": "req-xyz-456",
  "placement": "sidebar"
}
  • match_id 可以传递给 ads_explain 用于审计跟踪(为什么符合/不符合条件、过滤器、分数)
  • score 是余弦相似度(0-1)

跟我说

我总是热衷于研究MCP工具、检索系统和实用的LLM货币化。\ 如果你正在构建类似的东西,或者想对你的架构进行压力测试,请联系:

  • 🐦 推特:https://twitter.com/charoori_ai
  • 📧 电子邮件:mailto:chandrahas.aroori@gmail.com主题=AdKit

工具与能力

工具数量

11

资源数量

0

提示词数量

0

能力标签

语义广告匹配Python本地部署LLM应用广告引擎MCP工具

数量来自来源目录的标注,具体工具清单以官方文档为准。

典型使用场景

看服务状态

查询容器、日志和监控指标,定位异常。

执行部署变更

在权限范围内触发发布、回滚和环境切换。

核对资源用量

汇总用量,找出闲置和超额的部分。

选择建议

值得选的地方

  • 工具数量 11 个,一次接入能覆盖的操作比单点工具更全。
  • 有现成的安装命令,不用自己找入口,照着跑就能起服务。
  • 公开说明写得比较完整,接入前能看清能力边界。

先想清楚的地方

  • stdio 方式要求本地装好 运行环境,换机器要重新装一遍。
  • 第三方目录整理,版本更新和行为细节以官方仓库为准。

更适合

  • 需要在运维云端场景里让模型直接调用外部能力的人。
  • 想先快速试一下、能接受在本地跑服务的人。

不太适合

  • 完全不想在本地装环境的人。
  • 需要厂商级 SLA 和技术支持的生产环境。

同类对比

5 个同类
MCP Server工具数传输方式安装命令收录来源最后核验
Simple Ads As A Server

MCP World · 本页

11stdio有1 个2026-05-17
Ui Tars Desktop 8a825770

MCP World

0stdio有1 个2026-05-17
Elie222 MCP

MCP World

0未说明未标注1 个2026-05-17
Arizeai Phoenix MCP

MCP World

0stdio有3 个2026-05-17
Unity MCP 87ee506e

MCP World

42HTTP有2 个2026-05-17

按同分类和工具数量挑出最接近的几条,字段以各自详情页为准。

常见问题

5 条

Simple Ads As A Server 怎么安装?

公开资料给出的安装命令是 pip install uv,运行环境为 未标注。装完后按客户端要求写进 MCP 配置,重启客户端生效。

Simple Ads As A Server 怎么在 Claude Desktop、Cursor 里配置?

它是stdio 本地进程,客户端配置里要写启动命令和参数,运行环境是 未标注;保存后完全退出客户端再打开,配置才会生效。

Simple Ads As A Server 收费吗?

本站只整理公开资料,不代收费用,也没有标注具体价格。是否收费取决于服务本身和背后的接口额度,正式使用前按官方说明确认。

Simple Ads As A Server 需要 API Key 吗?

公开资料标注为无需认证,装好就能连;如果实际调用时报鉴权错误,按官方文档补上凭据。

Simple Ads As A Server 支持哪些客户端?

公开资料没有标注具体客户端;能配置本地 MCP 命令的客户端都能接,配置方式参照官方文档。

来源信息

继续浏览同类 MCP