@last9/mcp-server 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +194 -70
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -28,7 +28,7 @@ You can connect to Last9 MCP in two ways:
28
28
  ### Recommended: Managed MCP over HTTP
29
29
 
30
30
  This is the easiest and cleanest setup. You do not need to run a local binary.
31
- Use an API token from [Last9 API Access](https://app.last9.io/settings/api-access).
31
+ You'll need a **Client Token** (MCP type) — see [Getting your credentials](#getting-your-credentials) below. Your org slug is in your Last9 URL: `app.last9.io/<org_slug>/...`
32
32
 
33
33
  ```bash
34
34
  claude mcp add --transport http last9 https://app.last9.io/api/v4/organizations/<organization_slug>/mcp \
@@ -73,6 +73,46 @@ npm install -g @last9/mcp-server@latest
73
73
  npx -y @last9/mcp-server@latest
74
74
  ```
75
75
 
76
+ #### GitHub Releases (Windows / manual install)
77
+
78
+ Download the binary for your platform from [GitHub Releases](https://github.com/last9/last9-mcp-server/releases/latest):
79
+
80
+ | Platform | Archive |
81
+ |----------|---------|
82
+ | Windows (x64) | `last9-mcp-server_Windows_x86_64.zip` |
83
+ | Windows (ARM64) | `last9-mcp-server_Windows_arm64.zip` |
84
+ | Linux (x64) | `last9-mcp-server_Linux_x86_64.tar.gz` |
85
+ | Linux (ARM64) | `last9-mcp-server_Linux_arm64.tar.gz` |
86
+ | macOS (x64) | `last9-mcp-server_Darwin_x86_64.tar.gz` |
87
+ | macOS (ARM64) | `last9-mcp-server_Darwin_arm64.tar.gz` |
88
+
89
+ Extract the archive. On Windows the binary is `last9-mcp-server.exe`. Use the full path to the binary in your MCP client config (see [Windows example](#windows-example-claude-desktop) below).
90
+
91
+ > On Windows, [NPM](#npm) is easier to set up (no path management needed), or use the [hosted HTTP transport](#recommended-managed-mcp-over-http) to skip local installation entirely.
92
+
93
+ ## Getting Your Credentials
94
+
95
+ ### For hosted MCP (recommended)
96
+
97
+ You need a **Client Token** with MCP type. Only **admins** can create tokens. If you're not an admin, ask your admin to create one or grant you admin access via [User Access settings](https://app.last9.io/settings/user-access).
98
+
99
+ 1. Go to [Ingestion Tokens](https://app.last9.io/control-plane/ingestion-tokens)
100
+ 2. Click **New Ingestion Token**
101
+ 3. Set **Token Type** to **Client**
102
+ 4. Set **Client Type** to **MCP**
103
+ 5. Enter a name (e.g., `claude-desktop`, `cursor`)
104
+ 6. Click **Create** — copy the token immediately (shown only once)
105
+
106
+ Your **organization slug** is in your Last9 URL: `https://app.last9.io/<org_slug>/...`
107
+
108
+ ### For local binary (STDIO mode)
109
+
110
+ You need a **Refresh Token** with Write permissions. Only **admins** can create them.
111
+
112
+ 1. Go to [API Access](https://app.last9.io/settings/api-access)
113
+ 2. Click **Generate Token** with Write permissions
114
+ 3. Copy the token
115
+
76
116
  ## Status
77
117
 
78
118
  Works with Claude desktop app, or Cursor, Windsurf, and VSCode (Github Copilot)
@@ -113,10 +153,19 @@ IDEs. Implements the following MCP
113
153
 
114
154
  ### Time Input Standard
115
155
 
116
- - For relative windows, prefer `lookback_minutes`.
156
+ - For relative windows, prefer `lookback_minutes` (up to 20160 minutes = 14 days).
117
157
  - For absolute windows, use `start_time_iso`, `end_time_iso`, or `time_iso` in RFC3339/ISO8601 (for example, `2026-02-09T15:04:05Z`).
118
158
  - If both relative and absolute inputs are provided, absolute time inputs take precedence.
119
159
  - Legacy `YYYY-MM-DD HH:MM:SS` is accepted only for compatibility.
160
+ - If a lookback limit error occurs, retry using explicit `start_time_iso`/`end_time_iso` timestamps.
161
+
162
+ ### Deep Links
163
+
164
+ Most tools return a `deep_link` field in the response metadata. This is a direct URL to the relevant Last9 dashboard view for the queried data — click it to open the corresponding alerts, logs, traces, or APM dashboard page.
165
+
166
+ ### Attribute Caching
167
+
168
+ The server automatically fetches and caches available log and trace attribute names at startup (with a 10-second timeout) and refreshes the cache every 2 hours in the background. These dynamic attributes are embedded into the `get_logs`, `get_traces`, and `prometheus_range_query` tool descriptions, so AI assistants always see up-to-date field names when constructing queries.
120
169
 
121
170
  ### get_exceptions
122
171
 
@@ -126,7 +175,7 @@ Parameters:
126
175
  - `limit` (integer, optional): Maximum number of exceptions to return.
127
176
  Default: 20.
128
177
  - `lookback_minutes` (integer, recommended): Number of minutes to look back from
129
- now. Default: 60. Examples: 60, 30, 15.
178
+ now. Default: 60. Range: 1–20160 (14 days). Examples: 60, 30, 15.
130
179
  - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to use lookback_minutes.
131
180
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z). Leave empty to default to current time.
132
181
  - `service_name` (string, optional): Filter exceptions by service name (e.g., api-service).
@@ -157,9 +206,11 @@ Get detailed performance metrics for a specific service over a given time range.
157
206
  Parameters:
158
207
 
159
208
  - `service_name` (string, required): Name of the service to get performance details for.
160
- - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to default to now - 60 minutes.
209
+ - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days).
210
+ - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to use lookback_minutes.
161
211
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z). Leave empty to default to current time.
162
212
  - `env` (string, optional): Environment to filter by. Defaults to 'prod'.
213
+ Returns: throughput, error rate, p50/p90/p95/avg/max response times, apdex score, availability, top operations, and top errors.
163
214
 
164
215
  ### get_service_operations_summary
165
216
 
@@ -167,9 +218,11 @@ Get a summary of operations inside a service over a given time range. Returns op
167
218
  Parameters:
168
219
 
169
220
  - `service_name` (string, required): Name of the service to get operations summary for.
170
- - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to default to now - 60 minutes.
221
+ - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days).
222
+ - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to use lookback_minutes.
171
223
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z). Leave empty to default to current time.
172
224
  - `env` (string, optional): Environment to filter by. Defaults to 'prod'.
225
+ Each operation includes: throughput (rpm), error rate (rpm), error percentage, and p50/p90/p95/avg/max response times (ms).
173
226
 
174
227
  ### get_service_dependency_graph
175
228
 
@@ -177,9 +230,11 @@ Get details of the throughput, response times and error rates of incoming, outgo
177
230
  Parameters:
178
231
 
179
232
  - `service_name` (string, optional): Name of the service to get the dependency graph for.
180
- - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to default to now - 60 minutes.
233
+ - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days).
234
+ - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to use lookback_minutes.
181
235
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z). Leave empty to default to current time.
182
236
  - `env` (string, optional): Environment to filter by. Defaults to 'prod'.
237
+ Each node includes: throughput (rpm), error rate (rpm), error percentage, and p50/p90/p95/avg/max response times (ms).
183
238
 
184
239
  ### prometheus_range_query
185
240
 
@@ -225,7 +280,7 @@ Parameters:
225
280
 
226
281
  - `service_name` (string, required): Name of the service to get logs for.
227
282
  - `severity` (string, optional): Severity of the logs to get (automatically converted to severity_filters format).
228
- - `lookback_minutes` (integer, recommended): Number of minutes to look back from now. Default: 60. Examples: 60, 30, 15.
283
+ - `lookback_minutes` (integer, recommended): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days). Examples: 60, 30, 15.
229
284
  - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to use lookback_minutes.
230
285
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z). Leave empty to default to current time.
231
286
  - `limit` (integer, optional): Maximum number of logs to return. Default: 20.
@@ -282,6 +337,7 @@ Parameters:
282
337
  - `time_iso` (string, optional): Evaluation time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Preferred.
283
338
  - `timestamp` (integer, optional): Unix timestamp for the query time. Deprecated alias.
284
339
  - `window` (integer, optional): Time window in seconds to look back for alerts. Defaults to 900 seconds (15 minutes). Range: 60-86400 seconds.
340
+ - `lookback_minutes` (integer, optional): Relative time window in minutes. Used only when `window` is not provided. Range: 1-1440.
285
341
  Returns information about:
286
342
  - Alert rule details (ID, name, group, type)
287
343
  - Current state and severity
@@ -297,7 +353,7 @@ Get raw log entries for a specific service over a time range. This tool retrieve
297
353
  Parameters:
298
354
 
299
355
  - `service_name` (string, required): Name of the service to get logs for.
300
- - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60 minutes. Examples: 60, 30, 15.
356
+ - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days). Examples: 60, 30, 15.
301
357
  - `limit` (integer, optional): Maximum number of log entries to return. Default: 20.
302
358
  - `env` (string, optional): Environment to filter by. Use "get_service_environments" tool to get available environments.
303
359
  - `severity_filters` (array, optional): Array of severity patterns to filter logs (e.g., ["error", "warn"]). Uses OR logic.
@@ -333,7 +389,7 @@ Parameters:
333
389
  - `tracejson_query` (array, required): JSON pipeline query for traces. Use the tracejson_query_builder prompt to generate JSON pipeline queries from natural language.
334
390
  - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z).
335
391
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z).
336
- - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60 minutes.
392
+ - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days).
337
393
  - `limit` (integer, optional): Maximum number of traces to return. Default: 20. Range: 1-100.
338
394
  This tool supports complex queries with multiple filter conditions, aggregations, and custom processing pipelines for advanced trace analysis.
339
395
 
@@ -344,7 +400,7 @@ Parameters:
344
400
 
345
401
  - `trace_id` (string, optional): Specific trace ID to retrieve. Cannot be used with service_name.
346
402
  - `service_name` (string, optional): Name of service to get traces for. Cannot be used with trace_id.
347
- - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60 minutes. Examples: 60, 30, 15.
403
+ - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days). Examples: 60, 30, 15.
348
404
  - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to use lookback_minutes.
349
405
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z). Leave empty to default to current time.
350
406
  - `limit` (integer, optional): Maximum number of traces to return. Default: 10. Range: 1-100.
@@ -376,7 +432,7 @@ Parameters:
376
432
 
377
433
  - `start_time_iso` (string, optional): Start time in RFC3339/ISO8601 format (e.g. 2026-02-09T15:04:05Z). Leave empty to default to now - lookback_minutes.
378
434
  - `end_time_iso` (string, optional): End time in RFC3339/ISO8601 format (e.g. 2026-02-09T16:04:05Z). Leave empty to default to current time.
379
- - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60 minutes. Examples: 60, 30, 15.
435
+ - `lookback_minutes` (integer, optional): Number of minutes to look back from now. Default: 60. Range: 1–20160 (14 days). Examples: 60, 30, 15.
380
436
  - `service` (string, optional): Name of the service to filter change events for.
381
437
  - `environment` (string, optional): Environment to filter by.
382
438
  - `event_name` (string, optional): Name of the change event to filter by (use available_event_names to see valid values).
@@ -408,16 +464,16 @@ Set this header in your MCP client config:
408
464
  If you run the server locally (`last9-mcp`), use these environment variables:
409
465
 
410
466
  - `LAST9_REFRESH_TOKEN`: (required) Refresh Token with Write permissions from
