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