forked from spencerm/freshservice-claude
plugin/make-plugin.{sh,ps1} stamp a user's own Freshservice API key and the
shared server token into a template and emit a personalized freshservice.plugin
(direct HTTP MCP connection — no Node/mcp-remote/config editing on clients).
Built plugins embed credentials, so *.plugin is git-ignored; the committed
template holds only placeholders. Validated with 'claude plugin validate'.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
50 lines
2.2 KiB
PowerShell
50 lines
2.2 KiB
PowerShell
# Build a personalized freshservice.plugin for Claude Desktop / Cowork (Windows).
|
|
#
|
|
# Each person runs this ONCE with their own Freshservice API key. The output
|
|
# .plugin file contains your key — do not share it.
|
|
#
|
|
# Usage: powershell -ExecutionPolicy Bypass -File .\make-plugin.ps1
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$Template = Join-Path $ScriptDir "template"
|
|
|
|
$ServerUrl = if ($env:SERVER_URL) { $env:SERVER_URL } else { "http://192.168.101.12:3839/mcp" }
|
|
$FsDomain = if ($env:FS_DOMAIN) { $env:FS_DOMAIN } else { "pesco.freshservice.com" }
|
|
|
|
$FsKey = if ($env:FS_KEY) { $env:FS_KEY } else {
|
|
Read-Host "Your Freshservice API key (Freshservice -> profile picture -> Profile settings -> API key)"
|
|
}
|
|
$McpToken = if ($env:MCP_TOKEN) { $env:MCP_TOKEN } else {
|
|
Read-Host "Shared MCP server token (ask IT / Spencer)"
|
|
}
|
|
if (-not $FsKey) { throw "API key is required." }
|
|
if (-not $McpToken) { throw "MCP token is required." }
|
|
|
|
$Build = Join-Path ([System.IO.Path]::GetTempPath()) ("fsplugin-" + [guid]::NewGuid())
|
|
Copy-Item -Recurse -Force $Template $Build
|
|
|
|
$McpJson = Join-Path $Build ".mcp.json"
|
|
$content = Get-Content -Raw $McpJson
|
|
$content = $content.Replace("__SERVER_URL__", $ServerUrl)
|
|
$content = $content.Replace("__FS_DOMAIN__", $FsDomain)
|
|
$content = $content.Replace("__FS_KEY__", $FsKey)
|
|
$content = $content.Replace("__MCP_TOKEN__", $McpToken)
|
|
Set-Content -NoNewline -Path $McpJson -Value $content
|
|
|
|
# Sanity check: no placeholders left anywhere.
|
|
$leftover = Get-ChildItem -Recurse -File $Build | Select-String -Pattern "__[A-Z_]*__" -SimpleMatch:$false
|
|
if ($leftover) { throw "Unfilled placeholders remain; aborting." }
|
|
|
|
$Out = Join-Path $ScriptDir "freshservice.plugin"
|
|
if (Test-Path $Out) { Remove-Item $Out }
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
# CreateFromDirectory includes dot-directories (.claude-plugin), unlike
|
|
# Compress-Archive with a wildcard path.
|
|
[System.IO.Compression.ZipFile]::CreateFromDirectory($Build, $Out)
|
|
Remove-Item -Recurse -Force $Build
|
|
|
|
Write-Host "Built: $Out"
|
|
Write-Host "Install it in Claude Desktop (Cowork -> Customize -> add plugin), then start a new chat."
|
|
Write-Host "REMINDER: this file contains your personal API key -- don't share it."
|