@toa.io/extensions.exposition 1.0.0-alpha.282 → 1.0.0-alpha.284
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/CHANGELOG.md +56 -0
- package/components/exposition.octets/manifest.toa.yaml +11 -0
- package/components/exposition.octets/types/index.d.ts +3 -0
- package/components/exposition.octets/types/toa.d.ts +41 -0
- package/components/identity.bans/operations/transit.js +1 -1
- package/components/identity.bans/tsconfig.json +1 -1
- package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/types/index.d.ts +3 -0
- package/components/identity.bans/types/toa.d.ts +34 -0
- package/components/identity.basic/manifest.toa.yaml +13 -2
- package/components/identity.basic/operations/add.js +1 -1
- package/components/identity.basic/operations/authenticate.js +1 -1
- package/components/identity.basic/operations/check.js +1 -1
- package/components/identity.basic/operations/delete.js +1 -1
- package/components/identity.basic/operations/incept.js +18 -2
- package/components/identity.basic/operations/info.js +1 -1
- package/components/identity.basic/operations/lib/credentials.js +1 -1
- package/components/identity.basic/operations/transit.js +3 -2
- package/components/identity.basic/source/add.ts +3 -3
- package/components/identity.basic/source/authenticate.ts +2 -2
- package/components/identity.basic/source/check.ts +1 -1
- package/components/identity.basic/source/delete.ts +2 -2
- package/components/identity.basic/source/incept.ts +31 -3
- package/components/identity.basic/source/info.ts +1 -1
- package/components/identity.basic/source/transit.ts +6 -4
- package/components/identity.basic/tsconfig.json +1 -1
- package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/types/index.d.ts +22 -0
- package/components/identity.basic/types/toa.d.ts +121 -0
- package/components/identity.clients/manifest.toa.yaml +243 -0
- package/components/identity.clients/operations/describe.js +44 -0
- package/components/identity.clients/operations/lib/Context.js +2 -0
- package/components/identity.clients/operations/lib/Entity.js +2 -0
- package/components/identity.clients/operations/lib/canonical.js +24 -0
- package/components/identity.clients/operations/lib/cimd.js +86 -0
- package/components/identity.clients/operations/lib/errors.js +5 -0
- package/components/identity.clients/operations/lib/index.js +7 -0
- package/components/identity.clients/operations/lib/redirect.js +32 -0
- package/components/identity.clients/operations/register.js +84 -0
- package/components/identity.clients/source/describe.ts +65 -0
- package/components/identity.clients/source/lib/Context.ts +38 -0
- package/components/identity.clients/source/lib/Entity.ts +31 -0
- package/components/identity.clients/source/lib/canonical.test.ts +43 -0
- package/components/identity.clients/source/lib/canonical.ts +27 -0
- package/components/identity.clients/source/lib/cimd.test.ts +120 -0
- package/components/identity.clients/source/lib/cimd.ts +107 -0
- package/components/identity.clients/source/lib/errors.ts +4 -0
- package/components/identity.clients/source/lib/index.ts +6 -0
- package/components/identity.clients/source/lib/redirect.test.ts +41 -0
- package/components/identity.clients/source/lib/redirect.ts +35 -0
- package/components/identity.clients/source/register.ts +125 -0
- package/components/identity.clients/tsconfig.json +10 -0
- package/components/identity.clients/tsconfig.tsbuildinfo +1 -0
- package/components/identity.clients/types/index.d.ts +3 -0
- package/components/identity.clients/types/toa.d.ts +109 -0
- package/components/identity.credentials/operations/list.js +1 -1
- package/components/identity.credentials/source/list.ts +2 -1
- package/components/identity.credentials/tsconfig.json +4 -2
- package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
- package/components/identity.credentials/types/index.d.ts +3 -0
- package/components/identity.credentials/types/toa.d.ts +30 -0
- package/components/identity.federation/manifest.toa.yaml +37 -1
- package/components/identity.federation/operations/authenticate.js +7 -3
- package/components/identity.federation/operations/create.js +1 -1
- package/components/identity.federation/operations/decode.js +1 -1
- package/components/identity.federation/operations/delete.js +1 -1
- package/components/identity.federation/operations/incept.js +6 -2
- package/components/identity.federation/operations/lib/Configuration.js +1 -1
- package/components/identity.federation/operations/lib/Ctx.js +1 -1
- package/components/identity.federation/operations/lib/Payload.js +1 -1
- package/components/identity.federation/operations/lib/decode.js +23 -9
- package/components/identity.federation/operations/lib/discovery.js +1 -1
- package/components/identity.federation/operations/lib/errors.js +5 -1
- package/components/identity.federation/operations/lib/exchange.js +12 -7
- package/components/identity.federation/operations/lib/index.js +2 -1
- package/components/identity.federation/operations/lib/jose.js +1 -1
- package/components/identity.federation/operations/lib/principal.js +14 -0
- package/components/identity.federation/operations/lib/resolve.js +1 -1
- package/components/identity.federation/operations/list.js +1 -1
- package/components/identity.federation/operations/types/Scheme.js +1 -1
- package/components/identity.federation/operations/types/configuration.js +1 -1
- package/components/identity.federation/operations/types/context.js +1 -1
- package/components/identity.federation/operations/types/entity.js +1 -1
- package/components/identity.federation/operations/types/index.js +1 -1
- package/components/identity.federation/source/authenticate.ts +9 -3
- package/components/identity.federation/source/incept.ts +7 -1
- package/components/identity.federation/source/lib/Ctx.ts +2 -2
- package/components/identity.federation/source/lib/decode.ts +25 -9
- package/components/identity.federation/source/lib/errors.ts +5 -0
- package/components/identity.federation/source/lib/exchange.ts +11 -7
- package/components/identity.federation/source/lib/index.ts +1 -0
- package/components/identity.federation/source/lib/principal.ts +17 -0
- package/components/identity.federation/source/types/configuration.ts +1 -1
- package/components/identity.federation/source/types/context.ts +6 -2
- package/components/identity.federation/tsconfig.json +4 -2
- package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/types/index.d.ts +3 -0
- package/components/identity.federation/types/toa.d.ts +127 -0
- package/components/identity.grants/manifest.toa.yaml +245 -0
- package/components/identity.grants/operations/authorize.js +54 -0
- package/components/identity.grants/operations/exchange.js +89 -0
- package/components/identity.grants/operations/lib/code.js +30 -0
- package/components/identity.grants/operations/lib/identify.js +15 -0
- package/components/identity.grants/operations/lib/index.js +3 -0
- package/components/identity.grants/operations/list.js +18 -0
- package/components/identity.grants/operations/revoke.js +25 -0
- package/components/identity.grants/source/authorize.ts +90 -0
- package/components/identity.grants/source/exchange.ts +130 -0
- package/components/identity.grants/source/lib/code.ts +39 -0
- package/components/identity.grants/source/lib/identify.ts +16 -0
- package/components/identity.grants/source/lib/index.ts +3 -0
- package/components/identity.grants/source/list.ts +28 -0
- package/components/identity.grants/source/revoke.ts +38 -0
- package/components/identity.grants/tsconfig.json +10 -0
- package/components/identity.grants/tsconfig.tsbuildinfo +1 -0
- package/components/identity.grants/types/index.d.ts +60 -0
- package/components/identity.grants/types/toa.d.ts +108 -0
- package/components/identity.keys/manifest.toa.yaml +1 -0
- package/components/identity.keys/operations/create.js +1 -1
- package/components/identity.keys/operations/disable.js +1 -1
- package/components/identity.keys/operations/revoke.js +1 -1
- package/components/identity.keys/source/create.ts +1 -1
- package/components/identity.keys/source/revoke.ts +1 -1
- package/components/identity.keys/tsconfig.json +1 -1
- package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.keys/types/index.d.ts +3 -0
- package/components/identity.keys/types/toa.d.ts +47 -0
- package/components/identity.otp/operations/authenticate.js +1 -1
- package/components/identity.otp/operations/issue.js +1 -1
- package/components/identity.otp/operations/lib/Context.js +1 -1
- package/components/identity.otp/operations/lib/Entity.js +1 -1
- package/components/identity.otp/operations/lib/index.js +1 -1
- package/components/identity.otp/source/lib/Context.ts +4 -2
- package/components/identity.otp/tsconfig.json +1 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
- package/components/identity.otp/types/index.d.ts +3 -0
- package/components/identity.otp/types/toa.d.ts +56 -0
- package/components/identity.passkeys/manifest.toa.yaml +3 -0
- package/components/identity.passkeys/operations/authenticate.js +1 -1
- package/components/identity.passkeys/operations/challenge.js +1 -1
- package/components/identity.passkeys/operations/create.js +1 -1
- package/components/identity.passkeys/operations/delete.js +1 -1
- package/components/identity.passkeys/operations/lib/const.js +1 -1
- package/components/identity.passkeys/operations/list.js +1 -1
- package/components/identity.passkeys/operations/types/Configuration.js +1 -1
- package/components/identity.passkeys/operations/types/Context.js +1 -1
- package/components/identity.passkeys/operations/types/Passkey.js +1 -1
- package/components/identity.passkeys/operations/types/index.js +1 -1
- package/components/identity.passkeys/operations/use.js +1 -1
- package/components/identity.passkeys/source/authenticate.ts +1 -1
- package/components/identity.passkeys/source/challenge.ts +1 -1
- package/components/identity.passkeys/source/create.ts +1 -1
- package/components/identity.passkeys/source/types/Context.ts +2 -1
- package/components/identity.passkeys/source/use.ts +1 -1
- package/components/identity.passkeys/tsconfig.json +1 -1
- package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/types/index.d.ts +3 -0
- package/components/identity.passkeys/types/toa.d.ts +120 -0
- package/components/identity.roles/operations/grant.js +1 -1
- package/components/identity.roles/operations/lib/Entity.js +1 -1
- package/components/identity.roles/operations/list.js +1 -1
- package/components/identity.roles/operations/principal.js +29 -5
- package/components/identity.roles/source/principal.ts +33 -5
- package/components/identity.roles/tsconfig.json +1 -1
- package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/types/index.d.ts +3 -0
- package/components/identity.roles/types/toa.d.ts +43 -0
- package/components/identity.tokens/manifest.toa.yaml +34 -3
- package/components/identity.tokens/operations/authenticate.js +9 -1
- package/components/identity.tokens/operations/decrypt.js +3 -3
- package/components/identity.tokens/operations/encrypt.js +1 -1
- package/components/identity.tokens/operations/issue.js +3 -2
- package/components/identity.tokens/operations/lib/form.js +24 -0
- package/components/identity.tokens/operations/lib/index.js +2 -2
- package/components/identity.tokens/operations/lib/jose.js +1 -1
- package/components/identity.tokens/operations/lib/key.js +1 -1
- package/components/identity.tokens/operations/lib/pad.js +1 -1
- package/components/identity.tokens/operations/revoke.js +1 -1
- package/components/identity.tokens/source/authenticate.test.ts +8 -5
- package/components/identity.tokens/source/authenticate.ts +12 -1
- package/components/identity.tokens/source/decrypt.test.ts +1 -1
- package/components/identity.tokens/source/decrypt.ts +4 -3
- package/components/identity.tokens/source/encrypt.test.ts +1 -1
- package/components/identity.tokens/source/encrypt.ts +2 -1
- package/components/identity.tokens/source/issue.test.ts +71 -0
- package/components/identity.tokens/source/issue.ts +4 -2
- package/components/identity.tokens/source/lib/form.test.ts +25 -0
- package/components/identity.tokens/source/lib/form.ts +31 -0
- package/components/identity.tokens/source/lib/index.ts +2 -1
- package/components/identity.tokens/tsconfig.json +1 -1
- package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/types/index.d.ts +61 -0
- package/components/identity.tokens/types/toa.d.ts +113 -0
- package/documentation/access.md +13 -0
- package/documentation/cache.md +10 -1
- package/documentation/components.md +3 -0
- package/documentation/consent.md +101 -0
- package/documentation/identity.md +3 -1
- package/documentation/introspection.md +13 -5
- package/documentation/io.md +42 -2
- package/documentation/map.md +8 -0
- package/documentation/mcp.md +180 -0
- package/documentation/oauth.md +180 -0
- package/documentation/protocol.md +4 -0
- package/documentation/rpc.md +140 -0
- package/documentation/tree.md +3 -0
- package/features/auth.bearer.feature +120 -0
- package/features/cache.feature +46 -0
- package/features/identity.basic.feature +44 -0
- package/features/identity.federation.feature +2 -5
- package/features/introspection.feature +333 -0
- package/features/mcp.feature +687 -0
- package/features/oauth.clients.feature +195 -0
- package/features/oauth.discovery.feature +164 -0
- package/features/oauth.grants.feature +299 -0
- package/features/octets.cloudinary.feature +1 -0
- package/features/rpc.feature +429 -0
- package/features/steps/Cloudinary.ts +13 -0
- package/features/steps/Components.ts +0 -4
- package/features/steps/Gateway.ts +23 -2
- package/features/steps/Parameters.ts +22 -7
- package/features/steps/Realtime.ts +3 -0
- package/features/steps/components/echo/manifest.toa.yaml +3 -0
- package/features/steps/components/octets.tester/manifest.toa.yaml +2 -0
- package/features/steps/components/octets.tester/operations/redirect.js +6 -1
- package/features/steps/components/pots/manifest.toa.yaml +2 -0
- package/features/steps/components/users/manifest.toa.yaml +1 -0
- package/package.json +8 -6
- package/readme.md +6 -0
- package/schemas/annotation.cos.yaml +63 -0
- package/schemas/call.cos.yaml +18 -0
- package/source/Annotation.ts +54 -0
- package/source/Directive.test.ts +15 -15
- package/source/Directive.ts +77 -9
- package/source/Endpoint.test.ts +67 -0
- package/source/Endpoint.ts +31 -11
- package/source/Factory.ts +6 -2
- package/source/Gateway.ts +73 -11
- package/source/HTTP/Context.ts +7 -0
- package/source/HTTP/Server.ts +15 -5
- package/source/HTTP/exceptions.ts +2 -2
- package/source/HTTP/formats/form.ts +21 -0
- package/source/HTTP/formats/index.ts +17 -2
- package/source/HTTP/messages.test.ts +25 -1
- package/source/HTTP/messages.ts +20 -4
- package/source/Interception.ts +8 -2
- package/source/Introspection.ts +102 -0
- package/source/MCP/Server.ts +275 -0
- package/source/MCP/discover.ts +52 -0
- package/source/MCP/errors.ts +81 -0
- package/source/MCP/index.ts +1 -0
- package/source/MCP/schema.test.ts +85 -0
- package/source/MCP/schema.ts +87 -0
- package/source/MCP/tools.ts +156 -0
- package/source/MCP/types.ts +81 -0
- package/source/Query.ts +48 -8
- package/source/RPC/Context.ts +78 -0
- package/source/RPC/Dispatcher.ts +130 -0
- package/source/RPC/errors.test.ts +52 -0
- package/source/RPC/errors.ts +83 -0
- package/source/RPC/index.ts +1 -0
- package/source/RPC/names.test.ts +122 -0
- package/source/RPC/names.ts +182 -0
- package/source/RPC/types.ts +34 -0
- package/source/RTD/Directives.ts +52 -2
- package/source/RTD/Endpoint.ts +2 -1
- package/source/RTD/Method.ts +14 -11
- package/source/RTD/Node.ts +38 -7
- package/source/RTD/Route.ts +30 -3
- package/source/RTD/Tree.ts +37 -1
- package/source/RTD/expiration.test.ts +1 -1
- package/source/RTD/walk.test.ts +110 -0
- package/source/const.ts +15 -0
- package/source/deployment.ts +11 -1
- package/source/directives/auth/Anonymous.test.ts +38 -0
- package/source/directives/auth/Anonymous.ts +12 -0
- package/source/directives/auth/Anyone.ts +4 -0
- package/source/directives/auth/Authorization.ts +108 -22
- package/source/directives/auth/Delegate.test.ts +36 -0
- package/source/directives/auth/Delegate.ts +14 -0
- package/source/directives/auth/Echo.ts +5 -0
- package/source/directives/auth/Incept.ts +16 -10
- package/source/directives/auth/Role.ts +13 -0
- package/source/directives/auth/Rule.ts +29 -0
- package/source/directives/auth/Scheme.ts +5 -0
- package/source/directives/auth/schemes.test.ts +8 -4
- package/source/directives/auth/schemes.ts +22 -9
- package/source/directives/auth/types.ts +26 -2
- package/source/directives/cache/Cache.ts +14 -5
- package/source/directives/cache/Control.ts +0 -3
- package/source/directives/dev/Development.ts +1 -1
- package/source/directives/flow/Fetch.ts +1 -1
- package/source/directives/flow/Flow.ts +1 -1
- package/source/directives/index.ts +5 -2
- package/source/directives/io/Directive.ts +1 -1
- package/source/directives/io/IO.ts +34 -3
- package/source/directives/io/Input.ts +3 -2
- package/source/directives/io/Output.ts +10 -4
- package/source/directives/io/Status.test.ts +84 -0
- package/source/directives/io/Status.ts +46 -0
- package/source/directives/io/Throttle.ts +1 -1
- package/source/directives/io/lib/throttle/Quotas.ts +2 -2
- package/source/directives/map/Headers.ts +11 -0
- package/source/directives/map/Map.ts +10 -1
- package/source/directives/map/Mapping.ts +23 -0
- package/source/directives/map/Segments.ts +12 -0
- package/source/directives/mcp/MCP.ts +33 -0
- package/source/directives/mcp/Tool.test.ts +66 -0
- package/source/directives/mcp/Tool.ts +28 -0
- package/source/directives/mcp/index.ts +6 -0
- package/source/directives/oauth/Discovery.ts +70 -0
- package/source/directives/oauth/documents.ts +113 -0
- package/source/directives/oauth/index.ts +3 -0
- package/source/directives/octets/Delete.ts +1 -1
- package/source/directives/octets/Get.ts +1 -1
- package/source/directives/octets/Octets.ts +1 -1
- package/source/directives/octets/Workflow.ts +1 -1
- package/source/directives/octets/workflows/Execution.ts +1 -1
- package/source/directives/require/Directive.ts +1 -1
- package/source/directives/require/Headers.ts +1 -1
- package/source/directives/require/Require.ts +2 -2
- package/source/index.ts +6 -0
- package/source/octets.d.ts +17 -0
- package/source/schemas.ts +2 -0
- package/source/userland.ts +47 -0
- package/transpiled/Annotation.d.ts +41 -0
- package/transpiled/Directive.d.ts +18 -1
- package/transpiled/Directive.js +50 -6
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +9 -0
- package/transpiled/Endpoint.js +27 -11
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.js +6 -2
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +19 -2
- package/transpiled/Gateway.js +51 -9
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +6 -0
- package/transpiled/HTTP/Context.js +6 -0
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/HTTP/Server.d.ts +8 -1
- package/transpiled/HTTP/Server.js +4 -3
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/exceptions.d.ts +1 -1
- package/transpiled/HTTP/exceptions.js +2 -2
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/formats/form.d.ts +9 -0
- package/transpiled/HTTP/formats/form.js +18 -0
- package/transpiled/HTTP/formats/form.js.map +1 -0
- package/transpiled/HTTP/formats/index.d.ts +10 -2
- package/transpiled/HTTP/formats/index.js +10 -0
- package/transpiled/HTTP/formats/index.js.map +1 -1
- package/transpiled/HTTP/messages.d.ts +12 -0
- package/transpiled/HTTP/messages.js +12 -4
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Interception.d.ts +4 -1
- package/transpiled/Interception.js +4 -2
- package/transpiled/Interception.js.map +1 -1
- package/transpiled/Introspection.d.ts +40 -0
- package/transpiled/Introspection.js +50 -1
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/Server.d.ts +41 -0
- package/transpiled/MCP/Server.js +180 -0
- package/transpiled/MCP/Server.js.map +1 -0
- package/transpiled/MCP/discover.d.ts +13 -0
- package/transpiled/MCP/discover.js +29 -0
- package/transpiled/MCP/discover.js.map +1 -0
- package/transpiled/MCP/errors.d.ts +24 -0
- package/transpiled/MCP/errors.js +67 -0
- package/transpiled/MCP/errors.js.map +1 -0
- package/transpiled/MCP/index.d.ts +1 -0
- package/transpiled/MCP/index.js +2 -0
- package/transpiled/MCP/index.js.map +1 -0
- package/transpiled/MCP/schema.d.ts +18 -0
- package/transpiled/MCP/schema.js +64 -0
- package/transpiled/MCP/schema.js.map +1 -0
- package/transpiled/MCP/tools.d.ts +31 -0
- package/transpiled/MCP/tools.js +121 -0
- package/transpiled/MCP/tools.js.map +1 -0
- package/transpiled/MCP/types.d.ts +64 -0
- package/transpiled/MCP/types.js +13 -0
- package/transpiled/MCP/types.js.map +1 -0
- package/transpiled/Query.d.ts +7 -0
- package/transpiled/Query.js +38 -7
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RPC/Context.d.ts +11 -0
- package/transpiled/RPC/Context.js +63 -0
- package/transpiled/RPC/Context.js.map +1 -0
- package/transpiled/RPC/Dispatcher.d.ts +19 -0
- package/transpiled/RPC/Dispatcher.js +100 -0
- package/transpiled/RPC/Dispatcher.js.map +1 -0
- package/transpiled/RPC/errors.d.ts +18 -0
- package/transpiled/RPC/errors.js +67 -0
- package/transpiled/RPC/errors.js.map +1 -0
- package/transpiled/RPC/index.d.ts +1 -0
- package/transpiled/RPC/index.js +2 -0
- package/transpiled/RPC/index.js.map +1 -0
- package/transpiled/RPC/names.d.ts +30 -0
- package/transpiled/RPC/names.js +121 -0
- package/transpiled/RPC/names.js.map +1 -0
- package/transpiled/RPC/types.d.ts +27 -0
- package/transpiled/RPC/types.js +8 -0
- package/transpiled/RPC/types.js.map +1 -0
- package/transpiled/RTD/Directives.d.ts +41 -2
- package/transpiled/RTD/Endpoint.d.ts +2 -1
- package/transpiled/RTD/Method.d.ts +8 -3
- package/transpiled/RTD/Method.js +12 -10
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.d.ts +20 -2
- package/transpiled/RTD/Node.js +22 -4
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Route.d.ts +2 -1
- package/transpiled/RTD/Route.js +27 -2
- package/transpiled/RTD/Route.js.map +1 -1
- package/transpiled/RTD/Tree.d.ts +3 -1
- package/transpiled/RTD/Tree.js +26 -0
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/const.d.ts +12 -0
- package/transpiled/const.js +12 -0
- package/transpiled/const.js.map +1 -1
- package/transpiled/deployment.js +6 -0
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.d.ts +6 -0
- package/transpiled/directives/auth/Anonymous.js +10 -0
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Anyone.d.ts +1 -0
- package/transpiled/directives/auth/Anyone.js +3 -0
- package/transpiled/directives/auth/Anyone.js.map +1 -1
- package/transpiled/directives/auth/Authorization.d.ts +28 -2
- package/transpiled/directives/auth/Authorization.js +87 -19
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.d.ts +5 -0
- package/transpiled/directives/auth/Delegate.js +10 -0
- package/transpiled/directives/auth/Delegate.js.map +1 -1
- package/transpiled/directives/auth/Echo.d.ts +2 -0
- package/transpiled/directives/auth/Echo.js +4 -0
- package/transpiled/directives/auth/Echo.js.map +1 -1
- package/transpiled/directives/auth/Incept.d.ts +1 -1
- package/transpiled/directives/auth/Incept.js +13 -8
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Role.d.ts +2 -0
- package/transpiled/directives/auth/Role.js +9 -0
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/auth/Rule.d.ts +5 -0
- package/transpiled/directives/auth/Rule.js +20 -0
- package/transpiled/directives/auth/Rule.js.map +1 -1
- package/transpiled/directives/auth/Scheme.d.ts +2 -0
- package/transpiled/directives/auth/Scheme.js +4 -0
- package/transpiled/directives/auth/Scheme.js.map +1 -1
- package/transpiled/directives/auth/schemes.d.ts +16 -4
- package/transpiled/directives/auth/schemes.js +20 -8
- package/transpiled/directives/auth/schemes.js.map +1 -1
- package/transpiled/directives/auth/types.d.ts +20 -2
- package/transpiled/directives/cache/Cache.d.ts +1 -1
- package/transpiled/directives/cache/Cache.js +10 -3
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.js +0 -2
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/dev/Development.d.ts +1 -1
- package/transpiled/directives/dev/Development.js +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/flow/Flow.d.ts +1 -1
- package/transpiled/directives/flow/Flow.js +1 -1
- package/transpiled/directives/flow/Flow.js.map +1 -1
- package/transpiled/directives/index.js +4 -2
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/Directive.d.ts +1 -1
- package/transpiled/directives/io/IO.d.ts +7 -1
- package/transpiled/directives/io/IO.js +25 -3
- package/transpiled/directives/io/IO.js.map +1 -1
- package/transpiled/directives/io/Input.d.ts +3 -2
- package/transpiled/directives/io/Input.js +2 -1
- package/transpiled/directives/io/Input.js.map +1 -1
- package/transpiled/directives/io/Output.d.ts +5 -3
- package/transpiled/directives/io/Output.js +8 -3
- package/transpiled/directives/io/Output.js.map +1 -1
- package/transpiled/directives/io/Status.d.ts +19 -0
- package/transpiled/directives/io/Status.js +34 -0
- package/transpiled/directives/io/Status.js.map +1 -0
- package/transpiled/directives/io/Throttle.d.ts +1 -1
- package/transpiled/directives/io/Throttle.js +1 -1
- package/transpiled/directives/io/Throttle.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.d.ts +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.js +2 -2
- package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
- package/transpiled/directives/map/Headers.d.ts +2 -0
- package/transpiled/directives/map/Headers.js +8 -0
- package/transpiled/directives/map/Headers.js.map +1 -1
- package/transpiled/directives/map/Map.d.ts +3 -1
- package/transpiled/directives/map/Map.js +7 -1
- package/transpiled/directives/map/Map.js.map +1 -1
- package/transpiled/directives/map/Mapping.d.ts +13 -0
- package/transpiled/directives/map/Mapping.js +20 -0
- package/transpiled/directives/map/Mapping.js.map +1 -1
- package/transpiled/directives/map/Segments.d.ts +3 -0
- package/transpiled/directives/map/Segments.js +9 -0
- package/transpiled/directives/map/Segments.js.map +1 -1
- package/transpiled/directives/mcp/MCP.d.ts +15 -0
- package/transpiled/directives/mcp/MCP.js +23 -0
- package/transpiled/directives/mcp/MCP.js.map +1 -0
- package/transpiled/directives/mcp/Tool.d.ts +13 -0
- package/transpiled/directives/mcp/Tool.js +23 -0
- package/transpiled/directives/mcp/Tool.js.map +1 -0
- package/transpiled/directives/mcp/index.d.ts +4 -0
- package/transpiled/directives/mcp/index.js +4 -0
- package/transpiled/directives/mcp/index.js.map +1 -0
- package/transpiled/directives/oauth/Discovery.d.ts +23 -0
- package/transpiled/directives/oauth/Discovery.js +55 -0
- package/transpiled/directives/oauth/Discovery.js.map +1 -0
- package/transpiled/directives/oauth/documents.d.ts +9 -0
- package/transpiled/directives/oauth/documents.js +82 -0
- package/transpiled/directives/oauth/documents.js.map +1 -0
- package/transpiled/directives/oauth/index.d.ts +2 -0
- package/transpiled/directives/oauth/index.js +3 -0
- package/transpiled/directives/oauth/index.js.map +1 -0
- package/transpiled/directives/octets/Octets.d.ts +1 -1
- package/transpiled/directives/octets/Octets.js +1 -1
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/require/Directive.d.ts +1 -1
- package/transpiled/directives/require/Headers.d.ts +1 -1
- package/transpiled/directives/require/Headers.js +1 -1
- package/transpiled/directives/require/Headers.js.map +1 -1
- package/transpiled/directives/require/Require.d.ts +1 -1
- package/transpiled/directives/require/Require.js +2 -2
- package/transpiled/directives/require/Require.js.map +1 -1
- package/transpiled/index.d.ts +2 -0
- package/transpiled/schemas.d.ts +2 -0
- package/transpiled/schemas.js +1 -0
- package/transpiled/schemas.js.map +1 -1
- package/transpiled/userland.d.ts +39 -0
- package/transpiled/userland.js +7 -0
- package/transpiled/userland.js.map +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/operations/transit.d.ts +0 -14
- package/components/identity.bans/operations/transit.js.map +0 -1
- package/components/identity.basic/operations/add.d.ts +0 -3
- package/components/identity.basic/operations/add.js.map +0 -1
- package/components/identity.basic/operations/authenticate.d.ts +0 -13
- package/components/identity.basic/operations/authenticate.js.map +0 -1
- package/components/identity.basic/operations/check.d.ts +0 -7
- package/components/identity.basic/operations/check.js.map +0 -1
- package/components/identity.basic/operations/delete.d.ts +0 -7
- package/components/identity.basic/operations/delete.js.map +0 -1
- package/components/identity.basic/operations/incept.d.ts +0 -12
- package/components/identity.basic/operations/incept.js.map +0 -1
- package/components/identity.basic/operations/info.d.ts +0 -10
- package/components/identity.basic/operations/info.js.map +0 -1
- package/components/identity.basic/operations/lib/credentials.d.ts +0 -5
- package/components/identity.basic/operations/lib/credentials.js.map +0 -1
- package/components/identity.basic/operations/transit.d.ts +0 -14
- package/components/identity.basic/operations/transit.js.map +0 -1
- package/components/identity.basic/operations/types.d.ts +0 -61
- package/components/identity.basic/operations/types.js +0 -2
- package/components/identity.basic/operations/types.js.map +0 -1
- package/components/identity.basic/source/types.ts +0 -69
- package/components/identity.credentials/operations/list.d.ts +0 -51
- package/components/identity.credentials/operations/list.js.map +0 -1
- package/components/identity.federation/operations/authenticate.d.ts +0 -16
- package/components/identity.federation/operations/authenticate.js.map +0 -1
- package/components/identity.federation/operations/create.d.ts +0 -8
- package/components/identity.federation/operations/create.js.map +0 -1
- package/components/identity.federation/operations/decode.d.ts +0 -3
- package/components/identity.federation/operations/decode.js.map +0 -1
- package/components/identity.federation/operations/delete.d.ts +0 -8
- package/components/identity.federation/operations/delete.js.map +0 -1
- package/components/identity.federation/operations/incept.d.ts +0 -11
- package/components/identity.federation/operations/incept.js.map +0 -1
- package/components/identity.federation/operations/lib/Configuration.d.ts +0 -39
- package/components/identity.federation/operations/lib/Configuration.js.map +0 -1
- package/components/identity.federation/operations/lib/Ctx.d.ts +0 -8
- package/components/identity.federation/operations/lib/Ctx.js.map +0 -1
- package/components/identity.federation/operations/lib/Payload.d.ts +0 -5
- package/components/identity.federation/operations/lib/Payload.js.map +0 -1
- package/components/identity.federation/operations/lib/decode.d.ts +0 -3
- package/components/identity.federation/operations/lib/decode.js.map +0 -1
- package/components/identity.federation/operations/lib/discovery.d.ts +0 -5
- package/components/identity.federation/operations/lib/discovery.js.map +0 -1
- package/components/identity.federation/operations/lib/errors.d.ts +0 -70
- package/components/identity.federation/operations/lib/errors.js.map +0 -1
- package/components/identity.federation/operations/lib/exchange.d.ts +0 -3
- package/components/identity.federation/operations/lib/exchange.js.map +0 -1
- package/components/identity.federation/operations/lib/index.d.ts +0 -4
- package/components/identity.federation/operations/lib/index.js.map +0 -1
- package/components/identity.federation/operations/lib/jose.d.ts +0 -1
- package/components/identity.federation/operations/lib/jose.js.map +0 -1
- package/components/identity.federation/operations/lib/resolve.d.ts +0 -3
- package/components/identity.federation/operations/lib/resolve.js.map +0 -1
- package/components/identity.federation/operations/list.d.ts +0 -7
- package/components/identity.federation/operations/list.js.map +0 -1
- package/components/identity.federation/operations/types/Scheme.d.ts +0 -1
- package/components/identity.federation/operations/types/Scheme.js.map +0 -1
- package/components/identity.federation/operations/types/configuration.d.ts +0 -22
- package/components/identity.federation/operations/types/configuration.js.map +0 -1
- package/components/identity.federation/operations/types/context.d.ts +0 -35
- package/components/identity.federation/operations/types/context.js.map +0 -1
- package/components/identity.federation/operations/types/entity.d.ts +0 -9
- package/components/identity.federation/operations/types/entity.js.map +0 -1
- package/components/identity.federation/operations/types/index.d.ts +0 -4
- package/components/identity.federation/operations/types/index.js.map +0 -1
- package/components/identity.keys/operations/create.d.ts +0 -22
- package/components/identity.keys/operations/create.js.map +0 -1
- package/components/identity.keys/operations/disable.d.ts +0 -5
- package/components/identity.keys/operations/disable.js.map +0 -1
- package/components/identity.keys/operations/revoke.d.ts +0 -15
- package/components/identity.keys/operations/revoke.js.map +0 -1
- package/components/identity.otp/operations/authenticate.d.ts +0 -12
- package/components/identity.otp/operations/authenticate.js.map +0 -1
- package/components/identity.otp/operations/issue.d.ts +0 -12
- package/components/identity.otp/operations/issue.js.map +0 -1
- package/components/identity.otp/operations/lib/Context.d.ts +0 -14
- package/components/identity.otp/operations/lib/Context.js.map +0 -1
- package/components/identity.otp/operations/lib/Entity.d.ts +0 -6
- package/components/identity.otp/operations/lib/Entity.js.map +0 -1
- package/components/identity.otp/operations/lib/index.d.ts +0 -1
- package/components/identity.otp/operations/lib/index.js.map +0 -1
- package/components/identity.passkeys/operations/authenticate.d.ts +0 -16
- package/components/identity.passkeys/operations/authenticate.js.map +0 -1
- package/components/identity.passkeys/operations/challenge.d.ts +0 -35
- package/components/identity.passkeys/operations/challenge.js.map +0 -1
- package/components/identity.passkeys/operations/create.d.ts +0 -19
- package/components/identity.passkeys/operations/create.js.map +0 -1
- package/components/identity.passkeys/operations/delete.d.ts +0 -8
- package/components/identity.passkeys/operations/delete.js.map +0 -1
- package/components/identity.passkeys/operations/lib/const.d.ts +0 -1
- package/components/identity.passkeys/operations/lib/const.js.map +0 -1
- package/components/identity.passkeys/operations/list.d.ts +0 -7
- package/components/identity.passkeys/operations/list.js.map +0 -1
- package/components/identity.passkeys/operations/types/Configuration.d.ts +0 -6
- package/components/identity.passkeys/operations/types/Configuration.js.map +0 -1
- package/components/identity.passkeys/operations/types/Context.d.ts +0 -15
- package/components/identity.passkeys/operations/types/Context.js.map +0 -1
- package/components/identity.passkeys/operations/types/Passkey.d.ts +0 -12
- package/components/identity.passkeys/operations/types/Passkey.js.map +0 -1
- package/components/identity.passkeys/operations/types/index.d.ts +0 -2
- package/components/identity.passkeys/operations/types/index.js.map +0 -1
- package/components/identity.passkeys/operations/use.d.ts +0 -16
- package/components/identity.passkeys/operations/use.js.map +0 -1
- package/components/identity.roles/operations/grant.d.ts +0 -10
- package/components/identity.roles/operations/grant.js.map +0 -1
- package/components/identity.roles/operations/lib/Entity.d.ts +0 -5
- package/components/identity.roles/operations/lib/Entity.js.map +0 -1
- package/components/identity.roles/operations/list.d.ts +0 -2
- package/components/identity.roles/operations/list.js.map +0 -1
- package/components/identity.roles/operations/principal.d.ts +0 -13
- package/components/identity.roles/operations/principal.js.map +0 -1
- package/components/identity.tokens/operations/authenticate.d.ts +0 -9
- package/components/identity.tokens/operations/authenticate.js.map +0 -1
- package/components/identity.tokens/operations/decrypt.d.ts +0 -15
- package/components/identity.tokens/operations/decrypt.js.map +0 -1
- package/components/identity.tokens/operations/encrypt.d.ts +0 -8
- package/components/identity.tokens/operations/encrypt.js.map +0 -1
- package/components/identity.tokens/operations/issue.d.ts +0 -24
- package/components/identity.tokens/operations/issue.js.map +0 -1
- package/components/identity.tokens/operations/lib/index.d.ts +0 -3
- package/components/identity.tokens/operations/lib/index.js.map +0 -1
- package/components/identity.tokens/operations/lib/jose.d.ts +0 -1
- package/components/identity.tokens/operations/lib/jose.js.map +0 -1
- package/components/identity.tokens/operations/lib/key.d.ts +0 -1
- package/components/identity.tokens/operations/lib/key.js.map +0 -1
- package/components/identity.tokens/operations/lib/pad.d.ts +0 -1
- package/components/identity.tokens/operations/lib/pad.js.map +0 -1
- package/components/identity.tokens/operations/lib/types.d.ts +0 -88
- package/components/identity.tokens/operations/lib/types.js +0 -2
- package/components/identity.tokens/operations/lib/types.js.map +0 -1
- package/components/identity.tokens/operations/revoke.d.ts +0 -2
- package/components/identity.tokens/operations/revoke.js.map +0 -1
- package/components/identity.tokens/source/lib/types.ts +0 -102
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { console } from 'openspan'
|
|
2
|
+
import { BRANCH_TTL } from '../const.js'
|
|
3
|
+
import * as http from '../HTTP/index.js'
|
|
4
|
+
import { discovery, type Discovery } from './discover.js'
|
|
5
|
+
import { call, list, type Scope } from './tools.js'
|
|
6
|
+
import {
|
|
7
|
+
HEADER_MISMATCH,
|
|
8
|
+
INVALID_PARAMS,
|
|
9
|
+
INVALID_REQUEST,
|
|
10
|
+
METHOD_NOT_FOUND,
|
|
11
|
+
PARSE,
|
|
12
|
+
UNSUPPORTED_VERSION,
|
|
13
|
+
failure,
|
|
14
|
+
response
|
|
15
|
+
} from './errors.js'
|
|
16
|
+
import {
|
|
17
|
+
CLIENT_CAPABILITIES,
|
|
18
|
+
JSONRPC,
|
|
19
|
+
LEGACY,
|
|
20
|
+
MODERN,
|
|
21
|
+
PROTOCOL_VERSION,
|
|
22
|
+
SERVER_INFO,
|
|
23
|
+
VERSIONS,
|
|
24
|
+
type Cache,
|
|
25
|
+
type Message,
|
|
26
|
+
type Params
|
|
27
|
+
} from './types.js'
|
|
28
|
+
import type { Tree } from '../RTD/index.js'
|
|
29
|
+
import type { MCP } from '../Annotation.js'
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The Model Context Protocol, as one endpoint that remembers nothing between requests.
|
|
33
|
+
*
|
|
34
|
+
* Two revisions are answered from it. The modern one carries the version and the client's
|
|
35
|
+
* capabilities in every request; the one before it opens with `initialize`, which is what
|
|
36
|
+
* most clients still send. Neither needs a session, and neither needs a stream: every method
|
|
37
|
+
* here answers one object, which is why this can exist in a package that serves no SSE.
|
|
38
|
+
*/
|
|
39
|
+
export class Server {
|
|
40
|
+
private readonly options: MCP
|
|
41
|
+
private readonly tree: Tree
|
|
42
|
+
private readonly discovery: Discovery
|
|
43
|
+
private readonly origins: Set<string>
|
|
44
|
+
|
|
45
|
+
public constructor (options: MCP, tree: Tree) {
|
|
46
|
+
this.options = options
|
|
47
|
+
this.tree = tree
|
|
48
|
+
this.discovery = discovery(options)
|
|
49
|
+
this.origins = new Set(options.origins ?? [])
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async process (context: http.Context,
|
|
53
|
+
route: http.Processor): Promise<http.OutgoingMessage> {
|
|
54
|
+
if (context.request.method !== 'POST')
|
|
55
|
+
throw new http.MethodNotAllowed(new Headers({ allow: 'POST' }))
|
|
56
|
+
|
|
57
|
+
this.admit(context)
|
|
58
|
+
|
|
59
|
+
const message = await this.read(context)
|
|
60
|
+
const version = this.version(context, message)
|
|
61
|
+
const modern = version === MODERN
|
|
62
|
+
|
|
63
|
+
if (modern)
|
|
64
|
+
this.mirrored(context, message)
|
|
65
|
+
|
|
66
|
+
const result = await this.answer({ context, route, tree: this.tree }, message, modern)
|
|
67
|
+
|
|
68
|
+
// a notification is answered by not answering, and there is nothing here to remember
|
|
69
|
+
if (message.id === undefined)
|
|
70
|
+
return { status: ACCEPTED }
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
status: OK,
|
|
74
|
+
body: { jsonrpc: JSONRPC, id: message.id, result },
|
|
75
|
+
headers: new Headers({ 'cache-control': 'no-store' })
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Who may reach the endpoint at all, before anything it carries is read. */
|
|
80
|
+
private admit (context: http.Context): void {
|
|
81
|
+
const origin = context.request.headers.origin
|
|
82
|
+
|
|
83
|
+
// the revision requires this against DNS rebinding; a request without one is no browser's
|
|
84
|
+
if (origin !== undefined && !this.origins.has(origin))
|
|
85
|
+
throw new http.Forbidden('Origin is not allowed')
|
|
86
|
+
|
|
87
|
+
if (this.options.anonymous === true)
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
if ((context as { identity?: unknown }).identity == null)
|
|
91
|
+
throw new http.Unauthorized()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private async answer (scope: Scope, message: Message, modern: boolean): Promise<unknown> {
|
|
95
|
+
const params = message.params ?? {}
|
|
96
|
+
|
|
97
|
+
switch (message.method) {
|
|
98
|
+
case 'server/discover':
|
|
99
|
+
return this.complete(this.discovery.modern, modern, DISCOVERY_CACHE)
|
|
100
|
+
|
|
101
|
+
case 'tools/list':
|
|
102
|
+
return this.complete({ tools: await list(this.tree, scope.context) }, modern, TOOLS_CACHE)
|
|
103
|
+
|
|
104
|
+
case 'tools/call':
|
|
105
|
+
return this.complete(await this.tool(scope, params), modern)
|
|
106
|
+
|
|
107
|
+
// what a client of an earlier revision opens with; no session is made and none is named
|
|
108
|
+
case 'initialize':
|
|
109
|
+
return this.discovery.legacy(declared(params))
|
|
110
|
+
|
|
111
|
+
case 'notifications/initialized':
|
|
112
|
+
return null
|
|
113
|
+
|
|
114
|
+
case 'ping':
|
|
115
|
+
return {}
|
|
116
|
+
|
|
117
|
+
default:
|
|
118
|
+
throw new http.NotFound(response(message.id ?? null,
|
|
119
|
+
failure(METHOD_NOT_FOUND, `'${message.method}' is not a method this server answers`)))
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private async tool (scope: Scope, params: Params): Promise<object> {
|
|
124
|
+
const named = params.name
|
|
125
|
+
|
|
126
|
+
if (typeof named !== 'string')
|
|
127
|
+
throw new http.BadRequest(response(null,
|
|
128
|
+
failure(INVALID_PARAMS, '`tools/call` states the tool it calls by name')))
|
|
129
|
+
|
|
130
|
+
const args = params.arguments ?? {}
|
|
131
|
+
|
|
132
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args))
|
|
133
|
+
throw new http.BadRequest(response(null,
|
|
134
|
+
failure(INVALID_PARAMS, '`arguments` must be an object')))
|
|
135
|
+
|
|
136
|
+
return await console.span({ name: named },
|
|
137
|
+
async () => await call(scope, named, args as Params))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Every result of the modern revision says what kind it is, and who answered it. Where the
|
|
142
|
+
* revision names the operation as one whose result may be held, it says that too, and must.
|
|
143
|
+
*/
|
|
144
|
+
private complete (result: object, modern: boolean, cache?: Cache): object {
|
|
145
|
+
return modern
|
|
146
|
+
? { ...result, ...cache, resultType: 'complete', _meta: { [SERVER_INFO]: this.serverInfo() } }
|
|
147
|
+
: result
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private serverInfo (): unknown {
|
|
151
|
+
return (this.discovery.modern as { _meta: Record<string, unknown> })._meta[SERVER_INFO]
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Which revision this request is of. `initialize` is one by itself; otherwise the header
|
|
156
|
+
* says, and a request that names none is of a revision that did not send one.
|
|
157
|
+
*/
|
|
158
|
+
private version (context: http.Context, message: Message): string {
|
|
159
|
+
if (message.method === 'initialize')
|
|
160
|
+
return LEGACY
|
|
161
|
+
|
|
162
|
+
const header = context.request.headers['mcp-protocol-version']
|
|
163
|
+
const stated = declared(message.params ?? {})
|
|
164
|
+
|
|
165
|
+
if (header !== undefined && stated !== undefined && header !== stated)
|
|
166
|
+
throw new http.BadRequest(response(message.id ?? null, failure(HEADER_MISMATCH,
|
|
167
|
+
`'MCP-Protocol-Version' says '${String(header)}' and the body says '${stated}'`)))
|
|
168
|
+
|
|
169
|
+
const value = (header as string | undefined) ?? stated
|
|
170
|
+
|
|
171
|
+
if (value === undefined)
|
|
172
|
+
return LEGACY
|
|
173
|
+
|
|
174
|
+
if (!VERSIONS.includes(value))
|
|
175
|
+
throw new http.BadRequest(response(message.id ?? null,
|
|
176
|
+
failure(UNSUPPORTED_VERSION, 'Unsupported protocol version',
|
|
177
|
+
{ supported: VERSIONS, requested: value })))
|
|
178
|
+
|
|
179
|
+
return value
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* What the modern revision mirrors into headers, so that what routes a request and what
|
|
184
|
+
* answers it cannot be told two different things.
|
|
185
|
+
*/
|
|
186
|
+
private mirrored (context: http.Context, message: Message): void {
|
|
187
|
+
const meta = metadata(message.params ?? {})
|
|
188
|
+
|
|
189
|
+
if (meta?.[PROTOCOL_VERSION] === undefined || meta[CLIENT_CAPABILITIES] === undefined)
|
|
190
|
+
throw new http.BadRequest(response(message.id ?? null, failure(INVALID_PARAMS,
|
|
191
|
+
`'_meta' states '${PROTOCOL_VERSION}' and '${CLIENT_CAPABILITIES}'`)))
|
|
192
|
+
|
|
193
|
+
const id = message.id ?? null
|
|
194
|
+
|
|
195
|
+
mirrors(context, { id, header: 'mcp-method', value: message.method })
|
|
196
|
+
|
|
197
|
+
if (message.method === 'tools/call')
|
|
198
|
+
mirrors(context, { id, header: 'mcp-name', value: (message.params ?? {}).name })
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** A body the decoder refuses is a parse error; a media type it does not know is not. */
|
|
202
|
+
private async read (context: http.Context): Promise<Message> {
|
|
203
|
+
let body: unknown
|
|
204
|
+
|
|
205
|
+
try {
|
|
206
|
+
body = await context.body()
|
|
207
|
+
} catch (exception) {
|
|
208
|
+
if (exception instanceof http.BadRequest)
|
|
209
|
+
throw new http.BadRequest(response(null, failure(PARSE, 'Parse error')))
|
|
210
|
+
|
|
211
|
+
throw exception
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (typeof body !== 'object' || body === null || Array.isArray(body) ||
|
|
215
|
+
(body as Message).jsonrpc !== JSONRPC || typeof (body as Message).method !== 'string')
|
|
216
|
+
throw new http.BadRequest(response(null,
|
|
217
|
+
failure(INVALID_REQUEST, 'A request carries one JSON-RPC message')))
|
|
218
|
+
|
|
219
|
+
return body as Message
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** What a header says must be what the body says, or what routes and what answers differ. */
|
|
224
|
+
function mirrors (context: http.Context, mirror: Mirror): void {
|
|
225
|
+
const { id, header, value } = mirror
|
|
226
|
+
const stated = context.request.headers[header]
|
|
227
|
+
|
|
228
|
+
if (stated === undefined)
|
|
229
|
+
throw new http.BadRequest(response(id, failure(HEADER_MISMATCH, `'${header}' is required`)))
|
|
230
|
+
|
|
231
|
+
if (decode(String(stated)) !== value)
|
|
232
|
+
throw new http.BadRequest(response(id, failure(HEADER_MISMATCH,
|
|
233
|
+
`'${header}' says '${String(stated)}' and the body says '${String(value)}'`)))
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
interface Mirror {
|
|
237
|
+
id: string | number | null
|
|
238
|
+
header: string
|
|
239
|
+
value: unknown
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function metadata (params: Params): Record<string, unknown> | undefined {
|
|
243
|
+
const meta = params._meta
|
|
244
|
+
|
|
245
|
+
return typeof meta === 'object' && meta !== null
|
|
246
|
+
? meta as Record<string, unknown>
|
|
247
|
+
: undefined
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function declared (params: Params): string | undefined {
|
|
251
|
+
const stated = metadata(params)?.[PROTOCOL_VERSION]
|
|
252
|
+
|
|
253
|
+
return typeof stated === 'string' ? stated : undefined
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** What a header value that could not be written as ASCII was encoded as. */
|
|
257
|
+
function decode (value: string): string {
|
|
258
|
+
if (!value.startsWith(SENTINEL) || !value.endsWith(TERMINATOR))
|
|
259
|
+
return value
|
|
260
|
+
|
|
261
|
+
const encoded = value.slice(SENTINEL.length, -TERMINATOR.length)
|
|
262
|
+
|
|
263
|
+
return Buffer.from(encoded, 'base64').toString('utf8')
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** A tool list is what the tree holds, which stands until a branch of it expires. */
|
|
267
|
+
const TOOLS_CACHE: Cache = { ttlMs: BRANCH_TTL, cacheScope: 'private' }
|
|
268
|
+
|
|
269
|
+
/** What the annotation says, which is the same for every caller until the application is redeployed. */
|
|
270
|
+
const DISCOVERY_CACHE: Cache = { ttlMs: BRANCH_TTL, cacheScope: 'public' }
|
|
271
|
+
|
|
272
|
+
const OK = 200
|
|
273
|
+
const ACCEPTED = 202
|
|
274
|
+
const SENTINEL = '=?base64?'
|
|
275
|
+
const TERMINATOR = '?='
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { LEGACY, MODERN, SERVER_INFO, VERSIONS } from './types.js'
|
|
3
|
+
import type { MCP } from '../Annotation.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* What a client is told before it calls anything: the revisions served, what is served, and
|
|
7
|
+
* who serves it. It is a function of the annotation alone, so it is built once and answered
|
|
8
|
+
* as it is.
|
|
9
|
+
*/
|
|
10
|
+
export interface Discovery {
|
|
11
|
+
/** `server/discover`, which the modern revision has replaced the handshake with. */
|
|
12
|
+
modern: object
|
|
13
|
+
|
|
14
|
+
/** `initialize`, in the shape a client of an earlier revision reads. */
|
|
15
|
+
legacy: (offered: string | undefined) => object
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function discovery (options: MCP): Discovery {
|
|
19
|
+
const info = { name: options.name, version: VERSION }
|
|
20
|
+
|
|
21
|
+
// `listChanged` is a stream a client holds open, and this endpoint holds none
|
|
22
|
+
const capabilities = { tools: {} }
|
|
23
|
+
|
|
24
|
+
const modern: Record<string, unknown> = {
|
|
25
|
+
supportedVersions: VERSIONS,
|
|
26
|
+
capabilities,
|
|
27
|
+
_meta: { [SERVER_INFO]: info }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (options.instructions !== undefined)
|
|
31
|
+
modern.instructions = options.instructions
|
|
32
|
+
|
|
33
|
+
function legacy (offered: string | undefined): object {
|
|
34
|
+
const value: Record<string, unknown> = {
|
|
35
|
+
// what the client asked for where that is served, and the newest handshake otherwise
|
|
36
|
+
protocolVersion: offered !== undefined && offered !== MODERN ? offered : LEGACY,
|
|
37
|
+
capabilities,
|
|
38
|
+
serverInfo: info
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (options.instructions !== undefined)
|
|
42
|
+
value.instructions = options.instructions
|
|
43
|
+
|
|
44
|
+
return value
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { modern, legacy }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** What this gateway is, which is what answers however an application names itself. */
|
|
51
|
+
const VERSION: string = JSON.parse(
|
|
52
|
+
readFileSync(new URL('../../package.json', import.meta.url), 'utf8')).version
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as http from '../HTTP/index.js'
|
|
2
|
+
import { JSONRPC, type Failure, type Response } from './types.js'
|
|
3
|
+
|
|
4
|
+
/* The five JSON-RPC 2.0 fixes, which mean the same to every client. */
|
|
5
|
+
export const PARSE = -32700
|
|
6
|
+
export const INVALID_REQUEST = -32600
|
|
7
|
+
export const METHOD_NOT_FOUND = -32601
|
|
8
|
+
export const INVALID_PARAMS = -32602
|
|
9
|
+
export const INTERNAL = -32603
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* MCP's own. It reserves -32020 to -32099 for the specification and tells an implementation
|
|
13
|
+
* to use nothing of -32000 to -32019 at all — which is where this gateway's JSON-RPC codes
|
|
14
|
+
* sit, so none of them is answered here.
|
|
15
|
+
*/
|
|
16
|
+
export const HEADER_MISMATCH = -32020
|
|
17
|
+
export const MISSING_CAPABILITY = -32021
|
|
18
|
+
export const UNSUPPORTED_VERSION = -32022
|
|
19
|
+
|
|
20
|
+
export function failure (code: number, message: string, data?: unknown): Failure {
|
|
21
|
+
const value: Failure = { code, message }
|
|
22
|
+
|
|
23
|
+
if (data !== undefined)
|
|
24
|
+
value.data = data
|
|
25
|
+
|
|
26
|
+
return value
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function response (id: string | number | null, error: Failure): Response {
|
|
30
|
+
return { jsonrpc: JSONRPC, id, error }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* What an exception says as a JSON-RPC error.
|
|
35
|
+
*
|
|
36
|
+
* The readable text is `body`, never `message`: `http.Exception` calls `super()` with no
|
|
37
|
+
* argument, so every one of them carries an empty `message`.
|
|
38
|
+
*/
|
|
39
|
+
export function of (exception: unknown): Failure {
|
|
40
|
+
if (exception instanceof http.NotFound || exception instanceof http.MethodNotAllowed)
|
|
41
|
+
return failure(METHOD_NOT_FOUND, text(exception, 'Method not found'))
|
|
42
|
+
|
|
43
|
+
if (exception instanceof http.BadRequest)
|
|
44
|
+
return failure(INVALID_PARAMS, text(exception, 'Invalid params'))
|
|
45
|
+
|
|
46
|
+
return failure(INTERNAL, 'Internal error')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* What the call was refused with, which a model reads and may correct itself by: what the
|
|
51
|
+
* operation said, where it said anything, and otherwise what the status means here.
|
|
52
|
+
*/
|
|
53
|
+
export function refusal (exception: http.ClientError): string {
|
|
54
|
+
const body = exception.body
|
|
55
|
+
|
|
56
|
+
if (typeof body !== 'object' || body === null || typeof body.code !== 'string')
|
|
57
|
+
return text(exception, REFUSALS[exception.status] ?? 'Refused')
|
|
58
|
+
|
|
59
|
+
const message = body.message as unknown
|
|
60
|
+
|
|
61
|
+
return typeof message === 'string' && message !== '' ? message : body.code as string
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A refusal a model can act on, where the reply carried no words of its own. `auth` does
|
|
66
|
+
* not say which of its directives refused, and `auth:id` is what most of them are: a call
|
|
67
|
+
* naming a record that is not the caller's is the likeliest thing to have gone wrong.
|
|
68
|
+
*/
|
|
69
|
+
const REFUSALS: Record<number, string> = {
|
|
70
|
+
400: 'The arguments were refused',
|
|
71
|
+
403: "Not authorized. If an argument names an identity or a record, it may not be the caller's own",
|
|
72
|
+
404: 'There is nothing at that address',
|
|
73
|
+
409: 'The record changed while the call was made',
|
|
74
|
+
429: 'Too many calls'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function text (exception: http.Exception, fallback: string): string {
|
|
78
|
+
return typeof exception.body === 'string' && exception.body !== ''
|
|
79
|
+
? exception.body
|
|
80
|
+
: fallback
|
|
81
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Server } from './Server.js'
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
4
|
+
import { annotations, input, output } from './schema.js'
|
|
5
|
+
import type { Introspection, Schema } from '../Introspection.js'
|
|
6
|
+
|
|
7
|
+
const schema = (value: object): Schema => value as unknown as Schema
|
|
8
|
+
|
|
9
|
+
describe('input', () => {
|
|
10
|
+
it('should ask for a route variable by the name the template gives it', () => {
|
|
11
|
+
assert.deepEqual(input({ route: { id: schema({ type: 'string' }) } }, ['id']), {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: { id: { type: 'string' } },
|
|
14
|
+
required: ['id'],
|
|
15
|
+
additionalProperties: false
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('should ask for a variable the operation does not declare', () => {
|
|
20
|
+
assert.deepEqual(input({}, ['id']), {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: { id: { type: 'string' } },
|
|
23
|
+
required: ['id'],
|
|
24
|
+
additionalProperties: false
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should carry the querystring under a name of its own', () => {
|
|
29
|
+
const introspection: Introspection = { query: { limit: schema({ type: 'integer' }) } }
|
|
30
|
+
const { properties } = input(introspection, []) as { properties: Record<string, any> }
|
|
31
|
+
|
|
32
|
+
assert.equal(properties.query.type, 'object')
|
|
33
|
+
assert.deepEqual(properties.query.properties, { limit: { type: 'integer' } })
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should leave a header where a call has nowhere to put one', () => {
|
|
37
|
+
const introspection: Introspection = {
|
|
38
|
+
headers: { token: { header: 'x-access-token', type: 'string' } }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
assert.deepEqual(input(introspection, []),
|
|
42
|
+
{ type: 'object', properties: {}, additionalProperties: false })
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('should take the body as it is, requiring what it requires', () => {
|
|
46
|
+
const introspection: Introspection = {
|
|
47
|
+
input: schema({
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: { title: { type: 'string' }, volume: { type: 'number' } },
|
|
50
|
+
required: ['title']
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
assert.deepEqual(input(introspection, []), {
|
|
55
|
+
type: 'object',
|
|
56
|
+
properties: { title: { type: 'string' }, volume: { type: 'number' } },
|
|
57
|
+
required: ['title'],
|
|
58
|
+
additionalProperties: false
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe('output', () => {
|
|
64
|
+
it('should state a schema the operation declared', () => {
|
|
65
|
+
const declared = schema({ type: 'object', properties: { id: { type: 'string' } } })
|
|
66
|
+
|
|
67
|
+
assert.deepEqual(output({ output: declared }), declared)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('should state none where the operation declared none', () => {
|
|
71
|
+
// an operation's `output` is optional and normalizes to `{}`, which describes nothing
|
|
72
|
+
assert.equal(output({ output: schema({}) }), undefined)
|
|
73
|
+
assert.equal(output({}), undefined)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('annotations', () => {
|
|
78
|
+
it('should read what the verb says of the call', () => {
|
|
79
|
+
assert.deepEqual(annotations('GET'), { readOnlyHint: true })
|
|
80
|
+
assert.deepEqual(annotations('HEAD'), { readOnlyHint: true })
|
|
81
|
+
assert.deepEqual(annotations('DELETE'), { destructiveHint: true, idempotentHint: true })
|
|
82
|
+
assert.deepEqual(annotations('PUT'), { idempotentHint: true })
|
|
83
|
+
assert.equal(annotations('POST'), undefined)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Introspection, Schema } from '../Introspection.js'
|
|
2
|
+
import type { Annotations } from './types.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* What a tool takes, which is what the procedure takes: a route variable by the name the
|
|
6
|
+
* template gives it, the querystring under a name of its own, and what is left is the body.
|
|
7
|
+
*
|
|
8
|
+
* A `map:headers` property is not here: a call carries no headers of its own, so there is
|
|
9
|
+
* nowhere for a model to put one.
|
|
10
|
+
*/
|
|
11
|
+
export function input (introspection: Introspection, variables: string[]): object {
|
|
12
|
+
const properties: Record<string, unknown> = {}
|
|
13
|
+
const required: string[] = []
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* By the name the template gives it, which is what the tool's own name states and what
|
|
17
|
+
* resolving it consumes. A `map:segments` renaming is the gateway's, as invisible here as
|
|
18
|
+
* it is to whoever writes the path; and a variable the operation does not declare has no
|
|
19
|
+
* schema of its own, being a segment.
|
|
20
|
+
*/
|
|
21
|
+
for (const variable of variables) {
|
|
22
|
+
properties[variable] = introspection.route?.[variable] ?? { type: 'string' }
|
|
23
|
+
required.push(variable)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// it is a querystring on the wire, which is nothing a model knows or needs to; what it
|
|
27
|
+
// is to a caller is the part of a call that picks what the call is about
|
|
28
|
+
if (introspection.query !== undefined)
|
|
29
|
+
properties.query = {
|
|
30
|
+
type: 'object',
|
|
31
|
+
description: 'Which records the call works on: what to match, in what order, ' +
|
|
32
|
+
'and how many at once.',
|
|
33
|
+
properties: introspection.query
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const body = introspection.input as Shape | null | undefined
|
|
37
|
+
|
|
38
|
+
if (body?.properties !== undefined) {
|
|
39
|
+
Object.assign(properties, body.properties)
|
|
40
|
+
required.push(...body.required ?? [])
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const schema: Record<string, unknown> = { type: 'object', properties }
|
|
44
|
+
|
|
45
|
+
if (required.length > 0)
|
|
46
|
+
schema.required = required
|
|
47
|
+
|
|
48
|
+
// what a name does not state is not a parameter, and a model should not invent one
|
|
49
|
+
schema.additionalProperties = false
|
|
50
|
+
|
|
51
|
+
return schema
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* What a tool answers with, where that is worth stating. An operation's `output` is optional
|
|
56
|
+
* and normalizes to `{}`, which describes nothing — and a schema the revision would have the
|
|
57
|
+
* reply validated against is worse said emptily than left unsaid.
|
|
58
|
+
*/
|
|
59
|
+
export function output (introspection: Introspection): object | undefined {
|
|
60
|
+
const schema = introspection.output as Shape | null | undefined
|
|
61
|
+
|
|
62
|
+
if (schema === undefined || schema === null)
|
|
63
|
+
return undefined
|
|
64
|
+
|
|
65
|
+
return Object.keys(schema).length === 0 ? undefined : schema as object
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** What the verb says of the call, which the revision has a client treat as a hint. */
|
|
69
|
+
export function annotations (verb: string): Annotations | undefined {
|
|
70
|
+
const value: Annotations = {}
|
|
71
|
+
|
|
72
|
+
if (verb === 'GET' || verb === 'HEAD')
|
|
73
|
+
value.readOnlyHint = true
|
|
74
|
+
|
|
75
|
+
if (verb === 'DELETE')
|
|
76
|
+
value.destructiveHint = true
|
|
77
|
+
|
|
78
|
+
if (verb === 'PUT' || verb === 'DELETE')
|
|
79
|
+
value.idempotentHint = true
|
|
80
|
+
|
|
81
|
+
return Object.keys(value).length === 0 ? undefined : value
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface Shape {
|
|
85
|
+
properties?: Record<string, Schema>
|
|
86
|
+
required?: string[]
|
|
87
|
+
}
|