gunio-mcp
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., "@gunio-mcp show my recent job applications"
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.
gunio-mcp
A local-only, Docker-packaged MCP server (and a thin read CLI) for gun.io, authenticated with your own browser session — the same host-side cookie-broker + wrapper pattern as claudesync. It lets an MCP client (Claude Code, etc.) read your gun.io freelancer data — interviews, applications, jobs, profile — and perform a small set of gated writes.
Unofficial. No affiliation with gun.io. This talks to gun.io's private, undocumented API using your logged-in session. It is a personal automation tool; use it at your own risk and within gun.io's Terms of Service. No gun.io code is included in this repo.
How it works
Firefox session ──(host-side broker: rookie-cli)──▶ GUNIO_COOKIE ──▶ docker run ──▶ FastMCP server ──▶ app.gun.io/api/v2A cookie broker (
scripts/lib/harvest-cookie.sh) reads your gun.io session (sessionid+csrftoken) from the browser, host-side. Nothing leaves your machine.A thin wrapper passes that cookie into a container via the
GUNIO_COOKIEenv var anddocker runs it per invocation.Inside the container, a Python/FastMCP server (
gunio_mcp) calls gun.io's/api/v2through a safety-guarded client (gunio_broker).
Related MCP server: Upwork MCP Server
Security model
Reads need only the cookies. Writes echo the
csrftokenasX-CSRFToken(Django CSRF), and are double-gated: a call previews unlessconfirm=trueand the server env hasGUNIO_MCP_WRITE_SCOPEset.Hard denylist in the client, enforced regardless of tool:
auth/logout(a GET that kills your session), the entire/staff/tree,DELETEon a freelancer (account deletion),complete-screening, and telemetry writes.Cookies are never logged or placed in exceptions.
Local only. No data is sent anywhere except gun.io itself.
Install (once Docker image + installer land)
# bootstrap the broker + wrappers, pull the image
scripts/gunio-setup.sh install
# register the MCP server with Claude Code
claude mcp add --scope user gunio ~/.local/share/gunio/gunio-mcp-wrapper.shTo enable writes, set GUNIO_MCP_WRITE_SCOPE=writes in the server env (see the wrapper). Without it, write tools only ever return a dry-run preview.
Remote mode (--serve)
By default gunio-mcp speaks MCP over stdio for a local client. With --serve it
instead runs FastMCP's streamable HTTP transport as a long-lived service:
gunio-mcp --serve # http://127.0.0.1:8000/mcp
gunio-mcp --serve --host 0.0.0.0 --port 9000Configuration (flags win over env vars):
Flag | Env var | Default | Meaning |
|
|
| bind host |
|
|
| bind port |
n/a |
| unset | static bearer token required from clients |
n/a |
| unset |
|
Naming convention: GUNIO_MCP_* vars configure the server process itself;
GUNIO_* vars (today just GUNIO_COOKIE) configure the gun.io account/session.
Endpoint security
GUNIO_COOKIE authenticates the server TO gun.io; nothing inherent authenticates
clients TO this server. Anyone who can reach the HTTP endpoint can act as your
gun.io account, including gated writes if the write scope is set. Therefore:
Set
GUNIO_MCP_AUTH_TOKENto requireAuthorization: Bearer <token>on every request (compared in constant time; never logged).Binding a non-loopback host without that token refuses to start, unless you explicitly set
GUNIO_MCP_INSECURE=1because the network layer (e.g. Tailscale or an authenticating proxy) already provides access control.Do NOT set
GUNIO_MCP_WRITE_SCOPEon a remote deployment unlessGUNIO_MCP_AUTH_TOKENis configured.
Bearer auth applies only to serve mode; the stdio default ignores these vars.
Docker
docker run -e GUNIO_COOKIE=... -e GUNIO_MCP_AUTH_TOKEN=... -p 8000:8000 \
gunio-mcp:local --serve --host 0.0.0.0Inside a container, binding 0.0.0.0 with the token set is the expected pattern.
Operational caveat: the cookie is a deploy-time secret
In remote mode there is no host-side broker refreshing the session: the
GUNIO_COOKIE you deploy with is it. When gun.io expires that session, reads
start failing until the deployment is updated with a fresh cookie. The
auth_status tool (or gunio auth status on the CLI) is how you detect this: it
performs one lightweight authenticated read and reports
{"mode": "cookie", "authenticated": false, "checked_at": "...", "error": "gun.io returned HTTP 401"}without ever raising raw errors or leaking cookie material. Phase 2 will add credential-based login; this release is transport + visibility only.
Develop
uv sync --extra dev
uv run --extra dev pytest -q # full suite
uv run gunio me # thin CLI (needs GUNIO_COOKIE or a logged-in browser)
uv run gunio-mcp # run the MCP server over stdioGUNIO_COOKIE is a sessionid=...; csrftoken=... string; the broker produces it, or set it by hand for local dev.
Layout
Path | Role |
| Safety-guarded HTTP client for |
| Pure tool helpers (reads + gated writes), unit-tested |
| FastMCP wrappers + |
| Thin read-only CLI |
| Cookie broker, wrappers, installer (lifted from claudesync) |
License
MIT.
Available Tools
24 toolscancel_interviewB
Cancel an interview. Previews unless confirm=true and writes are enabled.
Inputs: interview_id (required), reason, confirm.
get_applicationB
Get a single job application by id.
Inputs: application_id (required).
get_availabilityB
Freelancer availability / seeking state.
Inputs: no named parameters.
get_freelancer_profileB
Full freelancer profile: bio, experiences, skills, rates.
Inputs: no named parameters.
get_interviewC
Get a single interview by id.
Inputs: interview_id (required).
get_jobA
Get a single job listing by id.
Inputs: job_id (required).
get_meA
Current gun.io user: identity, contact, flags, embedded freelancer summary.
Inputs: no named parameters.
get_subscriptionsB
The user's notification subscription settings.
Inputs: no named parameters.
get_workstyleC
The user's work-style preferences.
Inputs: no named parameters.
job_statsB
Platform job stats (e.g. jobs published last week).
Inputs: no named parameters.
list_applicationsC
List the freelancer's job applications (with status and embedded job info).
Inputs: page.
list_hiresC
List the freelancer's active/past engagements (hires).
Inputs: page.
list_interviewsB
List the freelancer's interviews, optionally filtered by status.
Inputs: status.
list_invitesB
List inbound invites for the freelancer.
Inputs: no named parameters.
list_mission_interviewsB
List the freelancer's mission interviews.
Inputs: no named parameters.
list_presentationsC
List client presentations for the freelancer.
Inputs: no named parameters.
list_reviewsC
List reviews the freelancer has received.
Inputs: page.
reschedule_interviewB
Reschedule an interview. Previews unless confirm=true and writes are enabled.
Inputs: body (required), interview_id (required), confirm.
respond_to_inviteC
Respond to an invite. Previews unless confirm=true and writes are enabled.
Inputs: body (required), invite_id (required), confirm.
schedule_interviewB
Schedule an interview. Previews unless confirm=true and writes are enabled.
Inputs: body (required), interview_id (required), confirm.
search_jobsC
Search open gun.io job listings.
Inputs: q, page.
update_applicationB
Patch a job application. Previews unless confirm=true and writes are enabled.
Inputs: patch (required), application_id (required), confirm.
update_profileA
Patch the freelancer profile. Previews unless confirm=true and writes are enabled.
Inputs: patch (required), confirm.
withdraw_applicationB
Withdraw a job application. Previews unless confirm=true and writes are enabled.
Inputs: application_id (required), reason, confirm.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 24 tools
Most tools target distinct resources (user, profile, interviews, applications, etc.), but 'list_interviews' and 'list_mission_interviews' could cause confusion; descriptions help clarify.
Predominantly uses verb_noun pattern (list_, get_, update_, etc.), with minor deviations like 'get_me' and 'job_stats' being slightly off-pattern.
24 tools is above the typical range but still reasonable for a comprehensive freelance platform client; each tool serves a distinct purpose without being excessive.
Covers core freelancer workflows (profile, applications, interviews, invites, hires, job search), but lacks tools for messaging or payment tracking which might be relevant.
Related MCP Connectors
Public MCP server for discovering open jobs. Search, filter, and get application links.
MCP server for Nylas — read email, calendars, events and contacts, and send email or create events.
Remote MCP server to read and edit GanttFather projects: tasks, dates, dependencies, critical path.
MCP server for customer-io
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server for programmatically accessing your own Toptal Talent profile, including profile management, applications, jobs, timesheets, and more.AGPL 3.0
- AlicenseAqualityDmaintenanceMCP server for Upwork via browser automation. Enables Claude Code to search jobs, manage proposals, messages, and contracts on Upwork.1872Apache 2.0
- FlicenseAqualityDmaintenanceA local job-hunting MCP server for discovering jobs across pluggable web sources, tracking applications through a status lifecycle, and managing profiles/resumes, with geo/map-region search.12-
- AlicenseNot gradedqualityDmaintenanceLocal-first MCP server for research on AI-assisted browsing of a user-owned professional-network account (e.g., LinkedIn), providing read-focused tools such as profile, company, search, and feed reads.MIT