Freelancer Ops MCP
Provides a tool for listing repository commits, used to build client status reports from development work.
Provides tools for sending messages, creating drafts, and listing threads, used for client status reports, change orders, and overdue invoice reminders.
Provides tools for inserting, listing, and quick-adding calendar events, enabling kickoff booking, billable hours tracking, and follow-up scheduling.
Provides tools for creating and retrieving documents, used for SOWs, change orders, status reports, and proposals.
Provides tools for copying files, creating permissions, listing comments, and replying to comments, supporting client onboarding and turning client feedback into tasks.
Provides a tool for appending spreadsheet values, used to turn client-tagged meetings into timesheets.
Provides tools for creating and retrieving projects and listing and creating issues, used for client project setup, status reporting, and feedback-to-task workflows.
Provides tools for managing Stripe customers, checkout sessions, invoice items, and invoices, enabling deposit links, payment collection, and overdue invoice chasing.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Freelancer Ops MCP onboard new client Acme Ltd with a $2,000 deposit and SOW from template"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Freelancer and Agency Ops
Client onboarding, invoices from calendar and commits, status reports and overdue chasers.
An MCP server with 8 workflows across Stripe, Google Drive, Linear, Google Calendar, Gmail, GitHub, Google Docs, Granola, Google Sheets and Firecrawl. Each workflow is a prompt your agent runs as a slash command, over the 26 tools it needs and no others.
uv tool install https://github.com/r28ai/freelancer-ops-mcp/releases/download/v0.1.0/freelancer_ops_mcp-0.1.0-py3-none-any.whl
claude mcp add freelance -- freelancer-ops-mcpIt installs with uv from this repository's release, with no git and nothing to build; nothing but Charter and the libraries it uses comes from PyPI. To update, run the install line from the latest release. If a desktop app cannot find freelancer-ops-mcp, give it the full path from which freelancer-ops-mcp (where freelancer-ops-mcp on Windows).
Then ask your agent to connect your apps, or run /mcp__freelance__setup.
Connect your apps
Ask the agent to connect one ("connect Linear"). It tells you where to get that app's key and the command that stores it, and the next call works, with no restart. The agent never asks for a key in the chat.
Or connect everything this server uses from a terminal:
freelancer-ops-mcp login # each app in turn
freelancer-ops-mcp login stripe # just one
freelancer-ops-mcp status # what is connectedTokens and keys go to your operating system's keychain (macOS Keychain, Windows Credential Manager, the Secret Service on Linux), and are checked with one read-only call to the app's own API before they are kept. Every key, token and OAuth client is yours: we register no app with any of these services, and nothing passes through a server of ours, because there isn't one.
App | How it connects | Or set |
Stripe | Your own key (get one), entered once. |
|
Browser sign-in, over your own OAuth client (make one). |
| |
Linear | Your own key (get one), entered once. |
|
GitHub | Your own key (get one), entered once. |
|
Granola | Your own key (get one), entered once. In the Granola app: Settings → Connectors → API keys. Business plan or above. |
|
Firecrawl | Your own key (get one), entered once. |
|
A variable set in your client's config always wins over the keychain.
Related MCP server: Marketing Ops
Workflows
Workflow | What you get | Apps |
Client onboarding | Deposit link, SOW from template, shared folder and project, for each new client. | Stripe, Google Drive, Linear |
Deposit paid → kickoff | The kickoff is booked the moment the deposit clears. | Stripe, Google Calendar, Linear, Gmail |
Client status report | A weekly report the client can read, built from the work itself. | Linear, GitHub, Google Docs, Gmail |
Scope creep detector | Asks on the call that aren't in the SOW get flagged and a change order drafted. | Granola, Google Docs, Linear, Gmail |
Billable hours from calendar | Client-tagged meetings become a timesheet and pending line items. | Google Calendar, Google Sheets, Stripe |
Overdue invoice chaser | Escalating reminders that cite the last thread, and a follow-up held on your calendar. | Stripe, Gmail, Google Calendar |
Client site audit → proposal | A prospect's site audited and turned into a scoped proposal with a pay link. | Firecrawl, Google Docs, Stripe |
Client feedback in Drive comments → tasks | Every comment the client left on a deliverable becomes a task, and they see the link. | Google Drive, Linear |
Every prompt takes one optional argument, details: the repo, team, channel, customer or date range you mean, so the agent does not have to ask. In Claude Code, put it in quotes, or only its first word arrives:
/mcp__freelance__client_onboarding "new client Acme Ltd, $2,000 deposit"Reads run without asking. Before anything that creates, sends, changes or deletes, the prompt tells the agent to show you the call and wait.
0 of the 8 workflows need no Google or Granola credential.
Other clients
Claude Desktop: install uv if you have not, since Claude Desktop starts the server with it, then open the .mcpb from the latest release. Claude asks for any keys in its own settings and keeps them in your keychain. The first start takes a few seconds longer, while uv installs it.
VS Code (.vscode/mcp.json): VS Code asks for each key the first time the server starts and stores it securely. Leave out any you stored with login.
{
"inputs": [
{
"type": "promptString",
"id": "stripe-api-key",
"description": "Stripe: Secret or restricted key",
"password": true
},
{
"type": "promptString",
"id": "google-client-secret",
"description": "Google: OAuth client secret",
"password": true
},
{
"type": "promptString",
"id": "linear-api-key",
"description": "Linear: Personal API key",
"password": true
},
{
"type": "promptString",
"id": "github-token",
"description": "GitHub: Personal access token",
"password": true
},
{
"type": "promptString",
"id": "granola-api-key",
"description": "Granola: API key",
"password": true
},
{
"type": "promptString",
"id": "firecrawl-api-key",
"description": "Firecrawl: API key",
"password": true
}
],
"servers": {
"freelance": {
"type": "stdio",
"command": "freelancer-ops-mcp",
"env": {
"STRIPE_API_KEY": "${input:stripe-api-key}",
"GOOGLE_CLIENT_SECRET": "${input:google-client-secret}",
"LINEAR_API_KEY": "${input:linear-api-key}",
"GITHUB_TOKEN": "${input:github-token}",
"GRANOLA_API_KEY": "${input:granola-api-key}",
"FIRECRAWL_API_KEY": "${input:firecrawl-api-key}",
"GOOGLE_CLIENT_ID": ""
}
}
}
}Cursor (.cursor/mcp.json) starts it the same way:
{
"mcpServers": {
"freelance": {
"command": "freelancer-ops-mcp"
}
}
}Codex (~/.codex/config.toml) starts a turn without waiting for a server unless it is required, and then the agent has none of its tools. required = true makes the session wait for it, and startup_readiness = "catalog" waits for its tool list rather than just its connection:
[mcp_servers.freelance]
command = "freelancer-ops-mcp"
required = true
startup_readiness = "catalog"
startup_timeout_sec = 30Name the server freelance. A host builds each tool's name from that key, and a longer one can push a tool past the 64 characters a function name allows.
Built with Charter
Every tool here is a Charter declaration: a Pydantic schema saying where each field goes on the wire. Charter's runtime builds the request, attaches and refreshes the credential, and trims the response before the model reads it. It runs in your process, with no proxy and no telemetry.
The 26 tool schemas come to 38,633 tokens.
The same tools work in your own agent, without MCP:
from charter.adapters.openai import to_openai_tools
from charter_packs_mcp import FAMILIES
tools = FAMILIES["agency"].tools()
definitions = to_openai_tools(tools) # or charter.adapters.langchainNeed an API that isn't here? Write a pack: your coding agent writes the declarations, and Charter's conformance suite checks them.
Stripe:
stripe_customers_create,stripe_checkout_sessions_create,stripe_checkout_sessions_list,stripe_invoice_items_create,stripe_invoices_listGoogle Drive:
gdrive_files_copy,gdrive_permissions_create,gdrive_comments_list,gdrive_replies_createLinear:
linear_project_create,linear_project_get,linear_issues_list,linear_issue_createGoogle Calendar:
gcalendar_events_insert,gcalendar_events_list,gcalendar_events_quick_addGmail:
gmail_messages_send,gmail_drafts_create,gmail_threads_listGitHub:
github_repos_list_commitsGoogle Docs:
gdocs_documents_create,gdocs_documents_getGranola:
granola_notes_getGoogle Sheets:
gsheets_spreadsheets_values_appendFirecrawl:
firecrawl_crawl,firecrawl_crawl_status
License
Apache 2.0.
Available Tools
28 toolsconnectA
Connect one app this server uses. For an app that issues keys, says where to get one and the terminal command that stores it. For Google, once the user's own OAuth client is set, starts the browser sign-in and returns at once: the user approves in the browser and the next call works. To see which apps are connected, call connection_status. Never ask the user for a key in the chat.
Inputs: app (required).
connection_statusARead-only
See which apps this server is connected to, and how to connect each one that is not. Changes nothing.
Inputs: no named parameters.
firecrawl_crawlC
Recursively crawl a website and scrape each discovered page.
Inputs: url (required), delay, limit, prompt, +15 more.
firecrawl_crawl_statusBRead-onlyIdempotent
Get the status and results of a crawl job.
Inputs: id (required).
gcalendar_events_insertC
Create a calendar event; returns details of the event.
Inputs: event (required), calendarId (required), sendUpdates, maxAttendees, +3 more.
gcalendar_events_listCRead-onlyIdempotent
List events matching a given search filter.
Inputs: calendarId (required), q, iCalUID, orderBy, +14 more.
gcalendar_events_quick_addA
Create an event from a plain-text description such as 'Appointment at Somewhere on June 3rd 10am-10:25am'. Google parses the time and title; use events_insert when the fields are already known.
Inputs: text (required), calendarId (required), sendUpdates.
gdocs_documents_createA
Create a blank document with a title. Only the title is honoured — the document is created empty. To add content, call this and then documents_batch_update with the returned documentId.
Inputs: body.
gdocs_documents_getARead-onlyIdempotent
Read a document's full structural content. The document ID is the long string in its URL, between '/d/' and '/edit'. Pass include_tabs_content=true for a document with several tabs, since the default response covers only the first.
Inputs: documentId (required), includeTabsContent, suggestionsViewMode.
gdrive_comments_listCRead-onlyIdempotent
List a file's comments. The fields parameter is required — for example comments(id,content,author,createdTime,resolved).
Inputs: fields (required), fileId (required), pageSize, pageToken, +2 more.
gdrive_files_copyA
Create a copy of a file and apply any requested updates with patch semantics. Typically send a new name and optionally parents.
Inputs: file (required), fileId (required), ocrLanguage, copyComments, +5 more.
gdrive_permissions_createA
Create a permission for a file or shared drive. type is user, group, domain or anyone; role is owner, organizer, fileOrganizer, writer, commenter or reader. For user or group, send emailAddress. Concurrent permission writes on the same file are not supported.
Inputs: fileId (required), permission (required), emailMessage, supportsAllDrives, +4 more.
gdrive_replies_createA
Create a reply to a comment. Send content, or an action of resolve or reopen. content is required if no action is specified.
Inputs: reply (required), fileId (required), commentId (required).
github_repos_list_commitsARead-onlyIdempotent
List commits, newest first. Narrow with sha for a branch, path for one file's history, or since/until for a window.
Inputs: repo (required), owner (required), sha, page, +5 more.
gmail_drafts_createC
Save an email draft to Gmail.
Inputs: body (required), userId.
gmail_messages_sendC
Send an email via the Gmail API.
Inputs: body (required), userId.
gmail_threads_listCRead-onlyIdempotent
List Gmail threads.
Inputs: q, userId, labelIds, pageToken, +2 more.
granola_notes_getARead-onlyIdempotent
Read one meeting note: its AI summary, the people who attended, the calendar event it was taken against, and the folders it belongs to. Pass include='transcript' to get the transcript inline as well. A transcript too large to inline answers 413 TRANSCRIPT_TOO_LARGE. Read it with notes_transcript_get instead.
Inputs: noteId (required), include.
gsheets_spreadsheets_values_appendC
Appends values to a spreadsheet.
Inputs: range (required), valueRange (required), spreadsheetId (required), valueInputOption (required), +4 more.
linear_issue_createA
Create an issue. team_id and title are required; everything else is optional. The UUIDs for team, assignee, state and labels come from teams_list, users_list and workflow_states_list — Linear does not accept names here. Set parent_id to create a sub-issue.
Inputs: variables (required).
linear_issues_listARead-onlyIdempotent
List issues, optionally filtered. Conditions on one filter object combine with AND. To find a team's open work, filter on team.key and state.type.
Inputs: variables.
linear_project_createA
Create a project. name and at least one team UUID are required; team UUIDs come from teams_list.
Inputs: variables (required).
linear_project_getBRead-onlyIdempotent
Get one project with its content, milestones and members. Accepts the project's UUID or the slug from its URL.
Inputs: variables (required).
stripe_checkout_sessions_createA
Create a Checkout Session and get a hosted payment URL. Pass line_items with price IDs and quantities, mode='payment' for one-time or mode='subscription' for recurring.
Inputs: mode (required), uiMode, currency, customer, +9 more.
stripe_checkout_sessions_listARead-onlyIdempotent
List checkout sessions. Stripe has no payment_status filter, so find paid ones by reading the results.
Inputs: limit, status, created, customer, +5 more.
stripe_customers_createC
Create a customer.
Inputs: name, email, phone, address, +6 more.
stripe_invoice_items_createA
Add a line to an invoice. Name an existing price as pricing.price, or give an amount directly. Without invoice the line waits for the customer's next subscription invoice.
Inputs: customer (required), amount, period, invoice, +11 more.
stripe_invoices_listARead-onlyIdempotent
List invoices, most recently created first. Filter by customer, subscription, status or collection method.
Inputs: limit, status, created, customer, +4 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 28 tools
Each tool targets a distinct service-resource-action combination, with no true duplicates. The only near-overlap, gcalendar_events_insert versus gcalendar_events_quick_add, is explicitly clarified by their descriptions.
Most names follow a predictable service_resource_action snake_case pattern (e.g. gdrive_permissions_create, linear_issue_create). The outliers connect and connection_status break the pattern, and a few action orderings vary slightly, but the set remains readable and mostly consistent.
28 tools is on the heavy side, but the server spans many apps (Drive, Docs, Gmail, Linear, Stripe, Calendar, GitHub, Granola, Firecrawl, Sheets), so the count is reasonable for the broad freelance-ops scope. Each tool represents a distinct operation, avoiding redundancy.
There are significant dead ends: gdocs_documents_create references documents_batch_update, which is missing; linear_issue_create and linear_project_create require UUIDs from teams_list, users_list, and workflow_states_list, none of which exist. Several services also have only one or two operations, leaving core workflows like file upload, event update, and GitHub issue handling uncovered.
Maintenance
Related MCP Connectors
The whole back office for your AI agent: CRM, invoices, books, email and more. Pay per action.
Run your service firm from your AI: client work to review, clients, deliverables, invoices.
Tasks, timers and earnings for freelancers and agencies: your AI agent works where you get paid.
Create contacts, move deals, send proposals and invoices, read your inbox, from Claude or ChatGPT.
Related MCP Servers
- AlicenseBqualityBmaintenanceRuns 20 slash-command workflows across Google Calendar, Gmail, Linear, Slack, Granola, Google Docs, GitHub, Stripe, Notion, Google Forms, Sheets and Drive to produce morning briefs, meeting prep, action items assigned to owners and weekly updates. Reads proceed without asking, while anything that creates, sends, changes or deletes is shown for approval first.471Apache 2.0
- AlicenseBqualityBmaintenanceRuns 13 agent slash-command workflows across Linear, GitHub, Google Docs, Slack, Firecrawl, Sheets, Tavily, Forms, Calendar, Gmail, Stripe, Granola and Notion — turning shipped features into blog and social drafts and handling competitor pricing, mention monitoring, SEO gaps, webinars, newsletters and launch-day tracking. Every credential is your own, kept in the OS keychain or client config, and anything that writes, sends or deletes is shown for approval first.29Apache 2.0
- AlicenseBqualityBmaintenanceEnables agents to run eight recruiting and onboarding workflows — filing applications with CVs into a candidate sheet, booking interview panels, summarising interviewer debriefs, researching a candidate's public work, provisioning a new hire's day one, running pulse surveys, drafting offer letters, and writing market-benchmarked job posts. It spans Gmail, Google Drive, Sheets, Calendar, Forms and Docs, plus Granola, Notion, Slack, GitHub, Linear, Tavily and Firecrawl, with read-only calls running freely and any write, send or delete shown for approval first.29Apache 2.0
- AlicenseBqualityBmaintenanceEnables an agent to run 14 packaged sales workflows over your own connected apps — calendar, email, Slack, Notion, Stripe, Slack and more — turning meetings, calls and inbound requests into pre-call briefs, follow-up emails, enriched lead sheets, CRM records and payment links. Reads run freely, while anything that creates, sends, changes or deletes is shown for confirmation first.35Apache 2.0