a digital entity named phi that roams bsky
phi.zzstoatzz.io
1# mcp integration
2
3phi uses the [model context protocol](https://modelcontextprotocol.io) to access external tools hosted as remote servers.
4
5## servers
6
7phi connects to two MCP servers via `MCPServerStreamableHTTP` (pydantic-ai):
8
9- **[pdsx](https://pdsx-by-zzstoatzz.fastmcp.app)** — atproto record CRUD. authenticated with phi's bluesky credentials. used for reading/writing posts, profiles, and records on any PDS.
10- **[pub-search](https://pub-search-by-zzstoatzz.fastmcp.app)** — publication search across leaflet, whitewind, and other long-form writing platforms. prefixed as `pub_*` to avoid tool name collisions.
11
12## why mcp
13
14- **separation**: tools live in external servers, not in phi's codebase
15- **extensibility**: add new capabilities by connecting another server
16- **reusability**: same servers can be used by other agents or tools
17- **no local dependencies**: phi doesn't need to bundle atproto client libraries for record CRUD
18
19## how it works
20
21MCP servers are created fresh per `agent.run()` call to avoid connection scope issues. the agent enters each server's async context before running, so parallel tool calls share the connection.
22
23```python
24toolsets = self._mcp_toolsets()
25async with contextlib.AsyncExitStack() as stack:
26 for ts in toolsets:
27 await stack.enter_async_context(ts)
28 result = await self.agent.run(prompt, deps=deps, toolsets=toolsets)
29```
30
31## native tools vs MCP tools
32
33phi has two kinds of tools:
34
35- **native tools** (defined in `src/bot/tools/`) — memory, search, cosmik records, trending, feeds, posting. these need direct access to phi's deps (memory client, config, etc).
36- **MCP tools** (from remote servers) — atproto CRUD, publication search. these are stateless HTTP calls that don't need phi's internal state.
37
38the agent sees all tools uniformly and picks the right one for the task.