commit 2e3715ee8bffc95f39383510e9b5374be1ad3280 Spenser Truex <truex@equwal.com> 2025-09-07 11:52:57 -0700 Initial commit
.aim/memory.jsonl | 0 .mcp.json | 566 +++++++++++++++++++++++++++++++++++++++++ README.md | 97 +++++++ restart-runlevel | 5 + services/irc/libera_onechannel | 1 + services/quark/quark_onefolder | 1 + tiny-runlevels | 1 + 7 files changed, 671 insertions(+)
diff --git a/.aim/memory.jsonl b/.aim/memory.jsonl new file mode 100644 index 0000000..e69de29 diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..c74c483 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,566 @@ +{ + "mcpServers": { + "permissions": { + "auto_approved_tools": [ + "memory", + "read-website-fast", + "duckduckgo", + "arxiv", + "hacker-news", + "sequential-thinking", + "llm-context", + "file-merger", + "everything-search", + "markitdown", + "mcpmcp", + "1mcp-agent", + "magg", + "open-library", + "manim-server", + "blender-mcp", + "bazi-mcp", + "quran-mcp", + "metmuseum-mcp", + "playwright-executeautomation", + "apple-reminders", + "youtube-transcript", + "playwright-microsoft", + "mcp-browser-kit", + "apple-shortcuts", + "aws-pricing-mcp", + "books-mcp-server", + "node-code-sandbox-mcp", + "mcp-server-leetcode", + "codemcp", + "leetcode-mcp-server", + "code-to-tree", + "serena", + "code-assistant", + "maxmsp-mcp-server", + "vertex-developer", + "mcp-server-notify", + "opendata-mcp", + "dicom-mcp", + "mongodb-lens", + "mcp-sqlite", + "mcp-server-duckdb", + "mongo-mcp", + "prisma-mcp", + "mcp-server-qdrant", + "quarkus-jdbc", + "redis-mcp-server", + "mcp-alchemy", + "aseprite-mcp", + "oorlogsbronnen-server", + "anilist-mcp" + ], + "require_permission": [ + "desktop-commander", + "docker", + "taskwarrior", + "playwright", + "playwright-executeautomation", + "apple-reminders", + "youtube-transcript", + "playwright-microsoft", + "mcp-browser-kit", + "apple-shortcuts" + ], + "claude_tools": { + "auto_approved": { + "read_operations": [ + "Read", + "Glob", + "Grep", + "WebFetch", + "WebSearch" + ], + "bash_read_only": [ + "ls", + "cat", + "grep", + "find", + "head", + "tail", + "wc", + "file", + "stat", + "pwd", + "whoami", + "date", + "ps", + "top", + "df", + "du", + "which", + "whereis" + ] + }, + "require_permission": { + "write_operations": [ + "Write", + "Edit", + "MultiEdit", + "NotebookEdit" + ], + "bash_write_operations": [ + "mkdir", + "touch", + "cp", + "mv", + "rm", + "chmod", + "chown", + "git", + "npm", + "pip", + "cargo", + "make", + "docker", + "systemctl", + "service" + ] + } + } + }, + "memory": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mcp-knowledge-graph", + "--memory-path", + "/home/jose/.config/claude-desktop/.aim/memory.jsonl" + ] + }, + "read-website-fast": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@just-every/mcp-read-website-fast" + ] + }, + "desktop-commander": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@wonderwhy-er/desktop-commander" + ] + }, + "sequential-thinking": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-sequential-thinking" + ] + }, + "taskwarrior": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mcp-server-taskwarrior" + ] + }, + "playwright": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@automatalabs/mcp-server-playwright" + ] + }, + "duckduckgo": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "duckduckgo-mcp-server" + ] + }, + "arxiv": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "arxiv-mcp-server" + ] + }, + "hacker-news": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mcp-hn" + ] + }, + "docker": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mcp-server-docker" + ] + }, + "mcpmcp": { + "type": "stdio", + "command": "npx", + "args": ["-y", "mcp-remote@latest", "https://mcpmcp.io/mcp"] + }, + "llm-context": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "llm-context", + "lc-mcp" + ] + }, + "file-merger": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@exoticknight/mcp-file-merger", + "/home/jose/.config/claude-desktop" + ] + }, + "everything-search": { + "type": "stdio", + "command": "uvx", + "args": [ + "mcp-server-everything-search" + ] + }, + "markitdown": { + "type": "stdio", + "command": "uvx", + "args": [ + "markitdown-mcp" + ] + }, + "1mcp-agent": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@1mcp/agent" + ] + }, + "magg": { + "type": "stdio", + "command": "uvx", + "args": [ + "magg" + ] + }, + "open-library": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@8enSmith/mcp-open-library" + ] + }, + "manim-server": { + "type": "stdio", + "command": "uvx", + "args": [ + "manim-mcp-server" + ] + }, + "blender-mcp": { + "type": "stdio", + "command": "uvx", + "args": [ + "blender-mcp" + ] + }, + "bazi-mcp": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@cantian-ai/bazi-mcp" + ] + }, + "quran-mcp": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "quran-mcp-server" + ] + }, + "metmuseum-mcp": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "metmuseum-mcp" + ] + }, + "playwright-executeautomation": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@executeautomation/playwright-mcp-server" + ] + }, + "apple-reminders": { + "type": "stdio", + "command": "mcp-server-apple-reminders", + "args": [] + }, + "youtube-transcript": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@kimtaeyoon83/mcp-server-youtube-transcript" + ] + }, + "playwright-microsoft": { + "type": "stdio", + "command": "npx", + "args": [ + "@playwright/mcp@latest" + ] + }, + "mcp-browser-kit": { + "type": "stdio", + "command": "npx", + "args": [ + "@mcp-browser-kit/server" + ] + }, + "apple-shortcuts": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mcp-server-apple-shortcuts" + ] + }, + "aws-pricing-mcp": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "git+https://github.com/trilogy-group/aws-pricing-mcp", + "aws-pricing-mcp" + ] + }, + "books-mcp-server": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "git+https://github.com/VmLia/books-mcp-server", + "books-mcp-server" + ] + }, + "node-code-sandbox-mcp": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "node-code-sandbox-mcp" + ] + }, + "mcp-server-leetcode": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@mcpfun/mcp-server-leetcode" + ] + }, + "codemcp": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "git+https://github.com/ezyang/codemcp@prod", + "codemcp" + ] + }, + "leetcode-mcp-server": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@jinzcdev/leetcode-mcp-server" + ] + }, + "code-to-tree": { + "type": "stdio", + "command": "code-to-tree", + "args": [] + }, + "serena": { + "type": "stdio", + "command": "uvx", + "args": [ + "serena" + ] + }, + "code-assistant": { + "type": "stdio", + "command": "code-assistant", + "args": [] + }, + "maxmsp-mcp-server": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "git+https://github.com/tiianhk/MaxMSP-MCP-Server", + "maxmsp-mcp-server" + ] + }, + "vertex-developer": { + "type": "stdio", + "command": "developer", + "args": [] + }, + "mcp-server-notify": { + "type": "stdio", + "command": "uvx", + "args": [ + "mcp-server-notify" + ] + }, + "opendata-mcp": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "git+https://github.com/OpenDataMCP/OpenDataMCP", + "odmcp" + ] + }, + "dicom-mcp": { + "type": "stdio", + "command": "uvx", + "args": [ + "dicom-mcp" + ] + }, + "mongodb-lens": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mongodb-lens" + ] + }, + "mcp-sqlite": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mcp-sqlite", + "/tmp/example.db" + ] + }, + "mcp-server-duckdb": { + "type": "stdio", + "command": "uvx", + "args": [ + "mcp-server-duckdb", + "--db-path", + "/tmp/example.duckdb" + ] + }, + "mongo-mcp": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "mongo-mcp", + "mongodb://localhost:27017/test" + ] + }, + "prisma-mcp": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "prisma", + "mcp" + ] + }, + "mcp-server-qdrant": { + "type": "stdio", + "command": "uvx", + "args": [ + "mcp-server-qdrant" + ], + "env": { + "QDRANT_URL": "http://localhost:6333", + "COLLECTION_NAME": "default" + } + }, + "quarkus-jdbc": { + "type": "stdio", + "command": "jbang", + "args": [ + "jdbc@quarkiverse/quarkus-mcp-servers", + "jdbc:sqlite::memory:" + ] + }, + "redis-mcp-server": { + "type": "stdio", + "command": "uvx", + "args": [ + "redis-mcp-server", + "--url", + "redis://localhost:6379/0" + ] + }, + "mcp-alchemy": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "mcp-alchemy", + "--with", + "sqlite", + "mcp-alchemy" + ], + "env": { + "DB_URL": "sqlite:///tmp/example.db" + } + }, + "aseprite-mcp": { + "type": "stdio", + "command": "uvx", + "args": [ + "--from", + "git+https://github.com/diivi/aseprite-mcp", + "aseprite-mcp" + ] + }, + "oorlogsbronnen-server": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "oorlogsbronnen-mcp" + ] + }, + "anilist-mcp": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "anilist-mcp" + ] + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..4985776 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +Using OpenRC runlevels to have lots of instances of simple (network) +programs like quark for multiple http serving locally or ii (or sic) +for IRC server connections. + +To keep programs simple, they should not do the same process for +unrelated uses. It is much more complicated to configure and manage +multiple webservers in the same process (like how nginx does it) than +just one. Init systems are designed to manage processes, and should be +used instead. Do one thing etc. etc. + +This is how to use the OpenRC runlevels for quark and ii runlevels +as examples. + +## The Tree (on my machine) + +```sh +/etc/runlevels +├── boot +│ └── ... +├── default +│ └── ... +├── irc-base +│ ├── oftc -> /etc/init.d/oftc +│ ├── liberachat -> /etc/init.d/liberachat +│ └── ... +├── net-base +│ ├── default -> ../default +│ └── quark -> ../quark +├── net-offline +│ ├── default -> ../default +│ └── net-base -> ../net-base +├── net-dns +│ ├── dnscrypt-proxy -> /etc/init.d/dnscrypt-proxy +│ └── unbound -> /etc/init.d/unbound +├── net-wifi +│ ├── dhcpcd -> /etc/init.d/dhcpcd +│ ├── net-base -> /etc/runlevels/net-base +│ ├── net-dns -> /etc/runlevels/net-dns +│ └── wpa_supplicant -> /etc/init.d/wpa_supplicant +├── net-wifi-irc +│ ├── irc-base -> ../irc-base +│ └── net-wifi -> ../net-wifi +├── quark +│ ├── quark-docs -> /etc/init.d/quark-docs +│ ├── quark-equwal -> /etc/init.d/quark-equwal +│ └── ... +├── shutdown +│ └── ... +└── sysinit + └── ... +``` +as you can see, IRC is connected after the real internet on wifi +(net-wifi), but quark runs on any network runlevel using net-base. + +## How To: + +OpenRC has its own commands for making the runlevels, but I find them +confusing. Let's just edit the files. + +```sh +# make runlevel +mkdir /etc/runlevels/quark +# add services (as many as needed) +ln -s /etc/int.d/quark-whatever /etc/runlevels/quark +# add runlevel to parent +ln -s /etc/runlevels/default /etc/runlevels/quark +# Reload since openrc is in default +openrc default +``` + +That works, but what about for networked IRC on a custom networking runlevel? Just add it to the networking runlevel. +```sh +# (first, make a network runlevel that contains default! Without default the system will crash, obviously.) +mkdir /etc/runlevels/net-wifi +ln -s /etc/runlevels/net-wifi /etc/runlevels/default +ln -s /etc/init.d/wpa_supplicant /etc/runlevels/net-wifi +# etc. +# Now add the irc-base to the network runlevel +mkdir /etc/runlevels/irc-base +ln -s /etc/init.d/liberachat irc-base +ln -s /etc/init.d/oftc irc-base +ln -s /etc/runlevels/irc-base /etc/runlevels/net-wifi +openrc net-wifi +``` + +## Tool: restart-runlevel +Openrc wants switch the whole stack `openrc runlevel` so I made a little +tool to just restart a specific runlevel. Nice for debugging. + +```sh +#!/bin/bash + +for link in /etc/runlevels/${1}/* +do [[ -L "$link" && "$(readlink "$link")" == /etc/init.d/* ]] && \ + rc-service "$(basename "$link")" restart +done +``` diff --git a/restart-runlevel b/restart-runlevel new file mode 100755 index 0000000..ead27d5 --- /dev/null +++ b/restart-runlevel @@ -0,0 +1,5 @@ +#!/bin/bash +for link in /etc/runlevels/${1}/* +do [[ -L "$link" && "$(readlink "$link")" == /etc/init.d/* ]] && \ + rc-service "$(basename "$link")" restart +done diff --git a/services/irc/libera_onechannel b/services/irc/libera_onechannel new file mode 120000 index 0000000..6bd899f --- /dev/null +++ b/services/irc/libera_onechannel @@ -0,0 +1 @@ +../../../ii-lchat-metapackage/services/lispirc \ No newline at end of file diff --git a/services/quark/quark_onefolder b/services/quark/quark_onefolder new file mode 120000 index 0000000..32e6e43 --- /dev/null +++ b/services/quark/quark_onefolder @@ -0,0 +1 @@ +/etc/init.d/quark \ No newline at end of file diff --git a/tiny-runlevels b/tiny-runlevels new file mode 100755 index 0000000..1a24852 --- /dev/null +++ b/tiny-runlevels @@ -0,0 +1 @@ +#!/bin/sh