-
Notifications
You must be signed in to change notification settings - Fork 1
docs: canonicalize AGENTS.md as the agent guide and freshen against code #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
jack-arturo
wants to merge
3
commits into
main
Choose a base branch
from
docs/agents-md-canonical
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+152
−102
Draft
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| # AGENTS.md | ||
|
|
||
| This file provides guidance to coding agents (Claude Code, Cursor, Codex, and others) when working with code in this repository. `CLAUDE.md` imports this file via `@AGENTS.md`, so this is the single source of truth for agent direction. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| MCP Pirsch Server - A Model Context Protocol server that provides analytics tools for Pirsch Analytics. It enables natural language queries, comparisons, and trend analysis of website traffic through an MCP interface. The server speaks MCP over stdio (`src/index.ts:1`). | ||
|
|
||
| ## Development Commands | ||
|
|
||
| ```bash | ||
| # Install dependencies | ||
| npm install | ||
|
|
||
| # Build TypeScript to JavaScript (dist/) — runs clean prebuild + chmod postbuild | ||
| npm run build | ||
|
|
||
| # Development mode with auto-reload (tsx watch) | ||
| npm run dev | ||
|
|
||
| # Start production server (node dist/index.js) | ||
| npm start | ||
|
|
||
| # Run the test suite (Vitest, single run) | ||
| npm test | ||
|
|
||
| # Watch-mode tests / coverage | ||
| npm run test:watch | ||
| npm run test:coverage | ||
|
|
||
| # Type-check without emitting, lint, and format | ||
| npm run typecheck | ||
| npm run lint | ||
| npm run format | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Core Components | ||
|
|
||
| - **src/index.ts**: MCP server implementation. Registers the tool list, wires `ListToolsRequestSchema`/`CallToolRequestSchema` handlers, resolves domain IDs, and implements the compare tool. | ||
| - **src/pirsch-api.ts**: `PirschAPI` client with token caching, auto-refresh, and retry/backoff (`src/pirsch-api.ts:19`). | ||
| - **src/filters.ts**: `buildFilterParams()` builds URL parameters from filter objects for API queries (`src/filters.ts:3`). | ||
| - **src/types.ts**: TypeScript interfaces for Pirsch data structures. | ||
| - **src/utils.ts**: Date range helpers (`getDateRange`, `isoDate`) and series aggregation (`sumSeries`, `pctChange`). | ||
|
|
||
| Each source module has a colocated `*.test.ts` (`src/index.test.ts`, `src/pirsch-api.test.ts`, `src/filters.test.ts`, `src/utils.test.ts`) run by Vitest (`vitest.config.ts`). | ||
|
|
||
| ### Token Management | ||
|
|
||
| The `PirschAPI` class implements token caching: | ||
| - Tokens are cached with expiration tracking; validity is checked against a configurable skew (`src/pirsch-api.ts:31`). | ||
| - Refreshes when the token expires within `PIRSCH_TOKEN_SKEW_MS` (default 60000 ms — `src/pirsch-api.ts:28`). | ||
| - Handles 401 responses with an automatic token refresh and retry (`src/pirsch-api.ts:93`). | ||
| - Rate limiting: 429 responses respect the `Retry-After` header before retrying (`src/pirsch-api.ts:99`). | ||
|
|
||
| ### MCP Tools Pattern | ||
|
|
||
| Most tools follow this structure: | ||
| 1. Resolve domain ID via `resolveDomainId()` — from args, `PIRSCH_DEFAULT_DOMAIN_ID`, or auto-detect by listing domains (`src/index.ts:349`). | ||
| 2. Build filter parameters using `buildFilterParams()`. | ||
| 3. Call the appropriate `PirschAPI` method / endpoint. | ||
| 4. Return a formatted response. | ||
|
|
||
| ## MCP Tools | ||
|
|
||
| The server registers **17 tools** (assembled into the `tools` array at `src/index.ts:507`): | ||
|
|
||
| | Tool | Purpose | | ||
| | --- | --- | | ||
| | `pirsch_list_domains` | List accessible Pirsch domains to discover domain IDs | | ||
| | `pirsch_overview` | Cached overview statistics for a domain (filters do not apply) | | ||
| | `pirsch_total` | Totals for visitors, views, sessions, bounces, bounce_rate, cr, custom metrics | | ||
| | `pirsch_visitors` | Visitors time series with optional scale | | ||
| | `pirsch_pages` | Page stats with sorting, search, optional avg time on page | | ||
| | `pirsch_entry_pages` | Entry page stats | | ||
| | `pirsch_exit_pages` | Exit page stats | | ||
| | `pirsch_referrers` | Referrer stats | | ||
| | `pirsch_goals` | Goal/conversion stats | | ||
| | `pirsch_events` | Event stats | | ||
| | `pirsch_event_pages` | Pages for a given event | | ||
| | `pirsch_growth` | Growth rates across core metrics for the period | | ||
| | `pirsch_sessions` | Session stats | | ||
| | `pirsch_session_details` | Session detail / page-flow lookups | | ||
| | `pirsch_utm` | UTM stats by dimension (source, medium, campaign, content, term) | | ||
| | `pirsch_active` | Active visitors and pages for the past N seconds (default 600) | | ||
| | `pirsch_compare` | Compare totals and visitor series between two periods | | ||
|
|
||
| Twelve of these (`pirsch_total` … `pirsch_session_details`) are generated from `statisticsToolConfigs` (`src/index.ts:419`); the rest are declared explicitly. When adding a statistics-style tool, add a config entry there; for a bespoke tool, add it directly to the `tools` array and a handler branch in the `CallToolRequestSchema` handler (`src/index.ts:561`). | ||
|
|
||
| ## Environment Configuration | ||
|
|
||
| Required environment variables (read in `src/index.ts:12`): | ||
| - `PIRSCH_CLIENT_ID`: OAuth client ID from Pirsch | ||
| - `PIRSCH_CLIENT_SECRET`: OAuth client secret from Pirsch | ||
|
|
||
| Optional: | ||
| - `PIRSCH_DEFAULT_DOMAIN_ID`: Default domain to query (auto-detects first domain if not set — `src/index.ts:14`) | ||
|
jack-arturo marked this conversation as resolved.
Outdated
|
||
| - `PIRSCH_TIMEZONE`: Default timezone passed to filter params (e.g. 'Europe/Berlin' — `src/pirsch-api.ts:140`) | ||
| - `PIRSCH_TOKEN_SKEW_MS`: Token refresh buffer in ms (default 60000 — `src/pirsch-api.ts:28`) | ||
|
|
||
| See `.env.example` for the canonical list. | ||
|
|
||
| ## Testing the MCP Server | ||
|
|
||
| ### Unit / integration tests | ||
| ```bash | ||
| npm test # vitest run | ||
| npm run test:watch | ||
| ``` | ||
|
|
||
| ### Local manual testing | ||
| ```bash | ||
| # Provide credentials and run the server (stdio transport) | ||
| PIRSCH_CLIENT_ID=xxx PIRSCH_CLIENT_SECRET=yyy npm run dev | ||
|
|
||
| # The server speaks stdio, so exercising tools requires an MCP client. | ||
| ``` | ||
|
|
||
| ### Integration with an MCP client | ||
| 1. Build the project: `npm run build` | ||
| 2. Register the server (e.g. `claude mcp add pirsch "npx @verygoodplugins/mcp-pirsch"`) or add it to `.mcp.json` / Claude Desktop config (see README). | ||
| 3. Restart the MCP client to load the server. | ||
| 4. Call `pirsch_list_domains` to verify the connection. | ||
|
|
||
| ## Key Implementation Details | ||
|
|
||
| ### Filter System | ||
| All statistics endpoints accept a filter object that maps to Pirsch API query parameters. `buildFilterParams()` (`src/filters.ts:3`) handles: | ||
| - Date/time ranges with timezone support | ||
| - Dimensions (path, referrer, browser, OS, etc.) | ||
| - UTM parameters | ||
| - Pagination and sorting | ||
| - Custom metrics and tags | ||
|
|
||
| Page-style tools additionally support an MCP-local `path_prefix` filter (`supportsLocalPathPrefix` in `statisticsToolConfigs`), normalized via `normalizePathPrefix()` (`src/index.ts:133`). | ||
|
|
||
| ### Comparison Logic | ||
| The `pirsch_compare` tool computes true period comparisons (`src/index.ts:320`): | ||
| 1. Fetches current and previous period totals directly from `/statistics/total`. | ||
| 2. Fetches current and previous visitor series from `/statistics/visitor`. | ||
| 3. Builds per-metric deltas with `buildComparisonTotals()` / `compareMetric()`, using `pctChange()` for percentage change (`src/index.ts:252`, `src/index.ts:256`). | ||
| 4. Returns both visitor series plus the computed totals/deltas. | ||
|
|
||
| (`sumSeries()` in `src/utils.ts` aggregates a visitor series and is unit-tested, but the compare tool relies on the `/statistics/total` endpoint for totals rather than summing the series.) | ||
|
|
||
| ### Error Handling | ||
| - Network/transient errors are retried with backoff in the request loop (`src/pirsch-api.ts:93`). | ||
| - 401 errors trigger a token refresh and retry. | ||
| - 429 rate limits respect `Retry-After` before retrying. | ||
| - Domain resolution throws a helpful error when no domain can be determined (`src/index.ts:355`). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,102 +1 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| MCP Pirsch Server - A Model Context Protocol server that provides analytics tools for Pirsch Analytics. It enables natural language queries, comparisons, and trend analysis of website traffic through an MCP interface. | ||
|
|
||
| ## Development Commands | ||
|
|
||
| ```bash | ||
| # Install dependencies | ||
| npm install | ||
|
|
||
| # Build TypeScript to JavaScript (dist/) | ||
| npm run build | ||
|
|
||
| # Development mode with auto-reload | ||
| npm run dev | ||
|
|
||
| # Start production server | ||
| npm start | ||
|
|
||
| # Quick test (runs help command) | ||
| npm test | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Core Components | ||
|
|
||
| - **src/index.ts**: MCP server implementation that registers tools and handles requests | ||
| - **src/pirsch-api.ts**: Pirsch API client with token caching and auto-refresh | ||
| - **src/filters.ts**: Builds URL parameters from filter objects for API queries | ||
| - **src/types.ts**: TypeScript interfaces for Pirsch data structures | ||
| - **src/utils.ts**: Date range helpers and data aggregation utilities | ||
|
|
||
| ### Token Management | ||
|
|
||
| The PirschAPI class implements intelligent token caching: | ||
| - Tokens are cached with expiration tracking | ||
| - Auto-refreshes 60 seconds before expiry (configurable via PIRSCH_TOKEN_SKEW_MS) | ||
| - Handles 401 errors with automatic retry after refresh | ||
| - Rate limiting with exponential backoff for 429 responses | ||
|
|
||
| ### MCP Tools Pattern | ||
|
|
||
| Each tool follows this structure: | ||
| 1. Resolve domain ID (from args, env, or auto-detect) | ||
| 2. Build filter parameters using buildFilterParams() | ||
| 3. Call appropriate PirschAPI method | ||
| 4. Return formatted response | ||
|
|
||
| ## Environment Configuration | ||
|
|
||
| Required environment variables: | ||
| - `PIRSCH_CLIENT_ID`: OAuth client ID from Pirsch | ||
| - `PIRSCH_CLIENT_SECRET`: OAuth client secret from Pirsch | ||
|
|
||
| Optional: | ||
| - `PIRSCH_DEFAULT_DOMAIN_ID`: Default domain to query (auto-detects if not set) | ||
| - `PIRSCH_TIMEZONE`: Default timezone for queries (e.g., 'Europe/Berlin') | ||
| - `PIRSCH_TOKEN_SKEW_MS`: Token refresh buffer in ms (default: 60000) | ||
|
|
||
| ## Testing the MCP Server | ||
|
|
||
| ### Local Testing | ||
| ```bash | ||
| # Test with environment variables | ||
| PIRSCH_CLIENT_ID=xxx PIRSCH_CLIENT_SECRET=yyy npm run dev | ||
|
|
||
| # The server expects stdio transport, so testing requires an MCP client | ||
| ``` | ||
|
|
||
| ### Integration Testing | ||
| 1. Build the project: `npm run build` | ||
| 2. Configure in `.mcp.json` or Claude Desktop config | ||
| 3. Restart the MCP client to load the server | ||
| 4. Test tools like `pirsch_list_domains` to verify connection | ||
|
|
||
| ## Key Implementation Details | ||
|
|
||
| ### Filter System | ||
| All statistics endpoints accept a FilterInput object that maps directly to Pirsch API query parameters. The buildFilterParams() function handles: | ||
| - Date/time ranges with timezone support | ||
| - Dimensions (path, referrer, browser, OS, etc.) | ||
| - UTM parameters | ||
| - Pagination and sorting | ||
| - Custom metrics and tags | ||
|
|
||
| ### Comparison Logic | ||
| The `pirsch_compare` tool implements period comparison by: | ||
| 1. Fetching two visitor series (current and comparison period) | ||
| 2. Computing totals using sumSeries() | ||
| 3. Calculating percentage changes with pctChange() | ||
| 4. Returning both series and delta metrics | ||
|
|
||
| ### Error Handling | ||
| - Network errors trigger retries with backoff | ||
| - 401 errors trigger token refresh | ||
| - 429 rate limits respect Retry-After headers | ||
| - Domain resolution fails gracefully with helpful messages | ||
| @AGENTS.md |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.