contra
README.md
# Contra MCP Starter Toolkit ⚡
[](https://nodejs.org)
[](https://modelcontextprotocol.io/)
[](https://github.com/alexandernevsky/contra-mcp-starter)
[](https://opensource.org/licenses/MIT)
[](https://contra.com)
> **Zero-dependency starter kit and automation SDK for managing your [Contra](https://contra.com) profile, flagship services, and portfolio case studies using Model Context Protocol (MCP) and AI coding agents (Google Antigravity, Cursor, Windsurf, Claude Code).**
[English](README.md) • [Русская версия](README.ru.md)
---
## Overview
[Contra](https://contra.com) is the premier commission-free platform for independent builders, product designers, and engineers. Contra natively provides a powerful **remote MCP endpoint** (`https://contra.com/mcp`) offering 119 programmatic tools to manage profiles, case studies, productized services, contracts, and proposals.
However, connecting AI agents to Contra typically involves complex OAuth 2.0 PKCE handshakes, expiring 1-hour access tokens, and navigating destructive write boundaries.
This repository provides an open-source, production-tested solution:
- **1-Click Interactive OAuth 2.0 PKCE**: Authenticates your Contra account in seconds via local callback server.
- **Zero External Dependencies**: Powered purely by native Node.js 18+ runtime (`fetch`, `crypto`, `http`).
- **Auto-Refreshing SDK Client**: Catches HTTP `401 Unauthorized` and silently renews access tokens using your `refresh_token`.
- **Two-Phase Safety Protocol (`prepare → confirm`)**: Guarantees AI coding agents never silently overwrite or mutate your public profile without human approval.
- **Content-as-Code Templates**: Ready-to-use Markdown templates for high-converting profile positioning, 3 flagship services (with monthly rates & FAQs), and structured case studies.
---
## Architecture
```text
┌────────────────────────────────────────────────────────┐
│ Your AI Coding Assistant │
│ (Google Antigravity / Cursor / Claude Code / Windsurf)│
└───────────────────────────┬────────────────────────────┘
│ (Calls MCP Tools)
▼
┌────────────────────────────────────────────────────────┐
│ Local Contra SDK Client (scripts/contra-client.mjs)│
│ - Reads contra_token.json │
│ - Auto-refreshes expired 1-hour sessions on 401 │
│ - Implements prepare -> review -> confirm workflow │
└───────────────────────────┬────────────────────────────┘
│ (Bearer Authorization)
▼
┌────────────────────────────────────────────────────────┐
│ Remote Contra MCP Server (https://contra.com/mcp) │
│ - 119 Official Tools (Profile, Services, Projects...) │
│ - Cloudinary Media Pipeline │
└────────────────────────────────────────────────────────┘
```
---
## Quickstart (2 Minutes)
### 1. Clone the repository
```bash
git clone https://github.com/alexandernevsky/contra-mcp-starter.git
cd contra-mcp-starter
```
### 2. Authenticate with Contra
Run the zero-dependency authenticator:
```bash
npm run auth
```
This will:
1. Dynamically register a secure local OAuth client with Contra.
2. Automatically open your default browser to authorize your account.
3. Capture the OAuth callback code on `localhost:4567`.
4. Exchange the code for an `access_token` and `refresh_token`.
5. Save the token securely to `contra_token.json` (strictly git-ignored).
### 3. Choose your workflow:
#### 🤖 Option A: Autonomous AI Mode (Zero Coding Required — Recommended)
Open this folder in **Cursor**, **Google Antigravity**, **Claude Code**, or **Windsurf**.
Simply copy and paste any prompt from **[`PROMPTS.md`](PROMPTS.md)** into the chat:
> *"Connect to my Contra via MCP. Read `templates/services.example.md` and `templates/profile.example.md`, inspect my live profile, and prepare the updates with a preview before applying."*
Your AI agent reads [`AGENTS.md`](AGENTS.md), executes the tools, formats your offerings, and shows you the exact before/after diff for approval. **You never write a line of code.**
#### 🛠️ Option B: Developer CLI & SDK Mode
If you prefer running commands manually in your terminal:
```bash
npm run whoami # Verify authenticated profile
npm run services # Inspect offered services & monthly rates
npm run projects # Inspect portfolio case studies & work posts
```
---
## Connecting to AI Coding Agents
### 1. Google Antigravity
The authenticator script automatically detects and updates your global `~/.gemini/config/mcp_config.json`:
```json
{
"mcpServers": {
"contra": {
"serverUrl": "https://contra.com/mcp",
"headers": {
"Authorization": "Bearer <YOUR_ACCESS_TOKEN>"
}
}
}
}
```
### 2. Cursor IDE
Add the remote MCP server to your Cursor workspace settings (`.cursor/mcp.json`):
```json
{
"mcpServers": {
"contra": {
"url": "https://contra.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
}
}
}
}
```
### 3. Claude Code / Claude Desktop
Add to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"contra": {
"command": "node",
"args": ["/path/to/contra-mcp-starter/scripts/contra-client.mjs"]
}
}
}
```
---
## The Safety Protocol: Prepare & Confirm
Contra MCP enforces a strict two-phase commit protocol on write operations to ensure safety.
### Example: Updating a Service
```javascript
import { callContraTool } from "./scripts/contra-client.mjs";
// Step 1: Prepare draft (no database changes)
const draft = await callContraTool("update_productized_service_prepare", {
slug: "your-service-slug",
price: {
type: "RATE",
amount: 6000,
interval: "MONTH"
}
});
// Step 2: Human Review Phase
console.log("Review changes:", draft.preview.changes);
// Step 3: Confirm update (commits to live database)
await callContraTool("update_productized_service_confirm", {
draftId: draft.draftId,
confirm: true
});
```
> [!IMPORTANT]
> **Full-Replacement Fields Warning:**
> In Contra MCP, array fields (`deliverables`, `faqs`, `tags`, `roles`, `tools`) behave as **full replacements**. Passing a list replaces the entire existing list on Contra. To preserve existing items, omit the field entirely from your update.
---
## Directory Structure
```text
contra-mcp-starter/
├── AGENTS.md # Operational rules for AI assistants
├── README.md # English documentation (this file)
├── README.ru.md # Russian documentation
├── package.json # Zero-dependency npm scripts
├── .gitignore # Strict token & secret isolation
│
├── scripts/
│ ├── auth.mjs # Interactive OAuth 2.0 PKCE CLI
│ ├── contra-client.mjs # Auto-refreshing MCP client SDK
│ └── examples/
│ ├── whoami.mjs # Profile inspector
│ ├── inspect-services.mjs # Services listing
│ ├── inspect-projects.mjs # Case studies & work posts listing
│ └── prepare-service-update.mjs # Safe two-phase commit demo
│
└── templates/
├── profile.example.md # Bio, headline & social links template
├── services.example.md # 3 flagship services architecture
└── case-study.example.md # High-impact case study structure
```
---
## Technical Constraints & Contra Architecture
1. **Unique Slug NanoIDs**: Every project and service on Contra begins with an 8-character ID (e.g. `cO2eXAUv-...`). This prefix is Contra's database lookup key because routes are global (`contra.com/p/...`). The text after the hyphen is automatically derived from your `title`.
2. **Cover Images vs Videos**:
- `coverImageUrl` in MCP accepts public image URLs (PNG, JPG, WebP) and automatically mirrors them to Cloudinary.
- Video covers (MP4) must be uploaded via the Contra web editor.
- Videos inside project bodies (`content`) are supported via standalone YouTube and Vimeo URLs.
3. **Projects vs Work Posts**:
- `projects` are full portfolio case studies with complete MCP CRUD support.
- `workPosts` are community feed items and cannot be edited via MCP.
---
## Contributing
Contributions, feedback, and issue reports are welcome! Feel free to open an issue or submit a pull request.
---
## License
MIT License © 2026 [Alexander Nevsky](https://contra.com/alexander_nevsky). Built for the global independent builder community.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues