Skip to content

Commit 0263b0b

Browse files
leggetterclaudegithub-actions[bot]
authored
feat: v2.0.0: MCP server, telemetry, issues CLI, metrics consolidation, Go SDK removal (#231)
* docs: add detailed MCP server implementation plan Comprehensive implementation plan mapping all 11 MCP tools to existing CLI codebase with exact file paths, API client methods, request/response types, and MCP input schemas. Identifies gaps (issues API client missing) and surfaces 9 questions covering functionality unknowns, plan ambiguities, and implementation risks. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * docs: update MCP plan with Issues backfill, metrics consolidation, and OpenAPI spec - Expand Section 1.2.9 (Issues) with full OpenAPI-derived schema, API client code, CLI commands, and MCP tool design - Rewrite Section 1.2.10 (Metrics) with 7→4 subcommand consolidation and CLI-layer routing logic - Update Section 1.3 (File Structure) with all new/modified/removed files - Replace resolved Q1-Q3 in Section 2 with updated open questions - Add OpenAPI spec (2025-07-01) to plans/ for reference https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Add Phase 1 progress tracker to implementation plan Adds a checklist at the top of the plan document breaking Phase 1 into 5 parts: Issues CLI backfill, Metrics consolidation, MCP server skeleton, MCP tool implementations, and integration testing. Each part lists every file/task as a checkbox so progress can be tracked across commits. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Phase 1 Part 1: Issues CLI backfill — complete Add full Issues API client and CLI commands: - pkg/hookdeck/issues.go: Issue types, enums, and 5 API client methods (ListIssues, GetIssue, UpdateIssue, DismissIssue, CountIssues) - pkg/cmd/issue.go: Issue group command (issue/issues aliases) - pkg/cmd/issue_list.go: List with filters (type, status, trigger, pagination) - pkg/cmd/issue_get.go: Get single issue by ID - pkg/cmd/issue_update.go: Update issue status (with validation) - pkg/cmd/issue_dismiss.go: Dismiss issue (DELETE, with confirmation) - pkg/cmd/issue_count.go: Count issues with filters - Register via addIssueCmdTo() in gateway.go - Mark Part 1 complete in plan progress tracker https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Add acceptance tests for issue commands Covers all 5 issue subcommands: - Help: verifies all subcommands listed, plural alias works - List: basic, type/status/limit/order-by filters, JSON output - Count: basic, type filter, status filter - Get/Update/Dismiss: argument validation (missing ID, missing status, invalid status) - Workflow: list → get → update on a real issue (skips if none exist) Follows the same patterns as metrics_test.go and event_test.go. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * test(acceptance): consolidate issue tests, skip flaky real-data tests - Single issue_test.go (was issue_0_test, issue_dismiss, issue_resolve) - Skip 18 tests that use createConnectionWithFailingTransformationAndIssue (flaky due to backend timing); 7 stable tests run (help + validation) - Helpers: createConnectionWithFailingTransformationAndIssue, dismissIssue, Issue type Made-with: Cursor * Add acceptance test requirements for CLI changes to implementation plan Parts 1-3 now include acceptance test tasks, and Part 5 separates CLI acceptance testing from MCP integration testing. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Expand Part 2 to cover all 4 metrics subcommands, not just events Part 2 now explicitly covers verifying --measures/--dimensions on requests, attempts, and transformations, plus comprehensive acceptance test updates for the full consolidation from 7 to 4 subcommands. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Consolidate metrics CLI from 7 subcommands to 4 resource-aligned ones Fold queue-depth, pending, and events-by-issue into the events subcommand with smart routing based on --measures and --dimensions flags: - queue_depth/max_depth/max_age measures → QueryQueueDepth API - pending measure with --granularity → QueryEventsPendingTimeseries API - issue_id dimension or --issue-id → QueryEventsByIssue API - All other combinations → QueryEventMetrics API (default) Remove metrics_pending.go, metrics_queue_depth.go, metrics_events_by_issue.go. Update acceptance tests to cover consolidated routing and verify --measures/--dimensions on all 4 subcommands. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * fix(metrics): help text, pending API measure, per-issue validation; expand acceptance tests - Help: user-facing copy for metrics and events (no 'consolidate'); document --issue-id required for per-issue in Long and flag help - Pending timeseries: send measures=count to API (routing keeps --measures pending) - Events-by-issue: require --issue-id when routing; clear error and help text - Tests: TestMetricsHelp asserts --start/--end; remove NotContains for old subcommands - Tests: TestMetricsEventsPerIssueRequiresIssueID (client-side validation) - Tests: requests/attempts/transformations — output JSON, granularity, one filter each; transformations missing start/end validation Made-with: Cursor * Update plan: mark Parts 1 and 2 as complete https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Add MCP server skeleton (Part 3): command, server, tools, error translation - Add github.com/modelcontextprotocol/go-sdk v1.4.0 dependency - Create pkg/gateway/mcp/ package: server.go (MCP server init + stdio transport), tools.go (11 tool definitions with placeholder handlers), errors.go (API error → MCP error translation), response.go (JSON/text/ error result helpers) - Create pkg/cmd/mcp.go: `hookdeck gateway mcp` Cobra command that validates auth, gets API client, and starts the MCP stdio server - Register MCP subcommand in pkg/cmd/gateway.go - Add acceptance tests: TestMCPHelp, TestGatewayHelpListsMCP The skeleton compiles, registers all 11 tools (placeholder implementations), and will respond to MCP initialize requests over stdio. Part 4 will fill in the real tool handler implementations. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Update plan: mark Part 3 as complete https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * fix(mcp): add required input schema for all tools The MCP go-sdk requires a non-nil input schema with type "object" for every tool (AddTool panics otherwise). Use a shared emptyObjectSchema so the server starts and responds to initialize/tools/list/tools/call. Made-with: Cursor * docs: update MCP plan with current status and next steps Parts 1-3 are complete. Add status summary table, note the InputSchema fix, and mark Part 4 (tool implementations) as next. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * feat(mcp): implement all 11 tool handlers with real API calls (Part 4) Replace placeholder handlers with real implementations that call the Hookdeck API. Each tool parses JSON arguments, maps parameters to API query params, and returns structured JSON results. Tools implemented: - hookdeck_projects: list/use (session-scoped project switching) - hookdeck_connections: list/get/pause/unpause - hookdeck_sources: list/get - hookdeck_destinations: list/get - hookdeck_transformations: list/get - hookdeck_requests: list/get/raw_body/events/ignored_events/retry - hookdeck_events: list/get/raw_body/retry/cancel/mute - hookdeck_attempts: list/get - hookdeck_issues: list/get/update/dismiss - hookdeck_metrics: events/requests/attempts/transformations - hookdeck_help: overview and per-tool detailed help Also adds proper JSON Schema input definitions for all tools and a shared input parsing helper (input.go) for typed argument extraction. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * docs(mcp): add Section 1.7 — MCP authentication & login flow design Document the hookdeck_login tool for in-band browser-based authentication when the CLI is not yet logged in. The MCP server always starts (never crashes on missing auth), registers all resource tools upfront, and adds a hookdeck_login tool when unauthenticated. Resource tools return isError until login completes. After login, hookdeck_login is removed via tools/list_changed notification. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * feat(mcp): implement hookdeck_login tool for in-band browser auth When the CLI is not authenticated, the MCP server now starts successfully (never crashes) and registers a hookdeck_login tool alongside all resource tools. Resource tools return isError until login completes. The login tool initiates browser-based device auth, polls for completion, saves credentials, and removes itself via tools/list_changed once authenticated. Changes: - New auth.go: requireAuth() helper for auth-gating - New tool_login.go: hookdeck_login handler using StartLogin/WaitForAPIKey - server.go: accepts *config.Config, conditionally registers login tool - mcp.go: removed ValidateAPIKey gate, passes config to NewServer - All 10 resource tool handlers: added requireAuth() check https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Fix metrics measures requirement and help topic error message - Mark 'measures' as required in hookdeck_metrics JSON schema so LLM clients know to include it (was causing confusing 422 errors) - Add server-side validation for measures in buildMetricsParams - Improve hookdeck_help error when topic doesn't match a tool name: now lists all available tools instead of a bare "unknown tool" message https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Document auth design decision: no API key param on hookdeck_login The hookdeck_login tool deliberately only supports browser-based device auth. For CI/headless environments, pass --api-key in the MCP server config. Both paths tested and verified against live API. Also updates Part 4 status to COMPLETE with accurate action lists. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * test(mcp): add integration tests for MCP server (Part 5) 20 tests covering server initialization, tool listing, help tool, auth guard, error translation, mock API tool calls, error scenarios (404, 422, 429), and input validation. Uses MCP SDK InMemoryTransport for end-to-end client-server testing. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * docs: README TOC, intro rebalance, Event Gateway MCP section, quick links Made-with: Cursor * Update package.json version to 1.10.0-beta.1 * docs: clarify MCP is client-started, config-first in README Made-with: Cursor * test(mcp): expand to comprehensive coverage of all tools and actions 94 tests (up from 20) covering all 12 tools and all 36 actions: - sources: list, get (success + missing ID + API errors 404/422/429) - destinations: list, get (success + missing ID + unknown action) - connections: list, get, pause, unpause (success + missing ID + disabled filter) - transformations: list, get (success + missing ID) - attempts: list, get (success + missing ID) - events: list, get, raw_body, retry, cancel, mute (success + missing ID + truncation + connection_id→webhook_id mapping) - requests: list, get, raw_body, events, ignored_events, retry (success + missing ID + truncation + connection_ids + verified filter) - issues: list, get, update, dismiss (success + missing ID + missing status) - projects: list, use (success + missing project_id + not found) - metrics: events (4 routing paths: default, queue_depth, pending_timeseries, by_issue), requests, attempts, transformations (missing start/end/measures) - login: already-authenticated early return - help: overview, specific topic, short name, unknown topic - auth guard: all 10 resource tools reject unauthenticated - input parsing: accessors, empty args, invalid JSON - error translation: 401, 404, 422, 429, 500, non-API https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * refactor(mcp): remove write operations to align with RFC read-only principle Per RFC #228, the MCP server should be read-focused for investigation workflows. Remove write actions that were added beyond the RFC scope: - events: remove retry, cancel, mute actions - requests: remove retry action - issues: remove update, dismiss actions Connection pause/unpause are retained as they are explicitly scoped in the RFC as "lightweight flow-control actions". https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * docs(mcp): rewrite tool descriptions for investigation focus and expand README Update all MCP tool descriptions to accurately reflect read-only investigation capabilities per MCP best practices: - Replace generic "Manage" with specific verbs (inspect, query, list) - Add contextual detail about what each tool returns and when to use it - Describe the webhook data model (requests → events → attempts) Expand README MCP section with: - Available tools table showing all 11 tools - Claude Desktop configuration alongside Cursor - Seven example prompts demonstrating investigation workflows https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * docs(mcp): use event-centric terminology instead of webhook-heavy language Hookdeck is HTTP in, HTTP out — webhook events are one type of event trigger. Update tool descriptions and README to reflect this: - "webhook sources" → "inbound sources" - "webhook delivery destinations" → "delivery destinations" - "webhook payloads" → "event payloads" - "webhook connections" → "connections" - "webhook traffic" → "event traffic" - Use "webhook events" only where specifically about webhooks https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * docs(mcp): update destination description to mention HTTP, CLI, MOCK types https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Update package.json version to 1.10.0-beta.2 * docs: add acceptance test setup to AGENTS.md, mark Part 5 complete in plan - AGENTS.md: add pointer to test/acceptance/README.md for API key setup - Plan: mark all Part 5 checklist items complete with test references https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * docs(mcp): add high-level plan for MCP investigation and operations Introduced a new document detailing the Hookdeck MCP build-out plan v2, focusing on the investigation and operations layer. The plan outlines the goals, scope, and phases of implementation, including success criteria and an end-to-end example of a production investigation workflow. This document serves as a guide for implementers and PMs, ensuring clarity on the MCP's capabilities and limitations. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Update v2 plan: reflect implemented features and add missing features section Updates the plan to match the actual implementation: - Add hookdeck_login tool (in-band browser auth, conditional registration, self-removing) - Add raw_body action to events and requests tools - Add events and ignored_events actions to requests tool - Update tool count from 11 to 12 - Update auth section to describe both pre-auth and in-band login paths - Resolve events enrichment decision (chose simpler path) - Fix server description mentioning retry (out of scope for Phase 1) - Update error handling table to match actual TranslateAPIError implementation Adds Section 7 "Missing features for consideration" covering 7 gaps: - Help tool skills+CLI redirect, server description, slog logging, project selection validation, projects name resolution, richer errors, and Retry-After header surfacing. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * chore: add CLAUDE.md to .gitignore Keep Claude Code project notes local-only so branch configuration doesn't get committed to the repository. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * test(mcp): add tests for server info, all help topics, and cross-tool errors Covers gaps identified in test review: - Server name/version via InitializeResult - Help topics for all 11 tools (full and short name forms) - Help overview lists all tools and handles empty ProjectID - Unknown topic error includes available tools list - Error translation for 401, 409, 429, 500, 502, 503 across different tools - Cross-tool error scenarios (destinations 500, connections 401, issues 422, attempts 429) https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Update package.json version to 1.10.0-beta.3 * fix(mcp): make hookdeck_login non-blocking so browser URL is shown immediately Previously, handleLogin blocked for up to 4 minutes while polling for the user to complete browser auth. The browser URL was only returned in the tool result after polling finished, meaning the user never saw it — they just saw a spinner with no way to authenticate. Now the handler returns the browser URL immediately and polls in a background goroutine. Subsequent calls to hookdeck_login report "in progress" (with the URL) or the final result. Once auth completes, the background goroutine updates the shared client and removes the login tool. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Update package.json version to 1.10.0-beta.4 * docs: add telemetry instrumentation plan for CLI and MCP usage tracking Outlines the design for making Hookdeck-CLI-Telemetry header useful: adding source (cli/mcp), invocation_id for grouping multi-call commands, and mcp_client identification. Covers both the internal client and SDK client paths, with a WithTelemetry() clone approach for MCP concurrency. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Add Phase 5: telemetry opt-out via config and CI detection strategy Adds plan for persistent telemetry disable in config.toml (top-level setting, not per-profile) with precedence: env var > config > default enabled. Includes CI/CD detection strategy that tags CI traffic as source="ci" rather than auto-disabling, preserving analytics visibility while enabling server-side filtering. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Separate source and environment as orthogonal telemetry dimensions source (cli/mcp) describes the interface; environment (interactive/ci) describes the runtime context. These are independent axes that enable cross-tabulation (e.g. "MCP tool calls from CI"). Previously CI was overloading the source field which would have lost that information. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Move telemetry plan to plans/ with descriptive name Renamed PLAN.md to plans/cli_mcp_telemetry_instrumentation_plan.md. Consolidated duplicate file change entries, added key source files reference table for implementer orientation. https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * Restructure telemetry plan: move to plans/, reorder sections - Moved PLAN.md to plans/cli_mcp_telemetry_instrumentation_plan.md - Reordered so all phases (1-6) are contiguous under Implementation - Promoted CI detection to Phase 6 (was nested under Phase 5) - Moved File Change Summary, Risks, Key Source Files, Testing after phases - Added CI-specific test cases to Testing Strategy https://claude.ai/code/session_01Y2eJZgKG78nDyN6Uw2tWQx * feat: Add CLI telemetry instrumentation and remove deprecated SDK (#233) * feat: implement CLI and MCP telemetry instrumentation Extend the telemetry header with source, environment, command_path, invocation_id, and mcp_client fields so the API server can distinguish CLI from MCP requests and correlate multiple API calls to a single command invocation. Phase 1 - Telemetry struct & CLI wiring: - Add Source, Environment, InvocationID, MCPClient fields to CLITelemetry - Add NewInvocationID() generator (8 random bytes, hex-encoded) - Add initTelemetry() helper called from root PersistentPreRun - Fix Cobra PersistentPreRun chaining for connection command Phase 2 - MCP per-request telemetry: - Add Telemetry field + WithTelemetry() clone method on Client - Update PerformRequest to use per-request telemetry when set - Wrap MCP tool handlers to set per-invocation telemetry context - Extract MCP client info from ServerSession.InitializeParams() Phase 3 - SDK client: - Works automatically: PersistentPreRun populates singleton before GetClient() bakes headers at construction time Phase 5 - Config-based opt-out: - Add TelemetryDisabled to Config, read from config.toml - Update telemetryOptedOut() to accept config flag - Thread TelemetryDisabled through API and SDK client construction Phase 6 - CI detection: - Add DetectEnvironment() checking CI, GITHUB_ACTIONS, GITLAB_CI, JENKINS_URL, CODEBUILD_BUILD_ID, BUILDKITE, TF_BUILD env vars - Tag requests with environment: "ci" or "interactive" https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * test: add end-to-end MCP telemetry integration tests Add 6 integration tests that exercise the full pipeline: MCP tool call → wrapWithTelemetry → HTTP request → mock API server, verifying the Hookdeck-CLI-Telemetry header arrives with correct content. Tests cover: - Header sent with correct source/command_path/invocation_id/mcp_client - Each tool call gets a unique invocation ID - Command path reflects the action (hookdeck_sources/list vs /get) - Telemetry disabled by config (TelemetryDisabled=true) - Telemetry disabled by env var (HOOKDECK_CLI_TELEMETRY_OPTOUT=true) - Multiple API calls within one tool invocation share the same ID https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * feat: add `hookdeck telemetry enable/disable` CLI command Adds a telemetry subcommand with enable/disable actions so users can toggle anonymous telemetry without manually editing config.toml. https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * refactor: make enable/disable positional args of telemetry command Instead of separate subcommands, `hookdeck telemetry enable` and `hookdeck telemetry disable` now use a single command with a required positional argument. Also adds telemetry section to the README. https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * test: add singleton reset functions and CLI telemetry tests Add ResetTelemetryInstanceForTesting() and ResetAPIClientForTesting() to enable isolated testing of the CLI telemetry path. Add tests that verify the singleton reset → populate → HTTP request → header cycle, singleton isolation between sequential commands, and initTelemetry correctness including generated resource detection. https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * Extract telemetry header name to constant with RFC 6648 comment Add TelemetryHeaderName constant to avoid hardcoded header strings across the codebase. Include a comment explaining why we omit the "X-" prefix (deprecated by RFC 6648). https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * Remove deprecated hookdeck-go-sdk, migrate listen to direct API client The listen command was the only consumer of the hookdeck-go-sdk (pinned to API version 2024-03-01). This migrates it to use the direct hookdeck.Client which hits the current API version (2025-07-01) and reads telemetry from the singleton on every request — fixing the gap where the SDK client baked headers at creation time and never updated. - Replace all hookdecksdk types with hookdeck types (Source, Connection, Destination) across listen/, proxy/, and tui/ packages - Replace SDK client calls (Source.List, Connection.Create, etc.) with direct Client methods (ListSources, CreateConnection, etc.) - Use Destination.GetCLIPath()/SetCLIPath() instead of direct CliPath field - Delete pkg/hookdeck/sdkclient.go and pkg/config/sdkclient.go - Remove github.com/hookdeck/hookdeck-go-sdk from go.mod https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * Rename telemetry header to X-Hookdeck-CLI-Telemetry Add X- prefix for consistency with X-Hookdeck-Client-User-Agent. https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL * test: parallelize acceptance tests into three slices (#234) * docs: generate REFERENCE.md in-place, remove REFERENCE.template.md - Default input is REFERENCE.md; run with no args for in-place update - Update README generator instructions and --check example - Remove REFERENCE.template.md Made-with: Cursor * feat!: introduce Hookdeck config file and root --hookdeck-config flag - Rename root-level --config to --hookdeck-config to avoid conflict with source/destination --config (JSON body) and --config-file (JSON path). - Add HOOKDECK_CONFIG_FILE env var for config path; precedence is flag, then env, then .hookdeck/config.toml, then default location. - Document env var and flag in README (precedence list and Global Flags). - Update REFERENCE.md global options and acceptance tests. Made-with: Cursor * test: parallelize acceptance tests into three slices - Add feature build tags to all automated acceptance test files so tests can be split across parallel runs (CI and local). - CI: run three matrix jobs with tags split by estimated runtime; each job uses its own API key (HOOKDECK_CLI_TESTING_API_KEY, _2, _3). - Local: run_parallel.sh runs three slices in parallel, writing to test/acceptance/logs/slice0.log, slice1.log, slice2.log; add logs/ to .gitignore. - Helpers: support ACCEPTANCE_SLICE=2 and HOOKDECK_CLI_TESTING_API_KEY_3; per-slice config path and API key selection for isolated projects. - Rebalance slices for ~5–5.5 min wall time (slice 0: connection/source/ destination/gateway/etc.; slice 1: request, event; slice 2: attempt, metrics, issue, transformation). - Document three-slice setup, tags, and run commands in test/acceptance/README.md. Made-with: Cursor * Consolidate API client usage and fix telemetry opt-out for all clients Several places constructed hookdeck.Client directly, bypassing GetAPIClient(). These clients didn't carry TelemetryDisabled from config, so they'd send telemetry even when the user had opted out. Two-layer fix: 1. Safety net: Add Disabled flag to the telemetry singleton. PerformRequest now checks both the per-client TelemetryDisabled and the singleton's Disabled flag, so even stray clients respect the config-level opt-out. 2. Consistency: Route as many callers as possible through GetAPIClient(): - project.go: use config.GetAPIClient() instead of raw construction - whoami.go: use Config.GetAPIClient().ValidateAPIKey() - Login() validate path: use config.GetAPIClient().ValidateAPIKey() - proxy.go createSession: receive APIClient via proxy.Config - tui/model.go: receive APIClient via tui.Config - Remove login/validate.go (no longer called) For unauthenticated login clients (Login, GuestLogin, CILogin, InteractiveLogin, MCP tool_login), pass TelemetryDisabled from config. https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL --------- Co-authored-by: Claude <noreply@anthropic.com> * Rename telemetry command arguments and environment variable (#235) * chore: bump version to 2.0.0-beta.0 and add comprehensive PR description Update package.json version from 1.10.0-beta.4 to 2.0.0-beta.0 to reflect the breaking changes in this release branch. Add PR_DESCRIPTION.md capturing the full scope of changes for the v2.0.0 release, including: - MCP server with 11 LLM-callable tools - Issues CLI (list, get, count, update, dismiss) - Telemetry instrumentation with opt-out support - Metrics consolidation (7 subcommands → 4) - Deprecated Hookdeck Go SDK removal (API 2024-03-01 → 2025-07-01) - Breaking change: --config flag renamed to --hookdeck-config https://claude.ai/code/session_012a587AhAbbWdqYx76cexPG * feat(mcp): add beta wrapping to MCP command and remove PR_DESCRIPTION.md Add ShortBeta/LongBeta wrapping to the MCP command for consistency with all other gateway subcommands. Remove PR_DESCRIPTION.md as it doesn't belong in the codebase. https://claude.ai/code/session_012a587AhAbbWdqYx76cexPG * refactor(telemetry): rename env var to HOOKDECK_CLI_TELEMETRY_DISABLED and use enabled/disabled args - Rename HOOKDECK_CLI_TELEMETRY_OPTOUT to HOOKDECK_CLI_TELEMETRY_DISABLED to match Next.js convention and align with the config key name - Change `hookdeck telemetry enable|disable` to `hookdeck telemetry enabled|disabled` - Update all tests and README accordingly https://claude.ai/code/session_012a587AhAbbWdqYx76cexPG --------- Co-authored-by: Claude <noreply@anthropic.com> * mcp: clarify event payload via raw_body, not request tool - Update hookdeck_events tool description to state that raw_body returns the event payload directly; agents should not use hookdeck_requests when they already have an event id. - Clarify in schema that get returns metadata/headers only; raw_body returns the payload. - Update help text for hookdeck_events to match. Made-with: Cursor * Update package.json version to 2.0.0-beta.1 * docs(cli): add cli.arguments annotations for connection get/update/delete/disable/enable/pause/unpause/upsert Enables website generator to emit required positional placeholders in asides. Made-with: Cursor * feat: project type (Gateway/Outpost/Console), gateway gating, whoami/list/use updates (#237) * feat: project type (Gateway/Outpost/Console), gateway gating, whoami/list/use updates - Add project_type to config (gateway, outpost, console) with fallback from project_mode - whoami: show Project type line - project list: show type column; --output json with id, org, project, type, current; --type filter - project use: use normalized list, match by id or org/project display - gateway: PersistentPreRunE requires Gateway project; block on Outpost/Console with clear error - MCP: tool_projects returns type; tool_login persists type; outbound excluded - Acceptance: project list tests require HOOKDECK_CLI_TESTING_CLI_KEY, auth via login --api-key Made-with: Cursor * test(acceptance): add project list filter-by-type and filter-by-org tests - TestProjectListFilterByType: project list --type gateway --output json, assert all items type gateway - TestProjectListFilterByOrgProject: project list <org_substring> --output json, assert org contains substring Both require HOOKDECK_CLI_TESTING_CLI_KEY (skip with clear message when unset). Made-with: Cursor * test(acceptance): add project list invalid --type and two-arg filter tests - TestProjectListInvalidType: project list --type invalid returns error (no CLI key) - TestProjectListFilterByOrgAndProject: project list <org> <project> --output json filters by both substrings Made-with: Cursor * feat: treat outbound project mode as Gateway (same as inbound) - ModeToProjectType(outbound) now returns ProjectTypeGateway; outbound projects appear in list as Gateway - IsGatewayProject(outbound) true so gateway commands work when profile has outbound mode - Unit tests: ModeToProjectType/IsGatewayProject outbound, NormalizeProjects includes outbound as Gateway, requireGatewayProject passes for outbound mode Made-with: Cursor * Update package.json version to 2.0.0-beta.2 * fix: init telemetry in gateway PersistentPreRunE and add regression tests - Call initTelemetry(cmd) in gateway's PersistentPreRunE so gateway subcommands send non-empty CLI telemetry (command_path, device_name, etc.). Cobra does not chain PersistentPreRun; adding requireGatewayProject in #237 replaced root's hook and skipped initTelemetry. - Add TestInitTelemetryWhenDisabled: initTelemetry must run even when telemetry is disabled (singleton is still populated; header is skipped in PerformRequest). - Add TestAllCommandsWithPersistentPreRunInitTelemetry: any command with its own PersistentPreRun(E) must call initTelemetry(cmd) so the test fails if a new command overrides the hook without initializing telemetry. Made-with: Cursor * Update package.json version to 2.0.0-beta.3 * fix: treat 410 Gone as not-found Hookdeck may return 410 for deleted resources; classify it as not-found to keep deletion UX and tests consistent. Made-with: Cursor * fix: use --hookdeck-config in login/ci local conflict tests and error messages - Acceptance tests: pass --hookdeck-config (not --config) when testing login --local / ci --local conflict; update comments and assertions. - login.go / ci.go: error message now says --hookdeck-config to match the actual global flag name. - Unit tests (login_ci_local_test.go): comments and require messages updated to --hookdeck-config for consistency. Made-with: Cursor --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
1 parent bd35f40 commit 0263b0b

123 files changed

Lines changed: 10124 additions & 828 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test-acceptance.yml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,24 @@ on:
77
- main
88

99
jobs:
10-
test:
10+
acceptance:
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
include:
15+
- slice: "0"
16+
api_key_secret: HOOKDECK_CLI_TESTING_API_KEY
17+
tags: "basic connection source destination gateway mcp listen project_use connection_list connection_upsert connection_error_hints connection_oauth_aws connection_update"
18+
- slice: "1"
19+
api_key_secret: HOOKDECK_CLI_TESTING_API_KEY_2
20+
tags: "request event"
21+
- slice: "2"
22+
api_key_secret: HOOKDECK_CLI_TESTING_API_KEY_3
23+
tags: "attempt metrics issue transformation"
1124
runs-on: ubuntu-latest
1225
env:
13-
HOOKDECK_CLI_TESTING_API_KEY: ${{ secrets.HOOKDECK_CLI_TESTING_API_KEY }}
26+
ACCEPTANCE_SLICE: ${{ matrix.slice }}
27+
HOOKDECK_CLI_TESTING_API_KEY: ${{ secrets[matrix.api_key_secret] }}
1428
steps:
1529
- name: Check out code
1630
uses: actions/checkout@v3
@@ -20,5 +34,5 @@ jobs:
2034
with:
2135
go-version: "1.24.9"
2236

23-
- name: Run Go Acceptance Tests
24-
run: go test ./test/acceptance/... -v -timeout 20m
37+
- name: Run Go Acceptance Tests (slice ${{ matrix.slice }})
38+
run: go test -tags="${{ matrix.tags }}" ./test/acceptance/... -v -timeout 12m

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ default_cassette.yaml
1616
__debug_bin
1717
node_modules/
1818
.env
19+
test/acceptance/logs/
1920
test-scripts/.install-test/
2021

2122
# Temporary OpenAPI spec download (large; do not commit)
@@ -24,5 +25,5 @@ test-scripts/.install-test/
2425
# Claude Code temporary worktrees
2526
.claude/worktrees/
2627

27-
# Auto-implement local worktrees (run-local-assess creates these)
28-
.worktrees/
28+
# Claude Code project notes (local only)
29+
CLAUDE.md

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,12 @@ if apiErr, ok := err.(*hookdeck.APIError); ok {
351351
- **Always run tests** when changing code. Run unit tests (`go test ./pkg/...`) and, for CLI-facing changes, acceptance tests (`go test ./test/acceptance/...`). If tests fail due to TLS/network/sandbox (e.g. `x509`, `operation not permitted`), prompt the user and re-run with elevated permissions (e.g. `required_permissions: ["all"]`) so tests can pass.
352352
- **Create tests for new functionality.** Add unit tests for validation and business logic; add acceptance tests for flows that use the CLI as a user or agent would (success and failure paths). Acceptance tests must pass or fail—no skipping to avoid failures.
353353
354+
### Acceptance Test Setup
355+
Acceptance tests require a Hookdeck API key. See [`test/acceptance/README.md`](test/acceptance/README.md) for full details. Quick setup: create `test/acceptance/.env` with `HOOKDECK_CLI_TESTING_API_KEY=<key>`. The `.env` file is git-ignored and must never be committed.
356+
357+
### Acceptance tests and feature tags
358+
Acceptance tests in `test/acceptance/` are partitioned by **feature build tags** so they can run in parallel (two slices in CI and locally). Each test file must have exactly one feature tag (e.g. `//go:build connection`, `//go:build request`). The runner (CI workflow or `run_parallel.sh`) maps features to slices and passes the corresponding `-tags="..."`; see [test/acceptance/README.md](test/acceptance/README.md) for slice mapping and setup. **Every new acceptance test file must have a feature tag**; otherwise it is included in every build and runs in both slices (duplicated). Use tags to balance and parallelize; same commands and env for local and CI.
359+
354360
### Unit Testing
355361
- Test validation logic thoroughly
356362
- Mock API calls for command tests

README.md

Lines changed: 142 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,50 @@ Using the Hookdeck CLI, you can forward your events (e.g. webhooks) to your loca
88

99
Hookdeck CLI is compatible with most of Hookdeck's features, such as filtering and fan-out delivery. You can use Hookdeck CLI to develop or test your event (e.g. webhook) integration code locally.
1010

11+
You can also manage Hookdeck Event Gateway resources—sources, destinations, connections, events, transformations—from the CLI. For AI and agent workflows, the Event Gateway MCP server (`hookdeck gateway mcp`) exposes these capabilities as tools in MCP-compatible clients (e.g. Cursor, Claude).
12+
1113
Although it uses a different approach and philosophy, it's a replacement for ngrok and alternative HTTP tunnel solutions.
1214

1315
Hookdeck for development is completely free, and we monetize the platform with our production offering.
1416

1517
For a complete reference of all commands and flags, see [REFERENCE.md](REFERENCE.md).
1618

19+
## Table of contents
20+
21+
- [Installation](#installation)
22+
- [NPM](#npm)
23+
- [macOS](#macos)
24+
- [Windows](#windows)
25+
- [Linux Or without package managers](#linux-or-without-package-managers)
26+
- [Docker](#docker)
27+
- [Usage](#usage)
28+
- [Commands](#commands)
29+
- [Login](#login)
30+
- [Listen](#listen)
31+
- [Logout](#logout)
32+
- [Skip SSL validation](#skip-ssl-validation)
33+
- [Disable health checks](#disable-health-checks)
34+
- [Version](#version)
35+
- [Completion](#completion)
36+
- [Running in CI](#running-in-ci)
37+
- [Event Gateway](#event-gateway)
38+
- [Event Gateway MCP](#event-gateway-mcp)
39+
- [Manage connections](#manage-connections)
40+
- [Transformations](#transformations)
41+
- [Requests, events, and attempts](#requests-events-and-attempts)
42+
- [Manage active project](#manage-active-project)
43+
- [Telemetry](#telemetry)
44+
- [Configuration files](#configuration-files)
45+
- [Global Flags](#global-flags)
46+
- [Troubleshooting](#troubleshooting)
47+
- [Developing](#developing)
48+
- [Testing](#testing)
49+
- [Releasing](#releasing)
50+
- [Repository Setup](#repository-setup)
51+
- [License](#license)
52+
53+
**Quick links:** [Local development (Listen)](#listen) · [Resource management (CLI)](#event-gateway) / [Manage connections](#manage-connections) · [AI / agent integration (Event Gateway MCP)](#event-gateway-mcp)
54+
1755
https://github.com/user-attachments/assets/7a333c5b-e4cb-45bb-8570-29fafd137bd2
1856

1957

@@ -491,6 +529,83 @@ hookdeck gateway transformation run --code "addHandler(\"transform\", (request,
491529

492530
For complete command and flag reference, see [REFERENCE.md](REFERENCE.md).
493531

532+
### Event Gateway MCP
533+
534+
The CLI includes an [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server for investigating event traffic in production. It exposes read-only tools that let AI agents query your Hookdeck Event Gateway — inspect connections, trace requests through events and delivery attempts, review issues, and pull aggregate metrics.
535+
536+
**Configure your MCP client** (Cursor, Claude Desktop, or any MCP-compatible host):
537+
538+
Cursor (`~/.cursor/mcp.json`):
539+
540+
```json
541+
{
542+
"mcpServers": {
543+
"hookdeck": {
544+
"command": "hookdeck",
545+
"args": ["gateway", "mcp"]
546+
}
547+
}
548+
}
549+
```
550+
551+
Claude Desktop (`claude_desktop_config.json`):
552+
553+
```json
554+
{
555+
"mcpServers": {
556+
"hookdeck": {
557+
"command": "hookdeck",
558+
"args": ["gateway", "mcp"]
559+
}
560+
}
561+
}
562+
```
563+
564+
The client starts `hookdeck gateway mcp` as a stdio subprocess. If you haven't authenticated yet, the `hookdeck_login` tool is available to log in via the browser.
565+
566+
#### Available tools
567+
568+
| Tool | Description |
569+
|------|-------------|
570+
| `hookdeck_projects` | List projects or switch the active project for this session |
571+
| `hookdeck_connections` | Inspect connections and control delivery flow (list, get, pause, unpause) |
572+
| `hookdeck_sources` | Inspect inbound sources (HTTP endpoints that receive events) |
573+
| `hookdeck_destinations` | Inspect delivery destinations (HTTP endpoints where events are sent) |
574+
| `hookdeck_transformations` | Inspect JavaScript transformations applied to event payloads |
575+
| `hookdeck_requests` | Query inbound requests — list, get details, raw body, linked events |
576+
| `hookdeck_events` | Query processed events — list, get details, raw payload body |
577+
| `hookdeck_attempts` | Query delivery attempts — retry history, response codes, errors |
578+
| `hookdeck_issues` | Inspect aggregated failure signals (delivery failures, transform errors, backpressure) |
579+
| `hookdeck_metrics` | Query aggregate metrics — counts, failure rates, queue depth over time |
580+
| `hookdeck_help` | Discover available tools and their actions |
581+
582+
#### Example prompts
583+
584+
Once the MCP server is configured, you can ask your agent questions like:
585+
586+
```
587+
"Are any of my events failing right now?"
588+
→ Agent uses hookdeck_issues to list open issues, then hookdeck_events to inspect recent failures.
589+
590+
"Show me the last 10 events for my Stripe source and check if any failed."
591+
→ Agent uses hookdeck_sources to find the Stripe source, then hookdeck_events filtered by source and status.
592+
593+
"What's the error rate for my API destination over the last 24 hours?"
594+
→ Agent uses hookdeck_metrics with measures like failed_count and count, grouped by destination.
595+
596+
"Trace request req_abc123 — what events did it produce, and did they all deliver successfully?"
597+
→ Agent uses hookdeck_requests to get the request, then the events action to list generated events.
598+
599+
"Why is my checkout endpoint returning 500s? Show me the latest attempt details."
600+
→ Agent uses hookdeck_events filtered by status FAILED, then hookdeck_attempts to inspect delivery details.
601+
602+
"Pause the connection between Stripe and my staging endpoint while I debug."
603+
→ Agent uses hookdeck_connections to find and pause the connection.
604+
605+
"Compare failure rates across all my destinations this week."
606+
→ Agent uses hookdeck_metrics with dimensions set to destination_id and measures like error_rate.
607+
```
608+
494609
### Manage connections
495610

496611
Create and manage webhook connections between sources and destinations with inline resource creation, authentication, processing rules, and lifecycle management. Use `hookdeck gateway connection` (or the backward-compatible alias `hookdeck connection`). For detailed examples with authentication, filters, retry rules, and rate limiting, see the complete [connection management](#manage-connections) section below.
@@ -617,7 +732,7 @@ By default, `project use` saves your selection to the **global configuration** (
617732

618733
The CLI uses exactly one configuration file based on this precedence:
619734

620-
1. **Custom config** (via `--config` flag) - highest priority
735+
1. **Custom config** (via `--hookdeck-config` flag) - highest priority
621736
2. **Local config** - `${PWD}/.hookdeck/config.toml` (if exists)
622737
3. **Global config** - `~/.config/hookdeck/config.toml` (default)
623738

@@ -667,11 +782,11 @@ This ensures your directory-specific configuration is preserved when it exists.
667782
hookdeck project use my-org my-project
668783
hookdeck project use my-org my-project --local
669784

670-
# ❌ Invalid (cannot combine --config with --local)
671-
hookdeck --config custom.toml project use my-org my-project --local
672-
Error: --local and --config flags cannot be used together
785+
# ❌ Invalid (cannot combine --hookdeck-config with --local)
786+
hookdeck --hookdeck-config custom.toml project use my-org my-project --local
787+
Error: --local and --hookdeck-config flags cannot be used together
673788
--local creates config at: .hookdeck/config.toml
674-
--config uses custom path: custom.toml
789+
--hookdeck-config uses custom path: custom.toml
675790
```
676791

677792
#### Benefits of local project pinning
@@ -980,6 +1095,20 @@ $ hookdeck gateway connection delete conn_123abc --force
9801095

9811096
For complete flag documentation and all examples, see [REFERENCE.md](REFERENCE.md).
9821097

1098+
### Telemetry
1099+
1100+
The Hookdeck CLI collects anonymous telemetry to help improve the tool. You can opt out at any time:
1101+
1102+
```sh
1103+
# Disable telemetry
1104+
hookdeck telemetry disabled
1105+
1106+
# Re-enable telemetry
1107+
hookdeck telemetry enabled
1108+
```
1109+
1110+
You can also disable telemetry by setting the `HOOKDECK_CLI_TELEMETRY_DISABLED` environment variable to `1` or `true`.
1111+
9831112
## Configuration files
9841113

9851114
The Hookdeck CLI uses configuration files to store the your keys, project settings, profiles, and other configurations.
@@ -988,9 +1117,10 @@ The Hookdeck CLI uses configuration files to store the your keys, project settin
9881117

9891118
The CLI will look for the configuration file in the following order:
9901119

991-
1. The `--config` flag, which allows you to specify a custom configuration file name and path per command.
992-
2. The local directory `.hookdeck/config.toml`.
993-
3. The default global configuration file location.
1120+
1. The `--hookdeck-config` flag, which allows you to specify a custom configuration file path per command.
1121+
2. The `HOOKDECK_CONFIG_FILE` environment variable (path to the config file).
1122+
3. The local directory `.hookdeck/config.toml`.
1123+
4. The default global configuration file location.
9941124

9951125
### Default configuration Location
9961126

@@ -1065,7 +1195,7 @@ The following flags can be used with any command:
10651195

10661196
- `--api-key`: Your API key to use for the command.
10671197
- `--color`: Turn on/off color output (on, off, auto).
1068-
- `--config`: Path to a specific configuration file.
1198+
- `--hookdeck-config`: Path to the CLI configuration file. You can also set the `HOOKDECK_CONFIG_FILE` environment variable to the config file path.
10691199
- `--device-name`: A unique name for your device.
10701200
- `--insecure`: Allow invalid TLS certificates.
10711201
- `--log-level`: Set the logging level (debug, info, warn, error).
@@ -1107,16 +1237,16 @@ go run main.go
11071237

11081238
### Generating REFERENCE.md
11091239

1110-
The [REFERENCE.md](REFERENCE.md) file is generated from Cobra command metadata. After changing commands, flags, or help text, regenerate it:
1240+
The [REFERENCE.md](REFERENCE.md) file is generated from Cobra command metadata. After changing commands, flags, or help text, regenerate it in place:
11111241

11121242
```sh
1113-
go run ./tools/generate-reference --input REFERENCE.template.md --output REFERENCE.md
1243+
go run ./tools/generate-reference
11141244
```
11151245

11161246
To validate that REFERENCE.md is up to date (useful in CI):
11171247

11181248
```sh
1119-
go run ./tools/generate-reference --input REFERENCE.template.md --output REFERENCE.md --check
1249+
go run ./tools/generate-reference --check
11201250
```
11211251

11221252
Build from source by running:

0 commit comments

Comments
 (0)