@tempo-ai/mcp 0.0.104 → 0.0.105-staging.2

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 CHANGED
@@ -1,13 +1,34 @@
1
- # @tempo-ai/mcp
1
+ # Tempo MCP
2
2
 
3
- Tempo's MCP server for external hosts Claude Code, Codex CLI, Cursor, and
4
- any other MCP-compatible client. ONE server entry exposes Tempo's full tool
5
- surface: issues, cloud docs, canvas comments, custom agents, run scripts,
6
- Slack (as the org's Tempo bot), Linear, and — when run inside a Tempo repo —
7
- the canvas tools, including headless `canvas_screenshot` and `canvas_share`
8
- with real preview capture.
3
+ Tempo ships **two** MCP surfaces. They expose the same underlying tools
4
+ pick by where your AI runs.
9
5
 
10
- ## Install
6
+ ## Which one do I install?
7
+
8
+ | Where your AI runs | Install this | What you get |
9
+ | --- | --- | --- |
10
+ | **A coding agent on your machine** — Claude Code, Codex CLI, Cursor, any stdio MCP host | **`@tempo-ai/mcp` (npm, local)** — see [Local package](#local-package-tempo-aimcp) | The FULL suite: issues, docs, comments, agents, scripts, Slack, Linear — reads **and writes** — plus canvas/design tools (screenshots, share links) when run inside a Tempo repo |
11
+ | **A chat app in the browser or on mobile** — ChatGPT, claude.ai, Claude mobile, or any client that takes a remote MCP URL | **`https://mcp.tempo.new/mcp` (hosted)** — see [Hosted server](#hosted-server-mcptempobuild) | The DB-backed toolsets, reads **and writes**: issues, docs, comments, agents, scripts, Slack, Linear. No canvas/design tools (no filesystem there) |
12
+
13
+ Rules of thumb:
14
+
15
+ - If the client can run `npx`, use the **local package** — it's the full
16
+ experience.
17
+ - If all you can give the client is a URL, use the **hosted server**.
18
+ - Never configure both in one client; the hosted tools are a subset of the
19
+ local ones.
20
+
21
+ ---
22
+
23
+ ## Local package (`@tempo-ai/mcp`)
24
+
25
+ One server entry exposes Tempo's full tool surface: issues, cloud docs,
26
+ canvas comments, custom agents, run scripts, Slack (as the org's Tempo
27
+ bot), Linear, and — when run inside a Tempo repo — the canvas tools,
28
+ including headless `canvas_screenshot` and `canvas_share` with real
29
+ preview capture.
30
+
31
+ ### Install
11
32
 
12
33
  Claude Code:
13
34
 
@@ -35,21 +56,12 @@ Sign in once (or let the first tool call prompt you):
35
56
  npx @tempo-ai/mcp login
36
57
  ```
37
58
 
38
- ## Scoping model
39
-
40
- Identity comes from your sign-in; SCOPE is explicit on every call. Each
41
- issues/docs/comments/agents/scripts/slack/linear tool requires an `orgId`
42
- argument, and project-scoped tools require `projectId` — the AI discovers
43
- both with the built-in `tempo_list_orgs` / `tempo_list_projects` tools.
44
- Nothing org-related is ever baked into the connection config, and Tempo's
45
- backend re-validates org membership on every function call regardless.
46
-
47
- ## Flags
59
+ ### Flags
48
60
 
49
61
  - `--toolsets issues,docs,canvas` — serve only the named toolsets
50
62
  - `--readonly` — register no write tools at all (also `TEMPO_MCP_READONLY=1`)
51
63
 
52
- ## Canvas visuals
64
+ ### Canvas visuals
53
65
 
54
66
  `canvas_screenshot` / `canvas_share` spawn a disposable canvas devserver and
55
67
  capture with headless Chromium (the same pipeline Tempo's visual-review CI
@@ -60,3 +72,71 @@ npx playwright install chromium
60
72
  ```
61
73
 
62
74
  Share links require the canvas's branch to be committed and pushed.
75
+
76
+ ---
77
+
78
+ ## Hosted server (`mcp.tempo.new`)
79
+
80
+ A remote MCP server (streamable HTTP + OAuth 2.1). You paste one URL, the
81
+ client walks you through a Clerk sign-in consent, and every call runs as
82
+ your Tempo account — reads and writes, with org membership re-validated
83
+ server-side on every call. Only connect clients you trust: an authorized
84
+ connector acts as you. Add `?readonly=1` to the URL for a connection that
85
+ can never write.
86
+
87
+ The URL for every client:
88
+
89
+ ```
90
+ https://mcp.tempo.new/mcp
91
+ ```
92
+
93
+ ### ChatGPT (web)
94
+
95
+ 1. Enable connector development: Settings → **Apps & Connectors** →
96
+ **Advanced settings** → enable **Developer mode**.
97
+ 2. Settings → Apps & Connectors → **Create** (custom connector) → paste
98
+ `https://mcp.tempo.new/mcp`, authentication **OAuth**.
99
+ 3. Approve the Tempo sign-in consent when prompted.
100
+ 4. In a chat, enable the connector under **Plus → More → Developer mode**.
101
+
102
+ Note: without Developer mode, ChatGPT connectors only run search-style
103
+ deep-research tools; Developer mode unlocks full tool calling.
104
+
105
+ ### claude.ai (web) and Claude mobile
106
+
107
+ 1. Settings → **Connectors** → **Add custom connector**.
108
+ 2. Paste `https://mcp.tempo.new/mcp`, then complete the OAuth consent.
109
+
110
+ ### Claude Code / Cursor (remote instead of local)
111
+
112
+ Prefer the local package (more tools). But the hosted URL also works:
113
+
114
+ ```bash
115
+ claude mcp add --transport http tempo-hosted https://mcp.tempo.new/mcp
116
+ ```
117
+
118
+ ### Connection options
119
+
120
+ - `?toolsets=issues,docs` — serve only the named toolsets (valid:
121
+ issues, docs, comments, agents, scripts, slack, linear)
122
+ - `?readonly=1` — strict opt-down: write tools are never registered on
123
+ this connection, whatever else is configured
124
+
125
+ ### Scoping model (both surfaces)
126
+
127
+ Identity comes from your sign-in; SCOPE is explicit on every call. Each
128
+ tool requires an `orgId` argument (and `projectId` where project-scoped) —
129
+ the AI discovers both with the built-in `tempo_list_orgs` /
130
+ `tempo_list_projects` tools. Nothing org-related is ever baked into the
131
+ connection config, and Tempo's backend re-validates org membership on
132
+ every function call regardless.
133
+
134
+ ### Hosted architecture (maintainers)
135
+
136
+ The endpoint lives in the `web-auth` Vercel deployable
137
+ (`tempo-client/web-auth/api/mcp.ts` + rewrites) and instantiates the same
138
+ factory modules as this package via `@tempo-modules/mcp-hosted`: Clerk
139
+ OAuth token verified per request → 60s ES256 service JWT minted for
140
+ Convex (additive `customJwt` provider in `auth.config.ts`) → stateless
141
+ streamable HTTP, fresh server instance per POST. Ops runbook:
142
+ `tempo-client/web-auth/CLAUDE.md` → "Hosted MCP".
package/dist/bin.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __tempoCreateRequire } from 'node:module'; const require = __tempoCreateRequire(import.meta.url);
3
3
  import {
4
4
  run
5
- } from "./chunk-2MN4FILH.js";
5
+ } from "./chunk-TK5FCMCH.js";
6
6
  import "./chunk-KFUOQZBJ.js";
7
7
 
8
8
  // src/bin.ts
@@ -8,7 +8,7 @@ import {
8
8
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
9
9
  import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
10
10
  async function connectAggregate(options) {
11
- const { createTempoAggregate } = await import("./serve-FWQ5ZBR7.js");
11
+ const { createTempoAggregate } = await import("./serve-AGHNN3WQ.js");
12
12
  const handle = await createTempoAggregate(options);
13
13
  const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
14
14
  const client = new Client({ name: "tempo-mcp-cli", version: "0" });
@@ -127,4 +127,4 @@ export {
127
127
  runCall,
128
128
  runTools
129
129
  };
130
- //# sourceMappingURL=call-5BVCQ6WY.js.map
130
+ //# sourceMappingURL=call-O6MXQFN2.js.map
@@ -157,7 +157,7 @@ async function run(argv) {
157
157
  process.stderr.write(USAGE);
158
158
  return 1;
159
159
  }
160
- const { runServe } = await import("./serve-FWQ5ZBR7.js");
160
+ const { runServe } = await import("./serve-AGHNN3WQ.js");
161
161
  return await runServe(options);
162
162
  }
163
163
  switch (subcommand) {
@@ -172,11 +172,11 @@ async function run(argv) {
172
172
  return await runToken(rest);
173
173
  }
174
174
  case "tools": {
175
- const { runTools } = await import("./call-5BVCQ6WY.js");
175
+ const { runTools } = await import("./call-O6MXQFN2.js");
176
176
  return await runTools(rest);
177
177
  }
178
178
  case "call": {
179
- const { runCall } = await import("./call-5BVCQ6WY.js");
179
+ const { runCall } = await import("./call-O6MXQFN2.js");
180
180
  return await runCall(rest);
181
181
  }
182
182
  default:
@@ -195,4 +195,4 @@ async function run(argv) {
195
195
  export {
196
196
  run
197
197
  };
198
- //# sourceMappingURL=chunk-2MN4FILH.js.map
198
+ //# sourceMappingURL=chunk-TK5FCMCH.js.map
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __tempoCreateRequire } from 'node:module'; const require = __tempoCreateRequire(import.meta.url);
2
2
  import {
3
3
  run
4
- } from "./chunk-2MN4FILH.js";
4
+ } from "./chunk-TK5FCMCH.js";
5
5
  import "./chunk-KFUOQZBJ.js";
6
6
  export {
7
7
  run