memory-journal-mcp 6.1.2 → 6.2.1
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/README.md +44 -28
- package/dist/{chunk-X4SWFATC.js → chunk-BI4ZNSKA.js} +38 -24
- package/dist/{chunk-HCEWINSB.js → chunk-N6EBIDN7.js} +99 -102
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/tools-WPRY5MJ6.js +2 -0
- package/package.json +10 -1
- package/skills/github-commander/SKILL.md +151 -0
- package/skills/github-commander/config/project-config.example.md +125 -0
- package/skills/github-commander/workflows/code-quality-audit.md +80 -0
- package/skills/github-commander/workflows/full-audit.md +134 -0
- package/skills/github-commander/workflows/issue-triage.md +239 -0
- package/skills/github-commander/workflows/milestone-sprint.md +81 -0
- package/skills/github-commander/workflows/perf-audit.md +142 -0
- package/skills/github-commander/workflows/pr-review.md +123 -0
- package/skills/github-commander/workflows/security-audit.md +170 -0
- package/skills/github-commander/workflows/update-deps.md +109 -0
- package/.dockerignore +0 -139
- package/.gitattributes +0 -20
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -95
- package/.github/ISSUE_TEMPLATE/config.yml +0 -11
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -110
- package/.github/ISSUE_TEMPLATE/question.md +0 -78
- package/.github/aw/actions-lock.json +0 -14
- package/.github/copilot-instructions.md +0 -122
- package/.github/dependabot.yml +0 -93
- package/.github/pull_request_template.md +0 -135
- package/.github/workflows/README.md +0 -133
- package/.github/workflows/agentics-maintenance.yml +0 -141
- package/.github/workflows/auto-release.yml +0 -68
- package/.github/workflows/ci-health-monitor.lock.yml +0 -1121
- package/.github/workflows/ci-health-monitor.md +0 -87
- package/.github/workflows/codeql.yml +0 -41
- package/.github/workflows/dependabot-auto-merge.yml +0 -42
- package/.github/workflows/dependency-maintenance.lock.yml +0 -1182
- package/.github/workflows/dependency-maintenance.md +0 -147
- package/.github/workflows/docker-publish.yml +0 -254
- package/.github/workflows/docs-drift-detector.lock.yml +0 -1142
- package/.github/workflows/docs-drift-detector.md +0 -115
- package/.github/workflows/lint-and-test.yml +0 -60
- package/.github/workflows/publish-npm.yml +0 -85
- package/.github/workflows/secrets-scanning.yml +0 -32
- package/.github/workflows/security-update.yml +0 -127
- package/.gitleaks.toml +0 -9
- package/.prettierignore +0 -21
- package/.prettierrc +0 -33
- package/.scout-ignore +0 -12
- package/.trivyignore +0 -21
- package/CHANGELOG.md +0 -1814
- package/CODE_OF_CONDUCT.md +0 -133
- package/CONTRIBUTING.md +0 -263
- package/DOCKER_README.md +0 -331
- package/Dockerfile +0 -128
- package/SECURITY.md +0 -227
- package/UNRELEASED.md +0 -1
- package/dist/tools-T4U5A3X4.js +0 -2
- package/docker-compose.yml +0 -71
- package/docs/README.md +0 -18
- package/docs/agentic-journal-synergy.md +0 -175
- package/docs/copilot-setup.md +0 -72
- package/eslint.config.js +0 -110
- package/mcp-config-example.json +0 -21
- package/playwright.config.ts +0 -35
- package/releases/v2.1.0.md +0 -220
- package/releases/v2.2.0.md +0 -168
- package/releases/v3.0.0.md +0 -237
- package/releases/v3.1.0.md +0 -104
- package/releases/v3.1.1.md +0 -42
- package/releases/v3.1.2.md +0 -40
- package/releases/v3.1.3.md +0 -64
- package/releases/v3.1.4.md +0 -32
- package/releases/v3.1.5.md +0 -44
- package/releases/v4.0.0.md +0 -71
- package/releases/v4.1.0.md +0 -88
- package/releases/v4.2.0.md +0 -90
- package/releases/v4.3.0.md +0 -92
- package/releases/v4.3.1.md +0 -69
- package/releases/v4.4.0.md +0 -120
- package/releases/v4.4.1.md +0 -33
- package/releases/v4.4.2.md +0 -31
- package/releases/v4.5.0.md +0 -116
- package/releases/v5.0.0.md +0 -105
- package/releases/v5.0.1.md +0 -25
- package/releases/v5.1.0.md +0 -83
- package/releases/v5.1.1.md +0 -10
- package/releases/v6.0.0.md +0 -48
- package/releases/v6.0.1.md +0 -36
- package/releases/v6.1.0.md +0 -68
- package/releases/v6.1.1.md +0 -30
- package/releases/v6.1.2.md +0 -23
- package/scripts/generate-server-instructions.ts +0 -306
- package/scripts/server-instructions-function-body.ts +0 -107
- package/scripts/server-instructions-gotchas.ts +0 -45
- package/server.json +0 -42
- package/social-preview.png +0 -0
- package/src/auth/auth-context.ts +0 -78
- package/src/auth/authorization-server-discovery.ts +0 -263
- package/src/auth/errors.ts +0 -215
- package/src/auth/index.ts +0 -58
- package/src/auth/middleware.ts +0 -392
- package/src/auth/oauth-resource-server.ts +0 -170
- package/src/auth/scope-map.ts +0 -46
- package/src/auth/scopes.ts +0 -256
- package/src/auth/token-validator.ts +0 -293
- package/src/auth/transport-agnostic.ts +0 -164
- package/src/auth/types.ts +0 -372
- package/src/cli.ts +0 -279
- package/src/codemode/api-constants.ts +0 -263
- package/src/codemode/api.ts +0 -302
- package/src/codemode/auto-return.ts +0 -65
- package/src/codemode/index.ts +0 -47
- package/src/codemode/sandbox-factory.ts +0 -144
- package/src/codemode/sandbox.ts +0 -220
- package/src/codemode/security.ts +0 -155
- package/src/codemode/types.ts +0 -228
- package/src/codemode/worker-sandbox.ts +0 -277
- package/src/codemode/worker-script.ts +0 -239
- package/src/constants/icons.ts +0 -183
- package/src/constants/server-instructions.md +0 -166
- package/src/constants/server-instructions.ts +0 -514
- package/src/database/adapter-factory.ts +0 -16
- package/src/database/core/entry-columns.ts +0 -10
- package/src/database/core/interfaces.ts +0 -188
- package/src/database/core/schema.ts +0 -152
- package/src/database/sqlite-adapter/backup.ts +0 -167
- package/src/database/sqlite-adapter/entries/crud.ts +0 -233
- package/src/database/sqlite-adapter/entries/importance.ts +0 -76
- package/src/database/sqlite-adapter/entries/index.ts +0 -142
- package/src/database/sqlite-adapter/entries/search.ts +0 -294
- package/src/database/sqlite-adapter/entries/shared.ts +0 -102
- package/src/database/sqlite-adapter/entries/statistics.ts +0 -162
- package/src/database/sqlite-adapter/index.ts +0 -265
- package/src/database/sqlite-adapter/native-connection.ts +0 -301
- package/src/database/sqlite-adapter/relationships.ts +0 -70
- package/src/database/sqlite-adapter/tags.ts +0 -182
- package/src/filtering/tool-filter.ts +0 -312
- package/src/github/github-integration/client.ts +0 -114
- package/src/github/github-integration/index.ts +0 -297
- package/src/github/github-integration/insights.ts +0 -155
- package/src/github/github-integration/issues.ts +0 -213
- package/src/github/github-integration/milestones.ts +0 -262
- package/src/github/github-integration/projects.ts +0 -414
- package/src/github/github-integration/pull-requests.ts +0 -235
- package/src/github/github-integration/repository.ts +0 -110
- package/src/github/github-integration/types.ts +0 -43
- package/src/handlers/prompts/github.ts +0 -210
- package/src/handlers/prompts/index.ts +0 -97
- package/src/handlers/prompts/workflow.ts +0 -361
- package/src/handlers/resources/core/briefing/context-section.ts +0 -182
- package/src/handlers/resources/core/briefing/github-section.ts +0 -354
- package/src/handlers/resources/core/briefing/index.ts +0 -106
- package/src/handlers/resources/core/briefing/user-message.ts +0 -114
- package/src/handlers/resources/core/health.ts +0 -75
- package/src/handlers/resources/core/index.ts +0 -31
- package/src/handlers/resources/core/instructions.ts +0 -45
- package/src/handlers/resources/core/utilities.ts +0 -310
- package/src/handlers/resources/github.ts +0 -340
- package/src/handlers/resources/graph.ts +0 -218
- package/src/handlers/resources/help.ts +0 -410
- package/src/handlers/resources/index.ts +0 -143
- package/src/handlers/resources/shared.ts +0 -219
- package/src/handlers/resources/team.ts +0 -134
- package/src/handlers/resources/templates.ts +0 -334
- package/src/handlers/tools/admin.ts +0 -351
- package/src/handlers/tools/analytics.ts +0 -346
- package/src/handlers/tools/backup.ts +0 -272
- package/src/handlers/tools/codemode.ts +0 -188
- package/src/handlers/tools/core.ts +0 -359
- package/src/handlers/tools/error-fields-mixin.ts +0 -10
- package/src/handlers/tools/export.ts +0 -150
- package/src/handlers/tools/github/copilot-tools.ts +0 -72
- package/src/handlers/tools/github/helpers.ts +0 -125
- package/src/handlers/tools/github/insights-tools.ts +0 -112
- package/src/handlers/tools/github/issue-tools.ts +0 -442
- package/src/handlers/tools/github/kanban-tools.ts +0 -153
- package/src/handlers/tools/github/milestone-tools.ts +0 -371
- package/src/handlers/tools/github/mutation-tools.ts +0 -17
- package/src/handlers/tools/github/read-tools.ts +0 -302
- package/src/handlers/tools/github/schemas.ts +0 -435
- package/src/handlers/tools/github.ts +0 -39
- package/src/handlers/tools/index.ts +0 -255
- package/src/handlers/tools/relationships.ts +0 -390
- package/src/handlers/tools/schemas.ts +0 -165
- package/src/handlers/tools/search.ts +0 -448
- package/src/handlers/tools/team/admin-tools.ts +0 -164
- package/src/handlers/tools/team/analytics-tools.ts +0 -233
- package/src/handlers/tools/team/backup-tools.ts +0 -83
- package/src/handlers/tools/team/core-tools.ts +0 -197
- package/src/handlers/tools/team/export-tools.ts +0 -130
- package/src/handlers/tools/team/helpers.ts +0 -66
- package/src/handlers/tools/team/index.ts +0 -45
- package/src/handlers/tools/team/relationship-tools.ts +0 -219
- package/src/handlers/tools/team/schemas.ts +0 -558
- package/src/handlers/tools/team/search-tools.ts +0 -145
- package/src/handlers/tools/team/vector-tools.ts +0 -261
- package/src/index.ts +0 -57
- package/src/server/mcp-server.ts +0 -446
- package/src/server/registration.ts +0 -141
- package/src/server/scheduler.ts +0 -283
- package/src/transports/http/handlers.ts +0 -78
- package/src/transports/http/index.ts +0 -8
- package/src/transports/http/security.ts +0 -147
- package/src/transports/http/server/index.ts +0 -397
- package/src/transports/http/server/legacy-sse.ts +0 -87
- package/src/transports/http/server/stateful.ts +0 -222
- package/src/transports/http/server/stateless.ts +0 -42
- package/src/transports/http/types.ts +0 -132
- package/src/types/entities.ts +0 -145
- package/src/types/error-types.ts +0 -92
- package/src/types/errors.ts +0 -200
- package/src/types/filtering.ts +0 -55
- package/src/types/github.ts +0 -216
- package/src/types/index.ts +0 -348
- package/src/utils/error-helpers.ts +0 -78
- package/src/utils/errors/error-response-fields.ts +0 -29
- package/src/utils/errors/suggestions.ts +0 -94
- package/src/utils/github-helpers.ts +0 -33
- package/src/utils/logger.ts +0 -107
- package/src/utils/mcp-logger.ts +0 -155
- package/src/utils/progress-utils.ts +0 -100
- package/src/utils/query-helpers.ts +0 -78
- package/src/utils/resource-annotations.ts +0 -75
- package/src/utils/security-utils.ts +0 -198
- package/src/utils/vector-index-helpers.ts +0 -24
- package/src/vector/vector-search-manager.ts +0 -409
- package/src/version.ts +0 -15
- package/test-server/README.md +0 -193
- package/test-server/code-map.md +0 -399
- package/test-server/test-agent-experience.md +0 -213
- package/test-server/test-filter-instructions.mjs +0 -295
- package/test-server/test-instruction-levels.mjs +0 -102
- package/test-server/test-preflight.md +0 -55
- package/test-server/test-prompts.mjs +0 -185
- package/test-server/test-scheduler.mjs +0 -174
- package/test-server/test-tool-annotations.mjs +0 -115
- package/test-server/test-tools-codemode.md +0 -632
- package/test-server/test-tools-codemode2.md +0 -1218
- package/test-server/test-tools-team.md +0 -215
- package/test-server/test-tools.md +0 -429
- package/test-server/test-tools2.md +0 -361
- package/test-server/test-tools3.md +0 -396
- package/test-server/tool-reference.md +0 -231
- package/tests/README.md +0 -54
- package/tests/auth/auth-context.test.ts +0 -162
- package/tests/auth/authorization-server-discovery.test.ts +0 -265
- package/tests/auth/errors.test.ts +0 -170
- package/tests/auth/middleware.test.ts +0 -585
- package/tests/auth/oauth-resource-server.test.ts +0 -173
- package/tests/auth/scope-map.test.ts +0 -66
- package/tests/auth/scopes.test.ts +0 -347
- package/tests/auth/token-validator.test.ts +0 -271
- package/tests/codemode/api.test.ts +0 -396
- package/tests/codemode/auto-return.test.ts +0 -167
- package/tests/codemode/codemode-tool-handlers.test.ts +0 -197
- package/tests/codemode/sandbox-factory.test.ts +0 -152
- package/tests/codemode/sandbox.test.ts +0 -190
- package/tests/codemode/security.test.ts +0 -242
- package/tests/codemode/worker-sandbox.test.ts +0 -106
- package/tests/constants/icons.test.ts +0 -101
- package/tests/constants/server-instructions.test.ts +0 -514
- package/tests/database/crud-workflow-branches.test.ts +0 -418
- package/tests/database/database-branches.test.ts +0 -132
- package/tests/database/entries-auth-branches.test.ts +0 -390
- package/tests/database/native-connection.test.ts +0 -249
- package/tests/database/shared-helpers.test.ts +0 -103
- package/tests/database/sqlite-adapter.bench.ts +0 -63
- package/tests/database/sqlite-adapter.test.ts +0 -690
- package/tests/database/tags.test.ts +0 -134
- package/tests/e2e/README.md +0 -39
- package/tests/e2e/auth.spec.ts +0 -106
- package/tests/e2e/codemode-abuse.spec.ts +0 -75
- package/tests/e2e/health.spec.ts +0 -63
- package/tests/e2e/helpers.ts +0 -139
- package/tests/e2e/oauth-discovery.spec.ts +0 -102
- package/tests/e2e/oauth-scopes.spec.ts +0 -222
- package/tests/e2e/payloads-admin.spec.ts +0 -76
- package/tests/e2e/payloads-analytics.spec.ts +0 -37
- package/tests/e2e/payloads-backup-restore.spec.ts +0 -102
- package/tests/e2e/payloads-backup.spec.ts +0 -44
- package/tests/e2e/payloads-codemode-api.spec.ts +0 -131
- package/tests/e2e/payloads-codemode-readonly.spec.ts +0 -116
- package/tests/e2e/payloads-codemode.spec.ts +0 -116
- package/tests/e2e/payloads-core.spec.ts +0 -82
- package/tests/e2e/payloads-error-contracts.spec.ts +0 -159
- package/tests/e2e/payloads-export.spec.ts +0 -46
- package/tests/e2e/payloads-github-degradation.spec.ts +0 -73
- package/tests/e2e/payloads-github.spec.ts +0 -176
- package/tests/e2e/payloads-relationships.spec.ts +0 -56
- package/tests/e2e/payloads-search.spec.ts +0 -64
- package/tests/e2e/payloads-team-happy.spec.ts +0 -231
- package/tests/e2e/payloads-team.spec.ts +0 -174
- package/tests/e2e/prompts-expanded.spec.ts +0 -137
- package/tests/e2e/prompts.spec.ts +0 -62
- package/tests/e2e/protocols.spec.ts +0 -134
- package/tests/e2e/rate-limiting.spec.ts +0 -291
- package/tests/e2e/resources-briefing-env.spec.ts +0 -106
- package/tests/e2e/resources-complete.spec.ts +0 -180
- package/tests/e2e/resources-expanded.spec.ts +0 -83
- package/tests/e2e/resources-instructions-levels.spec.ts +0 -145
- package/tests/e2e/resources-templates.spec.ts +0 -123
- package/tests/e2e/resources.spec.ts +0 -103
- package/tests/e2e/scheduler.spec.ts +0 -79
- package/tests/e2e/security.spec.ts +0 -112
- package/tests/e2e/session-advanced.spec.ts +0 -152
- package/tests/e2e/sessions.spec.ts +0 -95
- package/tests/e2e/stateless.spec.ts +0 -79
- package/tests/e2e/streaming.spec.ts +0 -176
- package/tests/e2e/tool-filtering-presets.spec.ts +0 -192
- package/tests/e2e/tool-filtering.spec.ts +0 -77
- package/tests/e2e/tools.spec.ts +0 -111
- package/tests/filtering/tool-filter.test.ts +0 -314
- package/tests/github/client-issues-errors.test.ts +0 -433
- package/tests/github/github-integration-branches.test.ts +0 -490
- package/tests/github/github-integration.test.ts +0 -1015
- package/tests/github/github-managers-branches.test.ts +0 -907
- package/tests/github/pull-requests.test.ts +0 -334
- package/tests/handlers/analytics-branches.test.ts +0 -222
- package/tests/handlers/backup-branches.test.ts +0 -270
- package/tests/handlers/briefing-context-section.test.ts +0 -388
- package/tests/handlers/briefing-github-section.test.ts +0 -392
- package/tests/handlers/briefing-user-message.test.ts +0 -405
- package/tests/handlers/codemode-tools.test.ts +0 -85
- package/tests/handlers/copilot-tools.test.ts +0 -126
- package/tests/handlers/error-path-coverage.test.ts +0 -324
- package/tests/handlers/export-tools.test.ts +0 -203
- package/tests/handlers/github-resource-handlers.test.ts +0 -929
- package/tests/handlers/github-tool-handlers.test.ts +0 -1452
- package/tests/handlers/handler-error-branches.test.ts +0 -346
- package/tests/handlers/help-resource.test.ts +0 -92
- package/tests/handlers/prompt-handler-coverage.test.ts +0 -108
- package/tests/handlers/prompt-handlers.test.ts +0 -131
- package/tests/handlers/resource-handler-coverage.test.ts +0 -281
- package/tests/handlers/resource-handlers.test.ts +0 -357
- package/tests/handlers/resource-prompt-branches.test.ts +0 -495
- package/tests/handlers/search-tool-handlers.test.ts +0 -379
- package/tests/handlers/targeted-gap-closure.test.ts +0 -387
- package/tests/handlers/team-admin.test.ts +0 -291
- package/tests/handlers/team-analytics.test.ts +0 -220
- package/tests/handlers/team-core.test.ts +0 -148
- package/tests/handlers/team-data.test.ts +0 -198
- package/tests/handlers/team-relationships.test.ts +0 -271
- package/tests/handlers/team-resource-handlers.test.ts +0 -161
- package/tests/handlers/team-search.test.ts +0 -134
- package/tests/handlers/team-tool-handlers.test.ts +0 -301
- package/tests/handlers/team-vector.test.ts +0 -213
- package/tests/handlers/template-github-branches.test.ts +0 -676
- package/tests/handlers/tool-annotations.test.ts +0 -90
- package/tests/handlers/tool-handler-coverage.test.ts +0 -514
- package/tests/handlers/tool-handlers.test.ts +0 -510
- package/tests/handlers/tool-output-schemas.test.ts +0 -116
- package/tests/handlers/vector-tool-handlers.test.ts +0 -238
- package/tests/security/sql-injection.test.ts +0 -284
- package/tests/server/mcp-server.bench.ts +0 -55
- package/tests/server/mcp-server.test.ts +0 -1326
- package/tests/server/scheduler.test.ts +0 -400
- package/tests/transports/http-legacy-sse.test.ts +0 -275
- package/tests/transports/http-security.test.ts +0 -322
- package/tests/transports/http-stateful.test.ts +0 -487
- package/tests/transports/http-transport-server.test.ts +0 -301
- package/tests/transports/http-transport.test.ts +0 -771
- package/tests/utils/github-helpers.test.ts +0 -58
- package/tests/utils/logger.test.ts +0 -180
- package/tests/utils/mcp-logger.test.ts +0 -211
- package/tests/utils/progress-utils.test.ts +0 -156
- package/tests/utils/query-helpers.test.ts +0 -80
- package/tests/utils/security-utils.test.ts +0 -82
- package/tests/vector/vector-search-branches.test.ts +0 -111
- package/tests/vector/vector-search-manager.test.ts +0 -375
- package/tests/vector/vector-search.bench.ts +0 -48
- package/tsconfig.json +0 -42
- package/tsup.config.ts +0 -19
- package/vitest.config.ts +0 -25
package/src/auth/middleware.ts
DELETED
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* memory-journal-mcp — OAuth Middleware
|
|
3
|
-
*
|
|
4
|
-
* Express middleware for OAuth 2.0 authentication and authorization.
|
|
5
|
-
* Extracts Bearer tokens, validates them, and enforces scope requirements.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { Request, Response, NextFunction, RequestHandler } from 'express'
|
|
9
|
-
import type { TokenClaims } from './types.js'
|
|
10
|
-
import type { TokenValidator } from './token-validator.js'
|
|
11
|
-
import type { OAuthResourceServer } from './oauth-resource-server.js'
|
|
12
|
-
import { TokenMissingError, InsufficientScopeError, isOAuthError } from './errors.js'
|
|
13
|
-
import { hasScope as checkScope } from './scopes.js'
|
|
14
|
-
import { getRequiredScope } from './scope-map.js'
|
|
15
|
-
import { logger } from '../utils/logger.js'
|
|
16
|
-
|
|
17
|
-
// =============================================================================
|
|
18
|
-
// Express Type Extensions
|
|
19
|
-
// =============================================================================
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Extended Express Request with auth context
|
|
23
|
-
* Uses module augmentation to extend Express.Request interface
|
|
24
|
-
*/
|
|
25
|
-
declare module 'express-serve-static-core' {
|
|
26
|
-
interface Request {
|
|
27
|
-
/** Authenticated user claims */
|
|
28
|
-
auth?: TokenClaims
|
|
29
|
-
/** Raw access token */
|
|
30
|
-
accessToken?: string
|
|
31
|
-
/** Request ID for tracing */
|
|
32
|
-
requestId?: string
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// =============================================================================
|
|
37
|
-
// Configuration
|
|
38
|
-
// =============================================================================
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Auth middleware configuration
|
|
42
|
-
*/
|
|
43
|
-
export interface AuthMiddlewareConfig {
|
|
44
|
-
/** Token validator instance */
|
|
45
|
-
tokenValidator: TokenValidator
|
|
46
|
-
|
|
47
|
-
/** Resource server instance (for WWW-Authenticate header) */
|
|
48
|
-
resourceServer: OAuthResourceServer
|
|
49
|
-
|
|
50
|
-
/** Paths that bypass authentication (e.g., '/.well-known/*', '/health') */
|
|
51
|
-
publicPaths?: string[]
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// =============================================================================
|
|
55
|
-
// Token Extraction
|
|
56
|
-
// =============================================================================
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Extract Bearer token from Authorization header
|
|
60
|
-
*
|
|
61
|
-
* @param authHeader - Authorization header value
|
|
62
|
-
* @returns The token or null if not present/invalid
|
|
63
|
-
*/
|
|
64
|
-
export function extractBearerToken(authHeader: string | undefined): string | null {
|
|
65
|
-
if (!authHeader) {
|
|
66
|
-
return null
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Check for Bearer scheme (case-insensitive)
|
|
70
|
-
const parts = authHeader.split(' ')
|
|
71
|
-
const scheme = parts[0]
|
|
72
|
-
const tokenPart = parts[1]
|
|
73
|
-
if (parts.length !== 2 || scheme?.toLowerCase() !== 'bearer') {
|
|
74
|
-
return null
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (tokenPart === undefined) {
|
|
78
|
-
return null
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const token = tokenPart.trim()
|
|
82
|
-
return token.length > 0 ? token : null
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// =============================================================================
|
|
86
|
-
// Path Matching
|
|
87
|
-
// =============================================================================
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Check if a path matches any of the public path patterns
|
|
91
|
-
*
|
|
92
|
-
* Supports:
|
|
93
|
-
* - Exact matches: '/health' matches '/health'
|
|
94
|
-
* - Wildcard suffix: '/api/*' matches '/api/users', '/api/posts/1'
|
|
95
|
-
* - Well-known paths are always public
|
|
96
|
-
*/
|
|
97
|
-
function isPublicPath(path: string, publicPaths: string[]): boolean {
|
|
98
|
-
// Well-known paths are always public (RFC requirement)
|
|
99
|
-
if (path.startsWith('/.well-known/')) {
|
|
100
|
-
return true
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
for (const pattern of publicPaths) {
|
|
104
|
-
// Exact match
|
|
105
|
-
if (pattern === path) {
|
|
106
|
-
return true
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Wildcard match
|
|
110
|
-
if (pattern.endsWith('/*')) {
|
|
111
|
-
const prefix = pattern.slice(0, -2)
|
|
112
|
-
if (path === prefix || path.startsWith(prefix + '/')) {
|
|
113
|
-
return true
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return false
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// =============================================================================
|
|
122
|
-
// Main Authentication Middleware
|
|
123
|
-
// =============================================================================
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Create the main authentication middleware
|
|
127
|
-
*
|
|
128
|
-
* This middleware:
|
|
129
|
-
* 1. Skips authentication for public paths (e.g., /.well-known/*)
|
|
130
|
-
* 2. Extracts Bearer token from Authorization header
|
|
131
|
-
* 3. Validates the token using the TokenValidator
|
|
132
|
-
* 4. Attaches validated claims to req.auth
|
|
133
|
-
* 5. Returns 401 with WWW-Authenticate header on failure
|
|
134
|
-
*/
|
|
135
|
-
export function createAuthMiddleware(config: AuthMiddlewareConfig): RequestHandler {
|
|
136
|
-
const { tokenValidator, resourceServer, publicPaths = [] } = config
|
|
137
|
-
|
|
138
|
-
return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
|
139
|
-
// Generate request ID for tracing
|
|
140
|
-
const requestId = crypto.randomUUID()
|
|
141
|
-
req.requestId = requestId
|
|
142
|
-
|
|
143
|
-
// Check if path is public
|
|
144
|
-
if (isPublicPath(req.path, publicPaths)) {
|
|
145
|
-
logger.info(`Public path accessed: ${req.path}`, {
|
|
146
|
-
module: 'AUTH',
|
|
147
|
-
operation: 'public-path',
|
|
148
|
-
})
|
|
149
|
-
next()
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Extract Bearer token
|
|
154
|
-
const token = extractBearerToken(req.headers.authorization)
|
|
155
|
-
|
|
156
|
-
if (!token) {
|
|
157
|
-
const error = new TokenMissingError(resourceServer.getResourceUri())
|
|
158
|
-
|
|
159
|
-
logger.warning('No access token provided', {
|
|
160
|
-
module: 'AUTH',
|
|
161
|
-
operation: 'authenticate',
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
res.status(error.httpStatus)
|
|
165
|
-
res.setHeader('WWW-Authenticate', error.wwwAuthenticate ?? '')
|
|
166
|
-
res.json({
|
|
167
|
-
error: 'unauthorized',
|
|
168
|
-
error_description: error.message,
|
|
169
|
-
})
|
|
170
|
-
return
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Validate token
|
|
174
|
-
const result = await tokenValidator.validate(token)
|
|
175
|
-
|
|
176
|
-
if (!result.valid) {
|
|
177
|
-
logger.warning(`Token validation failed: ${result.error ?? 'Unknown error'}`, {
|
|
178
|
-
module: 'AUTH',
|
|
179
|
-
operation: 'authenticate',
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
res.status(401)
|
|
183
|
-
res.setHeader(
|
|
184
|
-
'WWW-Authenticate',
|
|
185
|
-
resourceServer.getWWWAuthenticateHeader('invalid_token', result.error)
|
|
186
|
-
)
|
|
187
|
-
res.json({
|
|
188
|
-
error: 'invalid_token',
|
|
189
|
-
error_description: result.error,
|
|
190
|
-
})
|
|
191
|
-
return
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Attach claims to request (claims is guaranteed defined when valid is true)
|
|
195
|
-
const claims = result.claims
|
|
196
|
-
if (!claims) {
|
|
197
|
-
// Should not happen when valid is true, but satisfies TypeScript
|
|
198
|
-
res.status(500).json({ error: 'internal_error' })
|
|
199
|
-
return
|
|
200
|
-
}
|
|
201
|
-
req.auth = claims
|
|
202
|
-
req.accessToken = token
|
|
203
|
-
|
|
204
|
-
logger.info(`Request authenticated: ${claims.sub}`, {
|
|
205
|
-
module: 'AUTH',
|
|
206
|
-
operation: 'authenticate',
|
|
207
|
-
entityId: claims.sub,
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
next()
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// =============================================================================
|
|
215
|
-
// Scope Enforcement Middleware
|
|
216
|
-
// =============================================================================
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Middleware factory that requires a specific scope
|
|
220
|
-
*
|
|
221
|
-
* @param scope - Required scope
|
|
222
|
-
* @returns Express middleware
|
|
223
|
-
*/
|
|
224
|
-
export function requireScope(scope: string): RequestHandler {
|
|
225
|
-
return (req: Request, res: Response, next: NextFunction): void => {
|
|
226
|
-
if (!req.auth) {
|
|
227
|
-
// Should not happen if auth middleware is applied first
|
|
228
|
-
res.status(401).json({
|
|
229
|
-
error: 'unauthorized',
|
|
230
|
-
error_description: 'Authentication required',
|
|
231
|
-
})
|
|
232
|
-
return
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const scopeGranted =
|
|
236
|
-
req.auth.scopes.includes(scope) ||
|
|
237
|
-
req.auth.scopes.includes('admin') ||
|
|
238
|
-
req.auth.scopes.includes('full')
|
|
239
|
-
|
|
240
|
-
if (!scopeGranted) {
|
|
241
|
-
const error = new InsufficientScopeError(scope, req.auth.scopes)
|
|
242
|
-
|
|
243
|
-
logger.warning(`Insufficient scope: required ${scope}`, {
|
|
244
|
-
module: 'AUTH',
|
|
245
|
-
operation: 'scope-check',
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
res.status(error.httpStatus)
|
|
249
|
-
res.setHeader('WWW-Authenticate', error.wwwAuthenticate ?? '')
|
|
250
|
-
res.json({
|
|
251
|
-
error: 'insufficient_scope',
|
|
252
|
-
error_description: error.message,
|
|
253
|
-
required_scope: scope,
|
|
254
|
-
})
|
|
255
|
-
return
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
next()
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Middleware factory that requires any of the specified scopes
|
|
264
|
-
*
|
|
265
|
-
* @param scopes - Array of acceptable scopes (user must have at least one)
|
|
266
|
-
* @returns Express middleware
|
|
267
|
-
*/
|
|
268
|
-
export function requireAnyScope(scopes: string[]): RequestHandler {
|
|
269
|
-
return (req: Request, res: Response, next: NextFunction): void => {
|
|
270
|
-
if (!req.auth) {
|
|
271
|
-
res.status(401).json({
|
|
272
|
-
error: 'unauthorized',
|
|
273
|
-
error_description: 'Authentication required',
|
|
274
|
-
})
|
|
275
|
-
return
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Full or admin scope grants all
|
|
279
|
-
if (req.auth.scopes.includes('full') || req.auth.scopes.includes('admin')) {
|
|
280
|
-
next()
|
|
281
|
-
return
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const hasAnyScope = scopes.some((scope) => req.auth?.scopes.includes(scope))
|
|
285
|
-
|
|
286
|
-
if (!hasAnyScope) {
|
|
287
|
-
const error = new InsufficientScopeError(scopes, req.auth.scopes)
|
|
288
|
-
|
|
289
|
-
logger.warning(`Insufficient scope: required one of [${scopes.join(', ')}]`, {
|
|
290
|
-
module: 'AUTH',
|
|
291
|
-
operation: 'scope-check',
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
res.status(error.httpStatus)
|
|
295
|
-
res.setHeader('WWW-Authenticate', error.wwwAuthenticate ?? '')
|
|
296
|
-
res.json({
|
|
297
|
-
error: 'insufficient_scope',
|
|
298
|
-
error_description: error.message,
|
|
299
|
-
required_scopes: scopes,
|
|
300
|
-
})
|
|
301
|
-
return
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
next()
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Middleware factory that requires scope for a specific tool
|
|
310
|
-
*
|
|
311
|
-
* @param toolName - Name of the tool being accessed
|
|
312
|
-
* @returns Express middleware
|
|
313
|
-
*/
|
|
314
|
-
export function requireToolScope(toolName: string): RequestHandler {
|
|
315
|
-
return (req: Request, res: Response, next: NextFunction): void => {
|
|
316
|
-
if (!req.auth) {
|
|
317
|
-
res.status(401).json({
|
|
318
|
-
error: 'unauthorized',
|
|
319
|
-
error_description: 'Authentication required',
|
|
320
|
-
})
|
|
321
|
-
return
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Use scope hierarchy for tool access check
|
|
325
|
-
const requiredScope = getRequiredScope(toolName)
|
|
326
|
-
const hasAccess = checkScope(req.auth.scopes, requiredScope)
|
|
327
|
-
|
|
328
|
-
if (!hasAccess) {
|
|
329
|
-
const error = new InsufficientScopeError(`Tool access: ${toolName}`, req.auth.scopes)
|
|
330
|
-
|
|
331
|
-
logger.warning(`Insufficient scope for tool: ${toolName}`, {
|
|
332
|
-
module: 'AUTH',
|
|
333
|
-
operation: 'scope-check',
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
res.status(error.httpStatus)
|
|
337
|
-
res.setHeader('WWW-Authenticate', error.wwwAuthenticate ?? '')
|
|
338
|
-
res.json({
|
|
339
|
-
error: 'insufficient_scope',
|
|
340
|
-
error_description: `Access to tool '${toolName}' denied`,
|
|
341
|
-
tool: toolName,
|
|
342
|
-
})
|
|
343
|
-
return
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
next()
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// =============================================================================
|
|
351
|
-
// Error Handler
|
|
352
|
-
// =============================================================================
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Error handler middleware for OAuth errors
|
|
356
|
-
*
|
|
357
|
-
* Should be added after all routes to catch OAuth-related errors
|
|
358
|
-
*/
|
|
359
|
-
export function oauthErrorHandler(
|
|
360
|
-
error: Error,
|
|
361
|
-
_req: Request,
|
|
362
|
-
res: Response,
|
|
363
|
-
next: NextFunction
|
|
364
|
-
): void {
|
|
365
|
-
if (isOAuthError(error)) {
|
|
366
|
-
res.status(error.httpStatus)
|
|
367
|
-
|
|
368
|
-
if (error.wwwAuthenticate) {
|
|
369
|
-
res.setHeader('WWW-Authenticate', error.wwwAuthenticate)
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
res.json({
|
|
373
|
-
error: error.code,
|
|
374
|
-
error_description: error.message,
|
|
375
|
-
})
|
|
376
|
-
return
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Pass to next error handler
|
|
380
|
-
next(error)
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// =============================================================================
|
|
384
|
-
// Transport-Agnostic Auth (re-exports for backward compatibility)
|
|
385
|
-
// =============================================================================
|
|
386
|
-
|
|
387
|
-
export {
|
|
388
|
-
createAuthenticatedContext,
|
|
389
|
-
validateAuth,
|
|
390
|
-
formatOAuthError,
|
|
391
|
-
type AuthenticatedContext,
|
|
392
|
-
} from './transport-agnostic.js'
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* memory-journal-mcp — OAuth Protected Resource Server (RFC 9728)
|
|
3
|
-
*
|
|
4
|
-
* Implements the OAuth 2.0 Protected Resource Metadata endpoint
|
|
5
|
-
* as specified in RFC 9728.
|
|
6
|
-
*
|
|
7
|
-
* @see https://datatracker.ietf.org/doc/html/rfc9728
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { RequestHandler } from 'express'
|
|
11
|
-
import type { ProtectedResourceMetadata, ResourceServerConfig } from './types.js'
|
|
12
|
-
import { SUPPORTED_SCOPES, BASE_SCOPES } from './scopes.js'
|
|
13
|
-
import { logger } from '../utils/logger.js'
|
|
14
|
-
|
|
15
|
-
// =============================================================================
|
|
16
|
-
// OAuth Resource Server
|
|
17
|
-
// =============================================================================
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* OAuth 2.0 Protected Resource Server
|
|
21
|
-
*
|
|
22
|
-
* Provides Protected Resource Metadata (RFC 9728) for MCP authorization.
|
|
23
|
-
*/
|
|
24
|
-
export class OAuthResourceServer {
|
|
25
|
-
private readonly config: Required<ResourceServerConfig>
|
|
26
|
-
private metadata: ProtectedResourceMetadata | null = null
|
|
27
|
-
|
|
28
|
-
constructor(config: ResourceServerConfig) {
|
|
29
|
-
this.config = {
|
|
30
|
-
resource: config.resource,
|
|
31
|
-
authorizationServers: config.authorizationServers,
|
|
32
|
-
scopesSupported:
|
|
33
|
-
config.scopesSupported.length > 0 ? config.scopesSupported : [...SUPPORTED_SCOPES],
|
|
34
|
-
bearerMethodsSupported: config.bearerMethodsSupported ?? ['header'],
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
logger.info(`OAuth Resource Server initialized for: ${this.config.resource}`, {
|
|
38
|
-
module: 'AUTH',
|
|
39
|
-
operation: 'init',
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Get the Protected Resource Metadata document
|
|
45
|
-
*
|
|
46
|
-
* @returns RFC 9728 compliant metadata
|
|
47
|
-
*/
|
|
48
|
-
getMetadata(): ProtectedResourceMetadata {
|
|
49
|
-
this.metadata ??= this.buildMetadata()
|
|
50
|
-
return this.metadata
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Build the Protected Resource Metadata document
|
|
55
|
-
*/
|
|
56
|
-
private buildMetadata(): ProtectedResourceMetadata {
|
|
57
|
-
return {
|
|
58
|
-
resource: this.config.resource,
|
|
59
|
-
authorization_servers: this.config.authorizationServers,
|
|
60
|
-
scopes_supported: this.config.scopesSupported,
|
|
61
|
-
bearer_methods_supported: this.config.bearerMethodsSupported,
|
|
62
|
-
resource_documentation: `${this.config.resource}/docs`,
|
|
63
|
-
resource_signing_alg_values_supported: ['RS256', 'ES256'],
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Get Express request handler for the metadata endpoint
|
|
69
|
-
*
|
|
70
|
-
* Serves: GET /.well-known/oauth-protected-resource
|
|
71
|
-
*/
|
|
72
|
-
getMetadataHandler(): RequestHandler {
|
|
73
|
-
return (_req, res) => {
|
|
74
|
-
const metadata = this.getMetadata()
|
|
75
|
-
|
|
76
|
-
res.setHeader('Content-Type', 'application/json')
|
|
77
|
-
res.setHeader('Cache-Control', 'public, max-age=3600')
|
|
78
|
-
res.json(metadata)
|
|
79
|
-
|
|
80
|
-
logger.info('Protected Resource Metadata served', {
|
|
81
|
-
module: 'AUTH',
|
|
82
|
-
operation: 'metadata-served',
|
|
83
|
-
})
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Generate WWW-Authenticate header for 401 responses
|
|
89
|
-
*
|
|
90
|
-
* @param error - Error type for the header
|
|
91
|
-
* @param errorDescription - Human-readable error description
|
|
92
|
-
* @returns WWW-Authenticate header value
|
|
93
|
-
*/
|
|
94
|
-
getWWWAuthenticateHeader(error?: string, errorDescription?: string): string {
|
|
95
|
-
const parts = [`Bearer realm="${this.config.resource}"`]
|
|
96
|
-
|
|
97
|
-
if (error) {
|
|
98
|
-
parts.push(`error="${error}"`)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (errorDescription) {
|
|
102
|
-
parts.push(`error_description="${errorDescription}"`)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return parts.join(', ')
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Get the resource URI
|
|
110
|
-
*/
|
|
111
|
-
getResourceUri(): string {
|
|
112
|
-
return this.config.resource
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Get the authorization servers
|
|
117
|
-
*/
|
|
118
|
-
getAuthorizationServers(): string[] {
|
|
119
|
-
return [...this.config.authorizationServers]
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Get supported scopes
|
|
124
|
-
*/
|
|
125
|
-
getSupportedScopes(): string[] {
|
|
126
|
-
return [...this.config.scopesSupported]
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Check if a scope is supported by this resource server.
|
|
131
|
-
*/
|
|
132
|
-
isScopeSupported(scope: string): boolean {
|
|
133
|
-
// Check standard base scopes
|
|
134
|
-
if ((BASE_SCOPES as readonly string[]).includes(scope)) {
|
|
135
|
-
return true
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Check configured scopes
|
|
139
|
-
if (this.config.scopesSupported.includes(scope)) {
|
|
140
|
-
return true
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return false
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Get the well-known metadata endpoint path
|
|
148
|
-
*/
|
|
149
|
-
getWellKnownPath(): string {
|
|
150
|
-
return '/.well-known/oauth-protected-resource'
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Clear cached metadata (useful when configuration changes)
|
|
155
|
-
*/
|
|
156
|
-
clearCache(): void {
|
|
157
|
-
this.metadata = null
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// =============================================================================
|
|
162
|
-
// Factory Function
|
|
163
|
-
// =============================================================================
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Create an OAuth Resource Server instance
|
|
167
|
-
*/
|
|
168
|
-
export function createOAuthResourceServer(config: ResourceServerConfig): OAuthResourceServer {
|
|
169
|
-
return new OAuthResourceServer(config)
|
|
170
|
-
}
|
package/src/auth/scope-map.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* memory-journal-mcp — Tool Scope Map
|
|
3
|
-
*
|
|
4
|
-
* Builds a reverse lookup from tool name to required OAuth scope
|
|
5
|
-
* by inverting TOOL_GROUPS × TOOL_GROUP_SCOPES. Computed once at
|
|
6
|
-
* module load for O(1) per-call lookup.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { TOOL_GROUPS } from '../filtering/tool-filter.js'
|
|
10
|
-
import { TOOL_GROUP_SCOPES, SCOPES } from './scopes.js'
|
|
11
|
-
import type { StandardScope } from './scopes.js'
|
|
12
|
-
import type { ToolGroup } from '../types/index.js'
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Map from tool name to required minimum scope.
|
|
16
|
-
* Built by inverting TOOL_GROUPS (group → tools[]) and
|
|
17
|
-
* TOOL_GROUP_SCOPES (group → scope).
|
|
18
|
-
*/
|
|
19
|
-
const toolScopeMap = new Map<string, StandardScope>()
|
|
20
|
-
|
|
21
|
-
// Build the reverse map at module load
|
|
22
|
-
for (const [group, tools] of Object.entries(TOOL_GROUPS)) {
|
|
23
|
-
const scope = TOOL_GROUP_SCOPES[group as ToolGroup]
|
|
24
|
-
if (scope) {
|
|
25
|
-
for (const toolName of tools) {
|
|
26
|
-
toolScopeMap.set(toolName, scope)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Get the required scope for a tool by name.
|
|
33
|
-
*
|
|
34
|
-
* @param toolName - The MCP tool name (e.g., "create_entry")
|
|
35
|
-
* @returns The required scope, or "read" as a safe default for unknown tools
|
|
36
|
-
*/
|
|
37
|
-
export function getRequiredScope(toolName: string): StandardScope {
|
|
38
|
-
return toolScopeMap.get(toolName) ?? SCOPES.READ
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Get the full tool-to-scope map (for testing/debugging).
|
|
43
|
-
*/
|
|
44
|
-
export function getToolScopeMap(): ReadonlyMap<string, StandardScope> {
|
|
45
|
-
return toolScopeMap
|
|
46
|
-
}
|