Skip to content

feat: execute_rest_read / execute_rest_write tools (1.19.0)#40

Merged
ttpears merged 1 commit into
mainfrom
feat/execute-rest-tools
May 22, 2026
Merged

feat: execute_rest_read / execute_rest_write tools (1.19.0)#40
ttpears merged 1 commit into
mainfrom
feat/execute-rest-tools

Conversation

@ttpears
Copy link
Copy Markdown
Owner

@ttpears ttpears commented May 22, 2026

Summary

Opens up the full GitLab REST API to the model without waiting for curated tool PRs — same shape as the existing `execute_custom_query` does for GraphQL.

Split into two tools as discussed:

Tool Method requiresWrite destructiveHint Token fallback
`execute_rest_read` GET only false false GITLAB_TOKEN or GITLAB_READ_TOKEN
`execute_rest_write` POST / PUT / PATCH / DELETE true true GITLAB_TOKEN only

This mirrors the GITLAB_TOKEN / GITLAB_READ_TOKEN separation — read-only deployments physically cannot execute the write tool because `getClient()` rejects it. Destructive intent gating happens at the harness layer (the write tool's `destructiveHint` lets the MCP permission UI flag DELETEs) rather than asking the model to self-declare.

Path validation

Before any request, the path is checked:

  • Must start with `/`
  • Must not include `://` (no full URLs)
  • Must not include `?` (use the `query` arg)
  • No `..` segments

Prevents the caller from escaping the configured GitLab base URL.

Cleanups along the way

  • Added `PATCH` to `restRequest`'s method union (some MR approval-rule routes use it; was missing)
  • Removed a no-op `startsWith('gid://') ? p : p` ternary in `markAllTodosDone` left over from my 1.18.0 patch

Test plan

  • `npm run build` clean
  • CI green
  • After merge: smoke test from this session — call `execute_rest_read` with `/version` to confirm the path validation + auth fallback works

Adds open-ended REST escape hatches matching the existing
execute_custom_query for GraphQL. Lets agents reach any /api/v4
endpoint not covered by a dedicated tool instead of waiting for a
curated tool PR.

Split into two tools so the read variant is readOnlyHint: true /
requiresWrite: false and the write variant is requiresWrite: true /
destructiveHint: true. Same shape as the GITLAB_TOKEN /
GITLAB_READ_TOKEN separation — the read tool works with a read-only
token, the write tool is rejected by getClient when only a read token
is configured. Lets the MCP harness gate destructive calls without
asking the model to self-declare intent.

Path is validated to be /api/v4-relative before the request runs:
must start with '/', no host, no '?' query string (use the query
arg), no '..' segments. Prevents the caller from escaping the
configured GitLab base URL.

Also:
- restRequest now accepts PATCH (some endpoints use it, e.g. some MR
  approval-rule routes)
- Cleaned up a no-op startsWith('gid://') ternary in markAllTodosDone
  whose two branches resolved to the same value
@ttpears ttpears merged commit a0726fd into main May 22, 2026
2 checks passed
@ttpears ttpears deleted the feat/execute-rest-tools branch May 22, 2026 03:29
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