@utaba/ucm-mcp-server 6.1.0 → 6.2.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.
@@ -119,7 +119,7 @@ export declare class UcmLocalApiClient {
119
119
  * Returns connection details, auth status, and available tool schemas
120
120
  * Connection type is auto-detected by the server from the connectionId
121
121
  */
122
- accessConnection(connectionId: string): Promise<{
122
+ accessConnection(connectionId: string, toolNames?: string[]): Promise<{
123
123
  success: boolean;
124
124
  connectionId: string;
125
125
  connectionType: 'sharepoint' | 'remote-mcp';
@@ -127,20 +127,29 @@ export declare class UcmLocalApiClient {
127
127
  isAuthenticated: boolean;
128
128
  authRequired?: boolean;
129
129
  loginUrl?: string;
130
+ loginMessage?: string;
130
131
  tools?: any[];
131
- schema: string;
132
+ markdown?: string;
133
+ instructions?: string;
134
+ policies?: string[];
132
135
  }>;
133
136
  /**
134
137
  * Call a tool on an external connection
135
138
  * Executes a tool on a SharePoint connection or Remote MCP Server
136
139
  * Connection type is auto-detected by the server from the connectionId
137
140
  */
138
- callRemoteTool(connectionId: string, toolName: string, args?: Record<string, any>): Promise<{
141
+ callRemoteTool(connectionId: string, toolName: string, args?: any): Promise<{
139
142
  success: boolean;
140
143
  connectionId: string;
141
144
  connectionType: 'sharepoint' | 'remote-mcp';
142
145
  toolName: string;
143
- result?: any;
146
+ content?: Array<{
147
+ type: string;
148
+ text?: string;
149
+ data?: string;
150
+ mimeType?: string;
151
+ uri?: string;
152
+ }>;
144
153
  error?: string;
145
154
  errorCode?: string;
146
155
  authRequired?: boolean;
@@ -378,9 +378,13 @@ export class UcmLocalApiClient {
378
378
  * Returns connection details, auth status, and available tool schemas
379
379
  * Connection type is auto-detected by the server from the connectionId
380
380
  */
381
- async accessConnection(connectionId) {
381
+ async accessConnection(connectionId, toolNames) {
382
382
  const client = this.ensureClient();
383
- const response = await client.get(`/api/v1/connections/${connectionId}`);
383
+ const params = {};
384
+ if (toolNames && toolNames.length > 0) {
385
+ params.toolNames = toolNames.join(',');
386
+ }
387
+ const response = await client.get(`/api/v1/connections/${connectionId}`, { params });
384
388
  return response.data;
385
389
  }
386
390
  /**
@@ -390,10 +394,10 @@ export class UcmLocalApiClient {
390
394
  */
391
395
  async callRemoteTool(connectionId, toolName, args) {
392
396
  const client = this.ensureClient();
393
- const body = {
394
- toolName,
395
- args: args || {}
396
- };
397
+ const body = { toolName };
398
+ if (args !== undefined) {
399
+ body.args = args;
400
+ }
397
401
  const response = await client.post(`/api/v1/connections/${connectionId}/tools`, body);
398
402
  return response.data;
399
403
  }
@@ -39,6 +39,10 @@ export class McpHandler {
39
39
  }
40
40
  const result = await this.toolRegistry.executeTool(name, args || {});
41
41
  this.logger.info('MCP-Handler', `Tool ${name} executed successfully`);
42
+ // If the tool returned a pre-formatted MCP response (with content array), pass through
43
+ if (result && typeof result === 'object' && Array.isArray(result.content)) {
44
+ return result;
45
+ }
42
46
  // Handle string results directly (e.g., markdown content)
43
47
  if (typeof result === 'string') {
44
48
  return {
@@ -15,6 +15,7 @@ export declare class AccessConnectionTool extends BaseToolController {
15
15
  protected validateParams(params: any): void;
16
16
  protected handleExecute(params: {
17
17
  connectionId: string;
18
+ toolNames?: string[];
18
19
  }): Promise<any>;
19
20
  }
20
21
  //# sourceMappingURL=AccessConnectionTool.d.ts.map
@@ -25,6 +25,11 @@ export class AccessConnectionTool extends BaseToolController {
25
25
  description: 'Connection ID (SharePoint connection or Remote MCP Server) from ucm_list_connections',
26
26
  minLength: 36,
27
27
  maxLength: 36
28
+ },
29
+ toolNames: {
30
+ type: 'array',
31
+ items: { type: 'string' },
32
+ description: 'Optional list of tool names to get full parameter schemas for. If omitted, returns a summary index of all available tools. Pass in all tool names that could likely be relevant.'
28
33
  }
29
34
  },
30
35
  required: ['connectionId']
@@ -43,15 +48,32 @@ export class AccessConnectionTool extends BaseToolController {
43
48
  async handleExecute(params) {
44
49
  this.logger.info('AccessConnectionTool', `Accessing connection: ${params.connectionId}`);
45
50
  try {
46
- const result = await this.ucmClient.accessConnection(params.connectionId);
51
+ const result = await this.ucmClient.accessConnection(params.connectionId, params.toolNames);
47
52
  this.logger.info('AccessConnectionTool', 'Connection accessed successfully', '', {
48
53
  connectionId: params.connectionId,
49
54
  connectionType: result.connectionType,
50
55
  isAuthenticated: result.isAuthenticated,
51
56
  toolCount: result.tools?.length || 0
52
57
  });
53
- // Return the schema (JSON envelope with modelInstructions, policies, tools) for AI consumption
54
- return result.schema;
58
+ // Auth required return login message
59
+ if (!result.isAuthenticated) {
60
+ if (result.authRequired && result.loginUrl) {
61
+ return `Authentication required for "${result.connectionName}". Login URL: ${result.loginUrl}`;
62
+ }
63
+ return `Connection "${result.connectionName}" is not accessible: ${result.loginMessage || 'Authentication failed'}`;
64
+ }
65
+ // If markdown index returned (no toolNames requested), return markdown
66
+ if (result.markdown) {
67
+ return result.markdown;
68
+ }
69
+ // toolNames mode — return compact JSON with filtered tools
70
+ return JSON.stringify({
71
+ connectionId: result.connectionId,
72
+ connectionName: result.connectionName,
73
+ instructions: result.instructions,
74
+ policies: result.policies,
75
+ tools: result.tools
76
+ });
55
77
  }
56
78
  catch (error) {
57
79
  // Sanitize error for logging
@@ -16,7 +16,7 @@ export declare class CallRemoteToolTool extends BaseToolController {
16
16
  protected handleExecute(params: {
17
17
  connectionId: string;
18
18
  toolName: string;
19
- args?: Record<string, any>;
19
+ args?: any;
20
20
  }): Promise<any>;
21
21
  }
22
22
  //# sourceMappingURL=CallRemoteToolTool.d.ts.map
@@ -33,7 +33,8 @@ export class CallRemoteToolTool extends BaseToolController {
33
33
  },
34
34
  args: {
35
35
  type: 'object',
36
- description: 'Tool arguments object (see ucm_access_connection for parameter schemas)'
36
+ description: 'Tool arguments passed through to the remote tool as-is',
37
+ additionalProperties: true
37
38
  }
38
39
  },
39
40
  required: ['connectionId', 'toolName']
@@ -52,23 +53,27 @@ export class CallRemoteToolTool extends BaseToolController {
52
53
  if (!params.toolName || typeof params.toolName !== 'string') {
53
54
  throw new McpError(McpErrorCode.InvalidParams, 'toolName is required and must be a string');
54
55
  }
55
- // Validate args if provided — must be an object, not a string
56
- if (params.args !== undefined && (typeof params.args !== 'object' || params.args === null)) {
57
- throw new McpError(McpErrorCode.InvalidParams, 'args must be an object');
58
- }
59
56
  }
60
57
  async handleExecute(params) {
58
+ // MCP transport may serialize nested objects as strings — parse if needed
59
+ const args = typeof params.args === 'string'
60
+ ? JSON.parse(params.args)
61
+ : params.args;
61
62
  this.logger.info('CallRemoteToolTool', `Calling tool ${params.toolName} on connection: ${params.connectionId}`);
62
63
  try {
63
- const result = await this.ucmClient.callRemoteTool(params.connectionId, params.toolName, params.args);
64
+ const result = await this.ucmClient.callRemoteTool(params.connectionId, params.toolName, args);
64
65
  this.logger.info('CallRemoteToolTool', 'Tool executed successfully', '', {
65
66
  connectionId: params.connectionId,
66
67
  toolName: params.toolName,
67
68
  success: result.success,
68
69
  authRequired: result.authRequired || false
69
70
  });
70
- // Return the markdown content for AI consumption
71
- return result.markdown;
71
+ // Clean proxy: pass through content blocks directly
72
+ if (!result.success) {
73
+ return result.error || result.markdown || 'Tool execution failed';
74
+ }
75
+ // Return as pre-formatted MCP response — McpHandler will pass through
76
+ return { content: result.content };
72
77
  }
73
78
  catch (error) {
74
79
  // Sanitize error for logging
@@ -1,6 +1,6 @@
1
1
  import { BaseToolController } from '../base/BaseToolController.js';
2
2
  //import packageJson from '../../../../publish/package.json' assert { type: 'json' };
3
- const version = '6.0.0'; //TODO: tried to sync this with packageJson but it didn't work.
3
+ const version = '6.2.0'; //TODO: tried to sync this with packageJson but it didn't work.
4
4
  export class HealthCheckController extends BaseToolController {
5
5
  constructor(ucmClient, logger, publishingAuthorId) {
6
6
  super(ucmClient, logger, publishingAuthorId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utaba/ucm-mcp-server",
3
- "version": "6.1.0",
3
+ "version": "6.2.0",
4
4
  "description": "Universal Context Manager MCP Server - AI Productivity Platform",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ucm-mcp-server",
3
- "version": "6.1.0",
3
+ "version": "6.2.0",
4
4
  "description": "Universal Context Manager MCP Server - AI Productivity Platform",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",