@praxis-ai/praxis 0.1.4 → 0.1.5

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.
Files changed (55) hide show
  1. package/dist/agentCore/index.d.ts +11 -3
  2. package/dist/applicationLayer/applicationRuntime.js +7 -1
  3. package/dist/basetool/authoring.d.ts +2 -0
  4. package/dist/basetool/authoring.js +2 -0
  5. package/dist/basetool/catalog.d.ts +1 -1
  6. package/dist/basetool/catalog.js +86 -4
  7. package/dist/basetool/core/index.d.ts +4 -2
  8. package/dist/basetool/core/index.js +8 -0
  9. package/dist/basetool/core/mcpCompletions.d.ts +2 -0
  10. package/dist/basetool/core/mcpCompletions.js +70 -0
  11. package/dist/basetool/core/mcpPrompts.d.ts +2 -0
  12. package/dist/basetool/core/mcpPrompts.js +48 -0
  13. package/dist/basetool/core/mcpResources.js +41 -5
  14. package/dist/basetool/profiles.js +15 -1
  15. package/dist/basetool/registry.d.ts +1 -1
  16. package/dist/basetool/supportCatalog.js +23 -6
  17. package/dist/runtimeImplementation/praxisRuntimeKernel.js +1696 -1499
  18. package/dist/runtimeImplementation/runtime.execEngine/baseToolApprovalScope.js +11 -0
  19. package/dist/runtimeImplementation/runtime.execEngine/baseToolExecutorPortFactory.js +13 -1
  20. package/dist/runtimeImplementation/runtime.execEngine/baseToolPolicyAdjudicator.js +14 -0
  21. package/dist/runtimeImplementation/runtime.execEngine/mcpRuntimeAdapter.d.ts +27 -0
  22. package/dist/runtimeImplementation/runtime.execEngine/mcpRuntimeAdapter.js +648 -56
  23. package/dist/runtimeImplementation/runtime.execEngine/promptContextAssembly.d.ts +1 -0
  24. package/dist/runtimeImplementation/runtime.execEngine/promptContextAssembly.js +18 -0
  25. package/dist/runtimeImplementation/runtime.mcpPlane/index.d.ts +20 -7
  26. package/dist/runtimeImplementation/runtime.mcpPlane/index.js +105 -89
  27. package/dist/toolBase/catalog.d.ts +24 -0
  28. package/dist/toolBase/catalog.js +41 -3
  29. package/dist/toolBase/profiles.d.ts +3 -3
  30. package/dist/toolBase/profiles.js +2 -0
  31. package/dist/toolBase/types.d.ts +1 -1
  32. package/examples/raxode-mcp-plus-ten-server.config.json +229 -0
  33. package/examples/scripts/README.md +8 -2
  34. package/examples/scripts/mcp-plus-native-smoke.ts +1296 -0
  35. package/package.json +3 -1
  36. package/raxode-tui/dist/raxode-cli/backend/agents/codingAgent/prompts/tool-use.md +1 -1
  37. package/raxode-tui/dist/raxode-cli/backend/application/mcpConfig.d.ts +9 -0
  38. package/raxode-tui/dist/raxode-cli/backend/application/mcpConfig.js +65 -0
  39. package/raxode-tui/dist/raxode-cli/backend/application/mcpReadinessSummary.d.ts +28 -0
  40. package/raxode-tui/dist/raxode-cli/backend/application/mcpReadinessSummary.js +57 -0
  41. package/raxode-tui/dist/raxode-cli/backend/application/runtimeReadiness.d.ts +5 -1
  42. package/raxode-tui/dist/raxode-cli/backend/application/runtimeReadiness.js +40 -0
  43. package/raxode-tui/dist/raxode-cli/backend/application/stdioApplicationServer.js +6 -0
  44. package/raxode-tui/dist/raxode-cli/backend/directApplicationBackend.d.ts +4 -0
  45. package/raxode-tui/dist/raxode-cli/backend/directApplicationBackend.js +14 -0
  46. package/raxode-tui/dist/raxode-cli/backend/raxodeBackend.d.ts +1 -1
  47. package/raxode-tui/dist/raxode-cli/backend/raxodeBackend.js +16 -1
  48. package/raxode-tui/dist/raxode-cli/contracts.d.ts +1 -0
  49. package/raxode-tui/dist/raxode-cli/frontend/bridge/readiness.js +24 -0
  50. package/raxode-tui/dist/raxode-cli/frontend/tui/app/direct-tui.js +35 -0
  51. package/raxode-tui/dist/raxode-cli/frontend/tui/cli/raxode-cli.d.ts +2 -0
  52. package/raxode-tui/dist/raxode-cli/frontend/tui/cli/raxode-cli.js +8 -0
  53. package/raxode-tui/dist/raxode-cli/frontend/tui/config/raxode-config.d.ts +31 -0
  54. package/raxode-tui/dist/raxode-cli/frontend/tui/config/raxode-config.js +129 -0
  55. package/raxode-tui/dist/raxode-cli/index.d.ts +1 -0
