@frontmcp/skills 1.1.2 → 1.2.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/catalog/TEMPLATE.md +16 -11
- package/catalog/frontmcp-authorities/SKILL.md +116 -11
- package/catalog/frontmcp-authorities/references/authority-profiles.md +39 -36
- package/catalog/frontmcp-authorities/references/claims-mapping.md +7 -0
- package/catalog/frontmcp-authorities/references/custom-evaluators.md +63 -14
- package/catalog/frontmcp-channels/SKILL.md +36 -0
- package/catalog/frontmcp-channels/examples/channel-sources/file-watcher.md +8 -2
- package/catalog/frontmcp-channels/examples/channel-sources/replay-buffer.md +111 -30
- package/catalog/frontmcp-channels/examples/channel-two-way/whatsapp-bridge.md +45 -3
- package/catalog/frontmcp-channels/references/channel-sources.md +11 -3
- package/catalog/frontmcp-channels/references/channel-two-way.md +60 -89
- package/catalog/frontmcp-config/SKILL.md +111 -8
- package/catalog/frontmcp-config/examples/configure-auth-modes/local-self-signed-tokens.md +4 -4
- package/catalog/frontmcp-config/examples/configure-auth-modes/remote-enterprise-oauth.md +7 -1
- package/catalog/frontmcp-config/examples/configure-deployment-targets/distributed-ha-config.md +1 -1
- package/catalog/frontmcp-config/examples/configure-deployment-targets/json-schema-ide-support.md +1 -1
- package/catalog/frontmcp-config/examples/configure-deployment-targets/multi-target-with-security.md +12 -9
- package/catalog/frontmcp-config/examples/configure-http/cors-restricted-origins.md +2 -2
- package/catalog/frontmcp-config/examples/configure-http/entry-path-reverse-proxy.md +1 -1
- package/catalog/frontmcp-config/examples/configure-security-headers/csp-report-only.md +1 -1
- package/catalog/frontmcp-config/examples/configure-security-headers/full-production-headers.md +1 -1
- package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-basic.md +76 -0
- package/catalog/frontmcp-config/examples/configure-skills-http/audit-log-redis.md +116 -0
- package/catalog/frontmcp-config/examples/configure-skills-http/inject-instructions.md +59 -0
- package/catalog/frontmcp-config/references/configure-auth-modes.md +5 -5
- package/catalog/frontmcp-config/references/configure-deployment-targets.md +27 -24
- package/catalog/frontmcp-config/references/configure-http.md +14 -10
- package/catalog/frontmcp-config/references/configure-security-headers.md +2 -2
- package/catalog/frontmcp-config/references/configure-session.md +25 -25
- package/catalog/frontmcp-config/references/configure-skills-http.md +157 -0
- package/catalog/frontmcp-config/references/configure-throttle.md +1 -1
- package/catalog/frontmcp-config/references/configure-transport.md +2 -2
- package/catalog/frontmcp-deployment/SKILL.md +112 -9
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-build-with-custom-entry.md +23 -11
- package/catalog/frontmcp-deployment/examples/build-for-browser/browser-crypto-and-storage.md +44 -17
- package/catalog/frontmcp-deployment/examples/build-for-browser/react-provider-setup.md +53 -21
- package/catalog/frontmcp-deployment/examples/build-for-cli/cli-binary-build.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-cli/unix-socket-daemon.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-mcpb/mcpb-bundle-build.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-sdk/connect-openai.md +1 -1
- package/catalog/frontmcp-deployment/examples/build-for-sdk/multi-platform-connect.md +1 -1
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/basic-worker-deploy.md +7 -8
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-custom-domain.md +8 -6
- package/catalog/frontmcp-deployment/examples/deploy-to-cloudflare/worker-with-kv-storage.md +5 -4
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/cdk-deployment.md +8 -5
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/lambda-handler-with-cors.md +20 -18
- package/catalog/frontmcp-deployment/examples/deploy-to-lambda/sam-template-basic.md +8 -5
- package/catalog/frontmcp-deployment/examples/deploy-to-node/docker-compose-with-redis.md +3 -3
- package/catalog/frontmcp-deployment/examples/deploy-to-node/pm2-with-nginx.md +1 -1
- package/catalog/frontmcp-deployment/examples/deploy-to-node/resource-limits.md +2 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/basic-multistage-dockerfile.md +2 -2
- package/catalog/frontmcp-deployment/examples/deploy-to-node-dockerfile/secure-nonroot-dockerfile.md +1 -1
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-mcp-endpoint-test.md +23 -21
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-kv.md +25 -22
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel/vercel-with-skills-cache.md +23 -30
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/minimal-vercel-config.md +52 -28
- package/catalog/frontmcp-deployment/examples/deploy-to-vercel-config/vercel-config-with-security-headers.md +32 -55
- package/catalog/frontmcp-deployment/examples/mcp-client-integration/http-remote.md +9 -0
- package/catalog/frontmcp-deployment/references/build-for-browser.md +40 -17
- package/catalog/frontmcp-deployment/references/build-for-cli.md +8 -8
- package/catalog/frontmcp-deployment/references/deploy-to-cloudflare.md +43 -24
- package/catalog/frontmcp-deployment/references/deploy-to-lambda.md +36 -25
- package/catalog/frontmcp-deployment/references/deploy-to-node-dockerfile.md +56 -14
- package/catalog/frontmcp-deployment/references/deploy-to-node.md +9 -6
- package/catalog/frontmcp-deployment/references/deploy-to-vercel-config.md +57 -58
- package/catalog/frontmcp-deployment/references/deploy-to-vercel.md +49 -59
- package/catalog/frontmcp-deployment/references/mcp-client-integration.md +2 -0
- package/catalog/frontmcp-development/SKILL.md +186 -11
- package/catalog/frontmcp-development/examples/create-agent/custom-multi-pass-agent.md +1 -1
- package/catalog/frontmcp-development/examples/create-agent/nested-agents-with-swarm.md +30 -27
- package/catalog/frontmcp-development/examples/create-job/job-with-permissions.md +13 -8
- package/catalog/frontmcp-development/examples/create-provider/basic-database-provider.md +33 -23
- package/catalog/frontmcp-development/examples/create-provider/config-and-api-providers.md +19 -10
- package/catalog/frontmcp-development/examples/create-tool/tool-with-rate-limiting-and-progress.md +3 -3
- package/catalog/frontmcp-development/examples/create-workflow/webhook-triggered-workflow.md +6 -4
- package/catalog/frontmcp-development/examples/decorators-guide/agent-skill-job-workflow.md +1 -1
- package/catalog/frontmcp-development/examples/decorators-guide/basic-server-with-app-and-tools.md +13 -8
- package/catalog/frontmcp-development/examples/decorators-guide/multi-app-with-plugins-and-providers.md +50 -23
- package/catalog/frontmcp-development/references/create-agent.md +47 -30
- package/catalog/frontmcp-development/references/create-job.md +69 -54
- package/catalog/frontmcp-development/references/create-plugin-hooks.md +45 -28
- package/catalog/frontmcp-development/references/create-plugin.md +10 -8
- package/catalog/frontmcp-development/references/create-prompt.md +3 -3
- package/catalog/frontmcp-development/references/create-provider.md +91 -51
- package/catalog/frontmcp-development/references/create-resource.md +3 -3
- package/catalog/frontmcp-development/references/create-skill.md +2 -2
- package/catalog/frontmcp-development/references/create-tool.md +7 -7
- package/catalog/frontmcp-development/references/create-workflow.md +8 -10
- package/catalog/frontmcp-development/references/decorators-guide.md +92 -56
- package/catalog/frontmcp-development/references/official-plugins.md +4 -3
- package/catalog/frontmcp-development/references/openapi-adapter.md +1 -1
- package/catalog/frontmcp-extensibility/SKILL.md +70 -10
- package/catalog/frontmcp-extensibility/examples/skill-audit-log/custom-store.md +197 -0
- package/catalog/frontmcp-extensibility/examples/skill-audit-log/verify-chain.md +68 -0
- package/catalog/frontmcp-extensibility/examples/vectoriadb/product-catalog-search.md +3 -5
- package/catalog/frontmcp-extensibility/examples/vectoriadb/semantic-search-with-persistence.md +4 -11
- package/catalog/frontmcp-extensibility/examples/vectoriadb/tfidf-keyword-search.md +41 -30
- package/catalog/frontmcp-extensibility/references/skill-audit-log.md +233 -0
- package/catalog/frontmcp-extensibility/references/vectoriadb.md +73 -63
- package/catalog/frontmcp-guides/SKILL.md +84 -27
- package/catalog/frontmcp-guides/examples/example-knowledge-base/agent-and-plugin.md +72 -62
- package/catalog/frontmcp-guides/examples/example-knowledge-base/vector-search-and-resources.md +32 -43
- package/catalog/frontmcp-guides/examples/example-task-manager/auth-and-crud-tools.md +24 -17
- package/catalog/frontmcp-guides/examples/example-task-manager/authenticated-e2e-tests.md +23 -21
- package/catalog/frontmcp-guides/examples/example-task-manager/redis-provider-with-di.md +47 -39
- package/catalog/frontmcp-guides/examples/example-weather-api/server-and-app-setup.md +16 -6
- package/catalog/frontmcp-guides/examples/example-weather-api/unit-and-e2e-tests.md +9 -8
- package/catalog/frontmcp-guides/references/example-knowledge-base.md +192 -265
- package/catalog/frontmcp-guides/references/example-task-manager.md +60 -54
- package/catalog/frontmcp-guides/references/example-weather-api.md +22 -24
- package/catalog/frontmcp-observability/SKILL.md +66 -2
- package/catalog/frontmcp-observability/examples/telemetry-api/skill-counters.md +100 -0
- package/catalog/frontmcp-observability/examples/tracing-setup/production-tracing.md +7 -2
- package/catalog/frontmcp-observability/examples/vendor-integrations/coralogix-setup.md +6 -2
- package/catalog/frontmcp-observability/references/telemetry-api.md +72 -8
- package/catalog/frontmcp-observability/references/testing-observability.md +33 -49
- package/catalog/frontmcp-observability/references/tracing-setup.md +12 -5
- package/catalog/frontmcp-observability/references/vendor-integrations.md +46 -1
- package/catalog/frontmcp-production-readiness/SKILL.md +134 -3
- package/catalog/frontmcp-production-readiness/examples/common-checklist/caching-and-performance.md +57 -36
- package/catalog/frontmcp-production-readiness/examples/common-checklist/observability-setup.md +1 -1
- package/catalog/frontmcp-production-readiness/examples/common-checklist/security-hardening.md +102 -6
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/daemon-socket-config.md +2 -1
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/graceful-shutdown-cleanup.md +66 -58
- package/catalog/frontmcp-production-readiness/examples/production-cli-daemon/security-and-permissions.md +5 -3
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/durable-objects-state.md +2 -1
- package/catalog/frontmcp-production-readiness/examples/production-cloudflare/wrangler-config.md +55 -76
- package/catalog/frontmcp-production-readiness/examples/production-lambda/cold-start-connection-reuse.md +43 -40
- package/catalog/frontmcp-production-readiness/examples/production-lambda/sam-template.md +63 -94
- package/catalog/frontmcp-production-readiness/examples/production-lambda/scaling-and-monitoring.md +28 -18
- package/catalog/frontmcp-production-readiness/examples/production-node-sdk/multi-instance-cleanup.md +29 -14
- package/catalog/frontmcp-production-readiness/examples/production-node-server/graceful-shutdown.md +58 -42
- package/catalog/frontmcp-production-readiness/examples/production-node-server/redis-session-scaling.md +5 -2
- package/catalog/frontmcp-production-readiness/examples/production-vercel/cold-start-optimization.md +41 -24
- package/catalog/frontmcp-production-readiness/examples/production-vercel/vercel-edge-config.md +56 -65
- package/catalog/frontmcp-production-readiness/references/common-checklist.md +17 -5
- package/catalog/frontmcp-production-readiness/references/production-cli-daemon.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-cloudflare.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-lambda.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-node-sdk.md +5 -5
- package/catalog/frontmcp-production-readiness/references/production-node-server.md +1 -1
- package/catalog/frontmcp-production-readiness/references/production-vercel.md +5 -5
- package/catalog/frontmcp-setup/SKILL.md +88 -0
- package/catalog/frontmcp-setup/examples/project-structure-nx/nx-workspace-with-apps.md +10 -4
- package/catalog/frontmcp-setup/examples/project-structure-standalone/dev-workflow-commands.md +21 -8
- package/catalog/frontmcp-setup/examples/readme-guide/node-server-readme.md +3 -3
- package/catalog/frontmcp-setup/references/multi-app-composition.md +4 -3
- package/catalog/frontmcp-setup/references/project-structure-nx.md +15 -6
- package/catalog/frontmcp-setup/references/project-structure-standalone.md +18 -15
- package/catalog/frontmcp-setup/references/readme-guide.md +1 -1
- package/catalog/frontmcp-setup/references/setup-project.md +19 -5
- package/catalog/frontmcp-setup/references/setup-redis.md +27 -39
- package/catalog/frontmcp-setup/references/setup-sqlite.md +25 -18
- package/catalog/frontmcp-testing/SKILL.md +102 -15
- package/catalog/frontmcp-testing/examples/setup-testing/unit-test-tool-resource-prompt.md +3 -3
- package/catalog/frontmcp-testing/examples/test-auth/oauth-flow-test.md +50 -39
- package/catalog/frontmcp-testing/examples/test-auth/role-based-access-test.md +52 -29
- package/catalog/frontmcp-testing/examples/test-auth/token-factory-test.md +37 -20
- package/catalog/frontmcp-testing/examples/test-direct-client/basic-create-test.md +25 -15
- package/catalog/frontmcp-testing/examples/test-direct-client/openai-claude-format-test.md +27 -21
- package/catalog/frontmcp-testing/examples/test-e2e-handler/basic-e2e-test.md +29 -20
- package/catalog/frontmcp-testing/examples/test-e2e-handler/manual-client-with-transport.md +5 -3
- package/catalog/frontmcp-testing/examples/test-e2e-handler/tool-call-and-error-e2e.md +35 -26
- package/catalog/frontmcp-testing/examples/test-tool-unit/basic-tool-test.md +8 -3
- package/catalog/frontmcp-testing/examples/test-tool-unit/schema-validation-test.md +4 -1
- package/catalog/frontmcp-testing/examples/test-tool-unit/tool-error-handling-test.md +6 -3
- package/catalog/frontmcp-testing/references/setup-testing.md +35 -39
- package/catalog/frontmcp-testing/references/test-auth.md +86 -43
- package/catalog/frontmcp-testing/references/test-browser-build.md +1 -1
- package/catalog/frontmcp-testing/references/test-direct-client.md +29 -19
- package/catalog/frontmcp-testing/references/test-e2e-handler.md +31 -19
- package/catalog/frontmcp-testing/references/test-tool-unit.md +6 -2
- package/catalog/skills-manifest.json +428 -339
- package/package.json +1 -1
- package/src/manifest.d.ts +13 -0
- package/src/manifest.js.map +1 -1
|
@@ -3,11 +3,11 @@ name: openai-claude-format-test
|
|
|
3
3
|
reference: test-direct-client
|
|
4
4
|
level: intermediate
|
|
5
5
|
description: 'Verify that tools are returned in the correct format for OpenAI and Claude clients using `connectOpenAI` and `connectClaude`.'
|
|
6
|
-
tags: [testing, openai, anthropic, direct-client
|
|
6
|
+
tags: [testing, openai, anthropic, direct-client]
|
|
7
7
|
features:
|
|
8
|
-
- 'Using `connectOpenAI()`
|
|
8
|
+
- 'Using `connectOpenAI(ServerConfig)` to get an in-memory `DirectClient` (no HTTP server is started)'
|
|
9
9
|
- "Verifying OpenAI tool format: `{ type: 'function', function: { name, parameters } }`"
|
|
10
|
-
- 'Using
|
|
10
|
+
- 'Using `connectClaude(ServerConfig)` to verify Claude format: `{ name, description, input_schema }`'
|
|
11
11
|
- 'Proper cleanup with `client.close()` after each test'
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -19,22 +19,33 @@ Verify that tools are returned in the correct format for OpenAI and Claude clien
|
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
21
|
// src/__tests__/client-formats.spec.ts
|
|
22
|
-
|
|
22
|
+
// Real API:
|
|
23
|
+
// libs/sdk/src/direct/connect.ts — `connectOpenAI(config, options?)` (no `serve` field)
|
|
24
|
+
// libs/sdk/src/direct/connect.ts — `connectClaude(config, options?)`
|
|
25
|
+
// libs/sdk/src/index.ts — exports `Tool`, `ToolContext`, `App`, `FrontMcp`, `z`
|
|
26
|
+
import { App, connectClaude, connectOpenAI, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
@Tool({
|
|
25
29
|
name: 'add',
|
|
26
30
|
description: 'Add numbers',
|
|
27
31
|
inputSchema: { a: z.number(), b: z.number() },
|
|
28
32
|
outputSchema: { sum: z.number() },
|
|
29
|
-
})
|
|
33
|
+
})
|
|
34
|
+
class AddTool extends ToolContext {
|
|
35
|
+
async execute(input: { a: number; b: number }) {
|
|
36
|
+
return { sum: input.a + input.b };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@App({ name: 'test-app', tools: [AddTool] })
|
|
41
|
+
class TestApp {}
|
|
42
|
+
|
|
43
|
+
@FrontMcp({ info: { name: 'test', version: '1.0.0' }, apps: [TestApp] })
|
|
44
|
+
class TestServerConfig {}
|
|
30
45
|
|
|
31
46
|
describe('OpenAI format', () => {
|
|
32
|
-
it('
|
|
33
|
-
const client = await connectOpenAI(
|
|
34
|
-
info: { name: 'test', version: '1.0.0' },
|
|
35
|
-
tools: [AddTool],
|
|
36
|
-
serve: false,
|
|
37
|
-
});
|
|
47
|
+
it('returns OpenAI-formatted tools', async () => {
|
|
48
|
+
const client = await connectOpenAI(TestServerConfig);
|
|
38
49
|
|
|
39
50
|
const tools = await client.listTools();
|
|
40
51
|
// OpenAI format: [{ type: 'function', function: { name, parameters } }]
|
|
@@ -47,13 +58,8 @@ describe('OpenAI format', () => {
|
|
|
47
58
|
});
|
|
48
59
|
|
|
49
60
|
describe('Claude format', () => {
|
|
50
|
-
it('
|
|
51
|
-
const
|
|
52
|
-
const client = await connectClaude({
|
|
53
|
-
info: { name: 'test', version: '1.0.0' },
|
|
54
|
-
tools: [AddTool],
|
|
55
|
-
serve: false,
|
|
56
|
-
});
|
|
61
|
+
it('returns Claude-formatted tools', async () => {
|
|
62
|
+
const client = await connectClaude(TestServerConfig);
|
|
57
63
|
|
|
58
64
|
const tools = await client.listTools();
|
|
59
65
|
// Claude format: [{ name, description, input_schema }]
|
|
@@ -67,9 +73,9 @@ describe('Claude format', () => {
|
|
|
67
73
|
|
|
68
74
|
## What This Demonstrates
|
|
69
75
|
|
|
70
|
-
- Using `connectOpenAI()`
|
|
76
|
+
- Using `connectOpenAI(ServerConfig)` to get an in-memory `DirectClient` (no HTTP server is started)
|
|
71
77
|
- Verifying OpenAI tool format: `{ type: 'function', function: { name, parameters } }`
|
|
72
|
-
- Using
|
|
78
|
+
- Using `connectClaude(ServerConfig)` to verify Claude format: `{ name, description, input_schema }`
|
|
73
79
|
- Proper cleanup with `client.close()` after each test
|
|
74
80
|
|
|
75
81
|
## Related
|
|
@@ -5,10 +5,10 @@ level: basic
|
|
|
5
5
|
description: 'Set up a basic E2E test that starts a server, connects a client, and verifies tools are listed.'
|
|
6
6
|
tags: [testing, e2e, handler]
|
|
7
7
|
features:
|
|
8
|
-
- 'Using `TestServer.
|
|
9
|
-
- '
|
|
10
|
-
- '
|
|
11
|
-
- '
|
|
8
|
+
- 'Using `TestServer.start({ command, port })` to spawn the server as a child process'
|
|
9
|
+
- 'Building a client with `McpTestClient.create(...).withTransport(...).buildAndConnect()`'
|
|
10
|
+
- 'Calling the namespaced public API: `client.tools.list()`, `client.resources.list()`, `client.prompts.get(...)`'
|
|
11
|
+
- 'Cleaning up with `client.disconnect()` and `server.stop()`'
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
# Basic E2E Test with McpTestClient
|
|
@@ -19,36 +19,45 @@ Set up a basic E2E test that starts a server, connects a client, and verifies to
|
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
21
|
// src/__tests__/server.e2e.spec.ts
|
|
22
|
+
// Real API:
|
|
23
|
+
// libs/testing/src/server/test-server.ts:101 — `TestServer.start({ command, port })`
|
|
24
|
+
// libs/testing/src/client/mcp-test-client.builder.ts — `McpTestClient.create(...).buildAndConnect()`
|
|
25
|
+
// libs/testing/src/client/mcp-test-client.ts:306-402 — `client.tools.list/call`, `client.resources.list/read`, `client.prompts.list/get`, `client.disconnect`
|
|
22
26
|
import { McpTestClient, TestServer } from '@frontmcp/testing';
|
|
23
|
-
import Server from '../src/main';
|
|
24
27
|
|
|
25
28
|
describe('Server E2E', () => {
|
|
26
29
|
let client: McpTestClient;
|
|
27
30
|
let server: TestServer;
|
|
28
31
|
|
|
29
32
|
beforeAll(async () => {
|
|
30
|
-
server = await TestServer.
|
|
31
|
-
|
|
33
|
+
server = await TestServer.start({
|
|
34
|
+
command: 'npx tsx src/main.ts',
|
|
35
|
+
port: 3021,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
client = await McpTestClient.create({ baseUrl: server.info.baseUrl })
|
|
39
|
+
.withTransport('streamable-http')
|
|
40
|
+
.buildAndConnect();
|
|
32
41
|
});
|
|
33
42
|
|
|
34
43
|
afterAll(async () => {
|
|
35
|
-
await client.
|
|
36
|
-
await server.
|
|
44
|
+
await client.disconnect();
|
|
45
|
+
await server.stop();
|
|
37
46
|
});
|
|
38
47
|
|
|
39
|
-
it('
|
|
40
|
-
const
|
|
48
|
+
it('lists all tools', async () => {
|
|
49
|
+
const tools = await client.tools.list();
|
|
41
50
|
expect(tools.length).toBeGreaterThan(0);
|
|
42
51
|
expect(tools).toContainTool('add_numbers');
|
|
43
52
|
});
|
|
44
53
|
|
|
45
|
-
it('
|
|
46
|
-
const
|
|
47
|
-
expect(resources
|
|
54
|
+
it('lists resources', async () => {
|
|
55
|
+
const resources = await client.resources.list();
|
|
56
|
+
expect(Array.isArray(resources)).toBe(true);
|
|
48
57
|
});
|
|
49
58
|
|
|
50
|
-
it('
|
|
51
|
-
const result = await client.
|
|
59
|
+
it('gets a prompt', async () => {
|
|
60
|
+
const result = await client.prompts.get('summarize', { topic: 'testing' });
|
|
52
61
|
expect(result.messages).toBeDefined();
|
|
53
62
|
expect(result.messages.length).toBeGreaterThan(0);
|
|
54
63
|
});
|
|
@@ -57,10 +66,10 @@ describe('Server E2E', () => {
|
|
|
57
66
|
|
|
58
67
|
## What This Demonstrates
|
|
59
68
|
|
|
60
|
-
- Using `TestServer.
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
69
|
+
- Using `TestServer.start({ command, port })` to spawn the server as a child process
|
|
70
|
+
- Building a client with `McpTestClient.create(...).withTransport(...).buildAndConnect()`
|
|
71
|
+
- Calling the namespaced public API: `client.tools.list()`, `client.resources.list()`, `client.prompts.get(...)`
|
|
72
|
+
- Cleaning up with `client.disconnect()` and `server.stop()`
|
|
64
73
|
|
|
65
74
|
## Related
|
|
66
75
|
|
|
@@ -6,7 +6,7 @@ description: 'Use `McpTestClient.create()` with explicit transport settings for
|
|
|
6
6
|
tags: [testing, session, transport, e2e, handler, manual]
|
|
7
7
|
features:
|
|
8
8
|
- 'Using `TestServer.start()` with an explicit command and port for process-based server startup'
|
|
9
|
-
- "Building a client with `McpTestClient.create().withTransport('
|
|
9
|
+
- "Building a client with `McpTestClient.create().withTransport('streamable-http').buildAndConnect()`"
|
|
10
10
|
- 'Using `server.info.baseUrl` to wire the client to the correct address'
|
|
11
11
|
- 'Separate `disconnect()` / `stop()` calls for client and server teardown'
|
|
12
12
|
- 'The `toBeError()` and `toHaveTextContent()` custom matchers'
|
|
@@ -32,7 +32,9 @@ describe('Advanced E2E with Transport Config', () => {
|
|
|
32
32
|
port: 3004,
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
client = await McpTestClient.create({ baseUrl: server.info.baseUrl })
|
|
35
|
+
client = await McpTestClient.create({ baseUrl: server.info.baseUrl })
|
|
36
|
+
.withTransport('streamable-http')
|
|
37
|
+
.buildAndConnect();
|
|
36
38
|
});
|
|
37
39
|
|
|
38
40
|
afterAll(async () => {
|
|
@@ -61,7 +63,7 @@ describe('Advanced E2E with Transport Config', () => {
|
|
|
61
63
|
## What This Demonstrates
|
|
62
64
|
|
|
63
65
|
- Using `TestServer.start()` with an explicit command and port for process-based server startup
|
|
64
|
-
- Building a client with `McpTestClient.create().withTransport('
|
|
66
|
+
- Building a client with `McpTestClient.create().withTransport('streamable-http').buildAndConnect()`
|
|
65
67
|
- Using `server.info.baseUrl` to wire the client to the correct address
|
|
66
68
|
- Separate `disconnect()` / `stop()` calls for client and server teardown
|
|
67
69
|
- The `toBeError()` and `toHaveTextContent()` custom matchers
|
|
@@ -3,12 +3,12 @@ name: tool-call-and-error-e2e
|
|
|
3
3
|
reference: test-e2e-handler
|
|
4
4
|
level: intermediate
|
|
5
5
|
description: 'Test successful tool calls and verify that invalid inputs produce proper error responses over the full MCP protocol.'
|
|
6
|
-
tags: [testing, e2e, handler, tool
|
|
6
|
+
tags: [testing, e2e, handler, tool-call, error]
|
|
7
7
|
features:
|
|
8
|
-
- 'Calling tools via `client.
|
|
9
|
-
- '
|
|
10
|
-
- '
|
|
11
|
-
- 'Testing edge cases like zero values
|
|
8
|
+
- 'Calling tools via `client.tools.call(name, args)` and asserting success with `toBeSuccessful()`'
|
|
9
|
+
- 'Asserting text content with the `toHaveTextContent()` matcher'
|
|
10
|
+
- 'Asserting error results with `toBeError()` for invalid input and unknown tools'
|
|
11
|
+
- 'Testing edge cases like zero values'
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
# E2E Testing Tool Calls and Error Responses
|
|
@@ -19,53 +19,62 @@ Test successful tool calls and verify that invalid inputs produce proper error r
|
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
21
|
// src/__tests__/tool-calls.e2e.spec.ts
|
|
22
|
+
// Real API:
|
|
23
|
+
// libs/testing/src/server/test-server.ts:101 — `TestServer.start({ command, port })`
|
|
24
|
+
// libs/testing/src/client/mcp-test-client.ts:306 — `client.tools.call(name, args)` (public namespaced API)
|
|
25
|
+
// libs/testing/src/assertions/* — `toBeSuccessful`, `toBeError`, `toHaveTextContent`
|
|
22
26
|
import { McpTestClient, TestServer } from '@frontmcp/testing';
|
|
23
|
-
import Server from '../src/main';
|
|
24
27
|
|
|
25
28
|
describe('Tool Call E2E', () => {
|
|
26
29
|
let client: McpTestClient;
|
|
27
30
|
let server: TestServer;
|
|
28
31
|
|
|
29
32
|
beforeAll(async () => {
|
|
30
|
-
server = await TestServer.
|
|
31
|
-
|
|
33
|
+
server = await TestServer.start({
|
|
34
|
+
command: 'npx tsx src/main.ts',
|
|
35
|
+
port: 3022,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
client = await McpTestClient.create({ baseUrl: server.info.baseUrl })
|
|
39
|
+
.withTransport('streamable-http')
|
|
40
|
+
.buildAndConnect();
|
|
32
41
|
});
|
|
33
42
|
|
|
34
43
|
afterAll(async () => {
|
|
35
|
-
await client.
|
|
36
|
-
await server.
|
|
44
|
+
await client.disconnect();
|
|
45
|
+
await server.stop();
|
|
37
46
|
});
|
|
38
47
|
|
|
39
|
-
it('
|
|
40
|
-
const result = await client.
|
|
48
|
+
it('calls a tool and gets a successful result', async () => {
|
|
49
|
+
const result = await client.tools.call('add_numbers', { a: 5, b: 3 });
|
|
41
50
|
expect(result).toBeSuccessful();
|
|
42
|
-
expect(result
|
|
51
|
+
expect(result).toHaveTextContent('8');
|
|
43
52
|
});
|
|
44
53
|
|
|
45
|
-
it('
|
|
46
|
-
const result = await client.
|
|
47
|
-
expect(result
|
|
54
|
+
it('returns an error for invalid input', async () => {
|
|
55
|
+
const result = await client.tools.call('add_numbers', { a: 'bad' });
|
|
56
|
+
expect(result).toBeError();
|
|
48
57
|
});
|
|
49
58
|
|
|
50
|
-
it('
|
|
51
|
-
const result = await client.
|
|
52
|
-
expect(result
|
|
59
|
+
it('returns an error for a nonexistent tool', async () => {
|
|
60
|
+
const result = await client.tools.call('nonexistent_tool', {});
|
|
61
|
+
expect(result).toBeError();
|
|
53
62
|
});
|
|
54
63
|
|
|
55
|
-
it('
|
|
56
|
-
const result = await client.
|
|
64
|
+
it('handles edge case: zero values', async () => {
|
|
65
|
+
const result = await client.tools.call('add_numbers', { a: 10, b: 0 });
|
|
57
66
|
expect(result).toBeSuccessful();
|
|
58
|
-
expect(result
|
|
67
|
+
expect(result).toHaveTextContent('10');
|
|
59
68
|
});
|
|
60
69
|
});
|
|
61
70
|
```
|
|
62
71
|
|
|
63
72
|
## What This Demonstrates
|
|
64
73
|
|
|
65
|
-
- Calling tools via `client.
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- Testing edge cases like zero values
|
|
74
|
+
- Calling tools via `client.tools.call(name, args)` and asserting success with `toBeSuccessful()`
|
|
75
|
+
- Asserting text content with the `toHaveTextContent()` matcher
|
|
76
|
+
- Asserting error results with `toBeError()` for invalid input and unknown tools
|
|
77
|
+
- Testing edge cases like zero values
|
|
69
78
|
|
|
70
79
|
## Related
|
|
71
80
|
|
|
@@ -5,7 +5,7 @@ level: basic
|
|
|
5
5
|
description: "Test a simple tool's `execute()` method with mock context and verify the output."
|
|
6
6
|
tags: [testing, tool, unit]
|
|
7
7
|
features:
|
|
8
|
-
- '
|
|
8
|
+
- 'Mocking the real `ExecutionContextBase` API surface (`get`, `tryGet`, `scope`, `fail`, `mark`, `fetch`) plus `notify` from `ToolContext`'
|
|
9
9
|
- 'Assigning the mock context to the tool instance via `Object.assign`'
|
|
10
10
|
- 'Testing multiple input scenarios including edge cases (negatives, zero)'
|
|
11
11
|
---
|
|
@@ -18,7 +18,11 @@ Test a simple tool's `execute()` method with mock context and verify the output.
|
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
20
|
// src/tools/__tests__/add.tool.spec.ts
|
|
21
|
+
// Real API: libs/sdk/src/common/interfaces/execution-context.interface.ts
|
|
22
|
+
// ExecutionContextBase exposes: get, tryGet, scope, fail, mark, fetch
|
|
23
|
+
// ToolContext additionally exposes: notify (use only when the tool calls this.notify(...))
|
|
21
24
|
import { ToolContext } from '@frontmcp/sdk';
|
|
25
|
+
|
|
22
26
|
import { AddTool } from '../add.tool';
|
|
23
27
|
|
|
24
28
|
describe('AddTool', () => {
|
|
@@ -30,12 +34,13 @@ describe('AddTool', () => {
|
|
|
30
34
|
const ctx = {
|
|
31
35
|
get: jest.fn(),
|
|
32
36
|
tryGet: jest.fn(),
|
|
37
|
+
scope: { get: jest.fn(), tryGet: jest.fn() },
|
|
33
38
|
fail: jest.fn((err) => {
|
|
34
39
|
throw err;
|
|
35
40
|
}),
|
|
36
41
|
mark: jest.fn(),
|
|
42
|
+
fetch: jest.fn(),
|
|
37
43
|
notify: jest.fn(),
|
|
38
|
-
respondProgress: jest.fn(),
|
|
39
44
|
} as unknown as ToolContext;
|
|
40
45
|
|
|
41
46
|
Object.assign(tool, ctx);
|
|
@@ -60,7 +65,7 @@ describe('AddTool', () => {
|
|
|
60
65
|
|
|
61
66
|
## What This Demonstrates
|
|
62
67
|
|
|
63
|
-
-
|
|
68
|
+
- Mocking the real `ExecutionContextBase` API surface (`get`, `tryGet`, `scope`, `fail`, `mark`, `fetch`) plus `notify` from `ToolContext`
|
|
64
69
|
- Assigning the mock context to the tool instance via `Object.assign`
|
|
65
70
|
- Testing multiple input scenarios including edge cases (negatives, zero)
|
|
66
71
|
|
|
@@ -51,15 +51,18 @@ describe('AddTool schema validation', () => {
|
|
|
51
51
|
|
|
52
52
|
it('should coerce valid input and produce correct output', async () => {
|
|
53
53
|
const tool = new AddTool();
|
|
54
|
+
// Mock the real ExecutionContextBase + ToolContext surface.
|
|
55
|
+
// Real API: libs/sdk/src/common/interfaces/execution-context.interface.ts
|
|
54
56
|
const ctx = {
|
|
55
57
|
get: jest.fn(),
|
|
56
58
|
tryGet: jest.fn(),
|
|
59
|
+
scope: { get: jest.fn(), tryGet: jest.fn() },
|
|
57
60
|
fail: jest.fn((err) => {
|
|
58
61
|
throw err;
|
|
59
62
|
}),
|
|
60
63
|
mark: jest.fn(),
|
|
64
|
+
fetch: jest.fn(),
|
|
61
65
|
notify: jest.fn(),
|
|
62
|
-
respondProgress: jest.fn(),
|
|
63
66
|
} as unknown as ToolContext;
|
|
64
67
|
Object.assign(tool, ctx);
|
|
65
68
|
|
|
@@ -19,8 +19,8 @@ Test that a tool throws the correct MCP error classes with proper error codes an
|
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
21
|
// src/tools/__tests__/lookup.tool.spec.ts
|
|
22
|
-
import { ToolContext } from '@frontmcp/sdk';
|
|
23
|
-
|
|
22
|
+
import { MCP_ERROR_CODES, ResourceNotFoundError, ToolContext } from '@frontmcp/sdk';
|
|
23
|
+
|
|
24
24
|
import { LookupTool } from '../lookup.tool';
|
|
25
25
|
|
|
26
26
|
describe('LookupTool error handling', () => {
|
|
@@ -29,15 +29,18 @@ describe('LookupTool error handling', () => {
|
|
|
29
29
|
beforeEach(() => {
|
|
30
30
|
tool = new LookupTool();
|
|
31
31
|
|
|
32
|
+
// Mock the real ExecutionContextBase + ToolContext surface.
|
|
33
|
+
// Real API: libs/sdk/src/common/interfaces/execution-context.interface.ts
|
|
32
34
|
const ctx = {
|
|
33
35
|
get: jest.fn(),
|
|
34
36
|
tryGet: jest.fn(),
|
|
37
|
+
scope: { get: jest.fn(), tryGet: jest.fn() },
|
|
35
38
|
fail: jest.fn((err) => {
|
|
36
39
|
throw err;
|
|
37
40
|
}),
|
|
38
41
|
mark: jest.fn(),
|
|
42
|
+
fetch: jest.fn(),
|
|
39
43
|
notify: jest.fn(),
|
|
40
|
-
respondProgress: jest.fn(),
|
|
41
44
|
} as unknown as ToolContext;
|
|
42
45
|
|
|
43
46
|
Object.assign(tool, ctx);
|
|
@@ -120,7 +120,7 @@ describe('MyTool', () => {
|
|
|
120
120
|
|
|
121
121
|
### Testing a Resource
|
|
122
122
|
|
|
123
|
-
Resources extend `ResourceContext` and implement `
|
|
123
|
+
Resources extend `ResourceContext` and implement `execute(uri, params)`. Verify the output matches the MCP `ReadResourceResult` shape.
|
|
124
124
|
|
|
125
125
|
```typescript
|
|
126
126
|
// my-resource.spec.ts
|
|
@@ -129,7 +129,7 @@ import { MyResource } from '../my-resource';
|
|
|
129
129
|
describe('MyResource', () => {
|
|
130
130
|
it('should return resource contents', async () => {
|
|
131
131
|
const resource = new MyResource();
|
|
132
|
-
const result = await resource.
|
|
132
|
+
const result = await resource.execute('resource://item/123', { id: '123' });
|
|
133
133
|
|
|
134
134
|
expect(result).toEqual({
|
|
135
135
|
contents: [
|
|
@@ -174,7 +174,7 @@ describe('MyPrompt', () => {
|
|
|
174
174
|
Always verify error classes with `instanceof` checks and error codes:
|
|
175
175
|
|
|
176
176
|
```typescript
|
|
177
|
-
import {
|
|
177
|
+
import { MCP_ERROR_CODES, ResourceNotFoundError } from '@frontmcp/sdk';
|
|
178
178
|
|
|
179
179
|
describe('ResourceNotFoundError', () => {
|
|
180
180
|
it('should be instanceof ResourceNotFoundError', () => {
|
|
@@ -217,48 +217,41 @@ The `@frontmcp/testing` library provides a full E2E testing framework with a tes
|
|
|
217
217
|
|
|
218
218
|
```typescript
|
|
219
219
|
import {
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
AuthHeaders,
|
|
221
|
+
BaselineStore,
|
|
222
|
+
DefaultInterceptorChain,
|
|
223
|
+
// Interceptors & mocking
|
|
224
|
+
DefaultMockRegistry,
|
|
222
225
|
expect,
|
|
223
|
-
|
|
226
|
+
httpMock,
|
|
227
|
+
httpResponse,
|
|
228
|
+
interceptors,
|
|
229
|
+
LeakDetector,
|
|
230
|
+
// Assertions & matchers
|
|
231
|
+
McpAssertions,
|
|
232
|
+
// Low-level client
|
|
233
|
+
McpClient,
|
|
234
|
+
mcpMatchers,
|
|
235
|
+
McpStdioClientTransport,
|
|
224
236
|
// Manual client API
|
|
225
237
|
McpTestClient,
|
|
226
238
|
McpTestClientBuilder,
|
|
227
|
-
|
|
228
|
-
// Server management
|
|
229
|
-
TestServer,
|
|
230
|
-
|
|
231
|
-
// Auth testing
|
|
232
|
-
TestTokenFactory,
|
|
233
|
-
AuthHeaders,
|
|
234
|
-
TestUsers,
|
|
235
|
-
MockOAuthServer,
|
|
239
|
+
MetricsCollector,
|
|
236
240
|
MockAPIServer,
|
|
237
241
|
MockCimdServer,
|
|
238
|
-
|
|
239
|
-
// Assertions & matchers
|
|
240
|
-
McpAssertions,
|
|
241
|
-
mcpMatchers,
|
|
242
|
-
|
|
243
|
-
// Interceptors & mocking
|
|
244
|
-
DefaultMockRegistry,
|
|
245
|
-
DefaultInterceptorChain,
|
|
242
|
+
MockOAuthServer,
|
|
246
243
|
mockResponse,
|
|
247
|
-
interceptors,
|
|
248
|
-
httpMock,
|
|
249
|
-
httpResponse,
|
|
250
|
-
|
|
251
244
|
// Performance testing
|
|
252
245
|
perfTest,
|
|
253
|
-
MetricsCollector,
|
|
254
|
-
LeakDetector,
|
|
255
|
-
BaselineStore,
|
|
256
246
|
RegressionDetector,
|
|
257
247
|
ReportGenerator,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
248
|
+
// Primary API (fixture-based)
|
|
249
|
+
test,
|
|
250
|
+
// Server management
|
|
251
|
+
TestServer,
|
|
252
|
+
// Auth testing
|
|
253
|
+
TestTokenFactory,
|
|
254
|
+
TestUsers,
|
|
262
255
|
} from '@frontmcp/testing';
|
|
263
256
|
```
|
|
264
257
|
|
|
@@ -274,7 +267,7 @@ The fixture API manages server lifecycle automatically:
|
|
|
274
267
|
|
|
275
268
|
```typescript
|
|
276
269
|
// my-server.e2e.spec.ts
|
|
277
|
-
import {
|
|
270
|
+
import { expect, test } from '@frontmcp/testing';
|
|
278
271
|
|
|
279
272
|
test.use({
|
|
280
273
|
server: './src/main.ts',
|
|
@@ -316,10 +309,13 @@ test('prompts return well-formed messages', async ({ mcp }) => {
|
|
|
316
309
|
|
|
317
310
|
For more control, use `McpTestClient` and `TestServer` directly:
|
|
318
311
|
|
|
319
|
-
> **Note:** `
|
|
312
|
+
> **Note:** `TestServer.start({ command })` accepts any command that boots your server — your `dev` npm script, the built artifact (e.g. `node dist/main.js`), or `npx tsx src/main.ts` for unbuilt sources. The example below uses `npx tsx`; substitute whatever you use to start the server in development.
|
|
320
313
|
|
|
321
314
|
```typescript
|
|
322
315
|
// advanced.e2e.spec.ts
|
|
316
|
+
// Real API: libs/testing/src/server/test-server.ts:101 (TestServer.start),
|
|
317
|
+
// libs/testing/src/client/mcp-test-client.builder.ts (McpTestClient.create),
|
|
318
|
+
// libs/testing/src/client/mcp-test-client.types.ts:55 (TestTransportType = 'sse' | 'streamable-http')
|
|
323
319
|
import { McpTestClient, TestServer } from '@frontmcp/testing';
|
|
324
320
|
|
|
325
321
|
describe('Advanced E2E', () => {
|
|
@@ -333,7 +329,7 @@ describe('Advanced E2E', () => {
|
|
|
333
329
|
});
|
|
334
330
|
|
|
335
331
|
client = await McpTestClient.create({ baseUrl: server.info.baseUrl })
|
|
336
|
-
.withTransport('
|
|
332
|
+
.withTransport('streamable-http')
|
|
337
333
|
.buildAndConnect();
|
|
338
334
|
});
|
|
339
335
|
|
|
@@ -357,7 +353,7 @@ describe('Advanced E2E', () => {
|
|
|
357
353
|
### Testing with Authentication
|
|
358
354
|
|
|
359
355
|
```typescript
|
|
360
|
-
import {
|
|
356
|
+
import { expect, test } from '@frontmcp/testing';
|
|
361
357
|
|
|
362
358
|
test.use({
|
|
363
359
|
server: './src/main.ts',
|
|
@@ -521,7 +517,7 @@ node scripts/fix-unused-imports.mjs feature/my-branch
|
|
|
521
517
|
### Unit Tests
|
|
522
518
|
|
|
523
519
|
- [ ] Each tool's `execute()` method is tested with valid and invalid inputs
|
|
524
|
-
- [ ] Each resource's `
|
|
520
|
+
- [ ] Each resource's `execute(uri, params)` method is tested and output matches `ReadResourceResult` shape
|
|
525
521
|
- [ ] Each prompt's `execute()` method is tested and output matches `GetPromptResult` shape
|
|
526
522
|
- [ ] Constructor validation tests verify throws on invalid config
|
|
527
523
|
- [ ] Error classes are verified with `instanceof` checks and `mcpErrorCode` assertions
|