@smartbear/mcp 0.2.2 → 0.4.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 +207 -60
- package/dist/api-hub/client.js +298 -52
- package/dist/common/server.js +145 -0
- package/dist/index.js +31 -22
- package/dist/insight-hub/client/api/CurrentUser.js +9 -3
- package/dist/insight-hub/client/api/Error.js +81 -0
- package/dist/insight-hub/client/api/Project.js +19 -1
- package/dist/insight-hub/client/api/base.js +10 -2
- package/dist/insight-hub/client.js +524 -357
- package/dist/package.json +15 -5
- package/dist/pactflow/client/ai.js +127 -0
- package/dist/pactflow/client/base.js +1 -0
- package/dist/pactflow/client/tools.js +46 -0
- package/dist/pactflow/client.js +132 -0
- package/dist/reflect/client.js +100 -18
- package/dist/tests/unit/common/server.test.js +319 -0
- package/dist/tests/unit/insight-hub/api-utilities.test.js +31 -0
- package/dist/tests/unit/insight-hub/client.test.js +852 -0
- package/dist/tests/unit/insight-hub/filters.test.js +93 -0
- package/dist/tests/unit/pactflow/ai.test.js +21 -0
- package/dist/tests/unit/pactflow/client.test.js +67 -0
- package/dist/tests/unit/pactflow/tools.test.js +34 -0
- package/dist/vitest.config.js +57 -0
- package/package.json +15 -5
- package/api-hub/README.md +0 -29
- package/assets/smartbear-logo-dark.svg +0 -17
- package/assets/smartbear-logo-light.svg +0 -17
- package/dist/common/templates.js +0 -54
- package/insight-hub/README.md +0 -42
- package/reflect/README.md +0 -25
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { equals, notEquals, empty, relativeTime, isoTime, toUrlSearchParams } from '../../../insight-hub/client/api/filters.js';
|
|
3
|
+
describe('Filter Utilities', () => {
|
|
4
|
+
describe('equals', () => {
|
|
5
|
+
it('should create eq filter for string value', () => {
|
|
6
|
+
const result = equals('test-value');
|
|
7
|
+
expect(result).toEqual({ type: 'eq', value: 'test-value' });
|
|
8
|
+
});
|
|
9
|
+
it('should create eq filter for number value', () => {
|
|
10
|
+
const result = equals(42);
|
|
11
|
+
expect(result).toEqual({ type: 'eq', value: 42 });
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
describe('notEquals', () => {
|
|
15
|
+
it('should create ne filter for string value', () => {
|
|
16
|
+
const result = notEquals('test-value');
|
|
17
|
+
expect(result).toEqual({ type: 'ne', value: 'test-value' });
|
|
18
|
+
});
|
|
19
|
+
it('should create ne filter for number value', () => {
|
|
20
|
+
const result = notEquals(42);
|
|
21
|
+
expect(result).toEqual({ type: 'ne', value: 42 });
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('empty', () => {
|
|
25
|
+
it('should create empty filter for true', () => {
|
|
26
|
+
const result = empty(true);
|
|
27
|
+
expect(result).toEqual({ type: 'empty', value: 'true' });
|
|
28
|
+
});
|
|
29
|
+
it('should create empty filter for false', () => {
|
|
30
|
+
const result = empty(false);
|
|
31
|
+
expect(result).toEqual({ type: 'empty', value: 'false' });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('relativeTime', () => {
|
|
35
|
+
it('should create relative time filter with hours', () => {
|
|
36
|
+
const result = relativeTime(24, 'h');
|
|
37
|
+
expect(result).toEqual({ type: 'eq', value: '24h' });
|
|
38
|
+
});
|
|
39
|
+
it('should create relative time filter with days', () => {
|
|
40
|
+
const result = relativeTime(7, 'd');
|
|
41
|
+
expect(result).toEqual({ type: 'eq', value: '7d' });
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('isoTime', () => {
|
|
45
|
+
it('should create ISO time filter from date', () => {
|
|
46
|
+
const date = new Date('2023-01-01T12:00:00.000Z');
|
|
47
|
+
const result = isoTime(date);
|
|
48
|
+
expect(result).toEqual({ type: 'eq', value: '2023-01-01T12:00:00.000Z' });
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe('toUrlSearchParams', () => {
|
|
52
|
+
it('should convert simple filter object to URL params', () => {
|
|
53
|
+
const filters = {
|
|
54
|
+
'error.status': [{ type: 'eq', value: 'open' }],
|
|
55
|
+
'user.email': [{ type: 'ne', value: 'test@example.com' }]
|
|
56
|
+
};
|
|
57
|
+
const result = toUrlSearchParams(filters);
|
|
58
|
+
expect(result.get('filters[error.status][][type]')).toBe('eq');
|
|
59
|
+
expect(result.get('filters[error.status][][value]')).toBe('open');
|
|
60
|
+
expect(result.get('filters[user.email][][type]')).toBe('ne');
|
|
61
|
+
expect(result.get('filters[user.email][][value]')).toBe('test@example.com');
|
|
62
|
+
});
|
|
63
|
+
it('should handle multiple filters for same field', () => {
|
|
64
|
+
const filters = {
|
|
65
|
+
'error.status': [
|
|
66
|
+
{ type: 'eq', value: 'open' },
|
|
67
|
+
{ type: 'eq', value: 'in_progress' }
|
|
68
|
+
]
|
|
69
|
+
};
|
|
70
|
+
const result = toUrlSearchParams(filters);
|
|
71
|
+
const allEntries = Array.from(result.entries());
|
|
72
|
+
// Should have entries for both filter values
|
|
73
|
+
const statusFilters = allEntries.filter(([key]) => key.includes('error.status'));
|
|
74
|
+
expect(statusFilters.length).toBeGreaterThan(2); // type and value for each filter
|
|
75
|
+
});
|
|
76
|
+
it('should handle empty filter object', () => {
|
|
77
|
+
const filters = {};
|
|
78
|
+
const result = toUrlSearchParams(filters);
|
|
79
|
+
expect(result.toString()).toBe('');
|
|
80
|
+
});
|
|
81
|
+
it('should handle complex filter scenarios', () => {
|
|
82
|
+
const filters = {
|
|
83
|
+
'event.since': [{ type: 'eq', value: '7d' }],
|
|
84
|
+
'error.status': [{ type: 'ne', value: 'resolved' }],
|
|
85
|
+
'user.id': [{ type: 'empty', value: 'false' }]
|
|
86
|
+
};
|
|
87
|
+
const result = toUrlSearchParams(filters);
|
|
88
|
+
expect(result.get('filters[event.since][][value]')).toBe('7d');
|
|
89
|
+
expect(result.get('filters[error.status][][value]')).toBe('resolved');
|
|
90
|
+
expect(result.get('filters[user.id][][value]')).toBe('false');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { RefineInputSchema } from "../../../pactflow/client/ai.js";
|
|
3
|
+
describe("AI zod schemas validation tests", () => {
|
|
4
|
+
it("Parses RefineInputSchema with partial input", () => {
|
|
5
|
+
const result = RefineInputSchema.safeParse({
|
|
6
|
+
pactTests: {
|
|
7
|
+
filename: "test.js",
|
|
8
|
+
language: "javascript",
|
|
9
|
+
body: "describe('API', () => { it('works', () => { }); });"
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
expect(result.success).toBe(true);
|
|
13
|
+
expect(result.data).toEqual({
|
|
14
|
+
pactTests: {
|
|
15
|
+
filename: "test.js",
|
|
16
|
+
language: "javascript",
|
|
17
|
+
body: "describe('API', () => { it('works', () => { }); });"
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import { PactflowClient } from "../../../pactflow/client.js";
|
|
3
|
+
import * as toolsModule from "../../../pactflow/client/tools.js";
|
|
4
|
+
describe("PactflowClient.registerTools", () => {
|
|
5
|
+
const mockRegister = vi.fn();
|
|
6
|
+
const mockGetInput = vi.fn();
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
vi.resetAllMocks();
|
|
9
|
+
});
|
|
10
|
+
it("registers only tools matching the given clientType", () => {
|
|
11
|
+
// Arrange — mock TOOLS with multiple client types
|
|
12
|
+
const fakeTools = [
|
|
13
|
+
{
|
|
14
|
+
title: "tool1",
|
|
15
|
+
summary: "summary1",
|
|
16
|
+
purpose: "purpose1",
|
|
17
|
+
parameters: [],
|
|
18
|
+
handler: "generate",
|
|
19
|
+
clients: ["pactflow"], // should be registered
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
title: "tool2",
|
|
23
|
+
summary: "summary2",
|
|
24
|
+
purpose: "purpose2",
|
|
25
|
+
parameters: [],
|
|
26
|
+
handler: "generate",
|
|
27
|
+
clients: ["pact_broker"], // should NOT be registered
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
vi.spyOn(toolsModule, "TOOLS", "get").mockReturnValue(fakeTools);
|
|
31
|
+
const client = new PactflowClient("token", "https://example.com", "pactflow");
|
|
32
|
+
client.registerTools(mockRegister, mockGetInput);
|
|
33
|
+
expect(mockRegister).toHaveBeenCalledTimes(1);
|
|
34
|
+
expect(mockRegister.mock.calls[0][0].title).toBe("tool1");
|
|
35
|
+
expect(mockRegister.mock.calls[0][0].summary).toBe("summary1");
|
|
36
|
+
});
|
|
37
|
+
it("registers no tools if none match the clientType", () => {
|
|
38
|
+
const fakeTools = [
|
|
39
|
+
{
|
|
40
|
+
title: "tool2",
|
|
41
|
+
summary: "summary2",
|
|
42
|
+
purpose: "purpose2",
|
|
43
|
+
parameters: [],
|
|
44
|
+
handler: "generate",
|
|
45
|
+
clients: ["pact_broker"],
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
vi.spyOn(toolsModule, "TOOLS", "get").mockReturnValue(fakeTools);
|
|
49
|
+
const client = new PactflowClient("token", "https://example.com", "pactflow");
|
|
50
|
+
client.registerTools(mockRegister, mockGetInput);
|
|
51
|
+
expect(mockRegister).not.toHaveBeenCalled();
|
|
52
|
+
});
|
|
53
|
+
it("sets correct headers for pactflow", () => {
|
|
54
|
+
const client = new PactflowClient("my-token", "https://example.com", "pactflow");
|
|
55
|
+
expect(client["headers"]).toEqual(expect.objectContaining({
|
|
56
|
+
Authorization: expect.stringContaining("Bearer my-token"),
|
|
57
|
+
"Content-Type": expect.stringContaining("application/json"),
|
|
58
|
+
}));
|
|
59
|
+
});
|
|
60
|
+
it("sets correct headers for pact_broker", () => {
|
|
61
|
+
const client = new PactflowClient({ username: "user", password: "pass" }, "https://example.com", "pact_broker");
|
|
62
|
+
expect(client["headers"]).toEqual(expect.objectContaining({
|
|
63
|
+
Authorization: expect.stringContaining(`Basic ${Buffer.from("user:pass").toString("base64")}`),
|
|
64
|
+
"Content-Type": expect.stringContaining("application/json"),
|
|
65
|
+
}));
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { TOOLS } from "../../../pactflow/client/tools.js";
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
describe("TOOLS definition for 'Generate Pact Tests'", () => {
|
|
4
|
+
it("defines the generate pact tests tool with correct metadata", () => {
|
|
5
|
+
const tool = TOOLS.find((t) => t.title === "Generate Pact Tests");
|
|
6
|
+
expect(tool).toBeDefined();
|
|
7
|
+
expect(tool?.summary).toMatch(/Generate Pact tests using PactFlow AI/);
|
|
8
|
+
expect(tool?.clients).toEqual(["pactflow"]);
|
|
9
|
+
expect(tool?.handler).toBe("generate");
|
|
10
|
+
});
|
|
11
|
+
it("enforces presence of matcher when openapi input is provided", () => {
|
|
12
|
+
const tool = TOOLS.find((t) => t.title === "Generate Pact Tests");
|
|
13
|
+
const schema = tool?.zodSchema;
|
|
14
|
+
const openapiSchema = schema.shape["openapi"];
|
|
15
|
+
expect(openapiSchema).toBeDefined();
|
|
16
|
+
const invalidOpenapi = {
|
|
17
|
+
openapi: {
|
|
18
|
+
document: {
|
|
19
|
+
openapi: "3.0.0",
|
|
20
|
+
paths: {},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
expect(() => openapiSchema?.parse(invalidOpenapi.openapi)).toThrow(/matcher/);
|
|
25
|
+
});
|
|
26
|
+
it("rejects unsupported language values in the language field", () => {
|
|
27
|
+
const tool = TOOLS.find((t) => t.title === "Generate Pact Tests");
|
|
28
|
+
const schema = tool?.zodSchema;
|
|
29
|
+
const languageSchema = schema.shape["language"];
|
|
30
|
+
expect(languageSchema).toBeDefined();
|
|
31
|
+
const invalidData = "ruby"; // not in enum
|
|
32
|
+
expect(() => languageSchema?.parse(invalidData)).toThrow(/Invalid enum value/);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
export default defineConfig({
|
|
3
|
+
test: {
|
|
4
|
+
globals: true,
|
|
5
|
+
environment: 'node',
|
|
6
|
+
coverage: {
|
|
7
|
+
provider: 'v8',
|
|
8
|
+
reporter: ['text', 'json', 'json-summary', 'html', 'lcov'],
|
|
9
|
+
exclude: [
|
|
10
|
+
'dist/**',
|
|
11
|
+
'node_modules/**',
|
|
12
|
+
'tests/**',
|
|
13
|
+
'*.config.*',
|
|
14
|
+
'**/*.d.ts',
|
|
15
|
+
// Auto-generated API client files
|
|
16
|
+
'insight-hub/client/api/*.ts',
|
|
17
|
+
'insight-hub/client/index.ts',
|
|
18
|
+
'insight-hub/client/configuration.ts',
|
|
19
|
+
// Main entry point (tested via integration)
|
|
20
|
+
'index.ts',
|
|
21
|
+
// Other client implementations (not currently tested)
|
|
22
|
+
'api-hub/client.ts',
|
|
23
|
+
'reflect/client.ts',
|
|
24
|
+
// Utility modules
|
|
25
|
+
'common/bugsnag.ts',
|
|
26
|
+
'common/types.ts'
|
|
27
|
+
],
|
|
28
|
+
// Coverage thresholds for business logic only
|
|
29
|
+
thresholds: {
|
|
30
|
+
lines: 75,
|
|
31
|
+
functions: 75,
|
|
32
|
+
branches: 85,
|
|
33
|
+
statements: 75,
|
|
34
|
+
// Per-file thresholds for core files
|
|
35
|
+
perFile: false
|
|
36
|
+
},
|
|
37
|
+
// Generate more detailed reports
|
|
38
|
+
reportOnFailure: true,
|
|
39
|
+
all: true,
|
|
40
|
+
// Clean coverage directory before tests
|
|
41
|
+
clean: true,
|
|
42
|
+
// Include source map support
|
|
43
|
+
reportsDirectory: './coverage'
|
|
44
|
+
},
|
|
45
|
+
// Include TypeScript files
|
|
46
|
+
include: ['tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
47
|
+
// Setup files
|
|
48
|
+
// Placeholder for future setup files. Remove if not needed.
|
|
49
|
+
setupFiles: []
|
|
50
|
+
},
|
|
51
|
+
// Resolve imports correctly for ESM
|
|
52
|
+
resolve: {
|
|
53
|
+
alias: {
|
|
54
|
+
'@': new URL('./src', import.meta.url).pathname
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartbear/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "MCP server for interacting SmartBear Products",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"smartbear",
|
|
7
7
|
"mcp",
|
|
8
8
|
"insight-hub",
|
|
9
9
|
"reflect",
|
|
10
|
-
"api-hub"
|
|
10
|
+
"api-hub",
|
|
11
|
+
"pactflow"
|
|
11
12
|
],
|
|
12
13
|
"homepage": "https://developer.smartbear.com/smartbear-mcp",
|
|
13
14
|
"repository": {
|
|
@@ -31,20 +32,29 @@
|
|
|
31
32
|
"build": "tsc && shx chmod +x dist/*.js",
|
|
32
33
|
"lint": "eslint . --ext .ts",
|
|
33
34
|
"prepare": "npm run build",
|
|
34
|
-
"watch": "tsc --watch"
|
|
35
|
+
"watch": "tsc --watch",
|
|
36
|
+
"test": "vitest",
|
|
37
|
+
"test:watch": "vitest --watch",
|
|
38
|
+
"test:coverage": "vitest --coverage",
|
|
39
|
+
"test:coverage:ci": "vitest --coverage --reporter=verbose",
|
|
40
|
+
"test:run": "vitest run",
|
|
41
|
+
"coverage:check": "vitest --coverage --reporter=verbose --config vitest.config.coverage.ts"
|
|
35
42
|
},
|
|
36
43
|
"dependencies": {
|
|
37
44
|
"@bugsnag/js": "^8.2.0",
|
|
38
45
|
"@modelcontextprotocol/sdk": "^1.15.0",
|
|
39
|
-
"node-cache": "^5.1.2"
|
|
46
|
+
"node-cache": "^5.1.2",
|
|
47
|
+
"zod": "^3"
|
|
40
48
|
},
|
|
41
49
|
"devDependencies": {
|
|
42
50
|
"@eslint/js": "^9.29.0",
|
|
43
51
|
"@types/node": "^22",
|
|
52
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
44
53
|
"eslint": "^9.29.0",
|
|
45
54
|
"globals": "^16.2.0",
|
|
46
55
|
"shx": "^0.3.4",
|
|
47
56
|
"typescript": "^5.6.2",
|
|
48
|
-
"typescript-eslint": "^8.34.1"
|
|
57
|
+
"typescript-eslint": "^8.34.1",
|
|
58
|
+
"vitest": "^3.2.4"
|
|
49
59
|
}
|
|
50
60
|
}
|
package/api-hub/README.md
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# API Hub
|
|
2
|
-
|
|
3
|
-
## Environment Variables
|
|
4
|
-
|
|
5
|
-
- `API_HUB_API_KEY`: Required. The API key for API Hub MCP tools.
|
|
6
|
-
- `MCP_SERVER_INSIGHT_HUB_API_KEY`: Optional. If set, enables error reporting of the _MCP_server_ code via the BugSnag SDK. This is useful for debugging and monitoring of the MCP server itself and shouldn't be set to the same API key as your app.
|
|
7
|
-
|
|
8
|
-
## Tools
|
|
9
|
-
|
|
10
|
-
1. `list_portals`
|
|
11
|
-
- Search for available portals within API Hub. Only portals where you have at least a designer role, either at the product level or organization level, are returned.
|
|
12
|
-
2. `create_portal`
|
|
13
|
-
- Create a new portal within API Hub.
|
|
14
|
-
3. `get_portal`
|
|
15
|
-
- Retrieve information about a specific portal.
|
|
16
|
-
4. `delete_portal`
|
|
17
|
-
- Delete a portal.
|
|
18
|
-
5. `update_portal`
|
|
19
|
-
- Update a specific portal's configuration.
|
|
20
|
-
6. `list_portal_products`
|
|
21
|
-
- Get products for a specific portal matching your criteria.
|
|
22
|
-
7. `create_portal_product`
|
|
23
|
-
- Create a new product within a specific portal.
|
|
24
|
-
8. `get_portal_product`
|
|
25
|
-
- Retrieve information about a specific product resource.
|
|
26
|
-
9. `delete_portal_product`
|
|
27
|
-
- Delete a product from a specific portal.
|
|
28
|
-
10. `update_portal_product`
|
|
29
|
-
- Update a product's settings within a specific portal.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="253.9" height="179.21" viewBox="0 0 253.9 179.21">
|
|
2
|
-
<title>SB_Logo_Vertical_BLK_RGB</title>
|
|
3
|
-
<g>
|
|
4
|
-
<path d="M146,115.56H108l-6.75,20.79h51.55Zm102,20.79-20-61.43L241,35.24,193,0.4,159.26,24.94H94.7L60.93,0.4,13,35.24,25.87,74.92l-20,61.43h63L64,121.28l63-45.76,63,45.76-4.89,15.07h63ZM108,115.56l-6.75,20.79h51.55L146,115.56H108Zm38.05,0H108l-6.75,20.79h51.55Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
5
|
-
<g>
|
|
6
|
-
<path d="M17.86,156.7s-5.4-.62-7.64-0.62c-3.24,0-4.9,1.16-4.9,3.43,0,2.47,1.39,3,5.9,4.28,5.55,1.54,7.56,3,7.56,7.52,0,5.78-3.62,8.29-8.83,8.29a56.2,56.2,0,0,1-8.64-1l0.42-3.43s5.21,0.69,7.94.69c3.28,0,4.78-1.47,4.78-4.24,0-2.24-1.2-3-5.24-4C3.52,166.14,1,164.41,1,159.82c0-5.32,3.51-7.52,8.79-7.52a58.55,58.55,0,0,1,8.37.92Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
7
|
-
<path d="M29.06,152.76H36.5l5.9,20.63,5.9-20.63h7.48v26.42H51.46V156.35H51.24l-6.6,21.75H40.16l-6.6-21.75H33.34v22.83H29.06V152.76Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
8
|
-
<path d="M122.08,152.76h19.28v3.82h-7.44v22.6H129.6v-22.6h-7.52v-3.82Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
9
|
-
<path d="M160,152.76c5.24,0,8.06,2,8.06,6.86,0,3.2-1,4.78-3.12,5.94,2.28,0.89,3.78,2.51,3.78,6.13,0,5.4-3.28,7.48-8.41,7.48H150V152.76h10Zm-5.75,3.7V164h5.67c2.62,0,3.78-1.31,3.78-3.9s-1.31-3.66-3.93-3.66h-5.52Zm0,11.18v7.83h5.82c2.66,0,4.24-.85,4.24-4,0-3-2.24-3.82-4.32-3.82h-5.75Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
10
|
-
<path d="M179.32,152.76H196v3.74H183.6V164h10.07v3.66H183.6v7.75H196v3.78H179.32V152.76Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
11
|
-
<path d="M211.33,152.76h8.52l6.56,26.42h-4.32l-2-7.75H211l-2,7.75h-4.28Zm0.57,14.89h7.41l-2.73-11.3h-1.93Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
12
|
-
<path d="M240.22,171.35v7.83h-4.28V152.76h10c5.82,0,8.95,3.34,8.95,9.2,0,3.74-1.5,7.12-4.32,8.43l4.36,8.79h-4.71l-3.82-7.83h-6.21ZM246,156.46h-5.75v11.18H246c3.24,0,4.47-2.91,4.47-5.65C250.51,159,249,156.46,246,156.46Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
13
|
-
<path d="M71.64,152.76h8.52l6.56,26.42H82.39l-2-7.75h-9.1l-2,7.75H65.12Zm0.57,14.89h7.41l-2.73-11.3H75Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
14
|
-
<path d="M100.52,171.35v7.83H96.24V152.76h10c5.82,0,8.95,3.34,8.95,9.2,0,3.74-1.5,7.12-4.32,8.43l4.36,8.79h-4.71l-3.82-7.83h-6.21Zm5.75-14.89h-5.75v11.18h5.82c3.24,0,4.47-2.91,4.47-5.65C110.82,159,109.35,156.46,106.27,156.46Z" transform="translate(-1.05 -0.4)" fill="#2c282c"/>
|
|
15
|
-
</g>
|
|
16
|
-
</g>
|
|
17
|
-
</svg>
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="253.9" height="179.21" viewBox="0 0 253.9 179.21">
|
|
2
|
-
<title>SB_Logo_Vertical_WT_RGB</title>
|
|
3
|
-
<g>
|
|
4
|
-
<path d="M146,115.56H108l-6.75,20.79h51.55Zm102,20.79-20-61.43L241,35.24,193,0.4,159.26,24.94H94.7L60.93,0.4,13,35.24,25.87,74.92l-20,61.43h63L64,121.28l63-45.76,63,45.76-4.89,15.07h63ZM108,115.56l-6.75,20.79h51.55L146,115.56H108Zm38.05,0H108l-6.75,20.79h51.55Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
5
|
-
<g>
|
|
6
|
-
<path d="M17.86,156.7s-5.4-.62-7.64-0.62c-3.24,0-4.9,1.16-4.9,3.43,0,2.47,1.39,3,5.9,4.28,5.55,1.54,7.56,3,7.56,7.52,0,5.78-3.62,8.29-8.83,8.29a56.2,56.2,0,0,1-8.64-1l0.42-3.43s5.21,0.69,7.94.69c3.28,0,4.78-1.47,4.78-4.24,0-2.24-1.2-3-5.24-4C3.52,166.14,1,164.41,1,159.82c0-5.32,3.51-7.52,8.79-7.52a58.55,58.55,0,0,1,8.37.92Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
7
|
-
<path d="M29.06,152.76H36.5l5.9,20.63,5.9-20.63h7.48v26.42H51.46V156.35H51.24l-6.6,21.75H40.16l-6.6-21.75H33.34v22.83H29.06V152.76Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
8
|
-
<path d="M122.08,152.76h19.28v3.82h-7.44v22.6H129.6v-22.6h-7.52v-3.82Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
9
|
-
<path d="M160,152.76c5.24,0,8.06,2,8.06,6.86,0,3.2-1,4.78-3.12,5.94,2.28,0.89,3.78,2.51,3.78,6.13,0,5.4-3.28,7.48-8.41,7.48H150V152.76h10Zm-5.75,3.7V164h5.67c2.62,0,3.78-1.31,3.78-3.9s-1.31-3.66-3.93-3.66h-5.52Zm0,11.18v7.83h5.82c2.66,0,4.24-.85,4.24-4,0-3-2.24-3.82-4.32-3.82h-5.75Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
10
|
-
<path d="M179.32,152.76H196v3.74H183.6V164h10.07v3.66H183.6v7.75H196v3.78H179.32V152.76Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
11
|
-
<path d="M211.33,152.76h8.52l6.56,26.42h-4.32l-2-7.75H211l-2,7.75h-4.28Zm0.57,14.89h7.41l-2.73-11.3h-1.93Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
12
|
-
<path d="M240.22,171.35v7.83h-4.28V152.76h10c5.82,0,8.95,3.34,8.95,9.2,0,3.74-1.5,7.12-4.32,8.43l4.36,8.79h-4.71l-3.82-7.83h-6.21ZM246,156.46h-5.75v11.18H246c3.24,0,4.47-2.91,4.47-5.65C250.51,159,249,156.46,246,156.46Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
13
|
-
<path d="M71.64,152.76h8.52l6.56,26.42H82.39l-2-7.75h-9.1l-2,7.75H65.12Zm0.57,14.89h7.41l-2.73-11.3H75Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
14
|
-
<path d="M100.52,171.35v7.83H96.24V152.76h10c5.82,0,8.95,3.34,8.95,9.2,0,3.74-1.5,7.12-4.32,8.43l4.36,8.79h-4.71l-3.82-7.83h-6.21Zm5.75-14.89h-5.75v11.18h5.82c3.24,0,4.47-2.91,4.47-5.65C110.82,159,109.35,156.46,106.27,156.46Z" transform="translate(-1.05 -0.4)" fill="#fff"/>
|
|
15
|
-
</g>
|
|
16
|
-
</g>
|
|
17
|
-
</svg>
|
package/dist/common/templates.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export function toolDescriptionTemplate(params) {
|
|
2
|
-
const { summary, useCases, examples, parameters, hints } = params;
|
|
3
|
-
let description = summary;
|
|
4
|
-
// Parameters (essential)
|
|
5
|
-
if (parameters.length > 0) {
|
|
6
|
-
description += `\n\n**Parameters:** ${parameters.map(p => `${p.name} (${p.type})${p.required ? ' *required*' : ''}`).join(', ')}`;
|
|
7
|
-
}
|
|
8
|
-
// Use Cases
|
|
9
|
-
if (useCases.length > 0) {
|
|
10
|
-
description += `\n\n**Use Cases:** ${useCases.map((uc, i) => `${i + 1}. ${uc}`).join(' ')}`;
|
|
11
|
-
}
|
|
12
|
-
// Examples
|
|
13
|
-
if (examples.length > 0) {
|
|
14
|
-
description += `\n\n**Examples:**\n` + examples.map((ex, idx) => `${idx + 1}. ${ex.description}\n\`\`\`json\n${JSON.stringify(ex.parameters, null, 2)}\n\`\`\`${ex.expectedOutput ? `\nExpected Output: ${ex.expectedOutput}` : ''}`).join('\n\n');
|
|
15
|
-
}
|
|
16
|
-
// Hints
|
|
17
|
-
if (hints.length > 0) {
|
|
18
|
-
description += `\n\n**Tips:** ${hints.map((hint, i) => `${i + 1}. ${hint}`).join(' ')}`;
|
|
19
|
-
}
|
|
20
|
-
return description.trim();
|
|
21
|
-
}
|
|
22
|
-
// Backward-compatible version of the original function
|
|
23
|
-
export function simpleToolDescriptionTemplate(summary, useCases, examples, hints) {
|
|
24
|
-
return toolDescriptionTemplate({
|
|
25
|
-
summary,
|
|
26
|
-
purpose: summary,
|
|
27
|
-
useCases,
|
|
28
|
-
examples: examples.map(example => ({
|
|
29
|
-
description: example,
|
|
30
|
-
parameters: {}
|
|
31
|
-
})),
|
|
32
|
-
parameters: [],
|
|
33
|
-
hints
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
// Helper function to create parameter descriptions
|
|
37
|
-
export function createParameter(name, type, required, description, options = {}) {
|
|
38
|
-
return {
|
|
39
|
-
name,
|
|
40
|
-
type,
|
|
41
|
-
required,
|
|
42
|
-
description,
|
|
43
|
-
examples: options.examples,
|
|
44
|
-
constraints: options.constraints
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
// Helper function to create examples with proper structure
|
|
48
|
-
export function createExample(description, parameters, expectedOutput) {
|
|
49
|
-
return {
|
|
50
|
-
description,
|
|
51
|
-
parameters,
|
|
52
|
-
expectedOutput
|
|
53
|
-
};
|
|
54
|
-
}
|
package/insight-hub/README.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# Insight Hub
|
|
2
|
-
|
|
3
|
-
Fetch details of your app crashes and errors from your [Insight Hub](https://www.smartbear.com/insight-hub) dashboard for your LLM to help you diagnose and fix.
|
|
4
|
-
|
|
5
|
-
To connect an MCP server, you will need to create a personal auth token from the user settings page on your Insight Hub dashboard.
|
|
6
|
-
|
|
7
|
-
If you wish to interact with only one Insight Hub project, we also recommend setting `INSIGHT_HUB_PROJECT_API_KEY` to reduce the scope of the conversation. This allows the MCP server to pre-cache your project's custom filters for better filtering prompts.
|
|
8
|
-
|
|
9
|
-
## Example prompts
|
|
10
|
-
|
|
11
|
-
- "Help me fix this crash: https://app.bugsnag.com/my-org/my-project/errors/1a2b3c4d5e6f7g8h9i0j1k2l?&event_id=1a2b3c4d5e6f7g8h9i0j1k2l"
|
|
12
|
-
- "What are my latest events my project?"
|
|
13
|
-
- "Which errors occurred in the last 7 days?"
|
|
14
|
-
|
|
15
|
-
## Environment Variables
|
|
16
|
-
|
|
17
|
-
- `INSIGHT_HUB_AUTH_TOKEN`: (Required) The auth token for your account from your Insight Hub dashboard, under **Personal auth tokens** in user settings.
|
|
18
|
-
- `INSIGHT_HUB_PROJECT_API_KEY`: (Recommended) The API key for the Insight Hub project you wish to interact with. Use this to scope all operations to a single project.
|
|
19
|
-
- `INSIGHT_HUB_ENDPOINT`: (Optional) The API server to connect to. Use this for on-premise installations to point to your own endpoint (e.g. `https://your.api.server`).
|
|
20
|
-
|
|
21
|
-
## Tools
|
|
22
|
-
|
|
23
|
-
1. `list_insight_hub_projects`
|
|
24
|
-
- List all projects in an organization.
|
|
25
|
-
- Multi-project mode only.
|
|
26
|
-
2. `get_insight_hub_error`
|
|
27
|
-
- Get error details from a project.
|
|
28
|
-
3. `get_insight_hub_error_latest_event`
|
|
29
|
-
- Get the latest event for an error.
|
|
30
|
-
4. `get_insight_hub_event_details`
|
|
31
|
-
- Get details of a specific event.
|
|
32
|
-
5. `get_project_event_filters`
|
|
33
|
-
- List the filters available for a project.
|
|
34
|
-
6. `list_insight_hub_project_errors`
|
|
35
|
-
- List and filter the errors from a project.
|
|
36
|
-
|
|
37
|
-
## Resources
|
|
38
|
-
|
|
39
|
-
- **insight_hub_event**
|
|
40
|
-
- URI Template: `insighthub://event/{id}`
|
|
41
|
-
- Description: Fetches details for a specific event by its event ID. Returns the event details in JSON format.
|
|
42
|
-
- Example usage: Retrieve event details for debugging or analysis by referencing the event ID.
|
package/reflect/README.md
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# Reflect
|
|
2
|
-
|
|
3
|
-
## Environment Variables
|
|
4
|
-
|
|
5
|
-
- `REFLECT_API_TOKEN`: Required. The Reflect Account API Key.
|
|
6
|
-
- `MCP_SERVER_INSIGHT_HUB_API_KEY`: Optional. If set, enables error reporting of the _MCP_server_ code via the BugSnag SDK. This is useful for debugging and monitoring of the MCP server itself and shouldn't be set to the same API key as your app.
|
|
7
|
-
|
|
8
|
-
## Tools
|
|
9
|
-
|
|
10
|
-
1. `list_reflect_suites`
|
|
11
|
-
- List all Reflect suites for your account.
|
|
12
|
-
2. `list_reflect_suite_executions`
|
|
13
|
-
- List all executions for a given Reflect suite.
|
|
14
|
-
3. `reflect_suite_execution_status`
|
|
15
|
-
- Get the status of a Reflect suite execution.
|
|
16
|
-
4. `reflect_suite_execution`
|
|
17
|
-
- Execute a Reflect suite.
|
|
18
|
-
5. `cancel_reflect_suite_execution`
|
|
19
|
-
- Cancel a Reflect suite execution.
|
|
20
|
-
6. `list_reflect_tests`
|
|
21
|
-
- List all Reflect tests.
|
|
22
|
-
7. `run_reflect_test`
|
|
23
|
-
- Run a Reflect test.
|
|
24
|
-
8. `reflect_test_status`
|
|
25
|
-
- Get the status of a Reflect test execution.
|