@promptlayer/mcp-server 1.10.0 → 1.11.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/src/types.ts CHANGED
@@ -617,24 +617,129 @@ export const ResolveFolderIdArgsSchema = z.object({
617
617
  });
618
618
 
619
619
 
620
- // ── Search Request Logs (POST /api/public/v2/requests/search) ────────────
621
- // (StructuredFilter / StructuredFilterGroup are defined higher up so the
622
- // dataset-from-filter-params endpoint can reuse them.)
620
+ // ── Skill Collections ────────────────────────────────────────────────────
621
+ // Public API endpoints under /api/public/v2/skill-collections.
622
+ // MCP supports JSON bodies only (multipart/form-data with ZIP archive uploads
623
+ // is intentionally not exposed — agents should send file contents inline).
623
624
 
624
- export const SearchRequestLogsArgsSchema = z.object({
625
+ export const ListSkillCollectionsArgsSchema = z.object({
626
+ api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
627
+ });
628
+
629
+ const SkillCollectionFileSchema = z.object({
630
+ path: z.string().describe("Relative file path inside the collection (e.g. 'README.md', 'src/util.ts')"),
631
+ content: z.string().optional().describe("File contents as a string. Defaults to empty string if omitted."),
632
+ });
633
+
634
+ export const CreateSkillCollectionArgsSchema = z.object({
635
+ name: z.string().describe("Collection name. Must be a valid root folder name (will be made unique within the workspace)."),
636
+ description: z.string().optional().describe("Optional human-readable description"),
637
+ folder_id: z.number().int().optional().describe("Folder ID to place the collection into"),
638
+ provider: z.string().optional().describe("Provider hint (e.g. 'claude', 'cursor'). Auto-detected from file paths if omitted."),
639
+ files: z.array(SkillCollectionFileSchema).optional().describe("Initial files for the collection. Each item is {path, content}."),
640
+ commit_message: z.string().optional().describe("Commit message for the initial version"),
641
+ api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
642
+ });
643
+
644
+ export const GetSkillCollectionArgsSchema = z.object({
645
+ identifier: z.string().describe("Skill collection UUID, name, or root_path"),
646
+ label: z.string().optional().describe("Release label to pin the version (mutually exclusive with version)"),
647
+ version: z.number().int().min(1).optional().describe("Version number to pin (mutually exclusive with label)"),
648
+ api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
649
+ });
650
+
651
+ export const UpdateSkillCollectionArgsSchema = z.object({
652
+ identifier: z.string().describe("Skill collection UUID, name, or root_path"),
653
+ name: z.string().optional().describe("New collection name (will be made unique within the workspace if it collides)"),
654
+ description: z.string().optional().describe("New description. Pass empty string to clear."),
655
+ api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
656
+ });
657
+
658
+ const SkillCollectionFileMoveSchema = z.object({
659
+ old_path: z.string().describe("Existing relative path"),
660
+ new_path: z.string().describe("New relative path"),
661
+ });
662
+
663
+ export const SaveSkillCollectionVersionArgsSchema = z.object({
664
+ identifier: z.string().describe("Skill collection UUID, name, or root_path"),
665
+ file_updates: z.array(SkillCollectionFileSchema).optional().describe("Files to add or overwrite. Each item is {path, content}. Files not mentioned are carried forward from the previous version."),
666
+ moves: z.array(SkillCollectionFileMoveSchema).optional().describe("Files to rename: [{old_path, new_path}, ...]"),
667
+ deletes: z.array(z.string()).optional().describe("Relative paths of files to delete from the new version"),
668
+ commit_message: z.string().optional().describe("Commit message describing what changed"),
669
+ release_label: z.string().optional().describe("Release label to attach to the new version (e.g. 'production')"),
670
+ api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
671
+ });
672
+
673
+
674
+ // ── Patch Prompt Template Version (PATCH /rest/prompt-templates/{identifier}) ──
675
+ // Partial update: fetches the base version, applies field-level patches, creates a new version.
676
+
677
+ export const PatchPromptTemplateVersionArgsSchema = z.object({
678
+ identifier: z.string().describe("Prompt template name or numeric ID"),
679
+ version: z.number().int().optional().describe("Base version number to patch from (mutually exclusive with label; defaults to latest)"),
680
+ label: z.string().optional().describe("Release label identifying the base version (mutually exclusive with version)"),
681
+ messages: z.union([z.record(z.unknown()), z.array(z.record(z.unknown()))]).optional().describe(
682
+ "Chat templates only. " +
683
+ "Object form: index-based patch ({\"0\": {...}}) — only listed indices are updated, others preserved. " +
684
+ "Array form: full replacement of all messages."
685
+ ),
686
+ tools: z.union([z.record(z.unknown()), z.array(z.record(z.unknown())), z.null()]).optional().describe(
687
+ "Chat templates only. Same patching behavior as messages. Pass null to remove all tools."
688
+ ),
689
+ functions: z.union([z.record(z.unknown()), z.array(z.record(z.unknown())), z.null()]).optional().describe(
690
+ "Chat templates only. Same patching behavior as messages. Pass null to remove all functions."
691
+ ),
692
+ function_call: z.union([z.string(), z.record(z.unknown()), z.null()]).optional().describe("Replaces the function_call setting. Null removes."),
693
+ tool_choice: z.union([z.string(), z.record(z.unknown()), z.null()]).optional().describe("Replaces the tool_choice setting. Null removes."),
694
+ content: z.union([z.record(z.unknown()), z.array(z.record(z.unknown()))]).optional().describe(
695
+ "Completion templates only. Same index-based / full-replacement behavior as messages."
696
+ ),
697
+ model_parameters: z.record(z.unknown()).optional().describe("Shallow-merged into existing model parameters (e.g. temperature, max_tokens)."),
698
+ response_format: z.union([z.record(z.unknown()), z.null()]).optional().describe("Convenience field to set response_format inside model parameters. Null removes. Cannot be combined with response_format inside model_parameters."),
699
+ commit_message: z.string().optional().describe("Commit message for the new version"),
700
+ release_labels: z.array(z.string()).optional().describe("Release labels to create or move to the new version"),
701
+ api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
702
+ });
703
+
704
+
705
+
706
+
707
+ // ── Request log query (shared by /requests/search and /requests/analytics) ──
708
+ // Backend models: search uses PostStructuredSearchRequest = RequestLogQuery + page/per_page/include_prompt_name;
709
+ // analytics uses RequestLogQuery directly. We share the 4 RequestLogQuery fields here.
710
+
711
+ const RequestLogQueryShape = {
625
712
  filter_group: StructuredFilterGroupSchema.optional().describe("Filter group with AND/OR logic, supports nesting. Wrap multiple filters in an AND group."),
626
713
  q: z.string().optional().describe("Free-text search across prompt input and LLM output"),
627
- page: z.number().int().optional().describe("Page number (default: 1)"),
628
- per_page: z.number().int().optional().describe("Items per page (max: 25)"),
629
714
  sort_by: z.enum([
630
715
  "request_start_time", "input_tokens", "output_tokens", "cost", "latency_ms", "status",
631
716
  "turn_count", "tool_call_count",
632
717
  ]).optional().describe("Sort field"),
633
718
  sort_order: z.enum(["asc", "desc"]).optional().describe("Sort direction (must be provided with sort_by)"),
719
+ };
720
+
721
+ // ── Search Request Logs (POST /api/public/v2/requests/search) ────────────
722
+ // (StructuredFilter / StructuredFilterGroup are defined higher up so the
723
+ // dataset-from-filter-params endpoint can reuse them.)
724
+
725
+ export const SearchRequestLogsArgsSchema = z.object({
726
+ ...RequestLogQueryShape,
727
+ page: z.number().int().optional().describe("Page number (default: 1)"),
728
+ per_page: z.number().int().optional().describe("Items per page (max: 25)"),
634
729
  include_prompt_name: z.boolean().optional().describe("Include prompt template name in results"),
635
730
  api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
636
731
  });
637
732
 
733
+ // ── Get Request Analytics (POST /api/public/v2/requests/analytics) ───────
734
+ // Same RequestLogQuery body as search-request-logs but returns aggregated
735
+ // charts (requests/tokens/cost over time, latency stats, model & prompt
736
+ // breakdowns) instead of paginated rows.
737
+
738
+ export const GetRequestAnalyticsArgsSchema = z.object({
739
+ ...RequestLogQueryShape,
740
+ api_key: z.string().optional().describe("PromptLayer API key (optional, defaults to PROMPTLAYER_API_KEY env var)"),
741
+ });
742
+
638
743
  // ── Get Request (GET /api/public/v2/requests/{request_id}) ───────────────
639
744
 
640
745
  export const GetRequestArgsSchema = z.object({
@@ -1068,4 +1173,74 @@ export const TOOL_DEFINITIONS = {
1068
1173
  inputSchema: ResolveFolderIdArgsSchema,
1069
1174
  annotations: { readOnlyHint: true },
1070
1175
  },
1176
+
1177
+ // ── Skill Collections ───────────────────────────────────────────────
1178
+ "list-skill-collections": {
1179
+ name: "list-skill-collections",
1180
+ description: "List all skill collections in the workspace. Returns each collection's UUID, name, root_path, provider, description, and timestamps.",
1181
+ inputSchema: ListSkillCollectionsArgsSchema,
1182
+ annotations: { readOnlyHint: true },
1183
+ },
1184
+ "create-skill-collection": {
1185
+ name: "create-skill-collection",
1186
+ description:
1187
+ "Create a new skill collection with optional initial files. Each file is {path, content} where path is relative inside the collection " +
1188
+ "(e.g. 'README.md' or 'src/util.ts'). Provider is auto-detected from file paths if omitted (e.g. .claude/* → 'claude'). " +
1189
+ "Names are made unique within the workspace if they collide.",
1190
+ inputSchema: CreateSkillCollectionArgsSchema,
1191
+ annotations: { readOnlyHint: false },
1192
+ },
1193
+ "get-skill-collection": {
1194
+ name: "get-skill-collection",
1195
+ description:
1196
+ "Fetch a skill collection by UUID, name, or root_path. Returns the collection metadata, the version object, and a 'files' map of " +
1197
+ "{relative_path: file_content}. Pin a specific version with 'version' (number) or 'label' (release label) — these are mutually exclusive. " +
1198
+ "If neither is provided, returns the latest committed version.",
1199
+ inputSchema: GetSkillCollectionArgsSchema,
1200
+ annotations: { readOnlyHint: true },
1201
+ },
1202
+ "update-skill-collection": {
1203
+ name: "update-skill-collection",
1204
+ description: "Rename a skill collection or update its description. To save new file contents as a version, use save-skill-collection-version instead.",
1205
+ inputSchema: UpdateSkillCollectionArgsSchema,
1206
+ annotations: { readOnlyHint: false },
1207
+ },
1208
+ "save-skill-collection-version": {
1209
+ name: "save-skill-collection-version",
1210
+ description:
1211
+ "Save a new version of a skill collection. Apply file changes via three lists: " +
1212
+ "file_updates (add or overwrite — files not mentioned are carried forward unchanged), " +
1213
+ "moves (rename), and deletes (remove). Optionally attach a release_label to the new version.",
1214
+ inputSchema: SaveSkillCollectionVersionArgsSchema,
1215
+ annotations: { readOnlyHint: false },
1216
+ },
1217
+
1218
+ // ── Analytics ───────────────────────────────────────────────────────
1219
+ "get-request-analytics": {
1220
+ name: "get-request-analytics",
1221
+ description:
1222
+ "Aggregate analytics across request logs — totals (requests, tokens, cost), time-series breakdowns, latency percentiles, " +
1223
+ "and most-used models/prompts. Body is the same shape as search-request-logs (filter_group, q, sort_by, sort_order); the response is aggregated, not paginated rows. " +
1224
+ "Use this to answer questions like 'how much have we spent on GPT-4o this week?' or 'what's the p90 latency for prod traffic?'.",
1225
+ inputSchema: GetRequestAnalyticsArgsSchema,
1226
+ annotations: { readOnlyHint: true },
1227
+ },
1228
+
1229
+ // ── Prompt Template Patch ───────────────────────────────────────────
1230
+ "patch-prompt-template-version": {
1231
+ name: "patch-prompt-template-version",
1232
+ description:
1233
+ "Partially update a prompt template by creating a new version with merged changes. Fetches the base version (latest by default, or pin via version/label), " +
1234
+ "applies field-level patches, and creates a new version.\n\n" +
1235
+ "MERGE BEHAVIOR:\n" +
1236
+ " - messages/tools/functions/content: object form is index-based patch ({\"0\": {...}} updates only listed indices); array form fully replaces.\n" +
1237
+ " - tools/functions/function_call/tool_choice/response_format: pass null to remove.\n" +
1238
+ " - model_parameters: shallow merge — existing keys are preserved unless overwritten.\n" +
1239
+ " - release_labels: creates or moves the labels to the new version.\n\n" +
1240
+ "Use this for surgical edits (e.g. tweak the system message, add a tool, change temperature) without resending the whole template. " +
1241
+ "For a full rewrite, use publish-prompt-template instead.",
1242
+ inputSchema: PatchPromptTemplateVersionArgsSchema,
1243
+ annotations: { readOnlyHint: false },
1244
+ },
1245
+
1071
1246
  } as const;