@contractspec/bundle.library 3.8.4 → 3.8.7

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 (90) hide show
  1. package/.turbo/turbo-build.log +126 -112
  2. package/CHANGELOG.md +56 -0
  3. package/dist/application/index.js +806 -131
  4. package/dist/application/mcp/cliMcp.js +21 -2
  5. package/dist/application/mcp/common.js +21 -2
  6. package/dist/application/mcp/common.test.d.ts +1 -0
  7. package/dist/application/mcp/contractsMcp.js +21 -2
  8. package/dist/application/mcp/docsMcp.catalog.d.ts +2 -0
  9. package/dist/application/mcp/docsMcp.catalog.js +382 -0
  10. package/dist/application/mcp/docsMcp.d.ts +5 -1
  11. package/dist/application/mcp/docsMcp.data.d.ts +85 -0
  12. package/dist/application/mcp/docsMcp.data.js +148 -0
  13. package/dist/application/mcp/docsMcp.js +776 -101
  14. package/dist/application/mcp/docsMcp.prompts.d.ts +3 -0
  15. package/dist/application/mcp/docsMcp.prompts.js +522 -0
  16. package/dist/application/mcp/docsMcp.reference.d.ts +24 -0
  17. package/dist/application/mcp/docsMcp.reference.js +236 -0
  18. package/dist/application/mcp/docsMcp.resources.d.ts +3 -0
  19. package/dist/application/mcp/docsMcp.resources.js +520 -0
  20. package/dist/application/mcp/docsMcp.test.d.ts +1 -0
  21. package/dist/application/mcp/docsMcp.tools.d.ts +3 -0
  22. package/dist/application/mcp/docsMcp.tools.js +519 -0
  23. package/dist/application/mcp/index.js +806 -131
  24. package/dist/application/mcp/internalMcp.js +21 -2
  25. package/dist/application/mcp/normalizeMcpRequest.d.ts +1 -0
  26. package/dist/application/mcp/normalizeMcpRequest.js +22 -0
  27. package/dist/application/mcp/providerRankingMcp.js +21 -2
  28. package/dist/features/index.js +15 -15
  29. package/dist/index.js +171 -171
  30. package/dist/node/application/index.js +806 -131
  31. package/dist/node/application/mcp/cliMcp.js +21 -2
  32. package/dist/node/application/mcp/common.js +21 -2
  33. package/dist/node/application/mcp/contractsMcp.js +21 -2
  34. package/dist/node/application/mcp/docsMcp.catalog.js +381 -0
  35. package/dist/node/application/mcp/docsMcp.data.js +147 -0
  36. package/dist/node/application/mcp/docsMcp.js +776 -101
  37. package/dist/node/application/mcp/docsMcp.prompts.js +521 -0
  38. package/dist/node/application/mcp/docsMcp.reference.js +235 -0
  39. package/dist/node/application/mcp/docsMcp.resources.js +519 -0
  40. package/dist/node/application/mcp/docsMcp.tools.js +518 -0
  41. package/dist/node/application/mcp/index.js +806 -131
  42. package/dist/node/application/mcp/internalMcp.js +21 -2
  43. package/dist/node/application/mcp/normalizeMcpRequest.js +21 -0
  44. package/dist/node/application/mcp/providerRankingMcp.js +21 -2
  45. package/dist/node/features/index.js +15 -15
  46. package/dist/node/index.js +171 -171
  47. package/dist/node/presentation/features/hooks/index.js +12 -12
  48. package/dist/node/presentation/features/hooks/useContractsRegistry.js +12 -12
  49. package/dist/node/presentation/features/index.js +12 -12
  50. package/dist/node/presentation/features/organisms/FeatureDataViewsList.js +12 -12
  51. package/dist/node/presentation/features/organisms/FeatureEventsList.js +12 -12
  52. package/dist/node/presentation/features/organisms/FeatureFormsList.js +12 -12
  53. package/dist/node/presentation/features/organisms/FeaturePresentationsList.js +12 -12
  54. package/dist/node/presentation/features/organisms/index.js +12 -12
  55. package/dist/node/presentation/features/templates/FeatureDataViewsTemplate/FeatureDataViewsTemplate.js +12 -12
  56. package/dist/node/presentation/features/templates/FeatureDataViewsTemplate/index.js +12 -12
  57. package/dist/node/presentation/features/templates/FeatureEventsTemplate/FeatureEventsTemplate.js +12 -12
  58. package/dist/node/presentation/features/templates/FeatureEventsTemplate/index.js +12 -12
  59. package/dist/node/presentation/features/templates/FeatureFormsTemplate/FeatureFormsTemplate.js +12 -12
  60. package/dist/node/presentation/features/templates/FeatureFormsTemplate/index.js +12 -12
  61. package/dist/node/presentation/features/templates/FeaturePresentationsTemplate/FeaturePresentationsTemplate.js +12 -12
  62. package/dist/node/presentation/features/templates/FeaturePresentationsTemplate/index.js +12 -12
  63. package/dist/presentation/features/hooks/index.js +12 -12
  64. package/dist/presentation/features/hooks/useContractsRegistry.js +12 -12
  65. package/dist/presentation/features/index.js +12 -12
  66. package/dist/presentation/features/organisms/FeatureDataViewsList.js +12 -12
  67. package/dist/presentation/features/organisms/FeatureEventsList.js +12 -12
  68. package/dist/presentation/features/organisms/FeatureFormsList.js +12 -12
  69. package/dist/presentation/features/organisms/FeaturePresentationsList.js +12 -12
  70. package/dist/presentation/features/organisms/index.js +12 -12
  71. package/dist/presentation/features/templates/FeatureDataViewsTemplate/FeatureDataViewsTemplate.js +12 -12
  72. package/dist/presentation/features/templates/FeatureDataViewsTemplate/index.js +12 -12
  73. package/dist/presentation/features/templates/FeatureEventsTemplate/FeatureEventsTemplate.js +12 -12
  74. package/dist/presentation/features/templates/FeatureEventsTemplate/index.js +12 -12
  75. package/dist/presentation/features/templates/FeatureFormsTemplate/FeatureFormsTemplate.js +12 -12
  76. package/dist/presentation/features/templates/FeatureFormsTemplate/index.js +12 -12
  77. package/dist/presentation/features/templates/FeaturePresentationsTemplate/FeaturePresentationsTemplate.js +12 -12
  78. package/dist/presentation/features/templates/FeaturePresentationsTemplate/index.js +12 -12
  79. package/package.json +108 -24
  80. package/src/application/mcp/common.test.ts +64 -0
  81. package/src/application/mcp/common.ts +5 -2
  82. package/src/application/mcp/docsMcp.catalog.ts +2 -0
  83. package/src/application/mcp/docsMcp.data.ts +196 -0
  84. package/src/application/mcp/docsMcp.prompts.ts +165 -0
  85. package/src/application/mcp/docsMcp.reference.ts +152 -0
  86. package/src/application/mcp/docsMcp.resources.ts +194 -0
  87. package/src/application/mcp/docsMcp.test.ts +148 -0
  88. package/src/application/mcp/docsMcp.tools.ts +183 -0
  89. package/src/application/mcp/docsMcp.ts +13 -177
  90. package/src/application/mcp/normalizeMcpRequest.ts +30 -0
@@ -25,6 +25,25 @@ var authLogger = new Logger({
25
25
  enableContext: true,
26
26
  enableColors: false
27
27
  });
