@atbas/m-mcp 0.1.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/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/builder/transaction-builder.d.ts +53 -0
- package/dist/builder/transaction-builder.d.ts.map +1 -0
- package/dist/builder/transaction-builder.js +159 -0
- package/dist/builder/transaction-builder.js.map +1 -0
- package/dist/catalogue/default-catalogue.d.ts +18 -0
- package/dist/catalogue/default-catalogue.d.ts.map +1 -0
- package/dist/catalogue/default-catalogue.js +21 -0
- package/dist/catalogue/default-catalogue.js.map +1 -0
- package/dist/catalogue/endpoints.d.ts +22 -0
- package/dist/catalogue/endpoints.d.ts.map +1 -0
- package/dist/catalogue/endpoints.js +24 -0
- package/dist/catalogue/endpoints.js.map +1 -0
- package/dist/catalogue/flows.d.ts +32 -0
- package/dist/catalogue/flows.d.ts.map +1 -0
- package/dist/catalogue/flows.js +64 -0
- package/dist/catalogue/flows.js.map +1 -0
- package/dist/catalogue/hash-options.d.ts +112 -0
- package/dist/catalogue/hash-options.d.ts.map +1 -0
- package/dist/catalogue/hash-options.js +151 -0
- package/dist/catalogue/hash-options.js.map +1 -0
- package/dist/catalogue/types.d.ts +279 -0
- package/dist/catalogue/types.d.ts.map +1 -0
- package/dist/catalogue/types.js +360 -0
- package/dist/catalogue/types.js.map +1 -0
- package/dist/codegen/generate.d.ts +14 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/generate.js +490 -0
- package/dist/codegen/generate.js.map +1 -0
- package/dist/codegen/languages/node.d.ts +3 -0
- package/dist/codegen/languages/node.d.ts.map +1 -0
- package/dist/codegen/languages/node.js +32 -0
- package/dist/codegen/languages/node.js.map +1 -0
- package/dist/codegen/languages/php.d.ts +3 -0
- package/dist/codegen/languages/php.d.ts.map +1 -0
- package/dist/codegen/languages/php.js +27 -0
- package/dist/codegen/languages/php.js.map +1 -0
- package/dist/codegen/languages/python.d.ts +3 -0
- package/dist/codegen/languages/python.d.ts.map +1 -0
- package/dist/codegen/languages/python.js +27 -0
- package/dist/codegen/languages/python.js.map +1 -0
- package/dist/codegen/renderer.d.ts +24 -0
- package/dist/codegen/renderer.d.ts.map +1 -0
- package/dist/codegen/renderer.js +59 -0
- package/dist/codegen/renderer.js.map +1 -0
- package/dist/codegen/types.d.ts +50 -0
- package/dist/codegen/types.d.ts.map +1 -0
- package/dist/codegen/types.js +5 -0
- package/dist/codegen/types.js.map +1 -0
- package/dist/config/credentials.d.ts +64 -0
- package/dist/config/credentials.d.ts.map +1 -0
- package/dist/config/credentials.js +216 -0
- package/dist/config/credentials.js.map +1 -0
- package/dist/config/environment.d.ts +23 -0
- package/dist/config/environment.d.ts.map +1 -0
- package/dist/config/environment.js +54 -0
- package/dist/config/environment.js.map +1 -0
- package/dist/core/dependencies.d.ts +43 -0
- package/dist/core/dependencies.d.ts.map +1 -0
- package/dist/core/dependencies.js +2 -0
- package/dist/core/dependencies.js.map +1 -0
- package/dist/core/registry.d.ts +33 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +13 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/server.d.ts +61 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +90 -0
- package/dist/core/server.js.map +1 -0
- package/dist/dependencies.d.ts +28 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +2 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/diagnostics/diagnose.d.ts +43 -0
- package/dist/diagnostics/diagnose.d.ts.map +1 -0
- package/dist/diagnostics/diagnose.js +121 -0
- package/dist/diagnostics/diagnose.js.map +1 -0
- package/dist/domain/amount.d.ts +157 -0
- package/dist/domain/amount.d.ts.map +1 -0
- package/dist/domain/amount.js +275 -0
- package/dist/domain/amount.js.map +1 -0
- package/dist/domain/datetime.d.ts +95 -0
- package/dist/domain/datetime.d.ts.map +1 -0
- package/dist/domain/datetime.js +211 -0
- package/dist/domain/datetime.js.map +1 -0
- package/dist/domain/response-codes.d.ts +116 -0
- package/dist/domain/response-codes.d.ts.map +1 -0
- package/dist/domain/response-codes.js +380 -0
- package/dist/domain/response-codes.js.map +1 -0
- package/dist/domain/secure-hash.d.ts +78 -0
- package/dist/domain/secure-hash.d.ts.map +1 -0
- package/dist/domain/secure-hash.js +69 -0
- package/dist/domain/secure-hash.js.map +1 -0
- package/dist/domain/signature/jazzcash.d.ts +56 -0
- package/dist/domain/signature/jazzcash.d.ts.map +1 -0
- package/dist/domain/signature/jazzcash.js +214 -0
- package/dist/domain/signature/jazzcash.js.map +1 -0
- package/dist/domain/signature/registry.d.ts +69 -0
- package/dist/domain/signature/registry.d.ts.map +1 -0
- package/dist/domain/signature/registry.js +92 -0
- package/dist/domain/signature/registry.js.map +1 -0
- package/dist/domain/signature/scheme.d.ts +349 -0
- package/dist/domain/signature/scheme.d.ts.map +1 -0
- package/dist/domain/signature/scheme.js +398 -0
- package/dist/domain/signature/scheme.js.map +1 -0
- package/dist/domain/txn-ref.d.ts +76 -0
- package/dist/domain/txn-ref.d.ts.map +1 -0
- package/dist/domain/txn-ref.js +126 -0
- package/dist/domain/txn-ref.js.map +1 -0
- package/dist/domain/types.d.ts +45 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +70 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/errors.d.ts +84 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +87 -0
- package/dist/errors.js.map +1 -0
- package/dist/gateway/checkout-form.d.ts +16 -0
- package/dist/gateway/checkout-form.d.ts.map +1 -0
- package/dist/gateway/checkout-form.js +103 -0
- package/dist/gateway/checkout-form.js.map +1 -0
- package/dist/gateway/checkout-output.d.ts +70 -0
- package/dist/gateway/checkout-output.d.ts.map +1 -0
- package/dist/gateway/checkout-output.js +199 -0
- package/dist/gateway/checkout-output.js.map +1 -0
- package/dist/gateway/guards.d.ts +37 -0
- package/dist/gateway/guards.d.ts.map +1 -0
- package/dist/gateway/guards.js +44 -0
- package/dist/gateway/guards.js.map +1 -0
- package/dist/gateway/http-client.d.ts +42 -0
- package/dist/gateway/http-client.d.ts.map +1 -0
- package/dist/gateway/http-client.js +153 -0
- package/dist/gateway/http-client.js.map +1 -0
- package/dist/gateway/rest-client.d.ts +42 -0
- package/dist/gateway/rest-client.d.ts.map +1 -0
- package/dist/gateway/rest-client.js +241 -0
- package/dist/gateway/rest-client.js.map +1 -0
- package/dist/gateway/transport.d.ts +31 -0
- package/dist/gateway/transport.d.ts.map +1 -0
- package/dist/gateway/transport.js +73 -0
- package/dist/gateway/transport.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/install/cli.d.ts +38 -0
- package/dist/install/cli.d.ts.map +1 -0
- package/dist/install/cli.js +274 -0
- package/dist/install/cli.js.map +1 -0
- package/dist/install/harnesses.d.ts +74 -0
- package/dist/install/harnesses.d.ts.map +1 -0
- package/dist/install/harnesses.js +263 -0
- package/dist/install/harnesses.js.map +1 -0
- package/dist/knowledge/corpus.d.ts +15 -0
- package/dist/knowledge/corpus.d.ts.map +1 -0
- package/dist/knowledge/corpus.js +129 -0
- package/dist/knowledge/corpus.js.map +1 -0
- package/dist/knowledge/search.d.ts +29 -0
- package/dist/knowledge/search.d.ts.map +1 -0
- package/dist/knowledge/search.js +181 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/knowledge/source.d.ts +60 -0
- package/dist/knowledge/source.d.ts.map +1 -0
- package/dist/knowledge/source.js +91 -0
- package/dist/knowledge/source.js.map +1 -0
- package/dist/knowledge/types.d.ts +40 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +19 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/paths.d.ts +26 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +106 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompts/integration-walkthrough.d.ts +11 -0
- package/dist/prompts/integration-walkthrough.d.ts.map +1 -0
- package/dist/prompts/integration-walkthrough.js +52 -0
- package/dist/prompts/integration-walkthrough.js.map +1 -0
- package/dist/prompts/register.d.ts +4 -0
- package/dist/prompts/register.d.ts.map +1 -0
- package/dist/prompts/register.js +4 -0
- package/dist/prompts/register.js.map +1 -0
- package/dist/registry.d.ts +14 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +2 -0
- package/dist/registry.js.map +1 -0
- package/dist/resources/knowledge-resources.d.ts +5 -0
- package/dist/resources/knowledge-resources.d.ts.map +1 -0
- package/dist/resources/knowledge-resources.js +121 -0
- package/dist/resources/knowledge-resources.js.map +1 -0
- package/dist/resources/register.d.ts +4 -0
- package/dist/resources/register.d.ts.map +1 -0
- package/dist/resources/register.js +8 -0
- package/dist/resources/register.js.map +1 -0
- package/dist/server.d.ts +40 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +56 -0
- package/dist/server.js.map +1 -0
- package/dist/telemetry/logger.d.ts +31 -0
- package/dist/telemetry/logger.d.ts.map +1 -0
- package/dist/telemetry/logger.js +67 -0
- package/dist/telemetry/logger.js.map +1 -0
- package/dist/telemetry/redaction.d.ts +88 -0
- package/dist/telemetry/redaction.d.ts.map +1 -0
- package/dist/telemetry/redaction.js +238 -0
- package/dist/telemetry/redaction.js.map +1 -0
- package/dist/tools/build-transaction-parameters.d.ts +10 -0
- package/dist/tools/build-transaction-parameters.d.ts.map +1 -0
- package/dist/tools/build-transaction-parameters.js +154 -0
- package/dist/tools/build-transaction-parameters.js.map +1 -0
- package/dist/tools/call-context.d.ts +47 -0
- package/dist/tools/call-context.d.ts.map +1 -0
- package/dist/tools/call-context.js +15 -0
- package/dist/tools/call-context.js.map +1 -0
- package/dist/tools/codegen-tools.d.ts +4 -0
- package/dist/tools/codegen-tools.d.ts.map +1 -0
- package/dist/tools/codegen-tools.js +131 -0
- package/dist/tools/codegen-tools.js.map +1 -0
- package/dist/tools/credential-tools.d.ts +32 -0
- package/dist/tools/credential-tools.d.ts.map +1 -0
- package/dist/tools/credential-tools.js +65 -0
- package/dist/tools/credential-tools.js.map +1 -0
- package/dist/tools/descriptor.d.ts +52 -0
- package/dist/tools/descriptor.d.ts.map +1 -0
- package/dist/tools/descriptor.js +2 -0
- package/dist/tools/descriptor.js.map +1 -0
- package/dist/tools/diagnostic-tools.d.ts +3 -0
- package/dist/tools/diagnostic-tools.d.ts.map +1 -0
- package/dist/tools/diagnostic-tools.js +128 -0
- package/dist/tools/diagnostic-tools.js.map +1 -0
- package/dist/tools/gateway-tools.d.ts +6 -0
- package/dist/tools/gateway-tools.d.ts.map +1 -0
- package/dist/tools/gateway-tools.js +381 -0
- package/dist/tools/gateway-tools.js.map +1 -0
- package/dist/tools/hash-tools.d.ts +5 -0
- package/dist/tools/hash-tools.d.ts.map +1 -0
- package/dist/tools/hash-tools.js +238 -0
- package/dist/tools/hash-tools.js.map +1 -0
- package/dist/tools/knowledge-tools.d.ts +7 -0
- package/dist/tools/knowledge-tools.d.ts.map +1 -0
- package/dist/tools/knowledge-tools.js +247 -0
- package/dist/tools/knowledge-tools.js.map +1 -0
- package/dist/tools/onboarding-checklist.d.ts +3 -0
- package/dist/tools/onboarding-checklist.d.ts.map +1 -0
- package/dist/tools/onboarding-checklist.js +141 -0
- package/dist/tools/onboarding-checklist.js.map +1 -0
- package/dist/tools/register.d.ts +60 -0
- package/dist/tools/register.d.ts.map +1 -0
- package/dist/tools/register.js +145 -0
- package/dist/tools/register.js.map +1 -0
- package/dist/tools/tool-kit.d.ts +88 -0
- package/dist/tools/tool-kit.d.ts.map +1 -0
- package/dist/tools/tool-kit.js +297 -0
- package/dist/tools/tool-kit.js.map +1 -0
- package/dist/validation/payload-validator.d.ts +29 -0
- package/dist/validation/payload-validator.d.ts.map +1 -0
- package/dist/validation/payload-validator.js +79 -0
- package/dist/validation/payload-validator.js.map +1 -0
- package/dist/validation/rules/amount.d.ts +3 -0
- package/dist/validation/rules/amount.d.ts.map +1 -0
- package/dist/validation/rules/amount.js +77 -0
- package/dist/validation/rules/amount.js.map +1 -0
- package/dist/validation/rules/bill-reference.d.ts +10 -0
- package/dist/validation/rules/bill-reference.d.ts.map +1 -0
- package/dist/validation/rules/bill-reference.js +34 -0
- package/dist/validation/rules/bill-reference.js.map +1 -0
- package/dist/validation/rules/cnic.d.ts +3 -0
- package/dist/validation/rules/cnic.d.ts.map +1 -0
- package/dist/validation/rules/cnic.js +42 -0
- package/dist/validation/rules/cnic.js.map +1 -0
- package/dist/validation/rules/constants.d.ts +9 -0
- package/dist/validation/rules/constants.d.ts.map +1 -0
- package/dist/validation/rules/constants.js +28 -0
- package/dist/validation/rules/constants.js.map +1 -0
- package/dist/validation/rules/constraints.d.ts +3 -0
- package/dist/validation/rules/constraints.d.ts.map +1 -0
- package/dist/validation/rules/constraints.js +113 -0
- package/dist/validation/rules/constraints.js.map +1 -0
- package/dist/validation/rules/datetime.d.ts +3 -0
- package/dist/validation/rules/datetime.d.ts.map +1 -0
- package/dist/validation/rules/datetime.js +49 -0
- package/dist/validation/rules/datetime.js.map +1 -0
- package/dist/validation/rules/empty-string.d.ts +13 -0
- package/dist/validation/rules/empty-string.d.ts.map +1 -0
- package/dist/validation/rules/empty-string.js +32 -0
- package/dist/validation/rules/empty-string.js.map +1 -0
- package/dist/validation/rules/expiry.d.ts +3 -0
- package/dist/validation/rules/expiry.d.ts.map +1 -0
- package/dist/validation/rules/expiry.js +52 -0
- package/dist/validation/rules/expiry.js.map +1 -0
- package/dist/validation/rules/msisdn.d.ts +3 -0
- package/dist/validation/rules/msisdn.d.ts.map +1 -0
- package/dist/validation/rules/msisdn.js +45 -0
- package/dist/validation/rules/msisdn.js.map +1 -0
- package/dist/validation/rules/presence.d.ts +3 -0
- package/dist/validation/rules/presence.d.ts.map +1 -0
- package/dist/validation/rules/presence.js +90 -0
- package/dist/validation/rules/presence.js.map +1 -0
- package/dist/validation/rules/return-url.d.ts +14 -0
- package/dist/validation/rules/return-url.d.ts.map +1 -0
- package/dist/validation/rules/return-url.js +58 -0
- package/dist/validation/rules/return-url.js.map +1 -0
- package/dist/validation/rules/tool-argument.d.ts +16 -0
- package/dist/validation/rules/tool-argument.d.ts.map +1 -0
- package/dist/validation/rules/tool-argument.js +38 -0
- package/dist/validation/rules/tool-argument.js.map +1 -0
- package/dist/validation/rules/txn-ref.d.ts +3 -0
- package/dist/validation/rules/txn-ref.d.ts.map +1 -0
- package/dist/validation/rules/txn-ref.js +47 -0
- package/dist/validation/rules/txn-ref.js.map +1 -0
- package/dist/validation/rules/unknown-fields.d.ts +10 -0
- package/dist/validation/rules/unknown-fields.d.ts.map +1 -0
- package/dist/validation/rules/unknown-fields.js +29 -0
- package/dist/validation/rules/unknown-fields.js.map +1 -0
- package/dist/validation/types.d.ts +36 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +12 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/version.d.ts +23 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/knowledge/diagnostics/symptoms.json +321 -0
- package/knowledge/docs/bnpl-guide.md +77 -0
- package/knowledge/docs/card-page-redirection.md +67 -0
- package/knowledge/docs/card-refund.md +91 -0
- package/knowledge/docs/hmac-sha256-calculation.md +72 -0
- package/knowledge/docs/index.json +189 -0
- package/knowledge/docs/ipn-implementation.md +89 -0
- package/knowledge/docs/mwallet-recurring.md +117 -0
- package/knowledge/docs/mwallet-refund.md +65 -0
- package/knowledge/docs/mwallet-rest-v1-1.md +126 -0
- package/knowledge/docs/mwallet-rest-v2-0-cnic.md +113 -0
- package/knowledge/docs/portal-guide.md +45 -0
- package/knowledge/docs/shopify-guide.md +74 -0
- package/knowledge/docs/status-inquiry-2025-26.md +32 -0
- package/knowledge/docs/status-inquiry.md +111 -0
- package/knowledge/docs/wordpress-guide.md +49 -0
- package/knowledge/flow.schema.json +390 -0
- package/knowledge/flows/bnpl-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/card-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/mwallet-rest-v1.1.json +187 -0
- package/knowledge/flows/mwallet-rest-v2.0-cnic.json +197 -0
- package/knowledge/flows/mwallet-token-pay-v4.0.json +130 -0
- package/knowledge/flows/refund-bnpl.json +105 -0
- package/knowledge/flows/refund-card-v1.1.json +112 -0
- package/knowledge/flows/refund-card-v2.0.json +121 -0
- package/knowledge/flows/refund-mwallet-v1.1.json +106 -0
- package/knowledge/flows/status-inquiry-v1.1.json +102 -0
- package/knowledge/flows/status-inquiry-v2.0.json +103 -0
- package/knowledge/flows/token-delete-v1.json +85 -0
- package/knowledge/flows/token-inquiry-v1.json +85 -0
- package/knowledge/flows/wallet-linking-portal.json +103 -0
- package/knowledge/templates/node/checkout-redirect.tmpl +166 -0
- package/knowledge/templates/node/ipn-handler.tmpl +108 -0
- package/knowledge/templates/node/rest-client.tmpl +197 -0
- package/knowledge/templates/node/wallet-linking.tmpl +147 -0
- package/knowledge/templates/php/checkout-redirect.tmpl +149 -0
- package/knowledge/templates/php/ipn-handler.tmpl +105 -0
- package/knowledge/templates/php/rest-client.tmpl +191 -0
- package/knowledge/templates/php/wallet-linking.tmpl +137 -0
- package/knowledge/templates/python/checkout-redirect.tmpl +148 -0
- package/knowledge/templates/python/ipn-handler.tmpl +110 -0
- package/knowledge/templates/python/rest-client.tmpl +179 -0
- package/knowledge/templates/python/wallet-linking.tmpl +133 -0
- package/package.json +84 -0
package/dist/paths.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { JazzCashConfigError } from './errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Locate the package root, and the bundled knowledge corpus within it.
|
|
7
|
+
*
|
|
8
|
+
* The two are resolved separately and in that order. Requiring the root to
|
|
9
|
+
* contain `knowledge/` as well would make "where is this package installed" a
|
|
10
|
+
* question the corpus can answer wrongly: relocating the corpus, or serving it
|
|
11
|
+
* from somewhere that is not a directory at all, would break the same walk that
|
|
12
|
+
* also resolves `dist/`. `package.json`
|
|
13
|
+
* is the marker that actually defines a package root, so the walk asks for that
|
|
14
|
+
* and nothing else.
|
|
15
|
+
*
|
|
16
|
+
* The walk works unchanged from `src/` during development and from `dist/` after
|
|
17
|
+
* a build, which avoids a copy step and the class of bug where the built server
|
|
18
|
+
* silently serves a stale corpus.
|
|
19
|
+
*/
|
|
20
|
+
/** The file that marks the directory owning a package. */
|
|
21
|
+
const PACKAGE_MARKER = 'package.json';
|
|
22
|
+
/** Where the bundled corpus sits, relative to the package root. */
|
|
23
|
+
const CORPUS_DIRECTORY = 'knowledge';
|
|
24
|
+
/**
|
|
25
|
+
* Environment variable naming the corpus directory outright.
|
|
26
|
+
*
|
|
27
|
+
* The package-root walk starts from `import.meta.url`, which is only the truth
|
|
28
|
+
* while the module is executed as a file inside its own package. A bundler
|
|
29
|
+
* rewrites that value: hosting this server inside a Next.js route handler
|
|
30
|
+
* resolves the walk into `.next/`, whose `package.json` is real and whose
|
|
31
|
+
* `knowledge/` does not exist. The corpus loader then finds no documents, the
|
|
32
|
+
* search index is built over nothing, and the server answers merchant
|
|
33
|
+
* integration questions from an empty knowledge base — confidently, because
|
|
34
|
+
* nothing in that path fails. That is the worst failure mode this server has, so
|
|
35
|
+
* a deployment that knows where the corpus is says so instead of hoping.
|
|
36
|
+
*
|
|
37
|
+
* Deliberately not a tool argument, and deliberately not relative: resolving a
|
|
38
|
+
* relative path would anchor the corpus to the working directory of whichever
|
|
39
|
+
* process happened to start the server, which is exactly the unpredictable input
|
|
40
|
+
* this variable exists to remove.
|
|
41
|
+
*/
|
|
42
|
+
const CORPUS_DIRECTORY_VARIABLE = 'MCP_CORPUS_DIR';
|
|
43
|
+
let cachedRoot;
|
|
44
|
+
/**
|
|
45
|
+
* Walk upwards to the nearest directory that owns a `package.json`.
|
|
46
|
+
*
|
|
47
|
+
* Exported so the walk can be exercised from somewhere other than this module's
|
|
48
|
+
* own directory, which is the only way to prove that moving the corpus leaves
|
|
49
|
+
* root discovery intact.
|
|
50
|
+
*/
|
|
51
|
+
export function findPackageRoot(startDirectory) {
|
|
52
|
+
let current = resolve(startDirectory);
|
|
53
|
+
for (;;) {
|
|
54
|
+
if (existsSync(join(current, PACKAGE_MARKER))) {
|
|
55
|
+
return current;
|
|
56
|
+
}
|
|
57
|
+
const parent = dirname(current);
|
|
58
|
+
if (parent === current) {
|
|
59
|
+
throw new JazzCashConfigError(`Unable to locate the package root. Searched upwards from ${startDirectory} for a directory containing ${PACKAGE_MARKER}.`);
|
|
60
|
+
}
|
|
61
|
+
current = parent;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Absolute path to the package root. Cached after the first successful walk. */
|
|
65
|
+
export function packageRoot() {
|
|
66
|
+
cachedRoot ??= findPackageRoot(dirname(fileURLToPath(import.meta.url)));
|
|
67
|
+
return cachedRoot;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Absolute path to the directory holding the bundled corpus.
|
|
71
|
+
*
|
|
72
|
+
* Derived from the package root rather than being what identifies it, so this is
|
|
73
|
+
* the single place that has to change if the corpus stops shipping beside the
|
|
74
|
+
* code — and the single place `MCP_CORPUS_DIR` has to override.
|
|
75
|
+
*
|
|
76
|
+
* The override is validated on every call rather than memoised: the check is one
|
|
77
|
+
* `stat` in front of a file read that is about to happen anyway, and a cached
|
|
78
|
+
* answer would make the variable unreadable to anything that sets it after this
|
|
79
|
+
* module was first imported.
|
|
80
|
+
*/
|
|
81
|
+
export function corpusRoot() {
|
|
82
|
+
const configured = process.env[CORPUS_DIRECTORY_VARIABLE]?.trim() ?? '';
|
|
83
|
+
if (configured === '') {
|
|
84
|
+
return join(packageRoot(), CORPUS_DIRECTORY);
|
|
85
|
+
}
|
|
86
|
+
// Refused rather than resolved against `process.cwd()`. A silently resolved
|
|
87
|
+
// relative path would either find a corpus nobody meant to serve, or fall
|
|
88
|
+
// through to the empty-knowledge-base failure this variable exists to prevent.
|
|
89
|
+
if (!isAbsolute(configured)) {
|
|
90
|
+
throw new JazzCashConfigError(`${CORPUS_DIRECTORY_VARIABLE} must be an absolute path, but is "${configured}". A relative path would be resolved against the working directory of whichever process started the server, which is not something this server can predict.`);
|
|
91
|
+
}
|
|
92
|
+
// Checked here, at the one place the corpus is located, rather than left to
|
|
93
|
+
// the loader: an absent or mistyped directory yields no documents, and a
|
|
94
|
+
// server that serves no documents answers merchant questions from nothing
|
|
95
|
+
// instead of refusing to start.
|
|
96
|
+
const stats = statSync(configured, { throwIfNoEntry: false });
|
|
97
|
+
if (stats?.isDirectory() !== true) {
|
|
98
|
+
throw new JazzCashConfigError(`${CORPUS_DIRECTORY_VARIABLE} is set to "${configured}", which is not an existing directory. Point it at the ${CORPUS_DIRECTORY}/ directory that ships with this package, or unset it to resolve the corpus from the package root.`);
|
|
99
|
+
}
|
|
100
|
+
return configured;
|
|
101
|
+
}
|
|
102
|
+
/** Absolute path to `knowledge/`, optionally joined with further segments. */
|
|
103
|
+
export function knowledgePath(...segments) {
|
|
104
|
+
return join(corpusRoot(), ...segments);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;;;GAcG;AAEH,0DAA0D;AAC1D,MAAM,cAAc,GAAG,cAAc,CAAC;AAEtC,mEAAmE;AACnE,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAEnD,IAAI,UAA8B,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,cAAsB;IACpD,IAAI,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAEtC,SAAS,CAAC;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YAC9C,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,mBAAmB,CAC3B,4DAA4D,cAAc,+BAA+B,cAAc,GAAG,CAC3H,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW;IACzB,UAAU,KAAK,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAExE,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC/C,CAAC;IAED,4EAA4E;IAC5E,0EAA0E;IAC1E,+EAA+E;IAC/E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,mBAAmB,CAC3B,GAAG,yBAAyB,sCAAsC,UAAU,6JAA6J,CAC1O,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,0EAA0E;IAC1E,gCAAgC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,IAAI,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC;QAClC,MAAM,IAAI,mBAAmB,CAC3B,GAAG,yBAAyB,eAAe,UAAU,0DAA0D,gBAAgB,oGAAoG,CACpO,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,GAAG,QAA2B;IAC1D,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Registrar } from '../registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* Guided integration walkthrough.
|
|
4
|
+
*
|
|
5
|
+
* Sequences the tools in the order a resident engineer works through them, so
|
|
6
|
+
* that a merchant's AI does not have to infer the order — which is where most
|
|
7
|
+
* self-directed integrations go wrong, typically by writing checkout code before
|
|
8
|
+
* establishing what the hash rules are.
|
|
9
|
+
*/
|
|
10
|
+
export declare const registerIntegrationWalkthrough: Registrar;
|
|
11
|
+
//# sourceMappingURL=integration-walkthrough.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-walkthrough.d.ts","sourceRoot":"","sources":["../../src/prompts/integration-walkthrough.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAgD5C,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Guided integration walkthrough.
|
|
4
|
+
*
|
|
5
|
+
* Sequences the tools in the order a resident engineer works through them, so
|
|
6
|
+
* that a merchant's AI does not have to infer the order — which is where most
|
|
7
|
+
* self-directed integrations go wrong, typically by writing checkout code before
|
|
8
|
+
* establishing what the hash rules are.
|
|
9
|
+
*/
|
|
10
|
+
export const registerIntegrationWalkthrough = (server, deps) => {
|
|
11
|
+
server.registerPrompt('jazzcash_integration_walkthrough', {
|
|
12
|
+
title: 'JazzCash integration walkthrough',
|
|
13
|
+
description: 'Step-by-step guided integration: choose a flow, complete onboarding, generate code, test in sandbox, and go live.',
|
|
14
|
+
argsSchema: {
|
|
15
|
+
product: z.string().describe('What you want to accept: card, bnpl, mwallet, recurring, or refund.'),
|
|
16
|
+
platform: z.string().optional().describe('custom, woocommerce or shopify.'),
|
|
17
|
+
language: z.string().optional().describe('php, node or python.'),
|
|
18
|
+
},
|
|
19
|
+
}, ({ product, platform, language }) => {
|
|
20
|
+
const resolvedPlatform = platform ?? 'custom';
|
|
21
|
+
const resolvedLanguage = language ?? 'php';
|
|
22
|
+
const availableFlows = deps.catalogue
|
|
23
|
+
.list()
|
|
24
|
+
.map((flow) => `${flow.id} (${flow.product})`)
|
|
25
|
+
.join(', ');
|
|
26
|
+
const instructions = [
|
|
27
|
+
`I want to integrate JazzCash ${product} into a ${resolvedPlatform} application, writing ${resolvedLanguage}.`,
|
|
28
|
+
'',
|
|
29
|
+
'Work through this in order, using the jazzcash_* tools rather than general knowledge of payment gateways. Cite the document behind each answer.',
|
|
30
|
+
'',
|
|
31
|
+
'1. Call `jazzcash_list_integration_flows` and recommend one flow, saying why.',
|
|
32
|
+
'2. Call `jazzcash_get_integration_flow` for it. Summarise the mandatory parameters and any known documentation defects.',
|
|
33
|
+
`3. Call \`jazzcash_get_onboarding_checklist\` with that flow and platform "${resolvedPlatform}". Tell me what I must do in the JazzCash portal before any code runs.`,
|
|
34
|
+
`4. Call \`jazzcash_generate_integration_code\` for ${resolvedLanguage}. Explain where each generated file belongs and what still needs configuring.`,
|
|
35
|
+
'5. Call `jazzcash_generate_ipn_handler`. IPN and Status Inquiry are mandatory, not optional — do not skip them.',
|
|
36
|
+
'6. Call `jazzcash_build_transaction_parameters` to produce one signed sandbox payload, and show it to me.',
|
|
37
|
+
'7. Explain how to run the sandbox test: `jazzcash_send_gateway_request` for a REST flow, or `jazzcash_build_checkout_form` for a hosted page, which needs a human in a browser.',
|
|
38
|
+
'8. Remind me what evidence JazzCash requires before go-live.',
|
|
39
|
+
'',
|
|
40
|
+
'Rules for you:',
|
|
41
|
+
'- Never invent a parameter, endpoint or response code. If the corpus does not cover something, say so.',
|
|
42
|
+
'- Never compute the secure hash in browser JavaScript. The Integrity Salt is the HMAC key.',
|
|
43
|
+
'- Sandbox and production share identical endpoints, so remind me that going live is a credential change and to confirm which credentials are loaded before any live call.',
|
|
44
|
+
'',
|
|
45
|
+
`Flows available: ${availableFlows}.`,
|
|
46
|
+
].join('\n');
|
|
47
|
+
return {
|
|
48
|
+
messages: [{ role: 'user', content: { type: 'text', text: instructions } }],
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=integration-walkthrough.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-walkthrough.js","sourceRoot":"","sources":["../../src/prompts/integration-walkthrough.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAc,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IACxE,MAAM,CAAC,cAAc,CACnB,kCAAkC,EAClC;QACE,KAAK,EAAE,kCAAkC;QACzC,WAAW,EACT,mHAAmH;QACrH,UAAU,EAAE;YACV,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;YACnG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;YAC3E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;SACjE;KACF,EACD,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;QAClC,MAAM,gBAAgB,GAAG,QAAQ,IAAI,QAAQ,CAAC;QAC9C,MAAM,gBAAgB,GAAG,QAAQ,IAAI,KAAK,CAAC;QAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS;aAClC,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,GAAG,CAAC;aAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,YAAY,GAAG;YACnB,gCAAgC,OAAO,WAAW,gBAAgB,yBAAyB,gBAAgB,GAAG;YAC9G,EAAE;YACF,iJAAiJ;YACjJ,EAAE;YACF,+EAA+E;YAC/E,yHAAyH;YACzH,8EAA8E,gBAAgB,wEAAwE;YACtK,sDAAsD,gBAAgB,+EAA+E;YACrJ,iHAAiH;YACjH,2GAA2G;YAC3G,iLAAiL;YACjL,8DAA8D;YAC9D,EAAE;YACF,gBAAgB;YAChB,wGAAwG;YACxG,4FAA4F;YAC5F,2KAA2K;YAC3K,EAAE;YACF,oBAAoB,cAAc,GAAG;SACtC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/prompts/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,yBAAyB;AACzB,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAAqC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/prompts/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAE9E,yBAAyB;AACzB,MAAM,CAAC,MAAM,WAAW,GAAyB,CAAC,8BAA8B,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ServerDependencies } from './dependencies.js';
|
|
2
|
+
import type { RegistrarFor } from './core/registry.js';
|
|
3
|
+
export { applyRegistrars } from './core/registry.js';
|
|
4
|
+
/**
|
|
5
|
+
* Registration signature for a registrar that may read any part of the surface,
|
|
6
|
+
* including the documentation corpus.
|
|
7
|
+
*
|
|
8
|
+
* The default for tools, resources and prompts. A registrar that reads no corpus
|
|
9
|
+
* should be typed {@link import('./core/registry.js').CoreRegistrar} instead —
|
|
10
|
+
* it remains assignable here, so declaring the narrower type costs nothing and
|
|
11
|
+
* buys a compiler-checked claim about what the handler touches.
|
|
12
|
+
*/
|
|
13
|
+
export type Registrar = RegistrarFor<ServerDependencies>;
|
|
14
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAOrD;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Registrar } from '../registry.js';
|
|
2
|
+
export declare const registerIndexResource: Registrar;
|
|
3
|
+
export declare const registerDocumentResources: Registrar;
|
|
4
|
+
export declare const registerFlowResources: Registrar;
|
|
5
|
+
//# sourceMappingURL=knowledge-resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-resources.d.ts","sourceRoot":"","sources":["../../src/resources/knowledge-resources.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA0ChD,eAAO,MAAM,qBAAqB,EAAE,SA0CnC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,SA0BvC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,SA0BnC,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { resolveEndpoint } from '../catalogue/endpoints.js';
|
|
4
|
+
import { JazzCashNotFoundError } from '../errors.js';
|
|
5
|
+
import { CORPUS_VERSION } from '../version.js';
|
|
6
|
+
/**
|
|
7
|
+
* Read-only resources.
|
|
8
|
+
*
|
|
9
|
+
* Clients that prefer to pull context rather than call a tool can read the
|
|
10
|
+
* corpus and the flow catalogue directly. URIs match the citations that tools
|
|
11
|
+
* emit, so a citation is always resolvable — and when one is not, the client is
|
|
12
|
+
* told that in the protocol's own vocabulary rather than as a server fault.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* JSON-RPC code the MCP specification reserves for an unknown resource URI.
|
|
16
|
+
*
|
|
17
|
+
* Spelled out because the pinned SDK's `ErrorCode` enum has no member for it.
|
|
18
|
+
* Without the translation below, the thrown {@link JazzCashNotFoundError}
|
|
19
|
+
* carries a *string* code, and the protocol layer — which emits an error code
|
|
20
|
+
* only when it is a safe integer — reports every mistyped URI as `-32603`
|
|
21
|
+
* (internal error). A client then cannot tell its own typo from a broken server.
|
|
22
|
+
*/
|
|
23
|
+
const RESOURCE_NOT_FOUND = -32002;
|
|
24
|
+
/**
|
|
25
|
+
* Read a resource, translating "no such entry" into the protocol's own code.
|
|
26
|
+
*
|
|
27
|
+
* Resource callbacks have no `isError` channel, so unlike the tool handlers they
|
|
28
|
+
* cannot use `safeHandler`: the error has to leave through the protocol layer.
|
|
29
|
+
* Anything other than a missing entry is rethrown untouched, so a genuine server
|
|
30
|
+
* fault is still reported as one.
|
|
31
|
+
*/
|
|
32
|
+
function readOrNotFound(uri, read) {
|
|
33
|
+
try {
|
|
34
|
+
return read();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof JazzCashNotFoundError) {
|
|
38
|
+
throw new McpError(RESOURCE_NOT_FOUND, error.message, { uri: uri.href });
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export const registerIndexResource = (server, deps) => {
|
|
44
|
+
server.registerResource('jazzcash-index', 'jazzcash://index', {
|
|
45
|
+
title: 'JazzCash corpus index',
|
|
46
|
+
description: 'Every document and integration flow this server knows about.',
|
|
47
|
+
mimeType: 'application/json',
|
|
48
|
+
}, (uri) => ({
|
|
49
|
+
contents: [
|
|
50
|
+
{
|
|
51
|
+
uri: uri.href,
|
|
52
|
+
mimeType: 'application/json',
|
|
53
|
+
text: JSON.stringify({
|
|
54
|
+
corpusVersion: CORPUS_VERSION,
|
|
55
|
+
documents: deps.corpus.documents().map((document) => ({
|
|
56
|
+
uri: `jazzcash://docs/${document.metadata.docId}`,
|
|
57
|
+
docId: document.metadata.docId,
|
|
58
|
+
title: document.metadata.title,
|
|
59
|
+
sourcePdf: document.metadata.sourcePdf,
|
|
60
|
+
version: document.metadata.version,
|
|
61
|
+
sections: document.sections.map((section) => ({ id: section.sectionId, title: section.title })),
|
|
62
|
+
})),
|
|
63
|
+
flows: deps.catalogue.list().map((flow) => ({
|
|
64
|
+
uri: `jazzcash://flows/${flow.id}`,
|
|
65
|
+
id: flow.id,
|
|
66
|
+
title: flow.title,
|
|
67
|
+
product: flow.product,
|
|
68
|
+
transport: flow.transport,
|
|
69
|
+
movesMoney: flow.movesMoney,
|
|
70
|
+
endpoint: resolveEndpoint(flow, 'sandbox'),
|
|
71
|
+
})),
|
|
72
|
+
}, null, 2),
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
}));
|
|
76
|
+
};
|
|
77
|
+
export const registerDocumentResources = (server, deps) => {
|
|
78
|
+
server.registerResource('jazzcash-doc', new ResourceTemplate('jazzcash://docs/{docId}', {
|
|
79
|
+
list: () => ({
|
|
80
|
+
resources: deps.corpus.documents().map((document) => ({
|
|
81
|
+
uri: `jazzcash://docs/${document.metadata.docId}`,
|
|
82
|
+
name: document.metadata.title,
|
|
83
|
+
description: `Curated from ${document.metadata.sourcePdf} (version ${document.metadata.version}).`,
|
|
84
|
+
mimeType: 'text/markdown',
|
|
85
|
+
})),
|
|
86
|
+
}),
|
|
87
|
+
}), {
|
|
88
|
+
title: 'JazzCash integration guide',
|
|
89
|
+
description: 'A curated JazzCash integration guide, transcribed from the official 2026 PDF.',
|
|
90
|
+
mimeType: 'text/markdown',
|
|
91
|
+
}, (uri, variables) => {
|
|
92
|
+
const docId = String(variables['docId']);
|
|
93
|
+
const document = readOrNotFound(uri, () => deps.corpus.document(docId));
|
|
94
|
+
return {
|
|
95
|
+
contents: [{ uri: uri.href, mimeType: 'text/markdown', text: document.markdown }],
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
export const registerFlowResources = (server, deps) => {
|
|
100
|
+
server.registerResource('jazzcash-flow', new ResourceTemplate('jazzcash://flows/{flowId}', {
|
|
101
|
+
list: () => ({
|
|
102
|
+
resources: deps.catalogue.list().map((flow) => ({
|
|
103
|
+
uri: `jazzcash://flows/${flow.id}`,
|
|
104
|
+
name: flow.title,
|
|
105
|
+
description: flow.useWhen,
|
|
106
|
+
mimeType: 'application/json',
|
|
107
|
+
})),
|
|
108
|
+
}),
|
|
109
|
+
}), {
|
|
110
|
+
title: 'JazzCash flow specification',
|
|
111
|
+
description: 'Machine-readable specification for one integration flow.',
|
|
112
|
+
mimeType: 'application/json',
|
|
113
|
+
}, (uri, variables) => {
|
|
114
|
+
const flowId = String(variables['flowId']);
|
|
115
|
+
const flow = readOrNotFound(uri, () => deps.catalogue.get(flowId));
|
|
116
|
+
return {
|
|
117
|
+
contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(flow, null, 2) }],
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=knowledge-resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-resources.js","sourceRoot":"","sources":["../../src/resources/knowledge-resources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH,MAAM,kBAAkB,GAAG,CAAC,KAAK,CAAC;AAElC;;;;;;;GAOG;AACH,SAAS,cAAc,CAAI,GAAQ,EAAE,IAAa;IAChD,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,qBAAqB,EAAE,CAAC;YAC3C,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAc,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IAC/D,MAAM,CAAC,gBAAgB,CACrB,gBAAgB,EAChB,kBAAkB,EAClB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,8DAA8D;QAC3E,QAAQ,EAAE,kBAAkB;KAC7B,EACD,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACR,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,aAAa,EAAE,cAAc;oBAC7B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;wBACpD,GAAG,EAAE,mBAAmB,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE;wBACjD,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK;wBAC9B,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK;wBAC9B,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS;wBACtC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO;wBAClC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;qBAChG,CAAC,CAAC;oBACH,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBAC1C,GAAG,EAAE,oBAAoB,IAAI,CAAC,EAAE,EAAE;wBAClC,EAAE,EAAE,IAAI,CAAC,EAAE;wBACX,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,QAAQ,EAAE,eAAe,CAAC,IAAI,EAAE,SAAS,CAAC;qBAC3C,CAAC,CAAC;iBACJ,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAc,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IACnE,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,IAAI,gBAAgB,CAAC,yBAAyB,EAAE;QAC9C,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACX,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACpD,GAAG,EAAE,mBAAmB,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE;gBACjD,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK;gBAC7B,WAAW,EAAE,gBAAgB,QAAQ,CAAC,QAAQ,CAAC,SAAS,aAAa,QAAQ,CAAC,QAAQ,CAAC,OAAO,IAAI;gBAClG,QAAQ,EAAE,eAAe;aAC1B,CAAC,CAAC;SACJ,CAAC;KACH,CAAC,EACF;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,+EAA+E;QAC5F,QAAQ,EAAE,eAAe;KAC1B,EACD,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE;QACjB,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC;SAClF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAc,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;IAC/D,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,IAAI,gBAAgB,CAAC,2BAA2B,EAAE;QAChD,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACX,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC9C,GAAG,EAAE,oBAAoB,IAAI,CAAC,EAAE,EAAE;gBAClC,IAAI,EAAE,IAAI,CAAC,KAAK;gBAChB,WAAW,EAAE,IAAI,CAAC,OAAO;gBACzB,QAAQ,EAAE,kBAAkB;aAC7B,CAAC,CAAC;SACJ,CAAC;KACH,CAAC,EACF;QACE,KAAK,EAAE,6BAA6B;QACpC,WAAW,EAAE,0DAA0D;QACvE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,OAAO;YACL,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACjG,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/resources/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,2BAA2B;AAC3B,eAAO,MAAM,aAAa,EAAE,SAAS,SAAS,EAI7C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { registerDocumentResources, registerFlowResources, registerIndexResource } from './knowledge-resources.js';
|
|
2
|
+
/** Resource registrars. */
|
|
3
|
+
export const ALL_RESOURCES = [
|
|
4
|
+
registerIndexResource,
|
|
5
|
+
registerDocumentResources,
|
|
6
|
+
registerFlowResources,
|
|
7
|
+
];
|
|
8
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/resources/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEnH,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAyB;IACjD,qBAAqB;IACrB,yBAAyB;IACzB,qBAAqB;CACtB,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ServerDependencies } from './dependencies.js';
|
|
3
|
+
import { type Registrar } from './registry.js';
|
|
4
|
+
import { type ToolDescriptor } from './tools/register.js';
|
|
5
|
+
/**
|
|
6
|
+
* Composition root.
|
|
7
|
+
*
|
|
8
|
+
* Builds dependencies from the process environment, then hands them to the
|
|
9
|
+
* registration lists. It deliberately knows nothing about individual tools.
|
|
10
|
+
*
|
|
11
|
+
* The corpus-free half lives in `./core/server.js`, and this module adds the
|
|
12
|
+
* knowledge half on top. The split is not cosmetic: the three loaders imported
|
|
13
|
+
* below run at module scope for anything that reaches this file, so a host that
|
|
14
|
+
* serves only the credential tools imports the core module instead and never
|
|
15
|
+
* pays for — or gains access to — a corpus it does not serve.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createServerDependencies(source?: NodeJS.ProcessEnv): ServerDependencies;
|
|
18
|
+
/**
|
|
19
|
+
* Which parts of the surface to register.
|
|
20
|
+
*
|
|
21
|
+
* Every field defaults to the whole of it, so the stdio entry point calls
|
|
22
|
+
* `createServer(deps)` and gets exactly what it always got. The options exist
|
|
23
|
+
* for the hosted HTTP tier, which may only ever expose tools that need no
|
|
24
|
+
* merchant credential. The complementary set — the tools a merchant's local
|
|
25
|
+
* connector serves — has its own entry point in `./core/server.js`, because it
|
|
26
|
+
* must be reachable without a corpus at all.
|
|
27
|
+
*
|
|
28
|
+
* The tool list is passed as descriptors rather than as bare registrars because
|
|
29
|
+
* the caller doing the filtering has to reason about the tool's name, provider
|
|
30
|
+
* and credential dependence — none of which a `Registrar` reveals. See
|
|
31
|
+
* `src/tools/register.ts` for why that flag is written down rather than
|
|
32
|
+
* inferred from a tool's group.
|
|
33
|
+
*/
|
|
34
|
+
export interface ServerSurface {
|
|
35
|
+
readonly tools?: readonly ToolDescriptor[] | undefined;
|
|
36
|
+
readonly resources?: readonly Registrar[] | undefined;
|
|
37
|
+
readonly prompts?: readonly Registrar[] | undefined;
|
|
38
|
+
}
|
|
39
|
+
export declare function createServer(deps: ServerDependencies, surface?: ServerSurface): McpServer;
|
|
40
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAK5D,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG5E;;;;;;;;;;;GAWG;AASH,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,MAAM,CAAC,UAAwB,GAAG,kBAAkB,CAYpG;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAC;CACrD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,GAAE,aAAkB,GAAG,SAAS,CAsB7F"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { defaultFlowSource } from './catalogue/default-catalogue.js';
|
|
3
|
+
import { createCoreDependencies, SERVER_INSTRUCTIONS } from './core/server.js';
|
|
4
|
+
import { loadSymptomKnowledgeBase } from './diagnostics/diagnose.js';
|
|
5
|
+
import { loadKnowledgeCorpus } from './knowledge/corpus.js';
|
|
6
|
+
import { buildSearchIndex } from './knowledge/search.js';
|
|
7
|
+
import { ALL_PROMPTS } from './prompts/register.js';
|
|
8
|
+
import { applyRegistrars } from './registry.js';
|
|
9
|
+
import { ALL_RESOURCES } from './resources/register.js';
|
|
10
|
+
import { TOOL_DESCRIPTORS } from './tools/register.js';
|
|
11
|
+
import { SERVER_NAME, SERVER_VERSION } from './version.js';
|
|
12
|
+
/**
|
|
13
|
+
* Composition root.
|
|
14
|
+
*
|
|
15
|
+
* Builds dependencies from the process environment, then hands them to the
|
|
16
|
+
* registration lists. It deliberately knows nothing about individual tools.
|
|
17
|
+
*
|
|
18
|
+
* The corpus-free half lives in `./core/server.js`, and this module adds the
|
|
19
|
+
* knowledge half on top. The split is not cosmetic: the three loaders imported
|
|
20
|
+
* below run at module scope for anything that reaches this file, so a host that
|
|
21
|
+
* serves only the credential tools imports the core module instead and never
|
|
22
|
+
* pays for — or gains access to — a corpus it does not serve.
|
|
23
|
+
*/
|
|
24
|
+
// `createCredentialServer`, `createCoreDependencies` and `SERVER_INSTRUCTIONS`
|
|
25
|
+
// are deliberately not re-exported. This module loads the corpus at module
|
|
26
|
+
// scope, so offering the corpus-free entry points through it would invite
|
|
27
|
+
// exactly the import the split exists to prevent — a host serving only the
|
|
28
|
+
// credential tools would pull the whole knowledge half in behind them. They live
|
|
29
|
+
// in `./core/server.js`, which is where the connector reaches them.
|
|
30
|
+
export function createServerDependencies(source = process.env) {
|
|
31
|
+
const core = createCoreDependencies(source, { catalogue: defaultFlowSource() });
|
|
32
|
+
const corpus = loadKnowledgeCorpus();
|
|
33
|
+
const search = buildSearchIndex(corpus);
|
|
34
|
+
const symptoms = loadSymptomKnowledgeBase();
|
|
35
|
+
core.logger.info('Knowledge corpus loaded', {
|
|
36
|
+
documents: corpus.documents().length,
|
|
37
|
+
corpusVersion: corpus.corpusVersion,
|
|
38
|
+
});
|
|
39
|
+
return { ...core, corpus, search, symptoms };
|
|
40
|
+
}
|
|
41
|
+
export function createServer(deps, surface = {}) {
|
|
42
|
+
const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION }, { instructions: SERVER_INSTRUCTIONS });
|
|
43
|
+
const tools = surface.tools ?? TOOL_DESCRIPTORS;
|
|
44
|
+
const resources = surface.resources ?? ALL_RESOURCES;
|
|
45
|
+
const prompts = surface.prompts ?? ALL_PROMPTS;
|
|
46
|
+
applyRegistrars(server, deps, tools.map((descriptor) => descriptor.registrar));
|
|
47
|
+
applyRegistrars(server, deps, resources);
|
|
48
|
+
applyRegistrars(server, deps, prompts);
|
|
49
|
+
deps.logger.debug('Server surface registered', {
|
|
50
|
+
tools: tools.length,
|
|
51
|
+
resources: resources.length,
|
|
52
|
+
prompts: prompts.length,
|
|
53
|
+
});
|
|
54
|
+
return server;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAkB,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAuB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;;;;;;;;GAWG;AAEH,+EAA+E;AAC/E,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,iFAAiF;AACjF,oEAAoE;AAEpE,MAAM,UAAU,wBAAwB,CAAC,SAA4B,OAAO,CAAC,GAAG;IAC9E,MAAM,IAAI,GAAG,sBAAsB,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,wBAAwB,EAAE,CAAC;IAE5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;QAC1C,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM;QACpC,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC,CAAC;IAEH,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC;AAwBD,MAAM,UAAU,YAAY,CAAC,IAAwB,EAAE,UAAyB,EAAE;IAChF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAEpH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,gBAAgB,CAAC;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,aAAa,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC;IAE/C,eAAe,CACb,MAAM,EACN,IAAI,EACJ,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAChD,CAAC;IACF,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACzC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE;QAC7C,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,SAAS,EAAE,SAAS,CAAC,MAAM;QAC3B,OAAO,EAAE,OAAO,CAAC,MAAM;KACxB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured logger.
|
|
3
|
+
*
|
|
4
|
+
* WRITES TO STDERR ONLY. On the MCP stdio transport `stdout` carries JSON-RPC
|
|
5
|
+
* framing; a single byte written there by application code desynchronises the
|
|
6
|
+
* client for the remainder of the session. This is enforced by an ESLint rule
|
|
7
|
+
* banning `console` and `process.stdout` in `src/`, and by a unit test.
|
|
8
|
+
*/
|
|
9
|
+
export declare const LOG_LEVELS: readonly ["error", "warn", "info", "debug"];
|
|
10
|
+
export type LogLevel = (typeof LOG_LEVELS)[number];
|
|
11
|
+
export type LogContext = Readonly<Record<string, unknown>>;
|
|
12
|
+
export interface Logger {
|
|
13
|
+
error(message: string, context?: LogContext): void;
|
|
14
|
+
warn(message: string, context?: LogContext): void;
|
|
15
|
+
info(message: string, context?: LogContext): void;
|
|
16
|
+
debug(message: string, context?: LogContext): void;
|
|
17
|
+
/** Derive a logger that attaches `bindings` to every record it emits. */
|
|
18
|
+
child(bindings: LogContext): Logger;
|
|
19
|
+
}
|
|
20
|
+
export interface LoggerOptions {
|
|
21
|
+
readonly level: LogLevel;
|
|
22
|
+
/** Defaults to `process.stderr`. Overridable so tests can assert on output. */
|
|
23
|
+
readonly stream?: NodeJS.WritableStream;
|
|
24
|
+
/** Injectable clock, so log assertions are deterministic. */
|
|
25
|
+
readonly now?: () => Date;
|
|
26
|
+
}
|
|
27
|
+
export declare function isLogLevel(value: unknown): value is LogLevel;
|
|
28
|
+
export declare function createLogger(options: LoggerOptions): Logger;
|
|
29
|
+
/** A logger that discards everything. Useful in tests and pure code paths. */
|
|
30
|
+
export declare function createNullLogger(): Logger;
|
|
31
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/telemetry/logger.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,eAAO,MAAM,UAAU,6CAA8C,CAAC;AAEtE,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AASnD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3D,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAClD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnD,yEAAyE;IACzE,KAAK,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IACxC,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAmC3D;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,IAAI,MAAM,CAYzC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { redactForLog } from './redaction.js';
|
|
2
|
+
/**
|
|
3
|
+
* Structured logger.
|
|
4
|
+
*
|
|
5
|
+
* WRITES TO STDERR ONLY. On the MCP stdio transport `stdout` carries JSON-RPC
|
|
6
|
+
* framing; a single byte written there by application code desynchronises the
|
|
7
|
+
* client for the remainder of the session. This is enforced by an ESLint rule
|
|
8
|
+
* banning `console` and `process.stdout` in `src/`, and by a unit test.
|
|
9
|
+
*/
|
|
10
|
+
export const LOG_LEVELS = ['error', 'warn', 'info', 'debug'];
|
|
11
|
+
const LEVEL_SEVERITY = {
|
|
12
|
+
error: 0,
|
|
13
|
+
warn: 1,
|
|
14
|
+
info: 2,
|
|
15
|
+
debug: 3,
|
|
16
|
+
};
|
|
17
|
+
export function isLogLevel(value) {
|
|
18
|
+
return typeof value === 'string' && LOG_LEVELS.includes(value);
|
|
19
|
+
}
|
|
20
|
+
export function createLogger(options) {
|
|
21
|
+
const stream = options.stream ?? process.stderr;
|
|
22
|
+
const now = options.now ?? (() => new Date());
|
|
23
|
+
const threshold = LEVEL_SEVERITY[options.level];
|
|
24
|
+
const emit = (level, bindings, message, context) => {
|
|
25
|
+
if (LEVEL_SEVERITY[level] > threshold) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const record = {
|
|
29
|
+
timestamp: now().toISOString(),
|
|
30
|
+
level,
|
|
31
|
+
message,
|
|
32
|
+
...redactForLog({ ...bindings, ...context }),
|
|
33
|
+
};
|
|
34
|
+
stream.write(`${JSON.stringify(record)}\n`);
|
|
35
|
+
};
|
|
36
|
+
const build = (bindings) => ({
|
|
37
|
+
error: (message, context) => {
|
|
38
|
+
emit('error', bindings, message, context);
|
|
39
|
+
},
|
|
40
|
+
warn: (message, context) => {
|
|
41
|
+
emit('warn', bindings, message, context);
|
|
42
|
+
},
|
|
43
|
+
info: (message, context) => {
|
|
44
|
+
emit('info', bindings, message, context);
|
|
45
|
+
},
|
|
46
|
+
debug: (message, context) => {
|
|
47
|
+
emit('debug', bindings, message, context);
|
|
48
|
+
},
|
|
49
|
+
child: (extra) => build({ ...bindings, ...extra }),
|
|
50
|
+
});
|
|
51
|
+
return build({});
|
|
52
|
+
}
|
|
53
|
+
/** A logger that discards everything. Useful in tests and pure code paths. */
|
|
54
|
+
export function createNullLogger() {
|
|
55
|
+
const noop = () => {
|
|
56
|
+
/* intentionally empty */
|
|
57
|
+
};
|
|
58
|
+
const logger = {
|
|
59
|
+
error: noop,
|
|
60
|
+
warn: noop,
|
|
61
|
+
info: noop,
|
|
62
|
+
debug: noop,
|
|
63
|
+
child: () => logger,
|
|
64
|
+
};
|
|
65
|
+
return logger;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/telemetry/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAItE,MAAM,cAAc,GAAuC;IACzD,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAqBF,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,UAAgC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAS,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,CAAC,KAAe,EAAE,QAAoB,EAAE,OAAe,EAAE,OAAoB,EAAQ,EAAE;QAClG,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,SAAS,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE;YAC9B,KAAK;YACL,OAAO;YACP,GAAI,YAAY,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAA6B;SAC1E,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,QAAoB,EAAU,EAAE,CAAC,CAAC;QAC/C,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAChC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAQ,EAAE;YAChC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,EAAE,CAAC,KAAK,EAAU,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;KAC3D,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB;IAC9B,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,yBAAyB;IAC3B,CAAC,CAAC;IACF,MAAM,MAAM,GAAW;QACrB,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,GAAW,EAAE,CAAC,MAAM;KAC5B,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|