everyapp 0.2.2 → 0.3.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -77
- package/bin/everyapp.js +235 -0
- package/dist/access-F3GKBKAW.js +1 -0
- package/dist/activity-4MFMH5JP.js +12 -0
- package/dist/apps-63K2DGVT.js +9 -0
- package/dist/chunk-2UFJRKEE.js +4 -0
- package/dist/chunk-3AAHHUJC.js +11 -0
- package/dist/chunk-3Z53CH4F.js +6 -0
- package/dist/chunk-5ZTFC6DK.js +1 -0
- package/dist/chunk-6O3GJS5H.js +15 -0
- package/dist/chunk-74EST4VW.js +2 -0
- package/dist/chunk-7LG3F4FF.js +10 -0
- package/dist/chunk-AUDGOIHE.js +1 -0
- package/dist/chunk-BHMRY53V.js +2 -0
- package/dist/chunk-DQWOXSL3.js +32 -0
- package/dist/chunk-E3EPK27P.js +10 -0
- package/dist/chunk-E7EUXUVD.js +1 -0
- package/dist/chunk-ECLJ5IAL.js +126 -0
- package/dist/chunk-EQX4GKJ2.js +4 -0
- package/dist/chunk-EUNGJMJ6.js +20 -0
- package/dist/chunk-F6IH47GT.js +4 -0
- package/dist/chunk-G64S77GC.js +33 -0
- package/dist/chunk-GD2JZMD3.js +1 -0
- package/dist/chunk-GRFPP4UW.js +7 -0
- package/dist/chunk-IA534DGW.js +10 -0
- package/dist/chunk-IG26HYRR.js +45 -0
- package/dist/chunk-IZEOAOKL.js +6 -0
- package/dist/chunk-JYKRUS5C.js +1 -0
- package/dist/chunk-KMAOZRV4.js +18 -0
- package/dist/chunk-MC56CUQI.js +7 -0
- package/dist/chunk-MDORVBPD.js +1 -0
- package/dist/chunk-N4E5YE4X.js +5 -0
- package/dist/chunk-NJFWEYX7.js +1 -0
- package/dist/chunk-OEOVNJAN.js +1 -0
- package/dist/chunk-OVKVV6MK.js +2 -0
- package/dist/chunk-PL6EORDJ.js +15 -0
- package/dist/chunk-PMPIMHKG.js +6 -0
- package/dist/chunk-QZWSSWMP.js +22 -0
- package/dist/chunk-R4CGF622.js +2 -0
- package/dist/chunk-RFVMR32Y.js +1 -0
- package/dist/chunk-RQFHVU3Y.js +25 -0
- package/dist/chunk-SAT3PGZU.js +57 -0
- package/dist/chunk-SPPR6WCI.js +1 -0
- package/dist/chunk-TPWSGRNT.js +30 -0
- package/dist/chunk-VVQRET35.js +2 -0
- package/dist/chunk-VXJQGJ7Y.js +2 -0
- package/dist/chunk-WEM3WLOC.js +1 -0
- package/dist/chunk-Y3VIFPN5.js +1 -0
- package/dist/chunk-YJBYZWSP.js +22 -0
- package/dist/chunk-ZYL2ZHCF.js +98 -0
- package/dist/configure-2KMHM22T.js +8 -0
- package/dist/create-ELEJMZBS.js +22 -0
- package/dist/db-MZIAKGBN.js +9 -0
- package/dist/delete-H47KPJSB.js +3 -0
- package/dist/deploy-HGFJLLUO.js +1 -0
- package/dist/dev-62VA7UEM.js +86 -0
- package/dist/email-NNFD3VVB.js +10 -0
- package/dist/events-JDY76EG6.js +15 -0
- package/dist/groups-NQFXDZZP.js +8 -0
- package/dist/index.js +92 -1
- package/dist/install-JTZWRZIL.js +1 -0
- package/dist/login-P6LYQQWP.js +1 -0
- package/dist/mcp-NCFWEBMD.js +1 -0
- package/dist/provider-WVBI2VED.js +13 -0
- package/dist/release-6FYSPXXA.js +1 -0
- package/dist/restore-XBU7DOJV.js +3 -0
- package/dist/secret-ML5EXS3O.js +1 -0
- package/dist/setup-IEXCISLP.js +1 -0
- package/dist/status-OPLPKJ4U.js +4 -0
- package/dist/teardown-3JMMLK6O.js +22 -0
- package/dist/update-37ZDATLR.js +1 -0
- package/dist/workspace-DAFZVYQ2.js +21 -0
- package/package.json +30 -27
- package/skills/build-every-app/SKILL.md +199 -0
- package/skills/build-every-app/patterns.md +134 -0
- package/skills/everyapp/SKILL.md +292 -0
- package/skills/everyapp/mcp.md +336 -0
- package/skills/everyapp/security-review.md +61 -0
- package/skills/everyapp/setup/README.md +263 -0
- package/skills/everyapp/setup/access.md +178 -0
- package/skills/everyapp/setup/context.md +117 -0
- package/skills/everyapp/setup/dataforseo.md +287 -0
- package/skills/everyapp/setup/email.md +366 -0
- package/skills/everyapp/setup/gateway.md +243 -0
- package/skills/everyapp/setup/google.md +360 -0
- package/skills/everyapp/setup/microsoft-365.md +281 -0
- package/skills/everyapp/setup/openai.md +318 -0
- package/skills/everyapp/setup/openrouter.md +309 -0
- package/skills/everyapp/setup/providers.md +353 -0
- package/skills/everyapp/setup/remote-mcp.md +199 -0
- package/skills/everyapp/setup/slack.md +344 -0
- package/skills/everyapp/setup/workers-ai.md +138 -0
- package/bin/__everyapp_bash_complete.js +0 -12
- package/dist/bash-complete.js +0 -3
- package/dist/chunk-7BOQJFI5.js +0 -8
- package/dist/chunk-7YVJFS4A.js +0 -1
- package/dist/chunk-BIXKPCDH.js +0 -2
- package/dist/chunk-DLGPLHBH.js +0 -47
- package/dist/chunk-FD6K2YA7.js +0 -9
- package/dist/chunk-GAJEQYJH.js +0 -39
- package/dist/chunk-O2KDOP5R.js +0 -13
- package/dist/chunk-OI2MBGBG.js +0 -4
- package/dist/chunk-POSDLD3G.js +0 -8
- package/dist/chunk-RB5D2R45.js +0 -1
- package/dist/chunk-U4LIQ5VR.js +0 -1
- package/dist/chunk-VEYSNPDH.js +0 -3
- package/dist/chunk-VP6SKW44.js +0 -7
- package/dist/chunk-WO3NE7ZU.js +0 -7
- package/dist/chunk-XTO2VTPY.js +0 -6
- package/dist/chunk-YJ2DKIZS.js +0 -1
- package/dist/create-DYQ3NBWJ.js +0 -22
- package/dist/deploy-PYTCMDGV.js +0 -7
- package/dist/deploy-RMAHOA4Z.js +0 -55
- package/dist/dev-SAE237FS.js +0 -0
- package/dist/generateConfig-46Z3ERF3.js +0 -1
- package/dist/login-B6EF3SMX.js +0 -1
- package/dist/logout-XMKZBLNV.js +0 -1
- package/dist/remoteD1Shell-A67JMO3H.js +0 -6
- package/dist/setupLocal-TZJUW5ES.js +0 -6
- package/gateway/every-app-gateway-build.tar.gz +0 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
<!-- generated: pnpm -C packages/cli docs:update writes this file from the built-in catalog (packages/sdk/src/internal/capabilities.ts, through packages/cli/src/docs/providersCatalog.ts). Edit the catalog, never this file: a test fails CI when it is stale. -->
|
|
2
|
+
|
|
3
|
+
# Every catalog provider: its settings, its key and one check
|
|
4
|
+
|
|
5
|
+
For a coding agent setting up a provider the Gateway's built-in catalog has. Each provider is a section under its id, so `setup/providers.md#<id>` points at it. Where the provider has a file of its own in this folder (its **Guide**), follow that file and read this section as its summary. Read [README.md](README.md) first: its rules hold here too, above all that a key never goes through the chat.
|
|
6
|
+
|
|
7
|
+
A provider registered on one Gateway (`pnpm everyapp provider add`) is not in this file: `pnpm everyapp provider show <id>` prints its whole spec (its hint, settings, hosts, where the key comes from and its smoke request). The catalog has 23 providers: 2 API-key, 3 AI, 18 OAuth clients.
|
|
8
|
+
|
|
9
|
+
The smoke request needs the key, so it runs where the key is: the person's terminal, with the variable they read in hidden, or through the app that uses it. It is one call that costs nothing (unless marked charged).
|
|
10
|
+
|
|
11
|
+
## How a value gets in
|
|
12
|
+
|
|
13
|
+
The three ways of [README.md](README.md), one line each (the rules, and the codes a failure carries, are there):
|
|
14
|
+
|
|
15
|
+
- **The person types it**, in their own terminal in the `every-app` folder: `pnpm everyapp configure <app id>` (everything the app needs) or `pnpm everyapp secret set NAME` (one name), each value at a hidden prompt.
|
|
16
|
+
- **A command produced it**: pipe it straight in, `… | pnpm everyapp secret set NAME --json`, so it is never shown.
|
|
17
|
+
- **It is in an environment variable** the person read in hidden: `pnpm everyapp secret set NAME --from-env NAME --json`, or `pnpm everyapp configure <app id> --from-env --json`.
|
|
18
|
+
|
|
19
|
+
## Providers
|
|
20
|
+
|
|
21
|
+
| Id | Name | Kind | Settings | Guide |
|
|
22
|
+
| --- | --- | --- | --- | --- |
|
|
23
|
+
| [`dataforseo`](#dataforseo) | DataForSEO | API key | `DATAFORSEO_API_KEY` | [dataforseo.md](dataforseo.md) |
|
|
24
|
+
| [`context`](#context) | Context.dev | API key | `CONTEXT_API_KEY` | [context.md](context.md) |
|
|
25
|
+
| [`openai`](#openai) | OpenAI | AI | `OPENAI_API_KEY` | [openai.md](openai.md) |
|
|
26
|
+
| [`openrouter`](#openrouter) | OpenRouter | AI | `OPENROUTER_API_KEY` | [openrouter.md](openrouter.md) |
|
|
27
|
+
| [`workers-ai`](#workers-ai) | Workers AI | AI | `WORKERS_AI_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID` (set by `everyapp setup`) | [workers-ai.md](workers-ai.md) |
|
|
28
|
+
| [`linkedin`](#linkedin) | LinkedIn | OAuth client | `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET` | |
|
|
29
|
+
| [`facebook`](#facebook) | Facebook | OAuth client | `FACEBOOK_APP_ID`, `FACEBOOK_APP_SECRET` | |
|
|
30
|
+
| [`instagram`](#instagram) | Instagram | OAuth client | `INSTAGRAM_APP_ID`, `INSTAGRAM_APP_SECRET` | |
|
|
31
|
+
| [`threads`](#threads) | Threads | OAuth client | `THREADS_APP_ID`, `THREADS_APP_SECRET` | |
|
|
32
|
+
| [`youtube`](#youtube) | YouTube | OAuth client | `YOUTUBE_CLIENT_ID`, `YOUTUBE_CLIENT_SECRET` | [google.md](google.md) |
|
|
33
|
+
| [`tiktok`](#tiktok) | TikTok | OAuth client | `TIKTOK_CLIENT_ID`, `TIKTOK_CLIENT_SECRET` | |
|
|
34
|
+
| [`tiktok-business`](#tiktok-business) | TikTok Business | OAuth client | `TIKTOK_BUSINESS_CLIENT_ID`, `TIKTOK_BUSINESS_CLIENT_SECRET` | |
|
|
35
|
+
| [`reddit`](#reddit) | Reddit | OAuth client | `REDDIT_CLIENT_ID`, `REDDIT_CLIENT_SECRET` | |
|
|
36
|
+
| [`pinterest`](#pinterest) | Pinterest | OAuth client | `PINTEREST_CLIENT_ID`, `PINTEREST_CLIENT_SECRET` | |
|
|
37
|
+
| [`discord`](#discord) | Discord | OAuth client | `DISCORD_CLIENT_ID`, `DISCORD_CLIENT_SECRET` | |
|
|
38
|
+
| [`slack`](#slack) | Slack | OAuth client | `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET` | [slack.md](slack.md) |
|
|
39
|
+
| [`mastodon`](#mastodon) | Mastodon | OAuth client | `MASTODON_CLIENT_ID`, `MASTODON_CLIENT_SECRET`, `MASTODON_URL` | |
|
|
40
|
+
| [`kick`](#kick) | Kick | OAuth client | `KICK_CLIENT_ID`, `KICK_CLIENT_SECRET` | |
|
|
41
|
+
| [`twitch`](#twitch) | Twitch | OAuth client | `TWITCH_CLIENT_ID`, `TWITCH_CLIENT_SECRET` | |
|
|
42
|
+
| [`tumblr`](#tumblr) | Tumblr | OAuth client | `TUMBLR_CLIENT_ID`, `TUMBLR_CLIENT_SECRET` | |
|
|
43
|
+
| [`dribbble`](#dribbble) | Dribbble | OAuth client | `DRIBBBLE_CLIENT_ID`, `DRIBBBLE_CLIENT_SECRET` | |
|
|
44
|
+
| [`google-workspace`](#google-workspace) | Google (Gmail, Calendar, Search Console and Analytics) | OAuth client | `GOOGLE_WORKSPACE_CLIENT_ID`, `GOOGLE_WORKSPACE_CLIENT_SECRET` | [google.md](google.md) |
|
|
45
|
+
| [`microsoft-365`](#microsoft-365) | Microsoft 365 (Outlook mail and calendar) | OAuth client | `MICROSOFT_365_CLIENT_ID`, `MICROSOFT_365_CLIENT_SECRET` | [microsoft-365.md](microsoft-365.md) |
|
|
46
|
+
|
|
47
|
+
Gateway services have no key of this kind: `email`, `members` (sending mail is [email.md](email.md); the members list needs nothing).
|
|
48
|
+
|
|
49
|
+
## API-key providers
|
|
50
|
+
|
|
51
|
+
### dataforseo
|
|
52
|
+
|
|
53
|
+
**DataForSEO** (`api_key`): SEO data: keyword metrics, live search results, domain rankings, backlinks.
|
|
54
|
+
|
|
55
|
+
- **Settings:** `DATAFORSEO_API_KEY`
|
|
56
|
+
- **What the key is:** The API login and password from API Access, as login:password (or that pair base64-encoded); the Gateway sends them as HTTP Basic. login:password, or its base64; never the dashboard sign-in password.
|
|
57
|
+
- **Where the key comes from:** https://app.dataforseo.com/api-access
|
|
58
|
+
- **API reference:** https://docs.dataforseo.com/v3/
|
|
59
|
+
- **How it is sent:** `Authorization: Basic <DATAFORSEO_API_KEY>`, the value `login:password` base64-encoded (or sent as it is when it holds no colon: already encoded), to `api.dataforseo.com`, `sandbox.dataforseo.com` only, over https
|
|
60
|
+
- **What apps may do:** access `read`; GET, POST on any grant; account-wide paths refused: `tasks_ready`, `tasks_fixed`, `id_list`, `errors`, `appendix/user_data`, `appendix/webhook_resend`
|
|
61
|
+
- **Smoke request:** `GET https://api.dataforseo.com/v3/appendix/user_data`, expecting 200; free. Account-wide, so the Gateway refuses it for apps; run it from the person's terminal.
|
|
62
|
+
- **Cost:** per call. A Google SERP $0.002 per 10 results; a Labs task $0.012 plus $0.00012 per item. The Gateway reads each answer's `cost` field (US dollars) into the usage counters.
|
|
63
|
+
- **Rate:** not recorded
|
|
64
|
+
- **Verified:** 2026-10-25, live
|
|
65
|
+
- **Set it:** `pnpm everyapp secret set DATAFORSEO_API_KEY`, or `pnpm everyapp configure <app id>` for everything an app needs
|
|
66
|
+
- **Guide:** [dataforseo.md](dataforseo.md)
|
|
67
|
+
|
|
68
|
+
### context
|
|
69
|
+
|
|
70
|
+
**Context.dev** (`api_key`): Scrapes and renders web pages, JavaScript included.
|
|
71
|
+
|
|
72
|
+
- **Settings:** `CONTEXT_API_KEY`
|
|
73
|
+
- **What the key is:** An API key from the Context.dev dashboard; the Gateway puts it on every call as a bearer token.
|
|
74
|
+
- **Where the key comes from:** https://context.dev/
|
|
75
|
+
- **How it is sent:** `Authorization: Bearer <CONTEXT_API_KEY>`, to `api.context.dev` only, over https
|
|
76
|
+
- **What apps may do:** access `read`; GET, POST on any grant
|
|
77
|
+
- **Smoke request:** none recorded
|
|
78
|
+
- **Cost:** not recorded
|
|
79
|
+
- **Rate:** not recorded
|
|
80
|
+
- **Verified:** 2026-10-25, live
|
|
81
|
+
- **Set it:** `pnpm everyapp secret set CONTEXT_API_KEY`, or `pnpm everyapp configure <app id>` for everything an app needs
|
|
82
|
+
- **Guide:** [context.md](context.md)
|
|
83
|
+
|
|
84
|
+
## AI providers
|
|
85
|
+
|
|
86
|
+
### openai
|
|
87
|
+
|
|
88
|
+
**OpenAI** (`ai`): OpenAI's models: responses, chat, embeddings, audio, images.
|
|
89
|
+
|
|
90
|
+
- **Settings:** `OPENAI_API_KEY`
|
|
91
|
+
- **What the key is:** A secret key from the API keys page; the Gateway puts it on every call as a bearer token.
|
|
92
|
+
- **Where the key comes from:** https://platform.openai.com/api-keys
|
|
93
|
+
- **API reference:** https://platform.openai.com/docs/api-reference
|
|
94
|
+
- **How it is sent:** `Authorization: Bearer <OPENAI_API_KEY>`, to `api.openai.com` only, over https
|
|
95
|
+
- **What apps may do:** list it under `providers` and call `/api/ai/openai/…` with `createGatewayFetch()`: POST to `/v1/responses`, `/v1/chat/completions`, `/v1/embeddings`, `/v1/audio/speech`, `/v1/audio/transcriptions`, `/v1/audio/translations`, `/v1/images/generations`, `/v1/images/edits`, `/v1/images/variations`, and more only where both `AI_PROXY_EXTRA_ROUTES` and the app's `ai.routes` allow it
|
|
96
|
+
- **Smoke request:** none recorded
|
|
97
|
+
- **Cost:** not recorded
|
|
98
|
+
- **Rate:** not recorded
|
|
99
|
+
- **Verified:** 2026-10-25, live
|
|
100
|
+
- **Set it:** `pnpm everyapp secret set OPENAI_API_KEY`, or `pnpm everyapp configure <app id>` for everything an app needs
|
|
101
|
+
- **Guide:** [openai.md](openai.md)
|
|
102
|
+
|
|
103
|
+
### openrouter
|
|
104
|
+
|
|
105
|
+
**OpenRouter** (`ai`): One key for many models, through OpenAI's API shape.
|
|
106
|
+
|
|
107
|
+
- **Settings:** `OPENROUTER_API_KEY`
|
|
108
|
+
- **What the key is:** An API key from OpenRouter's keys page; the Gateway puts it on every call as a bearer token.
|
|
109
|
+
- **Where the key comes from:** https://openrouter.ai/settings/keys
|
|
110
|
+
- **API reference:** https://openrouter.ai/docs
|
|
111
|
+
- **How it is sent:** `Authorization: Bearer <OPENROUTER_API_KEY>`, to `openrouter.ai` only, over https
|
|
112
|
+
- **What apps may do:** list it under `providers` and call `/api/ai/openrouter/…` with `createGatewayFetch()`: POST to `/api/v1/chat/completions`, `/api/v1/completions`, `/api/v1/responses`, `/api/v1/embeddings`
|
|
113
|
+
- **Smoke request:** none recorded
|
|
114
|
+
- **Cost:** not recorded
|
|
115
|
+
- **Rate:** not recorded
|
|
116
|
+
- **Verified:** 2026-10-25, live
|
|
117
|
+
- **Set it:** `pnpm everyapp secret set OPENROUTER_API_KEY`, or `pnpm everyapp configure <app id>` for everything an app needs
|
|
118
|
+
- **Guide:** [openrouter.md](openrouter.md)
|
|
119
|
+
|
|
120
|
+
### workers-ai
|
|
121
|
+
|
|
122
|
+
**Workers AI** (`ai`): Cloudflare's models, in the Gateway's own account.
|
|
123
|
+
|
|
124
|
+
- **Settings:** `WORKERS_AI_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID` (set by `everyapp setup`)
|
|
125
|
+
- **What the key is:** A Cloudflare API token with Workers AI Read (the Workers AI page's prefilled token); the account is the Gateway's own.
|
|
126
|
+
- **Where the key comes from:** https://dash.cloudflare.com/profile/api-tokens
|
|
127
|
+
- **API reference:** https://developers.cloudflare.com/workers-ai/
|
|
128
|
+
- **How it is sent:** `Authorization: Bearer <WORKERS_AI_API_TOKEN>`, to `api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai` only, over https
|
|
129
|
+
- **What apps may do:** list it under `providers` and call `/api/ai/workers-ai/…` with `createGatewayFetch()`: POST to `/v1/chat/completions`, `/v1/embeddings`, `/v1/responses`
|
|
130
|
+
- **Smoke request:** none recorded
|
|
131
|
+
- **Cost:** not recorded
|
|
132
|
+
- **Rate:** not recorded
|
|
133
|
+
- **Verified:** 2026-10-25, live
|
|
134
|
+
- **Set it:** `pnpm everyapp secret set WORKERS_AI_API_TOKEN`, or `pnpm everyapp configure <app id>` for everything an app needs
|
|
135
|
+
- **Guide:** [workers-ai.md](workers-ai.md)
|
|
136
|
+
|
|
137
|
+
## OAuth clients
|
|
138
|
+
|
|
139
|
+
### linkedin
|
|
140
|
+
|
|
141
|
+
**LinkedIn** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
142
|
+
|
|
143
|
+
- **Settings:** `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET`
|
|
144
|
+
- **Where the client comes from:** https://www.linkedin.com/developers/apps
|
|
145
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/linkedin`, `https://<app>.<APP_BASE_DOMAIN>/integrations/social/linkedin-page`
|
|
146
|
+
- **How it is sent:** POST `www.linkedin.com/oauth/v2/accessToken` (the client in the form body)
|
|
147
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
148
|
+
- **Set it:** `pnpm everyapp secret set LINKEDIN_CLIENT_ID LINKEDIN_CLIENT_SECRET`
|
|
149
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
150
|
+
|
|
151
|
+
### facebook
|
|
152
|
+
|
|
153
|
+
**Facebook** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
154
|
+
|
|
155
|
+
- **Settings:** `FACEBOOK_APP_ID`, `FACEBOOK_APP_SECRET`
|
|
156
|
+
- **Where the client comes from:** https://developers.facebook.com/apps
|
|
157
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/facebook`, `https://<app>.<APP_BASE_DOMAIN>/integrations/social/instagram`
|
|
158
|
+
- **How it is sent:** GET/POST `graph.facebook.com/v<version>/oauth/access_token` (the client in the query)
|
|
159
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
160
|
+
- **Set it:** `pnpm everyapp secret set FACEBOOK_APP_ID FACEBOOK_APP_SECRET`
|
|
161
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
162
|
+
|
|
163
|
+
### instagram
|
|
164
|
+
|
|
165
|
+
**Instagram** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
166
|
+
|
|
167
|
+
- **Settings:** `INSTAGRAM_APP_ID`, `INSTAGRAM_APP_SECRET`
|
|
168
|
+
- **Where the client comes from:** https://developers.facebook.com/apps
|
|
169
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/instagram-standalone`
|
|
170
|
+
- **How it is sent:** POST `api.instagram.com/oauth/access_token` (the client in the form body); GET `graph.instagram.com/access_token` (the client in the query)
|
|
171
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
172
|
+
- **Set it:** `pnpm everyapp secret set INSTAGRAM_APP_ID INSTAGRAM_APP_SECRET`
|
|
173
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
174
|
+
|
|
175
|
+
### threads
|
|
176
|
+
|
|
177
|
+
**Threads** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
178
|
+
|
|
179
|
+
- **Settings:** `THREADS_APP_ID`, `THREADS_APP_SECRET`
|
|
180
|
+
- **Where the client comes from:** https://developers.facebook.com/apps
|
|
181
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/threads`
|
|
182
|
+
- **How it is sent:** GET/POST `graph.threads.net/oauth/access_token` (the client in the query); GET `graph.threads.net/access_token` (the client in the query)
|
|
183
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
184
|
+
- **Set it:** `pnpm everyapp secret set THREADS_APP_ID THREADS_APP_SECRET`
|
|
185
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
186
|
+
|
|
187
|
+
### youtube
|
|
188
|
+
|
|
189
|
+
**YouTube** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
190
|
+
|
|
191
|
+
- **Settings:** `YOUTUBE_CLIENT_ID`, `YOUTUBE_CLIENT_SECRET`
|
|
192
|
+
- **Where the client comes from:** https://console.cloud.google.com/apis/credentials
|
|
193
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/youtube`, `https://<app>.<APP_BASE_DOMAIN>/integrations/social/gmb`
|
|
194
|
+
- **How it is sent:** POST `oauth2.googleapis.com/token` (the client in the form body)
|
|
195
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
196
|
+
- **Set it:** `pnpm everyapp secret set YOUTUBE_CLIENT_ID YOUTUBE_CLIENT_SECRET`
|
|
197
|
+
- **Guide:** [google.md](google.md)
|
|
198
|
+
|
|
199
|
+
### tiktok
|
|
200
|
+
|
|
201
|
+
**TikTok** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
202
|
+
|
|
203
|
+
- **Settings:** `TIKTOK_CLIENT_ID`, `TIKTOK_CLIENT_SECRET`
|
|
204
|
+
- **Where the client comes from:** https://developers.tiktok.com/apps
|
|
205
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/tiktok`
|
|
206
|
+
- **How it is sent:** POST `open.tiktokapis.com/v2/oauth/token/` (the client in the form body)
|
|
207
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
208
|
+
- **Set it:** `pnpm everyapp secret set TIKTOK_CLIENT_ID TIKTOK_CLIENT_SECRET`
|
|
209
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
210
|
+
|
|
211
|
+
### tiktok-business
|
|
212
|
+
|
|
213
|
+
**TikTok Business** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
214
|
+
|
|
215
|
+
- **Settings:** `TIKTOK_BUSINESS_CLIENT_ID`, `TIKTOK_BUSINESS_CLIENT_SECRET`
|
|
216
|
+
- **Where the client comes from:** https://business-api.tiktok.com/portal/apps
|
|
217
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/tiktok-business/`
|
|
218
|
+
- **How it is sent:** POST `business-api.tiktok.com/open_api/v1.3/tt_user/oauth2/token/` (the client in the JSON body); POST `business-api.tiktok.com/open_api/v1.3/tt_user/oauth2/refresh_token/` (the client in the JSON body)
|
|
219
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
220
|
+
- **Set it:** `pnpm everyapp secret set TIKTOK_BUSINESS_CLIENT_ID TIKTOK_BUSINESS_CLIENT_SECRET`
|
|
221
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
222
|
+
|
|
223
|
+
### reddit
|
|
224
|
+
|
|
225
|
+
**Reddit** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
226
|
+
|
|
227
|
+
- **Settings:** `REDDIT_CLIENT_ID`, `REDDIT_CLIENT_SECRET`
|
|
228
|
+
- **Where the client comes from:** https://www.reddit.com/prefs/apps
|
|
229
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/reddit`
|
|
230
|
+
- **How it is sent:** POST `www.reddit.com/api/v1/access_token` (the client in the Basic header)
|
|
231
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
232
|
+
- **Set it:** `pnpm everyapp secret set REDDIT_CLIENT_ID REDDIT_CLIENT_SECRET`
|
|
233
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
234
|
+
|
|
235
|
+
### pinterest
|
|
236
|
+
|
|
237
|
+
**Pinterest** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
238
|
+
|
|
239
|
+
- **Settings:** `PINTEREST_CLIENT_ID`, `PINTEREST_CLIENT_SECRET`
|
|
240
|
+
- **Where the client comes from:** https://developers.pinterest.com/apps/
|
|
241
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/pinterest`
|
|
242
|
+
- **How it is sent:** POST `api.pinterest.com/v5/oauth/token` (the client in the Basic header)
|
|
243
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
244
|
+
- **Set it:** `pnpm everyapp secret set PINTEREST_CLIENT_ID PINTEREST_CLIENT_SECRET`
|
|
245
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
246
|
+
|
|
247
|
+
### discord
|
|
248
|
+
|
|
249
|
+
**Discord** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
250
|
+
|
|
251
|
+
- **Settings:** `DISCORD_CLIENT_ID`, `DISCORD_CLIENT_SECRET`
|
|
252
|
+
- **Where the client comes from:** https://discord.com/developers/applications
|
|
253
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/discord`
|
|
254
|
+
- **How it is sent:** POST `discord.com/api/oauth2/token` (the client in the Basic header)
|
|
255
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
256
|
+
- **Set it:** `pnpm everyapp secret set DISCORD_CLIENT_ID DISCORD_CLIENT_SECRET`
|
|
257
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
258
|
+
|
|
259
|
+
### slack
|
|
260
|
+
|
|
261
|
+
**Slack** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
262
|
+
|
|
263
|
+
- **Settings:** `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`
|
|
264
|
+
- **Where the client comes from:** https://api.slack.com/apps
|
|
265
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/slack`, `https://<app>.<APP_BASE_DOMAIN>/integrations/slack/callback`
|
|
266
|
+
- **How it is sent:** POST `slack.com/api/oauth.v2.access` (the client in the form body)
|
|
267
|
+
- **Scope sets an app lists:** `channels.read`, `users.read`, `users.email`, `messages.write`, `channels.join`, `channels.manage`, `files.write`, `user-channels.manage`
|
|
268
|
+
- **Set it:** `pnpm everyapp secret set SLACK_CLIENT_ID SLACK_CLIENT_SECRET`
|
|
269
|
+
- **Guide:** [slack.md](slack.md)
|
|
270
|
+
|
|
271
|
+
### mastodon
|
|
272
|
+
|
|
273
|
+
**Mastodon** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
274
|
+
|
|
275
|
+
- **Settings:** `MASTODON_CLIENT_ID`, `MASTODON_CLIENT_SECRET`, `MASTODON_URL`
|
|
276
|
+
- **Where the client comes from:** `<MASTODON_URL>/settings/applications`
|
|
277
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/mastodon`
|
|
278
|
+
- **How it is sent:** POST `<MASTODON_URL>/oauth/token` (the client in the form body)
|
|
279
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
280
|
+
- **Set it:** `pnpm everyapp secret set MASTODON_CLIENT_ID MASTODON_CLIENT_SECRET MASTODON_URL`
|
|
281
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
282
|
+
|
|
283
|
+
### kick
|
|
284
|
+
|
|
285
|
+
**Kick** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
286
|
+
|
|
287
|
+
- **Settings:** `KICK_CLIENT_ID`, `KICK_CLIENT_SECRET`
|
|
288
|
+
- **Where the client comes from:** https://kick.com/settings/developer
|
|
289
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/kick`
|
|
290
|
+
- **How it is sent:** POST `id.kick.com/oauth/token` (the client in the form body)
|
|
291
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
292
|
+
- **Set it:** `pnpm everyapp secret set KICK_CLIENT_ID KICK_CLIENT_SECRET`
|
|
293
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
294
|
+
|
|
295
|
+
### twitch
|
|
296
|
+
|
|
297
|
+
**Twitch** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
298
|
+
|
|
299
|
+
- **Settings:** `TWITCH_CLIENT_ID`, `TWITCH_CLIENT_SECRET`
|
|
300
|
+
- **Where the client comes from:** https://dev.twitch.tv/console/apps
|
|
301
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/twitch`
|
|
302
|
+
- **How it is sent:** POST `id.twitch.tv/oauth2/token` (the client in the form body)
|
|
303
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
304
|
+
- **Set it:** `pnpm everyapp secret set TWITCH_CLIENT_ID TWITCH_CLIENT_SECRET`
|
|
305
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
306
|
+
|
|
307
|
+
### tumblr
|
|
308
|
+
|
|
309
|
+
**Tumblr** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
310
|
+
|
|
311
|
+
- **Settings:** `TUMBLR_CLIENT_ID`, `TUMBLR_CLIENT_SECRET`
|
|
312
|
+
- **Where the client comes from:** https://www.tumblr.com/oauth/apps
|
|
313
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/tumblr`
|
|
314
|
+
- **How it is sent:** POST `api.tumblr.com/v2/oauth2/token` (the client in the form body)
|
|
315
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
316
|
+
- **Set it:** `pnpm everyapp secret set TUMBLR_CLIENT_ID TUMBLR_CLIENT_SECRET`
|
|
317
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
318
|
+
|
|
319
|
+
### dribbble
|
|
320
|
+
|
|
321
|
+
**Dribbble** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
322
|
+
|
|
323
|
+
- **Settings:** `DRIBBBLE_CLIENT_ID`, `DRIBBBLE_CLIENT_SECRET`
|
|
324
|
+
- **Where the client comes from:** https://dribbble.com/account/applications
|
|
325
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/social/dribbble`
|
|
326
|
+
- **How it is sent:** POST `dribbble.com/oauth/token` (the client in the query)
|
|
327
|
+
- **Scope sets an app lists:** none: the whole client is the grant
|
|
328
|
+
- **Set it:** `pnpm everyapp secret set DRIBBBLE_CLIENT_ID DRIBBBLE_CLIENT_SECRET`
|
|
329
|
+
- **Guide:** none beyond this section; the scopes to allow are in https://everyapp.com/docs/agent/repo/capabilities#oauth-clients
|
|
330
|
+
|
|
331
|
+
### google-workspace
|
|
332
|
+
|
|
333
|
+
**Google (Gmail, Calendar, Search Console and Analytics)** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
334
|
+
|
|
335
|
+
- **Settings:** `GOOGLE_WORKSPACE_CLIENT_ID`, `GOOGLE_WORKSPACE_CLIENT_SECRET`
|
|
336
|
+
- **Where the client comes from:** https://console.cloud.google.com/apis/credentials
|
|
337
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/google/callback`
|
|
338
|
+
- **How it is sent:** POST `oauth2.googleapis.com/token` (the client in the form body)
|
|
339
|
+
- **Scope sets an app lists:** `identity`, `gmail.read`, `calendar.read`, `search-console.read`, `analytics.read`
|
|
340
|
+
- **Set it:** `pnpm everyapp secret set GOOGLE_WORKSPACE_CLIENT_ID GOOGLE_WORKSPACE_CLIENT_SECRET`
|
|
341
|
+
- **Guide:** [google.md](google.md)
|
|
342
|
+
|
|
343
|
+
### microsoft-365
|
|
344
|
+
|
|
345
|
+
**Microsoft 365 (Outlook mail and calendar)** (`oauth_client`): the Gateway holds the client and completes the token endpoints only; the app builds the authorize URL from the public client id and keeps people's tokens.
|
|
346
|
+
|
|
347
|
+
- **Settings:** `MICROSOFT_365_CLIENT_ID`, `MICROSOFT_365_CLIENT_SECRET`
|
|
348
|
+
- **Where the client comes from:** https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
|
|
349
|
+
- **Redirect URIs to register:** `https://<app>.<APP_BASE_DOMAIN>/integrations/microsoft/callback`
|
|
350
|
+
- **How it is sent:** POST `login.microsoftonline.com/common/oauth2/v2.0/token` (the client in the form body)
|
|
351
|
+
- **Scope sets an app lists:** `identity`, `mail.read`, `calendar.read`
|
|
352
|
+
- **Set it:** `pnpm everyapp secret set MICROSOFT_365_CLIENT_ID MICROSOFT_365_CLIENT_SECRET`
|
|
353
|
+
- **Guide:** [microsoft-365.md](microsoft-365.md)
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# A remote MCP server as an MCP app
|
|
2
|
+
|
|
3
|
+
Any remote MCP server that speaks Streamable HTTP (a docs search, a
|
|
4
|
+
company's API, a SaaS tool's MCP endpoint) can become an MCP app of the
|
|
5
|
+
Gateway's: `pnpm everyapp mcp add <url>` registers it, the Gateway serves its
|
|
6
|
+
tools on its own `/mcp` to every member it is granted to as `<id>_<tool>`,
|
|
7
|
+
holds the server's credential itself (a Gateway setting, never sent to an AI
|
|
8
|
+
client), sends it only to the server's origin, and attributes, audits and
|
|
9
|
+
counts every call like an app's. A read-only connection sees only the tools
|
|
10
|
+
whose risk is `read`. At the end the person has the app on, its credential
|
|
11
|
+
set and pinned to the server's origin, the people who need it granted, and
|
|
12
|
+
one tool call through the Gateway's `/mcp` that worked.
|
|
13
|
+
|
|
14
|
+
## Settings
|
|
15
|
+
|
|
16
|
+
| NAME | required or optional | what it holds |
|
|
17
|
+
| ------------------------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| `<ID>_MCP_TOKEN` (the app id upper-cased, `-` as `_`; `--secret` picks another name ending in `_MCP_TOKEN`) | required, unless the server takes no credential (`--auth none`) | What the server's docs call its API key, token or password. `--auth bearer` sends it as `Authorization: Bearer <value>`; `--auth header --header X-Api-Key` as `X-Api-Key: <value>`; `--auth basic` takes `user:password` and sends HTTP Basic. |
|
|
19
|
+
|
|
20
|
+
The name is a Gateway setting like any provider key, set with
|
|
21
|
+
`pnpm everyapp secret set <NAME>` (any name ending in `_MCP_TOKEN` goes to the
|
|
22
|
+
Gateway; nothing else is accepted for it). When it is set, the CLI pins it to
|
|
23
|
+
the origin of the MCP app that declares it (`https://treg.to` for
|
|
24
|
+
`https://treg.to/mcp/`): the Gateway sends a credential only to the origin it
|
|
25
|
+
was set for. A server re-pointed or re-added at another address needs its
|
|
26
|
+
credential set again; only the operator (the Cloudflare login) can, so an
|
|
27
|
+
owner or admin who changes an app in the Gateway never moves a credential.
|
|
28
|
+
`mcp list` and `mcp show` say "needs setup" until it is set and pinned.
|
|
29
|
+
|
|
30
|
+
`--auth oauth` is accepted and recorded, but the Gateway doesn't sign in to
|
|
31
|
+
MCP servers with OAuth this week: such an app serves no tools ("OAuth: not
|
|
32
|
+
supported yet"). If an OAuth server also takes an API key, add it with
|
|
33
|
+
`--auth bearer` instead.
|
|
34
|
+
|
|
35
|
+
## Costs and plans
|
|
36
|
+
|
|
37
|
+
Every App charges nothing for an MCP app. The server's provider charges what
|
|
38
|
+
it charges for its calls (its own plan and limits apply; read them on its
|
|
39
|
+
site). Every forwarded call is counted in the organization's usage as
|
|
40
|
+
`mcp:<id>`, and an owner or admin can cap an app's calls per month in Admin →
|
|
41
|
+
Usage (off by default): past the cap a tool answers a tool error naming it
|
|
42
|
+
until the next UTC month.
|
|
43
|
+
|
|
44
|
+
## Only a person can
|
|
45
|
+
|
|
46
|
+
- Create an account with the server's provider and accept its terms, when it
|
|
47
|
+
has any.
|
|
48
|
+
- Create the API key or token on the provider's dashboard and type it at the
|
|
49
|
+
hidden prompt.
|
|
50
|
+
- Decide who gets the app beyond the owners and admins (Admin → Apps → Manage
|
|
51
|
+
access), and whether a tool the server says is safe should count as a write
|
|
52
|
+
(you suggest; they decide).
|
|
53
|
+
- Decide to replace a credential the Gateway already holds.
|
|
54
|
+
|
|
55
|
+
## Before you start
|
|
56
|
+
|
|
57
|
+
1. `pnpm everyapp status --json`: `data.installed` and `data.claimed` are
|
|
58
|
+
true; `data.gatewayUrl` is `https://<gateway host>`. Not installed, or no
|
|
59
|
+
owner: [gateway.md](gateway.md) first.
|
|
60
|
+
2. The server's MCP address and how it authenticates, from its docs: an
|
|
61
|
+
`https://` URL (often ending in `/mcp`) that speaks Streamable HTTP. An old
|
|
62
|
+
HTTP+SSE-only endpoint (a separate `/sse` URL from 2024) isn't served. The
|
|
63
|
+
credential is usually an API key sent as a bearer token; some servers read
|
|
64
|
+
a header of their own (`X-Api-Key`); public servers take none. The
|
|
65
|
+
Gateway follows no redirects, so use the address the server answers at,
|
|
66
|
+
not one that redirects to it.
|
|
67
|
+
3. `pnpm everyapp mcp list --json`: the server isn't added already (no entry
|
|
68
|
+
in `data.apps` with its `url`). The id is the domain's name, the label
|
|
69
|
+
before its suffix (`https://mcp.deepwiki.com/mcp` → `deepwiki`,
|
|
70
|
+
`https://treg.to/mcp/` → `treg`), or `--name <id>` (lowercase letters,
|
|
71
|
+
digits and hyphens, at most 32 characters); it is the tools' prefix, so
|
|
72
|
+
keep it short.
|
|
73
|
+
|
|
74
|
+
## Steps
|
|
75
|
+
|
|
76
|
+
One step per message: give the step, wait for the words it ends with
|
|
77
|
+
("done", "I have it"), then the next.
|
|
78
|
+
|
|
79
|
+
1. **You:** add it. `pnpm everyapp mcp add <url> --auth bearer --json` (or
|
|
80
|
+
`--auth header --header <name>`, `--auth basic`; nothing for a public
|
|
81
|
+
server), with `--name <id>` when the host name makes a poor id and
|
|
82
|
+
`--risk read` for a server that only reads and doesn't say so in its tool
|
|
83
|
+
annotations (`--risk write` treats every tool as a write). The app is on
|
|
84
|
+
at once for the person running it (when they are a member), the owners
|
|
85
|
+
and the admins. The `done` event's `data.id`, `data.key` (null for
|
|
86
|
+
`--auth none`; else the credential's `name` and whether it is `set` and
|
|
87
|
+
`bound` to the URL's origin) and `data.probe` (what one look at the server
|
|
88
|
+
from this machine found, without the credential) say what happened.
|
|
89
|
+
`PROVIDER_KEY_UNSET` means the credential comes next.
|
|
90
|
+
`REMOTE_MCP_PROBE_FAILED` and `REMOTE_MCP_WANTS_OAUTH` are warnings, never
|
|
91
|
+
refusals: a 401 with `--auth none` means the server wants a credential
|
|
92
|
+
(`pnpm everyapp mcp remove <id>`, then the same add with `--auth bearer`), a
|
|
93
|
+
redirect means another address, and "Couldn't reach" may be this
|
|
94
|
+
machine's network only (the Gateway fetches from Cloudflare).
|
|
95
|
+
2. **Person:** the credential. They create the key on the provider's
|
|
96
|
+
dashboard, then, in a second terminal in the `every-app` folder:
|
|
97
|
+
`pnpm everyapp secret set <NAME>` (the name from step 1, for example
|
|
98
|
+
`pnpm everyapp secret set TREG_MCP_TOKEN`) and paste it at the hidden
|
|
99
|
+
prompt (for `--auth basic`, `user:password`). It ends with
|
|
100
|
+
`Set <NAME> on the Gateway`. When the person runs `mcp add` themselves at
|
|
101
|
+
a terminal, it asks `Set <NAME> now?` right after adding and, on yes, shows
|
|
102
|
+
the same hidden prompt (`secret set`'s own); No leaves it for `secret set`.
|
|
103
|
+
The README's other two ways work as for any `secret set` (a pipe into
|
|
104
|
+
`pnpm everyapp secret set <NAME> --json`, or the hidden read then
|
|
105
|
+
`--from-env <VAR>`); `mcp add <url> --auth bearer --from-env <VAR> --json`
|
|
106
|
+
takes the variable at the add itself, read before anything is written.
|
|
107
|
+
Wait for "done".
|
|
108
|
+
3. **Person:** who gets it. The owners, the admins and whoever added it have
|
|
109
|
+
it already. Anyone else: Admin → Apps → the app's row → **Manage access**.
|
|
110
|
+
A member sees its tools after granting, in a client connected to the
|
|
111
|
+
Gateway (the next step).
|
|
112
|
+
4. **Person:** connect an AI client to the Gateway if theirs isn't yet:
|
|
113
|
+
`claude mcp add --transport http everyapp https://<gateway host>/mcp`,
|
|
114
|
+
then `/mcp` → **everyapp** → **Authenticate** in Claude Code (other clients:
|
|
115
|
+
the same URL; mcp.md beside this folder, "Connecting a person").
|
|
116
|
+
|
|
117
|
+
## Verify
|
|
118
|
+
|
|
119
|
+
1. `pnpm everyapp mcp show <id> --json`: `data.status` is `"on"` (not
|
|
120
|
+
`"needs setup"`), `data.key.set` and `data.key.bound` are true and
|
|
121
|
+
`data.key.boundOrigin` is the URL's origin (all three skipped for
|
|
122
|
+
`--auth none`: `data.key` is null). `data.snapshot` is null until the
|
|
123
|
+
Gateway lists the tools, on the first request to its `/mcp` after the add
|
|
124
|
+
(or within the hour). From the checkout root,
|
|
125
|
+
`pnpm everyapp secret list --json` agrees: the name is in
|
|
126
|
+
`data.gateway.names`, its `data.gateway.mcpCredentials` entry has
|
|
127
|
+
`set: true`, and the app has left `data.apps` (it is listed there only
|
|
128
|
+
while it needs setup, with `setup.command` the `secret set` that sets it
|
|
129
|
+
up).
|
|
130
|
+
2. One tool call through the Gateway: in the person's connected client, ask
|
|
131
|
+
for something the server does ("use <id> to …", or "list the tools <id>
|
|
132
|
+
offers"); the client shows a call to an `<id>_<tool>` tool and its
|
|
133
|
+
answer. On a Gateway with many tools the client may list them compactly:
|
|
134
|
+
then it finds them with `everyapp_search_tools` (`{ "app": "<id>" }`) and
|
|
135
|
+
runs one through `everyapp_call_read`. Then
|
|
136
|
+
`pnpm everyapp mcp show <id> --json` again: `data.snapshot.tools` is the
|
|
137
|
+
count listed and `data.tools[]` has each with its `name`, `serverName`,
|
|
138
|
+
`risk` and `source` (`hint`: the server's annotation; `default`: no
|
|
139
|
+
annotation, counted as a write; `app`: the `--risk` default;
|
|
140
|
+
`override`: yours).
|
|
141
|
+
3. Risks, with the person: a tool the server marks read-only is callable by
|
|
142
|
+
every connection; one without a hint is a write (hidden from read-only
|
|
143
|
+
connections); one marked destructive is hidden from every client until
|
|
144
|
+
approvals exist. Change one with
|
|
145
|
+
`pnpm everyapp mcp tool <id> <tool> --risk read|write|destructive --json`
|
|
146
|
+
(`--risk annotations` drops the override), or leave a tool out entirely
|
|
147
|
+
with `--off`; the Gateway lists the tools again on first use.
|
|
148
|
+
4. Logs, when a call fails: README's path (**Workers & Pages** →
|
|
149
|
+
`every-app-gateway` → **Observability** → **Live**). The remote proxy logs
|
|
150
|
+
each failed upstream call as `mcp.remote.upstream_failed` with the status
|
|
151
|
+
(never the credential), and a first-use pin as
|
|
152
|
+
`mcp.remote.credential_bound` (names from the design,
|
|
153
|
+
docs/design/2026-10-mcp-by-url.md; not checked against a live Gateway
|
|
154
|
+
here, unverified).
|
|
155
|
+
|
|
156
|
+
## If it fails
|
|
157
|
+
|
|
158
|
+
| error or symptom | meaning | what to do |
|
|
159
|
+
| ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
160
|
+
| `SECRET_VALUE_REQUIRED` from `secret set --json` | Nothing was piped and there is no terminal to prompt in | One of the README's three ways: the person's own terminal, a pipe, or `--from-env` |
|
|
161
|
+
| `SECRET_EMPTY` | The `--from-env` variable is empty or not exported in that shell (from `mcp add --from-env`, nothing was added) | The hidden read (README's third way) in that same terminal first, then rerun |
|
|
162
|
+
| `REMOTE_MCP_URL_REFUSED` | Not `https://`, an IP address, the Gateway's own host or app domain, or a provider the Gateway holds a key for | The server's own MCP address, by host name, over https |
|
|
163
|
+
| `REMOTE_MCP_EXISTS` | That id is an MCP app already | `pnpm everyapp mcp show <id>`; another address is `mcp remove <id>` then `mcp add` again, or another `--name` |
|
|
164
|
+
| `REMOTE_MCP_SECRET_TAKEN` | Another MCP app at another origin uses that credential name | `--secret <OTHER>_MCP_TOKEN`: one credential name per origin |
|
|
165
|
+
| `REMOTE_MCP_INVALID` | A bad id, risk, header or credential name, or flags that say two things | As the message says |
|
|
166
|
+
| `PROVIDER_APP_UNKNOWN` | The id isn't an MCP app here | `pnpm everyapp mcp list` for the ids |
|
|
167
|
+
| `REMOTE_MCP_SECRET_BOUND_ELSEWHERE` from `mcp add`, or `needs setup` in `mcp list` or `mcp show` with the key set | The credential is pinned to another origin (`data.key.boundOrigin`): it was set for an earlier server | `pnpm everyapp secret set <NAME>` again (Steps 2) |
|
|
168
|
+
| `REMOTE_MCP_TOOL_NOT_LISTED` from `mcp tool` | The tool's name isn't in the last listing: the override was kept under that name, as the server's | `pnpm everyapp mcp show <id>` for both names, then `mcp tool` with the right one |
|
|
169
|
+
| `REMOTE_MCP_SECRET_UNDECLARED` from `secret set` | No MCP app declares that name (a typo, or set before `mcp add`) | Check the name with `mcp show <id>`; `mcp add` first |
|
|
170
|
+
| `REMOTE_MCP_WANTS_OAUTH` | The server wants OAuth, which the Gateway doesn't do yet | If it also takes an API key: `--auth bearer` and set the key; otherwise it can't be served this week |
|
|
171
|
+
| `REMOTE_MCP_GATEWAY_OUTDATED` | The Gateway predates MCP apps by URL | `pnpm everyapp update`, then Verify |
|
|
172
|
+
| `data.snapshot.status` `error`, `lastError` naming 401 | The server rejected the credential | A fresh key from the provider, `secret set` again, then `pnpm everyapp mcp refresh <id>` |
|
|
173
|
+
| `lastError` naming a redirect or a timeout | The address redirects, or the server is slow or down | The address it redirects to (remove, add again); a slow server: retry later |
|
|
174
|
+
| The tools changed on the server, not on the Gateway | The Gateway's snapshot is up to an hour old | `pnpm everyapp mcp refresh <id>` |
|
|
175
|
+
| A tool is missing for one person only | Their connection is read-only (write tools hidden), or they weren't granted the app | Admin → Apps → Manage access; a read & write connection |
|
|
176
|
+
|
|
177
|
+
## Rerun, rotate, remove
|
|
178
|
+
|
|
179
|
+
- **Rerun.** `mcp add` refuses an id that exists (`REMOTE_MCP_EXISTS`), so a
|
|
180
|
+
rerun starts from Verify. `secret set` replaces; `mcp tool` and
|
|
181
|
+
`mcp refresh` can run again.
|
|
182
|
+
- **Rotate.** A new key on the provider's dashboard, then Steps 2 again: the
|
|
183
|
+
Gateway uses the new value on its next request. A value that went through
|
|
184
|
+
the chat is compromised: rotate it.
|
|
185
|
+
- **Off, and back on.** `pnpm everyapp mcp off <id> --json` stops serving it
|
|
186
|
+
and keeps everyone's access, tokens and the snapshot;
|
|
187
|
+
`pnpm everyapp mcp on <id> --json` serves it again at once.
|
|
188
|
+
- **Remove.** `pnpm everyapp mcp remove <id> --json`: a tombstone, with
|
|
189
|
+
everyone's access, its tokens and its place in AI connections gone (adding
|
|
190
|
+
it again starts fresh). The credential and its pin stay;
|
|
191
|
+
`pnpm everyapp secret unset <NAME> --json` removes both (it asks; with
|
|
192
|
+
`--json` add `--yes` only once the person said so). Then revoke the key on
|
|
193
|
+
the provider's side.
|
|
194
|
+
|
|
195
|
+
## Sources
|
|
196
|
+
|
|
197
|
+
- docs/design/2026-10-mcp-by-url.md (the remote block, the credential family and its pin, the proxy, the defaults taken)
|
|
198
|
+
- In code: `packages/sdk/src/internal/remoteMcp.ts` (the URL, id, auth and risk rules: `remoteMcpUrlProblem`, `remoteMcpIdFromUrl`, `remoteToolRisk`), `packages/sdk/src/internal/gatewaySettings.ts` (`isRemoteMcpSecretName`: any name ending in `_MCP_TOKEN` is the Gateway's), `packages/sdk/src/internal/appSettings.ts` (the `remote-mcp` setting kind naming this file), `packages/perimeter/src/registry/remoteMcpApps.ts` (`planRemoteMcpAppAdd` and its refusals), `packages/cli/src/commands/provider/index.ts` (`mcp add`, `show`, `tool`, the probe's warnings), `packages/cli/src/lib/gateway/remoteMcpApps.ts` (the rows, the pin in `remote_mcp_credentials`), `packages/cli/src/commands/secret/index.ts` (the pin on `secret set`, dropped on `secret unset`), `apps/every-app-gateway/src/db/remote-mcp.schema.ts` (migration 0011)
|
|
199
|
+
- https://modelcontextprotocol.io/specification (Streamable HTTP transport, tool annotations `readOnlyHint` and `destructiveHint`, authorization with `resource_metadata`)
|