chatgpt-jules-mcp
Secure MCP server allowing ChatGPT to manage Google Jules sessions through OpenAI Secure MCP Tunnel.
README
chatgpt-jules-mcp
Secure MCP server allowing ChatGPT to manage Google Jules sessions through OpenAI Secure MCP Tunnel.
Architecture
ChatGPT
-> OpenAI Secure MCP Tunnel
-> tunnel-client (your MacBook)
-> chatgpt-jules-mcp (stdio)
-> jules-agent-sdk
-> Google Jules
-> GitHub repository
No public HTTP. No Tailscale Funnel. No raw arbitrary HTTP.
Security Features
- Policy-based access control (
policy.yaml) — allowlist sources, titles, tools - Confirmation gate for
jules.approve_plan - Audit logging (JSONL) — every tool call recorded with metadata
- Secret redaction — JULES_API_KEY, tokens, private keys scrubbed from all output
- Rate limiting — per-tool, configurable via policy
- Error boundary — all exceptions caught, sanitized, never leak secrets
- No generic HTTP tools — only Jules-specific operations
Quick Start
# Install from PyPI
pip install chatgpt-jules-mcp
# Or install in development mode
pip install -e ".[dev]"
# Set credentials
export JULES_API_KEY="your-jules-api-key"
# Configure policy
mkdir -p ~/.config/chatgpt-jules-mcp
cp config/policy.example.yaml ~/.config/chatgpt-jules-mcp/policy.yaml
# Edit: add your sources to allowed_sources
# Run MCP server (module)
python -m chatgpt_jules_mcp
# Or with CLI script (installed via pip)
chatgpt-jules-mcp
# Or with custom config
python -m chatgpt_jules_mcp --config /path/to/policy.yaml
chatgpt-jules-mcp --config /path/to/policy.yaml
MCP Tools (14)
| Tool | Category | Description |
|---|---|---|
jules.health |
Diagnostics | Server status, API key check, policy load |
jules.list_sources |
Sources | List allowed GitHub sources |
jules.get_source |
Sources | Get single source details |
jules.find_source |
Sources | Fuzzy search sources (client-side) |
jules.create_session |
Sessions | Create Jules session with policy checks |
jules.get_session |
Sessions | Get session status |
jules.list_sessions |
Sessions | List sessions (filtered by policy) |
jules.approve_plan |
Sessions | Approve plan (requires confirmation) |
jules.send_message |
Sessions | Send follow-up message |
jules.wait_for_completion |
Sessions | Poll until session completes |
jules.list_activities |
Activities | List session activities |
jules.get_activity |
Activities | Get single activity |
jules.summarize_session |
Convenience | Best-effort session summary |
jules.extract_result |
Convenience | Extract final result from activities |
Project Structure
chatgpt-jules-mcp/
├── src/chatgpt_jules_mcp/
│ ├── server.py # FastMCP server, tool registration
│ ├── policy.py # Policy engine (YAML load, validate, enforce)
│ ├── audit.py # JSONL audit logger
│ ├── redaction.py # Secret pattern redaction
│ ├── errors.py # Custom exceptions, error boundary
│ ├── ratelimit.py # In-memory rate limiter
│ ├── shutdown.py # Graceful shutdown (SIGTERM/SIGINT)
│ ├── tools/
│ │ ├── health.py # jules.health
│ │ ├── sources.py # list_sources, get_source, find_source
│ │ ├── sessions.py # create_session, get_session, list_sessions, approve_plan, send_message, wait_for_completion
│ │ ├── activities.py # list_activities, get_activity
│ │ └── convenience.py # summarize_session, extract_result
├── tests/ # 103 tests across 10 test files
├── config/
│ └── policy.example.yaml # Example policy configuration
├── scripts/
│ └── emergency-stop.sh # Kill switch
└── docs/
└── openai-secure-mcp-tunnel.md # Tunnel setup guide
Configuration
Policy is controlled via ~/.config/chatgpt-jules-mcp/policy.yaml:
jules:
allowed_sources:
- "sources/your-repo"
default_require_plan_approval: true
sessions:
allowed_title_prefixes:
- "ChatGPT:"
max_prompt_chars: 12000
max_message_chars: 8000
tools:
allow:
- "jules.health"
- "jules.list_sources"
# ... see policy.example.yaml for full list
require_confirmation:
- "jules.approve_plan"
audit:
path: "~/.local/share/chatgpt-jules-mcp/audit.jsonl"
redact_secrets: true
Tests
pip install pytest pytest-asyncio
PYTHONPATH=src python -m pytest tests/ -v
50 tests covering: policy engine, audit logging, redaction, rate limiting, all 14 tools, error handling, input validation, secret redaction in transit.
OpenAI Secure MCP Tunnel
See docs/openai-secure-mcp-tunnel.md for full setup.
Quick version:
export CONTROL_PLANE_API_KEY="sk-..."
export CONTROL_PLANE_TUNNEL_ID="tunnel_..."
export JULES_API_KEY="..."
tunnel-client init \
--sample sample_mcp_stdio_local \
--profile chatgpt-jules-mcp-local \
--tunnel-id "$CONTROL_PLANE_TUNNEL_ID" \
--mcp-command "python -m chatgpt_jules_mcp"
tunnel-client doctor --profile chatgpt-jules-mcp-local --explain
tunnel-client run --profile chatgpt-jules-mcp-local
Emergency Stop
./scripts/emergency-stop.sh
Production Deployment
Security Checklist
- [ ] Set
allowed_sourcesto specific repositories (nevernullin production) - [ ] Set
allowed_title_prefixesto restrict session titles - [ ] Disable
log_full_prompts(keepfalse) - [ ] Set
redact_secrets: true - [ ] Restrict audit log file permissions (
chmod 600 audit.jsonl) - [ ] Run behind OpenAI Secure MCP Tunnel (no public HTTP)
- [ ] Set rate limits appropriate for your usage (
calls_per_minute) - [ ] Review and customize
redaction.patternsfor your environment
systemd Service (Linux)
Create /etc/systemd/system/chatgpt-jules-mcp.service:
[Unit]
Description=ChatGPT Jules MCP Server
After=network.target
[Service]
Type=simple
User=chatgpt-jules
Group=chatgpt-jules
Environment="JULES_API_KEY=your-key-here"
Environment="PYTHONUNBUFFERED=1"
WorkingDirectory=/opt/chatgpt-jules-mcp
ExecStart=/opt/chatgpt-jules-mcp/.venv/bin/python -m chatgpt_jules_mcp
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable chatgpt-jules-mcp
sudo systemctl start chatgpt-jules-mcp
sudo systemctl status chatgpt-jules-mcp
Docker
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -e ".[dev]"
ENV PYTHONUNBUFFERED=1
USER 1000
CMD ["python", "-m", "chatgpt_jules_mcp"]
docker build -t chatgpt-jules-mcp .
docker run -e JULES_API_KEY=... chatgpt-jules-mcp
License
Apache-2.0
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.