agent-orchestrator-mcp-server 0.2.5 → 0.3.0

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/README.md CHANGED
@@ -23,7 +23,7 @@ MCP server for PulseMCP's agent-orchestrator: a Claude Code + MCP-powered agent-
23
23
 
24
24
  | Tool | Tool Group | Read/Write | Description |
25
25
  | -------------------------- | ------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
- | `search_sessions` | sessions | read | Search/list sessions with optional ID lookup, query, and status filter |
26
+ | `quick_search_sessions` | sessions | read | Quick title-based search/list sessions with optional ID lookup, title query, and status filter |
27
27
  | `get_session` | sessions | read | Get detailed session info with optional logs, transcripts, and transcript format (text/json) |
28
28
  | `get_configs` | sessions | read | Fetch all static configuration (MCP servers, agent roots, stop conditions) |
29
29
  | `get_transcript_archive` | sessions | read | Get download URL and metadata for the transcript archive zip file |
@@ -59,7 +59,7 @@ Control which tools are available via the `TOOL_GROUPS` environment variable:
59
59
  | Group | Description |
60
60
  | ------------------------ | -------------------------------------------------------------------------------------------------------- |
61
61
  | `sessions` | All session tools (read + write): search, get, configs, transcript_archive, start, action, enqueued msgs |
62
- | `sessions_readonly` | Session tools (read only): search_sessions, get_session, get_configs, get_transcript_archive |
62
+ | `sessions_readonly` | Session tools (read only): quick_search_sessions, get_session, get_configs, get_transcript_archive |
63
63
  | `notifications` | All notification tools (read + write): get, send, mark read, dismiss |
64
64
  | `notifications_readonly` | Notification tools (read only): get_notifications |
65
65
  | `triggers` | All trigger tools (read + write): search, create, update, delete, toggle |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-orchestrator-mcp-server",
3
- "version": "0.2.5",
3
+ "version": "0.3.0",
4
4
  "description": "Local implementation of agent-orchestrator MCP server",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
@@ -36,7 +36,6 @@ export interface IAgentOrchestratorClient {
36
36
  per_page?: number;
37
37
  }): Promise<SessionsResponse>;
38
38
  searchSessions(query: string, options?: {
39
- search_contents?: boolean;
40
39
  status?: SessionStatus;
41
40
  agent_type?: string;
42
41
  show_archived?: boolean;
@@ -146,6 +145,11 @@ export declare class AgentOrchestratorClient implements IAgentOrchestratorClient
146
145
  private timeoutMs;
147
146
  constructor(baseUrl: string, apiKey: string, timeoutMs?: number);
148
147
  private request;
148
+ /**
149
+ * Like request(), but reads the response as text and wraps it in a TranscriptResponse.
150
+ * Used for API endpoints that return raw text instead of JSON (e.g., transcript with format=text).
151
+ */
152
+ private requestText;
149
153
  listSessions(options?: {
150
154
  status?: SessionStatus;
151
155
  agent_type?: string;
@@ -154,7 +158,6 @@ export declare class AgentOrchestratorClient implements IAgentOrchestratorClient
154
158
  per_page?: number;
155
159
  }): Promise<SessionsResponse>;
156
160
  searchSessions(query: string, options?: {
157
- search_contents?: boolean;
158
161
  status?: SessionStatus;
159
162
  agent_type?: string;
160
163
  show_archived?: boolean;
@@ -111,7 +111,6 @@ export function createIntegrationMockOrchestratorClient(initialMockData) {
111
111
  const paginatedSessions = sessions.slice(start, start + perPage);
112
112
  return {
113
113
  query,
114
- search_contents: options?.search_contents || false,
115
114
  sessions: paginatedSessions,
116
115
  pagination: {
117
116
  page,
@@ -98,6 +98,67 @@ export class AgentOrchestratorClient {
98
98
  }
99
99
  return response.json();
100
100
  }
101
+ /**
102
+ * Like request(), but reads the response as text and wraps it in a TranscriptResponse.
103
+ * Used for API endpoints that return raw text instead of JSON (e.g., transcript with format=text).
104
+ */
105
+ async requestText(method, path, body, queryParams) {
106
+ const url = new URL(`${this.baseUrl}${path}`);
107
+ if (queryParams) {
108
+ Object.entries(queryParams).forEach(([key, value]) => {
109
+ if (value !== undefined && value !== null) {
110
+ url.searchParams.append(key, String(value));
111
+ }
112
+ });
113
+ }
114
+ const headers = {
115
+ Authorization: `Bearer ${this.apiKey}`,
116
+ };
117
+ if (body) {
118
+ headers['Content-Type'] = 'application/json';
119
+ }
120
+ const controller = new AbortController();
121
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
122
+ const options = {
123
+ method,
124
+ headers,
125
+ signal: controller.signal,
126
+ };
127
+ if (body && (method === 'POST' || method === 'PATCH' || method === 'PUT')) {
128
+ options.body = JSON.stringify(body);
129
+ }
130
+ let response;
131
+ try {
132
+ response = await fetch(url.toString(), options);
133
+ }
134
+ catch (error) {
135
+ clearTimeout(timeoutId);
136
+ if (error instanceof Error && error.name === 'AbortError') {
137
+ throw new Error(`Request timeout after ${this.timeoutMs}ms`);
138
+ }
139
+ throw error;
140
+ }
141
+ finally {
142
+ clearTimeout(timeoutId);
143
+ }
144
+ if (!response.ok) {
145
+ const errorText = await response.text();
146
+ let errorMessage;
147
+ try {
148
+ const errorJson = JSON.parse(errorText);
149
+ errorMessage = errorJson.message || errorJson.error || errorText;
150
+ }
151
+ catch {
152
+ errorMessage = errorText;
153
+ }
154
+ throw new Error(`API Error (${response.status}): ${errorMessage}`);
155
+ }
156
+ if (response.status === 204) {
157
+ return { transcript_text: '' };
158
+ }
159
+ const text = await response.text();
160
+ return { transcript_text: text };
161
+ }
101
162
  // Sessions
102
163
  async listSessions(options) {
103
164
  return this.request('GET', '/sessions', undefined, options);
@@ -234,6 +295,11 @@ export class AgentOrchestratorClient {
234
295
  });
235
296
  }
236
297
  async getTranscript(id, format = 'json') {
298
+ if (format === 'text') {
299
+ // The API returns raw text (not JSON) when format=text,
300
+ // so we must use response.text() instead of response.json()
301
+ return this.requestText('GET', `/sessions/${id}/transcript`, undefined, { format });
302
+ }
237
303
  return this.request('GET', `/sessions/${id}/transcript`, undefined, {
238
304
  format,
239
305
  });
@@ -67,7 +67,7 @@ export function createRegisterResources(clientFactory) {
67
67
  },
68
68
  toolGroups: {
69
69
  sessions: 'All session tools (read + write): search, get, configs, start, action, enqueued messages',
70
- sessions_readonly: 'Session tools (read only): search_sessions, get_session, get_configs',
70
+ sessions_readonly: 'Session tools (read only): quick_search_sessions, get_session, get_configs',
71
71
  notifications: 'All notification tools (read + write): get, send, mark read, dismiss',
72
72
  notifications_readonly: 'Notification tools (read only): get_notifications',
73
73
  triggers: 'All trigger tools (read + write): search, create, update, delete, toggle',
@@ -1,10 +1,9 @@
1
1
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { z } from 'zod';
3
3
  import type { IAgentOrchestratorClient } from '../orchestrator-client/orchestrator-client.js';
4
- export declare const SearchSessionsSchema: z.ZodObject<{
4
+ export declare const QuickSearchSessionsSchema: z.ZodObject<{
5
5
  id: z.ZodOptional<z.ZodNumber>;
6
6
  query: z.ZodOptional<z.ZodString>;
7
- search_contents: z.ZodOptional<z.ZodBoolean>;
8
7
  status: z.ZodOptional<z.ZodEnum<["waiting", "running", "needs_input", "failed", "archived"]>>;
9
8
  agent_type: z.ZodOptional<z.ZodString>;
10
9
  show_archived: z.ZodOptional<z.ZodBoolean>;
@@ -16,7 +15,6 @@ export declare const SearchSessionsSchema: z.ZodObject<{
16
15
  agent_type?: string | undefined;
17
16
  show_archived?: boolean | undefined;
18
17
  page?: number | undefined;
19
- search_contents?: boolean | undefined;
20
18
  id?: number | undefined;
21
19
  query?: string | undefined;
22
20
  }, {
@@ -25,11 +23,10 @@ export declare const SearchSessionsSchema: z.ZodObject<{
25
23
  agent_type?: string | undefined;
26
24
  show_archived?: boolean | undefined;
27
25
  page?: number | undefined;
28
- search_contents?: boolean | undefined;
29
26
  id?: number | undefined;
30
27
  query?: string | undefined;
31
28
  }>;
32
- export declare function searchSessionsTool(_server: Server, clientFactory: () => IAgentOrchestratorClient): {
29
+ export declare function quickSearchSessionsTool(_server: Server, clientFactory: () => IAgentOrchestratorClient): {
33
30
  name: string;
34
31
  description: string;
35
32
  inputSchema: {
@@ -42,11 +39,7 @@ export declare function searchSessionsTool(_server: Server, clientFactory: () =>
42
39
  query: {
43
40
  type: string;
44
41
  maxLength: number;
45
- description: "Search query to find sessions. Searches across title, metadata, and custom_metadata. Leave empty to list all sessions.";
46
- };
47
- search_contents: {
48
- type: string;
49
- description: "Also search within transcript contents. May be slow for sessions with large transcripts. Default: false";
42
+ description: "Search query to find sessions. Matches against session title only — this is a simple title search, not a full-text or semantic search. Leave empty to list all sessions.";
50
43
  };
51
44
  status: {
52
45
  type: string;
@@ -1,18 +1,16 @@
1
1
  import { z } from 'zod';
2
2
  const PARAM_DESCRIPTIONS = {
3
3
  id: 'Get a specific session by ID. When provided, other filters are ignored.',
4
- query: 'Search query to find sessions. Searches across title, metadata, and custom_metadata. Leave empty to list all sessions.',
5
- search_contents: 'Also search within transcript contents. May be slow for sessions with large transcripts. Default: false',
4
+ query: 'Search query to find sessions. Matches against session title only — this is a simple title search, not a full-text or semantic search. Leave empty to list all sessions.',
6
5
  status: 'Filter results by status. Options: "waiting", "running", "needs_input", "failed", "archived"',
7
6
  agent_type: 'Filter results by agent type.',
8
7
  show_archived: 'Include archived sessions in results. Default: false',
9
8
  page: 'Page number for pagination. Default: 1',
10
9
  per_page: 'Number of results per page (1-100). Default: 25',
11
10
  };
12
- export const SearchSessionsSchema = z.object({
11
+ export const QuickSearchSessionsSchema = z.object({
13
12
  id: z.number().optional().describe(PARAM_DESCRIPTIONS.id),
14
13
  query: z.string().max(1000).optional().describe(PARAM_DESCRIPTIONS.query),
15
- search_contents: z.boolean().optional().describe(PARAM_DESCRIPTIONS.search_contents),
16
14
  status: z
17
15
  .enum(['waiting', 'running', 'needs_input', 'failed', 'archived'])
18
16
  .optional()
@@ -22,11 +20,13 @@ export const SearchSessionsSchema = z.object({
22
20
  page: z.number().min(1).optional().describe(PARAM_DESCRIPTIONS.page),
23
21
  per_page: z.number().min(1).max(100).optional().describe(PARAM_DESCRIPTIONS.per_page),
24
22
  });
25
- const TOOL_DESCRIPTION = `Search for agent sessions in the Agent Orchestrator.
23
+ const TOOL_DESCRIPTION = `Quick title-based search for agent sessions in the Agent Orchestrator.
24
+
25
+ **Important:** This tool only searches session titles. It is NOT a full-text or semantic search across session contents/transcripts. Use this when you roughly know the session title you're looking for.
26
26
 
27
27
  **Use cases:**
28
28
  - Find a specific session by ID (set id parameter)
29
- - Search sessions by keyword in title/prompt (set query parameter)
29
+ - Search sessions by title keyword (set query parameter)
30
30
  - List all sessions with optional status filter
31
31
  - Monitor sessions requiring attention (status: "needs_input")
32
32
 
@@ -66,9 +66,9 @@ function formatSession(session) {
66
66
  lines.push(`- **Updated:** ${session.updated_at}`);
67
67
  return lines.join('\n');
68
68
  }
69
- export function searchSessionsTool(_server, clientFactory) {
69
+ export function quickSearchSessionsTool(_server, clientFactory) {
70
70
  return {
71
- name: 'search_sessions',
71
+ name: 'quick_search_sessions',
72
72
  description: TOOL_DESCRIPTION,
73
73
  inputSchema: {
74
74
  type: 'object',
@@ -82,10 +82,6 @@ export function searchSessionsTool(_server, clientFactory) {
82
82
  maxLength: 1000,
83
83
  description: PARAM_DESCRIPTIONS.query,
84
84
  },
85
- search_contents: {
86
- type: 'boolean',
87
- description: PARAM_DESCRIPTIONS.search_contents,
88
- },
89
85
  status: {
90
86
  type: 'string',
91
87
  enum: ['waiting', 'running', 'needs_input', 'failed', 'archived'],
@@ -115,7 +111,7 @@ export function searchSessionsTool(_server, clientFactory) {
115
111
  },
116
112
  handler: async (args) => {
117
113
  try {
118
- const validatedArgs = SearchSessionsSchema.parse(args);
114
+ const validatedArgs = QuickSearchSessionsSchema.parse(args);
119
115
  const client = clientFactory();
120
116
  // If ID is provided, get that specific session
121
117
  if (validatedArgs.id !== undefined) {
@@ -133,9 +129,8 @@ export function searchSessionsTool(_server, clientFactory) {
133
129
  let sessions;
134
130
  let pagination;
135
131
  if (validatedArgs.query) {
136
- // Use search endpoint
132
+ // Use search endpoint (title-only search, no content search)
137
133
  const response = await client.searchSessions(validatedArgs.query, {
138
- search_contents: validatedArgs.search_contents,
139
134
  status: validatedArgs.status,
140
135
  agent_type: validatedArgs.agent_type,
141
136
  show_archived: validatedArgs.show_archived,
package/shared/tools.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
2
2
  // 13 tools across 4 domains
3
- import { searchSessionsTool } from './tools/search-sessions.js';
3
+ import { quickSearchSessionsTool } from './tools/search-sessions.js';
4
4
  import { startSessionTool } from './tools/start-session.js';
5
5
  import { getSessionTool } from './tools/get-session.js';
6
6
  import { actionSessionTool } from './tools/action-session.js';
@@ -59,7 +59,7 @@ export function parseEnabledToolGroups(enabledGroupsParam) {
59
59
  * All available tools with their group assignments.
60
60
  *
61
61
  * 14 tools across 4 domains:
62
- * - search_sessions: Search/list/get sessions by ID (sessions, read)
62
+ * - quick_search_sessions: Quick title-based search/list/get sessions by ID (sessions, read)
63
63
  * - get_session: Get detailed session info with optional logs/transcripts (sessions, read)
64
64
  * - get_configs: Fetch all static configuration (sessions, read)
65
65
  * - get_transcript_archive: Get transcript archive download URL and metadata (sessions, read)
@@ -76,7 +76,7 @@ export function parseEnabledToolGroups(enabledGroupsParam) {
76
76
  */
77
77
  const ALL_TOOLS = [
78
78
  // Session tools - read operations
79
- { factory: searchSessionsTool, group: 'sessions', isWriteOperation: false },
79
+ { factory: quickSearchSessionsTool, group: 'sessions', isWriteOperation: false },
80
80
  { factory: getSessionTool, group: 'sessions', isWriteOperation: false },
81
81
  { factory: getConfigsTool, group: 'sessions', isWriteOperation: false },
82
82
  { factory: getTranscriptArchiveTool, group: 'sessions', isWriteOperation: false },
package/shared/types.d.ts CHANGED
@@ -68,7 +68,6 @@ export interface SessionsResponse {
68
68
  }
69
69
  export interface SearchSessionsResponse {
70
70
  query: string;
71
- search_contents: boolean;
72
71
  sessions: Session[];
73
72
  pagination: Pagination;
74
73
  }