Мир не статичен
На главной странице pi.dev некогда красовалось заявление, что Pi не поддерживает MCP. В подкастах, где обсуждали Pi, звучали неоднозначные комментарии о протоколе. Марио даже опубликовал пост на эту тему. А теперь в обновлённой версии Pi появилась полная поддержка MCP. Что произошло?
Мир не статичен. За последний год MCP существенно изменился — это совсем не тот протокол, что был раньше. Но этого бы не хватило, чтобы встраивать его в ядро. У Pi отличная экосистема расширений — теоретически MCP мог бы остаться расширением, даже одобренным Earendil. И действительно, так оно и было. То, что MCP теперь часть ядра, результат пересмотра подхода после совместного обсуждения.
Что именно изменилось?
MCP попал в ядро не просто потому, что сам протокол улучшился. Оказалось, что необходимые для интеграции изменения имеют более широкую пользу. Например, модификации для MCP также упростили использование Jev в Pi. В сути своей, Pi и MCP нуждаются в похожем: в sandbox'е для экспериментов в виде интерпретатора.
Многое улучшилось в MCP, но не всё. Главная проблема осталась — сложно комбинировать разные инструменты. Даже с Codemode, который является просто хорошо сделанным sandbox'ем для композиции вызовов инструментов, MCP не полностью решает эту задачу. Но это уже в меньшей степени проблема самого MCP, а скорее проблема существующих MCP серверов и разных подходов к их интеграции.
Многие MCP серверы всё ещё рассчитаны на интеграторы, которые просто сбрасывают инструменты в контекст, стараясь оптимизировать расход токенов возвратом текста. Текущий взгляд на MCP — это скорее приближение к OpenAPI с интеллектуальным обнаружением инструментов. Инструменты должны возвращать структурированные данные и быть обнаруживаемыми по документации и описанию.
CLI-интерфейсы эффективны потому, что агент и модель просто комбинируют вызовы с помощью bash-команд. Но нет никаких фундаментальных причин, почему то же нельзя делать с MCP. MCP в Pi построен на основе JavaScript sandbox'а, как и в других системах вроде Codex.
MCP в современной LLM
Возникает вопрос: почему не просто использовать Codemode без MCP? Ответ связан с тем, как инструменты сегодня описываются в Pi. За последние месяцы проведена значительная работа, чтобы Pi мог работать с новыми моделями, поддерживающими отложенную загрузку инструментов, системные сообщения в середине диалога и изменение уровня рассуждений. Но текущий набор инструментов в Pi ещё не обновлён для масштабирования к этим новым возможностям.
В Codemode мире нужно решить, доступен ли инструмент для основной модели или только для Codemode части. Обычное расширение MCP не содержит достаточно метаданных из текущего набора инструментов Pi, чтобы обеспечить хороший опыт. Поэтому нужно было убедиться, что инструменты можно конфигурировать как отложенные или Codemode-специфичные.
Хотя можно было просто добавить необходимые метаданные для лучших MCP расширений, авторы считают, что MCP вместе с Codemode решает многие исторические проблемы протокола. Лучший способ позитивно влиять на технологию — принять её. Современный MCP в гораздо лучшем состоянии, чем когда-либо, но серверы и паттерны всё ещё имеют место для совершенствования. Авторы хотят быть частью этого диалога и помогать формировать протокол для эффективной работы в компактных системах, а не просто наблюдать со стороны.
Что такое Codemode?
Много говорилось о Codemode, пора объяснить, что это. Когда система исполняет инструменты, у неё есть две стороны: одна работает там, где запускается bash, другая в основном цикле агента. Уровень доверия очень разный. Основной цикл часто запускается в доверенной среде, а инструменты работают в sandbox'е с ограниченным доверием.
Codemode особенен тем, что работает там же, где основная система. Его лучше понимать как механизм для оркестрации и координации вызовов инструментов. Это sandbox, позволяющий агенту выполнять вызовы с большей гибкостью в выборе порядка и возможностью комбинировать их через JavaScript. Поскольку Codemode работает на стороне основной системы, его состояние сохраняется как часть истории сессии, а не в файловой системе.
Теоретически подойдёт любой язык, но JavaScript особенно привлекателен: компактные версии JavaScript можно поставлять как WASM бинарники с разумным уровнем защиты.
В Pi Codemode автоматически загружается при конфигурировании MCP или может быть добавлен как инструмент по умолчанию. Просто попросите Pi переконфигурировать себя для включения Codemode! После этого его можно использовать для интересных задач, не только для MCP. Например, с провайдером, который поддерживает Jev, можно делать вот такое:
Использовать typesafe/jev через Codemode, чтобы найти 20 самых разочарованных комментаторов в трекере задач
При этом система умно комбинирует инструменты, вроде Linear MCP и Jev, прямо в Pi, без какой-либо траты контекста.
> Use typesafe/jev via codemode to find the most frustrated people on our issue tracker
I'll pull the open issues from Linear and let Jev rate the tone of each thread, four at a time.
codemode
const { issues } = await tools.mcp__linear__list_issues({
team: "Pi", state: "open", limit: 250,
});
const jev = await models.getModelOfType(
"classifier", "cloudflare-workers-ai", "typesafe/jev",
);
const questions = {
frustration: {
type: "choice",
instructions: "Judge ONLY the emotional tone of the people writing. " +
"Ignore how severe the bug is.",
criteria: {
none: "Neutral, factual, or friendly, even about a serious bug",
mild: "Explicit annoyance, impatience, or disappointment",
high: "Clearly angry, exasperated, sarcastic, or fed up",
},
},
};
const results = [];
let next = 0;
async function worker() {
while (next < issues.length) {
const issue = issues[next++];
const { comments } = await tools.mcp__linear__list_comments({
issueId: issue.identifier,
});
const c = await models.classify(jev, { state: { ...issue, comments }, questions });
results.push({ id: issue.identifier, title: issue.title, ...c.answers.frustration });
}
}
await Promise.all([worker(), worker(), worker(), worker()]);
store("frustration", results);
const score = (r) => r.probabilities.mild * 0.5 + r.probabilities.high;
const counts = {};
for (const r of results) counts[r.choice] = (counts[r.choice] ?? 0) + 1;
const flagged = results.filter((r) => r.choice !== "none");
flagged.sort((a, b) => score(b) - score(a));
return {
total: results.length,
counts,
flagged: flagged.map((r) => `${r.id} ${r.title}`),
};
... (331 earlier calls)
✓ mcp__linear__list_issues {"team":"Pi","state":"open","limit":250} 450ms
✓ mcp__linear__list_comments {"issueId":"PI-4714"} 255ms
✓ mcp__linear__list_comments {"issueId":"PI-3200"} 354ms
✓ models.classify cloudflare-workers-ai/typesafe/jev 756ms
✓ models.classify cloudflare-workers-ai/typesafe/jev 750ms
{
"total": 167,
"counts": {
"none": 156,
"mild": 11
},
"flagged": [
"PI-7740 TUI after /reload does not follows custom tool's re…",
"PI-9566 context size defaults to 128k despite the real size…",
"PI-10031 Pi sporadically stuck in \"Working...\" when thinking…",
"PI-4714 [feature] /update TUI command instead of pi update",
"PI-5916 Support provider extensions with model aliases and…",
"PI-7547 [Windows] [sink-thread] How do you use Pi on window…",
"PI-6907 Add an Installation section to the README",
"PI-6212 Proposal: Bedrock path should honor `compat.forceAd…",
"PI-9932 before_agent_start: forced system prompt keeps tool…",
"PI-7730 High CPU usage on Mac OS with long session",
"PI-6600 pi update --extensions and npm scripts: npm 11.16.0…"
]
}
Most of the tracker is calm. Jev rated 156 of the 167 open issues as neutral, 11
as mildly frustrated and none as highly frustrated.
The clearest cases:
- PI-6907 no installation section in the README ("It's frustrating") - PI-10031
Pi gets stuck on "Working..." after pressing Esc during thinking - PI-4714 a
/update command request ("a pain in the butt") - PI-7730 high CPU usage on macOS
in long sessions
The per-issue verdicts are stored in codemode under frustration, so I can dig
into any of them without fetching the issues again.
О Jev и Codemode ещё будет больше информации, но эта статья служит примером того, как авторы продолжают внимательно адаптировать Pi по мере эволюции мира.