Skip to content

fix(den): preserve admin capability arguments - #3102

Merged
benjaminshafii merged 1 commit into
devfrom
fix/admin-capability-arguments
Jul 25, 2026
Merged

fix(den): preserve admin capability arguments#3102
benjaminshafii merged 1 commit into
devfrom
fix/admin-capability-arguments

Conversation

@benjaminshafii

Copy link
Copy Markdown
Member

Summary

Fixes admin MCP capability argument plumbing so execute_capability can call tools like admin:den_query with real input.

Reproduced error before the fix when executing admin:den_query with body {"sql":"SELECT @@sql_mode"} (and equivalently with the new regression's JSON-string body):

MCP error -32602: Input validation error: Invalid arguments for tool den_query: [
  { "expected": "string", "code": "invalid_type", "path": ["sql"],
    "message": "Invalid input: expected string, received undefined" }
]

Root cause / fix

  • Defect A: ee/apps/den-api/src/mcp/admin-capabilities.ts:98-104 now uses the existing normalizeToolRecord(body) ?? {} helper from ./invoke.js; the removed local normalizeArguments helper previously returned {} for JSON-encoded string bodies, silently dropping every admin argument.
  • Defect B: ee/apps/den-api/src/mcp/admin-capabilities.ts:40-63 now emits argumentsSchema: tool.inputSchema and invocation: { argumentsField: "body" } for admin tools with input, matching the external-MCP convention. ee/apps/den-api/src/mcp/search.ts:36-39 types those shared match fields.

No changes were made to admin:den_query behavior, SQL allowlisting, permission gating, or admin-tools.ts.

Regression proof

Before fix (tests added, production code still unfixed):

$ pnpm --filter @openwork-ee/den-api exec bun test test/admin-capabilities.test.ts
bun test v1.3.10 (30e609e0)

test/admin-capabilities.test.ts:
40 | 
41 |   test("forwards arguments when body is a JSON-encoded string", async () => {
42 |     const result = await adminCapabilities.executeAdminCapability("admin:den_query", JSON.stringify({ sql: "DELETE FROM user" }))
43 | 
44 |     expect(result?.isError).toBe(true)
45 |     expect(contentText(result)).toContain("Only SELECT/WITH/SHOW/DESCRIBE/EXPLAIN statements are allowed")
                                     ^
error: expect(received).toContain(expected)

Expected to contain: "Only SELECT/WITH/SHOW/DESCRIBE/EXPLAIN statements are allowed"
Received: "MCP error -32602: Input validation error: Invalid arguments for tool den_query: [\n  {\n    \"expected\": \"string\",\n    \"code\": \"invalid_type\",\n    \"path\": [\n      \"sql\"\n    ],\n    \"message\": \"Invalid input: expected string, received undefined\"\n  }\n]"

      at <anonymous> (/Users/benjaminshafii/openwork-enterprise/_repos/_worktrees/openwork-admin-capability-args/ee/apps/den-api/test/admin-capabilities.test.ts:45:33)
(fail) executeAdminCapability > forwards arguments when body is a JSON-encoded string [2.24ms]
68 |       throw new Error("Expected admin:den_query match to be a record")
69 |     }
70 | 
71 |     const argumentsSchema = match.argumentsSchema
72 |     if (!isRecord(argumentsSchema) || !isRecord(argumentsSchema.properties)) {
73 |       throw new Error("Expected admin:den_query to expose an object argumentsSchema")
                     ^
error: Expected admin:den_query to expose an object argumentsSchema
      at <anonymous> (/Users/benjaminshafii/openwork-enterprise/_repos/_worktrees/openwork-admin-capability-args/ee/apps/den-api/test/admin-capabilities.test.ts:73:17)
(fail) searchAdminCapabilities > exposes argumentsSchema for tools that take input [4.42ms]

 2 pass
 2 fail
 8 expect() calls
Ran 4 tests across 1 file. [147.00ms]
undefined
/Users/benjaminshafii/openwork-enterprise/_repos/_worktrees/openwork-admin-capability-args/ee/apps/den-api:
[ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL] Command failed with exit code 1: bun test test/admin-capabilities.test.ts

After fix:

$ NO_COLOR=1 pnpm --filter @openwork-ee/den-api exec bun test test/admin-capabilities.test.ts
bun test v1.3.10 (30e609e0)

test/admin-capabilities.test.ts:
2026-07-25T11:44:43.546Z WARN [Better Auth]: Please ensure '/.well-known/oauth-authorization-server/api/auth' exists. Upon completion, clear with silenceWarnings.oauthAuthServerConfig.

 4 pass
 0 fail
 10 expect() calls
Ran 4 tests across 1 file. [457.00ms]

Affected tests:

$ NO_COLOR=1 pnpm --filter @openwork-ee/den-api exec bun test test/admin-capabilities.test.ts test/admin-mcp.test.ts test/admin-mcp-routes.test.ts
bun test v1.3.10 (30e609e0)

test/admin-capabilities.test.ts:
2026-07-25T11:44:50.660Z WARN [Better Auth]: Please ensure '/.well-known/oauth-authorization-server/api/auth' exists. Upon completion, clear with silenceWarnings.oauthAuthServerConfig.

 19 pass
 0 fail
 49 expect() calls
Ran 19 tests across 3 files. [450.00ms]

Typecheck:

$ pnpm --filter @openwork-ee/den-api exec tsc -p tsconfig.json --noEmit
# exited 0 with no output

Other commands run:

$ pnpm --filter @openwork-ee/den-db build
# passed; needed because this fresh worktree had no den-db dist files for Bun's default workspace export resolution

$ pnpm --filter @openwork/email build
# passed; needed after importing invoke.ts because Bun resolves @openwork/email to dist in this local setup

$ git diff --check
# exited 0 with no output

No video/fraimz is included because this is an MCP argument-plumbing fix with no UI surface. The real end-to-end proof after deploy is admin:den_query accepting {"sql": "..."} through execute_capability.

@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview, Comment Jul 25, 2026 11:45am
openwork-den Ready Ready Preview, Comment Jul 25, 2026 11:45am
openwork-den-worker-proxy Ready Ready Preview, Comment Jul 25, 2026 11:45am
openwork-landing Ready Ready Preview, Comment, Open in v0 Jul 25, 2026 11:45am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
openwork-diagnostics Skipped Skipped Jul 25, 2026 11:45am

@benjaminshafii
benjaminshafii merged commit b8546fd into dev Jul 25, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant