@frontmcp/sdk 0.3.1 → 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/LICENSE +201 -0
- package/README.md +192 -164
- package/package.json +7 -4
- package/src/__test-utils__/fixtures/hook.fixtures.d.ts +46 -0
- package/src/__test-utils__/fixtures/hook.fixtures.js +114 -0
- package/src/__test-utils__/fixtures/hook.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/index.d.ts +7 -0
- package/src/__test-utils__/fixtures/index.js +11 -0
- package/src/__test-utils__/fixtures/index.js.map +1 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.d.ts +46 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.js +127 -0
- package/src/__test-utils__/fixtures/plugin.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/provider.fixtures.d.ts +69 -0
- package/src/__test-utils__/fixtures/provider.fixtures.js +131 -0
- package/src/__test-utils__/fixtures/provider.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/scope.fixtures.d.ts +14 -0
- package/src/__test-utils__/fixtures/scope.fixtures.js +59 -0
- package/src/__test-utils__/fixtures/scope.fixtures.js.map +1 -0
- package/src/__test-utils__/fixtures/tool.fixtures.d.ts +36 -0
- package/src/__test-utils__/fixtures/tool.fixtures.js +91 -0
- package/src/__test-utils__/fixtures/tool.fixtures.js.map +1 -0
- package/src/__test-utils__/helpers/assertion.helpers.d.ts +45 -0
- package/src/__test-utils__/helpers/assertion.helpers.js +153 -0
- package/src/__test-utils__/helpers/assertion.helpers.js.map +1 -0
- package/src/__test-utils__/helpers/async.helpers.d.ts +48 -0
- package/src/__test-utils__/helpers/async.helpers.js +112 -0
- package/src/__test-utils__/helpers/async.helpers.js.map +1 -0
- package/src/__test-utils__/helpers/index.d.ts +6 -0
- package/src/__test-utils__/helpers/index.js +10 -0
- package/src/__test-utils__/helpers/index.js.map +1 -0
- package/src/__test-utils__/helpers/setup.helpers.d.ts +54 -0
- package/src/__test-utils__/helpers/setup.helpers.js +106 -0
- package/src/__test-utils__/helpers/setup.helpers.js.map +1 -0
- package/src/__test-utils__/index.d.ts +9 -0
- package/src/__test-utils__/index.js +14 -0
- package/src/__test-utils__/index.js.map +1 -0
- package/src/__test-utils__/mocks/flow-instance.mock.d.ts +50 -0
- package/src/__test-utils__/mocks/flow-instance.mock.js +72 -0
- package/src/__test-utils__/mocks/flow-instance.mock.js.map +1 -0
- package/src/__test-utils__/mocks/hook-registry.mock.d.ts +25 -0
- package/src/__test-utils__/mocks/hook-registry.mock.js +65 -0
- package/src/__test-utils__/mocks/hook-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/index.d.ts +8 -0
- package/src/__test-utils__/mocks/index.js +12 -0
- package/src/__test-utils__/mocks/index.js.map +1 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.d.ts +43 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.js +70 -0
- package/src/__test-utils__/mocks/plugin-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/provider-registry.mock.d.ts +39 -0
- package/src/__test-utils__/mocks/provider-registry.mock.js +72 -0
- package/src/__test-utils__/mocks/provider-registry.mock.js.map +1 -0
- package/src/__test-utils__/mocks/tool-registry.mock.d.ts +43 -0
- package/src/__test-utils__/mocks/tool-registry.mock.js +79 -0
- package/src/__test-utils__/mocks/tool-registry.mock.js.map +1 -0
- package/src/app/app.utils.js.map +1 -1
- package/src/app/instances/app.local.instance.js +8 -11
- package/src/app/instances/app.local.instance.js.map +1 -1
- package/src/auth/flows/oauth.authorize.flow.d.ts +8 -8
- package/src/auth/flows/oauth.register.flow.d.ts +4 -4
- package/src/auth/flows/oauth.token.flow.d.ts +4 -4
- package/src/auth/flows/well-known.jwks.flow.d.ts +12 -12
- package/src/auth/flows/well-known.oauth-authorization-server.flow.d.ts +8 -8
- package/src/auth/flows/well-known.prm.flow.d.ts +4 -4
- package/src/common/decorators/tool.decorator.d.ts +97 -36
- package/src/common/decorators/tool.decorator.js +0 -1
- package/src/common/decorators/tool.decorator.js.map +1 -1
- package/src/common/entries/tool.entry.d.ts +54 -11
- package/src/common/entries/tool.entry.js +19 -0
- package/src/common/entries/tool.entry.js.map +1 -1
- package/src/common/interfaces/internal/registry.interface.d.ts +10 -2
- package/src/common/interfaces/internal/registry.interface.js.map +1 -1
- package/src/common/interfaces/plugin.interface.d.ts +1 -1
- package/src/common/interfaces/plugin.interface.js.map +1 -1
- package/src/common/interfaces/tool.interface.d.ts +12 -7
- package/src/common/interfaces/tool.interface.js +1 -1
- package/src/common/interfaces/tool.interface.js.map +1 -1
- package/src/common/metadata/front-mcp.metadata.d.ts +145 -145
- package/src/common/metadata/hook.metadata.d.ts +4 -2
- package/src/common/metadata/hook.metadata.js.map +1 -1
- package/src/common/metadata/prompt.metadata.d.ts +28 -28
- package/src/common/metadata/prompt.metadata.js.map +1 -1
- package/src/common/metadata/resource.metadata.d.ts +54 -54
- package/src/common/metadata/tool.metadata.d.ts +190 -7
- package/src/common/metadata/tool.metadata.js +41 -6
- package/src/common/metadata/tool.metadata.js.map +1 -1
- package/src/common/schemas/http-output.schema.d.ts +106 -106
- package/src/common/tokens/tool.tokens.js.map +1 -1
- package/src/common/types/options/logging.options.d.ts +1 -2
- package/src/common/types/options/logging.options.js +1 -9
- package/src/common/types/options/logging.options.js.map +1 -1
- package/src/common/types/options/server-info.options.d.ts +19 -19
- package/src/errors/error-handler.d.ts +65 -0
- package/src/errors/error-handler.js +107 -0
- package/src/errors/error-handler.js.map +1 -0
- package/src/errors/index.d.ts +2 -0
- package/src/errors/index.js +26 -0
- package/src/errors/index.js.map +1 -0
- package/src/errors/mcp.error.d.ts +156 -0
- package/src/errors/mcp.error.js +243 -0
- package/src/errors/mcp.error.js.map +1 -0
- package/src/flows/flow.instance.js +7 -6
- package/src/flows/flow.instance.js.map +1 -1
- package/src/flows/flow.registry.js +1 -1
- package/src/flows/flow.registry.js.map +1 -1
- package/src/front-mcp/front-mcp.providers.d.ts +20 -20
- package/src/hooks/hook.registry.d.ts +5 -3
- package/src/hooks/hook.registry.js +13 -1
- package/src/hooks/hook.registry.js.map +1 -1
- package/src/plugin/plugin.registry.d.ts +7 -2
- package/src/plugin/plugin.registry.js +23 -11
- package/src/plugin/plugin.registry.js.map +1 -1
- package/src/prompt/prompt.registry.js +1 -0
- package/src/prompt/prompt.registry.js.map +1 -1
- package/src/resource/resource.registry.js +1 -0
- package/src/resource/resource.registry.js.map +1 -1
- package/src/scope/scope.registry.js +1 -1
- package/src/scope/scope.registry.js.map +1 -1
- package/src/store/adapters/store.memory.adapter.js +3 -1
- package/src/store/adapters/store.memory.adapter.js.map +1 -1
- package/src/tool/flows/call-tool.flow.d.ts +1012 -676
- package/src/tool/flows/call-tool.flow.js +94 -61
- package/src/tool/flows/call-tool.flow.js.map +1 -1
- package/src/tool/flows/tools-list.flow.d.ts +347 -590
- package/src/tool/flows/tools-list.flow.js +76 -49
- package/src/tool/flows/tools-list.flow.js.map +1 -1
- package/src/tool/tool.instance.d.ts +27 -8
- package/src/tool/tool.instance.js +40 -5
- package/src/tool/tool.instance.js.map +1 -1
- package/src/tool/tool.registry.js +19 -21
- package/src/tool/tool.registry.js.map +1 -1
- package/src/tool/tool.utils.d.ts +3 -2
- package/src/tool/tool.utils.js +377 -14
- package/src/tool/tool.utils.js.map +1 -1
- package/src/transport/adapters/transport.sse.adapter.js.map +1 -1
- package/src/transport/adapters/transport.streamable-http.adapter.js.map +1 -1
- package/src/transport/flows/handle.sse.flow.js +6 -13
- package/src/transport/flows/handle.sse.flow.js.map +1 -1
- package/src/transport/flows/handle.streamable-http.flow.js +1 -0
- package/src/transport/flows/handle.streamable-http.flow.js.map +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.d.ts +1 -1
- package/src/transport/mcp-handlers/call-tool-request.handler.js +10 -5
- package/src/transport/mcp-handlers/call-tool-request.handler.js.map +1 -1
- package/src/transport/mcp-handlers/index.d.ts +151 -268
- package/src/transport/mcp-handlers/list-tools-request.handler.d.ts +124 -216
- package/src/transport/transport.local.js +1 -0
- package/src/transport/transport.local.js.map +1 -1
- package/src/utils/string.utils.js +1 -1
- package/src/utils/string.utils.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<picture>
|
|
4
|
+
<source width="400" media="(prefers-color-scheme: dark)" srcset="docs/assets/logo/frontmcp.dark.svg">
|
|
5
|
+
<source width="400" media="(prefers-color-scheme: light)" srcset="docs/assets/logo/frontmcp.light.svg">
|
|
6
|
+
<img width="400" alt="FrontMCP Logo" src="docs/assets/logo/frontmcp.light.svg">
|
|
7
|
+
</picture>
|
|
8
|
+
<hr>
|
|
4
9
|
|
|
5
|
-
<strong>The TypeScript
|
|
10
|
+
<strong>The TypeScript way to build MCP servers with decorators, DI, and Streamable HTTP.</strong>
|
|
6
11
|
|
|
7
12
|
_Made with ❤️ for TypeScript developers_
|
|
8
13
|
|
|
9
14
|
[](https://www.npmjs.com/package/@frontmcp/sdk)
|
|
10
|
-
[](https://nodejs.org)
|
|
11
16
|
[](https://github.com/agentfront/frontmcp/blob/main/LICENSE)
|
|
12
17
|
|
|
13
18
|
</div>
|
|
@@ -15,18 +20,18 @@ _Made with ❤️ for TypeScript developers_
|
|
|
15
20
|
---
|
|
16
21
|
|
|
17
22
|
FrontMCP is a **TypeScript-first framework** for the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
|
|
18
|
-
You
|
|
19
|
-
session/auth, and execution flow.
|
|
23
|
+
You write clean, typed code; FrontMCP handles the protocol, transport, DI, session/auth, and execution flow.
|
|
20
24
|
|
|
21
25
|
```ts
|
|
22
26
|
// src/main.ts
|
|
27
|
+
import 'reflect-metadata';
|
|
23
28
|
import { FrontMcp, LogLevel } from '@frontmcp/sdk';
|
|
24
29
|
import HelloApp from './hello.app';
|
|
25
30
|
|
|
26
31
|
@FrontMcp({
|
|
27
32
|
info: { name: 'Demo 🚀', version: '0.1.0' },
|
|
28
33
|
apps: [HelloApp],
|
|
29
|
-
http: { port:
|
|
34
|
+
http: { port: 3000 },
|
|
30
35
|
logging: { level: LogLevel.Info },
|
|
31
36
|
})
|
|
32
37
|
export default class Server {}
|
|
@@ -41,24 +46,24 @@ export default class Server {}
|
|
|
41
46
|
- [Why FrontMCP?](#why-frontmcp)
|
|
42
47
|
- [Installation](#installation)
|
|
43
48
|
- [Quickstart](#quickstart)
|
|
44
|
-
- [
|
|
49
|
+
- [1) Create Your FrontMCP Server](#1-create-your-frontmcp-server)
|
|
50
|
+
- [2) Define an App](#2-define-an-app)
|
|
51
|
+
- [3) Add Your First Tool](#3-add-your-first-tool)
|
|
52
|
+
- [4) Run It](#4-run-it)
|
|
45
53
|
- [Function and Class Tools](#function-and-class-tools)
|
|
46
54
|
- [Scripts & tsconfig](#scripts--tsconfig)
|
|
47
|
-
- [
|
|
55
|
+
- [Inspector](#inspector)
|
|
48
56
|
- [Core Concepts](#core-concepts)
|
|
49
57
|
- [Servers](#servers)
|
|
50
58
|
- [Apps](#apps)
|
|
51
59
|
- [Tools](#tools)
|
|
52
60
|
- [Resources](#resources)
|
|
53
61
|
- [Prompts](#prompts)
|
|
54
|
-
- [Providers](#providers)
|
|
55
|
-
- [Adapters](#adapters)
|
|
56
|
-
- [Plugins](#plugins)
|
|
62
|
+
- [Providers / Adapters / Plugins](#providers--adapters--plugins)
|
|
57
63
|
- [Authentication](#authentication)
|
|
58
64
|
- [Remote OAuth](#remote-oauth)
|
|
59
65
|
- [Local OAuth](#local-oauth)
|
|
60
66
|
- [Sessions & Transport](#sessions--transport)
|
|
61
|
-
- [Logging Transports](#logging-transports)
|
|
62
67
|
- [Deployment](#deployment)
|
|
63
68
|
- [Local Dev](#local-dev)
|
|
64
69
|
- [Production](#production)
|
|
@@ -70,73 +75,121 @@ export default class Server {}
|
|
|
70
75
|
|
|
71
76
|
## Why FrontMCP?
|
|
72
77
|
|
|
73
|
-
- **TypeScript-native DX** — decorators, Zod
|
|
74
|
-
- **Spec-aligned transports** — Streamable HTTP (GET/POST), streaming, sessions
|
|
78
|
+
- **TypeScript-native DX** — decorators, Zod, and strong typing end-to-end
|
|
75
79
|
- **Scoped invoker + DI** — secure, composable execution with hooks
|
|
76
|
-
- **Adapters & Plugins** —
|
|
77
|
-
- **
|
|
78
|
-
- **Logging** — pluggable log transports (console, JSONL, HTTP batch, …)
|
|
80
|
+
- **Adapters & Plugins** — extend your server without boilerplate
|
|
81
|
+
- **Spec-aligned transport** — Streamable HTTP for modern MCP clients
|
|
79
82
|
|
|
80
83
|
---
|
|
81
84
|
|
|
82
85
|
## Installation
|
|
83
86
|
|
|
84
|
-
|
|
87
|
+
**Prereqs:** Node.js ≥ 22, npm ≥ 10. ([Installation - FrontMCP][1])
|
|
88
|
+
|
|
89
|
+
### Option A — New project (recommended)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx frontmcp create my-app
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This scaffolds a FrontMCP project, writes a modern ESM `tsconfig.json` for decorators, adds helpful package scripts, and
|
|
96
|
+
installs required dev deps. ([Installation - FrontMCP][1])
|
|
97
|
+
|
|
98
|
+
### Option B — Add to an existing project
|
|
85
99
|
|
|
86
100
|
```bash
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
npm install -D typescript tsx @types/node rimraf @modelcontextprotocol/inspector
|
|
101
|
+
npm i -D frontmcp @types/node@^20
|
|
102
|
+
npx frontmcp init
|
|
90
103
|
```
|
|
91
104
|
|
|
92
|
-
|
|
105
|
+
`init` adds scripts, verifies your `tsconfig.json`, and checks layout. No need to install `@frontmcp/sdk` directly—the
|
|
106
|
+
CLI bundles a compatible SDK for you. ([Installation - FrontMCP][1])
|
|
93
107
|
|
|
94
108
|
---
|
|
95
109
|
|
|
96
110
|
## Quickstart
|
|
97
111
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
src/
|
|
102
|
-
main.ts
|
|
103
|
-
hello.app.ts
|
|
104
|
-
tools/
|
|
105
|
-
greet.tool.ts
|
|
106
|
-
```
|
|
112
|
+
If you haven’t installed FrontMCP yet, follow the [installation guide][1] first.
|
|
107
113
|
|
|
108
|
-
|
|
114
|
+
### 1) Create Your FrontMCP Server
|
|
109
115
|
|
|
110
116
|
```ts
|
|
111
|
-
|
|
117
|
+
// src/main.ts
|
|
112
118
|
import { FrontMcp, LogLevel } from '@frontmcp/sdk';
|
|
113
119
|
import HelloApp from './hello.app';
|
|
114
120
|
|
|
115
121
|
@FrontMcp({
|
|
116
122
|
info: { name: 'Hello MCP', version: '0.1.0' },
|
|
117
123
|
apps: [HelloApp],
|
|
118
|
-
http: { port:
|
|
119
|
-
logging: { level: LogLevel.
|
|
124
|
+
http: { port: 3000 },
|
|
125
|
+
logging: { level: LogLevel.INFO },
|
|
120
126
|
})
|
|
121
|
-
export default class
|
|
127
|
+
export default class HelloServer {}
|
|
122
128
|
```
|
|
123
129
|
|
|
124
|
-
|
|
130
|
+
### 2) Define an App
|
|
125
131
|
|
|
126
132
|
```ts
|
|
133
|
+
// src/hello.app.ts
|
|
127
134
|
import { App } from '@frontmcp/sdk';
|
|
128
135
|
import GreetTool from './tools/greet.tool';
|
|
129
136
|
|
|
130
137
|
@App({
|
|
131
138
|
id: 'hello',
|
|
132
|
-
name: 'Hello',
|
|
139
|
+
name: 'Hello App',
|
|
133
140
|
tools: [GreetTool],
|
|
134
141
|
})
|
|
135
142
|
export default class HelloApp {}
|
|
136
143
|
```
|
|
137
144
|
|
|
145
|
+
### 3) Add Your First Tool
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
// src/tools/greet.tool.ts
|
|
149
|
+
import { Tool } from '@frontmcp/sdk';
|
|
150
|
+
import { z } from 'zod';
|
|
151
|
+
|
|
152
|
+
@Tool({
|
|
153
|
+
name: 'greet',
|
|
154
|
+
description: 'Greets a user by name',
|
|
155
|
+
inputSchema: { name: z.string() },
|
|
156
|
+
})
|
|
157
|
+
export default class GreetTool {
|
|
158
|
+
async execute({ name }: { name: string }) {
|
|
159
|
+
return `Hello, ${name}!`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 4) Run It
|
|
165
|
+
|
|
166
|
+
Add scripts (if you didn't use `frontmcp create`):
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"scripts": {
|
|
171
|
+
"dev": "frontmcp dev",
|
|
172
|
+
"build": "frontmcp build",
|
|
173
|
+
"start": "node dist/main.js"
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Then:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
npm run dev
|
|
182
|
+
# Server listening on http://localhost:3000
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
> **Tip:** FrontMCP speaks **MCP Streamable HTTP**. Connect any MCP-capable client and call `greet` with
|
|
186
|
+
> `{"name": "Ada"}`. ([Quickstart - FrontMCP][2])
|
|
187
|
+
|
|
138
188
|
### Function and Class Tools
|
|
139
189
|
|
|
190
|
+
Tools are typed actions with Zod schemas. Implement them as classes with `@Tool({...})` or inline via `tool()`. Pass
|
|
191
|
+
**Zod fields directly** (no `z.object({...})`). ([Tools - FrontMCP][4])
|
|
192
|
+
|
|
140
193
|
**Function tool**
|
|
141
194
|
|
|
142
195
|
```ts
|
|
@@ -146,7 +199,7 @@ import { z } from 'zod';
|
|
|
146
199
|
export default tool({
|
|
147
200
|
name: 'greet',
|
|
148
201
|
description: 'Greets a user by name',
|
|
149
|
-
inputSchema:
|
|
202
|
+
inputSchema: { name: z.string() }, // shape, not z.object
|
|
150
203
|
})(({ name }) => `Hello, ${name}!`);
|
|
151
204
|
```
|
|
152
205
|
|
|
@@ -159,10 +212,10 @@ import { z } from 'zod';
|
|
|
159
212
|
@Tool({
|
|
160
213
|
name: 'add',
|
|
161
214
|
description: 'Add two numbers',
|
|
162
|
-
inputSchema:
|
|
215
|
+
inputSchema: { a: z.number(), b: z.number() },
|
|
163
216
|
})
|
|
164
217
|
export default class AddTool {
|
|
165
|
-
execute({ a, b }: { a: number; b: number }) {
|
|
218
|
+
async execute({ a, b }: { a: number; b: number }) {
|
|
166
219
|
return a + b;
|
|
167
220
|
}
|
|
168
221
|
}
|
|
@@ -170,22 +223,37 @@ export default class AddTool {
|
|
|
170
223
|
|
|
171
224
|
### Scripts & tsconfig
|
|
172
225
|
|
|
173
|
-
|
|
226
|
+
After `create` or `init`, you’ll have:
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"scripts": {
|
|
231
|
+
"dev": "frontmcp dev",
|
|
232
|
+
"build": "frontmcp build",
|
|
233
|
+
"inspect": "frontmcp inspector",
|
|
234
|
+
"doctor": "frontmcp doctor"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
These map to dev watch, production build, zero‑setup Inspector launch, and environment checks. ([Installation -
|
|
240
|
+
FrontMCP][1])
|
|
241
|
+
|
|
242
|
+
**Recommended `tsconfig.json` (ESM + decorators)**
|
|
174
243
|
|
|
175
244
|
```json
|
|
176
245
|
{
|
|
177
246
|
"compilerOptions": {
|
|
178
|
-
"target": "
|
|
179
|
-
"module": "
|
|
180
|
-
"lib": ["
|
|
247
|
+
"target": "es2021",
|
|
248
|
+
"module": "esnext",
|
|
249
|
+
"lib": ["es2021"],
|
|
250
|
+
"moduleResolution": "bundler",
|
|
181
251
|
"rootDir": "src",
|
|
182
252
|
"outDir": "dist",
|
|
183
|
-
"moduleResolution": "Node",
|
|
184
253
|
"strict": true,
|
|
185
254
|
"esModuleInterop": true,
|
|
186
|
-
"forceConsistentCasingInFileNames": true,
|
|
187
|
-
"skipLibCheck": true,
|
|
188
255
|
"resolveJsonModule": true,
|
|
256
|
+
"skipLibCheck": true,
|
|
189
257
|
"experimentalDecorators": true,
|
|
190
258
|
"emitDecoratorMetadata": true,
|
|
191
259
|
"sourceMap": true
|
|
@@ -195,7 +263,9 @@ export default class AddTool {
|
|
|
195
263
|
}
|
|
196
264
|
```
|
|
197
265
|
|
|
198
|
-
|
|
266
|
+
This mirrors what `init` writes for you. ([Local Dev Server - FrontMCP][3])
|
|
267
|
+
|
|
268
|
+
**Optional `tsconfig.build.json`**
|
|
199
269
|
|
|
200
270
|
```json
|
|
201
271
|
{
|
|
@@ -208,79 +278,55 @@ export default class AddTool {
|
|
|
208
278
|
}
|
|
209
279
|
```
|
|
210
280
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
```json
|
|
214
|
-
{
|
|
215
|
-
"scripts": {
|
|
216
|
-
"dev": "tsx watch src/main.ts",
|
|
217
|
-
"start:dev": "tsx src/main.ts",
|
|
218
|
-
"build": "tsc -p tsconfig.build.json",
|
|
219
|
-
"start": "node dist/main.js",
|
|
220
|
-
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
221
|
-
"clean": "rimraf dist",
|
|
222
|
-
"inspect:dev": "npx @modelcontextprotocol/inspector tsx src/main.ts",
|
|
223
|
-
"inspect:dist": "npx @modelcontextprotocol/inspector node dist/main.js"
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
> Always import **`reflect-metadata` first** in your entry to enable decorator metadata.
|
|
229
|
-
|
|
230
|
-
### MCP Inspector
|
|
281
|
+
### Inspector
|
|
231
282
|
|
|
232
|
-
|
|
283
|
+
Run a browser UI to exercise tools and messages:
|
|
233
284
|
|
|
234
285
|
```bash
|
|
235
|
-
|
|
236
|
-
npm run inspect:dev
|
|
237
|
-
# Dist (runs built JS)
|
|
238
|
-
npm run inspect:dist
|
|
286
|
+
npm run inspect
|
|
239
287
|
```
|
|
240
288
|
|
|
289
|
+
This launches the MCP Inspector; point it at your local server (e.g., `http://localhost:3000`). ([Local Dev Server -
|
|
290
|
+
FrontMCP][3])
|
|
291
|
+
|
|
241
292
|
---
|
|
242
293
|
|
|
243
294
|
## Core Concepts
|
|
244
295
|
|
|
245
296
|
### Servers
|
|
246
297
|
|
|
247
|
-
|
|
248
|
-
|
|
298
|
+
`@FrontMcp({...})` defines **info**, **apps**, **http**, **logging**, **session**, and optional **auth**. Keep it
|
|
299
|
+
minimal or scale up with providers and plugins. ([The FrontMCP Server - FrontMCP][5])
|
|
249
300
|
|
|
250
301
|
### Apps
|
|
251
302
|
|
|
252
|
-
Use `@App` to group **tools**, **resources**, **prompts**, **providers**, **adapters**, and **plugins**. With
|
|
253
|
-
`splitByApp: true`, each app
|
|
303
|
+
Use `@App` to group **tools**, **resources**, **prompts**, plus **providers**, **adapters**, and **plugins**. With
|
|
304
|
+
`splitByApp: true`, each app gets its own scope/base path and, if needed, its own auth surface. ([Apps - FrontMCP][6])
|
|
254
305
|
|
|
255
306
|
### Tools
|
|
256
307
|
|
|
257
|
-
|
|
308
|
+
Typed actions with schemas (class `@Tool` or inline `tool({...})(handler)`). Use the Zod‑field **shape** style for
|
|
309
|
+
`inputSchema`. ([Tools - FrontMCP][4])
|
|
258
310
|
|
|
259
311
|
### Resources
|
|
260
312
|
|
|
261
|
-
|
|
313
|
+
Readable data by URI or RFC6570 template (see `@Resource` / `@ResourceTemplate`). ([Resources - FrontMCP][7])
|
|
262
314
|
|
|
263
315
|
### Prompts
|
|
264
316
|
|
|
265
|
-
Reusable
|
|
317
|
+
Reusable templates returning MCP `GetPromptResult`, with typed arguments. ([Prompts - FrontMCP][8])
|
|
266
318
|
|
|
267
|
-
### Providers
|
|
319
|
+
### Providers / Adapters / Plugins
|
|
268
320
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
### Adapters
|
|
272
|
-
|
|
273
|
-
Generate tools/resources/prompts from external definitions (e.g., **OpenAPI**).
|
|
274
|
-
|
|
275
|
-
### Plugins
|
|
276
|
-
|
|
277
|
-
Cross-cutting behavior (caching, tracing, policy). Plugins can contribute providers/adapters/tools/resources/prompts.
|
|
321
|
+
Inject shared services, generate tools from OpenAPI, and add cross‑cutting behavior like caching and hooks. ([Add
|
|
322
|
+
OpenAPI Adapter - FrontMCP][9])
|
|
278
323
|
|
|
279
324
|
---
|
|
280
325
|
|
|
281
326
|
## Authentication
|
|
282
327
|
|
|
283
|
-
|
|
328
|
+
Configure auth at the **server** (shared) or **per app** (isolated). With `splitByApp: true`, define auth **per app**
|
|
329
|
+
(server‑level `auth` is disallowed). ([Authentication - FrontMCP][10])
|
|
284
330
|
|
|
285
331
|
### Remote OAuth
|
|
286
332
|
|
|
@@ -289,26 +335,27 @@ auth: {
|
|
|
289
335
|
type: 'remote',
|
|
290
336
|
name: 'frontegg',
|
|
291
337
|
baseUrl: 'https://idp.example.com',
|
|
292
|
-
dcrEnabled
|
|
293
|
-
clientId
|
|
294
|
-
mode
|
|
295
|
-
allowAnonymous
|
|
296
|
-
consent
|
|
297
|
-
scopes
|
|
298
|
-
grantTypes
|
|
299
|
-
authEndpoint
|
|
300
|
-
tokenEndpoint
|
|
301
|
-
registrationEndpoint
|
|
302
|
-
userInfoEndpoint
|
|
303
|
-
jwks
|
|
304
|
-
jwksUri
|
|
338
|
+
dcrEnabled?: boolean,
|
|
339
|
+
clientId?: string | ((info: { clientId: string }) => string),
|
|
340
|
+
mode?: 'orchestrated' | 'transparent',
|
|
341
|
+
allowAnonymous?: boolean,
|
|
342
|
+
consent?: boolean,
|
|
343
|
+
scopes?: string[],
|
|
344
|
+
grantTypes?: ('authorization_code' | 'refresh_token')[],
|
|
345
|
+
authEndpoint?: string,
|
|
346
|
+
tokenEndpoint?: string,
|
|
347
|
+
registrationEndpoint?: string,
|
|
348
|
+
userInfoEndpoint?: string,
|
|
349
|
+
jwks?: JSONWebKeySet,
|
|
350
|
+
jwksUri?: string
|
|
305
351
|
}
|
|
306
352
|
```
|
|
307
353
|
|
|
354
|
+
See **Authentication → Remote OAuth** for full details and DCR vs non‑DCR. ([Remote OAuth - FrontMCP][11])
|
|
355
|
+
|
|
308
356
|
### Local OAuth
|
|
309
357
|
|
|
310
358
|
```ts
|
|
311
|
-
{
|
|
312
359
|
auth: {
|
|
313
360
|
type: 'local',
|
|
314
361
|
id: 'local',
|
|
@@ -322,7 +369,7 @@ auth: {
|
|
|
322
369
|
}
|
|
323
370
|
```
|
|
324
371
|
|
|
325
|
-
|
|
372
|
+
Use per‑app when isolating scopes. ([Local OAuth - FrontMCP][12])
|
|
326
373
|
|
|
327
374
|
---
|
|
328
375
|
|
|
@@ -330,91 +377,72 @@ auth: {
|
|
|
330
377
|
|
|
331
378
|
```ts
|
|
332
379
|
session: {
|
|
333
|
-
sessionMode
|
|
334
|
-
...),
|
|
335
|
-
transportIdMode ? : 'uuid' | 'jwt' | ((issuer) =>
|
|
336
|
-
...), // default 'uuid'
|
|
380
|
+
sessionMode?: 'stateful' | 'stateless' | ((issuer) => ...), // default 'stateless'
|
|
381
|
+
transportIdMode?: 'uuid' | 'jwt' | ((issuer) => ...), // default 'uuid'
|
|
337
382
|
}
|
|
338
383
|
```
|
|
339
384
|
|
|
340
|
-
- **Stateful**: server
|
|
341
|
-
- **Stateless**:
|
|
342
|
-
- **Transport IDs**: `uuid` (per node) or `jwt` (signed; distributed setups).
|
|
385
|
+
- **Stateful**: server‑side store (e.g., Redis); supports refresh; best for short‑lived upstream tokens.
|
|
386
|
+
- **Stateless**: embeds session in JWT; simpler but no silent refresh.
|
|
387
|
+
- **Transport IDs**: `uuid` (per node) or `jwt` (signed; distributed setups). ([The FrontMCP Server - FrontMCP][5])
|
|
343
388
|
|
|
344
389
|
---
|
|
345
390
|
|
|
346
|
-
##
|
|
347
|
-
|
|
348
|
-
Add custom log sinks via `@LogTransport`:
|
|
349
|
-
|
|
350
|
-
```ts
|
|
351
|
-
import { LogTransport, LogTransportInterface, LogRecord } from '@frontmcp/sdk';
|
|
352
|
-
|
|
353
|
-
@LogTransport({ name: 'StructuredJson', description: 'JSONL to stdout' })
|
|
354
|
-
export class StructuredJsonTransport extends LogTransportInterface {
|
|
355
|
-
log(rec: LogRecord): void {
|
|
356
|
-
try {
|
|
357
|
-
process.stdout.write(
|
|
358
|
-
JSON.stringify({
|
|
359
|
-
ts: rec.timestamp.toISOString(),
|
|
360
|
-
level: rec.levelName,
|
|
361
|
-
msg: String(rec.message),
|
|
362
|
-
prefix: rec.prefix || undefined,
|
|
363
|
-
args: (rec.args || []).map(String),
|
|
364
|
-
}) + '\n',
|
|
365
|
-
);
|
|
366
|
-
} catch {}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
```
|
|
391
|
+
## Deployment
|
|
370
392
|
|
|
371
|
-
|
|
393
|
+
### Local Dev
|
|
372
394
|
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
level: LogLevel.Info,
|
|
376
|
-
enableConsole: false,
|
|
377
|
-
transports : [StructuredJsonTransport],
|
|
378
|
-
}
|
|
395
|
+
```bash
|
|
396
|
+
npm run dev
|
|
379
397
|
```
|
|
380
398
|
|
|
381
|
-
|
|
399
|
+
- Default HTTP port: `3000` unless configured
|
|
400
|
+
- `npm run doctor` checks Node/npm versions, `tsconfig`, and scripts. ([Local Dev Server - FrontMCP][3])
|
|
382
401
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
### Local Dev
|
|
402
|
+
### Production
|
|
386
403
|
|
|
387
404
|
```bash
|
|
388
|
-
|
|
389
|
-
npm
|
|
390
|
-
# yarn
|
|
391
|
-
yarn dev
|
|
392
|
-
# pnpm
|
|
393
|
-
pnpm dev
|
|
405
|
+
npm run build
|
|
406
|
+
NODE_ENV=production PORT=8080 npm start
|
|
394
407
|
```
|
|
395
408
|
|
|
396
|
-
|
|
397
|
-
|
|
409
|
+
Builds to `dist/` (uses `tsconfig.build.json`). Consider a process manager and reverse proxy; align all `@frontmcp/*`
|
|
410
|
+
versions. ([Production Build - FrontMCP][13])
|
|
398
411
|
|
|
399
412
|
---
|
|
400
413
|
|
|
401
414
|
## Version Alignment
|
|
402
415
|
|
|
403
|
-
If versions drift, the runtime
|
|
404
|
-
|
|
416
|
+
If versions drift, the runtime will throw a clear **“version mismatch”** at boot. Keep `@frontmcp/*` versions aligned.
|
|
417
|
+
([Production Build - FrontMCP][13])
|
|
405
418
|
|
|
406
419
|
---
|
|
407
420
|
|
|
408
421
|
## Contributing
|
|
409
422
|
|
|
410
|
-
PRs welcome!
|
|
411
|
-
|
|
412
|
-
- Keep changes focused and
|
|
413
|
-
-
|
|
414
|
-
|
|
423
|
+
- PRs welcome! Read the full [CONTRIBUTING.md](./CONTRIBUTING.md) for workflow details, coding standards, and the PR
|
|
424
|
+
checklist.
|
|
425
|
+
- Keep changes focused, add/adjust Jest specs, and update docs/snippets when behavior changes.
|
|
426
|
+
- Before opening a PR run `yarn nx run-many -t lint,test,build`, `npx frontmcp doctor`, and verify the demo/Inspector
|
|
427
|
+
flows relevant to your change.
|
|
428
|
+
- Align `@frontmcp/*` versions in examples to avoid runtime version mismatches.
|
|
415
429
|
|
|
416
430
|
---
|
|
417
431
|
|
|
418
432
|
## License
|
|
419
433
|
|
|
420
434
|
See [LICENSE](./LICENSE).
|
|
435
|
+
|
|
436
|
+
[1]: https://docs.agentfront.dev/docs/getting-started/installation 'Installation - FrontMCP'
|
|
437
|
+
[2]: https://docs.agentfront.dev/docs/getting-started/quickstart 'Quickstart - FrontMCP'
|
|
438
|
+
[3]: https://docs.agentfront.dev/docs/deployment/local-dev-server 'Local Dev Server - FrontMCP'
|
|
439
|
+
[4]: https://docs.agentfront.dev/docs/servers/tools 'Tools - FrontMCP'
|
|
440
|
+
[5]: https://docs.agentfront.dev/docs/servers/server 'The FrontMCP Server - FrontMCP'
|
|
441
|
+
[6]: https://docs.agentfront.dev/docs/servers/apps 'Apps - FrontMCP'
|
|
442
|
+
[7]: https://docs.agentfront.dev/docs/servers/resources 'Resources - FrontMCP'
|
|
443
|
+
[8]: https://docs.agentfront.dev/docs/servers/prompts 'Prompts - FrontMCP'
|
|
444
|
+
[9]: https://docs.agentfront.dev/docs/guides/add-openapi-adapter 'Add OpenAPI Adapter - FrontMCP'
|
|
445
|
+
[10]: https://docs.agentfront.dev/docs/servers/authentication/overview 'Authentication - FrontMCP'
|
|
446
|
+
[11]: https://docs.agentfront.dev/docs/servers/authentication/remote 'Remote OAuth - FrontMCP'
|
|
447
|
+
[12]: https://docs.agentfront.dev/docs/servers/authentication/local 'Local OAuth - FrontMCP'
|
|
448
|
+
[13]: https://docs.agentfront.dev/docs/deployment/production-build 'Production Build - FrontMCP'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontmcp/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "FrontMCP SDK",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -33,16 +33,19 @@
|
|
|
33
33
|
"default": "./src/index.js"
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"zod": "^3.25.76"
|
|
38
|
+
},
|
|
36
39
|
"dependencies": {
|
|
37
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
38
41
|
"axios": "^1.6.0",
|
|
39
42
|
"ioredis": "^5.8.0",
|
|
40
43
|
"jose": "^6.1.0",
|
|
41
44
|
"openapi-mcp-generator": "^3.2.0",
|
|
42
45
|
"reflect-metadata": "^0.2.2",
|
|
43
46
|
"rxjs": "^7.8.0",
|
|
44
|
-
"
|
|
45
|
-
"zod-to-json-schema": "^3.
|
|
47
|
+
"json-schema-to-zod-v3": "1.0.0",
|
|
48
|
+
"zod-to-json-schema": "^3.25.0",
|
|
46
49
|
"tslib": "^2.3.0"
|
|
47
50
|
},
|
|
48
51
|
"devDependencies": {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test fixtures for hooks
|
|
3
|
+
*/
|
|
4
|
+
import { HookMetadata } from '../../common/metadata';
|
|
5
|
+
import { Token } from '../../common/interfaces';
|
|
6
|
+
/**
|
|
7
|
+
* Test token for hook target
|
|
8
|
+
*/
|
|
9
|
+
export declare const TEST_HOOK_TARGET: Token;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a simple hook metadata object
|
|
12
|
+
*/
|
|
13
|
+
export declare function createHookMetadata(overrides?: Partial<HookMetadata>): HookMetadata;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a "will" stage hook metadata
|
|
16
|
+
*/
|
|
17
|
+
export declare function createWillHookMetadata(flow?: string, stage?: string): HookMetadata;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a "did" stage hook metadata
|
|
20
|
+
*/
|
|
21
|
+
export declare function createDidHookMetadata(flow?: string, stage?: string): HookMetadata;
|
|
22
|
+
/**
|
|
23
|
+
* Creates an "around" stage hook metadata
|
|
24
|
+
*/
|
|
25
|
+
export declare function createAroundHookMetadata(flow?: string, stage?: string): HookMetadata;
|
|
26
|
+
/**
|
|
27
|
+
* Mock hook class for testing
|
|
28
|
+
*/
|
|
29
|
+
export declare class MockHookClass {
|
|
30
|
+
onExecute: jest.Mock<Promise<void>, [ctx: any], any>;
|
|
31
|
+
willExecute: jest.Mock<Promise<void>, [ctx: any], any>;
|
|
32
|
+
didExecute: jest.Mock<Promise<void>, [ctx: any], any>;
|
|
33
|
+
aroundExecute: jest.Mock<Promise<any>, [ctx: any, next: () => Promise<any>], any>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates a mock hook instance for testing
|
|
37
|
+
*/
|
|
38
|
+
export declare function createMockHookInstance(metadata?: Partial<HookMetadata>): {
|
|
39
|
+
metadata: HookMetadata<keyof ExtendFlows, string, any>;
|
|
40
|
+
instance: MockHookClass;
|
|
41
|
+
execute: jest.Mock<Promise<void>, [ctx: any], any>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Creates multiple hooks with different priorities
|
|
45
|
+
*/
|
|
46
|
+
export declare function createPriorityHooks(priorities: number[]): HookMetadata[];
|