@qase/mcp-server 1.1.8 → 2.0.1
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/CHANGELOG.md +38 -0
- package/README.md +75 -542
- package/build/auth/client-context.d.ts +12 -0
- package/build/auth/client-context.d.ts.map +1 -0
- package/build/auth/client-context.js +12 -0
- package/build/auth/client-context.js.map +1 -0
- package/build/auth/jwks-verifier.d.ts +15 -0
- package/build/auth/jwks-verifier.d.ts.map +1 -0
- package/build/auth/jwks-verifier.js +31 -0
- package/build/auth/jwks-verifier.js.map +1 -0
- package/build/auth/mcp-guard.d.ts +15 -0
- package/build/auth/mcp-guard.d.ts.map +1 -0
- package/build/auth/mcp-guard.js +44 -0
- package/build/auth/mcp-guard.js.map +1 -0
- package/build/auth/oauth-config.d.ts +40 -0
- package/build/auth/oauth-config.d.ts.map +1 -0
- package/build/auth/oauth-config.js +34 -0
- package/build/auth/oauth-config.js.map +1 -0
- package/build/auth/proxy-provider.d.ts +31 -0
- package/build/auth/proxy-provider.d.ts.map +1 -0
- package/build/auth/proxy-provider.js +87 -0
- package/build/auth/proxy-provider.js.map +1 -0
- package/build/auth/token-type.d.ts +7 -0
- package/build/auth/token-type.d.ts.map +1 -0
- package/build/auth/token-type.js +10 -0
- package/build/auth/token-type.js.map +1 -0
- package/build/cache/circuit-breaker.d.ts +33 -0
- package/build/cache/circuit-breaker.d.ts.map +1 -0
- package/build/cache/circuit-breaker.js +68 -0
- package/build/cache/circuit-breaker.js.map +1 -0
- package/build/cache/index.d.ts +24 -0
- package/build/cache/index.d.ts.map +1 -0
- package/build/cache/index.js +86 -0
- package/build/cache/index.js.map +1 -0
- package/build/cache/keys.d.ts +25 -0
- package/build/cache/keys.d.ts.map +1 -0
- package/build/cache/keys.js +36 -0
- package/build/cache/keys.js.map +1 -0
- package/build/cache/layered.d.ts +31 -0
- package/build/cache/layered.d.ts.map +1 -0
- package/build/cache/layered.js +88 -0
- package/build/cache/layered.js.map +1 -0
- package/build/cache/memory.d.ts +32 -0
- package/build/cache/memory.d.ts.map +1 -0
- package/build/cache/memory.js +108 -0
- package/build/cache/memory.js.map +1 -0
- package/build/cache/metrics.d.ts +31 -0
- package/build/cache/metrics.d.ts.map +1 -0
- package/build/cache/metrics.js +95 -0
- package/build/cache/metrics.js.map +1 -0
- package/build/cache/prom-format.d.ts +7 -0
- package/build/cache/prom-format.d.ts.map +1 -0
- package/build/cache/prom-format.js +16 -0
- package/build/cache/prom-format.js.map +1 -0
- package/build/cache/redis-bus.d.ts +29 -0
- package/build/cache/redis-bus.d.ts.map +1 -0
- package/build/cache/redis-bus.js +50 -0
- package/build/cache/redis-bus.js.map +1 -0
- package/build/cache/redis.d.ts +32 -0
- package/build/cache/redis.d.ts.map +1 -0
- package/build/cache/redis.js +89 -0
- package/build/cache/redis.js.map +1 -0
- package/build/cache/types.d.ts +38 -0
- package/build/cache/types.d.ts.map +1 -0
- package/build/cache/types.js +2 -0
- package/build/cache/types.js.map +1 -0
- package/build/client/index.d.ts +10 -3
- package/build/client/index.d.ts.map +1 -1
- package/build/client/index.js +75 -50
- package/build/client/index.js.map +1 -1
- package/build/http/agent.d.ts +16 -0
- package/build/http/agent.d.ts.map +1 -0
- package/build/http/agent.js +16 -0
- package/build/http/agent.js.map +1 -0
- package/build/http/dedupe.d.ts +14 -0
- package/build/http/dedupe.d.ts.map +1 -0
- package/build/http/dedupe.js +69 -0
- package/build/http/dedupe.js.map +1 -0
- package/build/http/index.d.ts +6 -0
- package/build/http/index.d.ts.map +1 -0
- package/build/http/index.js +4 -0
- package/build/http/index.js.map +1 -0
- package/build/http/retry.d.ts +18 -0
- package/build/http/retry.d.ts.map +1 -0
- package/build/http/retry.js +52 -0
- package/build/http/retry.js.map +1 -0
- package/build/index.d.ts +1 -18
- package/build/index.d.ts.map +1 -1
- package/build/index.js +95 -63
- package/build/index.js.map +1 -1
- package/build/operations-v2/composites/ci-report.d.ts +2 -0
- package/build/operations-v2/composites/ci-report.d.ts.map +1 -0
- package/build/operations-v2/composites/ci-report.js +99 -0
- package/build/operations-v2/composites/ci-report.js.map +1 -0
- package/build/operations-v2/composites/regression-run.d.ts +2 -0
- package/build/operations-v2/composites/regression-run.d.ts.map +1 -0
- package/build/operations-v2/composites/regression-run.js +81 -0
- package/build/operations-v2/composites/regression-run.js.map +1 -0
- package/build/operations-v2/composites/triage-defect.d.ts +2 -0
- package/build/operations-v2/composites/triage-defect.d.ts.map +1 -0
- package/build/operations-v2/composites/triage-defect.js +67 -0
- package/build/operations-v2/composites/triage-defect.js.map +1 -0
- package/build/operations-v2/escape/api.d.ts +2 -0
- package/build/operations-v2/escape/api.d.ts.map +1 -0
- package/build/operations-v2/escape/api.js +34 -0
- package/build/operations-v2/escape/api.js.map +1 -0
- package/build/operations-v2/index.d.ts +21 -0
- package/build/operations-v2/index.d.ts.map +1 -0
- package/build/operations-v2/index.js +27 -0
- package/build/operations-v2/index.js.map +1 -0
- package/build/operations-v2/meta/discover.d.ts +9 -0
- package/build/operations-v2/meta/discover.d.ts.map +1 -0
- package/build/operations-v2/meta/discover.js +79 -0
- package/build/operations-v2/meta/discover.js.map +1 -0
- package/build/{operations/search.d.ts → operations-v2/qql/index.d.ts} +1 -1
- package/build/operations-v2/qql/index.d.ts.map +1 -0
- package/build/{operations/search.js → operations-v2/qql/index.js} +34 -9
- package/build/operations-v2/qql/index.js.map +1 -0
- package/build/operations-v2/read/get.d.ts +2 -0
- package/build/operations-v2/read/get.d.ts.map +1 -0
- package/build/operations-v2/read/get.js +115 -0
- package/build/operations-v2/read/get.js.map +1 -0
- package/build/operations-v2/read/project-context.d.ts +2 -0
- package/build/operations-v2/read/project-context.d.ts.map +1 -0
- package/build/operations-v2/read/project-context.js +102 -0
- package/build/operations-v2/read/project-context.js.map +1 -0
- package/build/operations-v2/write/attachments.d.ts +2 -0
- package/build/operations-v2/write/attachments.d.ts.map +1 -0
- package/build/operations-v2/write/attachments.js +58 -0
- package/build/operations-v2/write/attachments.js.map +1 -0
- package/build/operations-v2/write/case-fields.d.ts +206 -0
- package/build/operations-v2/write/case-fields.d.ts.map +1 -0
- package/build/operations-v2/write/case-fields.js +79 -0
- package/build/operations-v2/write/case-fields.js.map +1 -0
- package/build/operations-v2/write/cases-bulk.d.ts +2 -0
- package/build/operations-v2/write/cases-bulk.d.ts.map +1 -0
- package/build/operations-v2/write/cases-bulk.js +54 -0
- package/build/operations-v2/write/cases-bulk.js.map +1 -0
- package/build/operations-v2/write/cases.d.ts +2 -0
- package/build/operations-v2/write/cases.d.ts.map +1 -0
- package/build/operations-v2/write/cases.js +52 -0
- package/build/operations-v2/write/cases.js.map +1 -0
- package/build/operations-v2/write/defects.d.ts +2 -0
- package/build/operations-v2/write/defects.d.ts.map +1 -0
- package/build/operations-v2/write/defects.js +81 -0
- package/build/operations-v2/write/defects.js.map +1 -0
- package/build/operations-v2/write/environments.d.ts +2 -0
- package/build/operations-v2/write/environments.d.ts.map +1 -0
- package/build/operations-v2/write/environments.js +56 -0
- package/build/operations-v2/write/environments.js.map +1 -0
- package/build/operations-v2/write/external-issues.d.ts +2 -0
- package/build/operations-v2/write/external-issues.d.ts.map +1 -0
- package/build/operations-v2/write/external-issues.js +96 -0
- package/build/operations-v2/write/external-issues.js.map +1 -0
- package/build/operations-v2/write/milestones.d.ts +2 -0
- package/build/operations-v2/write/milestones.d.ts.map +1 -0
- package/build/operations-v2/write/milestones.js +56 -0
- package/build/operations-v2/write/milestones.js.map +1 -0
- package/build/operations-v2/write/plans.d.ts +2 -0
- package/build/operations-v2/write/plans.d.ts.map +1 -0
- package/build/operations-v2/write/plans.js +55 -0
- package/build/operations-v2/write/plans.js.map +1 -0
- package/build/operations-v2/write/results.d.ts +2 -0
- package/build/operations-v2/write/results.d.ts.map +1 -0
- package/build/operations-v2/write/results.js +72 -0
- package/build/operations-v2/write/results.js.map +1 -0
- package/build/operations-v2/write/runs.d.ts +2 -0
- package/build/operations-v2/write/runs.d.ts.map +1 -0
- package/build/operations-v2/write/runs.js +84 -0
- package/build/operations-v2/write/runs.js.map +1 -0
- package/build/operations-v2/write/shared-steps.d.ts +2 -0
- package/build/operations-v2/write/shared-steps.d.ts.map +1 -0
- package/build/operations-v2/write/shared-steps.js +60 -0
- package/build/operations-v2/write/shared-steps.js.map +1 -0
- package/build/operations-v2/write/suites.d.ts +2 -0
- package/build/operations-v2/write/suites.d.ts.map +1 -0
- package/build/operations-v2/write/suites.js +63 -0
- package/build/operations-v2/write/suites.js.map +1 -0
- package/build/prompts/index.d.ts +31 -0
- package/build/prompts/index.d.ts.map +1 -0
- package/build/prompts/index.js +229 -0
- package/build/prompts/index.js.map +1 -0
- package/build/transports/sse.d.ts.map +1 -1
- package/build/transports/sse.js +6 -0
- package/build/transports/sse.js.map +1 -1
- package/build/transports/streamableHttp.d.ts +6 -1
- package/build/transports/streamableHttp.d.ts.map +1 -1
- package/build/transports/streamableHttp.js +128 -16
- package/build/transports/streamableHttp.js.map +1 -1
- package/build/utils/auth-context.d.ts +8 -0
- package/build/utils/auth-context.d.ts.map +1 -1
- package/build/utils/auth-context.js +18 -0
- package/build/utils/auth-context.js.map +1 -1
- package/build/utils/case-enums.d.ts +5 -3
- package/build/utils/case-enums.d.ts.map +1 -1
- package/build/utils/case-enums.js +77 -59
- package/build/utils/case-enums.js.map +1 -1
- package/build/utils/output-schemas.d.ts +16 -0
- package/build/utils/output-schemas.d.ts.map +1 -0
- package/build/utils/output-schemas.js +82 -0
- package/build/utils/output-schemas.js.map +1 -0
- package/build/utils/registry.d.ts +42 -9
- package/build/utils/registry.d.ts.map +1 -1
- package/build/utils/registry.js +64 -11
- package/build/utils/registry.js.map +1 -1
- package/build/utils/response-shape.d.ts +23 -0
- package/build/utils/response-shape.d.ts.map +1 -0
- package/build/utils/response-shape.js +73 -0
- package/build/utils/response-shape.js.map +1 -0
- package/build/utils/rich-response.d.ts +58 -0
- package/build/utils/rich-response.d.ts.map +1 -0
- package/build/utils/rich-response.js +93 -0
- package/build/utils/rich-response.js.map +1 -0
- package/build/utils/server-context.d.ts +65 -0
- package/build/utils/server-context.d.ts.map +1 -0
- package/build/utils/server-context.js +67 -0
- package/build/utils/server-context.js.map +1 -0
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/docs/connect.md +81 -0
- package/docs/migration.md +351 -0
- package/docs/self-run.md +270 -0
- package/docs/tools.md +111 -0
- package/docs/troubleshooting.md +144 -0
- package/package.json +11 -2
- package/server.json +8 -2
- package/build/operations/attachments.d.ts +0 -8
- package/build/operations/attachments.d.ts.map +0 -1
- package/build/operations/attachments.js +0 -146
- package/build/operations/attachments.js.map +0 -1
- package/build/operations/authors.d.ts +0 -8
- package/build/operations/authors.d.ts.map +0 -1
- package/build/operations/authors.js +0 -70
- package/build/operations/authors.js.map +0 -1
- package/build/operations/cases.d.ts +0 -8
- package/build/operations/cases.d.ts.map +0 -1
- package/build/operations/cases.js +0 -370
- package/build/operations/cases.js.map +0 -1
- package/build/operations/configurations.d.ts +0 -10
- package/build/operations/configurations.d.ts.map +0 -1
- package/build/operations/configurations.js +0 -125
- package/build/operations/configurations.js.map +0 -1
- package/build/operations/custom-fields.d.ts +0 -8
- package/build/operations/custom-fields.d.ts.map +0 -1
- package/build/operations/custom-fields.js +0 -172
- package/build/operations/custom-fields.js.map +0 -1
- package/build/operations/defects.d.ts +0 -8
- package/build/operations/defects.d.ts.map +0 -1
- package/build/operations/defects.js +0 -256
- package/build/operations/defects.js.map +0 -1
- package/build/operations/environments.d.ts +0 -8
- package/build/operations/environments.d.ts.map +0 -1
- package/build/operations/environments.js +0 -154
- package/build/operations/environments.js.map +0 -1
- package/build/operations/milestones.d.ts +0 -8
- package/build/operations/milestones.d.ts.map +0 -1
- package/build/operations/milestones.js +0 -155
- package/build/operations/milestones.js.map +0 -1
- package/build/operations/plans.d.ts +0 -8
- package/build/operations/plans.d.ts.map +0 -1
- package/build/operations/plans.js +0 -158
- package/build/operations/plans.js.map +0 -1
- package/build/operations/projects.d.ts +0 -8
- package/build/operations/projects.d.ts.map +0 -1
- package/build/operations/projects.js +0 -192
- package/build/operations/projects.js.map +0 -1
- package/build/operations/results.d.ts +0 -8
- package/build/operations/results.d.ts.map +0 -1
- package/build/operations/results.js +0 -214
- package/build/operations/results.js.map +0 -1
- package/build/operations/runs.d.ts +0 -8
- package/build/operations/runs.d.ts.map +0 -1
- package/build/operations/runs.js +0 -224
- package/build/operations/runs.js.map +0 -1
- package/build/operations/search.d.ts.map +0 -1
- package/build/operations/search.js.map +0 -1
- package/build/operations/shared-parameters.d.ts +0 -10
- package/build/operations/shared-parameters.d.ts.map +0 -1
- package/build/operations/shared-parameters.js +0 -93
- package/build/operations/shared-parameters.js.map +0 -1
- package/build/operations/shared-steps.d.ts +0 -8
- package/build/operations/shared-steps.d.ts.map +0 -1
- package/build/operations/shared-steps.js +0 -160
- package/build/operations/shared-steps.js.map +0 -1
- package/build/operations/suites.d.ts +0 -8
- package/build/operations/suites.d.ts.map +0 -1
- package/build/operations/suites.js +0 -169
- package/build/operations/suites.js.map +0 -1
- package/build/operations/system-fields.d.ts +0 -10
- package/build/operations/system-fields.d.ts.map +0 -1
- package/build/operations/system-fields.js +0 -47
- package/build/operations/system-fields.js.map +0 -1
- package/build/operations/users.d.ts +0 -10
- package/build/operations/users.d.ts.map +0 -1
- package/build/operations/users.js +0 -78
- package/build/operations/users.js.map +0 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Prompt Templates (Skills)
|
|
3
|
+
*
|
|
4
|
+
* Workflow recipes that MCP clients can invoke to guide agents through
|
|
5
|
+
* multi-step testing workflows using Qase tools.
|
|
6
|
+
*
|
|
7
|
+
* Each prompt returns a sequence of messages that instruct the agent
|
|
8
|
+
* how to accomplish a specific testing goal.
|
|
9
|
+
*/
|
|
10
|
+
const prompts = [
|
|
11
|
+
{
|
|
12
|
+
name: 'triage_failed_run',
|
|
13
|
+
description: 'Analyze a failed test run: show all failed results grouped by error pattern, ' +
|
|
14
|
+
'suggest defects to create for unique failures.',
|
|
15
|
+
arguments: [
|
|
16
|
+
{ name: 'project', description: 'Project code (e.g. DEMO)', required: true },
|
|
17
|
+
{ name: 'run_id', description: 'Test run ID to triage', required: true },
|
|
18
|
+
],
|
|
19
|
+
build: (args) => [
|
|
20
|
+
{
|
|
21
|
+
role: 'user',
|
|
22
|
+
content: {
|
|
23
|
+
type: 'text',
|
|
24
|
+
text: [
|
|
25
|
+
`Triage the failed test run #${args.run_id} in project ${args.project}.`,
|
|
26
|
+
'',
|
|
27
|
+
'Steps:',
|
|
28
|
+
`1. Use qase_get to fetch run details: { entity: "run", code: "${args.project}", id: ${args.run_id} }`,
|
|
29
|
+
`2. Use qase_api to get all results: GET /v1/result/${args.project} with filters[run]=${args.run_id}`,
|
|
30
|
+
'3. Group the failed results by stacktrace similarity or error message pattern',
|
|
31
|
+
'4. For each unique failure pattern:',
|
|
32
|
+
' - Show the error message and affected test cases',
|
|
33
|
+
' - Suggest creating a defect with qase_triage_defect',
|
|
34
|
+
'5. Summarize: total passed/failed, unique failure patterns found, suggested defects',
|
|
35
|
+
].join('\n'),
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'release_readiness',
|
|
42
|
+
description: 'Check release readiness for a milestone: test coverage, pass rate, open defects, blocking issues.',
|
|
43
|
+
arguments: [
|
|
44
|
+
{ name: 'project', description: 'Project code (e.g. DEMO)', required: true },
|
|
45
|
+
{ name: 'milestone', description: 'Milestone name or ID', required: true },
|
|
46
|
+
],
|
|
47
|
+
build: (args) => [
|
|
48
|
+
{
|
|
49
|
+
role: 'user',
|
|
50
|
+
content: {
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: [
|
|
53
|
+
`Check release readiness for milestone "${args.milestone}" in project ${args.project}.`,
|
|
54
|
+
'',
|
|
55
|
+
'Steps:',
|
|
56
|
+
`1. Use qase_project_context to get project overview: { code: "${args.project}" }`,
|
|
57
|
+
`2. Search for test runs linked to this milestone:`,
|
|
58
|
+
` qql_search: entity = "run" and project = "${args.project}" and milestone ~ "${args.milestone}"`,
|
|
59
|
+
`3. Search for open defects:`,
|
|
60
|
+
` qql_search: entity = "defect" and project = "${args.project}" and status != "resolved"`,
|
|
61
|
+
`4. For the latest run, get detailed results via qase_api`,
|
|
62
|
+
'5. Produce a release readiness report:',
|
|
63
|
+
' - Milestone status and due date',
|
|
64
|
+
' - Test execution summary (total/passed/failed/untested)',
|
|
65
|
+
' - Pass rate percentage',
|
|
66
|
+
' - Open defects count by severity (blocker/critical/major)',
|
|
67
|
+
' - GO / NO-GO recommendation based on:',
|
|
68
|
+
' * No blocker/critical defects open',
|
|
69
|
+
' * Pass rate > 95%',
|
|
70
|
+
' * No untested high-priority cases',
|
|
71
|
+
].join('\n'),
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'regression_workflow',
|
|
78
|
+
description: 'Create and manage a full regression test cycle: set up a run from a plan or suites, ' +
|
|
79
|
+
'track progress, report results.',
|
|
80
|
+
arguments: [
|
|
81
|
+
{ name: 'project', description: 'Project code (e.g. DEMO)', required: true },
|
|
82
|
+
{
|
|
83
|
+
name: 'title',
|
|
84
|
+
description: 'Regression run title (e.g. "v2.1 Release Regression")',
|
|
85
|
+
required: true,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'source',
|
|
89
|
+
description: 'Source of test cases: plan ID, suite IDs (comma-separated), or "all"',
|
|
90
|
+
required: true,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
build: (args) => {
|
|
94
|
+
const source = args.source || 'all';
|
|
95
|
+
let sourceInstructions;
|
|
96
|
+
if (source.match(/^\d+$/)) {
|
|
97
|
+
sourceInstructions = ` Use plan_id: ${source}`;
|
|
98
|
+
}
|
|
99
|
+
else if (source.includes(',')) {
|
|
100
|
+
const ids = source.split(',').map((s) => s.trim());
|
|
101
|
+
sourceInstructions = ` Use suite_ids: [${ids.join(', ')}]`;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
sourceInstructions = ` Use qql_search to find all actual cases, then pass their IDs`;
|
|
105
|
+
}
|
|
106
|
+
return [
|
|
107
|
+
{
|
|
108
|
+
role: 'user',
|
|
109
|
+
content: {
|
|
110
|
+
type: 'text',
|
|
111
|
+
text: [
|
|
112
|
+
`Set up a regression test run "${args.title}" in project ${args.project}.`,
|
|
113
|
+
'',
|
|
114
|
+
'Steps:',
|
|
115
|
+
`1. Use qase_project_context to understand the project: { code: "${args.project}" }`,
|
|
116
|
+
`2. Create the regression run with qase_regression_run:`,
|
|
117
|
+
` - code: "${args.project}"`,
|
|
118
|
+
` - title: "${args.title}"`,
|
|
119
|
+
sourceInstructions,
|
|
120
|
+
'3. Report back:',
|
|
121
|
+
' - Run ID and URL',
|
|
122
|
+
' - Number of test cases included',
|
|
123
|
+
' - Which suites/plans were used as source',
|
|
124
|
+
'4. Ask if I want to record any results or complete the run',
|
|
125
|
+
].join('\n'),
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
];
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'onboard_project',
|
|
133
|
+
description: 'Get a comprehensive overview of a Qase project for a new team member: ' +
|
|
134
|
+
'structure, recent activity, key metrics.',
|
|
135
|
+
arguments: [{ name: 'project', description: 'Project code (e.g. DEMO)', required: true }],
|
|
136
|
+
build: (args) => [
|
|
137
|
+
{
|
|
138
|
+
role: 'user',
|
|
139
|
+
content: {
|
|
140
|
+
type: 'text',
|
|
141
|
+
text: [
|
|
142
|
+
`Give me a comprehensive overview of project ${args.project} as if I'm a new team member.`,
|
|
143
|
+
'',
|
|
144
|
+
'Steps:',
|
|
145
|
+
`1. Use qase_project_context: { code: "${args.project}" }`,
|
|
146
|
+
`2. Search for recent test runs (last 10):`,
|
|
147
|
+
` qql_search: entity = "run" and project = "${args.project}"`,
|
|
148
|
+
`3. Search for open defects:`,
|
|
149
|
+
` qql_search: entity = "defect" and project = "${args.project}"`,
|
|
150
|
+
`4. Search for test cases to understand coverage:`,
|
|
151
|
+
` qql_search: entity = "case" and project = "${args.project}"`,
|
|
152
|
+
'5. Present a structured overview:',
|
|
153
|
+
' - Project name, description, team size',
|
|
154
|
+
' - Test suite structure (top-level suites and their purpose)',
|
|
155
|
+
' - Test coverage: total cases, automation status if available',
|
|
156
|
+
' - Recent activity: last 5 runs with pass/fail stats',
|
|
157
|
+
' - Open defects by severity',
|
|
158
|
+
' - Environments and milestones in use',
|
|
159
|
+
' - Suggestions for where to start exploring',
|
|
160
|
+
].join('\n'),
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: 'ci_integration',
|
|
167
|
+
description: 'Report CI/CD test results to Qase: create a run, record results, and get a summary.',
|
|
168
|
+
arguments: [
|
|
169
|
+
{ name: 'project', description: 'Project code (e.g. DEMO)', required: true },
|
|
170
|
+
{
|
|
171
|
+
name: 'title',
|
|
172
|
+
description: 'CI run title (e.g. "Build #1234 - main branch")',
|
|
173
|
+
required: true,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: 'results_json',
|
|
177
|
+
description: 'JSON array of results: [{"case_id": 1, "status": "passed"}, ...]',
|
|
178
|
+
required: true,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
build: (args) => [
|
|
182
|
+
{
|
|
183
|
+
role: 'user',
|
|
184
|
+
content: {
|
|
185
|
+
type: 'text',
|
|
186
|
+
text: [
|
|
187
|
+
`Report CI test results to Qase project ${args.project}.`,
|
|
188
|
+
'',
|
|
189
|
+
'Steps:',
|
|
190
|
+
`1. Use qase_ci_report to record results in one call:`,
|
|
191
|
+
` - code: "${args.project}"`,
|
|
192
|
+
` - title: "${args.title}"`,
|
|
193
|
+
` - results: ${args.results_json}`,
|
|
194
|
+
` - complete: true`,
|
|
195
|
+
` - is_autotest: true`,
|
|
196
|
+
'2. Show the summary: run ID, pass/fail counts, any failures',
|
|
197
|
+
'3. If there are failures, suggest next steps (triage, create defects)',
|
|
198
|
+
].join('\n'),
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
];
|
|
204
|
+
/** Get all prompt definitions for ListPrompts */
|
|
205
|
+
export function listPrompts() {
|
|
206
|
+
return prompts.map((p) => ({
|
|
207
|
+
name: p.name,
|
|
208
|
+
description: p.description,
|
|
209
|
+
arguments: p.arguments,
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
/** Build prompt messages for GetPrompt */
|
|
213
|
+
export function getPrompt(name, args = {}) {
|
|
214
|
+
const prompt = prompts.find((p) => p.name === name);
|
|
215
|
+
if (!prompt) {
|
|
216
|
+
throw new Error(`Unknown prompt: "${name}". Available: ${prompts.map((p) => p.name).join(', ')}`);
|
|
217
|
+
}
|
|
218
|
+
// Validate required arguments
|
|
219
|
+
for (const arg of prompt.arguments) {
|
|
220
|
+
if (arg.required && !args[arg.name]) {
|
|
221
|
+
throw new Error(`Missing required argument "${arg.name}" for prompt "${name}"`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
description: prompt.description,
|
|
226
|
+
messages: prompt.build(args),
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAKnE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CA8CrF"}
|
package/build/transports/sse.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
3
3
|
import { requestTokenStorage } from '../utils/auth-context.js';
|
|
4
|
+
import { getMetrics } from '../cache/index.js';
|
|
4
5
|
export function setupSSETransport(server, config) {
|
|
5
6
|
const app = express();
|
|
6
7
|
app.use(express.json());
|
|
@@ -12,6 +13,11 @@ export function setupSSETransport(server, config) {
|
|
|
12
13
|
app.get('/health', (_req, res) => {
|
|
13
14
|
res.json({ status: 'ok', transport: 'sse' });
|
|
14
15
|
});
|
|
16
|
+
// Prometheus metrics endpoint
|
|
17
|
+
app.get('/metrics', (_req, res) => {
|
|
18
|
+
res.set('Content-Type', 'text/plain; version=0.0.4');
|
|
19
|
+
res.send(getMetrics().renderPrometheus());
|
|
20
|
+
});
|
|
15
21
|
// SSE endpoint for establishing connection
|
|
16
22
|
app.get(sseEndpoint, (_req, res) => {
|
|
17
23
|
console.error('[SSE] Client connected');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AAAA,OAAO,OAAoB,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AAAA,OAAO,OAAoB,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAS/C,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,MAA0B;IAC1E,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC;IACjD,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,WAAW,CAAC;IAChE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,CAAC;IAEtC,IAAI,SAAS,GAA8B,IAAI,CAAC;IAEhD,wBAAwB;IACxB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,8BAA8B;IAC9B,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAChC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,2BAA2B,CAAC,CAAC;QACrD,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,2CAA2C;IAC3C,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACjC,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACxC,SAAS,GAAG,IAAI,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,kDAAkD;IAClD,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACtC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAI,GAAG,CAAC,OAAO,CAAC,eAAe,CAAY,IAAI,EAAE,CAAC;QAClE,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,mBAAmB,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,SAAU,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,eAAe;IACf,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;QACjC,OAAO,CAAC,KAAK,CAAC,oCAAoC,IAAI,IAAI,MAAM,CAAC,IAAI,GAAG,WAAW,EAAE,CAAC,CAAC;QACvF,OAAO,CAAC,KAAK,CAAC,8BAA8B,IAAI,IAAI,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { type OAuthConfig } from '../auth/oauth-config.js';
|
|
4
|
+
import { type JwksVerifier } from '../auth/jwks-verifier.js';
|
|
3
5
|
export interface StreamableHttpConfig {
|
|
4
6
|
port: number;
|
|
5
7
|
host?: string;
|
|
6
8
|
endpoint?: string;
|
|
7
9
|
}
|
|
8
|
-
export declare function setupStreamableHttpTransport(createServer: () => Server, config: StreamableHttpConfig
|
|
10
|
+
export declare function setupStreamableHttpTransport(createServer: () => Server, config: StreamableHttpConfig, oauthDeps?: {
|
|
11
|
+
config: OAuthConfig;
|
|
12
|
+
verifier: JwksVerifier;
|
|
13
|
+
}): Express;
|
|
9
14
|
//# sourceMappingURL=streamableHttp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamableHttp.d.ts","sourceRoot":"","sources":["../../src/transports/streamableHttp.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"streamableHttp.d.ts","sourceRoot":"","sources":["../../src/transports/streamableHttp.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAMjF,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AASD,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,MAAM,EAC1B,MAAM,EAAE,oBAAoB,EAC5B,SAAS,CAAC,EAAE;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GAC1D,OAAO,CAsTT"}
|
|
@@ -1,18 +1,45 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
3
|
+
import { mcpAuthRouter } from '@modelcontextprotocol/sdk/server/auth/router.js';
|
|
3
4
|
import { randomUUID } from 'crypto';
|
|
4
5
|
import { requestTokenStorage } from '../utils/auth-context.js';
|
|
6
|
+
import { getMetrics } from '../cache/index.js';
|
|
7
|
+
import { getOAuthConfig } from '../auth/oauth-config.js';
|
|
8
|
+
import { createJwksVerifier } from '../auth/jwks-verifier.js';
|
|
9
|
+
import { createProxyProvider } from '../auth/proxy-provider.js';
|
|
10
|
+
import { createMcpGuard } from '../auth/mcp-guard.js';
|
|
11
|
+
import { authorizeRedirectUriStorage } from '../auth/client-context.js';
|
|
5
12
|
// Helper to check if a request is an initialize request
|
|
6
13
|
function isInitializeRequest(body) {
|
|
7
14
|
return (typeof body === 'object' && body !== null && 'method' in body && body.method === 'initialize');
|
|
8
15
|
}
|
|
9
|
-
export function setupStreamableHttpTransport(createServer, config) {
|
|
16
|
+
export function setupStreamableHttpTransport(createServer, config, oauthDeps) {
|
|
10
17
|
const app = express();
|
|
18
|
+
// Behind a reverse proxy (k8s ingress, load balancer, ngrok) the client's
|
|
19
|
+
// X-Forwarded-For header is set. The SDK's OAuth router uses express-rate-limit,
|
|
20
|
+
// which throws on rate-limited endpoints (/register, /authorize, /token) unless
|
|
21
|
+
// Express `trust proxy` is configured — otherwise those endpoints return 500.
|
|
22
|
+
// Default to trusting 1 proxy hop; override with TRUST_PROXY (a hop count, or
|
|
23
|
+
// 'false' to disable when running with no proxy in front).
|
|
24
|
+
const trustProxyEnv = process.env.TRUST_PROXY;
|
|
25
|
+
app.set('trust proxy', trustProxyEnv === undefined
|
|
26
|
+
? 1
|
|
27
|
+
: /^\d+$/.test(trustProxyEnv)
|
|
28
|
+
? Number(trustProxyEnv)
|
|
29
|
+
: trustProxyEnv === 'false'
|
|
30
|
+
? false
|
|
31
|
+
: trustProxyEnv === 'true'
|
|
32
|
+
? true
|
|
33
|
+
: trustProxyEnv);
|
|
11
34
|
// CORS middleware for inspector
|
|
12
35
|
app.use((req, res, next) => {
|
|
13
36
|
res.header('Access-Control-Allow-Origin', process.env.CORS_ORIGIN || '*');
|
|
14
37
|
res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
|
|
15
38
|
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, mcp-session-id');
|
|
39
|
+
// Expose auth challenge + session id so browser-based MCP clients (Inspector,
|
|
40
|
+
// Claude.ai web) can read them from cross-origin responses. Without this the
|
|
41
|
+
// 401 WWW-Authenticate challenge is invisible to client JS and OAuth never starts.
|
|
42
|
+
res.header('Access-Control-Expose-Headers', 'WWW-Authenticate, mcp-session-id');
|
|
16
43
|
if (req.method === 'OPTIONS') {
|
|
17
44
|
res.sendStatus(200);
|
|
18
45
|
return;
|
|
@@ -22,10 +49,76 @@ export function setupStreamableHttpTransport(createServer, config) {
|
|
|
22
49
|
next();
|
|
23
50
|
});
|
|
24
51
|
app.use(express.json());
|
|
52
|
+
// OAuth: mount proxy auth router + protected-resource metadata, and guard /mcp.
|
|
53
|
+
const oauthConfig = oauthDeps?.config ?? getOAuthConfig();
|
|
54
|
+
let mcpGuard = null;
|
|
55
|
+
if (oauthConfig.enabled) {
|
|
56
|
+
const verifier = oauthDeps?.verifier ?? createJwksVerifier(oauthConfig);
|
|
57
|
+
const provider = createProxyProvider(oauthConfig, verifier);
|
|
58
|
+
// Seed per-request redirect_uri so the proxy's getClient can echo it during /authorize.
|
|
59
|
+
app.use((req, _res, next) => {
|
|
60
|
+
const redirectUri = typeof req.query.redirect_uri === 'string' ? req.query.redirect_uri : undefined;
|
|
61
|
+
authorizeRedirectUriStorage.run(redirectUri, () => next());
|
|
62
|
+
});
|
|
63
|
+
// RFC 9728 protected-resource metadata — served at TWO paths by OUR OWN handlers:
|
|
64
|
+
//
|
|
65
|
+
// - `/.well-known/oauth-protected-resource/mcp` (resource="https://mcp.qase.io/mcp")
|
|
66
|
+
// for clients that use the full endpoint URL as the resource identifier (VS Code).
|
|
67
|
+
// - `/.well-known/oauth-protected-resource` (root, resource=origin) for clients that
|
|
68
|
+
// discover at the root (Claude, Cursor, Codex). Backward compatible.
|
|
69
|
+
//
|
|
70
|
+
// Why our own handlers instead of the SDK's mcpAuthMetadataRouter: the SDK derives
|
|
71
|
+
// authorization_servers from `new URL(issuer).href`, which appends a trailing slash
|
|
72
|
+
// ("https://auth.qase.io/"). The AS's own metadata advertises the issuer WITHOUT the
|
|
73
|
+
// slash ("https://auth.qase.io"), and RFC 8414 §3.3 requires the issuer a client used
|
|
74
|
+
// to discover the AS to match the metadata's `issuer` EXACTLY. That slash mismatch
|
|
75
|
+
// makes strict clients (VS Code) reject the AS metadata and refuse automatic client
|
|
76
|
+
// registration (DCR). So authorization_servers must be exactly oauthConfig.issuer,
|
|
77
|
+
// un-normalized. These routes are registered BEFORE mcpAuthRouter so they take
|
|
78
|
+
// precedence over the SDK's own (slash-normalized) PRM mount; the SDK still serves the
|
|
79
|
+
// AS metadata document + the proxy authorize/token/register endpoints.
|
|
80
|
+
const authorizationServers = [oauthConfig.issuer];
|
|
81
|
+
const rootResourceMetadata = {
|
|
82
|
+
resource: new URL(oauthConfig.publicUrl).href,
|
|
83
|
+
authorization_servers: authorizationServers,
|
|
84
|
+
};
|
|
85
|
+
const mcpResourceMetadata = {
|
|
86
|
+
resource: new URL(oauthConfig.resourceUrl).href,
|
|
87
|
+
authorization_servers: authorizationServers,
|
|
88
|
+
};
|
|
89
|
+
app.get('/.well-known/oauth-protected-resource', (_req, res) => {
|
|
90
|
+
res.json(rootResourceMetadata);
|
|
91
|
+
});
|
|
92
|
+
app.get('/.well-known/oauth-protected-resource/mcp', (_req, res) => {
|
|
93
|
+
res.json(mcpResourceMetadata);
|
|
94
|
+
});
|
|
95
|
+
app.use(mcpAuthRouter({
|
|
96
|
+
provider,
|
|
97
|
+
issuerUrl: new URL(oauthConfig.issuer),
|
|
98
|
+
// baseUrl = the public ORIGIN: the OAuth proxy endpoints (/authorize, /token,
|
|
99
|
+
// /register) and AS metadata mount here. MUST stay the origin — decoupled from
|
|
100
|
+
// resourceUrl — or the resource's `/mcp` path would leak into these paths.
|
|
101
|
+
baseUrl: new URL(oauthConfig.publicUrl),
|
|
102
|
+
// Still passed so the SDK generates its AS-metadata document; its own PRM mount is
|
|
103
|
+
// shadowed by the explicit routes above.
|
|
104
|
+
resourceServerUrl: new URL(oauthConfig.resourceUrl),
|
|
105
|
+
}));
|
|
106
|
+
mcpGuard = createMcpGuard(verifier, oauthConfig);
|
|
107
|
+
console.error('[StreamableHTTP] OAuth proxy enabled');
|
|
108
|
+
}
|
|
25
109
|
const endpoint = config.endpoint || '/mcp';
|
|
26
110
|
const host = config.host || '0.0.0.0';
|
|
27
|
-
|
|
28
|
-
|
|
111
|
+
const guards = mcpGuard ? [mcpGuard] : [];
|
|
112
|
+
// Session management - store transport and last-seen timestamp per session.
|
|
113
|
+
// Sessions are in-memory per pod; one idle longer than this window is evicted
|
|
114
|
+
// (the client transparently re-initializes on the resulting 404). Default 24h so
|
|
115
|
+
// intermittently-used hosted connectors aren't dropped on idle; tune via
|
|
116
|
+
// QASE_MCP_SESSION_TTL_MINUTES. Note: longer TTL keeps more sessions in memory.
|
|
117
|
+
const ttlMinutesRaw = process.env.QASE_MCP_SESSION_TTL_MINUTES;
|
|
118
|
+
const ttlMinutes = ttlMinutesRaw && /^\d+$/.test(ttlMinutesRaw) && Number(ttlMinutesRaw) > 0
|
|
119
|
+
? Number(ttlMinutesRaw)
|
|
120
|
+
: 1440; // 24 hours
|
|
121
|
+
const SESSION_TTL_MS = ttlMinutes * 60 * 1000;
|
|
29
122
|
const sessions = new Map();
|
|
30
123
|
const sessionLastSeen = new Map();
|
|
31
124
|
// Periodically evict stale sessions that never sent a DELETE
|
|
@@ -48,13 +141,21 @@ export function setupStreamableHttpTransport(createServer, config) {
|
|
|
48
141
|
app.get('/health', (_req, res) => {
|
|
49
142
|
res.json({ status: 'ok', transport: 'streamable-http' });
|
|
50
143
|
});
|
|
144
|
+
// Prometheus metrics endpoint
|
|
145
|
+
app.get('/metrics', (_req, res) => {
|
|
146
|
+
res.set('Content-Type', 'text/plain; version=0.0.4');
|
|
147
|
+
res.send(getMetrics().renderPrometheus());
|
|
148
|
+
});
|
|
51
149
|
// MCP endpoint - DELETE for session cleanup
|
|
52
|
-
app.delete(endpoint, async (req, res) => {
|
|
150
|
+
app.delete(endpoint, ...guards, async (req, res) => {
|
|
53
151
|
const sessionId = req.headers['mcp-session-id'];
|
|
54
|
-
if (!sessionId
|
|
55
|
-
res.status(400).json({
|
|
56
|
-
|
|
57
|
-
|
|
152
|
+
if (!sessionId) {
|
|
153
|
+
res.status(400).json({ error: 'Missing mcp-session-id header' });
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (!sessions.has(sessionId)) {
|
|
157
|
+
// Unknown session → 404 so the client re-initializes (see POST handler).
|
|
158
|
+
res.status(404).json({ error: 'Session not found. Reinitialize the session.' });
|
|
58
159
|
return;
|
|
59
160
|
}
|
|
60
161
|
const transport = sessions.get(sessionId);
|
|
@@ -75,12 +176,15 @@ export function setupStreamableHttpTransport(createServer, config) {
|
|
|
75
176
|
}
|
|
76
177
|
});
|
|
77
178
|
// MCP endpoint - GET for SSE streams (if needed)
|
|
78
|
-
app.get(endpoint, async (req, res) => {
|
|
179
|
+
app.get(endpoint, ...guards, async (req, res) => {
|
|
79
180
|
const sessionId = req.headers['mcp-session-id'];
|
|
80
|
-
if (!sessionId
|
|
81
|
-
res.status(400).json({
|
|
82
|
-
|
|
83
|
-
|
|
181
|
+
if (!sessionId) {
|
|
182
|
+
res.status(400).json({ error: 'Missing mcp-session-id header' });
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (!sessions.has(sessionId)) {
|
|
186
|
+
// Unknown session → 404 so the client re-initializes (see POST handler).
|
|
187
|
+
res.status(404).json({ error: 'Session not found. Reinitialize the session.' });
|
|
84
188
|
return;
|
|
85
189
|
}
|
|
86
190
|
const transport = sessions.get(sessionId);
|
|
@@ -97,7 +201,7 @@ export function setupStreamableHttpTransport(createServer, config) {
|
|
|
97
201
|
}
|
|
98
202
|
});
|
|
99
203
|
// MCP endpoint - POST for messages
|
|
100
|
-
app.post(endpoint, async (req, res) => {
|
|
204
|
+
app.post(endpoint, ...guards, async (req, res) => {
|
|
101
205
|
console.error(`[StreamableHTTP] POST ${endpoint} received`, {
|
|
102
206
|
sessionId: req.headers['mcp-session-id'],
|
|
103
207
|
body: req.body,
|
|
@@ -123,10 +227,18 @@ export function setupStreamableHttpTransport(createServer, config) {
|
|
|
123
227
|
await createServer().connect(transport);
|
|
124
228
|
console.error(`[StreamableHTTP] New session created: ${newSessionId}`);
|
|
125
229
|
}
|
|
230
|
+
else if (sessionId) {
|
|
231
|
+
// Session ID provided but unknown (expired, evicted, server restarted, or the
|
|
232
|
+
// request landed on a different instance). Per the MCP streamable-http spec,
|
|
233
|
+
// respond 404 so the client transparently starts a new session (re-initialize)
|
|
234
|
+
// instead of getting stuck on a 400. Auth (JWT) is client-side, so no re-login.
|
|
235
|
+
res.status(404).json({ error: 'Session not found. Reinitialize the session.' });
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
126
238
|
else {
|
|
127
|
-
//
|
|
239
|
+
// No session ID and not an initialize request.
|
|
128
240
|
res.status(400).json({
|
|
129
|
-
error: '
|
|
241
|
+
error: 'Bad Request: no session ID provided and not an initialize request',
|
|
130
242
|
});
|
|
131
243
|
return;
|
|
132
244
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamableHttp.js","sourceRoot":"","sources":["../../src/transports/streamableHttp.ts"],"names":[],"mappings":"AAAA,OAAO,OAAoB,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"streamableHttp.js","sourceRoot":"","sources":["../../src/transports/streamableHttp.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,4 +5,12 @@ import { AsyncLocalStorage } from 'async_hooks';
|
|
|
5
5
|
* Empty string means no user token — fall back to shared QASE_API_TOKEN.
|
|
6
6
|
*/
|
|
7
7
|
export declare const requestTokenStorage: AsyncLocalStorage<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Read the effective token for the current async context: request-scoped
|
|
10
|
+
* token first, then QASE_API_TOKEN env var.
|
|
11
|
+
*
|
|
12
|
+
* Throws if neither is available so callers never silently fall back to a
|
|
13
|
+
* global cache shard.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getEffectiveToken(): string;
|
|
8
16
|
//# sourceMappingURL=auth-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-context.d.ts","sourceRoot":"","sources":["../../src/utils/auth-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,2BAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"auth-context.d.ts","sourceRoot":"","sources":["../../src/utils/auth-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,2BAAkC,CAAC;AAEnE;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAW1C"}
|
|
@@ -5,4 +5,22 @@ import { AsyncLocalStorage } from 'async_hooks';
|
|
|
5
5
|
* Empty string means no user token — fall back to shared QASE_API_TOKEN.
|
|
6
6
|
*/
|
|
7
7
|
export const requestTokenStorage = new AsyncLocalStorage();
|
|
8
|
+
/**
|
|
9
|
+
* Read the effective token for the current async context: request-scoped
|
|
10
|
+
* token first, then QASE_API_TOKEN env var.
|
|
11
|
+
*
|
|
12
|
+
* Throws if neither is available so callers never silently fall back to a
|
|
13
|
+
* global cache shard.
|
|
14
|
+
*/
|
|
15
|
+
export function getEffectiveToken() {
|
|
16
|
+
const requestToken = requestTokenStorage.getStore();
|
|
17
|
+
if (requestToken)
|
|
18
|
+
return requestToken;
|
|
19
|
+
const envToken = process.env.QASE_API_TOKEN;
|
|
20
|
+
if (!envToken) {
|
|
21
|
+
throw new Error('QASE_API_TOKEN environment variable is required or a per-request Bearer token must be provided. ' +
|
|
22
|
+
'Get your API token from: https://app.qase.io/user/api/token');
|
|
23
|
+
}
|
|
24
|
+
return envToken;
|
|
25
|
+
}
|
|
8
26
|
//# sourceMappingURL=auth-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-context.js","sourceRoot":"","sources":["../../src/utils/auth-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,iBAAiB,EAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"auth-context.js","sourceRoot":"","sources":["../../src/utils/auth-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,iBAAiB,EAAU,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC;IACpD,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,kGAAkG;YAChG,6DAA6D,CAChE,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
type SystemFieldMap = Record<string,
|
|
1
|
+
type SystemFieldMap = Record<string, Record<string, number>>;
|
|
2
2
|
export declare function normalizeCaseEnums<T extends Record<string, unknown>>(caseData: T): Promise<T>;
|
|
3
|
-
|
|
4
|
-
export declare function __setCaseEnumCacheForTest(snapshot: SystemFieldMap): void
|
|
3
|
+
/** @internal — used by tests to pre-populate the tenant-scoped shard. */
|
|
4
|
+
export declare function __setCaseEnumCacheForTest(snapshot: SystemFieldMap): Promise<void>;
|
|
5
|
+
/** @internal — used by tests to clear the tenant-scoped shard. */
|
|
6
|
+
export declare function resetCaseEnumCacheForTest(): Promise<void>;
|
|
5
7
|
export {};
|
|
6
8
|
//# sourceMappingURL=case-enums.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"case-enums.d.ts","sourceRoot":"","sources":["../../src/utils/case-enums.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"case-enums.d.ts","sourceRoot":"","sources":["../../src/utils/case-enums.ts"],"names":[],"mappings":"AAkCA,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AA+E7D,wBAAsB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxE,QAAQ,EAAE,CAAC,GACV,OAAO,CAAC,CAAC,CAAC,CAaZ;AAED,yEAAyE;AACzE,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvF;AAED,kEAAkE;AAClE,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG/D"}
|