fridayy 1.0.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 +21 -0
- package/README.md +283 -0
- package/bin/fridayy.js +12 -0
- package/dist/adapters/base.d.ts +40 -0
- package/dist/adapters/base.d.ts.map +1 -0
- package/dist/adapters/base.js +7 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/manual/adapter.d.ts +18 -0
- package/dist/adapters/manual/adapter.d.ts.map +1 -0
- package/dist/adapters/manual/adapter.js +52 -0
- package/dist/adapters/manual/adapter.js.map +1 -0
- package/dist/adapters/nodejs/adapter.d.ts +19 -0
- package/dist/adapters/nodejs/adapter.d.ts.map +1 -0
- package/dist/adapters/nodejs/adapter.js +135 -0
- package/dist/adapters/nodejs/adapter.js.map +1 -0
- package/dist/adapters/nodejs/ast-scanner.d.ts +21 -0
- package/dist/adapters/nodejs/ast-scanner.d.ts.map +1 -0
- package/dist/adapters/nodejs/ast-scanner.js +102 -0
- package/dist/adapters/nodejs/ast-scanner.js.map +1 -0
- package/dist/adapters/openapi/adapter.d.ts +22 -0
- package/dist/adapters/openapi/adapter.d.ts.map +1 -0
- package/dist/adapters/openapi/adapter.js +271 -0
- package/dist/adapters/openapi/adapter.js.map +1 -0
- package/dist/adapters/openapi/parser.d.ts +30 -0
- package/dist/adapters/openapi/parser.d.ts.map +1 -0
- package/dist/adapters/openapi/parser.js +136 -0
- package/dist/adapters/openapi/parser.js.map +1 -0
- package/dist/adapters/openapi/request-builder.d.ts +13 -0
- package/dist/adapters/openapi/request-builder.d.ts.map +1 -0
- package/dist/adapters/openapi/request-builder.js +83 -0
- package/dist/adapters/openapi/request-builder.js.map +1 -0
- package/dist/adapters/registry.d.ts +28 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +46 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/rest/adapter.d.ts +18 -0
- package/dist/adapters/rest/adapter.d.ts.map +1 -0
- package/dist/adapters/rest/adapter.js +41 -0
- package/dist/adapters/rest/adapter.js.map +1 -0
- package/dist/adapters/rest/executor.d.ts +19 -0
- package/dist/adapters/rest/executor.d.ts.map +1 -0
- package/dist/adapters/rest/executor.js +101 -0
- package/dist/adapters/rest/executor.js.map +1 -0
- package/dist/cli/commands/config.d.ts +7 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +92 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +7 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +126 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +7 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +58 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +7 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +54 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/review.d.ts +7 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +151 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/scan.d.ts +7 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/scan.js +77 -0
- package/dist/cli/commands/scan.js.map +1 -0
- package/dist/cli/commands/start.d.ts +7 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +54 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/tools.d.ts +7 -0
- package/dist/cli/commands/tools.d.ts.map +1 -0
- package/dist/cli/commands/tools.js +48 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +42 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui/banner.d.ts +6 -0
- package/dist/cli/ui/banner.d.ts.map +1 -0
- package/dist/cli/ui/banner.js +20 -0
- package/dist/cli/ui/banner.js.map +1 -0
- package/dist/cli/ui/logger.d.ts +12 -0
- package/dist/cli/ui/logger.d.ts.map +1 -0
- package/dist/cli/ui/logger.js +13 -0
- package/dist/cli/ui/logger.js.map +1 -0
- package/dist/cli/ui/tables.d.ts +9 -0
- package/dist/cli/ui/tables.d.ts.map +1 -0
- package/dist/cli/ui/tables.js +72 -0
- package/dist/cli/ui/tables.js.map +1 -0
- package/dist/config/config-manager.d.ts +37 -0
- package/dist/config/config-manager.d.ts.map +1 -0
- package/dist/config/config-manager.js +129 -0
- package/dist/config/config-manager.js.map +1 -0
- package/dist/config/defaults.d.ts +8 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +37 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/core/authentication/manager.d.ts +20 -0
- package/dist/core/authentication/manager.d.ts.map +1 -0
- package/dist/core/authentication/manager.js +71 -0
- package/dist/core/authentication/manager.js.map +1 -0
- package/dist/core/authentication/secret-resolver.d.ts +39 -0
- package/dist/core/authentication/secret-resolver.d.ts.map +1 -0
- package/dist/core/authentication/secret-resolver.js +89 -0
- package/dist/core/authentication/secret-resolver.js.map +1 -0
- package/dist/core/discovery/index.d.ts +5 -0
- package/dist/core/discovery/index.d.ts.map +1 -0
- package/dist/core/discovery/index.js +5 -0
- package/dist/core/discovery/index.js.map +1 -0
- package/dist/core/discovery/project-scanner.d.ts +20 -0
- package/dist/core/discovery/project-scanner.d.ts.map +1 -0
- package/dist/core/discovery/project-scanner.js +174 -0
- package/dist/core/discovery/project-scanner.js.map +1 -0
- package/dist/core/permissions/classifier.d.ts +25 -0
- package/dist/core/permissions/classifier.d.ts.map +1 -0
- package/dist/core/permissions/classifier.js +92 -0
- package/dist/core/permissions/classifier.js.map +1 -0
- package/dist/core/permissions/enforcer.d.ts +24 -0
- package/dist/core/permissions/enforcer.d.ts.map +1 -0
- package/dist/core/permissions/enforcer.js +71 -0
- package/dist/core/permissions/enforcer.js.map +1 -0
- package/dist/core/schema/json-schema.d.ts +29 -0
- package/dist/core/schema/json-schema.d.ts.map +1 -0
- package/dist/core/schema/json-schema.js +129 -0
- package/dist/core/schema/json-schema.js.map +1 -0
- package/dist/core/schema/types.d.ts +187 -0
- package/dist/core/schema/types.d.ts.map +1 -0
- package/dist/core/schema/types.js +6 -0
- package/dist/core/schema/types.js.map +1 -0
- package/dist/core/tool-generator/description-builder.d.ts +15 -0
- package/dist/core/tool-generator/description-builder.d.ts.map +1 -0
- package/dist/core/tool-generator/description-builder.js +32 -0
- package/dist/core/tool-generator/description-builder.js.map +1 -0
- package/dist/core/tool-generator/generator.d.ts +21 -0
- package/dist/core/tool-generator/generator.d.ts.map +1 -0
- package/dist/core/tool-generator/generator.js +61 -0
- package/dist/core/tool-generator/generator.js.map +1 -0
- package/dist/core/tool-generator/name-sanitizer.d.ts +21 -0
- package/dist/core/tool-generator/name-sanitizer.d.ts.map +1 -0
- package/dist/core/tool-generator/name-sanitizer.js +84 -0
- package/dist/core/tool-generator/name-sanitizer.js.map +1 -0
- package/dist/core/validation/config-schema.d.ts +1458 -0
- package/dist/core/validation/config-schema.d.ts.map +1 -0
- package/dist/core/validation/config-schema.js +137 -0
- package/dist/core/validation/config-schema.js.map +1 -0
- package/dist/core/validation/validator.d.ts +28 -0
- package/dist/core/validation/validator.d.ts.map +1 -0
- package/dist/core/validation/validator.js +108 -0
- package/dist/core/validation/validator.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/prompts/prompt-registry.d.ts +28 -0
- package/dist/mcp/prompts/prompt-registry.d.ts.map +1 -0
- package/dist/mcp/prompts/prompt-registry.js +65 -0
- package/dist/mcp/prompts/prompt-registry.js.map +1 -0
- package/dist/mcp/resources/resource-registry.d.ts +26 -0
- package/dist/mcp/resources/resource-registry.d.ts.map +1 -0
- package/dist/mcp/resources/resource-registry.js +87 -0
- package/dist/mcp/resources/resource-registry.js.map +1 -0
- package/dist/mcp/server/fridayy-server.d.ts +38 -0
- package/dist/mcp/server/fridayy-server.d.ts.map +1 -0
- package/dist/mcp/server/fridayy-server.js +143 -0
- package/dist/mcp/server/fridayy-server.js.map +1 -0
- package/dist/mcp/tools/tool-handler.d.ts +29 -0
- package/dist/mcp/tools/tool-handler.d.ts.map +1 -0
- package/dist/mcp/tools/tool-handler.js +206 -0
- package/dist/mcp/tools/tool-handler.js.map +1 -0
- package/dist/mcp/tools/tool-registry.d.ts +20 -0
- package/dist/mcp/tools/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tools/tool-registry.js +38 -0
- package/dist/mcp/tools/tool-registry.js.map +1 -0
- package/dist/security/allowlist.d.ts +10 -0
- package/dist/security/allowlist.d.ts.map +1 -0
- package/dist/security/allowlist.js +30 -0
- package/dist/security/allowlist.js.map +1 -0
- package/dist/security/audit-logger.d.ts +35 -0
- package/dist/security/audit-logger.d.ts.map +1 -0
- package/dist/security/audit-logger.js +52 -0
- package/dist/security/audit-logger.js.map +1 -0
- package/dist/security/rate-limiter.d.ts +28 -0
- package/dist/security/rate-limiter.d.ts.map +1 -0
- package/dist/security/rate-limiter.js +64 -0
- package/dist/security/rate-limiter.js.map +1 -0
- package/dist/security/sanitizer.d.ts +17 -0
- package/dist/security/sanitizer.d.ts.map +1 -0
- package/dist/security/sanitizer.js +70 -0
- package/dist/security/sanitizer.js.map +1 -0
- package/package.json +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sabari Vasan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# fridayy
|
|
2
|
+
|
|
3
|
+
> **fridayy — Turn existing applications into AI-ready tools.**
|
|
4
|
+
|
|
5
|
+
[](https://github.com/fridayy/fridayy)
|
|
6
|
+
[](https://modelcontextprotocol.io)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🌟 What is fridayy?
|
|
12
|
+
|
|
13
|
+
**fridayy** is a developer-focused, local-first platform that converts existing APIs and applications into **Model Context Protocol (MCP) servers and tools**.
|
|
14
|
+
|
|
15
|
+
Instead of rewriting backend code or exposing raw endpoints to AI agents without safeguards, fridayy discovers existing application interfaces, standardizes them into structured tool definitions, applies granular security and permission gates, and serves them over standard MCP transports (Stdio & SSE).
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌───────────────────────────────┐
|
|
19
|
+
│ Existing Application │
|
|
20
|
+
│ (OpenAPI / REST / Node.js) │
|
|
21
|
+
└───────────────┬───────────────┘
|
|
22
|
+
│
|
|
23
|
+
▼
|
|
24
|
+
┌───────────────────────────────┐
|
|
25
|
+
│ fridayy │
|
|
26
|
+
│ • Capability Discovery │
|
|
27
|
+
│ • Schema Normalization │
|
|
28
|
+
│ • Permission & Risk Engine │
|
|
29
|
+
│ • Developer Review Workflow │
|
|
30
|
+
│ • Zero-Leak Secret Isolation │
|
|
31
|
+
└───────────────┬───────────────┘
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
┌───────────────────────────────┐
|
|
35
|
+
│ Standard MCP Server │
|
|
36
|
+
│ (Stdio / SSE / HTTP) │
|
|
37
|
+
└───────────────┬───────────────┘
|
|
38
|
+
│
|
|
39
|
+
┌───────────┼───────────┐
|
|
40
|
+
▼ ▼ ▼
|
|
41
|
+
Claude ChatGPT Cursor / Gemini
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 💡 Why fridayy Exists
|
|
47
|
+
|
|
48
|
+
Connecting existing production software to LLMs presents three major challenges:
|
|
49
|
+
|
|
50
|
+
1. **Protocol Impedance**: Large language models expect clean semantic descriptions and JSON Schemas, while legacy APIs have complex query strings, URL parameters, authentication headers, and nested payloads.
|
|
51
|
+
2. **Security & Destructive Risk**: Directly giving an AI agent unrestricted access to write or delete endpoints (`DELETE /users/{id}`, `POST /orders/refund`) is dangerous.
|
|
52
|
+
3. **Developer Friction**: Manually writing MCP servers for dozens of microservices and hundreds of endpoints is tedious and prone to maintenance drift.
|
|
53
|
+
|
|
54
|
+
**fridayy solves this by introducing a human-in-the-loop, secure abstraction layer.**
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 🚀 Quick Start
|
|
59
|
+
|
|
60
|
+
### 1. Installation
|
|
61
|
+
|
|
62
|
+
Install globally via npm:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm install -g fridayy
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or run directly in any project:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx fridayy init
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### 2. The 4-Step Developer Experience
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Step 1: Initialize Fridayy configuration in your project
|
|
80
|
+
fridayy init
|
|
81
|
+
|
|
82
|
+
# Step 2: Scan the workspace for APIs, OpenAPI specs, routes, and auth
|
|
83
|
+
fridayy scan
|
|
84
|
+
|
|
85
|
+
# Step 3: Generate candidate MCP tools
|
|
86
|
+
fridayy generate
|
|
87
|
+
|
|
88
|
+
# Step 4: Review and approve tools before exposing to AI
|
|
89
|
+
fridayy review
|
|
90
|
+
|
|
91
|
+
# Step 5: Start the standards-compliant MCP server
|
|
92
|
+
fridayy start
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🏗️ Architecture
|
|
98
|
+
|
|
99
|
+
fridayy is built with a modular, extensible architecture designed for future pluggability:
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
fridayy/
|
|
103
|
+
│
|
|
104
|
+
├── cli/ # Command-line interface & interactive prompts
|
|
105
|
+
│ ├── commands/ # init, scan, generate, review, start, tools, config, doctor
|
|
106
|
+
│ └── ui/ # Rich tables, badges, ascii banners
|
|
107
|
+
│
|
|
108
|
+
├── core/ # Core domain logic
|
|
109
|
+
│ ├── discovery/ # Project scanner & capability detection
|
|
110
|
+
│ ├── tool-generator/ # Tool name sanitization & description building
|
|
111
|
+
│ ├── schema/ # Unified JSON Schema converter & types
|
|
112
|
+
│ ├── permissions/ # READ / WRITE / DESTRUCTIVE classifier & enforcer
|
|
113
|
+
│ ├── authentication/ # API key, Bearer, Basic auth & secret isolation
|
|
114
|
+
│ └── validation/ # Input validation & config schemas (Zod)
|
|
115
|
+
│
|
|
116
|
+
├── adapters/ # Pluggable source adapters
|
|
117
|
+
│ ├── openapi/ # OpenAPI 3.0, 3.1 & Swagger 2.0 parser & request builder
|
|
118
|
+
│ ├── rest/ # Generic HTTP / REST executor
|
|
119
|
+
│ ├── nodejs/ # Express / Fastify / Koa AST route scanner
|
|
120
|
+
│ ├── manual/ # Custom user-defined tools
|
|
121
|
+
│ └── registry.ts # Adapter Registry (extensible to GraphQL, SQL, etc.)
|
|
122
|
+
│
|
|
123
|
+
├── mcp/ # Official Model Context Protocol integration
|
|
124
|
+
│ ├── server/ # Stdio & SSE MCP Server (@modelcontextprotocol/sdk)
|
|
125
|
+
│ ├── tools/ # Tool registry & execution handler
|
|
126
|
+
│ ├── resources/ # MCP resource providers (config, catalog, health)
|
|
127
|
+
│ └── prompts/ # Pre-configured guided prompt templates
|
|
128
|
+
│
|
|
129
|
+
├── config/ # Configuration & tools file manager
|
|
130
|
+
├── security/ # Rate limiting, audit logger, sanitizer, allowlists
|
|
131
|
+
└── examples/ # Working example e-commerce API & test suites
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🛡️ Security Model
|
|
137
|
+
|
|
138
|
+
Security is a first-class citizen in fridayy. AI models are **never** granted unrestricted access by default.
|
|
139
|
+
|
|
140
|
+
### 1. Permission Classification & Risk Assessment
|
|
141
|
+
|
|
142
|
+
Every operation is automatically classified:
|
|
143
|
+
|
|
144
|
+
| Classification | Typical Operations | Default Status | Risk Level |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `READ` | `GET /users`, `GET /products/{id}` | `APPROVED` | `low` |
|
|
147
|
+
| `WRITE` | `POST /orders`, `PUT /profile` | `PENDING` | `medium` |
|
|
148
|
+
| `DESTRUCTIVE` | `DELETE /users/{id}`, `POST /cache/purge` | `BLOCKED` | `high` |
|
|
149
|
+
|
|
150
|
+
> [!CAUTION]
|
|
151
|
+
> **Destructive operations default to `BLOCKED`.** They cannot be discovered or invoked by LLMs until the developer explicitly reviews and approves them via `fridayy review`.
|
|
152
|
+
|
|
153
|
+
### 2. Zero-Leak Secret Isolation
|
|
154
|
+
- Secrets and tokens are **never** embedded in tool schemas, descriptions, or LLM-visible payloads.
|
|
155
|
+
- Authentication tokens are resolved strictly from environment variables at execution time:
|
|
156
|
+
```env
|
|
157
|
+
FRIDAYY_API_KEY=your_api_key_here
|
|
158
|
+
FRIDAYY_BEARER_TOKEN=your_bearer_token_here
|
|
159
|
+
FRIDAYY_API_URL=http://localhost:4000
|
|
160
|
+
```
|
|
161
|
+
- Sensitive headers (`Authorization`, `x-api-key`, `Cookie`) and payload fields (`password`, `token`, `secret`) are automatically redacted in audit logs and error messages.
|
|
162
|
+
|
|
163
|
+
### 3. Dynamic Schema Validation
|
|
164
|
+
All input arguments provided by AI agents are validated against the tool's JSON Schema (types, required fields, ranges, and enum constraints) prior to dispatching HTTP requests.
|
|
165
|
+
|
|
166
|
+
### 4. Rate Limiting & Audit Logging
|
|
167
|
+
- **Rate Limiting**: Sliding-window rate limiter prevents runaway agent loops from overwhelming backend services.
|
|
168
|
+
- **Audit Logging**: Every invocation is recorded with timestamps, tool name, sanitized inputs, duration, and HTTP status codes.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 📋 CLI Reference
|
|
173
|
+
|
|
174
|
+
| Command | Description | Example |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| `fridayy init` | Initializes `fridayy.config.json` | `fridayy init --spec ./openapi.yaml` |
|
|
177
|
+
| `fridayy scan` | Analyzes workspace and detects endpoints/auth | `fridayy scan` |
|
|
178
|
+
| `fridayy generate` | Generates `fridayy.tools.json` from sources | `fridayy generate --force` |
|
|
179
|
+
| `fridayy review` | Review, approve, reject, or block candidate tools | `fridayy review --approve-read` |
|
|
180
|
+
| `fridayy start` | Boots standard MCP server (Stdio or SSE) | `fridayy start --transport sse --port 3000` |
|
|
181
|
+
| `fridayy tools` | Lists tool statuses and permission types | `fridayy tools --approved` |
|
|
182
|
+
| `fridayy config` | Displays or updates configuration | `fridayy config get source.baseUrl` |
|
|
183
|
+
| `fridayy doctor` | Runs diagnostics on config, secrets, and API | `fridayy doctor` |
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## ⚙️ Configuration Files
|
|
188
|
+
|
|
189
|
+
### `fridayy.config.json`
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"name": "my-ecommerce-app",
|
|
194
|
+
"version": "1.0.0",
|
|
195
|
+
"source": {
|
|
196
|
+
"type": "openapi",
|
|
197
|
+
"path": "./openapi.yaml",
|
|
198
|
+
"baseUrl": "https://api.example.com"
|
|
199
|
+
},
|
|
200
|
+
"server": {
|
|
201
|
+
"name": "ecommerce-mcp",
|
|
202
|
+
"transport": "stdio"
|
|
203
|
+
},
|
|
204
|
+
"security": {
|
|
205
|
+
"requireApprovalForDestructive": true,
|
|
206
|
+
"autoApproveRead": true,
|
|
207
|
+
"autoApproveWrite": false,
|
|
208
|
+
"allowlist": ["*"]
|
|
209
|
+
},
|
|
210
|
+
"auth": {
|
|
211
|
+
"ApiKeyAuth": {
|
|
212
|
+
"type": "apiKey",
|
|
213
|
+
"headerName": "x-api-key",
|
|
214
|
+
"envKey": "FRIDAYY_API_KEY"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 🤖 Connecting to MCP Clients
|
|
223
|
+
|
|
224
|
+
### Claude Desktop
|
|
225
|
+
|
|
226
|
+
Add to your `claude_desktop_config.json`:
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"mcpServers": {
|
|
231
|
+
"fridayy-api": {
|
|
232
|
+
"command": "npx",
|
|
233
|
+
"args": ["fridayy", "start"],
|
|
234
|
+
"env": {
|
|
235
|
+
"FRIDAYY_API_KEY": "your-api-key"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Cursor IDE
|
|
243
|
+
|
|
244
|
+
In Cursor Settings → Features → MCP:
|
|
245
|
+
- **Type**: `command`
|
|
246
|
+
- **Command**: `npx fridayy start`
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 🧪 Testing
|
|
251
|
+
|
|
252
|
+
Run the comprehensive test suite (12 suites, 41 unit & integration tests):
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
npm test
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Run the live E-Commerce end-to-end client demo:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
npm run example:demo
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 🗺️ Roadmap
|
|
267
|
+
|
|
268
|
+
- [x] OpenAPI 3.0, 3.1 & Swagger 2.0 support
|
|
269
|
+
- [x] Node.js / Express / Fastify route discovery
|
|
270
|
+
- [x] Stdio & SSE Transport support
|
|
271
|
+
- [x] Granular permission classifier & destructive blocking
|
|
272
|
+
- [x] Zero-leak secret isolation
|
|
273
|
+
- [x] Interactive CLI review workflow
|
|
274
|
+
- [ ] GraphQL Adapter
|
|
275
|
+
- [ ] PostgreSQL / MySQL / MongoDB direct query adapters
|
|
276
|
+
- [ ] Python / FastAPI / Django route scanner
|
|
277
|
+
- [ ] Webhook trigger tools
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 📄 License
|
|
282
|
+
|
|
283
|
+
MIT © fridayy
|
package/bin/fridayy.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Base Adapter Interface
|
|
3
|
+
* Provides the foundational abstraction for all application and API adapters.
|
|
4
|
+
*/
|
|
5
|
+
import { FridayyToolDefinition, FridayyConfig, ToolExecutionResult } from '../core/schema/types.js';
|
|
6
|
+
export interface AdapterScanContext {
|
|
7
|
+
rootDir: string;
|
|
8
|
+
config?: FridayyConfig;
|
|
9
|
+
}
|
|
10
|
+
export interface AdapterGenerationContext {
|
|
11
|
+
rootDir: string;
|
|
12
|
+
config?: FridayyConfig;
|
|
13
|
+
sourcePath?: string;
|
|
14
|
+
sourceUrl?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface AdapterExecutionContext {
|
|
17
|
+
config?: FridayyConfig;
|
|
18
|
+
headers?: Record<string, string>;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare abstract class BaseAdapter {
|
|
22
|
+
abstract readonly name: string;
|
|
23
|
+
abstract readonly description: string;
|
|
24
|
+
/**
|
|
25
|
+
* Detects whether the current workspace/target contains assets supported by this adapter.
|
|
26
|
+
*/
|
|
27
|
+
abstract detect(context: AdapterScanContext): Promise<{
|
|
28
|
+
detected: boolean;
|
|
29
|
+
details?: any;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Generates standardized FridayyToolDefinitions from the target source.
|
|
33
|
+
*/
|
|
34
|
+
abstract generateTools(context: AdapterGenerationContext): Promise<FridayyToolDefinition[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Executes a tool invocation against the underlying system.
|
|
37
|
+
*/
|
|
38
|
+
abstract executeTool(tool: FridayyToolDefinition, input: Record<string, any>, context?: AdapterExecutionContext): Promise<ToolExecutionResult>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EAEpB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8BAAsB,WAAW;IAC/B,kBAAyB,IAAI,EAAE,MAAM,CAAC;IACtC,kBAAyB,WAAW,EAAE,MAAM,CAAC;IAE7C;;OAEG;aACa,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAElG;;OAEG;aACa,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAElG;;OAEG;aACa,WAAW,CACzB,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,mBAAmB,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2BH,MAAM,OAAgB,WAAW;CAsBhC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Manual Custom Tools Adapter
|
|
3
|
+
* Supports custom defined tools with manual configurations or handlers.
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter, AdapterScanContext, AdapterGenerationContext, AdapterExecutionContext } from '../base.js';
|
|
6
|
+
import { FridayyToolDefinition, ToolExecutionResult } from '../../core/schema/types.js';
|
|
7
|
+
export declare class ManualAdapter extends BaseAdapter {
|
|
8
|
+
readonly name = "manual";
|
|
9
|
+
readonly description = "Adapter for manually defined tools and handlers";
|
|
10
|
+
private restExecutor;
|
|
11
|
+
detect(context: AdapterScanContext): Promise<{
|
|
12
|
+
detected: boolean;
|
|
13
|
+
details?: any;
|
|
14
|
+
}>;
|
|
15
|
+
generateTools(context: AdapterGenerationContext): Promise<FridayyToolDefinition[]>;
|
|
16
|
+
executeTool(tool: FridayyToolDefinition, input: Record<string, any>, context?: AdapterExecutionContext): Promise<ToolExecutionResult>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/manual/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAMpC,qBAAa,aAAc,SAAQ,WAAW;IAC5C,SAAgB,IAAI,YAAY;IAChC,SAAgB,WAAW,qDAAqD;IAEhF,OAAO,CAAC,YAAY,CAAuB;IAE9B,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAIlF,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAIlF,WAAW,CACtB,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,mBAAmB,CAAC;CAmChC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Manual Custom Tools Adapter
|
|
3
|
+
* Supports custom defined tools with manual configurations or handlers.
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter } from '../base.js';
|
|
6
|
+
import { buildHttpRequest } from '../openapi/request-builder.js';
|
|
7
|
+
import { defaultRestExecutor } from '../rest/executor.js';
|
|
8
|
+
import { AuthenticationManager } from '../../core/authentication/manager.js';
|
|
9
|
+
import { defaultSecretResolver } from '../../core/authentication/secret-resolver.js';
|
|
10
|
+
export class ManualAdapter extends BaseAdapter {
|
|
11
|
+
name = 'manual';
|
|
12
|
+
description = 'Adapter for manually defined tools and handlers';
|
|
13
|
+
restExecutor = defaultRestExecutor;
|
|
14
|
+
async detect(context) {
|
|
15
|
+
return { detected: false };
|
|
16
|
+
}
|
|
17
|
+
async generateTools(context) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
async executeTool(tool, input, context = {}) {
|
|
21
|
+
// If tool defines an HTTP endpoint, execute it
|
|
22
|
+
if (tool.source.url || tool.source.path) {
|
|
23
|
+
const authManager = new AuthenticationManager(context.config);
|
|
24
|
+
const baseUrl = defaultSecretResolver.resolveBaseUrl(context.config?.source?.baseUrl);
|
|
25
|
+
const preparedReq = buildHttpRequest(tool, input, baseUrl);
|
|
26
|
+
if (context.headers) {
|
|
27
|
+
Object.assign(preparedReq.headers, context.headers);
|
|
28
|
+
}
|
|
29
|
+
authManager.applyAuth(tool.authentication, {
|
|
30
|
+
headers: preparedReq.headers,
|
|
31
|
+
queryParams: {}
|
|
32
|
+
});
|
|
33
|
+
return await this.restExecutor.execute(preparedReq, tool.name, {
|
|
34
|
+
timeoutMs: context.timeoutMs
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// Otherwise return echo/manual data
|
|
38
|
+
return {
|
|
39
|
+
success: true,
|
|
40
|
+
data: {
|
|
41
|
+
message: `Executed manual tool "${tool.name}"`,
|
|
42
|
+
input
|
|
43
|
+
},
|
|
44
|
+
metadata: {
|
|
45
|
+
durationMs: 1,
|
|
46
|
+
timestamp: new Date().toISOString(),
|
|
47
|
+
toolName: tool.name
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/adapters/manual/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,WAAW,EAIZ,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAErF,MAAM,OAAO,aAAc,SAAQ,WAAW;IAC5B,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,iDAAiD,CAAC;IAExE,YAAY,GAAG,mBAAmB,CAAC;IAEpC,KAAK,CAAC,MAAM,CAAC,OAA2B;QAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,OAAiC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC;IAEM,KAAK,CAAC,WAAW,CACtB,IAA2B,EAC3B,KAA0B,EAC1B,UAAmC,EAAE;QAErC,+CAA+C;QAC/C,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,IAAI,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,qBAAqB,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAEtF,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC3D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YACtD,CAAC;YAED,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE;gBACzC,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,WAAW,EAAE,EAAE;aAChB,CAAC,CAAC;YAEH,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE;gBAC7D,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC,CAAC;QACL,CAAC;QAED,oCAAoC;QACpC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,OAAO,EAAE,yBAAyB,IAAI,CAAC,IAAI,GAAG;gBAC9C,KAAK;aACN;YACD,QAAQ,EAAE;gBACR,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,QAAQ,EAAE,IAAI,CAAC,IAAI;aACpB;SACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Node.js Framework Adapter
|
|
3
|
+
* Discovers endpoints directly from Express / Fastify / Koa applications.
|
|
4
|
+
*/
|
|
5
|
+
import { BaseAdapter, AdapterScanContext, AdapterGenerationContext, AdapterExecutionContext } from '../base.js';
|
|
6
|
+
import { FridayyToolDefinition, ToolExecutionResult } from '../../core/schema/types.js';
|
|
7
|
+
export declare class NodeJsAdapter extends BaseAdapter {
|
|
8
|
+
readonly name = "nodejs";
|
|
9
|
+
readonly description = "Adapter for Express, Fastify, and Node.js web applications";
|
|
10
|
+
private scanner;
|
|
11
|
+
private restExecutor;
|
|
12
|
+
detect(context: AdapterScanContext): Promise<{
|
|
13
|
+
detected: boolean;
|
|
14
|
+
details?: any;
|
|
15
|
+
}>;
|
|
16
|
+
generateTools(context: AdapterGenerationContext): Promise<FridayyToolDefinition[]>;
|
|
17
|
+
executeTool(tool: FridayyToolDefinition, input: Record<string, any>, context?: AdapterExecutionContext): Promise<ToolExecutionResult>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/nodejs/adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EAEpB,MAAM,4BAA4B,CAAC;AAWpC,qBAAa,aAAc,SAAQ,WAAW;IAC5C,SAAgB,IAAI,YAAY;IAChC,SAAgB,WAAW,gEAAgE;IAE3F,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,YAAY,CAAuB;IAE9B,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IA8BlF,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAgFlF,WAAW,CACtB,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,mBAAmB,CAAC;CAmBhC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Node.js Framework Adapter
|
|
3
|
+
* Discovers endpoints directly from Express / Fastify / Koa applications.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { BaseAdapter } from '../base.js';
|
|
8
|
+
import { NodeJsScanner } from './ast-scanner.js';
|
|
9
|
+
import { generateToolNameFromRoute } from '../../core/tool-generator/name-sanitizer.js';
|
|
10
|
+
import { classifyOperation } from '../../core/permissions/classifier.js';
|
|
11
|
+
import { buildToolDescription } from '../../core/tool-generator/description-builder.js';
|
|
12
|
+
import { buildUnifiedInputSchema } from '../../core/schema/json-schema.js';
|
|
13
|
+
import { defaultRestExecutor } from '../rest/executor.js';
|
|
14
|
+
import { buildHttpRequest } from '../openapi/request-builder.js';
|
|
15
|
+
import { AuthenticationManager } from '../../core/authentication/manager.js';
|
|
16
|
+
import { defaultSecretResolver } from '../../core/authentication/secret-resolver.js';
|
|
17
|
+
export class NodeJsAdapter extends BaseAdapter {
|
|
18
|
+
name = 'nodejs';
|
|
19
|
+
description = 'Adapter for Express, Fastify, and Node.js web applications';
|
|
20
|
+
scanner = new NodeJsScanner();
|
|
21
|
+
restExecutor = defaultRestExecutor;
|
|
22
|
+
async detect(context) {
|
|
23
|
+
const rootDir = context.rootDir;
|
|
24
|
+
const pkgJsonPath = path.resolve(rootDir, 'package.json');
|
|
25
|
+
let detectedFramework;
|
|
26
|
+
if (fs.existsSync(pkgJsonPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
29
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
30
|
+
if (allDeps.express)
|
|
31
|
+
detectedFramework = 'express';
|
|
32
|
+
else if (allDeps.fastify)
|
|
33
|
+
detectedFramework = 'fastify';
|
|
34
|
+
else if (allDeps.koa)
|
|
35
|
+
detectedFramework = 'koa';
|
|
36
|
+
else if (allDeps['@nestjs/core'])
|
|
37
|
+
detectedFramework = 'nestjs';
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// ignore
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const routes = await this.scanner.scanDirectory(rootDir, 50);
|
|
44
|
+
return {
|
|
45
|
+
detected: Boolean(detectedFramework || routes.length > 0),
|
|
46
|
+
details: {
|
|
47
|
+
framework: detectedFramework || (routes.length > 0 ? 'custom' : undefined),
|
|
48
|
+
discoveredRoutesCount: routes.length
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async generateTools(context) {
|
|
53
|
+
const rootDir = context.rootDir || process.cwd();
|
|
54
|
+
const routes = await this.scanner.scanDirectory(rootDir);
|
|
55
|
+
const tools = [];
|
|
56
|
+
const usedToolNames = new Set();
|
|
57
|
+
const baseUrl = defaultSecretResolver.resolveBaseUrl(context.config?.source?.baseUrl) ||
|
|
58
|
+
'http://localhost:3000';
|
|
59
|
+
for (const r of routes) {
|
|
60
|
+
let toolName = generateToolNameFromRoute(r.method, r.path);
|
|
61
|
+
if (usedToolNames.has(toolName)) {
|
|
62
|
+
let suffix = 2;
|
|
63
|
+
while (usedToolNames.has(`${toolName}_${suffix}`))
|
|
64
|
+
suffix++;
|
|
65
|
+
toolName = `${toolName}_${suffix}`;
|
|
66
|
+
}
|
|
67
|
+
usedToolNames.add(toolName);
|
|
68
|
+
const pathParams = r.pathParams.map(name => ({
|
|
69
|
+
name,
|
|
70
|
+
in: 'path',
|
|
71
|
+
required: true,
|
|
72
|
+
schema: { type: 'string' },
|
|
73
|
+
description: `Path parameter ${name}`
|
|
74
|
+
}));
|
|
75
|
+
const classification = classifyOperation({
|
|
76
|
+
method: r.method,
|
|
77
|
+
path: r.path,
|
|
78
|
+
name: toolName,
|
|
79
|
+
summary: r.description
|
|
80
|
+
}, context.config);
|
|
81
|
+
const description = buildToolDescription({
|
|
82
|
+
summary: r.description,
|
|
83
|
+
method: r.method,
|
|
84
|
+
path: r.path,
|
|
85
|
+
permissionType: classification.permissions.type,
|
|
86
|
+
risk: classification.risk
|
|
87
|
+
});
|
|
88
|
+
const inputSchema = buildUnifiedInputSchema({
|
|
89
|
+
parameters: { path: pathParams }
|
|
90
|
+
});
|
|
91
|
+
const tool = {
|
|
92
|
+
id: `tool_${toolName}`,
|
|
93
|
+
name: toolName,
|
|
94
|
+
description,
|
|
95
|
+
inputSchema,
|
|
96
|
+
source: {
|
|
97
|
+
type: 'nodejs',
|
|
98
|
+
method: r.method,
|
|
99
|
+
path: r.path,
|
|
100
|
+
baseUrl
|
|
101
|
+
},
|
|
102
|
+
parameters: {
|
|
103
|
+
path: pathParams
|
|
104
|
+
},
|
|
105
|
+
permissions: classification.permissions,
|
|
106
|
+
risk: classification.risk,
|
|
107
|
+
status: classification.status,
|
|
108
|
+
metadata: {
|
|
109
|
+
createdAt: new Date().toISOString(),
|
|
110
|
+
autoGenerated: true,
|
|
111
|
+
sourceFile: r.file,
|
|
112
|
+
line: r.line
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
tools.push(tool);
|
|
116
|
+
}
|
|
117
|
+
return tools;
|
|
118
|
+
}
|
|
119
|
+
async executeTool(tool, input, context = {}) {
|
|
120
|
+
const authManager = new AuthenticationManager(context.config);
|
|
121
|
+
const baseUrl = defaultSecretResolver.resolveBaseUrl(context.config?.source?.baseUrl);
|
|
122
|
+
const preparedReq = buildHttpRequest(tool, input, baseUrl);
|
|
123
|
+
if (context.headers) {
|
|
124
|
+
Object.assign(preparedReq.headers, context.headers);
|
|
125
|
+
}
|
|
126
|
+
authManager.applyAuth(tool.authentication, {
|
|
127
|
+
headers: preparedReq.headers,
|
|
128
|
+
queryParams: {}
|
|
129
|
+
});
|
|
130
|
+
return await this.restExecutor.execute(preparedReq, tool.name, {
|
|
131
|
+
timeoutMs: context.timeoutMs
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/adapters/nodejs/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Node.js Route Scanner
|
|
3
|
+
* Scans JavaScript and TypeScript files for Express/Fastify/Koa route declarations.
|
|
4
|
+
*/
|
|
5
|
+
export interface DiscoveredRoute {
|
|
6
|
+
method: string;
|
|
7
|
+
path: string;
|
|
8
|
+
file: string;
|
|
9
|
+
line: number;
|
|
10
|
+
description?: string;
|
|
11
|
+
pathParams: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare class NodeJsScanner {
|
|
14
|
+
/**
|
|
15
|
+
* Scans a directory recursively for Express/Fastify routes.
|
|
16
|
+
*/
|
|
17
|
+
scanDirectory(rootDir: string, maxFiles?: number): Promise<DiscoveredRoute[]>;
|
|
18
|
+
scanFileContent(content: string, filePath: string): DiscoveredRoute[];
|
|
19
|
+
private collectSourceFiles;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ast-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-scanner.d.ts","sourceRoot":"","sources":["../../../src/adapters/nodejs/ast-scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAID,qBAAa,aAAa;IACxB;;OAEG;IACU,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAiBhF,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE;IAkD5E,OAAO,CAAC,kBAAkB;CA8B3B"}
|