411
- [API Access](https://app.last9.io/settings/api-access). This token is used for
412
- all authentication and will automatically obtain access tokens as needed.
413
- - `OTEL_EXPORTER_OTLP_ENDPOINT`: (required) OpenTelemetry collector endpoint URL
414
- - `OTEL_EXPORTER_OTLP_HEADERS`: (required) Headers for OTLP exporter authentication
467
+ [API Access](https://app.last9.io/settings/api-access). Only admins can create
468
+ refresh tokens.
415
469
 
416
470
  Optional environment variables:
417
471
 
472
+ - `LAST9_DISABLE_TELEMETRY`: Defaults to `true` (telemetry is disabled by default). Set to `false` to enable OpenTelemetry tracing if you have an OTLP collector configured.
473
+ - `OTEL_EXPORTER_OTLP_ENDPOINT`: OpenTelemetry collector endpoint URL. Only needed if `LAST9_DISABLE_TELEMETRY=false`.
474
+ - `OTEL_EXPORTER_OTLP_HEADERS`: Headers for OTLP exporter authentication. Only needed if `LAST9_DISABLE_TELEMETRY=false`.
418
475
  - `LAST9_DATASOURCE`: Name of the datasource/cluster to use. If not specified, the default datasource configured in your Last9 organization will be used.
419
476
  - `LAST9_API_HOST`: API host to connect to. Defaults to `app.last9.io`. Use this if you need to connect to a different Last9 endpoint (e.g., regional or self-hosted instances).
420
- - `LAST9_DISABLE_TELEMETRY`: Set to `true` to disable OpenTelemetry tracing and metrics. Use this if you don't have an OTLP collector running or want to skip telemetry.
421
477
 
422
478
  ## Usage
423
479
 
@@ -433,6 +489,14 @@ Configure the Claude app to use the MCP server:
433
489
  4. Copy and paste the server config to your existing file, then save
434
490
  5. Restart Claude
435
491
 
492
+ ### Local STDIO
493
+
494
+ > **Note:** Claude Desktop currently supports local STDIO-based MCP servers only. Hosted HTTP transport is not yet supported in Claude Desktop.
495
+
496
+ Use a [Refresh Token](#getting-your-credentials).
497
+
498
+ Install via [Homebrew](#homebrew) or [NPM](#npm) first, then use a [Refresh Token](#getting-your-credentials).
499
+
436
500
  ### If installed via Homebrew:
437
501
 
438
502
  ```json
@@ -441,9 +505,7 @@ Configure the Claude app to use the MCP server:
441
505
  "last9": {
442
506
  "command": "/opt/homebrew/bin/last9-mcp",
443
507
  "env": {
444
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
445
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
446
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
508
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
447
509
  }
448
510
  }
449
511
  }
@@ -459,9 +521,7 @@ Configure the Claude app to use the MCP server:
459
521
  "command": "npx",
460
522
  "args": ["-y", "@last9/mcp-server@latest"],
461
523
  "env": {
462
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
463
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
464
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
524
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
465
525
  }
466
526
  }
467
527
  }
@@ -478,6 +538,24 @@ Configure Cursor to use the MCP server:
478
538
  4. Copy and paste the server config to your existing file, then save
479
539
  5. Restart Cursor
480
540
 
541
+ ### Hosted MCP over HTTP (recommended)
542
+
543
+ ```json
544
+ {
545
+ "mcpServers": {
546
+ "last9": {
547
+ "type": "http",
548
+ "url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp",
549
+ "headers": {
550
+ "X-LAST9-API-TOKEN": "Bearer <mcp_client_token>"
551
+ }
552
+ }
553
+ }
554
+ }
555
+ ```
556
+
557
+ ### Local STDIO (alternative)
558
+
481
559
  ### If installed via Homebrew:
482
560
 
483
561
  ```json
@@ -486,9 +564,7 @@ Configure Cursor to use the MCP server:
486
564
  "last9": {
487
565
  "command": "/opt/homebrew/bin/last9-mcp",
488
566
  "env": {
489
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
490
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
491
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
567
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
492
568
  }
493
569
  }
494
570
  }
@@ -504,9 +580,7 @@ Configure Cursor to use the MCP server:
504
580
  "command": "npx",
505
581
  "args": ["-y", "@last9/mcp-server@latest"],
506
582
  "env": {
507
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
508
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
509
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
583
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
510
584
  }
511
585
  }
512
586
  }
@@ -523,6 +597,24 @@ Configure Windsurf to use the MCP server:
523
597
  4. Copy and paste the server config to your existing file, then save
524
598
  5. Restart Windsurf
525
599
 
600
+ ### Hosted MCP over HTTP (recommended)
601
+
602
+ ```json
603
+ {
604
+ "mcpServers": {
605
+ "last9": {
606
+ "type": "http",
607
+ "url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp",
608
+ "headers": {
609
+ "X-LAST9-API-TOKEN": "Bearer <mcp_client_token>"
610
+ }
611
+ }
612
+ }
613
+ }
614
+ ```
615
+
616
+ ### Local STDIO (alternative)
617
+
526
618
  ### If installed via Homebrew:
527
619
 
528
620
  ```json
@@ -531,9 +623,7 @@ Configure Windsurf to use the MCP server:
531
623
  "last9": {
532
624
  "command": "/opt/homebrew/bin/last9-mcp",
533
625
  "env": {
534
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
535
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
536
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
626
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
537
627
  }
538
628
  }
539
629
  }
@@ -549,9 +639,7 @@ Configure Windsurf to use the MCP server:
549
639
  "command": "npx",
550
640
  "args": ["-y", "@last9/mcp-server@latest"],
551
641
  "env": {
552
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
553
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
554
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
642
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
555
643
  }
556
644
  }
557
645
  }
@@ -569,6 +657,26 @@ Configure Windsurf to use the MCP server:
569
657
  3. Copy and paste the server config to your existing file, then save
570
658
  4. Restart VS Code
571
659
 
660
+ ### Hosted MCP over HTTP (recommended)
661
+
662
+ ```json
663
+ {
664
+ "mcp": {
665
+ "servers": {
666
+ "last9": {
667
+ "type": "http",
668
+ "url": "https://app.last9.io/api/v4/organizations/<org_slug>/mcp",
669
+ "headers": {
670
+ "X-LAST9-API-TOKEN": "Bearer <mcp_client_token>"
671
+ }
672
+ }
673
+ }
674
+ }
675
+ }
676
+ ```
677
+
678
+ ### Local STDIO (alternative)
679
+
572
680
  ### If installed via Homebrew:
573
681
 
574
682
  ```json
@@ -579,9 +687,7 @@ Configure Windsurf to use the MCP server:
579
687
  "type": "stdio",
580
688
  "command": "/opt/homebrew/bin/last9-mcp",
581
689
  "env": {
582
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
583
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
584
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
690
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
585
691
  }
586
692
  }
