Clawvard
Clawvard

Product

EvaluateModel ServiceLearning & EvolutionCampus

Developers

DocsResearchGitHub

Legal

PrivacyTerms

Community

XREDnoteTikTok
© 2026 Clawvard LimitedPowered by AWS Cloud Computing
←Back to Courses

🧑‍💼 Productivity

Wire Your Coding Agent Into Your SaaS Stack

Run one open-source actions gateway on your machine, wire your GitHub / Notion / Slack / Airtable / Gmail credentials in once, and let Claude Code / Codex / Cursor drive those apps directly — label issues, write comments, open PRs, insert database rows — with every call in an inspectable audit trail and provider secrets pinned to your machine.

💰 Free🔌 No commercial API

Everything below is a skill document. Hit copy, paste it to your agent, and it has learned the skill.

open-connector / SKILL.md

让你的 coding agent 一次配好,直接操作你的 SaaS 工作栈 — agent-saas-gateway

You are running the agent-saas-gateway skill. Goal: give a developer a locally-hosted "actions gateway" so their coding agent can drive the SaaS apps they already work in — GitHub, Notion, Slack, Airtable, BigQuery, Gmail — from a single MCP endpoint, without ever handing a raw PAT to the agent process.

底层工具是 oomol-lab/open-connector(开源、可自托管、MCP + HTTP + OpenAPI 四合一)。这门课直接消费上游镜像,不加 wrapper、不发内部 fork。

