PAI Knowledge OSBLOCK
Personal AI Infrastructure
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Claude Code has a memory problem. Every new session starts cold — no idea what you built yesterday, what decisions you made, or where you left off. PAI fixes this.
Install PAI and Claude remembers. Ask it what you were working on, find that conversation about the database schema, or pick up exactly where the last session ended.
- Automatic session notes, split by topic, written by a background daemon
- Federated keyword and semantic search across sessions, notes and vaults
- Workers on any provider, orchestrated from one Claude Code session
- Everything runs locally
Install
The easy way, on macOS and Linux: open Claude Code and say "Clone https://github.com/mnott/PAI and set it up for me" Claude installs PAI, runs the setup wizard and checks the daemon.
Prerequisites: Claude Code, Node.js 20 or newer, and Docker if you choose PostgreSQL.
By hand, the same on macOS and Linux:
npm i -g @tekmidian/pai pai setup --yes --storage postgres # keyword + semantic search (pgvector in Docker); or: --storage sqlite pai daemon status # should show "running"
pai setup without --yes asks every question interactively. It installs the daemon as a LaunchAgent on macOS and a systemd user service on Linux. From a source checkout: git clone https://github.com/mnott/PAI && cd PAI && bun install && bun run build.
→ docs/install.md · docs/install-linux.md (both storage paths, Docker, systemd)
Command Reference
Every pai command area has a man page generated from the live CLI: pai help, pai help memory, pai memory --help.
→ docs/command-reference.md · docs/commands/
Worker Providers
Only the orchestrator session runs on Anthropic; every worker runs on a provider you choose, routed by class. Providers and classes live in one workers.yaml.
→ [docs/w
27a6963b9bccOBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add obsidian-pai-knowledge --env ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} --env ANTHROPIC_AUTH_TOKEN=${ANTHROPIC_AUTH_TOKEN} --env PAI_PASS_BACKGROUND=${PAI_PASS_BACKGROUND} --env TODOIST_API_KEY=${TODOIST_API_KEY} -- npx -y [email protected]{
"mcpServers": {
"obsidian-pai-knowledge": {
"command": "npx",
"args": [
"-y",
"[email protected]"
],
"env": {
"ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}",
"ANTHROPIC_AUTH_TOKEN": "${ANTHROPIC_AUTH_TOKEN}",
"PAI_PASS_BACKGROUND": "${PAI_PASS_BACKGROUND}",
"TODOIST_API_KEY": "${TODOIST_API_KEY}"
}
}
}
}Exposed tools (38)
36 read · 2 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
Bar | read | a disabled plugin skill |
Baz | read | unregistered plugin skill |
Foo | read | a skill |
Sessions | read | navigate sessions |
Shared | read | same skill twice |
config_get | read | |
config_list | read | |
config_set | write | |
config_unset | read | |
get_weather | read | Weather of a city |
memory_feedback | read | |
memory_get | read | |
memory_kg_search | read | |
memory_outline | read | |
memory_search | read | |
memory_taxonomy | read | |
memory_tunnels | read | |
memory_wakeup | read | |
project_detect | read | |
project_health | read | |
project_info | read | |
project_list | read | |
project_todo | read | |
registry_search | read | |
session_list | read | |
worker_capability | read | |
worker_classes | read | |
worker_fallback | read | |
worker_handoff | read | |
worker_model | read | |
worker_providers | read | |
worker_ps | read | |
worker_replay | read | |
worker_resume | read | |
worker_run | write | |
worker_say | read | |
worker_status | read | |
worker_toggle | read |
Trust audit
BLOCKgrade F · trust 36/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (8 observation(s))
- Network
- declared (9 observation(s))
- Shell
- declared (10 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
"\n" + chalk.bold("Dry run — would probe then exec (RESUME path):") + "\n""\n" + chalk.bold("Dry run — would exec (FRESH path, no resumable UUID):") + "\n"console.log("\n" + chalk.bold("Dry run — would exec (WORKER path):") + "\n");console.log("\n" + chalk.bold("Dry run — would probe then exec (RESUME path):") + "\n");console.log("\n" + chalk.bold("Dry run — would exec (FRESH path):") + "\n");* bun docker/migrate-sqlite.ts --connection-string "postgresql://pai:pai@localhost:5432/pai"
* or "postgresql://pai:pai@localhost:5432/pai" if not configured.
let connectionString = "postgresql://pai:pai@localhost:5432/pai";
const connStr = "postgresql://pai:pai@localhost:5432/pai";
<!-- Personal preferences and project mappings are read from ~/.claude/pai/agent-prefs.md -->
| [`pai shell-init`](shell-init.md) | Emit shell integration code. Add to ~/.zshrc: eval "$(pai shell-init)" |
| `pai shell-init` | Emit shell integration code. Add to ~/.zshrc: eval "$(pai shell-init)" |
> Emit shell integration code. Add to ~/.zshrc: eval "$(pai shell-init)"
console.log(dim(`token encoding: ${data.encoding}`));console.log(` ${bold("Token")} ${redact(todoist.apiKey)}${embedding: { backend: "transformers-cpu-q8", ollama: { baseUrl: "http://127.0.0.1:11434" } },ollamaBaseUrl: config.embedding?.ollama?.baseUrl ?? "http://127.0.0.1:11434",
WHEN path LIKE '👨💻 People/%' THEN 1
setConfigValueOp("postgres.connectionString", "postgresql://pai:hunter2@localhost:5432/pai", { force: true });If the user says **yes** (or this is a fresh setup): run the scan.
description: "Run the task bus — read cross-session work from the tracker, dispatch it to the sessions that own it, and file new findings. USE WHEN user says 'morning routine', 'what needs doing', 'ru
USE WHEN user says 'morning routine', 'what needs doing', 'run the routine', 'check my tasks', 'dispatch tasks', 'file a finding', 'add this to todoist', 'what did we find', OR /tasks.
curl -fsSL https://bun.sh/install | bash
import type { Finding } from "../../audit/severity.js";import { TOKEN_ENCODING } from "../../audit/tokens.js";Gates applied: no_behavioural_pass.
27a6963b9bccfull audit observations/trust-audit/mcp-server/mnott__pai.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | 27a6963b9bcc | BLOCK | F | 36 | first audit |
Questions
What is the @tekmidian/pai MCP server?
Personal AI Infrastructure
What tools does @tekmidian/pai expose?
38 in total: 36 read-only, 2 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is @tekmidian/pai safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (36/100) and found 13 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does @tekmidian/pai need?
It reads ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, PAI_PASS_BACKGROUND and TODOIST_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does @tekmidian/pai run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as obsidian-pai-knowledge at 0.1.0.
How current is this page?
The grade is for one exact copy of the source (27a6963b9bcc), read on 2026-10-11. The repository is watched and re-audited when it changes.