@sonordev/site-kit 4.2.3 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-manifest.json +11 -1
- package/dist/AnalyticsProvider-WRAJE62B.js +31 -0
- package/dist/{AnalyticsProvider-VSTTYP4W.js.map → AnalyticsProvider-WRAJE62B.js.map} +1 -1
- package/dist/AnalyticsProvider-YZAOPVAY.mjs +10 -0
- package/dist/{AnalyticsProvider-NW3UZYL5.mjs.map → AnalyticsProvider-YZAOPVAY.mjs.map} +1 -1
- package/dist/ChatWidget-NMZGPP7A.js +20 -0
- package/dist/{ChatWidget-BJOE2OSI.js.map → ChatWidget-NMZGPP7A.js.map} +1 -1
- package/dist/ChatWidget-ZI34F7JU.mjs +11 -0
- package/dist/{ChatWidget-EWQ7LRD4.mjs.map → ChatWidget-ZI34F7JU.mjs.map} +1 -1
- package/dist/EngageWidget-2U4EN7OP.js +18 -0
- package/dist/{EngageWidget-CZMNLFWI.js.map → EngageWidget-2U4EN7OP.js.map} +1 -1
- package/dist/EngageWidget-NI2BN6GO.mjs +9 -0
- package/dist/{EngageWidget-F427CI6Y.mjs.map → EngageWidget-NI2BN6GO.mjs.map} +1 -1
- package/dist/{FileField-5RVBU3Z4.mjs → FileField-I4UICUJF.mjs} +5 -5
- package/dist/{FileField-5RVBU3Z4.mjs.map → FileField-I4UICUJF.mjs.map} +1 -1
- package/dist/{FileField-Y4ZA7DST.js → FileField-UI6DAB3K.js} +6 -6
- package/dist/{FileField-Y4ZA7DST.js.map → FileField-UI6DAB3K.js.map} +1 -1
- package/dist/{FormSpotlight-MAEV6SZK.js → FormSpotlight-LO4BU6FY.js} +15 -15
- package/dist/{FormSpotlight-MAEV6SZK.js.map → FormSpotlight-LO4BU6FY.js.map} +1 -1
- package/dist/{FormSpotlight-CJPI2MRJ.mjs → FormSpotlight-RGFZMYPT.mjs} +3 -3
- package/dist/{FormSpotlight-CJPI2MRJ.mjs.map → FormSpotlight-RGFZMYPT.mjs.map} +1 -1
- package/dist/{FormStage-D42NAHSN.js → FormStage-NT5ZAH5Y.js} +13 -13
- package/dist/{FormStage-D42NAHSN.js.map → FormStage-NT5ZAH5Y.js.map} +1 -1
- package/dist/{FormStage-Z7WW3DNA.mjs → FormStage-RBXMNWM3.mjs} +3 -3
- package/dist/{FormStage-Z7WW3DNA.mjs.map → FormStage-RBXMNWM3.mjs.map} +1 -1
- package/dist/ManagedForm-CJOFGQK6.mjs +14 -0
- package/dist/{ManagedForm-A7BROQIN.mjs.map → ManagedForm-CJOFGQK6.mjs.map} +1 -1
- package/dist/ManagedForm-MKV5RM54.js +23 -0
- package/dist/{ManagedForm-Z3Z5Z6OL.js.map → ManagedForm-MKV5RM54.js.map} +1 -1
- package/dist/{SignalCore-77UH6PZ4.mjs → SignalCore-B2ZSLEXI.mjs} +5 -5
- package/dist/{SignalCore-77UH6PZ4.mjs.map → SignalCore-B2ZSLEXI.mjs.map} +1 -1
- package/dist/{SignalCore-NA6TJFVE.js → SignalCore-IX4L2TYS.js} +11 -11
- package/dist/{SignalCore-NA6TJFVE.js.map → SignalCore-IX4L2TYS.js.map} +1 -1
- package/dist/SitemapSync-2LLNO24P.mjs +8 -0
- package/dist/{SitemapSync-EY33A6P4.mjs.map → SitemapSync-2LLNO24P.mjs.map} +1 -1
- package/dist/SitemapSync-B2CY2JYM.js +17 -0
- package/dist/{SitemapSync-62F6HVAW.js.map → SitemapSync-B2CY2JYM.js.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +4 -4
- package/dist/{chunk-NEIUWAAL.js → chunk-2EA4DC2G.js} +5 -5
- package/dist/{chunk-NEIUWAAL.js.map → chunk-2EA4DC2G.js.map} +1 -1
- package/dist/chunk-2X5ZB5D7.mjs +6 -0
- package/dist/{chunk-XCFCG46K.mjs.map → chunk-2X5ZB5D7.mjs.map} +1 -1
- package/dist/{chunk-RDISSFEH.js → chunk-3AAFSXFC.js} +15 -15
- package/dist/{chunk-RDISSFEH.js.map → chunk-3AAFSXFC.js.map} +1 -1
- package/dist/{chunk-KL4MV6HK.mjs → chunk-3DFYFDGC.mjs} +3 -3
- package/dist/{chunk-KL4MV6HK.mjs.map → chunk-3DFYFDGC.mjs.map} +1 -1
- package/dist/{chunk-HVDKAR77.js → chunk-3KVG2PSJ.js} +7 -7
- package/dist/{chunk-HVDKAR77.js.map → chunk-3KVG2PSJ.js.map} +1 -1
- package/dist/{chunk-FZAAQE4Y.mjs → chunk-3ZD2XCLE.mjs} +4 -4
- package/dist/{chunk-FZAAQE4Y.mjs.map → chunk-3ZD2XCLE.mjs.map} +1 -1
- package/dist/{chunk-RRR6Y6Y5.mjs → chunk-5PBJ42NC.mjs} +4 -4
- package/dist/{chunk-RRR6Y6Y5.mjs.map → chunk-5PBJ42NC.mjs.map} +1 -1
- package/dist/{chunk-3P4HJAZA.mjs → chunk-5S735BSH.mjs} +4 -4
- package/dist/{chunk-3P4HJAZA.mjs.map → chunk-5S735BSH.mjs.map} +1 -1
- package/dist/{chunk-535HXGDU.mjs → chunk-6SN3ABID.mjs} +3 -3
- package/dist/{chunk-535HXGDU.mjs.map → chunk-6SN3ABID.mjs.map} +1 -1
- package/dist/{chunk-OHA43BNK.js → chunk-7X4LKAYJ.js} +14 -14
- package/dist/{chunk-OHA43BNK.js.map → chunk-7X4LKAYJ.js.map} +1 -1
- package/dist/{chunk-RCRDDMUO.mjs → chunk-ACL5FDJI.mjs} +3 -3
- package/dist/{chunk-RCRDDMUO.mjs.map → chunk-ACL5FDJI.mjs.map} +1 -1
- package/dist/{chunk-SL6ZGJVN.mjs → chunk-ANJBOE46.mjs} +4 -4
- package/dist/{chunk-SL6ZGJVN.mjs.map → chunk-ANJBOE46.mjs.map} +1 -1
- package/dist/{chunk-BN4AL7XB.js → chunk-BGIT5M27.js} +4 -4
- package/dist/{chunk-BN4AL7XB.js.map → chunk-BGIT5M27.js.map} +1 -1
- package/dist/{chunk-TFAYDIWM.mjs → chunk-DYDJ6NCM.mjs} +3 -3
- package/dist/{chunk-TFAYDIWM.mjs.map → chunk-DYDJ6NCM.mjs.map} +1 -1
- package/dist/{chunk-M2SEYO5J.js → chunk-F3MOVBEE.js} +7 -7
- package/dist/{chunk-M2SEYO5J.js.map → chunk-F3MOVBEE.js.map} +1 -1
- package/dist/{chunk-XA7RBHKT.js → chunk-FIVPS4Z6.js} +4 -4
- package/dist/{chunk-XA7RBHKT.js.map → chunk-FIVPS4Z6.js.map} +1 -1
- package/dist/{chunk-TKVADZFD.mjs → chunk-G5EETWKH.mjs} +4 -4
- package/dist/{chunk-TKVADZFD.mjs.map → chunk-G5EETWKH.mjs.map} +1 -1
- package/dist/{chunk-BX6FFL2Y.js → chunk-HXHDOIV6.js} +5 -5
- package/dist/{chunk-BX6FFL2Y.js.map → chunk-HXHDOIV6.js.map} +1 -1
- package/dist/{chunk-UDNXM6RB.mjs → chunk-IDSTSLMM.mjs} +3 -3
- package/dist/{chunk-UDNXM6RB.mjs.map → chunk-IDSTSLMM.mjs.map} +1 -1
- package/dist/{chunk-DZUOLOYS.mjs → chunk-IT76CWZ2.mjs} +3 -3
- package/dist/{chunk-DZUOLOYS.mjs.map → chunk-IT76CWZ2.mjs.map} +1 -1
- package/dist/{chunk-7BVZLSUJ.js → chunk-IW6S62NR.js} +8 -8
- package/dist/{chunk-7BVZLSUJ.js.map → chunk-IW6S62NR.js.map} +1 -1
- package/dist/{chunk-EHNUPEFY.mjs → chunk-IWFQPGA2.mjs} +7 -7
- package/dist/{chunk-EHNUPEFY.mjs.map → chunk-IWFQPGA2.mjs.map} +1 -1
- package/dist/{chunk-S5UATBC7.js → chunk-IWV72YOE.js} +14 -14
- package/dist/{chunk-S5UATBC7.js.map → chunk-IWV72YOE.js.map} +1 -1
- package/dist/{chunk-WCTOQFAN.js → chunk-IZVV36RT.js} +14 -14
- package/dist/{chunk-WCTOQFAN.js.map → chunk-IZVV36RT.js.map} +1 -1
- package/dist/{chunk-T3HGONNE.mjs → chunk-JBX6KV46.mjs} +4 -4
- package/dist/{chunk-T3HGONNE.mjs.map → chunk-JBX6KV46.mjs.map} +1 -1
- package/dist/{chunk-J6HWSJT7.mjs → chunk-JJTCVH4Q.mjs} +3 -3
- package/dist/{chunk-J6HWSJT7.mjs.map → chunk-JJTCVH4Q.mjs.map} +1 -1
- package/dist/{chunk-GDMOAGVS.js → chunk-K7QBRZLN.js} +18 -18
- package/dist/{chunk-GDMOAGVS.js.map → chunk-K7QBRZLN.js.map} +1 -1
- package/dist/{chunk-6D3HZKTZ.mjs → chunk-L4FHGCQ2.mjs} +3 -3
- package/dist/{chunk-6D3HZKTZ.mjs.map → chunk-L4FHGCQ2.mjs.map} +1 -1
- package/dist/{chunk-N5RTJNMN.js → chunk-LTALFZX7.js} +6 -6
- package/dist/{chunk-N5RTJNMN.js.map → chunk-LTALFZX7.js.map} +1 -1
- package/dist/{chunk-ZASFY4NR.mjs → chunk-LVMPYAOQ.mjs} +4 -4
- package/dist/{chunk-ZASFY4NR.mjs.map → chunk-LVMPYAOQ.mjs.map} +1 -1
- package/dist/{chunk-XOJYGBYF.js → chunk-NGAKS4WG.js} +3 -3
- package/dist/{chunk-XOJYGBYF.js.map → chunk-NGAKS4WG.js.map} +1 -1
- package/dist/{chunk-MP7ZYKMM.js → chunk-O4TMBV54.js} +8 -8
- package/dist/{chunk-MP7ZYKMM.js.map → chunk-O4TMBV54.js.map} +1 -1
- package/dist/{chunk-T6T5IQMN.mjs → chunk-OBRGUSGB.mjs} +3 -3
- package/dist/{chunk-T6T5IQMN.mjs.map → chunk-OBRGUSGB.mjs.map} +1 -1
- package/dist/{chunk-3DSGMX7P.js → chunk-OOBEJZJ5.js} +3 -3
- package/dist/{chunk-3DSGMX7P.js.map → chunk-OOBEJZJ5.js.map} +1 -1
- package/dist/{chunk-JJDY5XXG.js → chunk-PJZHIISA.js} +3 -3
- package/dist/{chunk-JJDY5XXG.js.map → chunk-PJZHIISA.js.map} +1 -1
- package/dist/{chunk-XWFUQMU6.mjs → chunk-QEHPIQYN.mjs} +3 -3
- package/dist/{chunk-XWFUQMU6.mjs.map → chunk-QEHPIQYN.mjs.map} +1 -1
- package/dist/{chunk-QJK2X3UK.js → chunk-R2O5VDNJ.js} +12 -12
- package/dist/{chunk-QJK2X3UK.js.map → chunk-R2O5VDNJ.js.map} +1 -1
- package/dist/{chunk-INA4NW3Y.mjs → chunk-RW76CJBS.mjs} +3 -3
- package/dist/{chunk-INA4NW3Y.mjs.map → chunk-RW76CJBS.mjs.map} +1 -1
- package/dist/{chunk-2XRGCDDG.js → chunk-SABYEM57.js} +9 -9
- package/dist/{chunk-2XRGCDDG.js.map → chunk-SABYEM57.js.map} +1 -1
- package/dist/{chunk-ZAVNGZJZ.js → chunk-SACGTFCK.js} +22 -6
- package/dist/chunk-SACGTFCK.js.map +1 -0
- package/dist/{chunk-SAR473OC.js → chunk-SM27DPML.js} +12 -12
- package/dist/{chunk-SAR473OC.js.map → chunk-SM27DPML.js.map} +1 -1
- package/dist/{chunk-HTLWSCUQ.mjs → chunk-SRJSR6YP.mjs} +22 -6
- package/dist/chunk-SRJSR6YP.mjs.map +1 -0
- package/dist/{chunk-NB4MK2Q5.js → chunk-SWIKKSKL.js} +3 -2
- package/dist/chunk-SWIKKSKL.js.map +1 -0
- package/dist/{chunk-GJKO2TZN.js → chunk-T6YDAJ5F.js} +4 -4
- package/dist/{chunk-GJKO2TZN.js.map → chunk-T6YDAJ5F.js.map} +1 -1
- package/dist/{chunk-MF6XLEX5.js → chunk-TBIWQQVF.js} +15 -15
- package/dist/{chunk-MF6XLEX5.js.map → chunk-TBIWQQVF.js.map} +1 -1
- package/dist/chunk-U3P4WF2A.js +8 -0
- package/dist/{chunk-S5L73KZQ.js.map → chunk-U3P4WF2A.js.map} +1 -1
- package/dist/{chunk-YWXZ4YLU.js → chunk-UDXWBLBH.js} +4 -4
- package/dist/{chunk-YWXZ4YLU.js.map → chunk-UDXWBLBH.js.map} +1 -1
- package/dist/{chunk-I7ORAWYT.mjs → chunk-UFT7IKDN.mjs} +4 -4
- package/dist/{chunk-I7ORAWYT.mjs.map → chunk-UFT7IKDN.mjs.map} +1 -1
- package/dist/{chunk-GU5OTUQS.mjs → chunk-VS67QHNX.mjs} +3 -3
- package/dist/{chunk-GU5OTUQS.mjs.map → chunk-VS67QHNX.mjs.map} +1 -1
- package/dist/{chunk-XR3MDDQT.mjs → chunk-XPNOM353.mjs} +3 -3
- package/dist/{chunk-XR3MDDQT.mjs.map → chunk-XPNOM353.mjs.map} +1 -1
- package/dist/{chunk-PTZB4ES3.mjs → chunk-YSLGMCQH.mjs} +8 -8
- package/dist/{chunk-PTZB4ES3.mjs.map → chunk-YSLGMCQH.mjs.map} +1 -1
- package/dist/{chunk-NI7OY4FW.mjs → chunk-ZN4HBK5C.mjs} +3 -2
- package/dist/chunk-ZN4HBK5C.mjs.map +1 -0
- package/dist/cli/index.js +36 -23
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +29 -16
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.js +5 -5
- package/dist/client/index.mjs +4 -4
- package/dist/commerce/index.js +56 -56
- package/dist/commerce/index.mjs +5 -5
- package/dist/engage/index.js +13 -13
- package/dist/engage/index.mjs +7 -7
- package/dist/fleet/index.js +8 -8
- package/dist/fleet/index.mjs +4 -4
- package/dist/forms/index.js +21 -21
- package/dist/forms/index.mjs +10 -10
- package/dist/forms/server.js +10 -10
- package/dist/forms/server.mjs +8 -8
- package/dist/forms/static.js +7 -7
- package/dist/forms/static.mjs +6 -6
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +63 -63
- package/dist/index.mjs +9 -9
- package/dist/layout/client.js +9 -9
- package/dist/layout/client.mjs +8 -8
- package/dist/layout/index.js +11 -11
- package/dist/layout/index.mjs +9 -9
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/mcp/WebMcpTools.d.ts +60 -0
- package/dist/mcp/WebMcpTools.d.ts.map +1 -0
- package/dist/mcp/client.d.ts +9 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +132 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/client.mjs +129 -0
- package/dist/mcp/client.mjs.map +1 -0
- package/dist/mcp/declarative.d.ts +77 -0
- package/dist/mcp/declarative.d.ts.map +1 -0
- package/dist/mcp/handlers.d.ts +92 -0
- package/dist/mcp/handlers.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +29 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +537 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/index.mjs +509 -0
- package/dist/mcp/index.mjs.map +1 -0
- package/dist/mcp/protocol.d.ts +140 -0
- package/dist/mcp/protocol.d.ts.map +1 -0
- package/dist/mcp/protocol.test.d.ts +2 -0
- package/dist/mcp/protocol.test.d.ts.map +1 -0
- package/dist/mcp/serverCard.d.ts +77 -0
- package/dist/mcp/serverCard.d.ts.map +1 -0
- package/dist/mcp/types.d.ts +154 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/og/config.d.ts +11 -1
- package/dist/og/config.d.ts.map +1 -1
- package/dist/og/index.js +5 -5
- package/dist/og/index.mjs +1 -1
- package/dist/og/pages.d.ts.map +1 -1
- package/dist/og/template.d.ts.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +5 -5
- package/dist/seo/client.mjs +4 -4
- package/dist/seo/index.js +5 -5
- package/dist/seo/index.mjs +4 -4
- package/dist/seo-pages/contract.js +6 -6
- package/dist/seo-pages/contract.mjs +2 -2
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/shared/build-entries.d.ts +4 -1
- package/dist/shared/build-entries.d.ts.map +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sites/contract.js +9 -9
- package/dist/sites/contract.mjs +2 -2
- package/dist/sites/normalize.d.ts +2 -1
- package/dist/sites/normalize.d.ts.map +1 -1
- package/dist/sync/index.js +16 -16
- package/dist/sync/index.mjs +4 -4
- package/package.json +11 -1
- package/dist/AnalyticsProvider-NW3UZYL5.mjs +0 -10
- package/dist/AnalyticsProvider-VSTTYP4W.js +0 -31
- package/dist/ChatWidget-BJOE2OSI.js +0 -20
- package/dist/ChatWidget-EWQ7LRD4.mjs +0 -11
- package/dist/EngageWidget-CZMNLFWI.js +0 -18
- package/dist/EngageWidget-F427CI6Y.mjs +0 -9
- package/dist/ManagedForm-A7BROQIN.mjs +0 -14
- package/dist/ManagedForm-Z3Z5Z6OL.js +0 -23
- package/dist/SitemapSync-62F6HVAW.js +0 -17
- package/dist/SitemapSync-EY33A6P4.mjs +0 -8
- package/dist/chunk-HTLWSCUQ.mjs.map +0 -1
- package/dist/chunk-NB4MK2Q5.js.map +0 -1
- package/dist/chunk-NI7OY4FW.mjs.map +0 -1
- package/dist/chunk-S5L73KZQ.js +0 -8
- package/dist/chunk-XCFCG46K.mjs +0 -6
- package/dist/chunk-ZAVNGZJZ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/types.ts","../../src/mcp/protocol.ts","../../src/mcp/serverCard.ts","../../src/mcp/handlers.ts","../../src/mcp/declarative.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit/mcp — shared types\n *\n * ONE tool definition, THREE surfaces. A `SiteKitMcpTool` is consumed by:\n *\n * 1. the remote MCP endpoint (`createMcpHandler`) — off-browser agents\n * 2. the in-page WebMCP API (`<WebMcpTools>`) — browser agents\n * 3. the MCP Server Card (`buildMcpServerCard`) — discovery only\n *\n * Keeping the definition in one shape is the whole point: the tool an agent\n * finds by crawling `/.well-known/mcp.json` and the tool it finds by driving a\n * browser to the page are the same tool, with the same schema and the same\n * handler. Two definitions would drift the way the two Square token refreshers\n * drifted (see the root CLAUDE.md \"Consolidate Duplicated Logic\" note).\n */\n\n// ============================================\n// JSON Schema (the subset MCP tool inputs use)\n// ============================================\n\n/** A JSON Schema node. Deliberately loose — MCP passes these through verbatim. */\nexport interface JsonSchemaNode {\n type?: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null'\n description?: string\n enum?: readonly (string | number | boolean | null)[]\n default?: unknown\n items?: JsonSchemaNode\n properties?: Record<string, JsonSchemaNode>\n required?: readonly string[]\n additionalProperties?: boolean | JsonSchemaNode\n minimum?: number\n maximum?: number\n minLength?: number\n maxLength?: number\n pattern?: string\n format?: string\n /** MCP 2026-07-28: mirror this param into an `Mcp-Param-{name}` HTTP header. */\n 'x-mcp-header'?: string\n [key: string]: unknown\n}\n\n/** Tool input schemas are always objects at the root, per the MCP spec. */\nexport interface JsonSchemaObject extends JsonSchemaNode {\n type: 'object'\n properties?: Record<string, JsonSchemaNode>\n required?: readonly string[]\n}\n\n// ============================================\n// Tool results\n// ============================================\n\nexport interface McpTextContent {\n type: 'text'\n text: string\n}\n\nexport interface McpResourceLinkContent {\n type: 'resource_link'\n uri: string\n name?: string\n description?: string\n mimeType?: string\n}\n\nexport type McpContent = McpTextContent | McpResourceLinkContent\n\nexport interface McpToolResult {\n content: McpContent[]\n /** Machine-readable payload. Agents prefer this over parsing `content`. */\n structuredContent?: unknown\n isError?: boolean\n}\n\n/**\n * What a handler may return. Anything that is not already an `McpToolResult`\n * is normalized by `toToolResult()`: objects become pretty JSON in a text block\n * AND are carried verbatim as `structuredContent`, so an agent can either read\n * the prose or consume the data.\n */\nexport type McpToolHandlerResult =\n | McpToolResult\n // `object` rather than `Record<string, unknown>` on purpose: a plain\n // `interface` has no index signature, so it does NOT satisfy Record and a\n // handler returning a typed shape would fail to compile for no good reason.\n | object\n | string\n | number\n | boolean\n | null\n\n/**\n * Behavioural hints. These are advisory — the spec is explicit that clients\n * must not make security decisions from them — but good agents use them to\n * decide what needs a human in the loop, so setting them honestly matters.\n */\nexport interface McpToolAnnotations {\n title?: string\n /** Tool does not modify anything. Every \"look something up\" tool is one. */\n readOnlyHint?: boolean\n /** Tool may perform irreversible updates. Anything creating a CRM record is. */\n destructiveHint?: boolean\n /** Calling twice with the same args changes nothing extra. */\n idempotentHint?: boolean\n /** Tool touches the open internet / third parties. */\n openWorldHint?: boolean\n}\n\n/** Context handed to every tool handler. */\nexport interface McpToolContext {\n /** Where the call came in from: the remote endpoint or the in-page API. */\n surface: 'http' | 'webmcp'\n /** Absolute site origin, e.g. `https://upforge.io`. */\n baseUrl?: string\n /** The originating Request, when the call arrived over HTTP. */\n request?: Request\n /** Negotiated protocol version, when known. */\n protocolVersion?: string\n /** Abort signal — WebMCP passes one; HTTP passes the request's. */\n signal?: AbortSignal\n}\n\nexport type McpToolHandler<Args = Record<string, unknown>> = (\n args: Args,\n context: McpToolContext,\n) => Promise<McpToolHandlerResult> | McpToolHandlerResult\n\n// ============================================\n// The tool definition\n// ============================================\n\nexport interface SiteKitMcpTool<Args = Record<string, unknown>> {\n /**\n * Machine name. Keep it `snake_case` and verb-led (`get_services`,\n * `request_site_audit`) — this is the string a model reasons about, and the\n * spec only SHOULDs header-safe characters, so stick to `[a-z0-9_]`.\n */\n name: string\n /** Human display name for tool pickers. */\n title?: string\n /**\n * What the tool does, in the voice of someone explaining it to a colleague.\n * This is the single highest-leverage field in the whole module: it is the\n * only thing a model reads when deciding whether to call the tool.\n */\n description: string\n inputSchema: JsonSchemaObject\n /** Optional schema for `structuredContent`. */\n outputSchema?: JsonSchemaObject\n annotations?: McpToolAnnotations\n handler: McpToolHandler<Args>\n /**\n * Set false to keep a tool off the in-page WebMCP surface while still\n * serving it from the remote endpoint (default: true). Useful for tools\n * whose handler needs server-only secrets.\n */\n exposeToWebMcp?: boolean\n /**\n * Set false to keep a tool off the remote HTTP endpoint while still\n * registering it in-page (default: true). Useful for tools that only make\n * sense against live DOM state.\n */\n exposeToHttp?: boolean\n}\n\n/** Identity-function helper: gives you inference + autocomplete on the schema. */\nexport function defineMcpTool<Args = Record<string, unknown>>(\n tool: SiteKitMcpTool<Args>,\n): SiteKitMcpTool<Args> {\n return tool\n}\n\n// ============================================\n// Server identity\n// ============================================\n\nexport interface McpServerInfo {\n /**\n * Reverse-DNS name with exactly one forward slash, per SEP-2127:\n * `io.upforge/site`. The part before the slash is a namespace you control.\n */\n name: string\n /** Semver. No ranges. */\n version: string\n /** Display name. */\n title?: string\n /** One or two sentences an agent reads before connecting. */\n description: string\n websiteUrl?: string\n /** Natural-language guidance for models on how to use this server well. */\n instructions?: string\n}\n\nexport interface McpServerIcon {\n src: string\n mimeType?: string\n sizes?: string\n theme?: 'light' | 'dark'\n}\n","/**\n * @sonordev/site-kit/mcp — MCP wire protocol (transport-agnostic)\n *\n * A dependency-free implementation of the server half of MCP, covering BOTH\n * protocol eras (the spec's own term — see /specification/2026-07-28/basic/versioning):\n *\n * modern (2026-07-28) stateless; every request carries its protocol version\n * in `_meta`, mirrored into the `MCP-Protocol-Version`\n * header. `server/discover` replaces the handshake.\n * No sessions, no GET stream.\n *\n * legacy (<= 2025-11-25) `initialize` handshake, then `tools/list`.\n * Still what most shipped clients and SDKs speak, so\n * dropping it would mean \"spec-compliant and unusable\".\n *\n * We deliberately do NOT depend on `@modelcontextprotocol/sdk`. The server\n * surface we need is a few hundred lines of JSON-RPC, and site-kit ships to\n * every marketing site in the fleet — an SDK in `dependencies` would land in\n * every one of those installs to save code we'd have to wrap anyway.\n *\n * This file is pure: it takes a parsed JSON-RPC message and returns a response\n * object. Anything HTTP-shaped lives in `handlers.ts`.\n */\n\nimport type {\n McpServerInfo,\n McpToolContext,\n McpToolResult,\n SiteKitMcpTool,\n} from './types'\n\n// ============================================\n// Protocol versions\n// ============================================\n\n/** Current revision: stateless, per-request `_meta`, `server/discover`. */\nexport const MCP_PROTOCOL_VERSION_MODERN = '2026-07-28'\n\n/**\n * Handshake-based revisions we still answer. Ordered newest-first — this is\n * also the preference order when a legacy client asks for something we don't\n * know, in which case the spec says to reply with our own best version.\n */\nexport const MCP_PROTOCOL_VERSIONS_LEGACY = ['2025-11-25', '2025-06-18', '2025-03-26'] as const\n\n/** Everything we accept, newest first. Advertised verbatim in errors. */\nexport const MCP_SUPPORTED_PROTOCOL_VERSIONS = [\n MCP_PROTOCOL_VERSION_MODERN,\n ...MCP_PROTOCOL_VERSIONS_LEGACY,\n] as const\n\n/** `_meta` keys defined by the modern revision. */\nexport const META_PROTOCOL_VERSION = 'io.modelcontextprotocol/protocolVersion'\nexport const META_CLIENT_INFO = 'io.modelcontextprotocol/clientInfo'\nexport const META_SERVER_INFO = 'io.modelcontextprotocol/serverInfo'\n\n// ============================================\n// JSON-RPC error codes\n// ============================================\n\nexport const JSONRPC_PARSE_ERROR = -32700\nexport const JSONRPC_INVALID_REQUEST = -32600\nexport const JSONRPC_METHOD_NOT_FOUND = -32601\nexport const JSONRPC_INVALID_PARAMS = -32602\nexport const JSONRPC_INTERNAL_ERROR = -32603\n/** MCP-defined: headers disagree with the body. */\nexport const MCP_ERROR_HEADER_MISMATCH = -32020\n/** MCP-defined: we don't speak the version the client asked for. */\nexport const MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION = -32022\n\n// ============================================\n// Message shapes\n// ============================================\n\nexport type JsonRpcId = string | number | null\n\nexport interface JsonRpcRequest {\n jsonrpc: '2.0'\n id?: JsonRpcId\n method: string\n params?: Record<string, unknown>\n}\n\nexport interface JsonRpcError {\n code: number\n message: string\n data?: unknown\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: '2.0'\n id: JsonRpcId\n result?: unknown\n error?: JsonRpcError\n}\n\n/**\n * A response plus the HTTP status the transport should use. The spec pins\n * specific statuses to specific errors (404 for unknown method, 400 for\n * version/header problems), so the status is part of the protocol, not a\n * transport detail the caller gets to invent.\n */\nexport interface DispatchOutcome {\n /** null for an accepted notification — the transport answers 202. */\n response: JsonRpcResponse | null\n status: number\n}\n\n// ============================================\n// Result normalization\n// ============================================\n\nconst MAX_JSON_TEXT = 60_000\n\nfunction isToolResult(value: unknown): value is McpToolResult {\n return (\n typeof value === 'object' &&\n value !== null &&\n Array.isArray((value as McpToolResult).content)\n )\n}\n\n/**\n * Normalize whatever a handler returned into a spec-shaped tool result.\n *\n * Structured data is emitted BOTH ways on purpose: as `structuredContent` for\n * agents that parse, and as pretty JSON inside a text block for agents (still\n * the majority) that only read `content`. Returning one or the other is how\n * you end up invisible to half the ecosystem.\n */\nexport function toToolResult(value: unknown): McpToolResult {\n if (isToolResult(value)) return value\n\n if (typeof value === 'string') {\n return { content: [{ type: 'text', text: value }] }\n }\n\n if (value === undefined || value === null) {\n return { content: [{ type: 'text', text: '(no result)' }] }\n }\n\n let text: string\n try {\n text = JSON.stringify(value, null, 2)\n } catch {\n text = String(value)\n }\n if (text.length > MAX_JSON_TEXT) {\n text = `${text.slice(0, MAX_JSON_TEXT)}\\n… (truncated)`\n }\n\n return {\n content: [{ type: 'text', text }],\n structuredContent: value,\n }\n}\n\nexport function toolErrorResult(message: string): McpToolResult {\n return { content: [{ type: 'text', text: message }], isError: true }\n}\n\n// ============================================\n// Tool descriptors\n// ============================================\n\nexport interface McpToolDescriptor {\n name: string\n title?: string\n description: string\n inputSchema: unknown\n outputSchema?: unknown\n annotations?: unknown\n}\n\n/** The public face of a tool — everything except the handler. */\nexport function toToolDescriptor(tool: SiteKitMcpTool<never>): McpToolDescriptor {\n const descriptor: McpToolDescriptor = {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n }\n if (tool.title) descriptor.title = tool.title\n if (tool.outputSchema) descriptor.outputSchema = tool.outputSchema\n if (tool.annotations) descriptor.annotations = tool.annotations\n return descriptor\n}\n\n// ============================================\n// Argument validation\n// ============================================\n\n/**\n * Minimal required-field + enum check.\n *\n * Intentionally shallow. A full JSON Schema validator is a dependency and a\n * maintenance surface, and the failure it would catch — a model inventing a\n * field — is better handled by the handler itself returning a helpful\n * `isError` result the model can read and retry against. What we DO enforce is\n * the part a model cannot recover from on its own: a missing required argument.\n */\nexport function validateArgs(\n tool: SiteKitMcpTool<never>,\n args: Record<string, unknown>,\n): string | null {\n const required = tool.inputSchema.required ?? []\n const missing = required.filter((key) => {\n const value = args[key]\n return value === undefined || value === null || value === ''\n })\n if (missing.length > 0) {\n return `Missing required argument${missing.length > 1 ? 's' : ''}: ${missing.join(', ')}.`\n }\n\n for (const [key, schema] of Object.entries(tool.inputSchema.properties ?? {})) {\n const value = args[key]\n if (value === undefined || value === null) continue\n if (schema.enum && !schema.enum.includes(value as string)) {\n return `Invalid value for \"${key}\": ${JSON.stringify(value)}. Expected one of: ${schema.enum\n .map((v) => JSON.stringify(v))\n .join(', ')}.`\n }\n }\n\n return null\n}\n\n// ============================================\n// Server definition\n// ============================================\n\nexport interface McpServerDefinition {\n info: McpServerInfo\n tools: SiteKitMcpTool<never>[]\n /** How long clients may cache `server/discover`, in ms. */\n discoverTtlMs?: number\n}\n\nfunction capabilities() {\n // `listChanged: false` is the honest answer for a statically-defined tool\n // set: there is no subscription stream to notify anyone on.\n return { tools: { listChanged: false } }\n}\n\nfunction serverInfoBlock(info: McpServerInfo) {\n return { name: info.name, version: info.version, ...(info.title ? { title: info.title } : {}) }\n}\n\n// ============================================\n// Version negotiation\n// ============================================\n\nexport function isSupportedVersion(version: string): boolean {\n return (MCP_SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(version)\n}\n\nfunction unsupportedVersionError(id: JsonRpcId, requested: string): DispatchOutcome {\n return {\n status: 400,\n response: {\n jsonrpc: '2.0',\n id,\n error: {\n code: MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION,\n message: 'Unsupported protocol version',\n data: { supported: [...MCP_SUPPORTED_PROTOCOL_VERSIONS], requested },\n },\n },\n }\n}\n\nexport function errorOutcome(\n id: JsonRpcId,\n code: number,\n message: string,\n status: number,\n data?: unknown,\n): DispatchOutcome {\n return {\n status,\n response: { jsonrpc: '2.0', id, error: { code, message, ...(data ? { data } : {}) } },\n }\n}\n\n// ============================================\n// Dispatch\n// ============================================\n\nexport interface DispatchOptions {\n server: McpServerDefinition\n context: Omit<McpToolContext, 'surface'>\n /**\n * Protocol version taken from the `MCP-Protocol-Version` header, if any.\n * Compared against the body's `_meta` value; a disagreement is a -32020.\n */\n headerProtocolVersion?: string | null\n /** `Mcp-Method` header, already base64-sentinel-decoded. */\n headerMethod?: string | null\n /** `Mcp-Name` header, already base64-sentinel-decoded. */\n headerName?: string | null\n /**\n * Reject modern requests that omit the required mirror headers.\n *\n * Off by default, and that is a considered choice rather than laziness: a\n * public marketing MCP server exists to be reachable, and today's shipped\n * clients overwhelmingly speak a legacy revision or omit the mirrors. We\n * always reject a header that *disagrees* with the body — that is the actual\n * security property the mirrors exist for (an intermediary routing on the\n * header while we execute the body). A merely absent header costs nothing.\n */\n strictHeaders?: boolean\n}\n\nexport async function dispatch(\n message: JsonRpcRequest,\n options: DispatchOptions,\n): Promise<DispatchOutcome> {\n const { server } = options\n const id = message.id ?? null\n const isNotification = message.id === undefined\n const params = (message.params ?? {}) as Record<string, unknown>\n const meta = (params._meta ?? {}) as Record<string, unknown>\n\n // ── Era detection ────────────────────────────────────────────────────────\n // A request is \"modern\" if it carries the per-request protocol version.\n const bodyVersion =\n typeof meta[META_PROTOCOL_VERSION] === 'string'\n ? (meta[META_PROTOCOL_VERSION] as string)\n : null\n const headerVersion = options.headerProtocolVersion || null\n\n if (bodyVersion && headerVersion && bodyVersion !== headerVersion) {\n return errorOutcome(\n id,\n MCP_ERROR_HEADER_MISMATCH,\n `Header mismatch: MCP-Protocol-Version header value '${headerVersion}' does not match body value '${bodyVersion}'`,\n 400,\n )\n }\n\n const requestedVersion = bodyVersion || headerVersion\n if (requestedVersion && !isSupportedVersion(requestedVersion)) {\n return unsupportedVersionError(id, requestedVersion)\n }\n\n // Mirror-header validation. A mismatch is always fatal; absence is fatal\n // only in strict mode (see DispatchOptions.strictHeaders).\n if (options.headerMethod && options.headerMethod !== message.method) {\n return errorOutcome(\n id,\n MCP_ERROR_HEADER_MISMATCH,\n `Header mismatch: Mcp-Method header value '${options.headerMethod}' does not match body value '${message.method}'`,\n 400,\n )\n }\n if (options.headerName) {\n const bodyName =\n typeof params.name === 'string'\n ? params.name\n : typeof params.uri === 'string'\n ? params.uri\n : null\n if (bodyName && options.headerName !== bodyName) {\n return errorOutcome(\n id,\n MCP_ERROR_HEADER_MISMATCH,\n `Header mismatch: Mcp-Name header value '${options.headerName}' does not match body value '${bodyName}'`,\n 400,\n )\n }\n }\n if (options.strictHeaders && bodyVersion) {\n if (!headerVersion) {\n return errorOutcome(\n id,\n MCP_ERROR_HEADER_MISMATCH,\n 'Header mismatch: required MCP-Protocol-Version header is missing',\n 400,\n )\n }\n if (!options.headerMethod) {\n return errorOutcome(\n id,\n MCP_ERROR_HEADER_MISMATCH,\n 'Header mismatch: required Mcp-Method header is missing',\n 400,\n )\n }\n }\n\n const negotiated = requestedVersion || MCP_PROTOCOL_VERSION_MODERN\n\n switch (message.method) {\n // ── Modern discovery (MUST implement) ──────────────────────────────────\n case 'server/discover': {\n return {\n status: 200,\n response: {\n jsonrpc: '2.0',\n id,\n result: {\n resultType: 'complete',\n supportedVersions: [...MCP_SUPPORTED_PROTOCOL_VERSIONS],\n capabilities: capabilities(),\n ...(server.info.instructions ? { instructions: server.info.instructions } : {}),\n ttlMs: server.discoverTtlMs ?? 3_600_000,\n cacheScope: 'public',\n _meta: { [META_SERVER_INFO]: serverInfoBlock(server.info) },\n },\n },\n }\n }\n\n // ── Legacy handshake ───────────────────────────────────────────────────\n case 'initialize': {\n // Echo the client's version when we speak it; otherwise answer with our\n // best legacy version. The spec asks modern-only servers to *name* their\n // versions here because legacy clients have no fall-forward path — we\n // support both eras, so we simply pick something mutually intelligible.\n const asked = typeof params.protocolVersion === 'string' ? params.protocolVersion : ''\n const agreed = isSupportedVersion(asked) ? asked : MCP_PROTOCOL_VERSIONS_LEGACY[0]\n return {\n status: 200,\n response: {\n jsonrpc: '2.0',\n id,\n result: {\n protocolVersion: agreed,\n capabilities: capabilities(),\n serverInfo: serverInfoBlock(server.info),\n ...(server.info.instructions ? { instructions: server.info.instructions } : {}),\n },\n },\n }\n }\n\n case 'notifications/initialized':\n case 'initialized':\n return { status: 202, response: null }\n\n case 'ping':\n return { status: 200, response: { jsonrpc: '2.0', id, result: {} } }\n\n // ── Tools ──────────────────────────────────────────────────────────────\n case 'tools/list': {\n const tools = server.tools\n .filter((t) => t.exposeToHttp !== false)\n .map((t) => toToolDescriptor(t))\n return { status: 200, response: { jsonrpc: '2.0', id, result: { tools } } }\n }\n\n case 'tools/call': {\n const name = typeof params.name === 'string' ? params.name : ''\n const tool = server.tools.find((t) => t.name === name && t.exposeToHttp !== false)\n\n if (!tool) {\n return errorOutcome(\n id,\n JSONRPC_INVALID_PARAMS,\n `Unknown tool: ${name || '(none)'}`,\n 400,\n {\n available: server.tools\n .filter((t) => t.exposeToHttp !== false)\n .map((t) => t.name),\n },\n )\n }\n\n const args = (params.arguments ?? {}) as Record<string, unknown>\n const invalid = validateArgs(tool, args)\n if (invalid) {\n // Returned as a tool result rather than a JSON-RPC error, on purpose:\n // an `isError` result goes back to the MODEL, which can read it and\n // retry with the right arguments. A protocol error goes to the client\n // harness and usually just surfaces as a failure.\n return {\n status: 200,\n response: { jsonrpc: '2.0', id, result: toolErrorResult(invalid) },\n }\n }\n\n try {\n const raw = await (tool.handler as (\n a: Record<string, unknown>,\n c: McpToolContext,\n ) => unknown)(args, {\n ...options.context,\n surface: 'http',\n protocolVersion: negotiated,\n })\n return { status: 200, response: { jsonrpc: '2.0', id, result: toToolResult(raw) } }\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error)\n return {\n status: 200,\n response: {\n jsonrpc: '2.0',\n id,\n result: toolErrorResult(`Tool \"${tool.name}\" failed: ${detail}`),\n },\n }\n }\n }\n\n // Declared unsupported rather than left to fall through, so the error names\n // the reason instead of looking like a typo'd method.\n case 'resources/list':\n return { status: 200, response: { jsonrpc: '2.0', id, result: { resources: [] } } }\n case 'prompts/list':\n return { status: 200, response: { jsonrpc: '2.0', id, result: { prompts: [] } } }\n\n default: {\n if (isNotification) return { status: 202, response: null }\n // 404 — the spec uses the status to distinguish an unknown METHOD on a\n // real MCP endpoint from a 404 for an endpoint that isn't there at all.\n return errorOutcome(id, JSONRPC_METHOD_NOT_FOUND, `Method not found: ${message.method}`, 404)\n }\n }\n}\n","/**\n * @sonordev/site-kit/mcp — MCP Server Card (SEP-2127)\n *\n * The card is a DISCOVERY document, not a capability manifest. SEP-2127 is\n * explicit that primitives (tools/resources/prompts) are omitted on purpose,\n * because what a server exposes can vary with auth state and feature flags —\n * the authoritative list is whatever `tools/list` returns at call time.\n *\n * So the card's job is small and specific: tell an agent that an MCP endpoint\n * exists here, what transport it speaks, and which protocol versions it knows,\n * with enough identity attached that a human reviewing the connection knows\n * what they're approving.\n *\n * ── The two paths ─────────────────────────────────────────────────────────\n * SEP-1649 originally proposed `/.well-known/mcp.json`. The ratified SEP-2127\n * moved to `/.well-known/mcp-server-card`. Plenty of deployed crawlers and\n * validators still probe the old path, and serving one JSON document from two\n * URLs costs nothing, so `createMcpServerCardHandler` is mounted at both.\n * `mcp-server-card` is the canonical one; `mcp.json` is compatibility.\n */\n\nimport type { McpServerIcon, McpServerInfo, SiteKitMcpTool } from './types'\nimport { MCP_SUPPORTED_PROTOCOL_VERSIONS } from './protocol'\n\nexport const MCP_SERVER_CARD_SCHEMA =\n 'https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json'\n\n/** Canonical well-known path (SEP-2127). */\nexport const MCP_SERVER_CARD_PATH = '/.well-known/mcp-server-card'\n/** Superseded SEP-1649 path, still widely probed. */\nexport const MCP_SERVER_CARD_LEGACY_PATH = '/.well-known/mcp.json'\n\n/**\n * Our own `_meta` namespace. `_meta` is the spec-sanctioned extension point,\n * and a reverse-DNS prefix is mandatory there, so a tool *summary* can ride\n * along without pretending to be a standard field. Agents that want the real\n * list still call `tools/list`; this is a hint for crawlers that never connect.\n */\nexport const SITE_KIT_CARD_META_KEY = 'io.sonor.site-kit/tools'\n\nexport interface McpRemote {\n type: 'streamable-http' | 'sse'\n url: string\n supportedProtocolVersions?: string[]\n headers?: {\n name: string\n description?: string\n isRequired?: boolean\n isSecret?: boolean\n default?: string\n choices?: string[]\n }[]\n}\n\nexport interface McpServerCard {\n $schema: string\n name: string\n version: string\n description: string\n title?: string\n websiteUrl?: string\n icons?: McpServerIcon[]\n remotes?: McpRemote[]\n _meta?: Record<string, unknown>\n}\n\nexport interface BuildMcpServerCardOptions {\n info: McpServerInfo\n /** Absolute site origin, e.g. `https://upforge.io` (no trailing slash). */\n baseUrl: string\n /** Path of the MCP endpoint on this origin (default `/api/mcp`). */\n mcpPath?: string\n icons?: McpServerIcon[]\n /** Supply the tool set to publish a name/description summary under `_meta`. */\n tools?: SiteKitMcpTool<never>[]\n /** Extra remotes (e.g. a second endpoint on another host). */\n additionalRemotes?: McpRemote[]\n}\n\nexport function buildMcpServerCard(options: BuildMcpServerCardOptions): McpServerCard {\n const base = options.baseUrl.replace(/\\/$/, '')\n const path = options.mcpPath ?? '/api/mcp'\n const mcpUrl = `${base}${path.startsWith('/') ? path : `/${path}`}`\n\n const card: McpServerCard = {\n $schema: MCP_SERVER_CARD_SCHEMA,\n name: options.info.name,\n version: options.info.version,\n description: options.info.description,\n remotes: [\n {\n type: 'streamable-http',\n url: mcpUrl,\n supportedProtocolVersions: [...MCP_SUPPORTED_PROTOCOL_VERSIONS],\n },\n ...(options.additionalRemotes ?? []),\n ],\n }\n\n if (options.info.title) card.title = options.info.title\n if (options.info.websiteUrl || base) card.websiteUrl = options.info.websiteUrl || base\n if (options.icons?.length) card.icons = options.icons\n\n const meta: Record<string, unknown> = {}\n if (options.info.instructions) {\n meta['io.sonor.site-kit/instructions'] = options.info.instructions\n }\n if (options.tools?.length) {\n meta[SITE_KIT_CARD_META_KEY] = options.tools\n .filter((t) => t.exposeToHttp !== false)\n .map((t) => ({\n name: t.name,\n ...(t.title ? { title: t.title } : {}),\n description: t.description,\n readOnly: t.annotations?.readOnlyHint ?? false,\n }))\n }\n if (Object.keys(meta).length > 0) card._meta = meta\n\n return card\n}\n\n/**\n * Validate a card against the parts of SEP-2127 that are actually checkable.\n * Returns human-readable problems; empty array means it looks conformant.\n * Used by the module's tests and worth calling in a site's own build check.\n */\nexport function validateMcpServerCard(card: McpServerCard): string[] {\n const problems: string[] = []\n\n if (card.$schema !== MCP_SERVER_CARD_SCHEMA) {\n problems.push(`$schema should be \"${MCP_SERVER_CARD_SCHEMA}\"`)\n }\n // Reverse-DNS with EXACTLY one slash. `io.upforge/site` is valid;\n // `upforge` and `io.upforge/site/mcp` are not.\n if (!/^[^/\\s]+\\/[^/\\s]+$/.test(card.name)) {\n problems.push(\n `name \"${card.name}\" must be reverse-DNS with exactly one forward slash, e.g. \"io.example/server\"`,\n )\n }\n if (!/^\\d+\\.\\d+\\.\\d+(?:[-+].+)?$/.test(card.version)) {\n problems.push(`version \"${card.version}\" should be a concrete semver (no ranges)`)\n }\n if (!card.description?.trim()) problems.push('description is required')\n\n for (const remote of card.remotes ?? []) {\n if (!/^https:\\/\\//.test(remote.url) && !/^http:\\/\\/localhost/.test(remote.url)) {\n problems.push(`remote url \"${remote.url}\" must be https (http allowed only on localhost)`)\n }\n }\n\n return problems\n}\n","/**\n * @sonordev/site-kit/mcp — Next.js route handlers (Streamable HTTP + card)\n *\n * Two things get mounted on a site:\n *\n * app/api/mcp/route.ts → createMcpHandler({ server })\n * app/.well-known/mcp-server-card/... → createMcpServerCardHandler({ ... })\n * app/.well-known/mcp.json/route.ts → the same handler (legacy path)\n *\n * The endpoint is stateless. Every request is self-describing, nothing is\n * cached between calls, and no session is minted — which is exactly what the\n * 2026-07-28 revision asks for and also the only thing that works on a\n * serverless host where consecutive requests hit different instances.\n */\n\nimport {\n dispatch,\n errorOutcome,\n JSONRPC_INVALID_REQUEST,\n JSONRPC_PARSE_ERROR,\n MCP_SUPPORTED_PROTOCOL_VERSIONS,\n MCP_PROTOCOL_VERSION_MODERN,\n type JsonRpcRequest,\n type McpServerDefinition,\n} from './protocol'\nimport {\n buildMcpServerCard,\n type BuildMcpServerCardOptions,\n type McpServerCard,\n} from './serverCard'\n\n// ============================================\n// CORS\n// ============================================\n\n/**\n * Headers the MCP wire uses. `Mcp-Session-Id` and `Last-Event-ID` are legacy\n * (dropped in 2026-07-28) but listed so an older client's preflight passes\n * rather than failing opaquely in the browser.\n */\nconst MCP_REQUEST_HEADERS = [\n 'Content-Type',\n 'Accept',\n 'Authorization',\n 'MCP-Protocol-Version',\n 'Mcp-Method',\n 'Mcp-Name',\n 'Mcp-Session-Id',\n 'Last-Event-ID',\n]\n\nfunction corsHeaders(origin: string): Record<string, string> {\n return {\n 'Access-Control-Allow-Origin': origin,\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': MCP_REQUEST_HEADERS.join(', '),\n 'Access-Control-Expose-Headers': 'MCP-Protocol-Version',\n 'Access-Control-Max-Age': '86400',\n }\n}\n\n// ============================================\n// Header decoding\n// ============================================\n\n/**\n * Undo the spec's Base64 sentinel wrapper: `=?base64?{b64}?=`.\n * Values that aren't wrapped come back untouched.\n */\nexport function decodeHeaderValue(value: string | null): string | null {\n if (!value) return value\n const match = /^=\\?base64\\?(.*)\\?=$/.exec(value)\n if (!match) return value\n try {\n if (typeof atob === 'function') {\n const binary = atob(match[1])\n const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0))\n return new TextDecoder().decode(bytes)\n }\n return Buffer.from(match[1], 'base64').toString('utf8')\n } catch {\n return value\n }\n}\n\n// ============================================\n// MCP endpoint\n// ============================================\n\nexport interface McpHandlerOptions {\n server: McpServerDefinition\n /** Absolute site origin, passed to every tool handler as context. */\n baseUrl?: string\n /**\n * Origins allowed to call the endpoint from a browser. Defaults to `*`.\n *\n * A public marketing MCP server is meant to be called by anyone's agent and\n * serves only data that is already on the public site, so the wildcard is\n * the correct setting, not a lapse. The DNS-rebinding attack the spec's\n * Origin rule defends against is about *localhost* servers, where the\n * browser can reach a private origin the attacker otherwise couldn't.\n * Set this explicitly for any endpoint that gains auth or writes.\n */\n allowedOrigins?: string[] | '*'\n /** Reject modern requests missing the mirror headers. See DispatchOptions. */\n strictHeaders?: boolean\n}\n\nexport interface McpRouteHandlers {\n POST: (request: Request) => Promise<Response>\n GET: (request: Request) => Promise<Response>\n DELETE: (request: Request) => Promise<Response>\n OPTIONS: (request: Request) => Promise<Response>\n}\n\nfunction resolveOrigin(request: Request, allowed: string[] | '*' | undefined): string | null {\n const origin = request.headers.get('origin')\n if (!allowed || allowed === '*') return '*'\n if (!origin) return allowed[0] ?? '*'\n return allowed.includes(origin) ? origin : null\n}\n\nfunction json(body: unknown, status: number, headers: Record<string, string>): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': 'no-store',\n ...headers,\n },\n })\n}\n\n/**\n * Create the Streamable HTTP MCP endpoint.\n *\n * @example\n * ```ts\n * // app/api/mcp/route.ts\n * import { createMcpHandler } from '@sonordev/site-kit/mcp'\n * import { mcpServer } from '@/lib/mcp/server'\n *\n * export const { POST, GET, DELETE, OPTIONS } = createMcpHandler({ server: mcpServer })\n * export const dynamic = 'force-dynamic'\n * ```\n */\nexport function createMcpHandler(options: McpHandlerOptions): McpRouteHandlers {\n const { server } = options\n\n async function POST(request: Request): Promise<Response> {\n const origin = resolveOrigin(request, options.allowedOrigins)\n if (origin === null) {\n // Spec: invalid Origin MUST be 403; the body MAY be a JSON-RPC error\n // with no id.\n return json(\n { jsonrpc: '2.0', error: { code: JSONRPC_INVALID_REQUEST, message: 'Origin not allowed' } },\n 403,\n {},\n )\n }\n const cors = corsHeaders(origin)\n\n let payload: unknown\n try {\n payload = await request.json()\n } catch {\n return json(\n { jsonrpc: '2.0', id: null, error: { code: JSONRPC_PARSE_ERROR, message: 'Parse error' } },\n 400,\n cors,\n )\n }\n\n const headerProtocolVersion = request.headers.get('mcp-protocol-version')\n const headerMethod = decodeHeaderValue(request.headers.get('mcp-method'))\n const headerName = decodeHeaderValue(request.headers.get('mcp-name'))\n\n const dispatchOptions = {\n server,\n context: {\n baseUrl: options.baseUrl,\n request,\n signal: request.signal,\n },\n headerProtocolVersion,\n headerMethod,\n headerName,\n strictHeaders: options.strictHeaders,\n }\n\n // The current revision says the body is a single message. Batching was\n // removed in 2025-06-18, but older clients still send arrays and answering\n // them is a few lines, so we do.\n if (Array.isArray(payload)) {\n const outcomes = await Promise.all(\n payload.map((m) => dispatch(m as JsonRpcRequest, dispatchOptions)),\n )\n const responses = outcomes.map((o) => o.response).filter(Boolean)\n if (responses.length === 0) return new Response(null, { status: 202, headers: cors })\n return json(responses, 200, {\n ...cors,\n 'MCP-Protocol-Version': headerProtocolVersion || MCP_PROTOCOL_VERSION_MODERN,\n })\n }\n\n const message = payload as JsonRpcRequest\n if (!message || typeof message !== 'object' || typeof message.method !== 'string') {\n const bad = errorOutcome(null, JSONRPC_INVALID_REQUEST, 'Invalid Request', 400)\n return json(bad.response, bad.status, cors)\n }\n\n const outcome = await dispatch(message, dispatchOptions)\n\n if (outcome.response === null) {\n // Accepted notification — 202 with no body, per the transport spec.\n return new Response(null, { status: 202, headers: cors })\n }\n\n return json(outcome.response, outcome.status, {\n ...cors,\n 'MCP-Protocol-Version': headerProtocolVersion || MCP_PROTOCOL_VERSION_MODERN,\n })\n }\n\n // 2026-07-28 removed the GET stream and DELETE session teardown. The spec\n // names 405 as the response a modern-only server gives older clients that\n // still try them.\n async function methodNotAllowed(request: Request): Promise<Response> {\n const origin = resolveOrigin(request, options.allowedOrigins) ?? '*'\n return new Response(\n JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: JSONRPC_INVALID_REQUEST,\n message:\n 'This MCP endpoint is stateless and accepts POST only. The GET stream and session teardown were removed in protocol revision 2026-07-28.',\n },\n }),\n {\n status: 405,\n headers: {\n 'Content-Type': 'application/json',\n Allow: 'POST, OPTIONS',\n ...corsHeaders(origin),\n },\n },\n )\n }\n\n async function OPTIONS(request: Request): Promise<Response> {\n const origin = resolveOrigin(request, options.allowedOrigins)\n if (origin === null) return new Response(null, { status: 403 })\n return new Response(null, { status: 204, headers: corsHeaders(origin) })\n }\n\n return { POST, GET: methodNotAllowed, DELETE: methodNotAllowed, OPTIONS }\n}\n\n// ============================================\n// Server card endpoint\n// ============================================\n\nexport interface McpServerCardHandlerOptions extends BuildMcpServerCardOptions {\n /** Seconds for `Cache-Control: public, max-age=…` (default 3600). */\n maxAge?: number\n}\n\nexport interface McpServerCardRouteHandlers {\n GET: () => Promise<Response>\n OPTIONS: () => Promise<Response>\n}\n\n/**\n * Serve the SEP-2127 server card. Mount at BOTH well-known paths.\n *\n * The handler never reads the incoming Request, so the route stays statically\n * prerenderable — the same constraint the llms.txt handlers document, and for\n * the same reason: touching `request.headers` opts the route into dynamic\n * rendering and it stops being served from the CDN.\n *\n * @example\n * ```ts\n * // app/.well-known/mcp-server-card/route.ts\n * import { createMcpServerCardHandler } from '@sonordev/site-kit/mcp'\n * import { mcpServer, SITE_URL } from '@/lib/mcp/server'\n *\n * export const { GET, OPTIONS } = createMcpServerCardHandler({\n * info: mcpServer.info,\n * tools: mcpServer.tools,\n * baseUrl: SITE_URL,\n * })\n * export const revalidate = 3600\n * ```\n */\nexport function createMcpServerCardHandler(\n options: McpServerCardHandlerOptions,\n): McpServerCardRouteHandlers {\n const card: McpServerCard = buildMcpServerCard(options)\n const body = `${JSON.stringify(card, null, 2)}\\n`\n const maxAge = options.maxAge ?? 3600\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Cache-Control': `public, max-age=${maxAge}`,\n // The card is a discovery document — it is meant to be fetched by anyone.\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n }\n\n return {\n GET: async () => new Response(body, { status: 200, headers }),\n OPTIONS: async () => new Response(null, { status: 204, headers }),\n }\n}\n\nexport { MCP_SUPPORTED_PROTOCOL_VERSIONS }\n","/**\n * @sonordev/site-kit/mcp — declarative WebMCP (forms as tools)\n *\n * The half of WebMCP that needs no JavaScript. A `<form>` carrying `toolname`\n * and `tooldescription` IS an agent tool: the browser synthesizes the input\n * schema from the form controls, and the agent fills and submits the real\n * form the human would have used.\n *\n * This matters more than the imperative API for one reason — there is exactly\n * one code path. The agent submits the same form, hits the same validation,\n * files the same CRM record. Nothing can drift, because there is nothing to\n * drift from.\n *\n * Attributes (per the W3C declarative-api explainer):\n * toolname on <form> — the tool's machine name\n * tooldescription on <form> — what it does\n * toolautosubmit on <form> — submit without waiting for the human\n * toolparamdescription on a control — describes that field in the schema\n *\n * These are plain HTML attributes; React 19 passes unknown lowercase\n * attributes straight through to the DOM, so the returned objects spread\n * directly onto JSX.\n */\n\nexport interface DeclarativeToolFormOptions {\n /** Machine name, `snake_case`. Match the remote tool it mirrors. */\n name: string\n /** What submitting this form accomplishes, in one sentence. */\n description: string\n /**\n * Let an agent submit without a human confirming.\n *\n * Default false, and leave it false for anything that creates a record,\n * sends a message, or spends money. A booking request or an audit request\n * should be something the person watching agrees to — `toolautosubmit` on a\n * lead form is how an agent files fifty of them by accident.\n */\n autoSubmit?: boolean\n}\n\nexport interface DeclarativeToolFormAttributes {\n toolname: string\n tooldescription: string\n toolautosubmit?: string\n}\n\n/**\n * Attributes that turn a `<form>` into an agent-callable tool.\n *\n * @example\n * ```tsx\n * <form {...declarativeToolForm({\n * name: 'request_site_audit',\n * description: 'Request a free technical SEO and performance audit of a website.',\n * })} action=\"/api/audit\" method=\"post\">\n * ```\n */\nexport function declarativeToolForm(\n options: DeclarativeToolFormOptions,\n): DeclarativeToolFormAttributes {\n const attributes: DeclarativeToolFormAttributes = {\n toolname: options.name,\n tooldescription: options.description,\n }\n // Boolean attribute: present means true. Omit it entirely for false —\n // `toolautosubmit=\"false\"` is still *present*, and so still true.\n if (options.autoSubmit) attributes.toolautosubmit = ''\n return attributes\n}\n\nexport interface DeclarativeToolFieldAttributes {\n toolparamdescription: string\n}\n\n/**\n * Describe one form control for the synthesized input schema.\n *\n * The control's `name` becomes the schema property and `required` marks it\n * required, so this only supplies the prose — but the prose is what the model\n * reads to decide what to put in the field.\n *\n * @example\n * ```tsx\n * <input\n * type=\"url\"\n * name=\"url\"\n * required\n * {...declarativeToolField('The full URL of the website to audit, including https://')}\n * />\n * ```\n */\nexport function declarativeToolField(description: string): DeclarativeToolFieldAttributes {\n return { toolparamdescription: description }\n}\n"]}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/mcp — MCP wire protocol (transport-agnostic)
|
|
3
|
+
*
|
|
4
|
+
* A dependency-free implementation of the server half of MCP, covering BOTH
|
|
5
|
+
* protocol eras (the spec's own term — see /specification/2026-07-28/basic/versioning):
|
|
6
|
+
*
|
|
7
|
+
* modern (2026-07-28) stateless; every request carries its protocol version
|
|
8
|
+
* in `_meta`, mirrored into the `MCP-Protocol-Version`
|
|
9
|
+
* header. `server/discover` replaces the handshake.
|
|
10
|
+
* No sessions, no GET stream.
|
|
11
|
+
*
|
|
12
|
+
* legacy (<= 2025-11-25) `initialize` handshake, then `tools/list`.
|
|
13
|
+
* Still what most shipped clients and SDKs speak, so
|
|
14
|
+
* dropping it would mean "spec-compliant and unusable".
|
|
15
|
+
*
|
|
16
|
+
* We deliberately do NOT depend on `@modelcontextprotocol/sdk`. The server
|
|
17
|
+
* surface we need is a few hundred lines of JSON-RPC, and site-kit ships to
|
|
18
|
+
* every marketing site in the fleet — an SDK in `dependencies` would land in
|
|
19
|
+
* every one of those installs to save code we'd have to wrap anyway.
|
|
20
|
+
*
|
|
21
|
+
* This file is pure: it takes a parsed JSON-RPC message and returns a response
|
|
22
|
+
* object. Anything HTTP-shaped lives in `handlers.ts`.
|
|
23
|
+
*/
|
|
24
|
+
import type { McpServerInfo, McpToolContext, McpToolResult, SiteKitMcpTool } from './types';
|
|
25
|
+
/** Current revision: stateless, per-request `_meta`, `server/discover`. */
|
|
26
|
+
export declare const MCP_PROTOCOL_VERSION_MODERN = "2026-07-28";
|
|
27
|
+
/**
|
|
28
|
+
* Handshake-based revisions we still answer. Ordered newest-first — this is
|
|
29
|
+
* also the preference order when a legacy client asks for something we don't
|
|
30
|
+
* know, in which case the spec says to reply with our own best version.
|
|
31
|
+
*/
|
|
32
|
+
export declare const MCP_PROTOCOL_VERSIONS_LEGACY: readonly ['2025-11-25', '2025-06-18', '2025-03-26'];
|
|
33
|
+
/** Everything we accept, newest first. Advertised verbatim in errors. */
|
|
34
|
+
export declare const MCP_SUPPORTED_PROTOCOL_VERSIONS: readonly ["2026-07-28", "2025-11-25", "2025-06-18", "2025-03-26"];
|
|
35
|
+
/** `_meta` keys defined by the modern revision. */
|
|
36
|
+
export declare const META_PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion";
|
|
37
|
+
export declare const META_CLIENT_INFO = "io.modelcontextprotocol/clientInfo";
|
|
38
|
+
export declare const META_SERVER_INFO = "io.modelcontextprotocol/serverInfo";
|
|
39
|
+
export declare const JSONRPC_PARSE_ERROR = -32700;
|
|
40
|
+
export declare const JSONRPC_INVALID_REQUEST = -32600;
|
|
41
|
+
export declare const JSONRPC_METHOD_NOT_FOUND = -32601;
|
|
42
|
+
export declare const JSONRPC_INVALID_PARAMS = -32602;
|
|
43
|
+
export declare const JSONRPC_INTERNAL_ERROR = -32603;
|
|
44
|
+
/** MCP-defined: headers disagree with the body. */
|
|
45
|
+
export declare const MCP_ERROR_HEADER_MISMATCH = -32020;
|
|
46
|
+
/** MCP-defined: we don't speak the version the client asked for. */
|
|
47
|
+
export declare const MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION = -32022;
|
|
48
|
+
export type JsonRpcId = string | number | null;
|
|
49
|
+
export interface JsonRpcRequest {
|
|
50
|
+
jsonrpc: '2.0';
|
|
51
|
+
id?: JsonRpcId;
|
|
52
|
+
method: string;
|
|
53
|
+
params?: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
export interface JsonRpcError {
|
|
56
|
+
code: number;
|
|
57
|
+
message: string;
|
|
58
|
+
data?: unknown;
|
|
59
|
+
}
|
|
60
|
+
export interface JsonRpcResponse {
|
|
61
|
+
jsonrpc: '2.0';
|
|
62
|
+
id: JsonRpcId;
|
|
63
|
+
result?: unknown;
|
|
64
|
+
error?: JsonRpcError;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A response plus the HTTP status the transport should use. The spec pins
|
|
68
|
+
* specific statuses to specific errors (404 for unknown method, 400 for
|
|
69
|
+
* version/header problems), so the status is part of the protocol, not a
|
|
70
|
+
* transport detail the caller gets to invent.
|
|
71
|
+
*/
|
|
72
|
+
export interface DispatchOutcome {
|
|
73
|
+
/** null for an accepted notification — the transport answers 202. */
|
|
74
|
+
response: JsonRpcResponse | null;
|
|
75
|
+
status: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Normalize whatever a handler returned into a spec-shaped tool result.
|
|
79
|
+
*
|
|
80
|
+
* Structured data is emitted BOTH ways on purpose: as `structuredContent` for
|
|
81
|
+
* agents that parse, and as pretty JSON inside a text block for agents (still
|
|
82
|
+
* the majority) that only read `content`. Returning one or the other is how
|
|
83
|
+
* you end up invisible to half the ecosystem.
|
|
84
|
+
*/
|
|
85
|
+
export declare function toToolResult(value: unknown): McpToolResult;
|
|
86
|
+
export declare function toolErrorResult(message: string): McpToolResult;
|
|
87
|
+
export interface McpToolDescriptor {
|
|
88
|
+
name: string;
|
|
89
|
+
title?: string;
|
|
90
|
+
description: string;
|
|
91
|
+
inputSchema: unknown;
|
|
92
|
+
outputSchema?: unknown;
|
|
93
|
+
annotations?: unknown;
|
|
94
|
+
}
|
|
95
|
+
/** The public face of a tool — everything except the handler. */
|
|
96
|
+
export declare function toToolDescriptor(tool: SiteKitMcpTool<never>): McpToolDescriptor;
|
|
97
|
+
/**
|
|
98
|
+
* Minimal required-field + enum check.
|
|
99
|
+
*
|
|
100
|
+
* Intentionally shallow. A full JSON Schema validator is a dependency and a
|
|
101
|
+
* maintenance surface, and the failure it would catch — a model inventing a
|
|
102
|
+
* field — is better handled by the handler itself returning a helpful
|
|
103
|
+
* `isError` result the model can read and retry against. What we DO enforce is
|
|
104
|
+
* the part a model cannot recover from on its own: a missing required argument.
|
|
105
|
+
*/
|
|
106
|
+
export declare function validateArgs(tool: SiteKitMcpTool<never>, args: Record<string, unknown>): string | null;
|
|
107
|
+
export interface McpServerDefinition {
|
|
108
|
+
info: McpServerInfo;
|
|
109
|
+
tools: SiteKitMcpTool<never>[];
|
|
110
|
+
/** How long clients may cache `server/discover`, in ms. */
|
|
111
|
+
discoverTtlMs?: number;
|
|
112
|
+
}
|
|
113
|
+
export declare function isSupportedVersion(version: string): boolean;
|
|
114
|
+
export declare function errorOutcome(id: JsonRpcId, code: number, message: string, status: number, data?: unknown): DispatchOutcome;
|
|
115
|
+
export interface DispatchOptions {
|
|
116
|
+
server: McpServerDefinition;
|
|
117
|
+
context: Omit<McpToolContext, 'surface'>;
|
|
118
|
+
/**
|
|
119
|
+
* Protocol version taken from the `MCP-Protocol-Version` header, if any.
|
|
120
|
+
* Compared against the body's `_meta` value; a disagreement is a -32020.
|
|
121
|
+
*/
|
|
122
|
+
headerProtocolVersion?: string | null;
|
|
123
|
+
/** `Mcp-Method` header, already base64-sentinel-decoded. */
|
|
124
|
+
headerMethod?: string | null;
|
|
125
|
+
/** `Mcp-Name` header, already base64-sentinel-decoded. */
|
|
126
|
+
headerName?: string | null;
|
|
127
|
+
/**
|
|
128
|
+
* Reject modern requests that omit the required mirror headers.
|
|
129
|
+
*
|
|
130
|
+
* Off by default, and that is a considered choice rather than laziness: a
|
|
131
|
+
* public marketing MCP server exists to be reachable, and today's shipped
|
|
132
|
+
* clients overwhelmingly speak a legacy revision or omit the mirrors. We
|
|
133
|
+
* always reject a header that *disagrees* with the body — that is the actual
|
|
134
|
+
* security property the mirrors exist for (an intermediary routing on the
|
|
135
|
+
* header while we execute the body). A merely absent header costs nothing.
|
|
136
|
+
*/
|
|
137
|
+
strictHeaders?: boolean;
|
|
138
|
+
}
|
|
139
|
+
export declare function dispatch(message: JsonRpcRequest, options: DispatchOptions): Promise<DispatchOutcome>;
|
|
140
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/mcp/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.test.d.ts","sourceRoot":"","sources":["../../src/mcp/protocol.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/mcp — MCP Server Card (SEP-2127)
|
|
3
|
+
*
|
|
4
|
+
* The card is a DISCOVERY document, not a capability manifest. SEP-2127 is
|
|
5
|
+
* explicit that primitives (tools/resources/prompts) are omitted on purpose,
|
|
6
|
+
* because what a server exposes can vary with auth state and feature flags —
|
|
7
|
+
* the authoritative list is whatever `tools/list` returns at call time.
|
|
8
|
+
*
|
|
9
|
+
* So the card's job is small and specific: tell an agent that an MCP endpoint
|
|
10
|
+
* exists here, what transport it speaks, and which protocol versions it knows,
|
|
11
|
+
* with enough identity attached that a human reviewing the connection knows
|
|
12
|
+
* what they're approving.
|
|
13
|
+
*
|
|
14
|
+
* ── The two paths ─────────────────────────────────────────────────────────
|
|
15
|
+
* SEP-1649 originally proposed `/.well-known/mcp.json`. The ratified SEP-2127
|
|
16
|
+
* moved to `/.well-known/mcp-server-card`. Plenty of deployed crawlers and
|
|
17
|
+
* validators still probe the old path, and serving one JSON document from two
|
|
18
|
+
* URLs costs nothing, so `createMcpServerCardHandler` is mounted at both.
|
|
19
|
+
* `mcp-server-card` is the canonical one; `mcp.json` is compatibility.
|
|
20
|
+
*/
|
|
21
|
+
import type { McpServerIcon, McpServerInfo, SiteKitMcpTool } from './types';
|
|
22
|
+
export declare const MCP_SERVER_CARD_SCHEMA = "https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json";
|
|
23
|
+
/** Canonical well-known path (SEP-2127). */
|
|
24
|
+
export declare const MCP_SERVER_CARD_PATH = "/.well-known/mcp-server-card";
|
|
25
|
+
/** Superseded SEP-1649 path, still widely probed. */
|
|
26
|
+
export declare const MCP_SERVER_CARD_LEGACY_PATH = "/.well-known/mcp.json";
|
|
27
|
+
/**
|
|
28
|
+
* Our own `_meta` namespace. `_meta` is the spec-sanctioned extension point,
|
|
29
|
+
* and a reverse-DNS prefix is mandatory there, so a tool *summary* can ride
|
|
30
|
+
* along without pretending to be a standard field. Agents that want the real
|
|
31
|
+
* list still call `tools/list`; this is a hint for crawlers that never connect.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SITE_KIT_CARD_META_KEY = "io.sonor.site-kit/tools";
|
|
34
|
+
export interface McpRemote {
|
|
35
|
+
type: 'streamable-http' | 'sse';
|
|
36
|
+
url: string;
|
|
37
|
+
supportedProtocolVersions?: string[];
|
|
38
|
+
headers?: {
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
isRequired?: boolean;
|
|
42
|
+
isSecret?: boolean;
|
|
43
|
+
default?: string;
|
|
44
|
+
choices?: string[];
|
|
45
|
+
}[];
|
|
46
|
+
}
|
|
47
|
+
export interface McpServerCard {
|
|
48
|
+
$schema: string;
|
|
49
|
+
name: string;
|
|
50
|
+
version: string;
|
|
51
|
+
description: string;
|
|
52
|
+
title?: string;
|
|
53
|
+
websiteUrl?: string;
|
|
54
|
+
icons?: McpServerIcon[];
|
|
55
|
+
remotes?: McpRemote[];
|
|
56
|
+
_meta?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
export interface BuildMcpServerCardOptions {
|
|
59
|
+
info: McpServerInfo;
|
|
60
|
+
/** Absolute site origin, e.g. `https://upforge.io` (no trailing slash). */
|
|
61
|
+
baseUrl: string;
|
|
62
|
+
/** Path of the MCP endpoint on this origin (default `/api/mcp`). */
|
|
63
|
+
mcpPath?: string;
|
|
64
|
+
icons?: McpServerIcon[];
|
|
65
|
+
/** Supply the tool set to publish a name/description summary under `_meta`. */
|
|
66
|
+
tools?: SiteKitMcpTool<never>[];
|
|
67
|
+
/** Extra remotes (e.g. a second endpoint on another host). */
|
|
68
|
+
additionalRemotes?: McpRemote[];
|
|
69
|
+
}
|
|
70
|
+
export declare function buildMcpServerCard(options: BuildMcpServerCardOptions): McpServerCard;
|
|
71
|
+
/**
|
|
72
|
+
* Validate a card against the parts of SEP-2127 that are actually checkable.
|
|
73
|
+
* Returns human-readable problems; empty array means it looks conformant.
|
|
74
|
+
* Used by the module's tests and worth calling in a site's own build check.
|
|
75
|
+
*/
|
|
76
|
+
export declare function validateMcpServerCard(card: McpServerCard): string[];
|
|
77
|
+
//# sourceMappingURL=serverCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverCard.d.ts","sourceRoot":"","sources":["../../src/mcp/serverCard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAG3E,eAAO,MAAM,sBAAsB,8EAC0C,CAAA;AAE7E,4CAA4C;AAC5C,eAAO,MAAM,oBAAoB,iCAAiC,CAAA;AAClE,qDAAqD;AACrD,eAAO,MAAM,2BAA2B,0BAA0B,CAAA;AAElE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,4BAA4B,CAAA;AAE/D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAA;IACpC,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,OAAO,CAAA;QACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KACnB,EAAE,CAAA;CACJ;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB,OAAO,CAAC,EAAE,SAAS,EAAE,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,aAAa,CAAA;IACnB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,CAAA;IAC/B,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,SAAS,EAAE,CAAA;CAChC;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,aAAa,CAyCpF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,EAAE,CAyBnE"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/mcp — shared types
|
|
3
|
+
*
|
|
4
|
+
* ONE tool definition, THREE surfaces. A `SiteKitMcpTool` is consumed by:
|
|
5
|
+
*
|
|
6
|
+
* 1. the remote MCP endpoint (`createMcpHandler`) — off-browser agents
|
|
7
|
+
* 2. the in-page WebMCP API (`<WebMcpTools>`) — browser agents
|
|
8
|
+
* 3. the MCP Server Card (`buildMcpServerCard`) — discovery only
|
|
9
|
+
*
|
|
10
|
+
* Keeping the definition in one shape is the whole point: the tool an agent
|
|
11
|
+
* finds by crawling `/.well-known/mcp.json` and the tool it finds by driving a
|
|
12
|
+
* browser to the page are the same tool, with the same schema and the same
|
|
13
|
+
* handler. Two definitions would drift the way the two Square token refreshers
|
|
14
|
+
* drifted (see the root CLAUDE.md "Consolidate Duplicated Logic" note).
|
|
15
|
+
*/
|
|
16
|
+
/** A JSON Schema node. Deliberately loose — MCP passes these through verbatim. */
|
|
17
|
+
export interface JsonSchemaNode {
|
|
18
|
+
type?: 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
|
|
19
|
+
description?: string;
|
|
20
|
+
enum?: readonly (string | number | boolean | null)[];
|
|
21
|
+
default?: unknown;
|
|
22
|
+
items?: JsonSchemaNode;
|
|
23
|
+
properties?: Record<string, JsonSchemaNode>;
|
|
24
|
+
required?: readonly string[];
|
|
25
|
+
additionalProperties?: boolean | JsonSchemaNode;
|
|
26
|
+
minimum?: number;
|
|
27
|
+
maximum?: number;
|
|
28
|
+
minLength?: number;
|
|
29
|
+
maxLength?: number;
|
|
30
|
+
pattern?: string;
|
|
31
|
+
format?: string;
|
|
32
|
+
/** MCP 2026-07-28: mirror this param into an `Mcp-Param-{name}` HTTP header. */
|
|
33
|
+
'x-mcp-header'?: string;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
/** Tool input schemas are always objects at the root, per the MCP spec. */
|
|
37
|
+
export interface JsonSchemaObject extends JsonSchemaNode {
|
|
38
|
+
type: 'object';
|
|
39
|
+
properties?: Record<string, JsonSchemaNode>;
|
|
40
|
+
required?: readonly string[];
|
|
41
|
+
}
|
|
42
|
+
export interface McpTextContent {
|
|
43
|
+
type: 'text';
|
|
44
|
+
text: string;
|
|
45
|
+
}
|
|
46
|
+
export interface McpResourceLinkContent {
|
|
47
|
+
type: 'resource_link';
|
|
48
|
+
uri: string;
|
|
49
|
+
name?: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
mimeType?: string;
|
|
52
|
+
}
|
|
53
|
+
export type McpContent = McpTextContent | McpResourceLinkContent;
|
|
54
|
+
export interface McpToolResult {
|
|
55
|
+
content: McpContent[];
|
|
56
|
+
/** Machine-readable payload. Agents prefer this over parsing `content`. */
|
|
57
|
+
structuredContent?: unknown;
|
|
58
|
+
isError?: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* What a handler may return. Anything that is not already an `McpToolResult`
|
|
62
|
+
* is normalized by `toToolResult()`: objects become pretty JSON in a text block
|
|
63
|
+
* AND are carried verbatim as `structuredContent`, so an agent can either read
|
|
64
|
+
* the prose or consume the data.
|
|
65
|
+
*/
|
|
66
|
+
export type McpToolHandlerResult = McpToolResult | object | string | number | boolean | null;
|
|
67
|
+
/**
|
|
68
|
+
* Behavioural hints. These are advisory — the spec is explicit that clients
|
|
69
|
+
* must not make security decisions from them — but good agents use them to
|
|
70
|
+
* decide what needs a human in the loop, so setting them honestly matters.
|
|
71
|
+
*/
|
|
72
|
+
export interface McpToolAnnotations {
|
|
73
|
+
title?: string;
|
|
74
|
+
/** Tool does not modify anything. Every "look something up" tool is one. */
|
|
75
|
+
readOnlyHint?: boolean;
|
|
76
|
+
/** Tool may perform irreversible updates. Anything creating a CRM record is. */
|
|
77
|
+
destructiveHint?: boolean;
|
|
78
|
+
/** Calling twice with the same args changes nothing extra. */
|
|
79
|
+
idempotentHint?: boolean;
|
|
80
|
+
/** Tool touches the open internet / third parties. */
|
|
81
|
+
openWorldHint?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** Context handed to every tool handler. */
|
|
84
|
+
export interface McpToolContext {
|
|
85
|
+
/** Where the call came in from: the remote endpoint or the in-page API. */
|
|
86
|
+
surface: 'http' | 'webmcp';
|
|
87
|
+
/** Absolute site origin, e.g. `https://upforge.io`. */
|
|
88
|
+
baseUrl?: string;
|
|
89
|
+
/** The originating Request, when the call arrived over HTTP. */
|
|
90
|
+
request?: Request;
|
|
91
|
+
/** Negotiated protocol version, when known. */
|
|
92
|
+
protocolVersion?: string;
|
|
93
|
+
/** Abort signal — WebMCP passes one; HTTP passes the request's. */
|
|
94
|
+
signal?: AbortSignal;
|
|
95
|
+
}
|
|
96
|
+
export type McpToolHandler<Args = Record<string, unknown>> = (args: Args, context: McpToolContext) => Promise<McpToolHandlerResult> | McpToolHandlerResult;
|
|
97
|
+
export interface SiteKitMcpTool<Args = Record<string, unknown>> {
|
|
98
|
+
/**
|
|
99
|
+
* Machine name. Keep it `snake_case` and verb-led (`get_services`,
|
|
100
|
+
* `request_site_audit`) — this is the string a model reasons about, and the
|
|
101
|
+
* spec only SHOULDs header-safe characters, so stick to `[a-z0-9_]`.
|
|
102
|
+
*/
|
|
103
|
+
name: string;
|
|
104
|
+
/** Human display name for tool pickers. */
|
|
105
|
+
title?: string;
|
|
106
|
+
/**
|
|
107
|
+
* What the tool does, in the voice of someone explaining it to a colleague.
|
|
108
|
+
* This is the single highest-leverage field in the whole module: it is the
|
|
109
|
+
* only thing a model reads when deciding whether to call the tool.
|
|
110
|
+
*/
|
|
111
|
+
description: string;
|
|
112
|
+
inputSchema: JsonSchemaObject;
|
|
113
|
+
/** Optional schema for `structuredContent`. */
|
|
114
|
+
outputSchema?: JsonSchemaObject;
|
|
115
|
+
annotations?: McpToolAnnotations;
|
|
116
|
+
handler: McpToolHandler<Args>;
|
|
117
|
+
/**
|
|
118
|
+
* Set false to keep a tool off the in-page WebMCP surface while still
|
|
119
|
+
* serving it from the remote endpoint (default: true). Useful for tools
|
|
120
|
+
* whose handler needs server-only secrets.
|
|
121
|
+
*/
|
|
122
|
+
exposeToWebMcp?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Set false to keep a tool off the remote HTTP endpoint while still
|
|
125
|
+
* registering it in-page (default: true). Useful for tools that only make
|
|
126
|
+
* sense against live DOM state.
|
|
127
|
+
*/
|
|
128
|
+
exposeToHttp?: boolean;
|
|
129
|
+
}
|
|
130
|
+
/** Identity-function helper: gives you inference + autocomplete on the schema. */
|
|
131
|
+
export declare function defineMcpTool<Args = Record<string, unknown>>(tool: SiteKitMcpTool<Args>): SiteKitMcpTool<Args>;
|
|
132
|
+
export interface McpServerInfo {
|
|
133
|
+
/**
|
|
134
|
+
* Reverse-DNS name with exactly one forward slash, per SEP-2127:
|
|
135
|
+
* `io.upforge/site`. The part before the slash is a namespace you control.
|
|
136
|
+
*/
|
|
137
|
+
name: string;
|
|
138
|
+
/** Semver. No ranges. */
|
|
139
|
+
version: string;
|
|
140
|
+
/** Display name. */
|
|
141
|
+
title?: string;
|
|
142
|
+
/** One or two sentences an agent reads before connecting. */
|
|
143
|
+
description: string;
|
|
144
|
+
websiteUrl?: string;
|
|
145
|
+
/** Natural-language guidance for models on how to use this server well. */
|
|
146
|
+
instructions?: string;
|
|
147
|
+
}
|
|
148
|
+
export interface McpServerIcon {
|
|
149
|
+
src: string;
|
|
150
|
+
mimeType?: string;
|
|
151
|
+
sizes?: string;
|
|
152
|
+
theme?: 'light' | 'dark';
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mcp/types.ts"],"names":[],"mappings":"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"}
|
package/dist/og/config.d.ts
CHANGED
|
@@ -58,6 +58,16 @@ export interface OgContent {
|
|
|
58
58
|
/** Bottom bar segments, e.g. ['Give an hour', 'ludlowpto.org']. */
|
|
59
59
|
bar?: string[];
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* A per-route entry in `cards`. Layered over the derived card, so it only
|
|
63
|
+
* states what differs — including inside `content`: a route can override just
|
|
64
|
+
* the subtitle and keep the title Sonor derived. The runtime always merged
|
|
65
|
+
* field by field; this type used to demand a full OgContent, which forced
|
|
66
|
+
* casts in every site that used the documented pattern.
|
|
67
|
+
*/
|
|
68
|
+
export type OgCardOverride = Partial<Omit<OgCardConfig, 'cards' | 'content'>> & {
|
|
69
|
+
content?: Partial<OgContent>;
|
|
70
|
+
};
|
|
61
71
|
export interface OgCardConfig {
|
|
62
72
|
theme: OgTheme;
|
|
63
73
|
/** First font = display face, second (optional) = hand/accent face. */
|
|
@@ -85,7 +95,7 @@ export interface OgCardConfig {
|
|
|
85
95
|
* Each entry is layered over the site card, so it only states what differs.
|
|
86
96
|
* Build-time only: never rendered as part of a card.
|
|
87
97
|
*/
|
|
88
|
-
cards?: Record<string,
|
|
98
|
+
cards?: Record<string, OgCardOverride>;
|
|
89
99
|
/**
|
|
90
100
|
* MIDDLE escape hatch: keep the loader/renderer/verifier pipeline but
|
|
91
101
|
* produce your own document. Receives the config and the same helpers the
|
package/dist/og/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/og/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAA;IACf,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,MAAM;IACrB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAA;IACb,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,OAAO;IACtB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;IACvD,0GAA0G;IAC1G,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,SAAS,CAAA;IAClB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/og/config.ts"],"names":[],"mappings":"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"}
|
package/dist/og/index.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkSACGTFCK_js = require('../chunk-SACGTFCK.js');
|
|
4
4
|
require('../chunk-SNAQBZPT.js');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "OG_HEIGHT", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkSACGTFCK_js.OG_HEIGHT; }
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(exports, "OG_WIDTH", {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunkSACGTFCK_js.OG_WIDTH; }
|
|
15
15
|
});
|
|
16
16
|
Object.defineProperty(exports, "buildOgHtml", {
|
|
17
17
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunkSACGTFCK_js.buildOgHtml; }
|
|
19
19
|
});
|
|
20
20
|
Object.defineProperty(exports, "defineOgCard", {
|
|
21
21
|
enumerable: true,
|
|
22
|
-
get: function () { return
|
|
22
|
+
get: function () { return chunkSACGTFCK_js.defineOgCard; }
|
|
23
23
|
});
|
|
24
24
|
//# sourceMappingURL=index.js.map
|
|
25
25
|
//# sourceMappingURL=index.js.map
|
package/dist/og/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { OG_HEIGHT, OG_WIDTH, buildOgHtml, defineOgCard } from '../chunk-
|
|
1
|
+
export { OG_HEIGHT, OG_WIDTH, buildOgHtml, defineOgCard } from '../chunk-SRJSR6YP.mjs';
|
|
2
2
|
import '../chunk-BEXTDHO4.mjs';
|
|
3
3
|
//# sourceMappingURL=index.mjs.map
|
|
4
4
|
//# sourceMappingURL=index.mjs.map
|