asistonto-mcp
Enables AI assistants to create validated question packs for the asistonto meeting copilot, converting meeting notes into pack files that surface questions during live meetings.
README
asistonto-mcp
An MCP server that teaches any AI assistant to build question packs for asistonto, a live meeting copilot.
asistonto listens to a meeting and, the moment a question it was told to watch for is actually being discussed, it surfaces that question. What it watches is a pack. Writing a good one used to be expert work: the questions have to be stated in a particular four-part format, and each of those parts belongs in a different field because of what was measured about retrieval — get that wrong and the pack loads fine and then stays dark all meeting.
This server hands that expertise to Claude, ChatGPT, Claude Code, Codex, or anything else that speaks MCP. You paste your meeting notes; the assistant writes the pack; the pack uploads to asistonto unchanged.
Install
There is nothing to install by hand. Every client below runs the server through
uvx, which fetches and launches it on demand. You need
uv and Python 3.12+.
The package is not on PyPI yet, so uvx asistonto-mcp will not find it.
Install it from the repository instead — this is the working command, and it is
the one used in every block below:
uvx --from git+https://github.com/R0DR0X/asistonto-mcp asistonto-mcp
That runs the server on stdio and waits, which is what an MCP client wants and
what looks like a hang in a terminal. Ctrl-C to leave. When PyPI publishing
happens the plain uvx asistonto-mcp will start working and every block here
gets shorter by three words; until then, use the --from form.
Claude Code
claude mcp add asistonto -- uvx --from git+https://github.com/R0DR0X/asistonto-mcp asistonto-mcp
Or, for every project on this machine rather than one:
claude mcp add --scope user asistonto -- uvx --from git+https://github.com/R0DR0X/asistonto-mcp asistonto-mcp
Check it with claude mcp list; the line should end in ✔ Connected. To upload
packs you also need an API token — see Getting a pack into
asistonto — which you can hand to the server at
registration time:
claude mcp add asistonto --env ASISTONTO_API_TOKEN=asist_... -- uvx --from git+https://github.com/R0DR0X/asistonto-mcp asistonto-mcp
Claude Desktop
claude_desktop_config.json — macOS:
~/Library/Application Support/Claude/claude_desktop_config.json, Windows:
%APPDATA%\Claude\claude_desktop_config.json.
{
"mcpServers": {
"asistonto": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/R0DR0X/asistonto-mcp",
"asistonto-mcp"
],
"env": { "ASISTONTO_API_TOKEN": "asist_..." }
}
}
}
Restart Claude Desktop afterwards. A desktop app has no shell to export a
variable in, so the token goes in env — which makes that config file a file
holding a secret. Keep it as private as the token itself, and leave env out
entirely if you only want to author packs and not upload them.
Cursor, Windsurf, and anything else taking the generic block
The same mcpServers object, in whichever file that client reads
(.cursor/mcp.json, ~/.codeium/windsurf/mcp_config.json, …):
{
"mcpServers": {
"asistonto": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/R0DR0X/asistonto-mcp",
"asistonto-mcp"
],
"env": {}
}
}
}
Codex
Codex keeps its configuration in ~/.codex/config.toml — TOML, not JSON:
[mcp_servers.asistonto]
command = "uvx"
args = ["--from", "git+https://github.com/R0DR0X/asistonto-mcp", "asistonto-mcp"]
[mcp_servers.asistonto.env]
ASISTONTO_API_TOKEN = "asist_..."
From a checkout
git clone https://github.com/R0DR0X/asistonto-mcp.git
uvx --from ./asistonto-mcp asistonto-mcp
What it gives the assistant
Tools
| tool | what it does |
|---|---|
pack_authoring_guide |
the guidance below, for clients that cannot read resources |
compose_question |
assembles one question from the four parts, each into the right field |
parse_meeting_notes |
reads an existing corpus document, in either format asistonto uses |
check_paraphrases |
lints phrasings: too few, keywords, document vocabulary, sibling collisions |
validate_pack |
everything that would fail to load, plus everything that would fail silently |
write_pack |
writes brief.json, paraphrases.json, background.txt, labels.json |
read_pack |
loads an existing pack the way the live server does, and validates it |
upload_pack |
sends a pack to asistonto over HTTP, so a session can pick it |
render_question_document |
writes the questions back out as markdown a person can correct |
pack_size_floor |
how many questions a pack needs before anything in it can fire |
Prompts — build_pack_for_meeting, write_paraphrases,
formulate_question, review_pack.
Resources — asistonto://guide/pack-format,
asistonto://guide/four-part-questions, asistonto://guide/paraphrases,
asistonto://guide/calibration, asistonto://guide/workflow,
asistonto://guide/publishing, asistonto://guide/labels,
asistonto://example/pack, asistonto://schema/brief.json.
The resources matter as much as the tools. An assistant that reads the paraphrase guidance before writing phrasings produces a materially better pack than one that only calls functions — the quality lives in judgement, and the judgement is written down there.
Worked example, end to end
1. Ask. In any client with the server registered:
Build me an asistonto pack for Tuesday's meeting with the warehouse lead about the new label. Here are my notes: (paste). The spec says the label carries the lot code, but the picking screen we saw last week only shows the pallet id, and nobody has said which one the scanner reads.
2. The assistant states each question in four parts and calls
compose_question:
| part | content |
|---|---|
| 1 — where it came from | ETIQUETAS_v3.md line 41: "la etiqueta lleva el código de lote" |
| 2 — what was observed | the picking screen shown on 12 May displays only the pallet id |
| 3 — the question | when the operator scans at picking, does the code identify the pallet or the lot? |
| 4 — why it matters | the traceability chain hangs off which one is scanned |
which becomes one entry of brief.json:
{
"id": "QC-7",
"title": "what the scanner reads at picking",
"priority": "alta",
"source": "ETIQUETAS_v3.md",
"line": 41,
"probes": ["When the operator scans at picking, does the code identify the pallet or the lot?"],
"people": ["warehouse lead"],
"rationale": "the traceability chain hangs off which of the two is scanned",
"blocking": true,
"context": "ETIQUETAS_v3.md line 41 says the label carries the lot code. The picking screen shown on 12 May displays only the pallet id."
}
The provenance sits in context, which is never indexed — indexing it costs
15 points of recall@1. The question sits in probes, the label in title, and
both of those are indexed.
3. Ten paraphrases per question, written from the question alone:
{
"QC-7": [
"when they scan at picking, what are they actually reading",
"the guy with the gun scans the pallet or the box",
"does the scan tell you which lot it is or just where it is",
"if two lots sit on the same pallet, how does the scan tell them apart",
"what comes up on the screen after the beep",
"can you tell from the scan which batch went out",
"is the code on the label the same one the system stores",
"do they scan once per pallet or once per unit",
"what happens when the label is torn and it does not scan",
"who decided which code goes on that label"
]
}
4. validate_pack, then write_pack. You get a directory:
packs/almacen/
├── brief.json ← the only file the live loop reads
├── paraphrases.json ← the editable source, folded into the brief
└── background.txt ← a PAST meeting, for calibration
write_pack refuses two things outright: a pack that would not load, and a pack
too small for anything in it to ever fire. The second refusal is the important
one, because that pack loads perfectly and then does nothing (see the three
things worth knowing).
5. upload_pack, which puts it where the copilot can see it. That is the
next section.
Getting a pack into asistonto
A pack on your disk is not a pack asistonto can use. The copilot runs on a
server; the pack has to be sent there over HTTP. That is what upload_pack
does.
Once, per person
-
Get an account. Sign in at https://asistonto.escorpia.com. Sign-in goes through Google, so you need a Google account and you need to be able to reach the panel before any of this works.
-
Create an API token in the panel. It looks like
asist_…and it is shown once — copy it then, not later. -
Put it in the environment the MCP server runs in, as
ASISTONTO_API_TOKEN. From a shell:export ASISTONTO_API_TOKEN=asist_...For a GUI client, use the
envblock shown in its section above.
Running your own asistonto? Set ASISTONTO_BASE_URL to your instance and
everything below points at it instead.
The server reads the token from the environment and from nowhere else. It is never a tool argument — a tool argument is written into the transcript — and the server never writes it to a file. Do not paste it into a chat.
Per pack
Ask the assistant to upload it, or let it call the tool directly:
upload_pack(directory="packs/almacen")
It sends brief.json, paraphrases.json and background.txt to
POST /packs/<name>. The account that uploads a pack owns it.
Then start the meeting
Open https://asistonto.escorpia.com, start a session, and pick the pack by name. Pack names must be letters, digits, dot, dash or underscore, starting with a letter or digit — the server rejects anything else.
When it does not work
| what comes back | what happened | what to do |
|---|---|---|
token_missing |
$ASISTONTO_API_TOKEN is not set where the server runs |
export it, or put it in the client's env block, and restart the client |
unauthorized |
the token is wrong, expired or revoked | create a new one in the panel and set it again |
name_taken |
somebody else already owns a pack with that name | choose another name: upload_pack(directory=…, pack="almacen-turno-b") |
rejected |
the pack is malformed; the message names the question | fix that question, validate_pack, upload again |
pack_cannot_fire |
the pack is under the size floor and would stay dark | add questions until there are at least 25 |
unreachable |
no network, or the wrong ASISTONTO_BASE_URL |
check both |
The three things worth knowing before you start
Provenance is never a paraphrase. Parts 1 and 2 describe documents; paraphrases describe speech. Measured with paraphrases already indexed, adding the provenance took recall@1 from 71.1% down to 55.6%. Worse, writing paraphrases while reading the provenance pulls document vocabulary — codes, annex numbers, file names — into phrasings that nobody ever says.
Paraphrases must separate siblings, not reword them. Six ways of saying the
same thing all resemble the neighbouring question equally, and 70% of measured
top-1 errors landed on a sibling of the same block. check_paraphrases flags
phrasings that fit the neighbour better than their own question.
A small pack cannot fire at all. The live gate is a z-score over the pack's
own scores, so its ceiling is (n-1)/√n. Against the default gate of 4.75 that
means at least 25 questions — below it the panel stays dark all meeting and
looks exactly like a quiet room. This is why write_pack and upload_pack
refuse a pack that small instead of warning about it.
The measurements behind all of this are in the guide resources, which the assistant can read directly.
Development
git clone https://github.com/R0DR0X/asistonto-mcp.git
cd asistonto-mcp
uv venv && uv pip install -e '.[dev]'
uv run pytest
The test suite runs the MCP server over a real client session and asserts that
what it writes round-trips through a copy of the product's own loader
(tests/test_product_compatibility.py). It never opens a socket: the upload
tests replace upload.post_json, the one function in the package that would.
License
MIT.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。