feat(security): seed Yerin agent + registry-selectable MCP server

- migration 011_yerin.sql: seed read-only 'yerin' agent ({read:true}, kind claude,
  model NULL = server default; switch to local Ollama via agents.model anytime)
- companion-stdio.js: select the toolset from VOID_TOOL_REGISTRY ('security' →
  Yerin's securityRegistry; default → Dross's companionRegistry)
- tests/mcp/registry_select.test.js

Remaining for Yerin (left for review): an entry point (route or cron) + persona
prompt — see docs/yerin-security-agent.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-02 00:17:53 +10:00
parent c45246b918
commit a3eb5a58f0
3 changed files with 62 additions and 4 deletions

View File

@@ -20,8 +20,16 @@ import {
CallToolRequestSchema
} from '@modelcontextprotocol/sdk/types.js';
import { companionRegistry } from '../ai/agent/tools/index.js';
import { securityRegistry } from '../ai/agent/tools/security/index.js';
import { buildCtxFromEnv } from './context.js';
// Which toolset this stdio server exposes, selected at launch via
// VOID_TOOL_REGISTRY (default: Dross's companion tools; 'security' = Yerin's).
const REGISTRIES = { companion: companionRegistry, security: securityRegistry };
function resolveRegistry(env = process.env) {
return REGISTRIES[env.VOID_TOOL_REGISTRY] || companionRegistry;
}
// ---------------------------------------------------------------------------
// Transport-free helpers (exported for testing)
// ---------------------------------------------------------------------------
@@ -30,8 +38,8 @@ import { buildCtxFromEnv } from './context.js';
* Returns the list of MCP tool descriptors (no handler) from the companion registry.
* @returns {{ name: string, description: string, input_schema: object }[]}
*/
export function listMcpTools() {
return companionRegistry.listTools().map(({ name, description, input_schema }) => ({
export function listMcpTools(env = process.env) {
return resolveRegistry(env).listTools().map(({ name, description, input_schema }) => ({
name,
description,
input_schema
@@ -45,8 +53,8 @@ export function listMcpTools() {
* @param {object} ctx tool context {agent, space_id, view, actor}
* @returns {Promise<object>} raw handler result
*/
export async function callMcpTool(name, args, ctx) {
const tool = companionRegistry.getTool(name);
export async function callMcpTool(name, args, ctx, env = process.env) {
const tool = resolveRegistry(env).getTool(name);
if (!tool) {
throw new Error(`Unknown tool: ${name}`);
}