UIFlowchartCreator
by umshere
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { AxiosInstance } from 'axios';
import {
ToolCallResponse,
ToolDefinition,
ToolHandler,
} from '../../../types/index.js';
import { BasePostmanTool } from '../base.js';
import { TOOL_DEFINITIONS } from './definitions.js';
/**
* Implements Postman API endpoints for managing APIs, schemas, versions, comments, and tags
* All API operations require the v10 Accept header
*/
export class ApiTools extends BasePostmanTool implements ToolHandler {
constructor(existingClient: AxiosInstance) {
super(null, {
acceptHeader: 'application/vnd.api.v10+json'
}, existingClient);
}
getToolDefinitions(): ToolDefinition[] {
return TOOL_DEFINITIONS;
}
private createResponse(data: any): ToolCallResponse {
return {
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }]
};
}
/**
* Handles tool calls for API-related operations
* @throws {McpError} With appropriate error code and message
*/
async handleToolCall(name: string, args: any): Promise<ToolCallResponse> {
try {
switch (name) {
case 'list_apis':
return await this.listApis(args);
case 'get_api':
return await this.getApi(args);
case 'create_api':
return await this.createApi(args);
case 'update_api':
return await this.updateApi(args);
case 'delete_api':
return await this.deleteApi(args.apiId);
case 'add_api_collection':
return await this.addApiCollection(args);
case 'get_api_collection':
return await this.getApiCollection(args);
case 'create_api_schema':
return await this.createApiSchema(args);
case 'get_api_schema':
return await this.getApiSchema(args);
case 'create_api_version':
return await this.createApiVersion(args);
case 'get_api_versions':
return await this.getApiVersions(args);
case 'get_api_version':
return await this.getApiVersion(args);
case 'update_api_version':
return await this.updateApiVersion(args);
case 'delete_api_version':
return await this.deleteApiVersion(args);
case 'get_api_comments':
return await this.getApiComments(args);
case 'create_api_comment':
return await this.createApiComment(args);
case 'update_api_comment':
return await this.updateApiComment(args);
case 'delete_api_comment':
return await this.deleteApiComment(args);
case 'get_api_tags':
return await this.getApiTags(args.apiId);
case 'update_api_tags':
return await this.updateApiTags(args);
case 'get_api_schema_files':
return await this.getApiSchemaFiles(args);
case 'get_schema_file_contents':
return await this.getSchemaFileContents(args);
case 'create_update_schema_file':
return await this.createUpdateSchemaFile(args);
case 'delete_schema_file':
return await this.deleteSchemaFile(args);
case 'sync_collection_with_schema':
return await this.syncCollectionWithSchema(args);
case 'get_task_status':
return await this.getTaskStatus(args);
default:
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
}
} catch (error) {
// Let base class interceptor handle API errors
throw error;
}
}
/**
* List all APIs in a workspace
* @param params Query parameters including workspaceId (required)
*/
async listApis(params: any): Promise<ToolCallResponse> {
if (!params.workspaceId) {
throw new McpError(ErrorCode.InvalidParams, 'workspaceId is required');
}
const response = await this.client.get('/apis', { params });
return this.createResponse(response.data);
}
/**
* Get details of a specific API
* @param params Parameters including apiId (required)
*/
async getApi(params: any): Promise<ToolCallResponse> {
if (!params.apiId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId is required');
}
const response = await this.client.get(`/apis/${params.apiId}`, {
params: { include: params.include?.join(',') }
});
return this.createResponse(response.data);
}
/**
* Create a new API
* @param data API data including name (required), workspaceId (required)
*/
async createApi(data: any): Promise<ToolCallResponse> {
if (!data.name || !data.workspaceId) {
throw new McpError(ErrorCode.InvalidParams, 'name and workspaceId are required');
}
const response = await this.client.post('/apis', data);
return this.createResponse(response.data);
}
/**
* Update an existing API
* @param args Parameters including apiId (required)
*/
async updateApi(args: any): Promise<ToolCallResponse> {
if (!args.apiId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId is required');
}
const { apiId, ...data } = args;
const response = await this.client.put(`/apis/${apiId}`, data);
return this.createResponse(response.data);
}
/**
* Delete an API
* @param apiId The ID of the API to delete (required)
*/
async deleteApi(apiId: string): Promise<ToolCallResponse> {
if (!apiId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId is required');
}
await this.client.delete(`/apis/${apiId}`);
return this.createResponse({ message: 'API deleted successfully' });
}
/**
* Add a collection to an API
* @param args Parameters including apiId (required), operationType (required)
*/
async addApiCollection(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.operationType) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and operationType are required');
}
const { apiId, ...data } = args;
const response = await this.client.post(`/apis/${apiId}/collections`, data);
return this.createResponse(response.data);
}
/**
* Get a specific collection from an API
* @param args Parameters including apiId (required), collectionId (required)
*/
async getApiCollection(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.collectionId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and collectionId are required');
}
const { apiId, collectionId, ...params } = args;
const response = await this.client.get(`/apis/${apiId}/collections/${collectionId}`, { params });
return this.createResponse(response.data);
}
/**
* Create a schema for an API
* @param args Parameters including apiId (required), type (required), files (required)
*/
async createApiSchema(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.type || !args.files) {
throw new McpError(ErrorCode.InvalidParams, 'apiId, type, and files are required');
}
const { apiId, ...data } = args;
const response = await this.client.post(`/apis/${apiId}/schemas`, data);
return this.createResponse(response.data);
}
/**
* Get a specific schema from an API
* @param args Parameters including apiId (required), schemaId (required)
*/
async getApiSchema(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.schemaId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and schemaId are required');
}
const { apiId, schemaId, ...params } = args;
const response = await this.client.get(`/apis/${apiId}/schemas/${schemaId}`, { params });
return this.createResponse(response.data);
}
/**
* Create a new version of an API
* @param args Parameters including apiId (required), name (required), schemas (required), collections (required)
*/
async createApiVersion(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.name || !args.schemas || !args.collections) {
throw new McpError(ErrorCode.InvalidParams, 'apiId, name, schemas, and collections are required');
}
const { apiId, ...data } = args;
const response = await this.client.post(`/apis/${apiId}/versions`, data);
return this.createResponse(response.data);
}
/**
* Get all versions of an API
* @param args Parameters including apiId (required)
*/
async getApiVersions(args: any): Promise<ToolCallResponse> {
if (!args.apiId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId is required');
}
const { apiId, ...params } = args;
const response = await this.client.get(`/apis/${apiId}/versions`, { params });
return this.createResponse(response.data);
}
/**
* Get a specific version of an API
* @param args Parameters including apiId (required), versionId (required)
*/
async getApiVersion(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.versionId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and versionId are required');
}
const response = await this.client.get(`/apis/${args.apiId}/versions/${args.versionId}`);
return this.createResponse(response.data);
}
/**
* Update an API version
* @param args Parameters including apiId (required), versionId (required), name (required)
*/
async updateApiVersion(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.versionId || !args.name) {
throw new McpError(ErrorCode.InvalidParams, 'apiId, versionId, and name are required');
}
const { apiId, versionId, ...data } = args;
const response = await this.client.put(`/apis/${apiId}/versions/${versionId}`, data);
return this.createResponse(response.data);
}
/**
* Delete an API version
* @param args Parameters including apiId (required), versionId (required)
*/
async deleteApiVersion(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.versionId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and versionId are required');
}
await this.client.delete(`/apis/${args.apiId}/versions/${args.versionId}`);
return this.createResponse({ message: 'API version deleted successfully' });
}
/**
* Get comments for an API
* @param args Parameters including apiId (required)
*/
async getApiComments(args: any): Promise<ToolCallResponse> {
if (!args.apiId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId is required');
}
const { apiId, ...params } = args;
const response = await this.client.get(`/apis/${apiId}/comments`, { params });
return this.createResponse(response.data);
}
/**
* Create a new comment on an API
* @param args Parameters including apiId (required), content (required)
*/
async createApiComment(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.content) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and content are required');
}
const { apiId, ...data } = args;
const response = await this.client.post(`/apis/${apiId}/comments`, data);
return this.createResponse(response.data);
}
/**
* Update an existing API comment
* @param args Parameters including apiId (required), commentId (required), content (required)
*/
async updateApiComment(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.commentId || !args.content) {
throw new McpError(ErrorCode.InvalidParams, 'apiId, commentId, and content are required');
}
const response = await this.client.put(
`/apis/${args.apiId}/comments/${args.commentId}`,
{ content: args.content }
);
return this.createResponse(response.data);
}
/**
* Delete an API comment
* @param args Parameters including apiId (required), commentId (required)
*/
async deleteApiComment(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.commentId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and commentId are required');
}
await this.client.delete(`/apis/${args.apiId}/comments/${args.commentId}`);
return this.createResponse({ message: 'Comment deleted successfully' });
}
/**
* Get tags for an API
* @param apiId The ID of the API (required)
*/
async getApiTags(apiId: string): Promise<ToolCallResponse> {
if (!apiId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId is required');
}
const response = await this.client.get(`/apis/${apiId}/tags`);
return this.createResponse(response.data);
}
/**
* Update tags for an API
* @param args Parameters including apiId (required), tags (required)
*/
async updateApiTags(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.tags) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and tags are required');
}
const response = await this.client.put(
`/apis/${args.apiId}/tags`,
{ tags: args.tags }
);
return this.createResponse(response.data);
}
/**
* Get files in an API schema
* @param args Parameters including apiId (required), schemaId (required)
*/
async getApiSchemaFiles(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.schemaId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and schemaId are required');
}
const { apiId, schemaId, ...params } = args;
const response = await this.client.get(`/apis/${apiId}/schemas/${schemaId}/files`, { params });
return this.createResponse(response.data);
}
/**
* Get contents of a schema file
* @param args Parameters including apiId (required), schemaId (required), filePath (required)
*/
async getSchemaFileContents(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.schemaId || !args.filePath) {
throw new McpError(ErrorCode.InvalidParams, 'apiId, schemaId, and filePath are required');
}
const { apiId, schemaId, filePath, versionId } = args;
const response = await this.client.get(
`/apis/${apiId}/schemas/${schemaId}/files/${filePath}`,
{ params: { versionId } }
);
return this.createResponse(response.data);
}
/**
* Create or update a schema file
* @param args Parameters including apiId (required), schemaId (required), filePath (required), content (required)
*/
async createUpdateSchemaFile(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.schemaId || !args.filePath || !args.content) {
throw new McpError(ErrorCode.InvalidParams, 'apiId, schemaId, filePath, and content are required');
}
const { apiId, schemaId, filePath, ...data } = args;
const response = await this.client.put(
`/apis/${apiId}/schemas/${schemaId}/files/${filePath}`,
data
);
return this.createResponse(response.data);
}
/**
* Delete a schema file
* @param args Parameters including apiId (required), schemaId (required), filePath (required)
*/
async deleteSchemaFile(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.schemaId || !args.filePath) {
throw new McpError(ErrorCode.InvalidParams, 'apiId, schemaId, and filePath are required');
}
await this.client.delete(
`/apis/${args.apiId}/schemas/${args.schemaId}/files/${args.filePath}`
);
return this.createResponse({ message: 'Schema file deleted successfully' });
}
/**
* Sync a collection with its schema
* @param args Parameters including apiId (required), collectionId (required)
*/
async syncCollectionWithSchema(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.collectionId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and collectionId are required');
}
const response = await this.client.put(
`/apis/${args.apiId}/collections/${args.collectionId}/sync-with-schema-tasks`,
{}
);
return this.createResponse(response.data);
}
/**
* Get status of an asynchronous task
* @param args Parameters including apiId (required), taskId (required)
*/
async getTaskStatus(args: any): Promise<ToolCallResponse> {
if (!args.apiId || !args.taskId) {
throw new McpError(ErrorCode.InvalidParams, 'apiId and taskId are required');
}
const response = await this.client.get(`/apis/${args.apiId}/tasks/${args.taskId}`);
return this.createResponse(response.data);
}
}