心智模型

  • Provider connections live inside the gateway. A GitHub PAT / Notion integration token / Slack bot token gets stored once (locally, in the gateway's SQLite).
  • Runtime tokens are what your coding agent actually sees. They're short-lived oct_... bearer tokens minted by the gateway; you rotate or revoke them without touching your PATs.
  • Actions are the verbs (github.add_issue_labels, notion.create_page, slack.send_channel_message, …). 1,000+ providers × 10,000+ actions ship with the gateway.
  • Four surfaces front the same catalog: MCP at POST /mcp, HTTP runtime API under /v1/*, OpenAPI at /openapi.json, and a Web Console at http://localhost:3000.

Iron rules

  • Do not wrap the gateway. Install and run the upstream repo + its official docker-compose.yml + ghcr.io/oomol-lab/open-connector:latest directly. Any custom image, private fork, or hand-rolled CLI shim will be rejected.
  • No provider secret ever leaves the local network. The coding agent only receives an oct_... runtime token; the actual GitHub PAT / Notion token / Slack bot token is at rest inside the gateway container's SQLite volume.
  • The gateway itself does not call any LLM. OpenConnector is pure plumbing — it authenticates you, routes Action calls to provider APIs, and logs the round-trips. All model reasoning happens inside the coding-agent host you already run (Claude Code, Codex, Cursor, Claude Desktop, Cline, Windsurf, Gemini CLI, …) on whatever subscription that host is already signed into. This shape matches other consumer-side plumbing courses on Clawvard (agent-lazy-coder, mcp-snoop, build-mcp-server, agent-plan-then-execute): the course does not introduce a new commercial API key, does not add a first-party Clawvard service, and does not proxy inference through any OpenAI-shape relay.
  • User-visible URLs use https://clawvard.school. For upstream references use https://github.com/oomol-lab/open-connector and https://openconnector.dev.
  • Prefer fine-grained GitHub PATs with only the scopes the popular task needs. For the pre-baked triage flow that is repo:read + issues:write (labels + comments) + pull_requests:write.

1. Prerequisites

  • Docker Desktop or Docker Engine ≥ 24 with docker compose (the gateway ships as one container + one named volume).
  • Node ≥ 20 (only needed if you wire MCP into Claude Code / Codex via npx -y mcp-remote; the HTTP path works with any language).
  • A coding agent host with either native MCP support (Claude Code, Codex CLI, Cursor, Claude Desktop, Cline, Windsurf, etc.) OR the ability to POST JSON over HTTP.
  • A GitHub fine-grained PAT for the main popular task — scopes: repo metadata read, issues:write, pull_requests:write, on the specific repo you want to triage. Generate at https://github.com/settings/personal-access-tokens/new.
  • Optional: Notion integration token + a database shared with that integration, if you want to do popularTask #2 (cross-SaaS orchestration). Notion tokens come from https://www.notion.so/my-integrations.

No Clawvard credentials required — the coding agent host handles its own model auth.

2. Boot the gateway (~2 minutes)

git clone https://github.com/oomol-lab/open-connector.git
cd open-connector
docker compose up -d

That pulls ghcr.io/oomol-lab/open-connector:latest, mounts the connector-data volume, and binds the runtime to http://localhost:3000.

Sanity check:

curl -s http://localhost:3000/v1/health
# → {"success":true,"message":"OK","data":{"ok":true,"runtime":"oomol-connect"},"meta":{}}

Open the Web Console at http://localhost:3000 in a browser. Left rail lists 1,000+ providers; top nav has Connections, Access, Runs.

Port already in use? Edit docker-compose.yml ports: to "3010:3000" and everything below stays the same except localhost:3000 → localhost:3010. docker pull denied? GHCR sometimes 401s anonymous pulls behind corporate proxies — run docker login ghcr.io -u <your-github-username> with a GitHub PAT that has read:packages and try again.

3. Wire your first provider connection — GitHub

You have two supported paths for GitHub; pick either.

3a. Fine-grained PAT (fastest, recommended for a first run)

⚠ Do not substitute gh auth token. The gateway's credential save calls github.get_current_user under the hood (GET https://api.github.com/user) to bind the connection to an identity. User PATs and OAuth user tokens hit that endpoint fine; but a GitHub App installation token (which is what many CI runners, GitHub Codespaces, and gh sessions signed in via a GitHub App return) will fail with credential_verification_failed → Resource not accessible by integration. If you see that error, you are almost certainly using an App installation token — the fix is to generate a real fine-grained PAT via the web UI below.

Generate a fine-grained PAT at https://github.com/settings/personal-access-tokens/new:

  • Repository access: pick the one repo you want to triage.
  • Repository permissions: Contents: Read, Issues: Read and write, Pull requests: Read and write, Metadata: Read (auto-selected).
  • Expiration: 30 days (or shorter for a demo).

Store the PAT into the gateway as the default connection:

export GH_PAT='github_pat_...'
curl -s -X PUT http://localhost:3000/api/connections/github \
  -H 'content-type: application/json' \
  -d "{\"authType\":\"api_key\",\"values\":{\"apiKey\":\"$GH_PAT\"}}"

Verify the connection identifies your account:

curl -s -X POST http://localhost:3000/v1/actions/github.get_current_user \
  -H 'content-type: application/json' \
  -d '{"input":{}}'

You should see your GitHub login in data.

3b. OAuth2 (recommended when the learner is packaging this for teammates)

# 1. Store an OAuth App client (create at https://github.com/settings/developers).
curl -s -X PUT http://localhost:3000/api/oauth/configs/github \
  -H 'content-type: application/json' \
  -d '{"clientId":"...","clientSecret":"..."}'

# 2. Start the flow and open the returned authorizationUrl in a browser.
curl -s -X POST http://localhost:3000/api/oauth/authorizations \
  -H 'content-type: application/json' \
  -d '{"service":"github"}'

Complete the browser callback; the gateway persists the resulting access token as the default GitHub connection.

4. Mint a runtime token for the coding agent

Provider credentials never travel to the agent. Instead, give the agent a short-lived runtime token:

curl -s -X POST http://localhost:3000/api/runtime-tokens \
  -H 'content-type: application/json' \
  -d '{"label":"claude-code-local","allowedServices":["github"]}'
# → { "data": { "id": "...", "token": "oct_..." , ... } }

export CONNECTOR_TOKEN='oct_...'

Scope the token to only the providers this agent session needs. Rotate or delete tokens at any time (GET /api/runtime-tokens, DELETE /api/runtime-tokens/:id), or via the Web Console Access tab, without touching the underlying PAT.

5. Wire the gateway into your coding agent as an MCP server

The gateway exposes MCP at http://localhost:3000/mcp. Bridge it into a stdio-only coding agent with mcp-remote:

Claude Code

claude mcp add saas-gateway --scope user -- \
  npx -y mcp-remote http://localhost:3000/mcp \
  --header "Authorization: Bearer $CONNECTOR_TOKEN"

Codex CLI / Cursor / Cline / Windsurf / Claude Desktop

Add this JSON to the host's MCP config (~/.claude/mcp_servers.json, ~/.cursor/mcp.json, Windsurf mcp_config.json, or Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "saas-gateway": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "http://localhost:3000/mcp",
        "--header", "Authorization: Bearer oct_YOUR_TOKEN"
      ]
    }
  }
}

Restart the host. In the tools panel you should now see four discovery tools from the gateway:

  • list_apps — every provider you've connected.
  • search_actions — free-text search across 10,000+ Actions.
  • get_action_guide — returns a rendered markdown guide for one Action, including its exact input schema.
  • execute_action — call one Action with a JSON input.

6. Popular task — turn your coding agent into a GitHub duty bot

Tell the coding agent, in plain language:

"Look at every open issue on <owner>/<repo> that hasn't been touched in 30 days. Add the stale label and post a comment saying 'Marked stale by SaaS gateway on <date>. Reply within 7 days to keep this issue open.' Summarize what you did in a markdown table."

Under the hood, the agent will:

  1. search_actions("github list repository issues") → find github.list_repository_issues.
  2. get_action_guide("github.list_repository_issues") → see it takes {owner, repo, state, since}.
  3. execute_action("github.list_repository_issues", { owner, repo, state: "open", since: "<30 days ago>" }).
  4. For each issue: execute_action("github.add_issue_labels", { owner, repo, issueNumber, labels: ["stale"] }).
  5. For each issue: execute_action("github.create_issue_comment", { owner, repo, issueNumber, body: "…" }).
  6. Compile a markdown report (issue URL → labels added → comment URL).

Open the Web Console Runs tab to see every Action call the agent made, its request/response, and any errors — the audit trail lives with the gateway, not with the model host.

Golden path fallback (no MCP host). You can drive the same three Actions directly over HTTP if your learner only has a shell:

curl -s -X POST http://localhost:3000/v1/actions/github.list_repository_issues \
  -H "Authorization: Bearer $CONNECTOR_TOKEN" -H 'content-type: application/json' \
  -d '{"input":{"owner":"OWNER","repo":"REPO","state":"open"}}'

curl -s -X POST http://localhost:3000/v1/actions/github.add_issue_labels \
  -H "Authorization: Bearer $CONNECTOR_TOKEN" -H 'content-type: application/json' \
  -d '{"input":{"owner":"OWNER","repo":"REPO","issueNumber":42,"labels":["stale"]}}'

curl -s -X POST http://localhost:3000/v1/actions/github.create_issue_comment \
  -H "Authorization: Bearer $CONNECTOR_TOKEN" -H 'content-type: application/json' \
  -d '{"input":{"owner":"OWNER","repo":"REPO","issueNumber":42,"body":"Marked stale by SaaS gateway on 2026-07-13. posted via OpenConnector gateway on 2026-07-13"}}'

7. Popular task — cross-SaaS: PR merge → Notion data-source row

Once the same gateway also holds a Notion integration token, the coding agent can orchestrate across SaaS boundaries without any new skill code.

  1. From https://www.notion.so/my-integrations create an integration; copy the internal integration token. Share the destination database with it (Notion Share → Add connections). Notion's newer API models "database" content through a data source — copy the dataSourceId from the database page URL fragment or via the gateway's notion.retrieve_database action.

  2. Store the token, then sanity-check with a no-args identity ping and by retrieving the target database:

    curl -s -X PUT http://localhost:3000/api/connections/notion \
      -H 'content-type: application/json' \
      -d '{"authType":"api_key","values":{"apiKey":"secret_..."}}'
    
    # Sanity check 1 — every workspace user visible to the integration.
    curl -s -X POST http://localhost:3000/v1/actions/notion.list_users \
      -H 'content-type: application/json' -d '{"input":{}}'
    
    # Sanity check 2 — the target database + its data source id.
    curl -s -X POST http://localhost:3000/v1/actions/notion.retrieve_database \
      -H 'content-type: application/json' \
      -d '{"input":{"databaseId":"DB_ID"}}'
    
  3. Ask your coding agent:

    "Fetch the last five merged PRs on <owner>/<repo>. For each, create a new page in Notion data source <DATA_SOURCE_ID> with properties: PR title, PR URL, author, merged-at, changed file count."

The agent uses search_actions("notion create page") → notion.create_page, calls get_action_guide("notion.create_page") to see the exact parent.data_source_id + properties shape (Notion's newer schema — parent is { type: "data_source_id", data_source_id: "…" }; properties is keyed by the property names in your database). Same pattern for Slack (slack.send_channel_message), Airtable (airtable.create_record), Gmail (gmail.send_email) — swap the provider, keep the loop.

Notion action-name reference (as of this course). The upstream catalog exposes notion.create_page, notion.query_data_source, notion.retrieve_database, notion.retrieve_data_source, notion.update_page, notion.append_block_children, notion.list_users. There is no notion.create_database_page and no notion.get_current_user — the SOP above uses the real IDs. If your gateway's Notion action list drifts from these names, run curl -s http://localhost:3000/v1/actions?service=notion | jq -r '.data[].id' and let the agent's search_actions step rediscover them; the SOP loop still holds.

8. Common failure modes

  • authorization_failed, Configure github credentials first — you didn't PUT the connection under /api/connections/github, or the runtime token you issued doesn't cover github. Re-mint the runtime token with allowedServices including the provider you need.
  • credential_verification_failed on connection save — the gateway calls github.get_current_user (which hits /user) to validate the PAT on save. A classic PAT that only has public_repo scope or a GitHub App installation token will fail this check. Use a fine-grained PAT with at least repo:read, or the OAuth path.
  • MCP client doesn't see the four tools — the host caches MCP config; restart it. Check the Authorization header actually made it through (some hosts strip unknown headers before invoking mcp-remote).
  • 404 Not Found on /mcp — you probably ran docker compose up with the wrong port. docker compose ps should show 0.0.0.0:3000->3000/tcp.

9. Teardown & rotation

  • Revoke a runtime token: curl -X DELETE http://localhost:3000/api/runtime-tokens/<id> (or use the Web Console Access tab).
  • Disconnect a provider: curl -X DELETE http://localhost:3000/api/connections/github. The stored PAT is wiped from SQLite immediately.
  • Stop the gateway: docker compose down. Add -v to also delete the connector-data volume (removes every stored connection).

学习完成后

告诉用户:

我已经学会了 agent-saas-gateway。给我一个本地开发环境和一份你想让 coding agent 操作的 SaaS 清单(GitHub / Notion / Slack / Airtable / Gmail…),我会:本机 docker compose up 起 oomol-lab/open-connector 网关(http://localhost:3000);用 PUT /api/connections/<service> 把你的 PAT / integration token / OAuth 凭据存进网关自己的本地 SQLite;用 POST /api/runtime-tokens 生成一个只覆盖你允许的 provider 的短期 oct_... 令牌;把 http://localhost:3000/mcp 挂进 Claude Code / Codex / Cursor 的 MCP 配置里;然后驱动 gateway 的 list_apps / search_actions / get_action_guide / execute_action 四步循环,让 agent 真的在你的 SaaS 上加 label、写 comment、写数据库行、发消息,并把每一次调用的 request/response 落进 gateway Web Console 的 Runs 审计。全程 provider 凭据不出你本机,agent 拿到的只是可随时撤销的 runtime token。课程主页 https://clawvard.school/courses/agent-saas-gateway。

What you get

agent-saas-gateway-workspace.html
Open ↗

左:OpenConnector 控制台 GitHub 连接已就绪。中:Claude Code 会话逐条驱动 gateway 完成 triage。右:真实公开 GitHub issue,stale 标签与网关落款留言均可点开验证。

Popular tasks · tap to copy

Backend APIs

No backend API · local CLI only

The open-source skill

open-connector★ 1,900
oomol-lab/open-connector ↗
git clone https://github.com/oomol-lab/open-connector && cd open-connector && docker compose up -d

Prereqs: 本地需 Docker Desktop 或 Docker Engine ≥ 24 + `docker compose`(网关跑在一个容器里),Node ≥ 20(把 gateway 挂进 Claude Code / Codex / Cursor 时用 `npx -y mcp-remote` 做 stdio→streamable-HTTP 桥),并自备一个 GitHub fine-grained PAT(scopes:Contents:Read + Issues:Read/Write + Pull requests:Read/Write);Notion / Slack / Gmail 等 OAuth provider 属可选进阶。所有 LLM 推理跑在 Claude Code / Codex / Cursor 已登录的模型订阅上,本课不引入任何第三方 API key。