Register Penpot's MCP server, whose token rides in the URL

Penpot's MCP server reads the user key only from the userToken query
parameter, never a header. link-mcp now substitutes a {TOKEN} placeholder
in a server's URL instead of sending the Authorization header, and the
servers list gains a penpot row that uses it.
This commit is contained in:
Gabriel Brown committed 2026-09-23 08:48:12 -04:00
1 parent 933c197060
commit 58a64d6cee
2 files changed
+15 -2

No files matched your search

+8 -1
View File
@@ -69,6 +69,9 @@ while read -r name transport url token_var _rest; do
continue continue
fi fi
# The token normally travels as an Authorization header. A server that only
# reads it from the query string (Penpot's userToken) marks the spot with
# {TOKEN} in its URL instead, and gets no header.
header=() header=()
if [[ -n "${token_var:-}" ]]; then if [[ -n "${token_var:-}" ]]; then
token="${!token_var:-}" token="${!token_var:-}"
@@ -77,7 +80,11 @@ while read -r name transport url token_var _rest; do
skipped=$((skipped + 1)) skipped=$((skipped + 1))
continue continue
fi fi
header=(-H "Authorization: $token") if [[ "$url" == *'{TOKEN}'* ]]; then
url="${url//\{TOKEN\}/$token}"
else
header=(-H "Authorization: $token")
fi
fi fi
# Re-registering is how this stays idempotent across upgrades, and how a # Re-registering is how this stays idempotent across upgrades, and how a
+7 -1
View File
@@ -6,7 +6,8 @@
# git. This file carries no secret, so it is tracked like the rest of user/ and # git. This file carries no secret, so it is tracked like the rest of user/ and
# a new machine gets the same servers by dropping its own env file beside it. # a new machine gets the same servers by dropping its own env file beside it.
# #
# A row with no token variable registers without an Authorization header. # A row with no token variable registers without an Authorization header. A URL
# containing {TOKEN} gets the token substituted there instead of as a header.
# #
# Lines beginning with # are comments and blank lines are ignored. # Lines beginning with # are comments and blank lines are ignored.
@@ -23,3 +24,8 @@ bill-tracker http https://mcp.billtracker.gbrown.org/mcp
# Atlassian's hosted MCP server for Jira and Confluence. No token: it is an # Atlassian's hosted MCP server for Jira and Confluence. No token: it is an
# OAuth server and Claude Code signs in through /mcp on first use. # OAuth server and Claude Code signs in through /mcp on first use.
atlassian http https://mcp.atlassian.com/v1/mcp atlassian http https://mcp.atlassian.com/v1/mcp
# Penpot's MCP server on the VPS (penpot.gbrown.org). The key is a per-user MCP
# key from Penpot's Account > Integrations, and Penpot only reads it from the
# query string, hence {TOKEN}. The same key connects the in-file MCP plugin.
penpot http https://penpot.gbrown.org/mcp/stream?userToken={TOKEN} PENPOT_MCP_TOKEN