@bevel-software/platform-core-backend 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-guide/access-control.md +49 -4
- package/agent-guide/html-views.md +76 -2
- package/dist/__tests__/test-repositories.d.ts +3 -0
- package/dist/__tests__/test-repositories.d.ts.map +1 -0
- package/dist/__tests__/test-repositories.js +18 -0
- package/dist/__tests__/test-repositories.js.map +1 -0
- package/dist/core/catalog-revision.js +3 -3
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +3 -2
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +3 -0
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +35 -5
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +8 -0
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +4 -0
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +20 -0
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +32 -1
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +135 -17
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +20 -6
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.d.ts +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.js +1 -1
- package/dist/modules/audit/agent-audit.service.d.ts.map +1 -1
- package/dist/modules/audit/agent-audit.service.js +66 -6
- package/dist/modules/audit/agent-audit.service.js.map +1 -1
- package/dist/modules/audit/audit.contract.d.ts +52 -8
- package/dist/modules/audit/audit.contract.d.ts.map +1 -1
- package/dist/modules/audit/audit.contract.js +37 -1
- package/dist/modules/audit/audit.contract.js.map +1 -1
- package/dist/modules/audit/audit.routes.d.ts +1 -1
- package/dist/modules/audit/audit.routes.d.ts.map +1 -1
- package/dist/modules/audit/audit.routes.js +15 -13
- package/dist/modules/audit/audit.routes.js.map +1 -1
- package/dist/modules/audit/request-audit.d.ts +21 -10
- package/dist/modules/audit/request-audit.d.ts.map +1 -1
- package/dist/modules/audit/request-audit.js +26 -10
- package/dist/modules/audit/request-audit.js.map +1 -1
- package/dist/modules/database/core-schema.d.ts +22 -3
- package/dist/modules/database/core-schema.d.ts.map +1 -1
- package/dist/modules/database/core-schema.js +15 -6
- package/dist/modules/database/core-schema.js.map +1 -1
- package/dist/modules/diff/diff.service.d.ts.map +1 -1
- package/dist/modules/diff/diff.service.js +7 -1
- package/dist/modules/diff/diff.service.js.map +1 -1
- package/dist/modules/kb-fs/git-dir.d.ts +21 -0
- package/dist/modules/kb-fs/git-dir.d.ts.map +1 -0
- package/dist/modules/kb-fs/git-dir.js +58 -0
- package/dist/modules/kb-fs/git-dir.js.map +1 -0
- package/dist/modules/kb-fs/index.d.ts +3 -0
- package/dist/modules/kb-fs/index.d.ts.map +1 -1
- package/dist/modules/kb-fs/index.js +3 -1
- package/dist/modules/kb-fs/index.js.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.d.ts.map +1 -1
- package/dist/modules/kb-fs/locking-filesystem.js +3 -12
- package/dist/modules/kb-fs/locking-filesystem.js.map +1 -1
- package/dist/modules/kb-fs/mutex.d.ts +11 -0
- package/dist/modules/kb-fs/mutex.d.ts.map +1 -1
- package/dist/modules/kb-fs/mutex.js +14 -0
- package/dist/modules/kb-fs/mutex.js.map +1 -1
- package/dist/modules/kb-fs/ref-files.d.ts +63 -0
- package/dist/modules/kb-fs/ref-files.d.ts.map +1 -0
- package/dist/modules/kb-fs/ref-files.js +249 -0
- package/dist/modules/kb-fs/ref-files.js.map +1 -0
- package/dist/modules/mcp/mcp-auth.middleware.d.ts +14 -0
- package/dist/modules/mcp/mcp-auth.middleware.d.ts.map +1 -1
- package/dist/modules/mcp/mcp-auth.middleware.js +4 -0
- package/dist/modules/mcp/mcp-auth.middleware.js.map +1 -1
- package/dist/modules/mcp/mcp.routes.d.ts +5 -0
- package/dist/modules/mcp/mcp.routes.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.routes.js +67 -0
- package/dist/modules/mcp/mcp.routes.js.map +1 -1
- package/dist/modules/mcp/mcp.service.d.ts +107 -27
- package/dist/modules/mcp/mcp.service.d.ts.map +1 -1
- package/dist/modules/mcp/mcp.service.js +257 -50
- package/dist/modules/mcp/mcp.service.js.map +1 -1
- package/dist/modules/mcp/request-context.d.ts +25 -0
- package/dist/modules/mcp/request-context.d.ts.map +1 -0
- package/dist/modules/mcp/request-context.js +11 -0
- package/dist/modules/mcp/request-context.js.map +1 -0
- package/dist/modules/mcp/shared-definitions.d.ts +56 -0
- package/dist/modules/mcp/shared-definitions.d.ts.map +1 -0
- package/dist/modules/mcp/shared-definitions.js +117 -0
- package/dist/modules/mcp/shared-definitions.js.map +1 -0
- package/dist/modules/mcp/surface-cache.d.ts +70 -0
- package/dist/modules/mcp/surface-cache.d.ts.map +1 -0
- package/dist/modules/mcp/surface-cache.js +104 -0
- package/dist/modules/mcp/surface-cache.js.map +1 -0
- package/dist/modules/plugins/teams.routes.d.ts +4 -0
- package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
- package/dist/modules/plugins/teams.routes.js +9 -1
- package/dist/modules/plugins/teams.routes.js.map +1 -1
- package/dist/modules/tool-auth/internal-token.service.d.ts +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts +1 -2
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js +1 -2
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
- package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool-context.js +33 -12
- package/dist/modules/tool-helpers/tool-context.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts +2 -2
- package/dist/modules/tool-helpers/tool.contract.d.ts +10 -2
- package/dist/modules/tool-helpers/tool.contract.d.ts.map +1 -1
- package/dist/modules/tool-helpers/tool.contract.js.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js +3 -14
- package/dist/modules/workflow/agent-tools/change-request-read.tools.js.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts +18 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
- package/dist/modules/workflow/agent-tools/workflow.tools.js +453 -2
- package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +142 -4
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +645 -128
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/read-on-branch.d.ts +35 -0
- package/dist/modules/workflow/read-on-branch.d.ts.map +1 -0
- package/dist/modules/workflow/read-on-branch.js +58 -0
- package/dist/modules/workflow/read-on-branch.js.map +1 -0
- package/dist/modules/workflow/workflow-hooks.d.ts +1 -1
- package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.routes.js +22 -41
- package/dist/modules/workflow/workflow.routes.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts +48 -8
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +163 -16
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/agent-access.gate.d.ts +2 -2
- package/dist/modules/workspace/agent-access.gate.js +2 -2
- package/dist/modules/workspace/bounded-matcher.d.ts +79 -0
- package/dist/modules/workspace/bounded-matcher.d.ts.map +1 -0
- package/dist/modules/workspace/bounded-matcher.js +261 -0
- package/dist/modules/workspace/bounded-matcher.js.map +1 -0
- package/dist/modules/workspace/fetch-instant.d.ts +9 -0
- package/dist/modules/workspace/fetch-instant.d.ts.map +1 -0
- package/dist/modules/workspace/fetch-instant.js +13 -0
- package/dist/modules/workspace/fetch-instant.js.map +1 -0
- package/dist/modules/workspace/index.d.ts +9 -0
- package/dist/modules/workspace/index.d.ts.map +1 -1
- package/dist/modules/workspace/index.js +10 -0
- package/dist/modules/workspace/index.js.map +1 -1
- package/dist/modules/workspace/kb-repository.contract.d.ts +124 -0
- package/dist/modules/workspace/kb-repository.contract.d.ts.map +1 -0
- package/dist/modules/workspace/kb-repository.contract.js +19 -0
- package/dist/modules/workspace/kb-repository.contract.js.map +1 -0
- package/dist/modules/workspace/kb-repository.d.ts +236 -0
- package/dist/modules/workspace/kb-repository.d.ts.map +1 -0
- package/dist/modules/workspace/kb-repository.js +811 -0
- package/dist/modules/workspace/kb-repository.js.map +1 -0
- package/dist/modules/workspace/pattern-matcher.contract.d.ts +50 -0
- package/dist/modules/workspace/pattern-matcher.contract.d.ts.map +1 -0
- package/dist/modules/workspace/pattern-matcher.contract.js +27 -0
- package/dist/modules/workspace/pattern-matcher.contract.js.map +1 -0
- package/dist/modules/workspace/routine-write-policy.d.ts +0 -7
- package/dist/modules/workspace/routine-write-policy.d.ts.map +1 -1
- package/dist/modules/workspace/routine-write-policy.js +0 -5
- package/dist/modules/workspace/routine-write-policy.js.map +1 -1
- package/dist/modules/workspace/set-aside-clone.d.ts +40 -0
- package/dist/modules/workspace/set-aside-clone.d.ts.map +1 -1
- package/dist/modules/workspace/set-aside-clone.js +139 -0
- package/dist/modules/workspace/set-aside-clone.js.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts +99 -0
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js +407 -29
- package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +68 -32
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +240 -161
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts +13 -4
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +162 -336
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/shared/git.contract.d.ts +7 -0
- package/dist/shared/git.contract.d.ts.map +1 -1
- package/dist/shared/git.contract.js +9 -0
- package/dist/shared/git.contract.js.map +1 -1
- package/dist/shared/no-link-below.d.ts +10 -0
- package/dist/shared/no-link-below.d.ts.map +1 -0
- package/dist/shared/no-link-below.js +30 -0
- package/dist/shared/no-link-below.js.map +1 -0
- package/dist/test-setup.js +4 -0
- package/dist/test-setup.js.map +1 -1
- package/migrations/0018_agent_events_page.sql +11 -0
- package/migrations/meta/0018_snapshot.json +2429 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +3 -3
- package/src/__tests__/test-repositories.ts +22 -0
- package/src/__tests__/workspace-service.ts +69 -0
- package/src/core/__tests__/lifecycle.test.ts +16 -0
- package/src/core/catalog-revision.ts +3 -3
- package/src/core/create-core-server.ts +3 -2
- package/src/core/create-core-services.ts +39 -4
- package/src/core/lifecycle.ts +10 -0
- package/src/modules/access/__tests__/access-control.atref-cache.test.ts +144 -4
- package/src/modules/access/__tests__/access-control.group-read.test.ts +73 -0
- package/src/modules/access/__tests__/access.routes.group-grant.test.ts +66 -0
- package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -0
- package/src/modules/access/access-control.interface.ts +22 -0
- package/src/modules/access/access-control.service.ts +138 -15
- package/src/modules/access/access.routes.ts +22 -6
- package/src/modules/agent-guide/__tests__/agent-guide.test.ts +22 -1
- package/src/modules/agent-instructions/shared-file-rules.ts +1 -1
- package/src/modules/audit/__tests__/agent-audit.service.test.ts +78 -1
- package/src/modules/audit/__tests__/audit.routes.test.ts +43 -5
- package/src/modules/audit/agent-audit.service.ts +66 -6
- package/src/modules/audit/audit.contract.ts +62 -10
- package/src/modules/audit/audit.routes.ts +14 -12
- package/src/modules/audit/request-audit.ts +28 -13
- package/src/modules/database/core-schema.ts +15 -6
- package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +2 -1
- package/src/modules/diff/__tests__/diff.service.test.ts +2 -1
- package/src/modules/diff/__tests__/diff.service.worktree.test.ts +76 -0
- package/src/modules/diff/diff.service.ts +6 -4
- package/src/modules/kb-fs/__tests__/git-dir.test.ts +77 -0
- package/src/modules/kb-fs/__tests__/mutex.canonical.test.ts +57 -0
- package/src/modules/kb-fs/__tests__/ref-files.test.ts +338 -0
- package/src/modules/kb-fs/git-dir.ts +53 -0
- package/src/modules/kb-fs/index.ts +3 -0
- package/src/modules/kb-fs/locking-filesystem.ts +3 -12
- package/src/modules/kb-fs/mutex.ts +16 -0
- package/src/modules/kb-fs/ref-files.ts +279 -0
- package/src/modules/mcp/__tests__/mcp-routes-harness.ts +7 -1
- package/src/modules/mcp/__tests__/mcp.routes.page.test.ts +115 -0
- package/src/modules/mcp/__tests__/mcp.surface-cache.test.ts +521 -0
- package/src/modules/mcp/__tests__/shared-definitions.test.ts +28 -0
- package/src/modules/mcp/__tests__/surface-cache.test.ts +127 -0
- package/src/modules/mcp/mcp-auth.middleware.ts +21 -0
- package/src/modules/mcp/mcp.routes.ts +68 -0
- package/src/modules/mcp/mcp.service.ts +315 -51
- package/src/modules/mcp/request-context.ts +34 -0
- package/src/modules/mcp/shared-definitions.ts +121 -0
- package/src/modules/mcp/surface-cache.ts +154 -0
- package/src/modules/plugins/__tests__/teams.routes.test.ts +55 -0
- package/src/modules/plugins/teams.routes.ts +14 -1
- package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +2 -2
- package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +2 -2
- package/src/modules/tool-auth/internal-token.service.ts +1 -1
- package/src/modules/tool-auth/tool-auth.middleware.ts +1 -2
- package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +2 -2
- package/src/modules/tool-helpers/tool-context.ts +37 -18
- package/src/modules/tool-helpers/tool-handler.ts +2 -2
- package/src/modules/tool-helpers/tool.contract.ts +10 -2
- package/src/modules/tool-registry/__tests__/own-tool-schemas.test.ts +1 -1
- package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +7 -2
- package/src/modules/workflow/__tests__/workflow.routes.history-read-gate.test.ts +23 -12
- package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +250 -4
- package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +464 -4
- package/src/modules/workflow/agent-tools/change-request-read.tools.ts +4 -22
- package/src/modules/workflow/agent-tools/workflow.tools.ts +462 -1
- package/src/modules/workflow/git/__tests__/git.service.changedPathsMemo.test.ts +175 -0
- package/src/modules/workflow/git/__tests__/git.service.diffFileBetweenBranches.test.ts +76 -11
- package/src/modules/workflow/git/__tests__/git.service.mergeIntoBranch.test.ts +721 -0
- package/src/modules/workflow/git/__tests__/git.service.worktrees.test.ts +284 -0
- package/src/modules/workflow/git/git.service.ts +719 -126
- package/src/modules/workflow/read-on-branch.ts +79 -0
- package/src/modules/workflow/workflow-hooks.ts +1 -1
- package/src/modules/workflow/workflow.routes.ts +21 -39
- package/src/modules/workflow/workflow.service.ts +203 -16
- package/src/modules/workspace/__tests__/agent-downloads.test.ts +2 -2
- package/src/modules/workspace/__tests__/bounded-matcher.test.ts +213 -0
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +22 -7
- package/src/modules/workspace/__tests__/kb-repository.test.ts +481 -0
- package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +14 -0
- package/src/modules/workspace/__tests__/routine-write-policy.test.ts +0 -11
- package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +4 -3
- package/src/modules/workspace/__tests__/workspace.service.any-workspace-credentials.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +12 -5
- package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.replaced-repository.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.test.ts +24 -23
- package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.worktrees.test.ts +620 -0
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +15 -1
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +71 -5
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +153 -298
- package/src/modules/workspace/agent-access.gate.ts +2 -2
- package/src/modules/workspace/bounded-matcher.ts +328 -0
- package/src/modules/workspace/fetch-instant.ts +13 -0
- package/src/modules/workspace/index.ts +23 -0
- package/src/modules/workspace/kb-repository.contract.ts +124 -0
- package/src/modules/workspace/kb-repository.ts +844 -0
- package/src/modules/workspace/pattern-matcher.contract.ts +69 -0
- package/src/modules/workspace/routine-write-policy.ts +0 -15
- package/src/modules/workspace/set-aside-clone.ts +140 -0
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +3 -2
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +12 -10
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.worktrees.test.ts +613 -0
- package/src/modules/workspace/startup/kb-startup-runner.ts +422 -29
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +4 -3
- package/src/modules/workspace/workspace.service.ts +247 -169
- package/src/modules/workspace/workspace.tools.ts +179 -365
- package/src/shared/__tests__/no-link-below.test.ts +45 -0
- package/src/shared/git.contract.ts +10 -0
- package/src/shared/no-link-below.ts +29 -0
- package/src/test-setup.ts +5 -0
|
@@ -12,6 +12,23 @@ import type { BevelOAuthProvider } from './oauth/bevel-oauth-provider.js';
|
|
|
12
12
|
import '../tool-auth/external-api-key.interface.js'; // Express Request augmentation (req.externalApiKeyId)
|
|
13
13
|
import '../audit/audit.contract.js'; // Express Request augmentation (req.agentConnectionId)
|
|
14
14
|
|
|
15
|
+
/** Which of the four credentials below an MCP request was authenticated with. */
|
|
16
|
+
export type McpCallerKind = 'key' | 'oauth' | 'internal' | 'session';
|
|
17
|
+
|
|
18
|
+
declare global {
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
20
|
+
namespace Express {
|
|
21
|
+
interface Request {
|
|
22
|
+
/**
|
|
23
|
+
* The kind of credential the MCP auth middleware admitted the request
|
|
24
|
+
* with. Only a `session` — the person signed in to the app — may name
|
|
25
|
+
* the page its call comes from (`X-Bevel-Page`).
|
|
26
|
+
*/
|
|
27
|
+
mcpCallerKind?: McpCallerKind;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
15
32
|
/**
|
|
16
33
|
* Auth middleware for the MCP endpoint. Accepts any of:
|
|
17
34
|
*
|
|
@@ -94,6 +111,7 @@ export function createMcpAuthMiddleware(
|
|
|
94
111
|
req.userId = resolved.user.id;
|
|
95
112
|
req.userEmail = resolved.user.email;
|
|
96
113
|
req.externalApiKeyId = resolved.tokenId;
|
|
114
|
+
req.mcpCallerKind = 'key';
|
|
97
115
|
next();
|
|
98
116
|
return;
|
|
99
117
|
} catch (err) {
|
|
@@ -136,6 +154,7 @@ export function createMcpAuthMiddleware(
|
|
|
136
154
|
// Outside the try so a synchronous throw from a downstream handler isn't
|
|
137
155
|
// misclassified as a token-verification failure (and doesn't try to write
|
|
138
156
|
// a second response).
|
|
157
|
+
req.mcpCallerKind = 'oauth';
|
|
139
158
|
next();
|
|
140
159
|
return;
|
|
141
160
|
}
|
|
@@ -215,6 +234,7 @@ export function createMcpAuthMiddleware(
|
|
|
215
234
|
oauthProvider.noteConnectionUse(claim.connectionId);
|
|
216
235
|
req.agentConnectionId = claim.connectionId;
|
|
217
236
|
}
|
|
237
|
+
req.mcpCallerKind = 'internal';
|
|
218
238
|
next();
|
|
219
239
|
return;
|
|
220
240
|
}
|
|
@@ -236,6 +256,7 @@ export function createMcpAuthMiddleware(
|
|
|
236
256
|
}
|
|
237
257
|
req.userId = session.userId;
|
|
238
258
|
req.userEmail = session.email;
|
|
259
|
+
req.mcpCallerKind = 'session';
|
|
239
260
|
next();
|
|
240
261
|
};
|
|
241
262
|
}
|
|
@@ -16,6 +16,8 @@ import { MCP_LOOPBACK_TOKEN_TTL_MS, type McpService } from './mcp.service.js';
|
|
|
16
16
|
import type { BevelOAuthProvider } from './oauth/bevel-oauth-provider.js';
|
|
17
17
|
import type { ILlmUsageMeter } from '../tool-auth/llm-usage-meter.js';
|
|
18
18
|
import '../tool-auth/external-api-key.interface.js'; // req.externalApiKeyId augmentation
|
|
19
|
+
import './mcp-auth.middleware.js'; // req.mcpCallerKind augmentation
|
|
20
|
+
import { isPagePath } from '../audit/index.js';
|
|
19
21
|
|
|
20
22
|
/** Pull the raw bearer token off an already-authenticated request. */
|
|
21
23
|
function extractBearer(req: Request): string {
|
|
@@ -43,6 +45,33 @@ function jsonRpcError(res: Response, status: number, code: number, message: stri
|
|
|
43
45
|
res.status(status).json({ jsonrpc: '2.0', error: { code, message }, id: null });
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
/** The header a page's calls carry: the page's knowledge-base path, URI-encoded. */
|
|
49
|
+
export const PAGE_HEADER = 'x-bevel-page';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The page a request names, decoded: null when it names none, an error
|
|
53
|
+
* message when it names one it may not.
|
|
54
|
+
*
|
|
55
|
+
* Only a session — the person signed in to the app, whose app is relaying a
|
|
56
|
+
* page's calls — may name one. A connection key, an OAuth token or an
|
|
57
|
+
* internal token belongs to an agent, which has an Audit log row of its own;
|
|
58
|
+
* letting it name a page would let it write its calls into a page's history.
|
|
59
|
+
*/
|
|
60
|
+
function pageOf(req: Request): { page: string | null } | { error: string } {
|
|
61
|
+
const raw = req.headers[PAGE_HEADER];
|
|
62
|
+
if (raw === undefined) return { page: null };
|
|
63
|
+
if (req.mcpCallerKind !== 'session') {
|
|
64
|
+
return { error: 'X-Bevel-Page names the page a signed-in person\'s call comes from; it is not accepted with this credential.' };
|
|
65
|
+
}
|
|
66
|
+
let page: string;
|
|
67
|
+
try {
|
|
68
|
+
page = decodeURIComponent(Array.isArray(raw) ? (raw[0] ?? '') : raw);
|
|
69
|
+
} catch {
|
|
70
|
+
return { error: 'X-Bevel-Page is not a URI-encoded path.' };
|
|
71
|
+
}
|
|
72
|
+
return isPagePath(page) ? { page } : { error: 'X-Bevel-Page is not a knowledge-base path.' };
|
|
73
|
+
}
|
|
74
|
+
|
|
46
75
|
/**
|
|
47
76
|
* Routes for the remote MCP server + the connection-key management endpoints.
|
|
48
77
|
*
|
|
@@ -57,6 +86,8 @@ function jsonRpcError(res: Response, status: number, code: number, message: stri
|
|
|
57
86
|
*
|
|
58
87
|
* POST /mcp/local-token — exchange an MCP OAuth access token
|
|
59
88
|
* for a loopback internal token
|
|
89
|
+
* POST /mcp/page-refusals — record a page's call its viewer
|
|
90
|
+
* refused (session only)
|
|
60
91
|
*
|
|
61
92
|
* The `/mcp` POST accepts either a connection key or a JWT/OAuth token (see
|
|
62
93
|
* McpAuthMiddleware). The `/mcp/external-api-keys/*` endpoints accept only the JWT —
|
|
@@ -100,6 +131,11 @@ export function createMcpRoutes(
|
|
|
100
131
|
* closes — finished, or abandoned by the client mid-call.
|
|
101
132
|
*/
|
|
102
133
|
router.post('/mcp', mcpAuthMiddleware, async (req, res) => {
|
|
134
|
+
const named = pageOf(req);
|
|
135
|
+
if ('error' in named) {
|
|
136
|
+
jsonRpcError(res, 400, TRANSPORT_ERROR, named.error);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
103
139
|
let server: Server | undefined;
|
|
104
140
|
res.on('close', () => {
|
|
105
141
|
// Closing the server closes its transport too.
|
|
@@ -122,6 +158,9 @@ export function createMcpRoutes(
|
|
|
122
158
|
// The proxy authenticates its loopback calls with the SAME bearer the
|
|
123
159
|
// client used here, so it acts on the request exactly as the caller would.
|
|
124
160
|
bearer: extractBearer(req),
|
|
161
|
+
// The page whose script made the call, when the app relays one —
|
|
162
|
+
// its calls are audited under the page (see pageOf).
|
|
163
|
+
...(named.page ? { page: named.page } : {}),
|
|
125
164
|
},
|
|
126
165
|
req.body,
|
|
127
166
|
);
|
|
@@ -165,6 +204,35 @@ export function createMcpRoutes(
|
|
|
165
204
|
router.get('/mcp', methodNotAllowed);
|
|
166
205
|
router.delete('/mcp', methodNotAllowed);
|
|
167
206
|
|
|
207
|
+
/**
|
|
208
|
+
* A call a page asked to make and its viewer refused. It never ran, so it
|
|
209
|
+
* never reached `/mcp`; the app reports it so the Audit log lists it
|
|
210
|
+
* under the page, as refused, beside the page's allowed calls.
|
|
211
|
+
*
|
|
212
|
+
* Body: `{ page, tool, args? }` — the page's knowledge-base path and the
|
|
213
|
+
* tool's name as the page called it. Session only, like the page header.
|
|
214
|
+
*/
|
|
215
|
+
router.post('/mcp/page-refusals', mcpAuthMiddleware, async (req, res) => {
|
|
216
|
+
if (req.mcpCallerKind !== 'session') {
|
|
217
|
+
res.status(403).json({ error: 'Only the app records a page\'s refused calls.' });
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const body = (req.body ?? {}) as { page?: unknown; tool?: unknown; args?: unknown };
|
|
221
|
+
if (typeof body.page !== 'string' || !isPagePath(body.page) || typeof body.tool !== 'string' || !body.tool) {
|
|
222
|
+
res.status(400).json({ error: 'page (a knowledge-base path) and tool are required' });
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const args =
|
|
226
|
+
body.args && typeof body.args === 'object' && !Array.isArray(body.args) ? (body.args as Record<string, unknown>) : {};
|
|
227
|
+
try {
|
|
228
|
+
await mcpService.recordPageRefusal({ userId: req.userId!, bearer: extractBearer(req) }, body.page, body.tool, args);
|
|
229
|
+
res.status(204).end();
|
|
230
|
+
} catch (err) {
|
|
231
|
+
log.error('recording a page refusal failed:', { err });
|
|
232
|
+
res.status(500).json({ error: 'Failed to record the refusal' });
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
168
236
|
// ── Connection-key management (JWT-only) ───────────────────────────────
|
|
169
237
|
|
|
170
238
|
router.get('/mcp/external-api-keys', jwtAuthMiddleware, async (req, res) => {
|