qyl-mcp-server 11.1.4 → 17.0.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.
- package/README.md +154 -159
- package/dist/analysis-client.d.ts +2 -2
- package/dist/analysis-client.js +1 -2
- package/dist/analysis-client.js.map +1 -1
- package/dist/analysis-summary.js +4 -2
- package/dist/analysis-summary.js.map +1 -1
- package/dist/analysis-tools.js +44 -72
- package/dist/analysis-tools.js.map +1 -1
- package/dist/ci.js +3 -3
- package/dist/ci.js.map +1 -1
- package/dist/collector-resources.d.ts +1 -1
- package/dist/collector-resources.js +5 -12
- package/dist/collector-resources.js.map +1 -1
- package/dist/collector.d.ts +6 -5
- package/dist/collector.js +16 -17
- package/dist/collector.js.map +1 -1
- package/dist/config.d.ts +4 -8
- package/dist/config.js +7 -11
- package/dist/config.js.map +1 -1
- package/dist/contract-handshake.d.ts +45 -58
- package/dist/contract-handshake.js +80 -106
- package/dist/contract-handshake.js.map +1 -1
- package/dist/contracts/generated/api.d.ts +2078 -0
- package/dist/contracts/generated/api.js +244 -0
- package/dist/contracts/generated/api.js.map +1 -0
- package/dist/contracts/generated/definitions.d.ts +310 -0
- package/dist/contracts/generated/definitions.js +2 -0
- package/dist/contracts/generated/definitions.js.map +1 -0
- package/dist/contracts/generated/headers.d.ts +12 -0
- package/dist/contracts/generated/headers.js +15 -0
- package/dist/contracts/generated/headers.js.map +1 -0
- package/dist/contracts/generated/tool-schemas.json +25515 -0
- package/dist/contracts/tool-schemas.d.ts +32 -0
- package/dist/contracts/tool-schemas.js +43 -0
- package/dist/contracts/tool-schemas.js.map +1 -0
- package/dist/contracts/unix-nanos.d.ts +4 -0
- package/dist/contracts/unix-nanos.js +14 -0
- package/dist/contracts/unix-nanos.js.map +1 -0
- package/dist/data.d.ts +1 -1
- package/dist/data.js +1 -2
- package/dist/data.js.map +1 -1
- package/dist/events.d.ts +1 -1
- package/dist/events.js +1 -1
- package/dist/events.js.map +1 -1
- package/dist/main.d.ts +0 -1
- package/dist/main.js +16 -30
- package/dist/main.js.map +1 -1
- package/dist/mcp-semconv.d.ts +9 -20
- package/dist/mcp-semconv.js +21 -62
- package/dist/mcp-semconv.js.map +1 -1
- package/dist/metrics-tools.js +7 -7
- package/dist/metrics-tools.js.map +1 -1
- package/dist/native-execution.d.ts +9 -10
- package/dist/native-execution.js +48 -63
- package/dist/native-execution.js.map +1 -1
- package/dist/oauth.d.ts +1 -1
- package/dist/oauth.js +2 -2
- package/dist/oauth.js.map +1 -1
- package/dist/request-scope.d.ts +5 -1
- package/dist/request-scope.js +8 -0
- package/dist/request-scope.js.map +1 -1
- package/dist/server.d.ts +1 -17
- package/dist/server.js +8 -142
- package/dist/server.js.map +1 -1
- package/dist/skills/qyl-investigate/SKILL.md +6 -9
- package/dist/skills.js +4 -5
- package/dist/skills.js.map +1 -1
- package/dist/stderr-log.d.ts +7 -2
- package/dist/stderr-log.js +7 -4
- package/dist/stderr-log.js.map +1 -1
- package/dist/summaries.js +1 -1
- package/dist/summaries.js.map +1 -1
- package/dist/telemetry.d.ts +2 -10
- package/dist/telemetry.js +20 -105
- package/dist/telemetry.js.map +1 -1
- package/dist/tool-scopes.d.ts +1 -1
- package/dist/tool-scopes.js +1 -1
- package/dist/tools.js +9 -9
- package/dist/tools.js.map +1 -1
- package/dist/wire.d.ts +3 -7
- package/dist/wire.js +3 -3
- package/dist/wire.js.map +1 -1
- package/dist/write-tools.d.ts +3 -3
- package/dist/write-tools.js +20 -28
- package/dist/write-tools.js.map +1 -1
- package/package.json +20 -57
- package/dist/contract-headers.d.ts +0 -28
- package/dist/contract-headers.js +0 -38
- package/dist/contract-headers.js.map +0 -1
- package/dist/contract-validation.d.ts +0 -190
- package/dist/contract-validation.js +0 -332
- package/dist/contract-validation.js.map +0 -1
- package/dist/execution-evidence.d.ts +0 -13
- package/dist/execution-evidence.js +0 -81
- package/dist/execution-evidence.js.map +0 -1
- package/dist/execution-result.d.ts +0 -5
- package/dist/execution-result.js +0 -17
- package/dist/execution-result.js.map +0 -1
- package/dist/mcp-app.html +0 -161
- package/dist/mcp-dashboard.html +0 -166
- package/dist/mcp-home.html +0 -195
- package/dist/observability-suppression.d.ts +0 -8
- package/dist/observability-suppression.js +0 -15
- package/dist/observability-suppression.js.map +0 -1
- package/dist/trace-query.d.ts +0 -5
- package/dist/trace-query.js +0 -8
- package/dist/trace-query.js.map +0 -1
- package/dist/ui-domain.d.ts +0 -4
- package/dist/ui-domain.js +0 -32
- package/dist/ui-domain.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,70 +1,38 @@
|
|
|
1
1
|
# qyl-mcp-server
|
|
2
2
|
|
|
3
|
-
MCP tools over a live [qyl](https://github.com/ANcpLua/qyl)
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
MCP tools over a live [qyl](https://github.com/ANcpLua/qyl) Collector — traces, logs, metrics,
|
|
4
|
+
sessions and CI runs — for agents investigating a running system. The Collector computes every
|
|
5
|
+
analysis; this server validates, scopes and frames the calls.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
bunx qyl-mcp-server --stdio # stdio MCP server
|
|
9
|
-
bunx qyl-mcp-server
|
|
9
|
+
bunx qyl-mcp-server # Streamable HTTP on 127.0.0.1:3001
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
`npx` and `pnpm dlx` also work when Bun 1.4 or newer is installed; the executable runs on Bun, the
|
|
13
|
+
library exports `qyl-mcp-server` and `qyl-mcp-server/auth` support Node 24. Point it at a Collector:
|
|
13
14
|
|
|
14
15
|
```bash
|
|
15
16
|
export QYL_COLLECTOR_URL=http://127.0.0.1:5100
|
|
16
|
-
export QYL_API_KEY='your-collector-key' # omit for an unsecured local
|
|
17
|
+
export QYL_API_KEY='your-collector-key' # omit for an unsecured local Collector
|
|
17
18
|
```
|
|
18
19
|
|
|
19
|
-
`QYL_API_KEY` is an *outgoing*
|
|
20
|
-
|
|
20
|
+
`QYL_API_KEY` is an *outgoing* Collector credential; it does not authenticate incoming MCP
|
|
21
|
+
clients, which is why the local server binds to loopback only.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
its own.
|
|
23
|
+
The hosted instance is `https://mcp.qyl.at/mcp`. It is an OAuth 2.1 resource server: an
|
|
24
|
+
unauthenticated request answers `401` with an RFC 9728 protected-resource document naming issuer
|
|
25
|
+
`https://qyl-eu.eu.auth0.com/` and scopes `qyl:read qyl:write qyl:delete`, which a stock MCP
|
|
26
|
+
client follows on its own.
|
|
26
27
|
|
|
27
|
-
Both use MCP TypeScript SDK v2: Streamable HTTP through `createMcpHandler`
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
endpoint.
|
|
32
|
-
|
|
33
|
-
## Hosted authentication
|
|
34
|
-
|
|
35
|
-
The hosted Auth0 profile requires CIMD and DCR discovery, Authorization Code
|
|
36
|
-
with PKCE S256, both `private_key_jwt` and `none` for ChatGPT CIMD compatibility,
|
|
37
|
-
`none` for Claude CIMD, and issuer identification. Auth0 owns registration and token
|
|
38
|
-
issuance; this server validates resource-bound RFC 9068 access tokens on every
|
|
39
|
-
MCP request. It rejects malformed/query credentials, invalid tokens and
|
|
40
|
-
insufficient scopes with distinct 400/401/403 responses. Every request needs
|
|
41
|
-
`qyl:read`. The initial 401 requests `qyl:read qyl:write qyl:delete` so new
|
|
42
|
-
connections can authorize the complete tool set. A write tool called without `qyl:write` or `qyl:delete` gets a
|
|
43
|
-
`403` with `error="insufficient_scope"` naming the scopes to request, in both
|
|
44
|
-
protocol eras, before the handler runs.
|
|
45
|
-
|
|
46
|
-
Optional resource-server integrations are selected explicitly:
|
|
47
|
-
|
|
48
|
-
```sh
|
|
49
|
-
MCP_AUTH_EXTENSIONS=enterprise-managed-authorization@1.0.0,oauth-client-credentials@1.0.0
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Enterprise-managed authorization is stable upstream; client credentials is a
|
|
53
|
-
draft extension. Both preserve the core token verifier and require matching
|
|
54
|
-
Auth0 capabilities and separately provisioned client grants. Integration versions
|
|
55
|
-
are independent of the MCP wire version. Embedders can use the exported
|
|
56
|
-
`qyl-mcp-server/auth` composition API for additional declarative modules and
|
|
57
|
-
explicit scope hierarchies.
|
|
58
|
-
|
|
59
|
-
See the [deployment and authentication guide](https://github.com/ANcpLua/qyl.mcp#authentication)
|
|
60
|
-
for Auth0 configuration, extension responsibilities, and verification. Auth0
|
|
61
|
-
requires Enterprise for `private_key_jwt`. Neither a provider capability flag nor
|
|
62
|
-
an enabled module proves a client has been provisioned.
|
|
28
|
+
Both use MCP TypeScript SDK v2: Streamable HTTP through `createMcpHandler` and stdio through
|
|
29
|
+
`serveStdio`. One factory serves revision `2026-07-28` and negotiates down for 2025-era clients
|
|
30
|
+
that send `initialize`. The HTTP server answers `/mcp`, `/healthz`, the OAuth discovery documents
|
|
31
|
+
and `/.well-known/openai-apps-challenge`; every other path, `/` included, is `404`.
|
|
63
32
|
|
|
64
33
|
## Tools
|
|
65
34
|
|
|
66
|
-
The
|
|
67
|
-
analysis queries and the generated qyl API contracts.
|
|
35
|
+
The committed [`tool-manifest.snapshot.json`](tool-manifest.snapshot.json) is the tool contract.
|
|
68
36
|
|
|
69
37
|
| Purpose | Tools |
|
|
70
38
|
| --- | --- |
|
|
@@ -73,90 +41,116 @@ analysis queries and the generated qyl API contracts.
|
|
|
73
41
|
| Read executions | `list_sessions`, `list_traces`, `get_trace`, `search_logs`, `ci_log` |
|
|
74
42
|
| Read metrics | `list_metrics`, `get_metric_series`, `query_metric` |
|
|
75
43
|
| Saved questions | `list_saved_queries`, `run_saved_query` |
|
|
76
|
-
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
|
|
105
|
-
|
|
44
|
+
| Write project records | `create_annotation`, `update_annotation`, `create_saved_query`, `update_saved_query`, `delete_record`, `update_failure_status` |
|
|
45
|
+
|
|
46
|
+
Read tools accept an absolute RFC 3339 time window or `lookback_minutes` and report the resolved
|
|
47
|
+
`window` and `coverage`: examined, matched and returned counts, truncation, scan completeness and
|
|
48
|
+
observation time. Unknown counts are null. Filtering happens before pagination; reuse an opaque
|
|
49
|
+
`next_cursor` with the same filters to continue a page. Shared matchers support `eq`, `neq`, `in`,
|
|
50
|
+
`prefix`, `contains`, `exists`, `gt`, `gte`, `lt` and `lte`, with span, resource or log scope. Span
|
|
51
|
+
durations are milliseconds; metrics keep their recorded units. Histogram percentiles identify their
|
|
52
|
+
approximation, cumulative counter changes account for resets, and verification reports
|
|
53
|
+
insufficient traffic as pending rather than calling an unobserved failure fixed.
|
|
54
|
+
|
|
55
|
+
`get_trace` returns all spans, errors, errors with ancestors, or the critical path, with selected
|
|
56
|
+
attributes and correlated logs. `ci_log` reads telemetry from any CI following its emitter
|
|
57
|
+
convention; `service_prefix` defaults to `qyl-ci`. `get_mcp_stats` reports MCP request totals, the
|
|
58
|
+
numerator and denominator behind rates, failure classes, the window's 60 time buckets, per-tool
|
|
59
|
+
requests, errors and latency, and simultaneous server, transport and method breakdowns. The `qyl-investigate` skill says which
|
|
60
|
+
tool to start with; the server serves it through the MCP skills extension (`skills/list`,
|
|
61
|
+
`skills/get`, `skill://qyl/qyl-investigate/SKILL.md`), and the build copies it from `skills/` into
|
|
62
|
+
`dist/skills`.
|
|
63
|
+
|
|
64
|
+
Every read tool carries `readOnlyHint: true`. The write tools change only records in the caller's
|
|
65
|
+
Collector project: annotations (plain-text notes of at most 2000 characters on a trace, span,
|
|
66
|
+
session or failure, with optional labels; a bookmark is a note labelled `bookmark`), saved queries
|
|
67
|
+
(named filters for traces, logs or metrics) and the status of recorded failures (`open`,
|
|
68
|
+
`resolved`, `ignored`, assignee, ignore-until). `delete_record` removes one annotation or saved
|
|
69
|
+
query (`kind` is `annotation` or `saved_query`). Updates and deletes send the current `etag` as
|
|
70
|
+
`If-Match`: a stale etag is refused with `precondition_failed`, a duplicate saved-query name with
|
|
71
|
+
`conflict`. Create calls reuse the stored result for 24 hours; without an explicit
|
|
72
|
+
`idempotency_key` the server derives one from the project, operation and request body. No tool
|
|
73
|
+
edits or deletes recorded telemetry; retention alone removes it.
|
|
106
74
|
|
|
107
75
|
`qyl:read` covers reads, `qyl:write` adds creation and updates, and `qyl:delete` permits
|
|
108
|
-
`
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
Every tool runs inside its request scope, forwarding cancellation to the
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
76
|
+
`delete_record`. A missing scope returns the OAuth step-up challenge `403`
|
|
77
|
+
`insufficient_scope` naming the scopes to request, in both protocol eras, before the handler runs.
|
|
78
|
+
Failed calls carry a stable code, retryability, the problem type and field-level validation
|
|
79
|
+
details when available. Secrets are redacted before model text, structured content or durable
|
|
80
|
+
evidence. Every tool runs inside its request scope, forwarding cancellation to the Collector;
|
|
81
|
+
requested progress reports completion. Analysis reads require a live Collector; synthetic data
|
|
82
|
+
exists only in test fixtures.
|
|
83
|
+
|
|
84
|
+
## Hosted authentication
|
|
85
|
+
|
|
86
|
+
The hosted Auth0 profile is **CIMD or DCR + OAuth 2.1 Authorization Code with PKCE S256 + issuer
|
|
87
|
+
identification**. ChatGPT's client metadata advertises `none` and `private_key_jwt` and uses the
|
|
88
|
+
latter; Claude's CIMD is a public client using `none`. Auth0 owns registration and token issuance;
|
|
89
|
+
the server validates resource-bound RFC 9068 access tokens (signature, issuer, resource audience,
|
|
90
|
+
expiry and scopes) on every MCP request and rejects malformed or query credentials, invalid tokens
|
|
91
|
+
and insufficient scopes with distinct `400`/`401`/`403` responses. Only the qyl production Auth0
|
|
92
|
+
issuer is accepted. `/.well-known/oauth-protected-resource/mcp` and
|
|
93
|
+
`/.well-known/oauth-protected-resource` describe the same `/mcp` resource.
|
|
94
|
+
|
|
95
|
+
Operating a hosted deployment:
|
|
96
|
+
|
|
97
|
+
1. Register the resource audience `<public-url>/mcp`, RS256 access tokens and the permissions
|
|
98
|
+
`qyl:read`, `qyl:write` and `qyl:delete`.
|
|
99
|
+
2. Provision each client through its current CIMD document or DCR, keeping its actual callback and
|
|
100
|
+
authentication method. When DCR is enabled, set `dynamic_client_registration_security_mode` to
|
|
101
|
+
`strict`; the DCR endpoint is open to registration, so keep third-party API default permissions
|
|
102
|
+
empty.
|
|
103
|
+
3. `qyl:read` exposes traces, logs, metrics, sessions and CI evidence; grant it only to intended
|
|
104
|
+
clients and users. `qyl:write` and `qyl:delete` reach only annotations, saved queries and failure
|
|
105
|
+
status in the caller's project, and the Collector key the server uses needs the Collector's
|
|
106
|
+
`write` and `delete` roles.
|
|
107
|
+
4. Configure `MCP_PUBLIC_URL`, `MCP_BIND_HOST`, allowed hosts and origins, and the Collector URL and
|
|
108
|
+
key. Non-loopback serving requires a public URL and hosted authorization.
|
|
109
|
+
|
|
110
|
+
`eng/auth0` in the repository records and reconciles the tenant's API scopes, named client grants
|
|
111
|
+
and mapped-user permissions.
|
|
112
|
+
|
|
113
|
+
Optional authorization extensions are selected explicitly:
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
MCP_AUTH_EXTENSIONS=enterprise-managed-authorization@1.0.0,oauth-client-credentials@1.0.0
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`enterprise-managed-authorization@1.0.0` is stable and needs the JWT bearer and ID-JAG grant
|
|
120
|
+
profile; `oauth-client-credentials@1.0.0` is a draft and needs client credentials with
|
|
121
|
+
`private_key_jwt` (Auth0 Enterprise). Unknown versions and conflicting provider requirements are
|
|
122
|
+
rejected; neither replaces the core verifier. Embedders compose further modules through
|
|
123
|
+
`qyl-mcp-server/auth`.
|
|
124
|
+
|
|
125
|
+
The alternative `MCP_AUTH_PROVIDER=cloudflare-access` mode (with `MCP_ACCESS_TEAM_DOMAIN`,
|
|
126
|
+
`MCP_ACCESS_AUD` and `MCP_PUBLIC_URL`) validates `Cf-Access-Jwt-Assertion`: issuer, application
|
|
127
|
+
audience, expiry and subject, with RS256 signatures. Its assertion carries no qyl scopes, so it
|
|
128
|
+
grants the read tools only, and Auth0-backed Events cannot be enabled in it.
|
|
125
129
|
|
|
126
130
|
## Configuration
|
|
127
131
|
|
|
128
132
|
| Variable | Meaning |
|
|
129
133
|
| --- | --- |
|
|
130
|
-
| `QYL_COLLECTOR_URL` | Collector
|
|
131
|
-
| `QYL_API_KEY` | Collector credential for reads and OTLP; the write tools need
|
|
132
|
-
| `QYL_PROJECT` | Server-owned
|
|
133
|
-
| `MCP_COLLECTOR_PROJECTS` | Optional secret JSON mapping
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `MCP_EVENTS_STORE` |
|
|
139
|
-
| `MCP_EVENTS_AUTH0_CLIENT_ID
|
|
140
|
-
| `MCP_EVENTS_POLL_MS` | Collector polling interval, at least 5000 ms; default 30000 ms. |
|
|
141
|
-
| `
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
`
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
The existing tenant's API scopes, named client grants and mapped-user permissions
|
|
152
|
-
are managed by [the Auth0 configuration and drift checker](https://github.com/ANcpLua/qyl.mcp/tree/main/tools/auth0).
|
|
153
|
-
Run its check before applying changes; it preserves unrelated tenant configuration
|
|
154
|
-
and never creates identities or rotates credentials.
|
|
155
|
-
|
|
156
|
-
To give a reviewer access to sample data, provision a separate Collector
|
|
157
|
-
project/key through the Collector's `QYL_OTLP_PROJECT_KEYS` configuration and
|
|
158
|
-
assign that key to the reviewer's validated Auth0 subject. Configure the MCP
|
|
159
|
-
service's secret `MCP_COLLECTOR_PROJECTS` with this shape (placeholder values):
|
|
134
|
+
| `QYL_COLLECTOR_URL` | Collector base URL; default `http://127.0.0.1:5100`. Also the OTLP base when set. |
|
|
135
|
+
| `QYL_API_KEY` | Collector credential for reads and OTLP; the write tools need its `write` and `delete` roles. Outgoing only. |
|
|
136
|
+
| `QYL_PROJECT` | Server-owned Collector project scope. Unset, the server sends no project header and the Collector's default project applies. Never accepted as tool input. |
|
|
137
|
+
| `MCP_COLLECTOR_PROJECTS` | Optional secret JSON mapping verified Auth0 subjects to project-bound Collector keys (below). |
|
|
138
|
+
| `MCP_PUBLIC_URL` | Public base URL of a hosted deployment; sets the resource audience and the canonical `/mcp` URL and disables the local execution record. |
|
|
139
|
+
| `MCP_BIND_HOST`, `PORT` | Listener address and port; default `127.0.0.1:3001`. |
|
|
140
|
+
| `MCP_ALLOWED_HOSTS`, `MCP_ALLOWED_ORIGIN_HOSTS` | Comma-separated request and browser-origin hostnames added to the public URL's hostname. |
|
|
141
|
+
| `MCP_AUTH_PROVIDER`, `MCP_AUTH_EXTENSIONS` | Authorization mode and optional extensions (above). |
|
|
142
|
+
| `MCP_EVENTS_STORE` | Persistent Events subscription file; unset disables Events. |
|
|
143
|
+
| `MCP_EVENTS_AUTH0_CLIENT_ID`, `MCP_EVENTS_AUTH0_CLIENT_SECRET` | Management API application with `read:users`, `read:clients`, `read:client_grants`, `read:grants`; resolves CIMD identities and keeps Events access checks current without storing subscriber tokens. |
|
|
144
|
+
| `MCP_EVENTS_POLL_MS` | Collector polling interval for Events, at least 5000 ms; default 30000 ms. |
|
|
145
|
+
| `OPENAI_APPS_CHALLENGE` | Text served at `/.well-known/openai-apps-challenge`; `404` while blank. |
|
|
146
|
+
| `QYL_OTLP_ENDPOINT` | Optional OTLP base for self-telemetry; signal-specific `OTEL_*` endpoints take precedence. |
|
|
147
|
+
| `QYL_MCP_TELEMETRY=0` | Disable MCP spans, metrics and operation logs. |
|
|
148
|
+
| `QYL_MCP_NATIVE_STATE_PATH` | Location of the local execution record; default `~/.qyl/mcp-native-executions.json`. |
|
|
149
|
+
|
|
150
|
+
With `MCP_COLLECTOR_PROJECTS` set, only the verified SDK `AuthInfo.extra.subject` selects the
|
|
151
|
+
project; tool inputs and request metadata cannot override it. An enabled map rejects unmapped
|
|
152
|
+
callers and never falls back to `QYL_API_KEY`; missing, malformed, duplicate or conflicting entries
|
|
153
|
+
fail validation. It needs the hosted Auth0 configuration. Shape (placeholder values):
|
|
160
154
|
|
|
161
155
|
```json
|
|
162
156
|
[
|
|
@@ -165,38 +159,39 @@ service's secret `MCP_COLLECTOR_PROJECTS` with this shape (placeholder values):
|
|
|
165
159
|
]
|
|
166
160
|
```
|
|
167
161
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
and
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
`bun
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
`QYL_BIN=/path/to/
|
|
198
|
-
|
|
162
|
+
Tool-call OTLP exports use the mapped project's credential; an unassigned caller gets no fallback
|
|
163
|
+
export destination. Project keys are redacted from text and structured results.
|
|
164
|
+
|
|
165
|
+
## MCP Events
|
|
166
|
+
|
|
167
|
+
On authenticated Auth0 deployments with `MCP_EVENTS_STORE`, clients can subscribe to `trace.error`,
|
|
168
|
+
optionally filtered by `service_name`. The server verifies callbacks, signs deliveries, checks
|
|
169
|
+
ongoing authorization, expires subscriptions and cancels delivery on unsubscribe or confirmed
|
|
170
|
+
revocation. Subscription state is bounded and holds no OAuth tokens or copied telemetry.
|
|
171
|
+
|
|
172
|
+
## Execution records and telemetry
|
|
173
|
+
|
|
174
|
+
A local server (`--stdio`, or HTTP without `MCP_PUBLIC_URL`) records each inbound `tools/call` —
|
|
175
|
+
tool name, timing, status, error type and a server-generated ID, never arguments, metadata, result
|
|
176
|
+
bodies or error messages — atomically in the execution record, keeping the latest 1,000. A hosted
|
|
177
|
+
deployment records nothing to disk. A completed or failed record that cannot be written never
|
|
178
|
+
changes the call's outcome: the tool's result or error is returned, a structured `warn` line goes
|
|
179
|
+
to stderr and the operation span carries `error.type=evidence_persistence_failed`; a record that
|
|
180
|
+
cannot be written before the tool runs refuses the call. OTLP exports carry operation timing,
|
|
181
|
+
status and trace correlation, without argument or result bodies.
|
|
182
|
+
|
|
183
|
+
## Checks
|
|
184
|
+
|
|
185
|
+
From `services/qyl.mcp` after `bun install --frozen-lockfile && bun run build`:
|
|
186
|
+
`bun run test:built` (unit tests), `bun run smoke` (stdio transport), `bun run smoke:quiet`
|
|
187
|
+
(an 18-second quiet response over HTTP), `bun run test:answer-key` (seeded OTLP through a fresh
|
|
188
|
+
Collector, then every analysis check through MCP) and `bun run smoke:projects` (two real
|
|
189
|
+
Collector projects, every tool, both protocol eras). The last two use the Collector's Release
|
|
190
|
+
build in `artifacts/bin/qyl.collector/release/`; `QYL_COLLECTOR_DLL` selects another build.
|
|
191
|
+
`QYL_BIN=/path/to/qyl bun run smoke:live` calls every tool against a Collector started by an
|
|
192
|
+
installed qyl tool. `mise run hosted-eval` checks the hosted server with a real login
|
|
193
|
+
([eval/](eval/)).
|
|
199
194
|
|
|
200
195
|
## Release notes
|
|
201
196
|
|
|
202
|
-
|
|
197
|
+
[CHANGELOG.md](https://github.com/ANcpLua/qyl/blob/main/CHANGELOG.md)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Shared HTTP transport; every callable analysis operation is registered by name. */
|
|
2
2
|
import type { CallToolResult } from "@modelcontextprotocol/server";
|
|
3
|
-
import type
|
|
3
|
+
import type { ContractSchemaName } from "./contracts/tool-schemas.js";
|
|
4
4
|
import type { ToolScope } from "./request-scope.js";
|
|
5
|
-
export declare function queryAnalysis<Input extends object
|
|
5
|
+
export declare function queryAnalysis<Input extends object>(operation: string, input: Input, schema: ContractSchemaName, scope: ToolScope): Promise<CallToolResult>;
|
package/dist/analysis-client.js
CHANGED
|
@@ -26,8 +26,7 @@ export async function queryAnalysis(operation, input, schema, scope) {
|
|
|
26
26
|
const page = output;
|
|
27
27
|
const originalPoints = operation === "get_metric_series" && typeof args.series_id === "string";
|
|
28
28
|
const points = page.points;
|
|
29
|
-
const
|
|
30
|
-
const sizeKey = originalPoints ? "points_limit" : traceView ? "max_spans" : operation === "query_metric" ? "series_limit" : operation === "get_agent_run" ? "max_steps" : "limit";
|
|
29
|
+
const sizeKey = originalPoints ? "points_limit" : operation === "get_trace" ? "max_spans" : operation === "query_metric" ? "series_limit" : operation === "get_agent_run" ? "max_steps" : "limit";
|
|
31
30
|
const trace = page.trace;
|
|
32
31
|
const observed = page.observed;
|
|
33
32
|
const sizes = [trace?.spans?.length, observed?.error_spans?.length, observed?.logs?.length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis-client.js","sourceRoot":"","sources":["../src/analysis-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"analysis-client.js","sourceRoot":"","sources":["../src/analysis-client.ts"],"names":[],"mappings":"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"}
|
package/dist/analysis-summary.js
CHANGED
|
@@ -19,7 +19,7 @@ export function analysisSummary(operation, output) {
|
|
|
19
19
|
if (data[key] !== undefined)
|
|
20
20
|
lines.push(`${key}: ${short(data[key])}`);
|
|
21
21
|
}
|
|
22
|
-
const totals = record(data.totals
|
|
22
|
+
const totals = record(data.totals);
|
|
23
23
|
if (totals.requests !== undefined)
|
|
24
24
|
lines.push(`${short(totals.errors)} errors / ${short(totals.requests)} requests; p95 ${short(totals.p95_ms)} ms.`);
|
|
25
25
|
const trace = record(data.trace);
|
|
@@ -28,7 +28,9 @@ export function analysisSummary(operation, output) {
|
|
|
28
28
|
const cause = record(record(data.observed).root_cause_span);
|
|
29
29
|
if (cause.name)
|
|
30
30
|
lines.push(`Recorded failure: ${short(cause.service)} / ${short(cause.name)} — ${short(record(cause.exception).message ?? cause.status)}`);
|
|
31
|
-
|
|
31
|
+
if (typeof data.span_count_analyzed === "number")
|
|
32
|
+
lines.push(`${data.span_count_analyzed} MCP spans analyzed${data.truncated === true ? " from an incomplete scan" : ""}.`);
|
|
33
|
+
const collections = ["failures", "regressions", "groups", "tools", "steps", "traces", "sessions", "logs", "items", "attributes", "releases", "nodes", "runs", "phases", "saved_queries"];
|
|
32
34
|
let evidence = 0;
|
|
33
35
|
for (const field of collections) {
|
|
34
36
|
const rows = data[field];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis-summary.js","sourceRoot":"","sources":["../src/analysis-summary.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,MAAc;IAC/D,MAAM,IAAI,GAAG,MAAiC,CAAC;IAC/C,MAAM,MAAM,GAAG,CAAC,KAAc,EAA2B,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzK,MAAM,KAAK,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnL,MAAM,KAAK,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,yCAAyC,EAAE,CAAC,CAAC;IAC5N,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;QACjF,KAAK,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,KAAK,CAAC,MAAM,gBAAgB,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,kCAAkC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACpI,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACvE,KAAK,CAAC,IAAI,CAAC,wGAAwG,CAAC,CAAC;QACvH,CAAC;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;QACpF,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"analysis-summary.js","sourceRoot":"","sources":["../src/analysis-summary.ts"],"names":[],"mappings":"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"}
|