Install
$ agentstack add mcp-guptayush02-adaptora ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ● Shell / process execution Used
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Adaptora
A self-hosted Dynamic API Agent with an MCP (Model Context Protocol) layer on top. Talk to any REST API in natural language — the agent discovers the docs, handles auth, plans the HTTP call, and executes it. Plug it into Claude Desktop, Cursor, Cline, n8n, or any MCP-compatible client to give your AI assistant access to every API you can describe.
> Bring-your-own-LLM. Runs locally with Ollama (default: qwen2.5-coder:3b). Optional Anthropic/OpenAI keys for tougher queries. No SaaS dependencies.
Demo
https://github.com/user-attachments/assets/62dad55a-a0a3-46d8-a689-bca21e9007db
Setting up a tool in Adaptora and running it on the Docker stack — plays right here on GitHub. ▶️ Watch in HD on YouTube
> "list my open GitHub issues assigned to me"
[agent] identifying tool... github
[agent] loading docs... 122 endpoints cached
[agent] planning action... GET /issues?filter=assigned&state=open
[agent] executing...
[agent] You have 7 open issues. Top 3:
1. #482 — Bug: cache invalidation race (opened 2 days ago)
2. #481 — Doc fetcher should support YAML specs
3. #475 — Streaming endpoint for /tools/refresh
Why Adaptora?
Connecting an LLM to real APIs usually breaks on the unglamorous parts: hunting down docs, wiring up auth, hand-writing a JSON schema for every endpoint, and one malformed argument silently killing the call. Adaptora owns that boundary for you — point it at any API and it discovers the docs, stores your credentials encrypted, turns every endpoint into a typed tool, and runs it from plain language through MCP, a REST API, or the web UI.
Key Features
- Dynamic Tool Discovery — Type a tool name (
github,stripe,shopify,notion, …) or describe what you want to do, and the agent fetches its docs, OpenAPI spec, and rate limits automatically. Curated seed tools (github, aws, stripe, slack, notion, openai, razorpay, linear, gmail) ship pre-configured. - Multi-source doc fetching — Web search + OpenAPI spec probing (24+ URL patterns) + native parsing + LLM extraction, merged with method/path deduplication. Refreshing
githubgrows from 5 → 120+ endpoints; AWS uses localboto3introspection for 49+. - MCP Server — Exposes the agent over the Model Context Protocol. Every connected tool's endpoints become typed MCP tools your AI assistant can call directly.
- REST API + developer keys — Mint a secret key on the dashboard and call Adaptora from any project in any language (
POST /api/v1/runwithAuthorization: Bearer adp_live_…). Every call runs against your saved connections and is logged, tagged by key and tool, on the dashboard. A streaming variant (POST /api/v1/run/stream, Server-Sent Events) emits each pipeline step as it happens so you can render the agent's progress live in your own UI. - Live execution logs — The dashboard Logs page tails every run from every source (Web UI, MCP, and
/api/v1) in real time over SSE. In-flight runs appear as a live row at the top of the table that updates step-by-step, then settle into the completed-run history once done. - Authenticated chat UI — React frontend with per-user encrypted credential storage (AES), conversation history, streaming SSE responses, and a "Cached Tools" page with live refresh progress.
- Token tracking & caching — Tracks every model call, caches identical prompts, routes simple queries to local Ollama and complex ones to Claude/GPT (optional).
- One-command Docker deploy — 3-container stack (app, Postgres, Redis) wired with healthchecks and persistent volumes; the LLM (Ollama) runs natively on the host so it can use your GPU.
Quick Start
Option 1 — Docker (recommended)
The app, Postgres and Redis run in containers. The LLM (Ollama) runs natively on your host — on macOS the Apple GPU can't be passed into Docker, so a containerised Ollama would be CPU-only and very slow (~100 s per call for 7b). Running Ollama on the host lets it use your GPU.
git clone https://github.com/guptayush02/adaptora.git
cd adaptora
# 1. Set up the LLM locally (on the host, not in Docker)
# Install Ollama from https://ollama.com/download (or `brew install ollama`)
ollama serve & # start the daemon (uses your GPU)
ollama pull qwen2.5-coder:7b # or qwen2.5-coder:3b for a smaller/faster one
# 2. Configure — point the app at your local model
cp .env.docker.example .env.docker
# .env.docker already sets, and is the single source of truth for, both:
# OLLAMA_MODEL=qwen2.5-coder:7b
# OLLAMA_API_URL=http://host.docker.internal:11434 # container → host Ollama
# Also set SECRET_KEY. Make sure OLLAMA_MODEL matches the model you pulled.
# 3. Bring up the stack (app + db + cache)
docker compose --env-file .env.docker up --build
# 4. Open the web UI
open http://localhost:8000
> host.docker.internal is how a container reaches a service on the Mac/Windows host. Keep ollama serve running on the host whenever you use the stack.
> No Ollama container by default. The ollama service sits behind the with-ollama compose profile, so docker compose up -d --build builds and starts only app, db and cache — it never builds or launches an Ollama container. The container is opt-in via --profile with-ollama (see below).
Running Ollama inside Docker instead (Linux / NVIDIA hosts)
On a Linux host with an NVIDIA GPU, a container can use the GPU. To run everything in one stack, point the app at the container service and enable the optional profile:
# in .env.docker:
# OLLAMA_API_URL=http://ollama:11434
docker compose --env-file .env.docker --profile with-ollama up --build
For GPU passthrough, install the nvidia-container-toolkit and uncomment the deploy.resources.devices block on the ollama service in [docker-compose.yml](./docker-compose.yml).
Option 2 — Local (no Docker)
Useful for development. You'll need Python 3.11+, Node 18+, Ollama, and Redis running on your host.
# Backend
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# Install the headless browser used to render JS-heavy doc sites (one-time).
# Docker does this automatically; for a local install you must run it yourself,
# or doc rendering fails with "Executable doesn't exist … run playwright install".
playwright install chromium
# Pull the LLM
ollama pull qwen2.5-coder:3b
# Frontend
cd frontend && npm install && npm run build && cd ..
# Configure
cp .env.example .env # edit OLLAMA_API_URL, REDIS_URL, etc.
# Run (DB auto-initialises on first start)
python -m uvicorn main:app --host 0.0.0.0 --port 8000
# open http://localhost:8000
Using the MCP Server
The MCP server runs as a subprocess that any MCP client can talk to over JSON-RPC stdio — your AI assistant launches python mcp_server.py.
> **Important — the MCP server must talk to the same database as your web UI. It reads credentials/connections by user, so if the two point at different databases, you'll see User not found and tools won't connect. Pick the launch style that matches how you run Adaptora: > > - Running the full stack with Docker Compose?** The app stores everything in the Postgres container, not in a local token_optimizer.db. Launch the MCP server inside the running container with docker exec so it inherits the container's DATABASE_URL/SECRET_KEY. See [Docker stack](#quickest-path--claude-desktop-docker-stack) below. > - Running locally (no Docker)? Launch host python mcp_server.py directly — it uses the same local SQLite DB the app does. See [Local install](#quickest-path--claude-desktop-local-install) below. > > A host python mcp_server.py started while the stack runs in Docker defaults to an empty local SQLite DB — that mismatch is the #1 cause of User not found.
What you get
| Always-on meta-tools | What it does | |---|---| | setup_new_tool | Discover docs for any tool (web search → OpenAPI probe → LLM extract → merge) and seed it | | refresh_tool_docs | Re-fetch the latest docs (equivalent to the UI's Refresh button) | | list_known_tools | Every cached tool with endpoint counts | | list_connections | Which tools you've authenticated | | run_action | Natural-language dispatch through the full Dynamic Agent pipeline |
Plus dynamic per-endpoint tools: every endpoint of every connected tool becomes its own MCP tool with a typed input schema (github_list_repos, stripe_create_charge, etc.). Newly connected tools appear automatically — no restart required.
Setup for various clients
Full step-by-step configs for 8+ clients are in [docs/MCPCLIENTS.md](./docs/MCPCLIENTS.md):
- Claude Desktop (macOS / Windows)
- Claude Code (Anthropic CLI)
- Cursor (IDE)
- Cline (VS Code extension)
- Continue.dev (VS Code / JetBrains)
- Zed (editor)
- n8n / make.com (workflow automation)
- Custom Python / TypeScript clients
Config file location:
- macOS:
~/Library/Application\ Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
> On macOS, quote the path if you cat/cp it — it contains a space (Application Support). Unquoted, the shell splits it into two paths and reads/writes the wrong file.
Quickest path — Claude Desktop (Docker stack)
Use this when you brought the stack up with docker compose up. The MCP server runs inside the adaptora-app container, so it automatically inherits the same Postgres DATABASE_URL and SECRET_KEY as the web app — you only pass your email.
{
"mcpServers": {
"adaptora": {
"command": "/usr/local/bin/docker",
"args": [
"exec", "-i",
"-e", "MCP_USER_EMAIL=you@example.com",
"adaptora-app",
"python", "mcp_server.py"
]
}
}
}
Prerequisites: the adaptora-app container must be running (docker ps), and MCP_USER_EMAIL must match an email that exists in the Postgres DB:
docker exec -i adaptora-db psql -U tokopt -d tokopt -c "SELECT id, email FROM users;"
Adaptora running on a remote server (VPS / cloud) — connect over SSH
The configs above launch the MCP server on your own computer. But if you've deployed Adaptora on a remote machine (a DigitalOcean droplet, an AWS EC2 instance, a Hetzner VPS, your office server…), your AI assistant still runs on your laptop — and it can't reach the server's database directly. Launching a local mcp_server.py would talk to an empty local database and fail with User not found.
The fix: tell your assistant to start the MCP server on the remote machine, over SSH. SSH is the standard, secure way to run a command on another computer; it carries the MCP messages back and forth over the same encrypted connection your assistant already needs. No code changes, no extra ports to open — if you can ssh into the box, this works.
{
"mcpServers": {
"adaptora": {
"command": "ssh",
"args": [
"user@your-server.com",
"docker", "exec", "-i",
"-e", "MCP_USER_EMAIL=you@example.com",
"adaptora-app",
"python", "mcp_server.py"
]
}
}
}
What is user@your-server.com? It's the exact same thing you type to log into your server with SSH — ssh user@your-server.com — split into two parts:
| Part | What it means | Examples | |---|---|---| | user (before the @) | Your login username on the server | ubuntu (common on AWS), root, ayush | | your-server.com (after the @) | The server's address — its domain name or its public IP address | adaptora.mycompany.com, 203.0.113.42 |
So if you log into your server with ssh ubuntu@203.0.113.42, then you'd write "ubuntu@203.0.113.42" on that first line. Don't copy user@your-server.com literally — replace it with your real values.
Before this works, check three things:
- You can SSH in without typing a password. Your assistant runs
ssh
unattended, so it can't answer a password prompt. Set up key-based login (GitHub's SSH key guide works for any server) and confirm ssh user@your-server.com logs you in with no prompt.
- The
adaptora-appcontainer is running on the server. SSH in and run
docker ps — you should see adaptora-app.
MCP_USER_EMAILmatches a real account. Check on the server with the
psql command shown just above.
> Not using Docker on the server? Replace the docker exec … part with the > path to the remote Python and script, e.g. > "user@your-server.com", "/path/to/adaptora/venv/bin/python", "/path/to/adaptora/mcp_server.py", > and move MCP_USER_EMAIL into an SSH-set env var or the command itself.
Quickest path — Claude Desktop (local install)
Use this when you run Adaptora directly on your host (no Docker) — the server shares the app's local SQLite DB.
{
"mcpServers": {
"adaptora": {
"command": "/ABSOLUTE/PATH/TO/adaptora/venv/bin/python",
"args": ["/ABSOLUTE/PATH/TO/adaptora/mcp_server.py"],
"env": { "MCP_USER_EMAIL": "you@example.com" }
}
}
}
Restart Claude Desktop. The hammer icon now lists setup_new_tool, run_action, and every connected tool's endpoints.
Quickest path — Claude Code (CLI)
# Find which email your web-UI account uses
/ABSOLUTE/PATH/TO/adaptora/venv/bin/python \
/ABSOLUTE/PATH/TO/adaptora/mcp_server.py --list-users
# Register the server
claude mcp add adaptora \
--scope user \
--transport stdio \
--env MCP_USER_EMAIL=you@example.com \
-- \
/ABSOLUTE/PATH/TO/adaptora/venv/bin/python \
/ABSOLUTE/PATH/TO/adaptora/mcp_server.py
Verify:
claude mcp list
# adaptora: … - ✓ Connected
Start a session:
claude
> /mcp # confirms adaptora is listed
> List my open GitHub issues # → calls run_action under the hood
> Set up shopify with the Admin API # → calls setup_new_tool
> Refresh the docs for stripe # → calls refresh_tool_docs
Using the REST API (developer keys)
Want to call Adaptora from your own app — a backend service, a script, a cron job — instead of an MCP client? Mint a developer secret key on the dashboard and hit the public REST API. The key authenticates as you, so every call runs against the tools you've already connected.
1. Create a key
In the web UI, open Developer Keys in the sidebar → New key → give it a name (e.g. production-backend). The secret (adp_live_…) is shown once — copy it now; only its hash is stored, so it can never be retrieved again. Revoke a key anytime from the same page (calls using it immediately start returning 401).
2. Call POST /api/v1/run
Send your prompt with the key as a bearer token. The agent identifies the right service, plans the call, executes it against your saved credentials, and returns the result:
curl -X POST http://localhost:8000/api/v1/run \
-H "Authorization: Bearer adp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "list my open github issues"}'
# Python
import requests
resp = requests.post(
"http://localhost:8000/api/v1/run",
headers={"Authorization": "Bearer adp_live_YOUR_KEY"},
json={"prompt": "list my open github issues"},
)
print(resp.json())
// Node.js (fetch)
const resp = await fetch("http://localhost:8000/api/v1/run", {
method: "POST",
headers: {
"Authorization": "Bearer adp_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.string
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [guptayush02](https://github.com/guptayush02)
- **Source:** [guptayush02/adaptora](https://github.com/guptayush02/adaptora)
- **License:** MIT
- **Homepage:** https://www.linkedin.com/company/113237472/admin/page-posts/published/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.