587
693
  }
@@ -600,9 +706,7 @@ Configure Windsurf to use the MCP server:
600
706
  "command": "npx",
601
707
  "args": ["-y", "@last9/mcp-server@latest"],
602
708
  "env": {
603
- "LAST9_REFRESH_TOKEN": "<last9_refresh_token>",
604
- "OTEL_EXPORTER_OTLP_ENDPOINT": "<otel_endpoint_url>",
605
- "OTEL_EXPORTER_OTLP_HEADERS": "<otel_headers>"
709
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
606
710
  }
607
711
  }
608
712
  }
@@ -610,6 +714,25 @@ Configure Windsurf to use the MCP server:
610
714
  }
611
715
  ```
612
716
 
717
+ ## Windows Example (Claude Desktop)
718
+
719
+ After downloading `last9-mcp-server_Windows_x86_64.zip` from [GitHub Releases](https://github.com/last9/last9-mcp-server/releases/latest), extract to get `last9-mcp-server.exe` and use its full path:
720
+
721
+ ```json
722
+ {
723
+ "mcpServers": {
724
+ "last9": {
725
+ "command": "C:\\Users\\<user>\\AppData\\Local\\Programs\\last9-mcp-server.exe",
726
+ "env": {
727
+ "LAST9_REFRESH_TOKEN": "<last9_refresh_token>"
728
+ }
729
+ }
730
+ }
731
+ }
732
+ ```
733
+
734
+ The same pattern applies for Cursor and Windsurf on Windows. For VS Code, use the `"mcp": { "servers": { ... } }` wrapper. On Windows, prefer [NPM](#npm) to avoid path management, or use the [hosted HTTP transport](#recommended-managed-mcp-over-http) to skip local installation entirely.
735
+
613
736
  ## Development
614
737
 
615
738
  For local development and testing, you can run the MCP server in HTTP mode which makes it easier to debug requests and responses.
@@ -621,8 +744,6 @@ Set the `LAST9_HTTP` environment variable to enable HTTP server mode:
621
744
  ```bash
