forbin-mcp 0.1.0__tar.gz
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.
- forbin_mcp-0.1.0/.env.example +40 -0
- forbin_mcp-0.1.0/.github/workflows/ci.yml +23 -0
- forbin_mcp-0.1.0/.github/workflows/release.yml +74 -0
- forbin_mcp-0.1.0/.gitignore +15 -0
- forbin_mcp-0.1.0/.pre-commit-config.yaml +32 -0
- forbin_mcp-0.1.0/.python-version +1 -0
- forbin_mcp-0.1.0/.vscode/settings.json +3 -0
- forbin_mcp-0.1.0/CHANGELOG.md +31 -0
- forbin_mcp-0.1.0/CLAUDE.md +223 -0
- forbin_mcp-0.1.0/CONTRIBUTING.md +168 -0
- forbin_mcp-0.1.0/DOCS.md +64 -0
- forbin_mcp-0.1.0/LICENSE +21 -0
- forbin_mcp-0.1.0/Makefile +168 -0
- forbin_mcp-0.1.0/PKG-INFO +392 -0
- forbin_mcp-0.1.0/README.md +366 -0
- forbin_mcp-0.1.0/docs/CONFIGURATION.md +209 -0
- forbin_mcp-0.1.0/docs/DEVELOPMENT.md +433 -0
- forbin_mcp-0.1.0/docs/INSTALLATION.md +191 -0
- forbin_mcp-0.1.0/docs/USAGE.md +253 -0
- forbin_mcp-0.1.0/forbin/__init__.py +36 -0
- forbin_mcp-0.1.0/forbin/__main__.py +9 -0
- forbin_mcp-0.1.0/forbin/cli.py +288 -0
- forbin_mcp-0.1.0/forbin/client.py +232 -0
- forbin_mcp-0.1.0/forbin/config.py +28 -0
- forbin_mcp-0.1.0/forbin/display.py +260 -0
- forbin_mcp-0.1.0/forbin/tools.py +193 -0
- forbin_mcp-0.1.0/forbin/utils.py +111 -0
- forbin_mcp-0.1.0/img/forbin_avatar.jpg +0 -0
- forbin_mcp-0.1.0/pyproject.toml +72 -0
- forbin_mcp-0.1.0/tests/__init__.py +1 -0
- forbin_mcp-0.1.0/tests/conftest.py +99 -0
- forbin_mcp-0.1.0/tests/test_integration.py +285 -0
- forbin_mcp-0.1.0/tests/test_main.py +333 -0
- forbin_mcp-0.1.0/uv.lock +1437 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# MCP Remote Tool Tester Configuration
|
|
2
|
+
# Copy this file to .env and configure with your MCP server details
|
|
3
|
+
|
|
4
|
+
# Required: MCP Server URL
|
|
5
|
+
# This is the endpoint where your MCP server is hosted
|
|
6
|
+
MCP_SERVER_URL=https://your-mcp-server.example.com/mcp
|
|
7
|
+
|
|
8
|
+
# Required: Authentication Token
|
|
9
|
+
# Bearer token for authenticating with the MCP server
|
|
10
|
+
MCP_TOKEN=your-secret-token-here
|
|
11
|
+
|
|
12
|
+
# Optional: Health Check URL
|
|
13
|
+
# Used to wake up suspended services (e.g., Fly.io apps)
|
|
14
|
+
# If your server doesn't suspend, you can omit this
|
|
15
|
+
MCP_HEALTH_URL=https://your-mcp-server.example.com/health
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# ============================================================================
|
|
19
|
+
# Example Configurations
|
|
20
|
+
# ============================================================================
|
|
21
|
+
|
|
22
|
+
# Local Development Server:
|
|
23
|
+
# MCP_SERVER_URL=http://localhost:8000/mcp
|
|
24
|
+
# MCP_TOKEN=test-token-123
|
|
25
|
+
# MCP_HEALTH_URL=http://localhost:8000/health
|
|
26
|
+
|
|
27
|
+
# Fly.io Production Server:
|
|
28
|
+
# MCP_SERVER_URL=https://my-app.fly.dev/mcp
|
|
29
|
+
# MCP_HEALTH_URL=https://my-app.fly.dev/health
|
|
30
|
+
# MCP_TOKEN=prod-token-xyz
|
|
31
|
+
|
|
32
|
+
# Fly.io Preview/Staging Server:
|
|
33
|
+
# MCP_SERVER_URL=https://my-app-staging.fly.dev/mcp
|
|
34
|
+
# MCP_HEALTH_URL=https://my-app-staging.fly.dev/health
|
|
35
|
+
# MCP_TOKEN=staging-token-abc
|
|
36
|
+
|
|
37
|
+
# Remote Server (No Health Check):
|
|
38
|
+
# MCP_SERVER_URL=https://api.example.com/mcp
|
|
39
|
+
# MCP_TOKEN=api-key-here
|
|
40
|
+
# # MCP_HEALTH_URL is omitted - server doesn't suspend
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v3
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v4
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.13"
|
|
18
|
+
- name: Install uv
|
|
19
|
+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: uv sync
|
|
22
|
+
- name: Run tests
|
|
23
|
+
run: uv run pytest
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- name: Set up Python
|
|
14
|
+
uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.13"
|
|
17
|
+
- name: Install uv
|
|
18
|
+
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
19
|
+
- name: Install dependencies
|
|
20
|
+
run: uv sync
|
|
21
|
+
- name: Run tests
|
|
22
|
+
run: uv run pytest
|
|
23
|
+
|
|
24
|
+
build:
|
|
25
|
+
needs: test
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- name: Set up Python
|
|
30
|
+
uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.13"
|
|
33
|
+
- name: Install build tools
|
|
34
|
+
run: pip install build
|
|
35
|
+
- name: Build package
|
|
36
|
+
run: python -m build
|
|
37
|
+
- name: Upload artifacts
|
|
38
|
+
uses: actions/upload-artifact@v4
|
|
39
|
+
with:
|
|
40
|
+
name: dist
|
|
41
|
+
path: dist/
|
|
42
|
+
|
|
43
|
+
publish:
|
|
44
|
+
needs: build
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
environment: pypi
|
|
47
|
+
permissions:
|
|
48
|
+
id-token: write
|
|
49
|
+
steps:
|
|
50
|
+
- name: Download artifacts
|
|
51
|
+
uses: actions/download-artifact@v4
|
|
52
|
+
with:
|
|
53
|
+
name: dist
|
|
54
|
+
path: dist/
|
|
55
|
+
- name: Publish to PyPI
|
|
56
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
57
|
+
|
|
58
|
+
release:
|
|
59
|
+
needs: publish
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
permissions:
|
|
62
|
+
contents: write
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v4
|
|
65
|
+
- name: Download artifacts
|
|
66
|
+
uses: actions/download-artifact@v4
|
|
67
|
+
with:
|
|
68
|
+
name: dist
|
|
69
|
+
path: dist/
|
|
70
|
+
- name: Create GitHub Release
|
|
71
|
+
uses: softprops/action-gh-release@v1
|
|
72
|
+
with:
|
|
73
|
+
files: dist/*
|
|
74
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Pre-commit hooks for Zorac
|
|
2
|
+
# Install: pre-commit install
|
|
3
|
+
# Run manually: pre-commit run --all-files
|
|
4
|
+
|
|
5
|
+
repos:
|
|
6
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
7
|
+
rev: v6.0.0
|
|
8
|
+
hooks:
|
|
9
|
+
- id: trailing-whitespace
|
|
10
|
+
- id: end-of-file-fixer
|
|
11
|
+
- id: check-yaml
|
|
12
|
+
- id: check-added-large-files
|
|
13
|
+
- id: check-json
|
|
14
|
+
- id: check-toml
|
|
15
|
+
- id: check-merge-conflict
|
|
16
|
+
- id: debug-statements
|
|
17
|
+
- id: mixed-line-ending
|
|
18
|
+
|
|
19
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
20
|
+
rev: v0.14.8
|
|
21
|
+
hooks:
|
|
22
|
+
- id: ruff
|
|
23
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
24
|
+
- id: ruff-format
|
|
25
|
+
|
|
26
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
27
|
+
rev: v1.19.0
|
|
28
|
+
hooks:
|
|
29
|
+
- id: mypy
|
|
30
|
+
additional_dependencies:
|
|
31
|
+
- types-requests
|
|
32
|
+
args: [--ignore-missing-imports]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-02-05
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Interactive CLI** - Two-level tool browser for exploring and testing MCP tools
|
|
13
|
+
- **Automatic server wake-up** - Health check polling for suspended services (Fly.io, etc.)
|
|
14
|
+
- **Cold-start resilient connections** - Retry logic with extended timeouts for slow-starting servers
|
|
15
|
+
- **Tool schema inspection** - View detailed tool schemas with syntax-highlighted JSON
|
|
16
|
+
- **Interactive parameter input** - Type-safe parsing for strings, booleans, numbers, and JSON objects
|
|
17
|
+
- **Connectivity test mode** - `forbin --test` for verifying server connectivity
|
|
18
|
+
- **Verbose logging toggle** - Press `v` at any time to toggle debug output
|
|
19
|
+
- **Modular package structure** - Organized into cli, client, tools, display, and utils modules
|
|
20
|
+
- **Comprehensive documentation** - README, CLAUDE.md, DOCS.md, USAGE.md, DEVELOPMENT.md, CONTRIBUTING.md
|
|
21
|
+
- **CI/CD pipeline** - GitHub Actions workflow for testing and linting
|
|
22
|
+
- **Pre-commit hooks** - Automated code quality checks
|
|
23
|
+
- **Makefile automation** - Common development tasks (`make test`, `make check`, etc.)
|
|
24
|
+
|
|
25
|
+
### Technical Details
|
|
26
|
+
|
|
27
|
+
- Python 3.13+ required
|
|
28
|
+
- Built with fastmcp, httpx, python-dotenv, and tenacity
|
|
29
|
+
- MIT licensed
|
|
30
|
+
|
|
31
|
+
[1.0.0]: https://github.com/chris-colinsky/Forbin/releases/tag/v1.0.0
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**Forbin** is an interactive CLI tool for testing remote MCP (Model Context Protocol) servers and their tools. Named after Dr. Charles Forbin from "Colossus: The Forbin Project" (1970), where two computers learn to communicate - a perfect parallel to MCP enabling systems to communicate.
|
|
8
|
+
|
|
9
|
+
It's designed for developers building agentic workflows and testing FastAPI/FastMCP-based remote tools. The tool specializes in handling suspended services (like Fly.io) with automatic wake-up functionality.
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- Interactive tool browser with parameter input
|
|
14
|
+
- Automatic server wake-up for suspended services
|
|
15
|
+
- Cold-start resilient connection logic
|
|
16
|
+
- Type-safe parameter parsing
|
|
17
|
+
- Connectivity testing mode
|
|
18
|
+
|
|
19
|
+
## Running the Tool
|
|
20
|
+
|
|
21
|
+
### Interactive Mode
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python forbin.py
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This launches the interactive tool browser that:
|
|
28
|
+
1. Wakes up suspended servers (if health URL configured)
|
|
29
|
+
2. Connects to the MCP server
|
|
30
|
+
3. Lists all available tools
|
|
31
|
+
4. Allows interactive tool selection and calling
|
|
32
|
+
|
|
33
|
+
### Connectivity Test Mode
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
python forbin.py --test
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Tests server connectivity without running tools.
|
|
40
|
+
|
|
41
|
+
### Help
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
python forbin.py --help
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Configuration
|
|
48
|
+
|
|
49
|
+
Configuration is via `.env` file:
|
|
50
|
+
|
|
51
|
+
- `MCP_SERVER_URL` (required) - MCP server endpoint
|
|
52
|
+
- `MCP_TOKEN` (required) - Bearer token for authentication
|
|
53
|
+
- `MCP_HEALTH_URL` (optional) - Health endpoint for wake-up
|
|
54
|
+
|
|
55
|
+
Create from template:
|
|
56
|
+
```bash
|
|
57
|
+
cp .env.example .env
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Architecture
|
|
61
|
+
|
|
62
|
+
### Main Components
|
|
63
|
+
|
|
64
|
+
**`forbin.py`** - Single-file CLI application with these key functions:
|
|
65
|
+
|
|
66
|
+
1. **wake_up_server()** (lines 72-111)
|
|
67
|
+
- Polls health endpoint until server responds
|
|
68
|
+
- 6 attempts with 5-second waits
|
|
69
|
+
- Returns True if server is awake
|
|
70
|
+
|
|
71
|
+
2. **connect_to_mcp_server()** (lines 114-161)
|
|
72
|
+
- Establishes MCP connection with retry logic
|
|
73
|
+
- Uses `init_timeout=30.0` for cold starts
|
|
74
|
+
- 3 attempts with 5-second waits
|
|
75
|
+
- Returns connected Client or None
|
|
76
|
+
|
|
77
|
+
3. **list_tools()** (lines 164-177)
|
|
78
|
+
- Retrieves tool manifest from server
|
|
79
|
+
- 15-second timeout for the list operation
|
|
80
|
+
|
|
81
|
+
4. **interactive_session()** (lines 394-476)
|
|
82
|
+
- Main interactive loop
|
|
83
|
+
- Handles tool selection and parameter input
|
|
84
|
+
- Displays results
|
|
85
|
+
|
|
86
|
+
5. **test_connectivity()** (lines 348-391)
|
|
87
|
+
- Connectivity-only testing mode
|
|
88
|
+
- Useful for CI/CD health checks
|
|
89
|
+
|
|
90
|
+
### Wake-Up Process
|
|
91
|
+
|
|
92
|
+
Three-step approach for suspended services:
|
|
93
|
+
|
|
94
|
+
1. **Health Check Wake-Up** - Polls `/health` endpoint until 200 response
|
|
95
|
+
2. **Initialization Wait** - Waits 20 seconds for MCP server to fully initialize
|
|
96
|
+
3. **Connection with Retry** - Connects with extended timeout and retry logic
|
|
97
|
+
|
|
98
|
+
This is critical for Fly.io and similar platforms that suspend inactive services.
|
|
99
|
+
|
|
100
|
+
### Error Handling
|
|
101
|
+
|
|
102
|
+
**FilteredStderr class** (lines 18-51):
|
|
103
|
+
- Suppresses harmless MCP session termination errors
|
|
104
|
+
- Filters stderr output for cleaner user experience
|
|
105
|
+
- Specifically suppresses "Session termination failed: 400" warnings
|
|
106
|
+
|
|
107
|
+
**Connection retry logic**:
|
|
108
|
+
- Handles `BrokenResourceError`, `ClosedResourceError`, `TimeoutError`
|
|
109
|
+
- Creates fresh client on each retry attempt
|
|
110
|
+
- Provides clear feedback on connection status
|
|
111
|
+
|
|
112
|
+
### Parameter Handling
|
|
113
|
+
|
|
114
|
+
**parse_parameter_value()** (lines 236-250):
|
|
115
|
+
- Converts string input to appropriate types
|
|
116
|
+
- Supports: boolean, integer, number, string, object, array
|
|
117
|
+
- Handles JSON parsing for complex types
|
|
118
|
+
|
|
119
|
+
**get_tool_parameters()** (lines 253-310):
|
|
120
|
+
- Interactive parameter collection
|
|
121
|
+
- Validates required vs optional parameters
|
|
122
|
+
- Shows enum values when available
|
|
123
|
+
- Retry loop for invalid inputs
|
|
124
|
+
|
|
125
|
+
## Development Notes
|
|
126
|
+
|
|
127
|
+
### Dependencies
|
|
128
|
+
|
|
129
|
+
- **fastmcp** - MCP client library (requires >=2.0.0)
|
|
130
|
+
- **httpx** - Async HTTP for health checks
|
|
131
|
+
- **python-dotenv** - Environment variable management
|
|
132
|
+
- **tenacity** - Retry logic utilities (currently imported but not actively used)
|
|
133
|
+
|
|
134
|
+
### Package Management
|
|
135
|
+
|
|
136
|
+
Uses `uv` for dependency management:
|
|
137
|
+
```bash
|
|
138
|
+
uv sync
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Python 3.11+ required.
|
|
142
|
+
|
|
143
|
+
### CLI Entry Point
|
|
144
|
+
|
|
145
|
+
Configured in `pyproject.toml`:
|
|
146
|
+
```toml
|
|
147
|
+
[project.scripts]
|
|
148
|
+
mcp-test = "main:main"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
After installation, users can run `mcp-test` directly.
|
|
152
|
+
|
|
153
|
+
### Making Changes
|
|
154
|
+
|
|
155
|
+
When modifying the tool:
|
|
156
|
+
|
|
157
|
+
1. **Connection logic** - Edit `connect_to_mcp_server()` and adjust timeouts/retries
|
|
158
|
+
2. **Wake-up behavior** - Edit `wake_up_server()` and the 20-second sleep in `interactive_session()`
|
|
159
|
+
3. **Display formatting** - Edit `display_tools()` and `display_tool_schema()`
|
|
160
|
+
4. **Parameter parsing** - Edit `parse_parameter_value()` for new type support
|
|
161
|
+
5. **Error suppression** - Edit `FilteredStderr` class patterns
|
|
162
|
+
|
|
163
|
+
### Important Constants
|
|
164
|
+
|
|
165
|
+
- **Health check**: 6 attempts x 5 seconds = 30 seconds max
|
|
166
|
+
- **Initialization wait**: 20 seconds after health check
|
|
167
|
+
- **Connection retry**: 3 attempts with 30-second init timeout each
|
|
168
|
+
- **Tool listing timeout**: 15 seconds
|
|
169
|
+
|
|
170
|
+
These are tuned for Fly.io cold starts but can be adjusted for other platforms.
|
|
171
|
+
|
|
172
|
+
## Testing
|
|
173
|
+
|
|
174
|
+
The tool itself is used for testing MCP servers. To test the tester:
|
|
175
|
+
|
|
176
|
+
1. Set up a local MCP server or use a remote one
|
|
177
|
+
2. Configure `.env` with server details
|
|
178
|
+
3. Run `python forbin.py --test` to verify connectivity
|
|
179
|
+
4. Run `python forbin.py` to test interactive mode
|
|
180
|
+
|
|
181
|
+
## FastAPI/FastMCP Server Compatibility
|
|
182
|
+
|
|
183
|
+
This tool expects servers to:
|
|
184
|
+
- Expose an MCP endpoint (e.g., `/mcp`)
|
|
185
|
+
- Implement bearer token authentication
|
|
186
|
+
- Optionally provide `/health` endpoint for wake-up detection
|
|
187
|
+
- Follow MCP protocol specification
|
|
188
|
+
|
|
189
|
+
Example compatible server:
|
|
190
|
+
```python
|
|
191
|
+
from fastapi import FastAPI
|
|
192
|
+
from fastmcp import FastMCP
|
|
193
|
+
|
|
194
|
+
app = FastAPI()
|
|
195
|
+
mcp = FastMCP("My Tools")
|
|
196
|
+
|
|
197
|
+
@mcp.tool()
|
|
198
|
+
def my_tool(param: str) -> str:
|
|
199
|
+
return f"Result: {param}"
|
|
200
|
+
|
|
201
|
+
app.include_router(mcp.get_router(), prefix="/mcp")
|
|
202
|
+
|
|
203
|
+
@app.get("/health")
|
|
204
|
+
def health():
|
|
205
|
+
return {"status": "ok"}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Common Issues
|
|
209
|
+
|
|
210
|
+
### "Failed to wake up server"
|
|
211
|
+
- Check `MCP_HEALTH_URL` is correct and accessible
|
|
212
|
+
- Try increasing retry attempts in `wake_up_server()`
|
|
213
|
+
- Remove `MCP_HEALTH_URL` if server doesn't suspend
|
|
214
|
+
|
|
215
|
+
### "Connection error (server not ready)"
|
|
216
|
+
- Increase initialization wait time (line 410: `await asyncio.sleep(20)`)
|
|
217
|
+
- Verify `MCP_SERVER_URL` and `MCP_TOKEN` are correct
|
|
218
|
+
- Check server logs for initialization issues
|
|
219
|
+
|
|
220
|
+
### "Session termination failed: 400"
|
|
221
|
+
- This is harmless and automatically suppressed
|
|
222
|
+
- Occurs during FastMCP library cleanup
|
|
223
|
+
- No action needed
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Contributing to Forbin
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Forbin! This document provides guidelines and information for contributors.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
1. **Fork the repository** on GitHub
|
|
8
|
+
2. **Clone your fork** locally:
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/yourusername/forbin.git
|
|
11
|
+
cd forbin
|
|
12
|
+
```
|
|
13
|
+
3. **Install dependencies**:
|
|
14
|
+
```bash
|
|
15
|
+
uv sync
|
|
16
|
+
# or
|
|
17
|
+
pip install -r requirements.txt
|
|
18
|
+
```
|
|
19
|
+
4. **Set up your environment**:
|
|
20
|
+
```bash
|
|
21
|
+
cp .env.example .env
|
|
22
|
+
# Edit .env with your test MCP server details
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Development Workflow
|
|
26
|
+
|
|
27
|
+
1. **Create a branch** for your feature or bugfix:
|
|
28
|
+
```bash
|
|
29
|
+
git checkout -b feature/your-feature-name
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
2. **Make your changes** following the code style guidelines below
|
|
33
|
+
|
|
34
|
+
3. **Test your changes**:
|
|
35
|
+
```bash
|
|
36
|
+
# Test connectivity
|
|
37
|
+
python forbin.py --test
|
|
38
|
+
|
|
39
|
+
# Test interactive mode
|
|
40
|
+
python forbin.py
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
4. **Commit your changes**:
|
|
44
|
+
```bash
|
|
45
|
+
git add .
|
|
46
|
+
git commit -m "Add feature: description of your changes"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
5. **Push to your fork**:
|
|
50
|
+
```bash
|
|
51
|
+
git push origin feature/your-feature-name
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
6. **Open a Pull Request** on GitHub
|
|
55
|
+
|
|
56
|
+
## Code Style Guidelines
|
|
57
|
+
|
|
58
|
+
- **Python version**: Target Python 3.11+
|
|
59
|
+
- **Line length**: 100 characters (configured in `pyproject.toml`)
|
|
60
|
+
- **Formatting**: We use Black for code formatting
|
|
61
|
+
```bash
|
|
62
|
+
black forbin.py
|
|
63
|
+
```
|
|
64
|
+
- **Linting**: We use Ruff for linting
|
|
65
|
+
```bash
|
|
66
|
+
ruff check forbin.py
|
|
67
|
+
```
|
|
68
|
+
- **Type hints**: Use type hints where appropriate
|
|
69
|
+
- **Docstrings**: Use docstrings for functions, following Google style
|
|
70
|
+
|
|
71
|
+
## What to Contribute
|
|
72
|
+
|
|
73
|
+
### Good First Issues
|
|
74
|
+
|
|
75
|
+
- Improve error messages
|
|
76
|
+
- Add support for new parameter types
|
|
77
|
+
- Enhance display formatting
|
|
78
|
+
- Update documentation
|
|
79
|
+
|
|
80
|
+
### Feature Ideas
|
|
81
|
+
|
|
82
|
+
- Support for environment variable expansion in parameters
|
|
83
|
+
- Save/load parameter presets for frequent tool calls
|
|
84
|
+
- Export tool call results to file
|
|
85
|
+
- Batch tool calling
|
|
86
|
+
- Non-interactive mode for scripting
|
|
87
|
+
|
|
88
|
+
### Bug Reports
|
|
89
|
+
|
|
90
|
+
When reporting bugs, please include:
|
|
91
|
+
- Your Python version (`python --version`)
|
|
92
|
+
- Your operating system
|
|
93
|
+
- Steps to reproduce the issue
|
|
94
|
+
- Expected vs actual behavior
|
|
95
|
+
- Relevant error messages
|
|
96
|
+
|
|
97
|
+
## Testing
|
|
98
|
+
|
|
99
|
+
We have comprehensive automated testing with pytest:
|
|
100
|
+
|
|
101
|
+
**Run all tests:**
|
|
102
|
+
```bash
|
|
103
|
+
make test
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Run specific test types:**
|
|
107
|
+
```bash
|
|
108
|
+
make test-unit # Unit tests only
|
|
109
|
+
make test-integration # Integration tests only
|
|
110
|
+
make test-coverage # With coverage report
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Writing tests:**
|
|
114
|
+
- Add unit tests to `tests/test_main.py`
|
|
115
|
+
- Add integration tests to `tests/test_integration.py`
|
|
116
|
+
- Use fixtures from `tests/conftest.py`
|
|
117
|
+
- Mark async tests with `@pytest.mark.asyncio`
|
|
118
|
+
|
|
119
|
+
**Example test:**
|
|
120
|
+
```python
|
|
121
|
+
import pytest
|
|
122
|
+
from unittest.mock import AsyncMock
|
|
123
|
+
|
|
124
|
+
@pytest.mark.asyncio
|
|
125
|
+
async def test_new_feature(mock_mcp_client):
|
|
126
|
+
"""Test description."""
|
|
127
|
+
result = await your_function()
|
|
128
|
+
assert result == expected
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Manual testing:**
|
|
132
|
+
1. Set up a test MCP server (local or remote)
|
|
133
|
+
2. Test connectivity with `make run-test`
|
|
134
|
+
3. Test interactive mode with `make run`
|
|
135
|
+
4. Verify new features work as expected
|
|
136
|
+
|
|
137
|
+
**Coverage requirements:**
|
|
138
|
+
- New code should maintain or improve coverage
|
|
139
|
+
- Check coverage with `make test-coverage`
|
|
140
|
+
- View HTML report: `open htmlcov/index.html`
|
|
141
|
+
|
|
142
|
+
## Documentation
|
|
143
|
+
|
|
144
|
+
When adding features:
|
|
145
|
+
- Update `README.md` with usage examples
|
|
146
|
+
- Update `CLAUDE.md` with implementation details
|
|
147
|
+
- Add comments for complex logic
|
|
148
|
+
- Update `--help` text if adding CLI arguments
|
|
149
|
+
|
|
150
|
+
## Pull Request Guidelines
|
|
151
|
+
|
|
152
|
+
- **Keep PRs focused**: One feature or bugfix per PR
|
|
153
|
+
- **Write clear commit messages**: Explain what and why, not just how
|
|
154
|
+
- **Update documentation**: Keep docs in sync with code changes
|
|
155
|
+
- **Test thoroughly**: Verify your changes don't break existing functionality
|
|
156
|
+
- **Respond to feedback**: Be open to suggestions and iteration
|
|
157
|
+
|
|
158
|
+
## Questions or Need Help?
|
|
159
|
+
|
|
160
|
+
- Open an issue on GitHub
|
|
161
|
+
- Check existing issues and PRs for similar topics
|
|
162
|
+
- Review the `CLAUDE.md` file for implementation guidance
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
167
|
+
|
|
168
|
+
Thank you for contributing to Forbin!
|
forbin_mcp-0.1.0/DOCS.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Forbin Technical Documentation
|
|
2
|
+
|
|
3
|
+
This document provides a detailed look at how Forbin works under the hood, its connection logic, and its user interface components.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
### Wake-Up Process
|
|
8
|
+
|
|
9
|
+
For suspended services (like Fly.io apps), Forbin uses a orchestrated three-step approach to ensure the server is ready before attempting an MCP connection:
|
|
10
|
+
|
|
11
|
+
1. **Health Check Wake-Up**
|
|
12
|
+
- Polls the configured `MCP_HEALTH_URL` until it returns a successful (200 OK) response.
|
|
13
|
+
- **Limit:** 6 attempts with 5-second intervals (30 seconds total).
|
|
14
|
+
- This triggers the cloud provider to wake up the suspended instance.
|
|
15
|
+
|
|
16
|
+
2. **Initialization Wait**
|
|
17
|
+
- Once the health endpoint responds, Forbin waits for an additional **20 seconds**.
|
|
18
|
+
- This gives the MCP server time to fully initialize its inner services after the container has started.
|
|
19
|
+
|
|
20
|
+
3. **Connection with Retry**
|
|
21
|
+
- Connects to the MCP server with an extended `init_timeout` of **30 seconds**.
|
|
22
|
+
- **Retry logic:** 3 attempts with 5-second waits between them if the connection fails or times out.
|
|
23
|
+
|
|
24
|
+
This process ensures reliable connections even to cold-started servers that might take significant time to become "fully" ready for MCP traffic.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## User Interface
|
|
29
|
+
|
|
30
|
+
### Step Indicators
|
|
31
|
+
|
|
32
|
+
Throughout the connection and execution process, Forbin displays step indicators to show progress.
|
|
33
|
+
|
|
34
|
+
| Color | Icon | Meaning |
|
|
35
|
+
|-------|------|---------|
|
|
36
|
+
| **Yellow** | > | **In Progress** - The current action is being performed. |
|
|
37
|
+
| **Green** | + | **Success** - The step completed successfully. |
|
|
38
|
+
| **Dim/Grey** | - | **Skip** - This step was skipped (e.g., wake-up skipped if no health URL). |
|
|
39
|
+
|
|
40
|
+
### Anytime Logging Toggle
|
|
41
|
+
|
|
42
|
+
Forbin includes a background listener that monitors for the **`v`** keypress.
|
|
43
|
+
|
|
44
|
+
- **Non-blocking:** You can toggle logging even while Forbin is waiting for a health check or establishing a connection.
|
|
45
|
+
- **Real-time unsuppression:** When logging is toggled **ON**, Forbin's `FilteredStderr` immediately stops suppressing typical MCP library warnings and errors, showing you full tracebacks and connection details.
|
|
46
|
+
- **Visual Feedback:** A notification will appear in the CLI whenever the logging state changes.
|
|
47
|
+
|
|
48
|
+
### Interactive Tool Browser
|
|
49
|
+
|
|
50
|
+
1. **Discovery:** Forbin lists all tools provided by the MCP server.
|
|
51
|
+
2. **Inspection:** Selecting a tool shows its description and parameter requirements.
|
|
52
|
+
3. **Execution:** Forbin prompts for each parameter, performing basic type validation:
|
|
53
|
+
- **Strings:** Direct input.
|
|
54
|
+
- **Booleans:** Accepts `true`, `false`, `y`, `n`, `1`, `0`.
|
|
55
|
+
- **Numbers:** Parses integers and floats.
|
|
56
|
+
- **Objects/Arrays:** Parses local JSON strings.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Error Handling Details
|
|
61
|
+
|
|
62
|
+
- **Session termination errors:** FastMCP sometimes returns a 400 error when a session is closed. Forbin automatically suppresses these harmless warnings.
|
|
63
|
+
- **Connection retries:** Uses exponential backoff and fresh client instantiation for each retry to recover from transient network issues.
|
|
64
|
+
- **Timeout management:** Specifically tuned timeouts for discovery (15s) and tool execution (30s+).
|