28
+ // src/application/mcp/normalizeMcpRequest.ts
29
+ var REQUIRED_ACCEPT_TYPES = ["application/json", "text/event-stream"];
30
+ function canNormalizeAcceptHeader(acceptHeader) {
31
+ return !acceptHeader || acceptHeader.includes("*/*") || acceptHeader.includes("application/*") || REQUIRED_ACCEPT_TYPES.some((value) => acceptHeader.includes(value));
32
+ }
33
+ function normalizeMcpRequest(request) {
34
+ if (request.method !== "POST")
35
+ return request;
36
+ const acceptHeader = request.headers.get("accept");
37
+ if (!canNormalizeAcceptHeader(acceptHeader))
38
+ return request;
39
+ const missingTypes = REQUIRED_ACCEPT_TYPES.filter((value) => !acceptHeader?.includes(value));
40
+ if (missingTypes.length === 0)
41
+ return request;
42
+ const headers = new Headers(request.headers);
43
+ headers.set("accept", [acceptHeader, ...missingTypes].filter(Boolean).join(", "));
44
+ return new Request(request, { headers });
45
+ }
46
+
28
47
  // src/application/mcp/common.ts
29
48
  import { randomUUID } from "node:crypto";
30
49
  import { createMcpServer } from "@contractspec/lib.contracts-runtime-server-mcp/provider-mcp";
@@ -120,7 +139,7 @@ function createMcpElysiaHandler({
120
139
  stateful: false
121
140
  });
122
141
  try {
123
- return await state.transport.handleRequest(request);
142
+ return await state.transport.handleRequest(normalizeMcpRequest(request));
124
143
  } finally {
125
144
  await closeSessionState(state);
126
145
  }
@@ -156,7 +175,7 @@ function createMcpElysiaHandler({
156
175
  createdState = true;
157
176
  }
158
177
  try {
159
- const response = await state.transport.handleRequest(request);
178
+ const response = await state.transport.handleRequest(normalizeMcpRequest(request));
160
179
  const activeSessionId = state.transport.sessionId;
161
180
  if (activeSessionId && !sessions.has(activeSessionId)) {
162
181
  sessions.set(activeSessionId, state);
@@ -763,90 +782,393 @@ function createContractsMcpHandler(path2 = "/api/mcp/contracts", services) {
763
782
  });
764
783
  }
765
784
 
766
- // src/features/docs/docs.contracts.ts
785
+ // src/application/mcp/docsMcp.data.ts
786
+ import { defaultDocRegistry } from "@contractspec/lib.contracts-spec/docs";
787
+ var DEFAULT_LIMIT = 20;
788
+ var MAX_LIMIT = 100;
789
+ function normalizeText(value) {
790
+ return value?.trim().toLowerCase() ?? "";
791
+ }
792
+ function normalizeRoute(route) {
793
+ const decoded = decodeURIComponent(route).trim();
794
+ if (!decoded)
795
+ return "/";
796
+ return decoded.startsWith("/") ? decoded : `/${decoded}`;
797
+ }
798
+ function normalizeTags(value) {
799
+ const tags = Array.isArray(value) ? value : value ? [value] : [];
800
+ return tags.map((tag) => normalizeText(tag)).filter(Boolean);
801
+ }
802
+ function clampLimit(limit) {
803
+ if (!limit || Number.isNaN(limit))
804
+ return DEFAULT_LIMIT;
805
+ return Math.min(Math.max(limit, 1), MAX_LIMIT);
806
+ }
807
+ function clampOffset(offset) {
808
+ if (!offset || Number.isNaN(offset))
809
+ return 0;
810
+ return Math.max(offset, 0);
811
+ }
812
+ function toDocSummary({ block, route }) {
813
+ return {
814
+ id: block.id,
815
+ title: block.title,
816
+ summary: block.summary ?? "",
817
+ route,
818
+ visibility: block.visibility ?? "public",
819
+ kind: block.kind ?? "reference",
820
+ version: block.version ?? "1.0.0",
821
+ tags: block.tags ?? []
822
+ };
823
+ }
824
+ function scoreDoc(route, query) {
825
+ if (!query)
826
+ return 1;
827
+ const tokens = query.split(/\s+/).filter(Boolean);
828
+ const title = normalizeText(route.block.title);
829
+ const id = normalizeText(route.block.id);
830
+ const summary = normalizeText(route.block.summary);
831
+ const body = normalizeText(route.block.body);
832
+ const path2 = normalizeText(route.route);
833
+ const tags = (route.block.tags ?? []).map((tag) => normalizeText(tag));
834
+ const haystack = [title, id, summary, body, path2, ...tags].join(" ");
835
+ if (tokens.some((token) => !haystack.includes(token)))
836
+ return 0;
837
+ let score = 0;
838
+ for (const token of tokens) {
839
+ if (id.includes(token))
840
+ score += 8;
841
+ if (title.includes(token))
842
+ score += 7;
843
+ if (tags.some((tag) => tag.includes(token)))
844
+ score += 5;
845
+ if (summary.includes(token))
846
+ score += 4;
847
+ if (path2.includes(token))
848
+ score += 3;
849
+ if (body.includes(token))
850
+ score += 2;
851
+ }
852
+ return score;
853
+ }
854
+ function searchDocs(routes, args) {
855
+ const query = normalizeText(typeof args.query === "string" ? args.query : undefined);
856
+ const tags = normalizeTags(args.tag);
857
+ const visibility = normalizeText(typeof args.visibility === "string" ? args.visibility : undefined);
858
+ const kind = normalizeText(typeof args.kind === "string" ? args.kind : undefined);
859
+ const limit = clampLimit(typeof args.limit === "number" ? args.limit : undefined);
860
+ const offset = clampOffset(typeof args.offset === "number" ? args.offset : undefined);
861
+ const ranked = routes.map((route) => ({
862
+ doc: toDocSummary(route),
863
+ score: scoreDoc(route, query)
864
+ })).filter(({ doc, score }) => {
865
+ const matchesQuery = query ? score > 0 : true;
866
+ const matchesTags = tags.length ? tags.every((tag) => doc.tags.some((docTag) => normalizeText(docTag).includes(tag))) : true;
867
+ const matchesVisibility = visibility ? normalizeText(doc.visibility) === visibility : true;
868
+ const matchesKind = kind ? normalizeText(doc.kind) === kind : true;
869
+ return matchesQuery && matchesTags && matchesVisibility && matchesKind;
870
+ }).sort((left, right) => {
871
+ if (right.score !== left.score)
872
+ return right.score - left.score;
873
+ return left.doc.title.localeCompare(right.doc.title);
874
+ });
875
+ const docs = ranked.slice(offset, offset + limit).map(({ doc }) => doc);
876
+ const nextOffset = offset + docs.length < ranked.length ? offset + docs.length : undefined;
877
+ return {
878
+ docs,
879
+ items: docs,
880
+ total: ranked.length,
881
+ ...nextOffset != null ? { nextOffset } : {}
882
+ };
883
+ }
884
+ function getDocById(id) {
885
+ const normalizedId = decodeURIComponent(id);
886
+ const found = defaultDocRegistry.get(normalizedId);
887
+ if (!found)
888
+ return;
889
+ return {
890
+ doc: toDocSummary(found),
891
+ content: String(found.block.body ?? "")
892
+ };
893
+ }
894
+ function getDocByRoute(routes, routePath) {
895
+ const normalizedPath = normalizeRoute(routePath);
896
+ const found = routes.find((route) => normalizeRoute(route.route) === normalizedPath);
897
+ if (!found)
898
+ return;
899
+ return {
900
+ doc: toDocSummary(found),
901
+ content: String(found.block.body ?? "")
902
+ };
903
+ }
904
+ function listDocFacets(routes) {
905
+ const tags = new Map;
906
+ const kinds = new Map;
907
+ const visibilities = new Map;
908
+ for (const route of routes) {
909
+ const kind = route.block.kind ?? "reference";
910
+ const visibility = route.block.visibility ?? "public";
911
+ kinds.set(kind, (kinds.get(kind) ?? 0) + 1);
912
+ visibilities.set(visibility, (visibilities.get(visibility) ?? 0) + 1);
913
+ for (const tag of route.block.tags ?? []) {
914
+ tags.set(tag, (tags.get(tag) ?? 0) + 1);
915
+ }
916
+ }
917
+ const toEntries = (values, key) => [...values.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0])).map(([value, count]) => ({ [key]: value, count }));
918
+ return {
919
+ totalDocs: routes.length,
920
+ tags: toEntries(tags, "tag"),
921
+ kinds: toEntries(kinds, "kind"),
922
+ visibilities: toEntries(visibilities, "visibility")
923
+ };
924
+ }
925
+
926
+ // src/features/contracts-registry.ts
927
+ import {
928
+ EventRegistry,
929
+ OperationSpecRegistry as OperationSpecRegistry3
930
+ } from "@contractspec/lib.contracts-spec";
767
931
  import {
932
+ DataViewRegistry
933
+ } from "@contractspec/lib.contracts-spec/data-views";
934
+ import {
935
+ ContractReferenceDataView,
768
936
  ContractReferenceQuery,
769
- DocSummaryModel,
770
- DocsIndexInput,
771
- DocsIndexOutput,
937
+ DocsGenerateCommand,
938
+ DocsGeneratedEvent,
939
+ DocsIndexDataView,
772
940
  DocsIndexQuery,
773
- DocsIndexQuery as DocsIndexQuery2
941
+ DocsLayoutPresentation,
942
+ DocsPublishCommand,
943
+ DocsPublishedEvent,
944
+ DocsReferencePagePresentation,
945
+ DocsSearchForm,
946
+ ExampleCatalogDataView
774
947
  } from "@contractspec/lib.contracts-spec/docs";