622
745
  # Export required environment variables
623
746
  export LAST9_REFRESH_TOKEN="your_refresh_token"
624
- export OTEL_EXPORTER_OTLP_ENDPOINT="<otel_endpoint_url>"
625
- export OTEL_EXPORTER_OTLP_HEADERS="<otel_headers>"
626
747
  export LAST9_HTTP=true
627
748
  export LAST9_PORT=8080 # Optional, defaults to 8080
628
749
  # Run the server
@@ -633,51 +754,54 @@ The server will start on `http://localhost:8080/mcp` and you can test it with cu
633
754
 
634
755
  ### Testing with curl
635
756
 
757
+ The MCP Streamable HTTP protocol requires an initialize handshake first. The server creates and returns a session ID in the response — do **not** set `Mcp-Session-Id` on the first request.
758
+
636
759
  ```bash
637
- # Test get_service_logs
638
- curl -X POST http://localhost:8080/mcp \
760
+ # Step 1: Initialize — omit Mcp-Session-Id so the server creates the session.
761
+ # Extract the returned Mcp-Session-Id from the response headers.
762
+ SESSION_ID=$(curl -si -X POST http://localhost:8080/mcp \
639
763
  -H "Content-Type: application/json" \
640
- -H "Mcp-Session-Id: session_$(date +%s)000000000" \
641
764
  -d '{
642
765
  "jsonrpc": "2.0",
643
766
  "id": 1,
644
- "method": "tools/call",
767
+ "method": "initialize",
645
768
  "params": {
646
- "name": "get_service_logs",
647
- "arguments": {
648
- "service_name": "your-service-name",
649
- "lookback_minutes": 30,
650
- "limit": 10
651
- }
769
+ "protocolVersion": "2024-11-05",
770
+ "capabilities": {},
771
+ "clientInfo": {"name": "curl-test", "version": "1.0"}
652
772
  }
653
- }'
654
- # Test get_service_traces
655
- curl -X POST http://localhost:8080/mcp \
773
+ }' | grep -i "^Mcp-Session-Id:" | awk '{print $2}' | tr -d '\r')
774
+ echo "Session: $SESSION_ID"
775
+
776
+ # Step 2: Send the initialized notification
777
+ curl -s -X POST http://localhost:8080/mcp \
656
778
  -H "Content-Type: application/json" \
657
- -H "Mcp-Session-Id: session_$(date +%s)000000000" \
779
+ -H "Mcp-Session-Id: $SESSION_ID" \
780
+ -d '{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}'
781
+
782
+ # Step 3: List available tools
783
+ curl -s -X POST http://localhost:8080/mcp \
784
+ -H "Content-Type: application/json" \
785
+ -H "Mcp-Session-Id: $SESSION_ID" \
786
+ -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}'
787
+
788
+ # Step 4: Call a tool
789
+ curl -s -X POST http://localhost:8080/mcp \
790
+ -H "Content-Type: application/json" \
791
+ -H "Mcp-Session-Id: $SESSION_ID" \
658
792
  -d '{
659
793
  "jsonrpc": "2.0",
660
- "id": 2,
794
+ "id": 3,
661
795
  "method": "tools/call",
662
796
  "params": {
663
- "name": "get_service_traces",
797
+ "name": "get_service_logs",
664
798
  "arguments": {
665
799
  "service_name": "your-service-name",
666
- "lookback_minutes": 60,
667
- "limit": 5
800
+ "lookback_minutes": 30,
801
+ "limit": 10
668
802
  }
669
803
  }
670
804
  }'
671
- # List available tools
672
- curl -X POST http://localhost:8080/mcp \
673
- -H "Content-Type: application/json" \
674
- -H "Mcp-Session-Id: session_$(date +%s)000000000" \
675
- -d '{
676
- "jsonrpc": "2.0",
677
- "id": 3,
678
- "method": "tools/list",
679
- "params": {}
680
- }'
681
805
  ```
682
806
 
683
807
  ### Building from Source
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@last9/mcp-server",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Last9 MCP Server - Model Context Protocol server implementation for Last9",
5
5
  "bin": {
6
6
  "last9-mcp": "./bin/cli.js"