Connectors
Connectors parse raw HTTP requests into structured actions. Each connector knows the API schema for a specific service and maps HTTP method + URL path to an action type like github.pr.merge or stripe.charge.create.
Built-in connectors
GitHub
| Field | Value |
|---|---|
| Domains | api.github.com |
| Actions | 20+ (PRs, issues, branches, releases, files, repos, orgs, teams) |
| Auth | Authorization: token {PAT} |
| GitHub Enterprise | Supported — set custom base URL in connector config |
Action types
| Action | HTTP | Risk |
|---|---|---|
| github.pr.create | POST /repos/{owner}/{repo}/pulls | low |
| github.pr.merge | PUT /repos/{owner}/{repo}/pulls/{number}/merge | medium |
| github.pr.update | PATCH /repos/{owner}/{repo}/pulls/{number} | low |
| github.pr.close | PATCH /repos/{owner}/{repo}/pulls/{number} (state=closed) | low |
| github.pr.review | POST /repos/{owner}/{repo}/pulls/{number}/reviews | low |
| github.issue.create | POST /repos/{owner}/{repo}/issues | low |
| github.issue.update | PATCH /repos/{owner}/{repo}/issues/{number} | low |
| github.issue.close | PATCH /repos/{owner}/{repo}/issues/{number} (state=closed) | low |
| github.branch.create | POST /repos/{owner}/{repo}/git/refs | low |
| github.branch.delete | DELETE /repos/{owner}/{repo}/git/refs/{ref} | high |
| github.release.create | POST /repos/{owner}/{repo}/releases | medium |
| github.release.delete | DELETE /repos/{owner}/{repo}/releases/{id} | high |
| github.file.create | PUT /repos/{owner}/{repo}/contents/{path} (new) | low |
| github.file.update | PUT /repos/{owner}/{repo}/contents/{path} (existing) | low |
| github.file.delete | DELETE /repos/{owner}/{repo}/contents/{path} | medium |
| github.repo.create | POST /user/repos or POST /orgs/{org}/repos | medium |
| github.repo.delete | DELETE /repos/{owner}/{repo} | high |
| github.repo.update | PATCH /repos/{owner}/{repo} | low |
| github.org.update | PATCH /orgs/{org} | medium |
| github.team.create | POST /orgs/{org}/teams | low |
GitHub Enterprise Server (GHE)
To use with GitHub Enterprise, set a custom base URL when adding the connector:
npx tf connector add github \
--token-env GITHUB_TOKEN \
--base-url https://github.yourcompany.com/api/v3The connector automatically adjusts URL parsing for the custom base URL. All action types work the same as with api.github.com.
OpenAI / Anthropic
| Field | Value |
|---|---|
| Domains | api.openai.com, api.anthropic.com |
| Actions | 24+ (chat, embeddings, images, audio, files, fine-tuning, models) |
| Auth | Authorization: Bearer {key} (OpenAI), x-api-key: {key} (Anthropic) |
| Azure OpenAI | Not yet supported — use the generic connector with Azure endpoints |
Action types (OpenAI)
| Action | HTTP | Risk |
|---|---|---|
| openai.chat.create | POST /v1/chat/completions | low |
| openai.chat.create_stream | POST /v1/chat/completions (stream=true) | low |
| openai.embedding.create | POST /v1/embeddings | low |
| openai.image.generate | POST /v1/images/generations | medium |
| openai.image.edit | POST /v1/images/edits | medium |
| openai.audio.transcribe | POST /v1/audio/transcriptions | low |
| openai.audio.translate | POST /v1/audio/translations | low |
| openai.audio.speech | POST /v1/audio/speech | low |
| openai.file.upload | POST /v1/files | medium |
| openai.file.delete | DELETE /v1/files/{id} | medium |
| openai.file.list | GET /v1/files | low |
| openai.finetune.create | POST /v1/fine_tuning/jobs | high |
| openai.finetune.cancel | POST /v1/fine_tuning/jobs/{id}/cancel | medium |
| openai.model.list | GET /v1/models | low |
| openai.model.delete | DELETE /v1/models/{id} | high |
Azure OpenAI workaround
Azure OpenAI uses different endpoints ({resource}.openai.azure.com). Use the generic connector:
npx tf connector add generic \
--domains "myresource.openai.azure.com" \
--token-env AZURE_OPENAI_KEY \
--auth-header "api-key"Actions will be parsed as generic.post, generic.get, etc. For richer action types, a dedicated Azure OpenAI connector is planned.
Stripe
| Field | Value |
|---|---|
| Domains | api.stripe.com |
| Actions | 40+ (charges, refunds, payments, subscriptions, invoices, customers, transfers) |
| Auth | Authorization: Bearer {secret_key} |
Action types (selection)
| Action | HTTP | Risk |
|---|---|---|
| stripe.charge.create | POST /v1/charges | high |
| stripe.charge.refund | POST /v1/refunds | high |
| stripe.customer.create | POST /v1/customers | low |
| stripe.customer.delete | DELETE /v1/customers/{id} | medium |
| stripe.subscription.create | POST /v1/subscriptions | medium |
| stripe.subscription.cancel | DELETE /v1/subscriptions/{id} | medium |
| stripe.invoice.create | POST /v1/invoices | medium |
| stripe.invoice.pay | POST /v1/invoices/{id}/pay | high |
| stripe.transfer.create | POST /v1/transfers | high |
| stripe.payout.create | POST /v1/payouts | high |
| stripe.balance.retrieve | GET /v1/balance | low |
Slack
| Field | Value |
|---|---|
| Domains | slack.com, api.slack.com |
| Actions | 35+ (messages, channels, files, users, admin, reactions) |
| Auth | Authorization: Bearer {bot_token} |
Action types (selection)
| Action | HTTP | Risk |
|---|---|---|
| slack.message.post | POST /api/chat.postMessage | low |
| slack.message.update | POST /api/chat.update | low |
| slack.message.delete | POST /api/chat.delete | medium |
| slack.channel.create | POST /api/conversations.create | medium |
| slack.channel.archive | POST /api/conversations.archive | medium |
| slack.channel.invite | POST /api/conversations.invite | low |
| slack.file.upload | POST /api/files.upload | medium |
| slack.file.delete | POST /api/files.delete | medium |
| slack.user.list | GET /api/users.list | low |
| slack.admin.invite | POST /api/admin.users.invite | high |
Generic HTTP
The generic connector works with any HTTP API. It parses actions based on HTTP method only.
| Field | Value |
|---|---|
| Domains | Any (configured per-connector) |
| Actions | Method-based: generic.get, generic.post, generic.put, generic.patch, generic.delete |
| Auth | Configurable header (default: Authorization: Bearer {token}) |
Adding a generic connector
# Single domain
npx tf connector add generic --domains api.example.com --token-env EXAMPLE_KEY
# Multiple domains
npx tf connector add generic \
--domains "api.example.com,api.other.com" \
--token-env EXAMPLE_KEY
# Custom auth header
npx tf connector add generic \
--domains api.example.com \
--token-env EXAMPLE_KEY \
--auth-header "X-API-Key"Action counting
Each HTTP request through the generic connector counts as one action, regardless of the response. This is the same as structured connectors — one request = one action.
Semantic limitations
The generic connector cannot parse domain-specific action types. A POST to any endpoint is generic.post. For richer action types and risk hints, use a structured connector or build a custom one.
Custom connector development
You can build custom connectors in Go to add domain-specific action parsing for APIs that don't have a built-in connector.
Connector interface
Every connector implements this Go interface:
// internal/connectors/interface.go
type Connector interface {
// Name returns the connector identifier (e.g., "github", "stripe")
Name() string
// Domains returns the list of domains this connector handles
Domains() []string
// ParseAction parses an HTTP request into a structured action
ParseAction(req *http.Request) (*Action, error)
// InjectCredentials adds authentication to the outbound request
InjectCredentials(req *http.Request, cred *Credential) error
}
type Action struct {
Type string // e.g., "github.pr.merge"
Resource Resource
Parameters map[string]any
RiskHints map[string]any
}Example: Custom Jira connector
package jira
import (
"net/http"
"strings"
"github.com/tameflare/tameflare/apps/gateway-v2/internal/connectors"
)
type JiraConnector struct{}
func (c *JiraConnector) Name() string {
return "jira"
}
func (c *JiraConnector) Domains() []string {
return []string{"your-org.atlassian.net"}
}
func (c *JiraConnector) ParseAction(req *http.Request) (*connectors.Action, error) {
path := req.URL.Path
method := req.Method
var actionType string
switch {
case method == "POST" && strings.Contains(path, "/rest/api/3/issue"):
actionType = "jira.issue.create"
case method == "PUT" && strings.Contains(path, "/rest/api/3/issue"):
actionType = "jira.issue.update"
case method == "DELETE" && strings.Contains(path, "/rest/api/3/issue"):
actionType = "jira.issue.delete"
case method == "POST" && strings.Contains(path, "/rest/api/3/issue") && strings.Contains(path, "/transitions"):
actionType = "jira.issue.transition"
default:
actionType = "jira." + strings.ToLower(method)
}
return &connectors.Action{
Type: actionType,
Resource: connectors.Resource{
Provider: "jira",
},
RiskHints: map[string]any{
"irreversible": method == "DELETE",
},
}, nil
}
func (c *JiraConnector) InjectCredentials(req *http.Request, cred *connectors.Credential) error {
req.Header.Set("Authorization", "Basic "+cred.Token)
return nil
}Registering a custom connector
Add your connector to the registry in internal/connectors/registry.go:
func NewRegistry() *Registry {
r := &Registry{connectors: make(map[string]Connector)}
r.Register(&github.GitHubConnector{})
r.Register(&openai.OpenAIConnector{})
r.Register(&stripe.StripeConnector{})
r.Register(&slack.SlackConnector{})
r.Register(&generic.GenericConnector{})
r.Register(&jira.JiraConnector{}) // Your custom connector
return r
}Rebuild the gateway after adding a connector:
cd apps/gateway-v2 && go build -o gateway ./cmd/gatewayNext steps
- Proxy Behavior — headers, streaming, protocol support
- Action Types — full action type reference
- Integration Guide — connecting your agent to TameFlare
- Writing Policies — create rules for connector actions