Skip to content

Commit f1a2f31

Browse files
feat: enhance tool introspection to return undefined for tools outside the allowedTools whitelist and improve plain JSON schema handling
1 parent 938afb3 commit f1a2f31

35 files changed

Lines changed: 315 additions & 309 deletions

File tree

apps/e2e/demo-e2e-codecall/e2e/codecall.e2e.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,10 @@ test.describe('CodeCall Plugin E2E', () => {
446446

447447
expect(execResult.result.name).toBe('users-list');
448448
expect(execResult.result.inputType).toBe('object');
449-
// Schema instance internals and methods must not be reachable from the script.
450-
expect(execResult.result.internal).not.toBe('object');
451-
expect(execResult.result.parse).not.toBe('function');
449+
// Plain JSON Schema carries no schema-instance internals or methods, so both reads
450+
// resolve to undefined rather than an object, a function, or a denied access.
451+
expect(execResult.result.internal).toBe('undefined');
452+
expect(execResult.result.parse).toBe('undefined');
452453
});
453454

454455
test('should not reach a host constructor through a tool schema', async ({ mcp }) => {

docs/frontmcp/plugins/codecall/agentscript.mdx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,25 @@ if (result.success) {
6767

6868
### getTool(name)
6969

70-
Get metadata about a tool (name, description, schemas) without calling it.
70+
Get metadata about a tool (name, description, schemas) without calling it. Schemas come back
71+
as plain JSON Schema documents, and are `null` when the tool declares none.
7172

7273
```ts
7374
const meta = getTool('users:list');
7475
console.log(meta.description); // "List users with optional filtering"
7576
console.log(meta.inputSchema); // { type: "object", properties: { ... } }
7677
```
7778

79+
Returns `undefined` when the tool cannot be described — an unknown name, a CodeCall meta-tool
80+
(same rule as [`callTool`](/frontmcp/plugins/codecall/security#self-reference-guard)), or a
81+
tool outside the `allowedTools` whitelist the script was invoked with. Guard the result before
82+
reading from it:
83+
84+
```ts
85+
const meta = getTool('billing:charge');
86+
if (!meta) return { skipped: 'billing:charge is not available to this script' };
87+
```
88+
7889
---
7990

8091
### codecallContext

libs/adapters/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@frontmcp/adapters",
3-
"version": "1.4.0",
3+
"version": "1.5.2",
44
"description": "Adapters for the FrontMCP framework",
55
"author": "AgentFront <info@agentfront.dev>",
66
"homepage": "https://docs.agentfront.dev",
@@ -67,15 +67,15 @@
6767
"node": ">=24.0.0"
6868
},
6969
"dependencies": {
70-
"@frontmcp/auth": "1.4.0",
71-
"@frontmcp/di": "1.4.0",
72-
"@frontmcp/sdk": "1.4.0",
73-
"@frontmcp/utils": "1.4.0",
70+
"@frontmcp/auth": "1.5.2",
71+
"@frontmcp/di": "1.5.2",
72+
"@frontmcp/sdk": "1.5.2",
73+
"@frontmcp/utils": "1.5.2",
7474
"js-yaml": "^4.1.0",
7575
"mcp-from-openapi": "2.5.1",
7676
"openapi-types": "^12.1.3"
7777
},
7878
"peerDependencies": {
79-
"@frontmcp/lazy-zod": "1.4.0"
79+
"@frontmcp/lazy-zod": "1.5.2"
8080
}
8181
}

libs/auth/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@frontmcp/auth",
3-
"version": "1.4.0",
3+
"version": "1.5.2",
44
"description": "FrontMCP Auth - Authentication, session management, and credential vault",
55
"author": "AgentFront <info@agentfront.dev>",
66
"homepage": "https://docs.agentfront.dev",
@@ -48,8 +48,8 @@
4848
"node": ">=24.0.0"
4949
},
5050
"peerDependencies": {
51-
"@frontmcp/lazy-zod": "1.4.0",
52-
"@frontmcp/storage-sqlite": "1.4.0",
51+
"@frontmcp/lazy-zod": "1.5.2",
52+
"@frontmcp/storage-sqlite": "1.5.2",
5353
"@vercel/kv": "^3.0.0",
5454
"ioredis": "^5.0.0"
5555
},
@@ -65,8 +65,8 @@
6565
}
6666
},
6767
"dependencies": {
68-
"@frontmcp/di": "1.4.0",
69-
"@frontmcp/utils": "1.4.0",
68+
"@frontmcp/di": "1.5.2",
69+
"@frontmcp/utils": "1.5.2",
7070
"jose": "^6.0.0"
7171
},
7272
"devDependencies": {

libs/cli/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "frontmcp",
3-
"version": "1.4.0",
3+
"version": "1.5.2",
44
"description": "FrontMCP command line interface",
55
"author": "AgentFront <info@agentfront.dev>",
66
"homepage": "https://docs.agentfront.dev",
@@ -35,9 +35,9 @@
3535
},
3636
"dependencies": {
3737
"@clack/prompts": "^0.10.0",
38-
"@frontmcp/lazy-zod": "1.4.0",
39-
"@frontmcp/skills": "1.4.0",
40-
"@frontmcp/utils": "1.4.0",
38+
"@frontmcp/lazy-zod": "1.5.2",
39+
"@frontmcp/skills": "1.5.2",
40+
"@frontmcp/utils": "1.5.2",
4141
"@rspack/core": "^1.7.6",
4242
"commander": "^13.0.0",
4343
"esbuild": "^0.27.3",

libs/cli/src/commands/package/__tests__/install.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ beforeEach(() => {
7272
fs.mkdirSync(packageDir, { recursive: true });
7373
jest.spyOn(console, 'log').mockImplementation(() => undefined);
7474
jest.clearAllMocks();
75+
// Drop any per-test implementation (the build-from-config case installs one); the other
76+
// mocks keep the implementations their module factories provide.
77+
(runCmd as jest.Mock).mockReset();
7578
});
7679

7780
afterEach(() => {

libs/di/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@frontmcp/di",
3-
"version": "1.4.0",
3+
"version": "1.5.2",
44
"description": "Generic dependency injection container and registry utilities for TypeScript applications",
55
"author": "AgentFront <info@agentfront.dev>",
66
"license": "Apache-2.0",
@@ -48,7 +48,7 @@
4848
"node": ">=24.0.0"
4949
},
5050
"peerDependencies": {
51-
"@frontmcp/lazy-zod": "1.4.0",
51+
"@frontmcp/lazy-zod": "1.5.2",
5252
"reflect-metadata": "^0.2.0"
5353
},
5454
"devDependencies": {

libs/edge/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@frontmcp/edge",
3-
"version": "1.4.0",
3+
"version": "1.5.2",
44
"description": "Run a FrontMCP MCP server on Cloudflare Workers / V8 isolates from a plain config — no decorators, no build step",
55
"author": "AgentFront <info@agentfront.dev>",
66
"license": "Apache-2.0",
@@ -49,8 +49,8 @@
4949
"node": ">=24.0.0"
5050
},
5151
"peerDependencies": {
52-
"@frontmcp/plugin-skilled-openapi": "1.4.0",
53-
"@frontmcp/sdk": "1.4.0"
52+
"@frontmcp/plugin-skilled-openapi": "1.5.2",
53+
"@frontmcp/sdk": "1.5.2"
5454
},
5555
"peerDependenciesMeta": {
5656
"@frontmcp/plugin-skilled-openapi": {

libs/guard/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@frontmcp/guard",
3-
"version": "1.4.0",
3+
"version": "1.5.2",
44
"description": "Rate limiting, concurrency control, timeout, IP filtering, and traffic guard utilities for FrontMCP",
55
"author": "AgentFront <info@agentfront.dev>",
66
"license": "Apache-2.0",
@@ -49,10 +49,10 @@
4949
"node": ">=24.0.0"
5050
},
5151
"dependencies": {
52-
"@frontmcp/utils": "1.4.0"
52+
"@frontmcp/utils": "1.5.2"
5353
},
5454
"peerDependencies": {
55-
"@frontmcp/lazy-zod": "1.4.0"
55+
"@frontmcp/lazy-zod": "1.5.2"
5656
},
5757
"devDependencies": {
5858
"@types/node": "^24.0.0",

libs/lazy-zod/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@frontmcp/lazy-zod",
3-
"version": "1.4.0",
3+
"version": "1.5.2",
44
"description": "Drop-in zod replacement that lazily constructs compound schemas for dramatic cold-start speedups. Exports `z` (lazy, drop-in), `eagerZ` (real zod, zero overhead), and `lazyZ` (explicit factory wrapper).",
55
"author": "AgentFront <info@agentfront.dev>",
66
"license": "Apache-2.0",

0 commit comments

Comments
 (0)