@@ -193,6 +193,8 @@ export declare const baseTool: Readonly<{
193
193
  readonly contextLoad: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
194
194
  readonly mcpUse: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
195
195
  readonly mcpResources: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
196
+ readonly mcpPrompts: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
197
+ readonly mcpCompletions: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
196
198
  };
197
199
  readonly runtime: {
198
200
  readonly processWait: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
@@ -271,7 +273,7 @@ export declare const baseTool: Readonly<{
271
273
  baseToolCodingCoreDescriptor: {
272
274
  readonly surface: "basetool.core";
273
275
  readonly profileName: "agentCore";
274
- readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
276
+ readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "mcp.prompts", "mcp.completions", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
275
277
  readonly directHostAccess: false;
276
278
  readonly runtimePortRequired: true;
277
279
  readonly inspiredBy: "opencode tool execute core, adapted to Praxis BaseToolExecutorPort";
@@ -702,6 +704,8 @@ export declare const praxis: Readonly<{
702
704
  readonly contextLoad: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
703
705
  readonly mcpUse: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
704
706
  readonly mcpResources: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
707
+ readonly mcpPrompts: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
708
+ readonly mcpCompletions: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
705
709
  };
706
710
  readonly runtime: {
707
711
  readonly processWait: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
@@ -730,6 +734,8 @@ export declare const praxis: Readonly<{
730
734
  readonly contextLoad: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
731
735
  readonly mcpUse: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
732
736
  readonly mcpResources: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
737
+ readonly mcpPrompts: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
738
+ readonly mcpCompletions: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
733
739
  };
734
740
  readonly runtime: {
735
741
  readonly processWait: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
@@ -759,6 +765,8 @@ export declare const praxis: Readonly<{
759
765
  readonly contextLoad: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
760
766
  readonly mcpUse: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
761
767
  readonly mcpResources: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
768
+ readonly mcpPrompts: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
769
+ readonly mcpCompletions: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
762
770
  };
763
771
  readonly runtime: {
764
772
  readonly processWait: (input?: import("../basetool/types.js").BaseToolSpecInput) => import("../runtimeImplementation/runtimeAgentManifest.js").ToolSpec;
@@ -837,7 +845,7 @@ export declare const praxis: Readonly<{
837
845
  baseToolCodingCoreDescriptor: {
838
846
  readonly surface: "basetool.core";
839
847
  readonly profileName: "agentCore";
840
- readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
848
+ readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "mcp.prompts", "mcp.completions", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
841
849
  readonly directHostAccess: false;
842
850
  readonly runtimePortRequired: true;
843
851
  readonly inspiredBy: "opencode tool execute core, adapted to Praxis BaseToolExecutorPort";
@@ -904,7 +912,7 @@ export declare const praxis: Readonly<{
904
912
  baseToolCodingCoreDescriptor: {
905
913
  readonly surface: "basetool.core";
906
914
  readonly profileName: "agentCore";
907
- readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
915
+ readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "mcp.prompts", "mcp.completions", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
908
916
  readonly directHostAccess: false;
909
917
  readonly runtimePortRequired: true;
910
918
  readonly inspiredBy: "opencode tool execute core, adapted to Praxis BaseToolExecutorPort";
@@ -1160,6 +1160,7 @@ function summarizeMcpToolInput(toolCall) {
1160
1160
  const serverId = firstStringValue(target?.serverId, target?.connectionId, args.serverId, args.connectionId);
1161
1161
  const toolName = firstStringValue(target?.toolName, target?.name, args.toolName, args.name);
1162
1162
  const resourceUri = firstStringValue(target?.resourceUri, target?.uri, args.resourceUri, args.uri);
1163
+ const promptName = firstStringValue(target?.promptName, target?.name, args.promptName, args.name);
1163
1164
  if (toolCall.toolId === "mcp.use")
1164
1165
  return `Calling MCP tool ${toolName ?? "tool"}${serverId ? ` on ${serverId}` : ""}`;
1165
1166
  if (toolCall.toolId === "mcp.resources") {
@@ -1167,6 +1168,11 @@ function summarizeMcpToolInput(toolCall) {
1167
1168
  ? `Reading MCP resource ${resourceUri}${serverId ? ` from ${serverId}` : ""}`
1168
1169
  : `Listing MCP resources${serverId ? ` from ${serverId}` : ""}`;
1169
1170
  }
1171
+ if (toolCall.toolId === "mcp.prompts") {
1172
+ return promptName
1173
+ ? `Reading MCP prompt ${promptName}${serverId ? ` from ${serverId}` : ""}`
1174
+ : `Listing MCP prompts${serverId ? ` from ${serverId}` : ""}`;
1175
+ }
1170
1176
  return `${toolCall.toolId}${serverId ? ` on ${serverId}` : ""}`;
1171
1177
  }
1172
1178
  function summarizeMcpToolOutputForHumans(toolCall, output) {
@@ -2555,7 +2561,7 @@ function createApplicationMcpModule(options) {
2555
2561
  return options.mcpModule;
2556
2562
  const nativeServers = (options.mcpServers ?? []).map((server) => ({
2557
2563
  ...server,
2558
- mode: server.mode ?? "native",
2564
+ mode: server.mode ?? (server.manifest === undefined ? "native" : "mcp-plus"),
2559
2565
  }));
2560
2566
  const plusServers = (options.mcpPlusServers ?? []).map((server) => ({
2561
2567
  ...server,
@@ -47,6 +47,8 @@ export declare const basetool: {
47
47
  readonly contextLoad: (input?: BaseToolSpecInput) => ToolSpec;
48
48
  readonly mcpUse: (input?: BaseToolSpecInput) => ToolSpec;
49
49
  readonly mcpResources: (input?: BaseToolSpecInput) => ToolSpec;
50
+ readonly mcpPrompts: (input?: BaseToolSpecInput) => ToolSpec;
51
+ readonly mcpCompletions: (input?: BaseToolSpecInput) => ToolSpec;
50
52
  };
51
53
  readonly runtime: {
52
54
  readonly processWait: (input?: BaseToolSpecInput) => ToolSpec;
@@ -92,6 +92,8 @@ export const basetool = {
92
92
  contextLoad: (input) => knownTool("context.load", input),
93
93
  mcpUse: (input) => knownTool("mcp.use", input),
94
94
  mcpResources: (input) => knownTool("mcp.resources", input),
95
+ mcpPrompts: (input) => knownTool("mcp.prompts", input),
96
+ mcpCompletions: (input) => knownTool("mcp.completions", input),
95
97
  },
96
98
  runtime: {
97
99
  processWait: (input) => knownTool("process.wait", input),
@@ -1,4 +1,4 @@
1
1
  import type { BaseToolDefinition } from "./types.js";
2
- export declare const semanticBaseToolCatalog: readonly [BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition];
2
+ export declare const semanticBaseToolCatalog: readonly [BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition, BaseToolDefinition];
3
3
  export declare function listSemanticBaseToolDefinitions(): readonly BaseToolDefinition[];
4
4
  export declare function getSemanticBaseToolDefinition(toolId: string): BaseToolDefinition | undefined;
@@ -474,21 +474,103 @@ export const semanticBaseToolCatalog = [
474
474
  toolId: "mcp.resources",
475
475
  layer: "agent",
476
476
  title: "Read MCP Resources",
477
- description: "List or read MCP resources through runtime-owned MCP clients.",
477
+ description: "List resources, list resource templates, read, subscribe to, or unsubscribe from MCP resources through runtime-owned MCP clients.",
478
478
  risk: "read",
479
- runtimePorts: ["mcp.listResources", "mcp.readResource"],
480
- permissionHints: ["mcp:resources", "mcp:read"],
479
+ runtimePorts: ["mcp.listResources", "mcp.listResourceTemplates", "mcp.readResource", "mcp.subscribe", "mcp.unsubscribe"],
480
+ permissionHints: ["mcp:resources", "mcp:read", "mcp:resource:template:list", "mcp:resource:subscribe"],
481
481
  inputSchema: schema({
482
482
  type: "object",
483
483
  properties: {
484
- operation: { type: "string", enum: ["list", "read"] },
484
+ operation: { type: "string", enum: ["list", "templates", "read", "subscribe", "unsubscribe"] },
485
485
  serverId: { type: "string" },
486
486
  uri: { type: "string" },
487
+ uriPrefix: { type: "string" },
488
+ cursor: { type: "string" },
489
+ subscriptionId: { type: "string" },
487
490
  },
488
491
  required: ["operation"],
489
492
  additionalProperties: false,
490
493
  }),
491
494
  }),
495
+ define({
496
+ toolId: "mcp.prompts",
497
+ layer: "agent",
498
+ title: "Read MCP Prompts",
499
+ description: "List or get MCP prompts through runtime-owned MCP clients.",
500
+ risk: "read",
501
+ runtimePorts: ["mcp.listPrompts", "mcp.getPrompt"],
502
+ permissionHints: ["mcp:prompt:list", "mcp:prompt:get"],
503
+ inputSchema: schema({
504
+ type: "object",
505
+ properties: {
506
+ operation: { type: "string", enum: ["list", "get"] },
507
+ serverId: { type: "string" },
508
+ cursor: { type: "string" },
509
+ name: { type: "string" },
510
+ arguments: { type: "object" },
511
+ },
512
+ required: ["operation"],
513
+ additionalProperties: false,
514
+ }),
515
+ }),
516
+ define({
517
+ toolId: "mcp.completions",
518
+ layer: "agent",
519
+ title: "Complete MCP Arguments",
520
+ description: "Request MCP completion suggestions for prompt arguments or resource template variables through runtime-owned MCP clients.",
521
+ risk: "read",
522
+ runtimePorts: ["mcp.complete"],
523
+ permissionHints: ["mcp:completion"],
524
+ inputSchema: schema({
525
+ type: "object",
526
+ properties: {
527
+ serverId: { type: "string" },
528
+ ref: {
529
+ oneOf: [
530
+ {
531
+ type: "object",
532
+ properties: {
533
+ type: { const: "ref/prompt" },
534
+ name: { type: "string" },
535
+ },
536
+ required: ["type", "name"],
537
+ additionalProperties: false,
538
+ },
539
+ {
540
+ type: "object",
541
+ properties: {
542
+ type: { const: "ref/resource" },
543
+ uri: { type: "string" },
544
+ },
545
+ required: ["type", "uri"],
546
+ additionalProperties: false,
547
+ },
548
+ ],
549
+ },
550
+ argument: {
551
+ type: "object",
552
+ properties: {
553
+ name: { type: "string" },
554
+ value: { type: "string" },
555
+ },
556
+ required: ["name", "value"],
557
+ additionalProperties: false,
558
+ },
559
+ context: {
560
+ type: "object",
561
+ properties: {
562
+ arguments: {
563
+ type: "object",
564
+ additionalProperties: { type: "string" },
565
+ },
566
+ },
567
+ additionalProperties: false,
568
+ },
569
+ },
570
+ required: ["ref", "argument"],
571
+ additionalProperties: false,
572
+ }),
573
+ }),
492
574
  define({
493
575
  toolId: "media.viewImage",
494
576
  layer: "optional",
@@ -1,13 +1,13 @@
1
1
  import type { BaseToolDefinition, BaseToolInvokeRequest, BaseToolInvokeResult } from "../types.js";
2
2
  export type BaseToolCoreInvoker = (definition: BaseToolDefinition, request: BaseToolInvokeRequest) => Promise<BaseToolInvokeResult> | BaseToolInvokeResult;
3
- export declare const codingCoreToolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
3
+ export declare const codingCoreToolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "mcp.prompts", "mcp.completions", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
4
4
  export type CodingCoreToolId = (typeof codingCoreToolIds)[number];
5
5
  export declare const codingCoreInvokers: Readonly<Record<CodingCoreToolId, BaseToolCoreInvoker>>;
6
6
  export declare function lookupBaseToolCoreInvoker(toolId: string): BaseToolCoreInvoker | undefined;
7
7
  export declare const baseToolCodingCoreDescriptor: {
8
8
  readonly surface: "basetool.core";
9
9
  readonly profileName: "agentCore";
10
- readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
10
+ readonly toolIds: readonly ["file.read", "file.search", "patch.apply", "web.search", "web.fetch", "shell.run", "skill.load", "context.load", "mcp.use", "mcp.resources", "mcp.prompts", "mcp.completions", "media.viewImage", "process.wait", "process.kill", "plan.update", "user.ask", "tool.discover", "tool.describe", "agent.spawn", "agent.message", "agent.inbox", "agent.list", "agent.inspect", "agent.wait", "agent.stop", "agent.kill"];
11
11
  readonly directHostAccess: false;
12
12
  readonly runtimePortRequired: true;
13
13
  readonly inspiredBy: "opencode tool execute core, adapted to Praxis BaseToolExecutorPort";
@@ -24,6 +24,8 @@ export * from "./skillLoad.js";
24
24
  export * from "./contextLoad.js";
25
25
  export * from "./mcpUse.js";
26
26
  export * from "./mcpResources.js";
27
+ export * from "./mcpPrompts.js";
28
+ export * from "./mcpCompletions.js";
27
29
  export * from "./processWait.js";
28
30
  export * from "./processKill.js";
29
31
  export * from "./mediaViewImage.js";
@@ -12,6 +12,8 @@ import { invokeSkillLoadCore } from "./skillLoad.js";
12
12
  import { invokeContextLoadCore } from "./contextLoad.js";
13
13
  import { invokeMcpUseCore } from "./mcpUse.js";
14
14
  import { invokeMcpResourcesCore } from "./mcpResources.js";
15
+ import { invokeMcpPromptsCore } from "./mcpPrompts.js";
16
+ import { invokeMcpCompletionsCore } from "./mcpCompletions.js";
15
17
  import { invokeMediaViewImageCore } from "./mediaViewImage.js";
16
18
  import { invokeToolDiscoverCore } from "./toolDiscover.js";
17
19
  import { invokeToolDescribeCore } from "./toolDescribe.js";
@@ -27,6 +29,8 @@ export const codingCoreToolIds = [
27
29
  "context.load",
28
30
  "mcp.use",
29
31
  "mcp.resources",
32
+ "mcp.prompts",
33
+ "mcp.completions",
30
34
  "media.viewImage",
31
35
  "process.wait",
32
36
  "process.kill",
@@ -54,6 +58,8 @@ export const codingCoreInvokers = {
54
58
  "context.load": invokeContextLoadCore,
55
59
  "mcp.use": invokeMcpUseCore,
56
60
  "mcp.resources": invokeMcpResourcesCore,
61
+ "mcp.prompts": invokeMcpPromptsCore,
62
+ "mcp.completions": invokeMcpCompletionsCore,
57
63
  "process.wait": invokeProcessWaitCore,
58
64
  "process.kill": invokeProcessKillCore,
59
65
  "media.viewImage": invokeMediaViewImageCore,
@@ -93,6 +99,8 @@ export * from "./skillLoad.js";
93
99
  export * from "./contextLoad.js";
94
100
  export * from "./mcpUse.js";
95
101
  export * from "./mcpResources.js";
102
+ export * from "./mcpPrompts.js";
103
+ export * from "./mcpCompletions.js";
96
104
  export * from "./processWait.js";
97
105
  export * from "./processKill.js";
98
106
  export * from "./mediaViewImage.js";
@@ -0,0 +1,2 @@
1
+ import type { BaseToolDefinition, BaseToolInvokeRequest, BaseToolInvokeResult } from "../types.js";
2
+ export declare function invokeMcpCompletionsCore(definition: BaseToolDefinition, request: BaseToolInvokeRequest): Promise<BaseToolInvokeResult>;
@@ -0,0 +1,70 @@
1
+ import { callRuntimePort, errorResult } from "./results.js";
2
+ import { compactRecord, inputRecord, namespaceMethod, recordField, stringField } from "./validation.js";
3
+ function stringRecordValue(value, key) {
4
+ const field = value[key];
5
+ return typeof field === "string" ? field : undefined;
6
+ }
7
+ function hasOnlyStringValues(value) {
8
+ return Object.values(value).every((field) => typeof field === "string");
9
+ }
10
+ export async function invokeMcpCompletionsCore(definition, request) {
11
+ const input = inputRecord(definition, request);
12
+ if (!input.ok)
13
+ return input.result;
14
+ const serverId = stringField(definition, input.value, "serverId");
15
+ if (!serverId.ok)
16
+ return serverId.result;
17
+ const ref = recordField(definition, input.value, "ref");
18
+ if (!ref.ok)
19
+ return ref.result;
20
+ const argument = recordField(definition, input.value, "argument");
21
+ if (!argument.ok)
22
+ return argument.result;
23
+ const context = recordField(definition, input.value, "context");
24
+ if (!context.ok)
25
+ return context.result;
26
+ if (ref.value === undefined) {
27
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.completions requires 'ref'.");
28
+ }
29
+ if (argument.value === undefined) {
30
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.completions requires 'argument'.");
31
+ }
32
+ const refType = stringRecordValue(ref.value, "type");
33
+ if (refType !== "ref/prompt" && refType !== "ref/resource") {
34
+ return errorResult(definition, "INVALID_FIELD_VALUE", "mcp.completions ref.type must be 'ref/prompt' or 'ref/resource'.");
35
+ }
36
+ if (refType === "ref/prompt" && (stringRecordValue(ref.value, "name")?.trim().length ?? 0) === 0) {
37
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.completions prompt ref requires 'name'.");
38
+ }
39
+ if (refType === "ref/resource" && (stringRecordValue(ref.value, "uri")?.trim().length ?? 0) === 0) {
40
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.completions resource ref requires 'uri'.");
41
+ }
42
+ const argumentName = stringRecordValue(argument.value, "name");
43
+ const argumentValue = stringRecordValue(argument.value, "value");
44
+ if ((argumentName?.trim().length ?? 0) === 0) {
45
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.completions argument requires non-empty 'name'.");
46
+ }
47
+ if (argumentValue === undefined) {
48
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.completions argument requires string 'value'.");
49
+ }
50
+ const contextArguments = context.value?.arguments;
51
+ if (contextArguments !== undefined && (typeof contextArguments !== "object" || contextArguments === null || Array.isArray(contextArguments) || !hasOnlyStringValues(contextArguments))) {
52
+ return errorResult(definition, "INVALID_FIELD_TYPE", "mcp.completions context.arguments must be a JSON object with string values.");
53
+ }
54
+ const complete = namespaceMethod(definition, request, "mcp", "complete");
55
+ if (!complete.ok)
56
+ return complete.result;
57
+ return callRuntimePort(definition, complete.value(compactRecord({
58
+ serverId: serverId.value,
59
+ ref: ref.value,
60
+ argument: argument.value,
61
+ context: context.value,
62
+ })), {
63
+ portPath: "mcp.complete",
64
+ metadata: {
65
+ serverId: serverId.value,
66
+ refType,
67
+ argumentName,
68
+ },
69
+ });
70
+ }
@@ -0,0 +1,2 @@
1
+ import type { BaseToolDefinition, BaseToolInvokeRequest, BaseToolInvokeResult } from "../types.js";
2
+ export declare function invokeMcpPromptsCore(definition: BaseToolDefinition, request: BaseToolInvokeRequest): Promise<BaseToolInvokeResult>;
@@ -0,0 +1,48 @@
1
+ import { callRuntimePort, errorResult } from "./results.js";
2
+ import { compactRecord, inputRecord, namespaceMethod, recordField, requiredStringField, stringField } from "./validation.js";
3
+ export async function invokeMcpPromptsCore(definition, request) {
4
+ const input = inputRecord(definition, request);
5
+ if (!input.ok)
6
+ return input.result;
7
+ const operation = requiredStringField(definition, input.value, "operation", { minLength: 1 });
8
+ if (!operation.ok)
9
+ return operation.result;
10
+ const serverId = stringField(definition, input.value, "serverId");
11
+ if (!serverId.ok)
12
+ return serverId.result;
13
+ const cursor = stringField(definition, input.value, "cursor");
14
+ if (!cursor.ok)
15
+ return cursor.result;
16
+ const name = stringField(definition, input.value, "name");
17
+ if (!name.ok)
18
+ return name.result;
19
+ const args = recordField(definition, input.value, "arguments");
20
+ if (!args.ok)
21
+ return args.result;
22
+ if (operation.value !== "list" && operation.value !== "get") {
23
+ return errorResult(definition, "INVALID_FIELD_VALUE", "mcp.prompts operation must be 'list' or 'get'.");
24
+ }
25
+ if (operation.value === "get" && (name.value?.trim().length ?? 0) === 0) {
26
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.prompts get requires 'name'.");
27
+ }
28
+ if (operation.value === "list") {
29
+ const listPrompts = namespaceMethod(definition, request, "mcp", "listPrompts");
30
+ if (!listPrompts.ok)
31
+ return listPrompts.result;
32
+ return callRuntimePort(definition, listPrompts.value(compactRecord({ serverId: serverId.value, cursor: cursor.value })), {
33
+ portPath: "mcp.listPrompts",
34
+ metadata: { operation: operation.value, serverId: serverId.value, cursor: cursor.value },
35
+ });
36
+ }
37
+ const getPrompt = namespaceMethod(definition, request, "mcp", "getPrompt");
38
+ if (!getPrompt.ok)
39
+ return getPrompt.result;
40
+ return callRuntimePort(definition, getPrompt.value(compactRecord({
41
+ serverId: serverId.value,
42
+ name: name.value,
43
+ arguments: args.value ?? {},
44
+ })), {
45
+ portPath: "mcp.getPrompt",
46
+ metadata: { operation: operation.value, serverId: serverId.value, name: name.value },
47
+ });
48
+ }
@@ -13,18 +13,54 @@ export async function invokeMcpResourcesCore(definition, request) {
13
13
  const uri = stringField(definition, input.value, "uri");
14
14
  if (!uri.ok)
15
15
  return uri.result;
16
- if (operation.value !== "list" && operation.value !== "read") {
17
- return errorResult(definition, "INVALID_FIELD_VALUE", "mcp.resources operation must be 'list' or 'read'.");
16
+ const uriPrefix = stringField(definition, input.value, "uriPrefix");
17
+ if (!uriPrefix.ok)
18
+ return uriPrefix.result;
19
+ const cursor = stringField(definition, input.value, "cursor");
20
+ if (!cursor.ok)
21
+ return cursor.result;
22
+ const subscriptionId = stringField(definition, input.value, "subscriptionId");
23
+ if (!subscriptionId.ok)
24
+ return subscriptionId.result;
25
+ if (!["list", "templates", "read", "subscribe", "unsubscribe"].includes(operation.value)) {
26
+ return errorResult(definition, "INVALID_FIELD_VALUE", "mcp.resources operation must be 'list', 'templates', 'read', 'subscribe', or 'unsubscribe'.");
18
27
  }
19
28
  if (operation.value === "read" && (uri.value?.trim().length ?? 0) === 0) {
20
29
  return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.resources read requires 'uri'.");
21
30
  }
22
- const method = operation.value === "list" ? "listResources" : "readResource";
31
+ if (operation.value === "subscribe" && (uri.value?.trim().length ?? 0) === 0) {
32
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.resources subscribe requires 'uri'.");
33
+ }
34
+ if (operation.value === "unsubscribe" && (uri.value?.trim().length ?? 0) === 0 && (subscriptionId.value?.trim().length ?? 0) === 0) {
35
+ return errorResult(definition, "MISSING_REQUIRED_FIELD", "mcp.resources unsubscribe requires 'uri' or 'subscriptionId'.");
36
+ }
37
+ const method = operation.value === "list"
38
+ ? "listResources"
39
+ : operation.value === "templates"
40
+ ? "listResourceTemplates"
41
+ : operation.value === "read"
42
+ ? "readResource"
43
+ : operation.value;
23
44
  const resourcePort = namespaceMethod(definition, request, "mcp", method);
24
45
  if (!resourcePort.ok)
25
46
  return resourcePort.result;
26
- return callRuntimePort(definition, resourcePort.value(compactRecord({ serverId: serverId.value, uri: uri.value })), {
47
+ return callRuntimePort(definition, resourcePort.value(compactRecord({
48
+ serverId: serverId.value,
49
+ uri: uri.value,
50
+ uriPrefix: uriPrefix.value,
51
+ cursor: cursor.value,
52
+ subjectType: operation.value === "subscribe" ? "resource" : undefined,
53
+ subject: operation.value === "subscribe" ? uri.value : undefined,
54
+ subscriptionId: subscriptionId.value,
55
+ })), {
27
56
  portPath: `mcp.${method}`,
28
- metadata: { operation: operation.value, serverId: serverId.value, uri: uri.value },
57
+ metadata: {
58
+ operation: operation.value,
59
+ serverId: serverId.value,
60
+ uri: uri.value,
61
+ uriPrefix: uriPrefix.value,
62
+ cursor: cursor.value,
63
+ subscriptionId: subscriptionId.value,
64
+ },
29
65
  });
30
66
  }
@@ -26,6 +26,8 @@ const researchCoreTools = [
26
26
  "file.search",
27
27
  "context.load",
28
28
  "mcp.resources",
29
+ "mcp.prompts",
30
+ "mcp.completions",
29
31
  "plan.update",
30
32
  "user.ask",
31
33
  ];
@@ -52,7 +54,7 @@ const runtimeCoreTools = [
52
54
  "plan.update",
53
55
  "user.ask",
54
56
  ];
55
- const agentExtensionTools = ["skill.load", "context.load", "mcp.use", "mcp.resources"];
57
+ const agentExtensionTools = ["skill.load", "context.load", "mcp.use", "mcp.resources", "mcp.prompts", "mcp.completions"];
56
58
  const multiagentMeshTools = [
57
59
  "agent.spawn",
58
60
  "agent.message",
@@ -107,6 +109,12 @@ const researchDescribeOverlays = {
107
109
  "mcp.resources": overlay({
108
110
  summary: "Read external MCP resources without invoking arbitrary MCP tool actions.",
109
111
  }),
112
+ "mcp.prompts": overlay({
113
+ summary: "List or get reusable prompts exposed by mounted MCP servers.",
114
+ }),
115
+ "mcp.completions": overlay({
116
+ summary: "Ask mounted MCP servers for prompt argument or resource template variable completions.",
117
+ }),
110
118
  };
111
119
  const workDescribeOverlays = {
112
120
  "shell.run": overlay({
@@ -162,6 +170,12 @@ const agentDescribeOverlays = {
162
170
  "mcp.resources": overlay({
163
171
  summary: "List or read mounted MCP resources through runtime-owned clients.",
164
172
  }),
173
+ "mcp.prompts": overlay({
174
+ summary: "List or get mounted MCP prompts through runtime-owned clients.",
175
+ }),
176
+ "mcp.completions": overlay({
177
+ summary: "Request mounted MCP completion suggestions for prompt arguments and resource template variables.",
178
+ }),
165
179
  "skill.load": overlay({
166
180
  summary: "Load local skill instructions through the governed skill port.",
167
181
  }),
@@ -12,6 +12,6 @@ export declare const builtinBaseToolHandlers: Readonly<{
12
12
  export declare const baseToolRegistryDescriptor: {
13
13
  readonly surface: "basetool.registry";
14
14
  readonly semanticCatalog: true;
15
- readonly builtinToolCountTarget: 25;
15
+ readonly builtinToolCountTarget: 27;
16
16
  readonly dynamicToolsSupported: "future-mcp-plugin-registry";
17
17
  };
@@ -64,14 +64,31 @@ function toolInputRecord(value) {
64
64
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
65
65
  }
66
66
  function activeSupportsFor(entry, toolInput) {
67
- if (entry.toolId !== "mcp.resources")
68
- return entry.requiredSupports;
69
67
  const operation = toolInputRecord(toolInput).operation;
70
- if (operation === "list") {
71
- return entry.requiredSupports.filter((support) => support.portPath !== "mcp.readResource");
68
+ if (entry.toolId === "mcp.resources") {
69
+ const activePort = operation === "list"
70
+ ? "mcp.listResources"
71
+ : operation === "templates"
72
+ ? "mcp.listResourceTemplates"
73
+ : operation === "read"
74
+ ? "mcp.readResource"
75
+ : operation === "subscribe"
76
+ ? "mcp.subscribe"
77
+ : operation === "unsubscribe"
78
+ ? "mcp.unsubscribe"
79
+ : undefined;
80
+ if (activePort !== undefined) {
81
+ return entry.requiredSupports.filter((support) => support.portPath === activePort);
82
+ }
83
+ return entry.requiredSupports;
72
84
  }
73
- if (operation === "read") {
74
- return entry.requiredSupports.filter((support) => support.portPath !== "mcp.listResources");
85
+ if (entry.toolId === "mcp.prompts") {
86
+ if (operation === "list") {
87
+ return entry.requiredSupports.filter((support) => support.portPath !== "mcp.getPrompt");
88
+ }
89
+ if (operation === "get") {
90
+ return entry.requiredSupports.filter((support) => support.portPath !== "mcp.listPrompts");
91
+ }
75
92
  }
76
93
  return entry.requiredSupports;
77
94
  }