775
- // src/application/mcp/docsMcp.ts
948
+ import { FormRegistry } from "@contractspec/lib.contracts-spec/forms";
776
949
  import {
777
- definePrompt as definePrompt3,
778
- defineResourceTemplate as defineResourceTemplate3,
779
- installOp as installOp3,
780
- OperationSpecRegistry as OperationSpecRegistry3,
781
- PromptRegistry as PromptRegistry3,
782
- ResourceRegistry as ResourceRegistry3
783
- } from "@contractspec/lib.contracts-spec";
784
- import { defaultDocRegistry } from "@contractspec/lib.contracts-spec/docs";
785
- import z3 from "zod";
786
- var DOC_OWNERS = ["@contractspec"];
787
- var DOC_TAGS = ["docs", "mcp"];
788
- function buildDocResources(routes) {
789
- const resources = new ResourceRegistry3;
790
- resources.register(defineResourceTemplate3({
791
- meta: {
792
- uriTemplate: "docs://list",
793
- title: "DocBlocks index",
794
- description: "All registered DocBlocks with route, visibility, tags, and summary.",
795
- mimeType: "application/json",
796
- tags: DOC_TAGS
950
+ PresentationRegistry as PresentationRegistry2
951
+ } from "@contractspec/lib.contracts-spec/presentations";
952
+ import {
953
+ serializeDataViewSpec,
954
+ serializeEventSpec,
955
+ serializeFormSpec,
956
+ serializeOperationSpec,
957
+ serializePresentationSpec
958
+ } from "@contractspec/lib.contracts-spec/serialization";
959
+ var operationRegistry = null;
960
+ function createContractSpecOperationRegistry() {
961
+ const registry = new OperationSpecRegistry3;
962
+ registry.register(DocsIndexQuery).register(ContractReferenceQuery).register(DocsGenerateCommand).register(DocsPublishCommand);
963
+ return registry;
964
+ }
965
+ function getContractSpecOperationRegistry() {
966
+ if (!operationRegistry) {
967
+ operationRegistry = createContractSpecOperationRegistry();
968
+ }
969
+ return operationRegistry;
970
+ }
971
+ function resolveOperationSpec(key, version) {
972
+ return getContractSpecOperationRegistry().get(key, version);
973
+ }
974
+ var eventRegistry = null;
975
+ function createContractSpecEventRegistry() {
976
+ const registry = new EventRegistry;
977
+ registry.register(DocsGeneratedEvent).register(DocsPublishedEvent);
978
+ return registry;
979
+ }
980
+ function getContractSpecEventRegistry() {
981
+ if (!eventRegistry) {
982
+ eventRegistry = createContractSpecEventRegistry();
983
+ }
984
+ return eventRegistry;
985
+ }
986
+ function resolveEventSpec(key, version) {
987
+ return getContractSpecEventRegistry().get(key, version);
988
+ }
989
+ var presentationRegistry = null;
990
+ function createContractSpecPresentationRegistry() {
991
+ const registry = new PresentationRegistry2;
992
+ registry.register(DocsLayoutPresentation).register(DocsReferencePagePresentation);
993
+ return registry;
994
+ }
995
+ function getContractSpecPresentationRegistry() {
996
+ if (!presentationRegistry) {
997
+ presentationRegistry = createContractSpecPresentationRegistry();
998
+ }
999
+ return presentationRegistry;
1000
+ }
1001
+ function resolvePresentationSpec(key, version) {
1002
+ return getContractSpecPresentationRegistry().get(key, version);
1003
+ }
1004
+ var dataViewRegistry = null;
1005
+ function createContractSpecDataViewRegistry() {
1006
+ const registry = new DataViewRegistry;
1007
+ registry.register(DocsIndexDataView).register(ContractReferenceDataView).register(ExampleCatalogDataView);
1008
+ return registry;
1009
+ }
1010
+ function getContractSpecDataViewRegistry() {
1011
+ if (!dataViewRegistry) {
1012
+ dataViewRegistry = createContractSpecDataViewRegistry();
1013
+ }
1014
+ return dataViewRegistry;
1015
+ }
1016
+ function resolveDataViewSpec(key, version) {
1017
+ return getContractSpecDataViewRegistry().get(key, version);
1018
+ }
1019
+ var formRegistry = null;
1020
+ function createContractSpecFormRegistry() {
1021
+ const registry = new FormRegistry;
1022
+ registry.register(DocsSearchForm);
1023
+ return registry;
1024
+ }
1025
+ function getContractSpecFormRegistry() {
1026
+ if (!formRegistry) {
1027
+ formRegistry = createContractSpecFormRegistry();
1028
+ }
1029
+ return formRegistry;
1030
+ }
1031
+ function resolveFormSpec(key, _version) {
1032
+ return getContractSpecFormRegistry().get(key);
1033
+ }
1034
+ function resolveSerializedOperationSpec(key, version) {
1035
+ const spec = resolveOperationSpec(key, version);
1036
+ return serializeOperationSpec(spec) ?? undefined;
1037
+ }
1038
+ function resolveSerializedEventSpec(key, version) {
1039
+ const spec = resolveEventSpec(key, version);
1040
+ return serializeEventSpec(spec) ?? undefined;
1041
+ }
1042
+ function resolveSerializedPresentationSpec(key, version) {
1043
+ const spec = resolvePresentationSpec(key, version);
1044
+ return serializePresentationSpec(spec) ?? undefined;
1045
+ }
1046
+ function resolveSerializedDataViewSpec(key, version) {
1047
+ const spec = resolveDataViewSpec(key, version);
1048
+ return serializeDataViewSpec(spec) ?? undefined;
1049
+ }
1050
+ function resolveSerializedFormSpec(key, version) {
1051
+ const spec = resolveFormSpec(key, version);
1052
+ return serializeFormSpec(spec) ?? undefined;
1053
+ }
1054
+ function resetContractSpecOperationRegistry() {
1055
+ operationRegistry = null;
1056
+ }
1057
+ function resetContractSpecEventRegistry() {
1058
+ eventRegistry = null;
1059
+ }
1060
+ function resetContractSpecPresentationRegistry() {
1061
+ presentationRegistry = null;
1062
+ }
1063
+ function resetContractSpecDataViewRegistry() {
1064
+ dataViewRegistry = null;
1065
+ }
1066
+ function resetContractSpecFormRegistry() {
1067
+ formRegistry = null;
1068
+ }
1069
+ function resetAllContractSpecRegistries() {
1070
+ resetContractSpecOperationRegistry();
1071
+ resetContractSpecEventRegistry();
1072
+ resetContractSpecPresentationRegistry();
1073
+ resetContractSpecDataViewRegistry();
1074
+ resetContractSpecFormRegistry();
1075
+ }
1076
+
1077
+ // src/application/mcp/docsMcp.reference.ts
1078
+ import { defaultDocRegistry as defaultDocRegistry2 } from "@contractspec/lib.contracts-spec/docs";
1079
+ function normalizeText2(value) {
1080
+ return value?.trim().toLowerCase() ?? "";
1081
+ }
1082
+ function routeFromDocIds(docIds) {
1083
+ for (const docId of docIds ?? []) {
1084
+ const doc = defaultDocRegistry2.get(docId);
1085
+ if (doc)
1086
+ return doc.route;
1087
+ }
1088
+ return;
1089
+ }
1090
+ function toReference(spec, type, schema, policy) {
1091
+ const title = spec.meta.title ?? spec.meta.key;
1092
+ const route = routeFromDocIds(spec.meta.docId);
1093
+ const description = spec.meta.description;
1094
+ return {
1095
+ key: spec.meta.key,
1096
+ version: spec.meta.version,
1097
+ type,
1098
+ title,
1099
+ description,
1100
+ markdown: [
1101
+ `# ${title}`,
1102
+ `- Key: ${spec.meta.key}`,
1103
+ `- Type: ${type}`,
1104
+ `- Version: ${spec.meta.version}`,
1105
+ route ? `- Docs route: ${route}` : "",
1106
+ description ? `
1107
+ ${description}` : ""
1108
+ ].filter(Boolean).join(`
1109
+ `),
1110
+ ...route ? { route } : {},
1111
+ ...schema ? { schema } : {},
1112
+ ...policy ? { policy } : {},
1113
+ tags: spec.meta.tags ?? [],
1114
+ owners: spec.meta.owners ?? [],
1115
+ stability: spec.meta.stability
1116
+ };
1117
+ }
1118
+ function resolveContractReference(args) {
1119
+ const includeSchema = args.includeSchema ?? false;
1120
+ const requestedType = normalizeText2(args.type);
1121
+ const operation = resolveOperationSpec(args.key, args.version);
1122
+ if (operation && (!requestedType || requestedType === "operation" || requestedType === operation.meta.kind)) {
1123
+ return {
1124
+ reference: toReference(operation, operation.meta.kind, includeSchema ? resolveSerializedOperationSpec(args.key, args.version) : undefined, operation.policy)
1125
+ };
1126
+ }
1127
+ const resolvers = [
1128
+ {
1129
+ type: "data-view",
1130
+ spec: resolveDataViewSpec(args.key, args.version),
1131
+ schema: includeSchema ? resolveSerializedDataViewSpec(args.key, args.version) : undefined
797
1132
  },
798
- input: z3.object({}),
799
- resolve: async () => {
800
- const docs = routes.map(({ block, route }) => ({
801
- id: block.id,
802
- title: block.title,
803
- summary: block.summary ?? "",
804
- tags: block.tags ?? [],
805
- visibility: block.visibility ?? "public",
806
- route
807
- }));
808
- return {
809
- uri: "docs://list",
810
- mimeType: "application/json",
811
- data: JSON.stringify(docs, null, 2)
812
- };
813
- }
814
- }));
815
- resources.register(defineResourceTemplate3({
816
- meta: {
817
- uriTemplate: "docs://doc/{id}",
818
- title: "DocBlock markdown",
819
- description: "Fetch DocBlock body by id as markdown.",
820
- mimeType: "text/markdown",
821
- tags: DOC_TAGS
1133
+ {
1134
+ type: "form",
1135
+ spec: resolveFormSpec(args.key, args.version),
1136
+ schema: includeSchema ? resolveSerializedFormSpec(args.key, args.version) : undefined
822
1137
  },
823
- input: z3.object({ id: z3.string() }),
824
- resolve: async ({ id }) => {
825
- const found = defaultDocRegistry.get(id);
826
- if (!found) {
827
- return {
828
- uri: `docs://doc/${encodeURIComponent(id)}`,
829
- mimeType: "text/plain",
830
- data: `DocBlock not found: ${id}`
831
- };
832
- }
1138
+ {
1139
+ type: "presentation",
1140
+ spec: resolvePresentationSpec(args.key, args.version),
1141
+ schema: includeSchema ? resolveSerializedPresentationSpec(args.key, args.version) : undefined
1142
+ },
1143
+ {
1144
+ type: "event",
1145
+ spec: resolveEventSpec(args.key, args.version),
1146
+ schema: includeSchema ? resolveSerializedEventSpec(args.key, args.version) : undefined
1147
+ }
1148
+ ];
1149
+ for (const candidate of resolvers) {
1150
+ if (candidate.spec && (!requestedType || requestedType === candidate.type)) {
833
1151
  return {
834
- uri: `docs://doc/${encodeURIComponent(id)}`,
835
- mimeType: "text/markdown",
836
- data: String(found.block.body ?? "")
1152
+ reference: toReference(candidate.spec, candidate.type, candidate.schema)
837
1153
  };
838
1154
  }
839
- }));
840
- return resources;
1155
+ }
1156
+ throw new Error(`Contract reference not found: ${args.key}`);
841
1157
  }
842
- function buildDocPrompts() {
1158
+
1159
+ // src/application/mcp/docsMcp.prompts.ts
1160
+ import { definePrompt as definePrompt3, PromptRegistry as PromptRegistry3 } from "@contractspec/lib.contracts-spec";
1161
+ import z3 from "zod";
1162
+ var DOC_OWNERS = ["@contractspec"];
1163
+ var DOC_TAGS = ["docs", "mcp"];
1164
+ function buildDocPrompts(routes) {
843
1165
  const prompts = new PromptRegistry3;
844
1166
  prompts.register(definePrompt3({
845
1167
  meta: {
846
1168
  key: "docs.navigator",
847
1169
  version: "1.0.0",
848
1170
  title: "Find relevant ContractSpec docs",
849
- description: "Guide agents to pick the right DocBlock by topic or tag.",
1171
+ description: "Guide agents to search, filter, and open the right ContractSpec docs.",
850
1172
  tags: DOC_TAGS,
851
1173
  stability: "beta",
852
1174
  owners: DOC_OWNERS
@@ -858,6 +1180,12 @@ function buildDocPrompts() {
858
1180
  required: false,
859
1181
  schema: z3.string().optional()
860
1182
  },
1183
+ {
1184
+ name: "kind",
1185
+ description: "Optional doc kind filter.",
1186
+ required: false,
1187
+ schema: z3.string().optional()
1188
+ },
861
1189
  {
862
1190
  name: "tag",
863
1191
  description: "Optional tag filter.",
@@ -867,82 +1195,429 @@ function buildDocPrompts() {
867
1195
  ],
868
1196
  input: z3.object({
869
1197
  topic: z3.string().optional(),
1198
+ kind: z3.string().optional(),
870
1199
  tag: z3.string().optional()
871
1200
  }),
872
- render: async ({ topic, tag }) => {
873
- const parts = [
1201
+ render: async ({ topic, kind, tag }) => {
1202
+ const matches = searchDocs(routes, {
1203
+ query: topic,
1204
+ kind,
1205
+ tag,
1206
+ limit: 3
1207
+ });
1208
+ const suggestedDocs = matches.docs.length ? matches.docs.map((doc) => `- ${doc.title} (${doc.id}) -> ${doc.route}`).join(`
1209
+ `) : "- No direct pre-match. Use docs_list_facets-v1_0_0 to browse tags and kinds.";
1210
+ return [
874
1211
  {
875
1212
  type: "text",
876
- text: `Use the docs index to choose DocBlocks. If a specific topic is provided, prefer docs whose id/title/summary match it.${topic ? ` Topic: ${topic}.` : ""}${tag ? ` Tag: ${tag}.` : ""}`
1213
+ text: [
1214
+ "Use docs_search-v1_0_0 first, then read docs://doc/{id} for the strongest matches.",
1215
+ "Use docs_resolve_route-v1_0_0 when the user already gives you a docs URL or route.",
1216
+ "Use docs_list_facets-v1_0_0 or docs://facets to browse the docs taxonomy before guessing.",
1217
+ topic ? `Topic: ${topic}` : "",
1218
+ kind ? `Kind: ${kind}` : "",
1219
+ tag ? `Tag: ${tag}` : "",
1220
+ "Suggested starting docs:",
1221
+ suggestedDocs
1222
+ ].filter(Boolean).join(`
1223
+ `)
877
1224
  },
878
1225
  {
879
1226
  type: "resource",
880
- uri: "docs://list",
1227
+ uri: "docs://index",
881
1228
  title: "DocBlocks index"
1229
+ },
1230
+ {
1231
+ type: "resource",
1232
+ uri: "docs://facets",
1233
+ title: "Docs facets"
1234
+ }
1235
+ ];
1236
+ }
1237
+ }));
1238
+ prompts.register(definePrompt3({
1239
+ meta: {
1240
+ key: "docs.reference.guide",
1241
+ version: "1.0.0",
1242
+ title: "Resolve a ContractSpec reference",
1243
+ description: "Guide agents to fetch the canonical reference payload for a ContractSpec surface.",
1244
+ tags: DOC_TAGS,
1245
+ stability: "beta",
1246
+ owners: DOC_OWNERS
1247
+ },
1248
+ args: [
1249
+ {
1250
+ name: "key",
1251
+ description: "ContractSpec key to resolve.",
1252
+ required: true,
1253
+ schema: z3.string()
1254
+ },
1255
+ {
1256
+ name: "version",
1257
+ description: "Optional version override.",
1258
+ required: false,
1259
+ schema: z3.string().optional()
1260
+ },
1261
+ {
1262
+ name: "type",
1263
+ description: "Optional surface type: command, query, form, data-view, presentation, event.",
1264
+ required: false,
1265
+ schema: z3.string().optional()
1266
+ }
1267
+ ],
1268
+ input: z3.object({
1269
+ key: z3.string(),
1270
+ version: z3.string().optional(),
1271
+ type: z3.string().optional()
1272
+ }),
1273
+ render: async ({ key, version, type }) => {
1274
+ const reference = resolveContractReference({
1275
+ key,
1276
+ version,
1277
+ type,
1278
+ includeSchema: true
1279
+ }).reference;
1280
+ return [
1281
+ {
1282
+ type: "text",
1283
+ text: [
1284
+ "Use docs_contract_reference-v1_0_0 when you need the canonical docs payload for a ContractSpec surface.",
1285
+ "Use docs_get-v1_0_0 only when you already know the exact DocBlock id and need raw markdown.",
1286
+ `Resolved key: ${reference.key}`,
1287
+ `Resolved type: ${reference.type}`,
1288
+ reference.route ? `Docs route: ${reference.route}` : "",
1289
+ `Resource URI: docs://contract-reference/${encodeURIComponent(key)}`
1290
+ ].filter(Boolean).join(`
1291
+ `)
1292
+ },
1293
+ {
1294
+ type: "resource",
1295
+ uri: `docs://contract-reference/${encodeURIComponent(key)}`,
1296
+ title: "Contract reference"
882
1297
  }
883
1298
  ];
884
- return parts;
885
1299
  }
886
1300
  }));
887
1301
  return prompts;
888
1302
  }
1303
+
1304
+ // src/application/mcp/docsMcp.resources.ts
1305
+ import {
1306
+ defineResourceTemplate as defineResourceTemplate3,
1307
+ ResourceRegistry as ResourceRegistry3
1308
+ } from "@contractspec/lib.contracts-spec";
1309
+ import z4 from "zod";
1310
+ var DOC_TAGS2 = ["docs", "mcp"];
1311
+ function buildDocResources(routes) {
1312
+ const resources = new ResourceRegistry3;
1313
+ const readDocIndex = (input) => searchDocs(routes, input);
1314
+ resources.register(defineResourceTemplate3({
1315
+ meta: {
1316
+ uriTemplate: "docs://index",
1317
+ title: "DocBlocks index",
1318
+ description: "Default ContractSpec docs index resource.",
1319
+ mimeType: "application/json",
1320
+ tags: DOC_TAGS2
1321
+ },
1322
+ input: z4.object({}),
1323
+ resolve: async () => ({
1324
+ uri: "docs://index",
1325
+ mimeType: "application/json",
1326
+ data: JSON.stringify(readDocIndex({}), null, 2)
1327
+ })
1328
+ }));
1329
+ resources.register(defineResourceTemplate3({
1330
+ meta: {
1331
+ uriTemplate: "docs://index{?query,tag,kind,visibility,limit,offset}",
1332
+ title: "DocBlocks index",
1333
+ description: "Search and paginate ContractSpec docs by query, tag, kind, or visibility.",
1334
+ mimeType: "application/json",
1335
+ tags: DOC_TAGS2
1336
+ },
1337
+ input: z4.object({
1338
+ query: z4.string().optional(),
1339
+ tag: z4.string().optional(),
1340
+ kind: z4.string().optional(),
1341
+ visibility: z4.string().optional(),
1342
+ limit: z4.coerce.number().optional(),
1343
+ offset: z4.coerce.number().optional()
1344
+ }),
1345
+ resolve: async (input) => ({
1346
+ uri: "docs://index",
1347
+ mimeType: "application/json",
1348
+ data: JSON.stringify(readDocIndex(input), null, 2)
1349
+ })
1350
+ }));
1351
+ resources.register(defineResourceTemplate3({
1352
+ meta: {
1353
+ uriTemplate: "docs://list",
1354
+ title: "DocBlocks index (legacy alias)",
1355
+ description: "Compatibility alias for the docs index resource.",
1356
+ mimeType: "application/json",
1357
+ tags: DOC_TAGS2
1358
+ },
1359
+ input: z4.object({}),
1360
+ resolve: async () => ({
1361
+ uri: "docs://list",
1362
+ mimeType: "application/json",
1363
+ data: JSON.stringify(readDocIndex({}), null, 2)
1364
+ })
1365
+ }));
1366
+ resources.register(defineResourceTemplate3({
1367
+ meta: {
1368
+ uriTemplate: "docs://doc/{id}",
1369
+ title: "Doc markdown",
1370
+ description: "Fetch a single DocBlock body by id as markdown.",
1371
+ mimeType: "text/markdown",
1372
+ tags: DOC_TAGS2
1373
+ },
1374
+ input: z4.object({ id: z4.string() }),
1375
+ resolve: async ({ id }) => {
1376
+ const found = getDocById(id);
1377
+ if (!found) {
1378
+ return {
1379
+ uri: `docs://doc/${encodeURIComponent(id)}`,
1380
+ mimeType: "text/plain",
1381
+ data: `DocBlock not found: ${id}`
1382
+ };
1383
+ }
1384
+ return {
1385
+ uri: `docs://doc/${encodeURIComponent(id)}`,
1386
+ mimeType: "text/markdown",
1387
+ data: found.content
1388
+ };
1389
+ }
1390
+ }));
1391
+ resources.register(defineResourceTemplate3({
1392
+ meta: {
1393
+ uriTemplate: "docs://route/{routePath}",
1394
+ title: "Doc by route",
1395
+ description: "Resolve a docs route to the matching DocBlock summary and body.",
1396
+ mimeType: "application/json",
1397
+ tags: DOC_TAGS2
1398
+ },
1399
+ input: z4.object({ routePath: z4.string() }),
1400
+ resolve: async ({ routePath }) => ({
1401
+ uri: `docs://route/${encodeURIComponent(routePath)}`,
1402
+ mimeType: "application/json",
1403
+ data: JSON.stringify(getDocByRoute(routes, routePath) ?? {
1404
+ error: "not_found",
1405
+ route: routePath
1406
+ }, null, 2)
1407
+ })
1408
+ }));
1409
+ resources.register(defineResourceTemplate3({
1410
+ meta: {
1411
+ uriTemplate: "docs://facets",
1412
+ title: "Docs facets",
1413
+ description: "Counts of available tags, kinds, and visibilities across docs.",
1414
+ mimeType: "application/json",
1415
+ tags: DOC_TAGS2
1416
+ },
1417
+ input: z4.object({}),
1418
+ resolve: async () => ({
1419
+ uri: "docs://facets",
1420
+ mimeType: "application/json",
1421
+ data: JSON.stringify(listDocFacets(routes), null, 2)
1422
+ })
1423
+ }));
1424
+ resources.register(defineResourceTemplate3({
1425
+ meta: {
1426
+ uriTemplate: "docs://contract-reference/{key}{?version,type,includeSchema}",
1427
+ title: "Contract reference",
1428
+ description: "Resolve a ContractSpec surface into a docs-ready reference payload.",
1429
+ mimeType: "application/json",
1430
+ tags: DOC_TAGS2
1431
+ },
1432
+ input: z4.object({
1433
+ key: z4.string(),
1434
+ version: z4.string().optional(),
1435
+ type: z4.string().optional(),
1436
+ includeSchema: z4.coerce.boolean().optional()
1437
+ }),
1438
+ resolve: async ({ key, version, type, includeSchema }) => ({
1439
+ uri: `docs://contract-reference/${encodeURIComponent(key)}`,
1440
+ mimeType: "application/json",
1441
+ data: JSON.stringify(resolveContractReference({ key, version, type, includeSchema }), null, 2)
1442
+ })
1443
+ }));
1444
+ return resources;
1445
+ }
1446
+
1447
+ // src/application/mcp/docsMcp.tools.ts
1448
+ import {
1449
+ defineCommand as defineCommand3,
1450
+ defineSchemaModel as defineSchemaModel3,
1451
+ installOp as installOp3,
1452
+ OperationSpecRegistry as OperationSpecRegistry4
1453
+ } from "@contractspec/lib.contracts-spec";
1454
+ import {
1455
+ ContractReferenceInput,
1456
+ ContractReferenceOutput,
1457
+ DocsIndexInput,
1458
+ DocsIndexOutput
1459
+ } from "@contractspec/lib.contracts-spec/docs";
1460
+ import { ScalarTypeEnum as ScalarTypeEnum3 } from "@contractspec/lib.schema";
1461
+ var DOC_OWNERS2 = ["@contractspec"];
1462
+ var DOC_TAGS3 = ["docs", "mcp"];
1463
+ var DocsGetInput = defineSchemaModel3({
1464
+ name: "DocsGetInput",
1465
+ fields: {
1466
+ id: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
1467
+ }
1468
+ });
1469
+ var DocsGetOutput = defineSchemaModel3({
1470
+ name: "DocsGetOutput",
1471
+ fields: {
1472
+ doc: { type: ScalarTypeEnum3.JSON(), isOptional: false },
1473
+ content: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
1474
+ }
1475
+ });
1476
+ var DocsResolveRouteInput = defineSchemaModel3({
1477
+ name: "DocsResolveRouteInput",
1478
+ fields: {
1479
+ route: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
1480
+ }
1481
+ });
1482
+ var DocsResolveRouteOutput = defineSchemaModel3({
1483
+ name: "DocsResolveRouteOutput",
1484
+ fields: {
1485
+ doc: { type: ScalarTypeEnum3.JSON(), isOptional: false },
1486
+ content: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
1487
+ }
1488
+ });
1489
+ var DocsFacetsInput = defineSchemaModel3({
1490
+ name: "DocsFacetsInput",
1491
+ fields: {}
1492
+ });
1493
+ var DocsFacetsOutput = defineSchemaModel3({
1494
+ name: "DocsFacetsOutput",
1495
+ fields: {
1496
+ facets: { type: ScalarTypeEnum3.JSON(), isOptional: false }
1497
+ }
1498
+ });
889
1499
  function buildDocOps(routes) {
890
- const registry = new OperationSpecRegistry3;
891
- installOp3(registry, DocsIndexQuery, async (args) => {
892
- const query = args.query?.toLowerCase().trim();
893
- const tagsFilter = args.tag?.map((t) => t.toLowerCase().trim()) ?? [];
894
- const visibility = args.visibility?.toLowerCase().trim();
895
- const docs = routes.map(({ block, route }) => ({
896
- id: block.id,
897
- title: block.title,
898
- summary: block.summary ?? "",
899
- tags: block.tags ?? [],
900
- visibility: (block.visibility ?? "public").toLowerCase(),
901
- route
902
- })).filter((doc) => {
903
- const matchesQuery = query ? doc.id.toLowerCase().includes(query) || doc.title.toLowerCase().includes(query) || doc.summary.toLowerCase().includes(query) : true;
904
- const matchesTags = tagsFilter.length ? tagsFilter.every((t) => doc.tags.some((tag) => tag.toLowerCase().includes(t))) : true;
905
- const matchesVisibility = visibility ? doc.visibility === visibility : true;
906
- return matchesQuery && matchesTags && matchesVisibility;
907
- });
908
- return {
909
- docs,
910
- items: docs,
911
- total: docs.length
912
- };
1500
+ const registry = new OperationSpecRegistry4;
1501
+ installOp3(registry, defineCommand3({
1502
+ meta: {
1503
+ key: "docs.search",
1504
+ version: "1.0.0",
1505
+ stability: "beta",
1506
+ owners: DOC_OWNERS2,
1507
+ tags: DOC_TAGS3,
1508
+ description: "Search ContractSpec docs by query, tag, kind, or visibility.",
1509
+ goal: "Find the most relevant DocBlocks without browsing the full corpus.",
1510
+ context: "Read-only docs MCP search surface."
1511
+ },
1512
+ io: { input: DocsIndexInput, output: DocsIndexOutput },
1513
+ policy: { auth: "anonymous" },
1514
+ transport: { mcp: { toolName: "docs_search-v1_0_0" } }
1515
+ }), async (args) => searchDocs(routes, args));
1516
+ installOp3(registry, defineCommand3({
1517
+ meta: {
1518
+ key: "docs.get",
1519
+ version: "1.0.0",
1520
+ stability: "beta",
1521
+ owners: DOC_OWNERS2,
1522
+ tags: DOC_TAGS3,
1523
+ description: "Read a single DocBlock by id.",
1524
+ goal: "Fetch the exact markdown content and metadata for a known doc id.",
1525
+ context: "Read-only docs MCP surface."
1526
+ },
1527
+ io: { input: DocsGetInput, output: DocsGetOutput },
1528
+ policy: { auth: "anonymous" },
1529
+ transport: { mcp: { toolName: "docs_get-v1_0_0" } }
1530
+ }), async ({ id }) => {
1531
+ const found = getDocById(id);
1532
+ if (!found)
1533
+ throw new Error(`DocBlock not found: ${id}`);
1534
+ return found;
913
1535
  });
1536
+ installOp3(registry, defineCommand3({
1537
+ meta: {
1538
+ key: "docs.resolveRoute",
1539
+ version: "1.0.0",
1540
+ stability: "beta",
1541
+ owners: DOC_OWNERS2,
1542
+ tags: DOC_TAGS3,
1543
+ description: "Resolve a docs route to the matching DocBlock.",
1544
+ goal: "Turn a route or URL path into a canonical doc id and markdown body.",
1545
+ context: "Read-only docs MCP surface."
1546
+ },
1547
+ io: { input: DocsResolveRouteInput, output: DocsResolveRouteOutput },
1548
+ policy: { auth: "anonymous" },
1549
+ transport: { mcp: { toolName: "docs_resolve_route-v1_0_0" } }
1550
+ }), async ({ route }) => {
1551
+ const found = getDocByRoute(routes, route);
1552
+ if (!found)
1553
+ throw new Error(`Doc route not found: ${route}`);
1554
+ return found;
1555
+ });
1556
+ installOp3(registry, defineCommand3({
1557
+ meta: {
1558
+ key: "docs.contract.lookup",
1559
+ version: "1.0.0",
1560
+ stability: "beta",
1561
+ owners: DOC_OWNERS2,
1562
+ tags: DOC_TAGS3,
1563
+ description: "Resolve a ContractSpec surface into a docs-ready reference payload.",
1564
+ goal: "Get canonical docs metadata, route, and optional schema for a spec key.",
1565
+ context: "Read-only docs MCP surface."
1566
+ },
1567
+ io: { input: ContractReferenceInput, output: ContractReferenceOutput },
1568
+ policy: { auth: "anonymous" },
1569
+ transport: { mcp: { toolName: "docs_contract_reference-v1_0_0" } }
1570
+ }), async (args) => resolveContractReference(args));
1571
+ installOp3(registry, defineCommand3({
1572
+ meta: {
1573
+ key: "docs.list.facets",
1574
+ version: "1.0.0",
1575
+ stability: "beta",
1576
+ owners: DOC_OWNERS2,
1577
+ tags: DOC_TAGS3,
1578
+ description: "List docs taxonomy facets such as tags, kinds, and visibilities.",
1579
+ goal: "Help agents browse the docs corpus before making targeted reads.",
1580
+ context: "Read-only docs MCP surface."
1581
+ },
1582
+ io: { input: DocsFacetsInput, output: DocsFacetsOutput },
1583
+ policy: { auth: "anonymous" },
1584
+ transport: { mcp: { toolName: "docs_list_facets-v1_0_0" } }
1585
+ }), async () => ({ facets: listDocFacets(routes) }));
914
1586
  return registry;
915
1587
  }
916
- function createDocsMcpHandler(path2 = "/api/mcp/docs") {
917
- const routes = defaultDocRegistry.list();
1588
+
1589
+ // src/application/mcp/docsMcp.ts
1590
+ import { defaultDocRegistry as defaultDocRegistry3 } from "@contractspec/lib.contracts-spec/docs";
1591
+ function createDocsMcpHandler(path2 = "/api/mcp/docs", options = {}) {
1592
+ const routes = defaultDocRegistry3.list();
918
1593
  return createMcpElysiaHandler({
919
1594
  logger: appLogger,
920
1595
  path: path2,
921
1596
  serverName: "contractspec-docs-mcp",
922
1597
  ops: buildDocOps(routes),
923
1598
  resources: buildDocResources(routes),
924
- prompts: buildDocPrompts(),
925
- presentations: routes.map(({ descriptor }) => descriptor)
1599
+ prompts: buildDocPrompts(routes),
1600
+ presentations: options.includePresentations ? routes.map(({ descriptor }) => descriptor) : undefined
926
1601
  });
927
1602
  }
928
1603
 
929
1604
  // src/application/mcp/internalMcp.ts
930
1605
  import {
931
- defineCommand as defineCommand3,
1606
+ defineCommand as defineCommand4,
932
1607
  definePrompt as definePrompt4,
933
1608
  defineResourceTemplate as defineResourceTemplate4,
934
1609
  installOp as installOp4,
935
- OperationSpecRegistry as OperationSpecRegistry4,
1610
+ OperationSpecRegistry as OperationSpecRegistry5,
936
1611
  PromptRegistry as PromptRegistry4,
937
1612
  ResourceRegistry as ResourceRegistry4
938
1613
  } from "@contractspec/lib.contracts-spec";
939
- import { defineSchemaModel as defineSchemaModel3, ScalarTypeEnum as ScalarTypeEnum3 } from "@contractspec/lib.schema";
1614
+ import { defineSchemaModel as defineSchemaModel4, ScalarTypeEnum as ScalarTypeEnum4 } from "@contractspec/lib.schema";
940
1615
  import {
941
1616
  getExample,
942
1617
  listExamples,
943
1618
  searchExamples
944
1619
  } from "@contractspec/module.examples";
945
- import z4 from "zod";
1620
+ import z5 from "zod";
946
1621
  var INTERNAL_TAGS = ["internal", "mcp"];
947
1622
  var INTERNAL_OWNERS = ["@contractspec"];
948
1623
  var ENDPOINTS = {
@@ -962,7 +1637,7 @@ function buildInternalResources() {
962
1637
  mimeType: "application/json",
963
1638
  tags: ["examples", ...INTERNAL_TAGS]
964
1639
  },
965
- input: z4.object({ q: z4.string().optional() }),
1640
+ input: z5.object({ q: z5.string().optional() }),
966
1641
  resolve: async ({ q }) => {
967
1642
  const items = q ? searchExamples(q) : [...listExamples()];
968
1643
  return {
@@ -980,7 +1655,7 @@ function buildInternalResources() {
980
1655
  mimeType: "application/json",
981
1656
  tags: ["examples", ...INTERNAL_TAGS]
982
1657
  },
983
- input: z4.object({ id: z4.string().min(1) }),
1658
+ input: z5.object({ id: z5.string().min(1) }),
984
1659
  resolve: async ({ id }) => {
985
1660
  const example = getExample(id);
986
1661
  if (!example) {
@@ -1005,7 +1680,7 @@ function buildInternalResources() {
1005
1680
  mimeType: "application/json",
1006
1681
  tags: INTERNAL_TAGS
1007
1682
  },
1008
- input: z4.object({}),
1683
+ input: z5.object({}),
1009
1684
  resolve: async () => ({
1010
1685
  uri: "internal://endpoints",
1011
1686
  mimeType: "application/json",
@@ -1020,7 +1695,7 @@ function buildInternalResources() {
1020
1695
  mimeType: "text/markdown",
1021
1696
  tags: INTERNAL_TAGS
1022
1697
  },
1023
- input: z4.object({}),
1698
+ input: z5.object({}),
1024
1699
  resolve: async () => ({
1025
1700
  uri: "internal://playbook",
1026
1701
  mimeType: "text/markdown",
@@ -1050,7 +1725,7 @@ function buildInternalPrompts() {
1050
1725
  stability: "beta"
1051
1726
  },
1052
1727
  args: [],
1053
- input: z4.object({}),
1728
+ input: z5.object({}),
1054
1729
  render: async () => [
1055
1730
  {
1056
1731
  type: "text",
@@ -1066,18 +1741,18 @@ function buildInternalPrompts() {
1066
1741
  return prompts;
1067
1742
  }
1068
1743
  function buildInternalOps() {
1069
- const registry = new OperationSpecRegistry4;
1070
- const InternalDescribeOutput = defineSchemaModel3({
1744
+ const registry = new OperationSpecRegistry5;
1745
+ const InternalDescribeOutput = defineSchemaModel4({
1071
1746
  name: "InternalDescribeOutput",
1072
1747
  fields: {
1073
1748
  endpoints: {
1074
- type: ScalarTypeEnum3.JSONObject(),
1749
+ type: ScalarTypeEnum4.JSONObject(),
1075
1750
  isOptional: false
1076
1751
  },
1077
- notes: { type: ScalarTypeEnum3.String_unsecure(), isOptional: false }
1752
+ notes: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false }
1078
1753
  }
1079
1754
  });
1080
- const describeSpec = defineCommand3({
1755
+ const describeSpec = defineCommand4({
1081
1756
  meta: {
1082
1757
  key: "internal_describe",
1083
1758
  version: "1.0.0",
@@ -1089,7 +1764,7 @@ function buildInternalOps() {
1089
1764
  context: "Used by internal MCP surface; read-only."
1090
1765
  },
1091
1766
  io: {
1092
- input: defineSchemaModel3({
1767
+ input: defineSchemaModel4({
1093
1768
  name: "InternalDescribeInput",
1094
1769
  fields: {}
1095
1770
  }),
@@ -1122,7 +1797,7 @@ import {
1122
1797
  definePrompt as definePrompt5,
1123
1798
  defineResourceTemplate as defineResourceTemplate5,
1124
1799
  installOp as installOp5,
1125
- OperationSpecRegistry as OperationSpecRegistry5,
1800
+ OperationSpecRegistry as OperationSpecRegistry6,
1126
1801
  PromptRegistry as PromptRegistry5,
1127
1802
  ResourceRegistry as ResourceRegistry5
1128
1803
  } from "@contractspec/lib.contracts-spec";
@@ -1137,9 +1812,9 @@ import {
1137
1812
  computeModelRankings,
1138
1813
  normalizeBenchmarkResults
1139
1814
  } from "@contractspec/lib.provider-ranking/scoring";
1140
- import z5 from "zod";
1141
- var TransportFilterSchema = z5.enum(["rest", "mcp", "webhook", "sdk"]).optional();
1142
- var AuthFilterSchema = z5.enum([
1815
+ import z6 from "zod";
1816
+ var TransportFilterSchema = z6.enum(["rest", "mcp", "webhook", "sdk"]).optional();
1817
+ var AuthFilterSchema = z6.enum([
1143
1818
  "api-key",
1144
1819
  "oauth2",
1145
1820
  "bearer",
@@ -1167,7 +1842,7 @@ function buildRankingResources() {
1167
1842
  mimeType: "application/json",
1168
1843
  tags: RANKING_TAGS
1169
1844
  },
1170
- input: z5.object({
1845
+ input: z6.object({
1171
1846
  transport: TransportFilterSchema,
1172
1847
  authMethod: AuthFilterSchema
1173
1848
  }),
@@ -1193,8 +1868,8 @@ function buildRankingResources() {
1193
1868
  mimeType: "application/json",
1194
1869
  tags: RANKING_TAGS
1195
1870
  },
1196
- input: z5.object({
1197
- dimension: z5.string(),
1871
+ input: z6.object({
1872
+ dimension: z6.string(),
1198
1873
  transport: TransportFilterSchema,
1199
1874
  authMethod: AuthFilterSchema
1200
1875
  }),
@@ -1221,7 +1896,7 @@ function buildRankingResources() {
1221
1896
  mimeType: "application/json",
1222
1897
  tags: RANKING_TAGS
1223
1898
  },
1224
- input: z5.object({ modelId: z5.string() }),
1899
+ input: z6.object({ modelId: z6.string() }),
1225
1900
  resolve: async ({ modelId }) => {
1226
1901
  const store = getStore();
1227
1902
  const profile = await store.getModelProfile(modelId);
@@ -1262,7 +1937,7 @@ function buildRankingResources() {
1262
1937
  mimeType: "application/json",
1263
1938
  tags: RANKING_TAGS
1264
1939
  },
1265
- input: z5.object({}),
1940
+ input: z6.object({}),
1266
1941
  resolve: async () => {
1267
1942
  const store = getStore();
1268
1943
  const result = await store.listBenchmarkResults({ limit: 200 });
@@ -1292,13 +1967,13 @@ function buildRankingPrompts() {
1292
1967
  name: "task",
1293
1968
  description: "The task or use case to recommend a model for.",
1294
1969
  required: true,
1295
- schema: z5.string()
1970
+ schema: z6.string()
1296
1971
  },
1297
1972
  {
1298
1973
  name: "priority",
1299
1974
  description: "Priority dimension (coding, reasoning, cost, latency, etc.).",
1300
1975
  required: false,
1301
- schema: z5.string().optional()
1976
+ schema: z6.string().optional()
1302
1977
  },
1303
1978
  {
1304
1979
  name: "transport",
@@ -1313,9 +1988,9 @@ function buildRankingPrompts() {
1313
1988
  schema: AuthFilterSchema
1314
1989
  }
1315
1990
  ],
1316
- input: z5.object({
1317
- task: z5.string(),
1318
- priority: z5.string().optional(),
1991
+ input: z6.object({
1992
+ task: z6.string(),
1993
+ priority: z6.string().optional(),
1319
1994
  transport: TransportFilterSchema,
1320
1995
  authMethod: AuthFilterSchema
1321
1996
  }),
@@ -1343,7 +2018,7 @@ function buildRankingPrompts() {
1343
2018
  return prompts;
1344
2019
  }
1345
2020
  function buildRankingOps() {
1346
- const registry = new OperationSpecRegistry5;
2021
+ const registry = new OperationSpecRegistry6;
1347
2022
  const ingesterRegistry = createDefaultIngesterRegistry();
1348
2023
  installOp5(registry, BenchmarkIngestCommand, async (args) => {
1349
2024
  const store = getStore();