agent-orchestrator-mcp-server 0.5.0 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-orchestrator-mcp-server",
3
- "version": "0.5.0",
3
+ "version": "0.6.7",
4
4
  "description": "Local implementation of agent-orchestrator MCP server",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
@@ -26,15 +26,11 @@ export interface AgentRootValidationResult {
26
26
  * Validate a start_session request against the allowed agent roots constraints.
27
27
  *
28
28
  * When ALLOWED_AGENT_ROOTS is set:
29
- * - git_root (and optionally branch/subdirectory) must match one of the allowed agent roots
29
+ * - agent_root must be provided and must be one of the allowed agent root names
30
30
  * - mcp_servers must exactly match the default_mcp_servers of that agent root
31
31
  * (no more, no less — any deviation is rejected)
32
32
  *
33
- * When multiple allowed agent roots share the same git_root, branch and subdirectory
34
- * are used to disambiguate. This is critical for monorepo setups where multiple agent
35
- * roots point to the same repository but different subdirectories.
36
- *
37
33
  * Returns { valid: true } if the request is allowed, or { valid: false, error: string } if not.
38
34
  */
39
- export declare function validateAgentRootConstraints(allowedRoots: string[] | null, agentRoots: AgentRootInfo[], gitRoot?: string, mcpServers?: string[], branch?: string, subdirectory?: string): AgentRootValidationResult;
35
+ export declare function validateAgentRootConstraints(allowedRoots: string[] | null, agentRoots: AgentRootInfo[], agentRootName?: string, mcpServers?: string[]): AgentRootValidationResult;
40
36
  //# sourceMappingURL=allowed-agent-roots.d.ts.map
@@ -39,46 +39,37 @@ export function filterAgentRoots(agentRoots, allowedRoots) {
39
39
  * Validate a start_session request against the allowed agent roots constraints.
40
40
  *
41
41
  * When ALLOWED_AGENT_ROOTS is set:
42
- * - git_root (and optionally branch/subdirectory) must match one of the allowed agent roots
42
+ * - agent_root must be provided and must be one of the allowed agent root names
43
43
  * - mcp_servers must exactly match the default_mcp_servers of that agent root
44
44
  * (no more, no less — any deviation is rejected)
45
45
  *
46
- * When multiple allowed agent roots share the same git_root, branch and subdirectory
47
- * are used to disambiguate. This is critical for monorepo setups where multiple agent
48
- * roots point to the same repository but different subdirectories.
49
- *
50
46
  * Returns { valid: true } if the request is allowed, or { valid: false, error: string } if not.
51
47
  */
52
- export function validateAgentRootConstraints(allowedRoots, agentRoots, gitRoot, mcpServers, branch, subdirectory) {
48
+ export function validateAgentRootConstraints(allowedRoots, agentRoots, agentRootName, mcpServers) {
53
49
  if (allowedRoots === null) {
54
50
  return { valid: true };
55
51
  }
56
- // Find all allowed agent roots that match by git_root
57
- const candidates = agentRoots.filter((root) => allowedRoots.includes(root.name) && root.git_root === gitRoot);
58
- // When multiple candidates share the same git_root, disambiguate using branch and subdirectory
59
- let matchingRoot;
60
- if (candidates.length > 1) {
61
- matchingRoot = candidates.find((root) => {
62
- const branchMatch = !branch || (root.default_branch ?? 'main') === branch;
63
- const subdirMatch = !subdirectory || root.default_subdirectory === subdirectory;
64
- return branchMatch && subdirMatch;
65
- });
52
+ if (!agentRootName) {
53
+ return {
54
+ valid: false,
55
+ error: `ALLOWED_AGENT_ROOTS is set — agent_root is required. ` +
56
+ `Allowed agent roots: ${allowedRoots.join(', ')}`,
57
+ };
66
58
  }
67
- else {
68
- matchingRoot = candidates[0];
59
+ if (!allowedRoots.includes(agentRootName)) {
60
+ return {
61
+ valid: false,
62
+ error: `ALLOWED_AGENT_ROOTS is set — agent_root "${agentRootName}" is not permitted. ` +
63
+ `Allowed agent roots: ${allowedRoots.join(', ')}`,
64
+ };
69
65
  }
66
+ // Find the matching agent root config to validate mcp_servers
67
+ const matchingRoot = agentRoots.find((root) => root.name === agentRootName);
70
68
  if (!matchingRoot) {
71
- const allowedNames = allowedRoots.join(', ');
72
- const allowedGitRoots = agentRoots
73
- .filter((root) => allowedRoots.includes(root.name))
74
- .map((root) => root.git_root);
75
69
  return {
76
70
  valid: false,
77
- error: `ALLOWED_AGENT_ROOTS is set only the following agent roots are permitted: ${allowedNames}. ` +
78
- `The provided git_root "${gitRoot || '(not provided)'}" does not match any allowed agent root. ` +
79
- (allowedGitRoots.length > 0
80
- ? `Allowed git_root values: ${allowedGitRoots.join(', ')}`
81
- : 'No matching agent roots found in configuration.'),
71
+ error: `Agent root "${agentRootName}" is in the allowed list but was not found in the configuration. ` +
72
+ `Available agent roots: ${agentRoots.map((r) => r.name).join(', ')}`,
82
73
  };
83
74
  }
84
75
  // Validate mcp_servers matches the default_mcp_servers exactly
@@ -178,9 +178,14 @@ export class AgentOrchestratorClient {
178
178
  return response.session;
179
179
  }
180
180
  async createSession(data) {
181
- // Remap `skills` to `catalog_skills` for the API (Rails strong params expects `catalog_skills`)
182
- const { skills, ...rest } = data;
183
- const body = skills !== undefined ? { ...rest, catalog_skills: skills } : rest;
181
+ // Remap `skills` to `catalog_skills` and `plugins` to `catalog_plugins`
182
+ // for the API (Rails strong params expects `catalog_skills`/`catalog_plugins`)
183
+ const { skills, plugins, ...rest } = data;
184
+ const body = {
185
+ ...rest,
186
+ ...(skills !== undefined && { catalog_skills: skills }),
187
+ ...(plugins !== undefined && { catalog_plugins: plugins }),
188
+ };
184
189
  const response = await this.request('POST', '/sessions', body);
185
190
  return response.session;
186
191
  }
@@ -77,6 +77,9 @@ function formatSessionDetails(session, includeTranscript) {
77
77
  if (session.catalog_skills && session.catalog_skills.length > 0) {
78
78
  lines.push(`- **Skills:** ${session.catalog_skills.join(', ')}`);
79
79
  }
80
+ if (session.catalog_plugins && session.catalog_plugins.length > 0) {
81
+ lines.push(`- **Plugins:** ${session.catalog_plugins.join(', ')}`);
82
+ }
80
83
  if (session.prompt) {
81
84
  lines.push('');
82
85
  lines.push('### Current Prompt');
@@ -4,43 +4,40 @@ import type { IAgentOrchestratorClient } from '../orchestrator-client/orchestrat
4
4
  export declare const StartSessionSchema: z.ZodObject<{
5
5
  agent_type: z.ZodOptional<z.ZodString>;
6
6
  prompt: z.ZodOptional<z.ZodString>;
7
- git_root: z.ZodOptional<z.ZodString>;
8
- branch: z.ZodOptional<z.ZodString>;
9
- subdirectory: z.ZodOptional<z.ZodString>;
7
+ agent_root: z.ZodOptional<z.ZodString>;
10
8
  title: z.ZodOptional<z.ZodString>;
11
9
  slug: z.ZodOptional<z.ZodString>;
12
10
  stop_condition: z.ZodOptional<z.ZodString>;
13
11
  execution_provider: z.ZodOptional<z.ZodEnum<["local_filesystem", "remote_sandbox"]>>;
14
12
  mcp_servers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
15
13
  skills: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
14
+ plugins: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
16
15
  config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
17
16
  custom_metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
18
17
  }, "strip", z.ZodTypeAny, {
19
18
  agent_type?: string | undefined;
20
19
  skills?: string[] | undefined;
20
+ plugins?: string[] | undefined;
21
21
  prompt?: string | undefined;
22
- git_root?: string | undefined;
23
- branch?: string | undefined;
24
- subdirectory?: string | undefined;
25
22
  title?: string | undefined;
26
23
  slug?: string | undefined;
27
24
  stop_condition?: string | undefined;
28
25
  execution_provider?: "local_filesystem" | "remote_sandbox" | undefined;
29
26
  mcp_servers?: string[] | undefined;
27
+ agent_root?: string | undefined;
30
28
  config?: Record<string, unknown> | undefined;
31
29
  custom_metadata?: Record<string, unknown> | undefined;
32
30
  }, {
33
31
  agent_type?: string | undefined;
34
32
  skills?: string[] | undefined;
33
+ plugins?: string[] | undefined;
35
34
  prompt?: string | undefined;
36
- git_root?: string | undefined;
37
- branch?: string | undefined;
38
- subdirectory?: string | undefined;
39
35
  title?: string | undefined;
40
36
  slug?: string | undefined;
41
37
  stop_condition?: string | undefined;
42
38
  execution_provider?: "local_filesystem" | "remote_sandbox" | undefined;
43
39
  mcp_servers?: string[] | undefined;
40
+ agent_root?: string | undefined;
44
41
  config?: Record<string, unknown> | undefined;
45
42
  custom_metadata?: Record<string, unknown> | undefined;
46
43
  }>;
@@ -58,17 +55,9 @@ export declare function startSessionTool(_server: Server, clientFactory: () => I
58
55
  type: string;
59
56
  description: "Initial prompt for the agent. If provided, the agent job is automatically queued. Omit for a clone-only session.";
60
57
  };
61
- git_root: {
58
+ agent_root: {
62
59
  type: string;
63
- description: "Repository URL or local path. Examples: \"https://github.com/example/repo.git\", \"/path/to/repo\"";
64
- };
65
- branch: {
66
- type: string;
67
- description: "Git branch to work on. Default: \"main\"";
68
- };
69
- subdirectory: {
70
- type: string;
71
- description: string;
60
+ description: "Agent root name from get_configs. The API resolves git_root, branch, subdirectory, default_model, and other defaults from the agent root configuration. Always pass this so the session inherits the correct repository, model, and settings.";
72
61
  };
73
62
  title: {
74
63
  type: string;
@@ -101,6 +90,13 @@ export declare function startSessionTool(_server: Server, clientFactory: () => I
101
90
  };
102
91
  description: "List of skill names to enable for this session. Always include the agent root's default_skills from get_configs as the starting point — omitting skills means the session gets none. Add extras as needed; removing a default should be rare and intentional. Example: [\"discovery-classify\", \"publish-and-pr\"]";
103
92
  };
93
+ plugins: {
94
+ type: string;
95
+ items: {
96
+ type: string;
97
+ };
98
+ description: "List of plugin names to enable for this session. Plugins extend agent capabilities with additional integrations. Example: [\"my-plugin\"]";
99
+ };
104
100
  config: {
105
101
  type: string;
106
102
  description: "Additional configuration as a JSON object.";
@@ -4,14 +4,7 @@ import { getConfigsCache, setConfigsCache } from '../cache/configs-cache.js';
4
4
  const PARAM_DESCRIPTIONS = {
5
5
  agent_type: 'Agent type for the session. Currently only "claude_code" is supported. Default: "claude_code"',
6
6
  prompt: 'Initial prompt for the agent. If provided, the agent job is automatically queued. Omit for a clone-only session.',
7
- git_root: 'Repository URL or local path. Examples: "https://github.com/example/repo.git", "/path/to/repo"',
8
- branch: 'Git branch to work on. Default: "main"',
9
- subdirectory: 'Subdirectory within the repository to use as the agent working directory. ' +
10
- 'This should match a preconfigured agent root default_subdirectory from get_configs — it defines ' +
11
- 'the root scope for the agent session. Do NOT use this to point at internal package directories ' +
12
- '(e.g. "experimental/gcs" in a monorepo) as this blinds the agent to root-level configuration ' +
13
- 'like CLAUDE.md, build scripts, CI workflows, and monorepo tooling. If no agent root defines ' +
14
- 'a default_subdirectory, leave this unset.',
7
+ agent_root: 'Agent root name from get_configs. The API resolves git_root, branch, subdirectory, default_model, and other defaults from the agent root configuration. Always pass this so the session inherits the correct repository, model, and settings.',
15
8
  title: 'STRONGLY RECOMMENDED: Always set a title — treat it as effectively required. ' +
16
9
  'The title appears in the AO web UI and push notifications, making sessions identifiable at a glance. ' +
17
10
  'Compose a short, descriptive title (under 70 characters) that captures what the session is doing ' +
@@ -22,15 +15,14 @@ const PARAM_DESCRIPTIONS = {
22
15
  execution_provider: 'Execution environment. Options: "local_filesystem" (runs locally), "remote_sandbox" (runs in isolated sandbox). Default: "local_filesystem"',
23
16
  mcp_servers: 'List of MCP server names to enable for this session. Example: ["github-development", "slack"]',
24
17
  skills: 'List of skill names to enable for this session. Always include the agent root\'s default_skills from get_configs as the starting point — omitting skills means the session gets none. Add extras as needed; removing a default should be rare and intentional. Example: ["discovery-classify", "publish-and-pr"]',
18
+ plugins: 'List of plugin names to enable for this session. Plugins extend agent capabilities with additional integrations. Example: ["my-plugin"]',
25
19
  config: 'Additional configuration as a JSON object.',
26
20
  custom_metadata: 'User-defined metadata as a JSON object. Useful for tracking tickets, projects, etc.',
27
21
  };
28
22
  export const StartSessionSchema = z.object({
29
23
  agent_type: z.string().optional().describe(PARAM_DESCRIPTIONS.agent_type),
30
24
  prompt: z.string().optional().describe(PARAM_DESCRIPTIONS.prompt),
31
- git_root: z.string().optional().describe(PARAM_DESCRIPTIONS.git_root),
32
- branch: z.string().optional().describe(PARAM_DESCRIPTIONS.branch),
33
- subdirectory: z.string().optional().describe(PARAM_DESCRIPTIONS.subdirectory),
25
+ agent_root: z.string().optional().describe(PARAM_DESCRIPTIONS.agent_root),
34
26
  title: z.string().optional().describe(PARAM_DESCRIPTIONS.title),
35
27
  slug: z.string().optional().describe(PARAM_DESCRIPTIONS.slug),
36
28
  stop_condition: z.string().optional().describe(PARAM_DESCRIPTIONS.stop_condition),
@@ -40,12 +32,13 @@ export const StartSessionSchema = z.object({
40
32
  .describe(PARAM_DESCRIPTIONS.execution_provider),
41
33
  mcp_servers: z.array(z.string()).optional().describe(PARAM_DESCRIPTIONS.mcp_servers),
42
34
  skills: z.array(z.string()).optional().describe(PARAM_DESCRIPTIONS.skills),
35
+ plugins: z.array(z.string()).optional().describe(PARAM_DESCRIPTIONS.plugins),
43
36
  config: z.record(z.unknown()).optional().describe(PARAM_DESCRIPTIONS.config),
44
37
  custom_metadata: z.record(z.unknown()).optional().describe(PARAM_DESCRIPTIONS.custom_metadata),
45
38
  });
46
39
  const TOOL_DESCRIPTION = `Start a new agent session in the Agent Orchestrator.
47
40
 
48
- **IMPORTANT:** Before starting a session, call get_configs to discover available MCP servers, stop conditions, and preconfigured agent roots.
41
+ **IMPORTANT:** Before starting a session, call get_configs to discover available agent roots, MCP servers, stop conditions, and their defaults.
49
42
 
50
43
  **Returns:** The created session with its ID, status, and configuration.
51
44
 
@@ -53,7 +46,9 @@ const TOOL_DESCRIPTION = `Start a new agent session in the Agent Orchestrator.
53
46
  - If a prompt is provided, the agent job is automatically queued to start
54
47
  - If no prompt is provided, creates a clone-only session that can be started later with action_session
55
48
 
56
- **Defaults from Agent Roots:** When starting a session that matches a preconfigured agent root (from \`get_configs\`), the agent root defines \`default_mcp_servers\`, \`default_skills\`, and optionally a \`default_stop_condition\`. Omitting \`mcp_servers\` or \`skills\` means the session gets NONE — there is no automatic fallback to defaults.
49
+ **Agent Roots:** Use \`agent_root\` to specify which preconfigured agent root to use. The API resolves git_root, branch, subdirectory, default_model, and other defaults from the agent root configuration.
50
+
51
+ **Defaults from Agent Roots:** The agent root defines \`default_mcp_servers\`, \`default_skills\`, and optionally a \`default_stop_condition\`. Omitting \`mcp_servers\` or \`skills\` means the session gets NONE — there is no automatic fallback to defaults.
57
52
 
58
53
  - **MCP servers:** Start with \`default_mcp_servers\`. Drop servers the task doesn't need (least-privilege). Add extras when the task requires tools beyond the defaults. When \`ALLOWED_AGENT_ROOTS\` is active, you cannot add servers beyond the defaults.
59
54
  - **Skills:** Start with \`default_skills\`. You can freely add skills beyond the defaults. Removing a default skill should be rare and intentional — only when you have a specific reason, like replacing a skill with a more capable variant that covers the same ground. Skills are lightweight text files with no blast radius, so keeping all defaults costs nothing.
@@ -78,17 +73,9 @@ export function startSessionTool(_server, clientFactory) {
78
73
  type: 'string',
79
74
  description: PARAM_DESCRIPTIONS.prompt,
80
75
  },
81
- git_root: {
82
- type: 'string',
83
- description: PARAM_DESCRIPTIONS.git_root,
84
- },
85
- branch: {
86
- type: 'string',
87
- description: PARAM_DESCRIPTIONS.branch,
88
- },
89
- subdirectory: {
76
+ agent_root: {
90
77
  type: 'string',
91
- description: PARAM_DESCRIPTIONS.subdirectory,
78
+ description: PARAM_DESCRIPTIONS.agent_root,
92
79
  },
93
80
  title: {
94
81
  type: 'string',
@@ -117,6 +104,11 @@ export function startSessionTool(_server, clientFactory) {
117
104
  items: { type: 'string' },
118
105
  description: PARAM_DESCRIPTIONS.skills,
119
106
  },
107
+ plugins: {
108
+ type: 'array',
109
+ items: { type: 'string' },
110
+ description: PARAM_DESCRIPTIONS.plugins,
111
+ },
120
112
  config: {
121
113
  type: 'object',
122
114
  description: PARAM_DESCRIPTIONS.config,
@@ -141,7 +133,7 @@ export function startSessionTool(_server, clientFactory) {
141
133
  configs = await client.getConfigs();
142
134
  setConfigsCache(configs);
143
135
  }
144
- const validation = validateAgentRootConstraints(allowedRoots, configs.agent_roots, validatedArgs.git_root, validatedArgs.mcp_servers, validatedArgs.branch, validatedArgs.subdirectory);
136
+ const validation = validateAgentRootConstraints(allowedRoots, configs.agent_roots, validatedArgs.agent_root, validatedArgs.mcp_servers);
145
137
  if (!validation.valid) {
146
138
  return {
147
139
  content: [{ type: 'text', text: `Error starting session: ${validation.error}` }],
package/shared/types.d.ts CHANGED
@@ -24,6 +24,7 @@ export interface Session {
24
24
  stop_condition: string | null;
25
25
  mcp_servers: string[];
26
26
  catalog_skills?: string[];
27
+ catalog_plugins?: string[];
27
28
  config: Record<string, unknown>;
28
29
  metadata: Record<string, unknown>;
29
30
  custom_metadata: Record<string, unknown>;
@@ -145,6 +146,8 @@ export interface CreateSessionRequest {
145
146
  execution_provider?: string;
146
147
  mcp_servers?: string[];
147
148
  skills?: string[];
149
+ plugins?: string[];
150
+ agent_root?: string;
148
151
  config?: Record<string, unknown>;
149
152
  custom_metadata?: Record<string, unknown>;
150
153
  }