@llamaventures/cli 1.2.2 → 1.2.4
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/AGENT_BRIEFING.md +3 -2
- package/README.md +293 -180
- package/README.zh-CN.md +392 -0
- package/bin/llama-mcp.mjs +5 -34
- package/bin/llama.mjs +52 -4
- package/lib/external.mjs +13 -0
- package/package.json +11 -3
package/AGENT_BRIEFING.md
CHANGED
|
@@ -116,11 +116,11 @@ llama post <dealId> "message"
|
|
|
116
116
|
llama mentions
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
Run `llama --help` for the full
|
|
119
|
+
Run `llama --help` for the full surface (~40 commands).
|
|
120
120
|
|
|
121
121
|
## MCP-native agents
|
|
122
122
|
|
|
123
|
-
If you support [MCP](https://modelcontextprotocol.io), **prefer the MCP server over parsing CLI output.** The same package ships `llama-mcp` (
|
|
123
|
+
If you support [MCP](https://modelcontextprotocol.io), **prefer the MCP server over parsing CLI output.** The same package ships `llama-mcp` (20 typed tools, identical auth chain).
|
|
124
124
|
|
|
125
125
|
Add to your MCP client config (Claude Desktop / Claude Code / Cursor / OpenClaw / Codex / etc.):
|
|
126
126
|
|
|
@@ -136,6 +136,7 @@ Tools available:
|
|
|
136
136
|
- `wiki_search` / `wiki_save`
|
|
137
137
|
- `timeline` / `post`
|
|
138
138
|
- `mentions_list`
|
|
139
|
+
- `pitch_start` / `pitch_send_message` / `pitch_upload_file` / `pitch_status` / `pitch_finalize` — public intake (no Llama token needed; for founders / EAs / external agents)
|
|
139
140
|
- `llama_api` — escape hatch for any endpoint not yet wrapped (path must start `/api/`)
|
|
140
141
|
|
|
141
142
|
You can also fetch this exact briefing as an MCP prompt named `agent_briefing`.
|
package/README.md
CHANGED
|
@@ -1,273 +1,386 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/llama-ventures-logo.svg" alt="Llama Ventures" width="280">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">@llamaventures/cli</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>The Llama Ventures CLI & MCP server.</strong><br/>
|
|
9
|
+
One <code>npm install</code>, one auth chain, two interfaces — humans and AI agents
|
|
10
|
+
talk to <a href="https://command.llamaventures.vc">command.llamaventures.vc</a>
|
|
11
|
+
through the same client.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://www.npmjs.com/package/@llamaventures/cli"><img alt="npm" src="https://img.shields.io/npm/v/@llamaventures/cli?label=npm&color=cb3837&logo=npm&logoColor=white"></a>
|
|
16
|
+
<a href="https://github.com/SoujiOkita98/llama-cli/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/SoujiOkita98/llama-cli/actions/workflows/ci.yml/badge.svg"></a>
|
|
17
|
+
<a href="https://docs.npmjs.com/trusted-publishers"><img alt="Provenance" src="https://img.shields.io/badge/provenance-signed-2e8b57?logo=npm"></a>
|
|
18
|
+
<a href="https://nodejs.org/"><img alt="Node" src="https://img.shields.io/node/v/@llamaventures/cli?color=339933&logo=nodedotjs&logoColor=white"></a>
|
|
19
|
+
<a href="https://modelcontextprotocol.io"><img alt="MCP 2024-11-05" src="https://img.shields.io/badge/MCP-2024--11--05-7d3aed"></a>
|
|
20
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<strong>English</strong> · <a href="README.zh-CN.md">简体中文</a>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<a href="#install">Install</a> ·
|
|
29
|
+
<a href="#authenticate">Authenticate</a> ·
|
|
30
|
+
<a href="#cli-tour">CLI</a> ·
|
|
31
|
+
<a href="#mcp-server">MCP</a> ·
|
|
32
|
+
<a href="#external-pitch-no-llama-account-required">External pitch</a> ·
|
|
33
|
+
<a href="AGENT_BRIEFING.md">Agent briefing</a> ·
|
|
34
|
+
<a href="SECURITY.md">Security</a> ·
|
|
35
|
+
<a href="CHANGELOG.md">Changelog</a>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
> **Public source for low-friction install. Not an open-source product.**
|
|
39
|
+
> Most operations require a Llama Ventures team account
|
|
40
|
+
> ([gavin@llamaventures.vc](mailto:gavin@llamaventures.vc) mints tokens). The one
|
|
41
|
+
> exception is the **public `pitch`** family — see
|
|
42
|
+
> [External pitch](#external-pitch-no-llama-account-required).
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What's in the box
|
|
2
47
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
> [Authenticate](#authenticate).
|
|
48
|
+
```
|
|
49
|
+
@llamaventures/cli
|
|
50
|
+
├── bin/llama interactive CLI for humans + bash
|
|
51
|
+
└── bin/llama-mcp stdio MCP server, 20 tools — for any MCP-native agent
|
|
52
|
+
```
|
|
9
53
|
|
|
10
|
-
|
|
54
|
+
Both binaries share `lib/client.mjs` — the **same** auth chain, **same** HTTP
|
|
55
|
+
client, **same** error format. CLI and MCP can never drift on transport or
|
|
56
|
+
identity. Zero runtime dependencies for the CLI itself; the bundled MCP
|
|
57
|
+
server depends only on `@modelcontextprotocol/sdk` (Anthropic-maintained,
|
|
58
|
+
pinned exact).
|
|
59
|
+
|
|
60
|
+
```mermaid
|
|
61
|
+
flowchart LR
|
|
62
|
+
Human([🧑💻 Human]) --> CLI[bin/llama<br/>argv parser]
|
|
63
|
+
Agent([🤖 MCP-native agent]) --> MCP[bin/llama-mcp<br/>stdio JSON-RPC]
|
|
64
|
+
CLI --> Client[lib/client.mjs<br/>auth · fetch · errors]
|
|
65
|
+
MCP --> Client
|
|
66
|
+
Client -- HTTPS --> API[(command.llamaventures.vc)]
|
|
67
|
+
classDef src fill:#dcfce7,stroke:#166534,color:#14532d
|
|
68
|
+
classDef edge fill:#dbeafe,stroke:#1e40af,color:#1e3a8a
|
|
69
|
+
class Human,Agent edge
|
|
70
|
+
class CLI,MCP,Client src
|
|
71
|
+
```
|
|
11
72
|
|
|
12
|
-
|
|
73
|
+
---
|
|
13
74
|
|
|
14
|
-
|
|
75
|
+
## Install
|
|
15
76
|
|
|
16
|
-
|
|
17
|
-
|
|
77
|
+
```bash
|
|
78
|
+
npm i -g @llamaventures/cli
|
|
79
|
+
```
|
|
18
80
|
|
|
19
|
-
|
|
81
|
+
Requires **Node 18+** (uses native `fetch` and ESM). CI runs the matrix on 18 / 20 / 22.
|
|
20
82
|
|
|
21
|
-
|
|
83
|
+
Verify:
|
|
22
84
|
|
|
23
85
|
```bash
|
|
24
|
-
|
|
86
|
+
llama --version
|
|
87
|
+
llama auth status # round-trips against /api/me
|
|
25
88
|
```
|
|
26
89
|
|
|
27
|
-
|
|
90
|
+
The same install puts `llama-mcp` on your `PATH` for the MCP server — no second package.
|
|
91
|
+
|
|
92
|
+
> **Upgrading from `npm link`?** The CLI used to live in the `llama-os/cli/`
|
|
93
|
+
> directory and was distributed via `npm link`. As of CLI v1.x it ships as
|
|
94
|
+
> `@llamaventures/cli`. Run `npm i -g @llamaventures/cli@latest`; the legacy
|
|
95
|
+
> directory keeps working during the soak window but is no longer the source
|
|
96
|
+
> of truth. See [`llama-os/cli/DEPRECATED.md`](https://github.com/SoujiOkita98/llama-os/blob/main/cli/DEPRECATED.md).
|
|
97
|
+
|
|
98
|
+
---
|
|
28
99
|
|
|
29
100
|
## Authenticate
|
|
30
101
|
|
|
31
|
-
The
|
|
102
|
+
The client tries credentials **in this order**, on every call:
|
|
32
103
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
104
|
+
| # | Source | Header sent | Best for |
|
|
105
|
+
|---|--------|-------------|----------|
|
|
106
|
+
| 1 | `gcloud auth print-identity-token` | `Authorization: Bearer …` | Team members on a workstation (zero config) |
|
|
107
|
+
| 2 | `$LLAMA_TOKEN` env var | `X-Llama-Token` | CI runners, sandboxed cloud agents |
|
|
108
|
+
| 3 | `~/.llama/token` (mode `0600`) | `X-Llama-Token` | Persistent local install |
|
|
109
|
+
| 4 | `~/.llama-command/config.json` | `X-Llama-Token` | Legacy CLI v0.1 — auto-migrates to `~/.llama/token` on first read |
|
|
37
110
|
|
|
38
|
-
|
|
111
|
+
Both Bearer and X-Llama-Token are sent if both exist. The server tries Bearer
|
|
112
|
+
first; on verification failure it falls through to X-Llama-Token. Inspect the
|
|
113
|
+
resolved identity any time with `llama auth status`.
|
|
39
114
|
|
|
40
|
-
### Zero-config
|
|
115
|
+
### Zero-config — recommended for team members
|
|
41
116
|
|
|
42
117
|
```bash
|
|
43
|
-
gcloud auth login # one-time
|
|
44
|
-
llama auth status #
|
|
45
|
-
llama deal search acme-ai # ready
|
|
118
|
+
gcloud auth login # one-time; pick your @llamaventures.vc account
|
|
119
|
+
llama auth status # → role + email
|
|
120
|
+
llama deal search acme-ai # ready
|
|
46
121
|
```
|
|
47
122
|
|
|
48
|
-
### Manual token
|
|
123
|
+
### Manual token — for machines without `gcloud`, or stable CI
|
|
49
124
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
2. Visit `/settings/tokens` → click **Mint Token**
|
|
54
|
-
3. Save the `llc_…` value to `~/.llama/token`:
|
|
125
|
+
1. Sign in to https://command.llamaventures.vc.
|
|
126
|
+
2. Open `/settings/tokens` → **Mint Token**.
|
|
127
|
+
3. Save the `llc_…` value:
|
|
55
128
|
|
|
56
129
|
```bash
|
|
57
130
|
llama token set llc_paste_token_here
|
|
58
|
-
# writes ~/.llama/token (mode 0600)
|
|
131
|
+
# → writes ~/.llama/token (mode 0600)
|
|
132
|
+
# → round-trips /api/me before saving — bad token never lands on disk
|
|
59
133
|
```
|
|
60
134
|
|
|
61
|
-
Or
|
|
135
|
+
Or, in CI / one-shot environments:
|
|
62
136
|
|
|
63
137
|
```bash
|
|
64
138
|
export LLAMA_TOKEN=llc_paste_token_here
|
|
65
139
|
```
|
|
66
140
|
|
|
67
|
-
|
|
68
|
-
[gavin@llamaventures.vc](mailto:gavin@llamaventures.vc)
|
|
141
|
+
> **Don't have an account?** Email
|
|
142
|
+
> [gavin@llamaventures.vc](mailto:gavin@llamaventures.vc). Any email — including
|
|
143
|
+
> non-`@llamaventures.vc` — can be granted a token; the system admin
|
|
144
|
+
> mints it via `/settings/tokens`. Token first-use auto-creates the user row.
|
|
69
145
|
|
|
70
|
-
|
|
146
|
+
---
|
|
71
147
|
|
|
72
|
-
|
|
73
|
-
EA, a prospective hire, or just exploring — the CLI ships a separate
|
|
74
|
-
`pitch` command family that talks to our public intake agent at
|
|
75
|
-
[command.llamaventures.vc/external-agent](https://command.llamaventures.vc/external-agent).
|
|
76
|
-
Same conversation, structured intake, same 12-dimension verdict as the web
|
|
77
|
-
flow — but driven from your terminal (or your AI agent over MCP).
|
|
148
|
+
## CLI tour
|
|
78
149
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# Send a message (single-shot, prints reply)
|
|
84
|
-
llama pitch say "We're building an AI dev tool for X..."
|
|
85
|
-
|
|
86
|
-
# Attach your deck / one-pager
|
|
87
|
-
llama pitch upload ./deck.pdf
|
|
88
|
-
|
|
89
|
-
# Or open an interactive REPL
|
|
90
|
-
llama pitch
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Caps (server-enforced — same as the web flow): 5 sessions/IP/day,
|
|
94
|
-
3 sessions/email/day, 30min idle timeout, 100 messages/session,
|
|
95
|
-
1M tokens/session.
|
|
96
|
-
|
|
97
|
-
The MCP server exposes the same surface as `pitch_*` tools
|
|
98
|
-
(`pitch_start`, `pitch_send_message`, `pitch_upload_file`, `pitch_status`,
|
|
99
|
-
`pitch_finalize`) — so the founder's own AI agent (Claude / Cursor /
|
|
100
|
-
OpenClaw / etc.) can help them pitch via Llama's intake agent. True A2A.
|
|
101
|
-
|
|
102
|
-
## CLI command reference
|
|
150
|
+
The CLI is the canonical interface. The HTTP API beneath it is stable, but the
|
|
151
|
+
CLI handles auth, error formatting, and forward-compatibility across server
|
|
152
|
+
schema changes — **prefer the CLI even from inside scripts.**
|
|
103
153
|
|
|
104
154
|
```bash
|
|
105
|
-
# Auth
|
|
155
|
+
# Auth + tokens
|
|
106
156
|
llama auth status
|
|
107
|
-
|
|
108
|
-
# Token management
|
|
109
|
-
llama token set <llc_...> [--base https://command.llamaventures.vc]
|
|
157
|
+
llama token set <llc_...>
|
|
110
158
|
llama token show
|
|
111
159
|
|
|
112
|
-
#
|
|
113
|
-
llama deal search
|
|
114
|
-
llama deal list
|
|
160
|
+
# Pipeline — read
|
|
161
|
+
llama deal search "acme ai"
|
|
162
|
+
llama deal list --owner alex --status Diligence
|
|
115
163
|
llama deal show <dealId>
|
|
116
164
|
|
|
117
|
-
#
|
|
118
|
-
llama deal create "
|
|
119
|
-
llama deal update <dealId>
|
|
120
|
-
llama deal delete
|
|
165
|
+
# Pipeline — write
|
|
166
|
+
llama deal create "Acme AI" --description "..." --source Gavin
|
|
167
|
+
llama deal update <dealId> status Diligence
|
|
168
|
+
llama deal delete <dealId> # soft (audit-logged)
|
|
121
169
|
llama deal restore <dealId>
|
|
122
|
-
llama deal trash # list soft-deleted
|
|
123
170
|
|
|
124
|
-
#
|
|
125
|
-
llama
|
|
126
|
-
llama
|
|
127
|
-
llama
|
|
128
|
-
llama
|
|
129
|
-
llama
|
|
130
|
-
llama
|
|
171
|
+
# Deal Brief — ordered, typed blocks (text · link · embed · callout)
|
|
172
|
+
llama brief blocks <dealId>
|
|
173
|
+
llama brief add-text <dealId> --heading "..." --body "..."
|
|
174
|
+
llama brief add-link <dealId> --url "..." --label "..."
|
|
175
|
+
llama brief add-callout <dealId> --tone insight --heading "..." --body "..."
|
|
176
|
+
llama brief edit <dealId> <blockId> [--heading ...] [--body ...]
|
|
177
|
+
llama brief history <dealId> <blockId>
|
|
178
|
+
|
|
179
|
+
# Ownership + approvals
|
|
180
|
+
llama claim <dealId>
|
|
181
|
+
llama nominate <dealId> --user <userId>
|
|
182
|
+
llama approvals list
|
|
183
|
+
llama approvals decide <approvalId> approved --note "..."
|
|
131
184
|
|
|
132
185
|
# Timeline + posts
|
|
133
186
|
llama timeline <dealId>
|
|
134
|
-
llama post
|
|
135
|
-
|
|
136
|
-
#
|
|
137
|
-
llama
|
|
138
|
-
llama
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
llama
|
|
142
|
-
llama brief edit <dealId> <blockId> [--heading ...] [--body ...] [--url ...] [--label ...] [--tone ...]
|
|
143
|
-
llama brief delete <dealId> <blockId> # soft
|
|
144
|
-
llama brief restore <dealId> <blockId>
|
|
145
|
-
llama brief history <dealId> <blockId> [--limit 50]
|
|
146
|
-
llama brief restore-version <dealId> <blockId> <historyId>
|
|
147
|
-
|
|
148
|
-
# Collaborators
|
|
149
|
-
llama deal collab list <dealId>
|
|
150
|
-
llama deal collab add <dealId> --user <userId|email>
|
|
151
|
-
llama deal collab remove <dealId> --user <userId|email>
|
|
152
|
-
llama deal collab restore <dealId> --user <userId|email>
|
|
153
|
-
|
|
154
|
-
# Links (URLs attached to a deal — Netlify demos, Gamma decks, etc.)
|
|
155
|
-
llama deal link list <dealId> [--include-deleted]
|
|
156
|
-
llama deal link add <dealId> --url <url> [--label "..."]
|
|
157
|
-
llama deal link delete <dealId> <linkId>
|
|
158
|
-
llama deal link restore <dealId> <linkId>
|
|
159
|
-
|
|
160
|
-
# Brief / persona refresh
|
|
161
|
-
llama deal refresh-brief <dealId> [--force]
|
|
162
|
-
llama deal refresh-persona <dealId> <persona>
|
|
163
|
-
|
|
164
|
-
# Deal facts (AI / human-asserted, with verification)
|
|
165
|
-
llama deal fact list <dealId>
|
|
166
|
-
llama deal fact add <dealId> --category <cat> --claim "<text>" [--source <url>] [--confidence high|medium|low]
|
|
167
|
-
llama deal fact verify <dealId> <factId> --status confirmed|disputed [--corrected-value "..."]
|
|
168
|
-
|
|
169
|
-
# Mentions / inbox
|
|
170
|
-
llama mentions # my unresolved cues (default)
|
|
171
|
-
llama mentions list [--everyone] [--all]
|
|
172
|
-
llama mentions show <mentionId>
|
|
187
|
+
llama post <dealId> "message body" [--link url]
|
|
188
|
+
|
|
189
|
+
# Wiki
|
|
190
|
+
llama wiki search "<query>"
|
|
191
|
+
llama wiki save <slug> --title "..." --content "..."
|
|
192
|
+
|
|
193
|
+
# Mentions inbox
|
|
194
|
+
llama mentions
|
|
173
195
|
llama mentions resolve <mentionId>
|
|
174
|
-
llama mentions unread # badge count
|
|
175
|
-
|
|
176
|
-
# Skill corrections (persona-owner workflow)
|
|
177
|
-
llama skill-correction list <skill-slug> [--include-deleted]
|
|
178
|
-
llama skill-correction add <skill-slug> "<rule>" [--deal <uuid>] [--block <blockId>]
|
|
179
|
-
llama skill-correction delete <id>
|
|
180
|
-
|
|
181
|
-
# Wiki (knowledge base)
|
|
182
|
-
llama wiki search <query>
|
|
183
|
-
llama wiki read <slug>
|
|
184
|
-
llama wiki save <slug> --title "..." --content "..." [--sources "url1;url2"]
|
|
185
|
-
|
|
186
|
-
# Admin event feeds (system admin only)
|
|
187
|
-
llama admin auth-events [--kind X] [--actor email] [--since 24h] [--limit 100]
|
|
188
|
-
llama admin deal-events [--kind X] [--deal <uuid>] [--since 24h]
|
|
189
|
-
llama admin agent-events [--kind tool_call|loop_stalled] [--errors-only]
|
|
190
196
|
```
|
|
191
197
|
|
|
192
|
-
|
|
198
|
+
Run `llama --help` for the full surface (~40 commands across deals, briefs,
|
|
199
|
+
ownership, timeline, facts, wiki, mentions, skill corrections, and admin event
|
|
200
|
+
feeds). Soft-delete is the default everywhere — every removal is reversible
|
|
201
|
+
and audit-logged via `deal_events`.
|
|
202
|
+
|
|
203
|
+
### Error codes — for agents
|
|
204
|
+
|
|
205
|
+
The CLI's stderr exit messages start with stable, parseable prefixes:
|
|
193
206
|
|
|
194
|
-
|
|
207
|
+
| Prefix | Meaning | Recovery |
|
|
208
|
+
|--------|---------|----------|
|
|
209
|
+
| `Error[NO_AUTH]` | No credentials found anywhere | `gcloud auth login` **or** `llama token set` |
|
|
210
|
+
| `Error[UNAUTHORIZED]` | Server rejected the credentials we sent | Token may be revoked / expired / wrong gcloud account |
|
|
195
211
|
|
|
196
|
-
|
|
212
|
+
The MCP server returns the same prefixes inside `isError: true` content so
|
|
213
|
+
agents can pattern-match without parsing prose.
|
|
197
214
|
|
|
198
|
-
|
|
215
|
+
---
|
|
199
216
|
|
|
200
|
-
|
|
217
|
+
## MCP server
|
|
218
|
+
|
|
219
|
+
The bundled `llama-mcp` is a **stdio Model Context Protocol** server exposing
|
|
220
|
+
**19 typed tools** that mirror the most-used CLI surface. Every tool is named
|
|
221
|
+
and scoped — there is no generic API passthrough, by design (a public-package
|
|
222
|
+
escape hatch reachable from a prompt-injectable agent context is exactly the
|
|
223
|
+
shape we want to avoid).
|
|
201
224
|
|
|
202
225
|
```
|
|
203
|
-
auth_status
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
226
|
+
auth_status
|
|
227
|
+
|
|
228
|
+
deal_search deal_show
|
|
229
|
+
deal_create deal_update
|
|
230
|
+
|
|
231
|
+
brief_blocks brief_add_text
|
|
232
|
+
brief_add_link brief_add_callout
|
|
233
|
+
|
|
234
|
+
timeline post
|
|
235
|
+
|
|
236
|
+
wiki_search wiki_save
|
|
237
|
+
|
|
208
238
|
mentions_list
|
|
209
|
-
|
|
239
|
+
|
|
240
|
+
pitch_start pitch_send_message
|
|
241
|
+
pitch_upload_file pitch_status
|
|
242
|
+
pitch_finalize
|
|
210
243
|
```
|
|
211
244
|
|
|
212
|
-
|
|
245
|
+
Auth is identical to the CLI's chain (gcloud → `$LLAMA_TOKEN` → `~/.llama/token`).
|
|
246
|
+
The `agent_briefing` MCP **prompt** also returns
|
|
247
|
+
[`AGENT_BRIEFING.md`](AGENT_BRIEFING.md) verbatim, so any new agent loading the
|
|
248
|
+
server can self-onboard without leaving the protocol.
|
|
249
|
+
|
|
250
|
+
### Wire into your agent
|
|
213
251
|
|
|
214
|
-
|
|
252
|
+
<details open>
|
|
253
|
+
<summary><strong>Claude Desktop</strong> (macOS path shown — Linux/Windows differ)</summary>
|
|
215
254
|
|
|
216
|
-
|
|
217
|
-
`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
255
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
218
256
|
|
|
219
257
|
```json
|
|
220
258
|
{
|
|
221
259
|
"mcpServers": {
|
|
222
|
-
"llama": {
|
|
223
|
-
"command": "llama-mcp"
|
|
224
|
-
}
|
|
260
|
+
"llama": { "command": "llama-mcp" }
|
|
225
261
|
}
|
|
226
262
|
}
|
|
227
263
|
```
|
|
228
264
|
|
|
229
|
-
Restart Claude Desktop.
|
|
265
|
+
Restart Claude Desktop. Tools appear under the 🛠️ menu.
|
|
266
|
+
</details>
|
|
230
267
|
|
|
231
|
-
|
|
268
|
+
<details>
|
|
269
|
+
<summary><strong>Claude Code</strong></summary>
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
claude mcp add llama -- llama-mcp
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Or edit `~/.claude/claude.json` directly — same JSON shape as Desktop.
|
|
276
|
+
</details>
|
|
277
|
+
|
|
278
|
+
<details>
|
|
279
|
+
<summary><strong>Cursor</strong></summary>
|
|
232
280
|
|
|
233
281
|
`~/.cursor/mcp.json`:
|
|
234
282
|
|
|
235
283
|
```json
|
|
236
284
|
{
|
|
237
285
|
"mcpServers": {
|
|
238
|
-
"llama": {
|
|
239
|
-
"command": "llama-mcp"
|
|
240
|
-
}
|
|
286
|
+
"llama": { "command": "llama-mcp" }
|
|
241
287
|
}
|
|
242
288
|
}
|
|
243
289
|
```
|
|
290
|
+
</details>
|
|
291
|
+
|
|
292
|
+
<details>
|
|
293
|
+
<summary><strong>OpenCode / OpenClaw / Codex / arbitrary stdio MCP client</strong></summary>
|
|
294
|
+
|
|
295
|
+
Most clients accept a `command` + `args` pair. Locate the binary
|
|
296
|
+
(`which llama-mcp` → typically `/usr/local/bin/llama-mcp` or
|
|
297
|
+
`~/.npm-global/bin/llama-mcp`) and point the client at it. No protocol
|
|
298
|
+
extensions, no transport flags.
|
|
299
|
+
</details>
|
|
300
|
+
|
|
301
|
+
> If you're new and want the agent to onboard itself, run
|
|
302
|
+
> `llama agent-onboard` from the CLI or fetch the `agent_briefing` prompt from
|
|
303
|
+
> the MCP server. It's the workflow contract — autonomy levels, attribution
|
|
304
|
+
> grammar, error recovery, anti-pollution rules.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## External pitch — no Llama account required
|
|
309
|
+
|
|
310
|
+
If you're a **founder pitching us, an EA, or a prospective hire** without a
|
|
311
|
+
Llama Command token, the CLI ships a `pitch` command family (and the parallel
|
|
312
|
+
`pitch_*` MCP tools) that talks to our public intake agent at
|
|
313
|
+
[command.llamaventures.vc/external-agent](https://command.llamaventures.vc/external-agent).
|
|
314
|
+
Same conversation, same structured 12-dimension verdict — driven from your
|
|
315
|
+
terminal or your own AI agent.
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
llama pitch start --name "Jane Doe" --email "jane@acme.ai"
|
|
319
|
+
llama pitch say "We're building an AI dev tool for X..."
|
|
320
|
+
llama pitch upload ./deck.pdf
|
|
321
|
+
llama pitch # interactive REPL
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Server-enforced caps (same as the web flow): 5 sessions/IP/day,
|
|
325
|
+
3 sessions/email/day, 30 min idle timeout, 100 messages/session,
|
|
326
|
+
1 M tokens/session.
|
|
327
|
+
|
|
328
|
+
This is genuine **agent-to-agent**: your AI helps you tell the story, our
|
|
329
|
+
intake agent extracts the structured fields and produces the verdict.
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Stability
|
|
244
334
|
|
|
245
|
-
|
|
335
|
+
- **Versioning:** [SemVer](https://semver.org). Renaming or removing a CLI
|
|
336
|
+
command bumps **major**. Adding a tool, command, or flag bumps minor.
|
|
337
|
+
Bugfixes bump patch. The CLI prints `--version`; the MCP server reports
|
|
338
|
+
the same value in its `serverInfo`.
|
|
339
|
+
- **Backwards compatibility:** The wire format (Bearer / X-Llama-Token) and
|
|
340
|
+
the `Error[…]` prefixes are part of the public contract and won't change
|
|
341
|
+
inside a major version.
|
|
342
|
+
- **Server schema drift:** When the API gains an endpoint, the CLI / MCP gain
|
|
343
|
+
a typed wrapper in the next minor release. While you wait, the `llama` CLI
|
|
344
|
+
itself ships the full `llama` command surface (40+ commands) — use it for
|
|
345
|
+
ad-hoc HTTP work that the MCP doesn't yet wrap.
|
|
246
346
|
|
|
247
|
-
|
|
347
|
+
See [`CHANGELOG.md`](CHANGELOG.md) for the per-version log.
|
|
248
348
|
|
|
249
|
-
|
|
349
|
+
---
|
|
250
350
|
|
|
251
|
-
|
|
351
|
+
## Security
|
|
252
352
|
|
|
253
|
-
- `
|
|
254
|
-
|
|
353
|
+
- **`@llamaventures/cli` is published via npm
|
|
354
|
+
[Trusted Publishers](https://docs.npmjs.com/trusted-publishers)** — no
|
|
355
|
+
`NPM_TOKEN` lives in repo secrets. Each release ships with `--provenance`
|
|
356
|
+
(sigstore-signed); the npm registry shows a **Provenance** badge traceable
|
|
357
|
+
to the exact GitHub Action workflow + commit.
|
|
358
|
+
- **Minimal dependency tree.** The CLI is zero-deps. The MCP server depends
|
|
359
|
+
only on `@modelcontextprotocol/sdk`, pinned exact.
|
|
360
|
+
- **Branch protection** on `main`; Dependabot, secret scanning, and
|
|
361
|
+
push-protection are enabled.
|
|
362
|
+
- **Tokens:** stored locally at `~/.llama/token` mode `0600`. Server-side they
|
|
363
|
+
are stored as sha256 hashes — plaintext only ever exists in the user's
|
|
364
|
+
possession.
|
|
255
365
|
|
|
256
|
-
|
|
366
|
+
Reporting a vulnerability: see [`SECURITY.md`](SECURITY.md). **Do not** file
|
|
367
|
+
public GitHub issues for security bugs.
|
|
257
368
|
|
|
258
|
-
|
|
369
|
+
---
|
|
259
370
|
|
|
260
|
-
|
|
371
|
+
## Contributing
|
|
261
372
|
|
|
262
|
-
|
|
373
|
+
This is an internal tool maintained by Llama Ventures. PRs from team members
|
|
374
|
+
are welcome — see [`CONTRIBUTING.md`](CONTRIBUTING.md) for the local dev loop,
|
|
375
|
+
release flow (Trusted Publishers + GitHub Releases), and the conventions we
|
|
376
|
+
follow (zero-deps, lockstep CLI/MCP, stable `Error[…]` prefixes).
|
|
263
377
|
|
|
264
|
-
|
|
378
|
+
External contributions: feel free to open issues for documentation gaps or
|
|
379
|
+
broken flows. Feature requests for non-team workflows are best directed at
|
|
380
|
+
the [external pitch path](#external-pitch-no-llama-account-required) instead.
|
|
265
381
|
|
|
266
|
-
|
|
267
|
-
[gavin@llamaventures.vc](mailto:gavin@llamaventures.vc). See
|
|
268
|
-
[SECURITY.md](./SECURITY.md) for scope, response SLA, and the
|
|
269
|
-
supply-chain posture (Trusted Publishers + provenance + zero-deps CLI).
|
|
382
|
+
---
|
|
270
383
|
|
|
271
384
|
## License
|
|
272
385
|
|
|
273
|
-
[MIT](
|
|
386
|
+
[MIT](LICENSE) — © 2026 Llama Ventures, Inc.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/llama-ventures-logo.svg" alt="Llama Ventures" width="280">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">@llamaventures/cli</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Llama Ventures 官方 CLI 与 MCP server。</strong><br/>
|
|
9
|
+
一行 <code>npm install</code>,一套统一的认证链,两个接口——
|
|
10
|
+
团队成员和 AI agent 都通过同一份客户端访问
|
|
11
|
+
<a href="https://command.llamaventures.vc">command.llamaventures.vc</a>。
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://www.npmjs.com/package/@llamaventures/cli"><img alt="npm" src="https://img.shields.io/npm/v/@llamaventures/cli?label=npm&color=cb3837&logo=npm&logoColor=white"></a>
|
|
16
|
+
<a href="https://github.com/SoujiOkita98/llama-cli/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/SoujiOkita98/llama-cli/actions/workflows/ci.yml/badge.svg"></a>
|
|
17
|
+
<a href="https://docs.npmjs.com/trusted-publishers"><img alt="Provenance" src="https://img.shields.io/badge/provenance-signed-2e8b57?logo=npm"></a>
|
|
18
|
+
<a href="https://nodejs.org/"><img alt="Node" src="https://img.shields.io/node/v/@llamaventures/cli?color=339933&logo=nodedotjs&logoColor=white"></a>
|
|
19
|
+
<a href="https://modelcontextprotocol.io"><img alt="MCP 2024-11-05" src="https://img.shields.io/badge/MCP-2024--11--05-7d3aed"></a>
|
|
20
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
<p align="center">
|
|
24
|
+
<a href="README.md">English</a> · <strong>简体中文</strong>
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<a href="#给华人创业者-向-llama-pitch">🚀 向 Llama pitch(无需账号)</a> ·
|
|
29
|
+
<a href="#安装">安装</a> ·
|
|
30
|
+
<a href="#认证">认证</a> ·
|
|
31
|
+
<a href="#cli-速览">CLI</a> ·
|
|
32
|
+
<a href="#mcp-server">MCP</a> ·
|
|
33
|
+
<a href="AGENT_BRIEFING.md">Agent 协议</a> ·
|
|
34
|
+
<a href="SECURITY.md">安全</a> ·
|
|
35
|
+
<a href="CHANGELOG.md">更新日志</a>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
> **公开源码、低摩擦安装;不是开源产品。** 大多数命令需要 Llama Ventures
|
|
39
|
+
> 团队账号(联系 [gavin@llamaventures.vc](mailto:gavin@llamaventures.vc)
|
|
40
|
+
> 发 token)。**唯一例外是公开的 `pitch` 命令族**——任何创业者、EA、
|
|
41
|
+
> 行政助理都能用,不需要 token,详见下方
|
|
42
|
+
> [给华人创业者:向 Llama pitch](#给华人创业者-向-llama-pitch)。
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 包里有什么
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
@llamaventures/cli
|
|
50
|
+
├── bin/llama 给人 + bash 用的交互式 CLI
|
|
51
|
+
└── bin/llama-mcp 给 MCP 原生 agent 用的 stdio MCP server,20 个工具
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
两个 binary 共享 `lib/client.mjs`——**同一**认证链、**同一** HTTP 客户端、
|
|
55
|
+
**同一**错误格式。CLI 与 MCP 不可能在身份或传输上漂移。CLI 自身零依赖;
|
|
56
|
+
MCP server 仅依赖 `@modelcontextprotocol/sdk`(Anthropic 维护,pin 死版本)。
|
|
57
|
+
|
|
58
|
+
```mermaid
|
|
59
|
+
flowchart LR
|
|
60
|
+
Human([🧑💻 团队成员]) --> CLI[bin/llama<br/>argv 解析]
|
|
61
|
+
Agent([🤖 MCP 原生 agent]) --> MCP[bin/llama-mcp<br/>stdio JSON-RPC]
|
|
62
|
+
CLI --> Client[lib/client.mjs<br/>认证 · fetch · 错误]
|
|
63
|
+
MCP --> Client
|
|
64
|
+
Client -- HTTPS --> API[(command.llamaventures.vc)]
|
|
65
|
+
classDef src fill:#dcfce7,stroke:#166534,color:#14532d
|
|
66
|
+
classDef edge fill:#dbeafe,stroke:#1e40af,color:#1e3a8a
|
|
67
|
+
class Human,Agent edge
|
|
68
|
+
class CLI,MCP,Client src
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 给华人创业者:向 Llama pitch
|
|
74
|
+
|
|
75
|
+
如果你是创业者、EA、或者帮老板探索的助理,**不需要 token、不需要找认识的人介绍**——
|
|
76
|
+
我们专门为外部 pitch 留了一条公开通道。它跟你在
|
|
77
|
+
[command.llamaventures.vc/external-agent](https://command.llamaventures.vc/external-agent)
|
|
78
|
+
上看到的网页版聊的是同一个 intake agent,结构化提取、12 维投资判断都是同一套,
|
|
79
|
+
只是入口换成了你的终端,或者你自己的 AI 助手。
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# 1. 装 CLI(不需要 Llama 账号)
|
|
83
|
+
npm i -g @llamaventures/cli
|
|
84
|
+
|
|
85
|
+
# 2. 起一个 session
|
|
86
|
+
llama pitch start --name "张三" --email "you@yourstartup.com"
|
|
87
|
+
|
|
88
|
+
# 3. 跟 agent 聊——单条消息
|
|
89
|
+
llama pitch say "我们做 X,目标 Y,团队背景 Z..."
|
|
90
|
+
|
|
91
|
+
# 4. 把 deck / 一页纸传上来
|
|
92
|
+
llama pitch upload ./deck.pdf
|
|
93
|
+
|
|
94
|
+
# 5. 或者直接进交互式 REPL
|
|
95
|
+
llama pitch
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**也可以让你自己的 AI agent 帮你 pitch(A2A)。** 把这个仓库的 MCP server
|
|
99
|
+
挂到 Claude / Cursor / Codex / OpenClaw 上(任何能跑 MCP 的 agent 都行),
|
|
100
|
+
然后告诉它"帮我 pitch Llama Ventures"。它会用 `pitch_start`、
|
|
101
|
+
`pitch_send_message`、`pitch_upload_file`、`pitch_finalize` 这五个工具
|
|
102
|
+
跟我们的 intake agent 对话。配置见 [MCP server](#mcp-server)。
|
|
103
|
+
|
|
104
|
+
**会被服务端约束的上限**(跟网页版一样):
|
|
105
|
+
- 单 IP 每天 5 个 session
|
|
106
|
+
- 单邮箱每天 3 个 session
|
|
107
|
+
- 30 分钟无活动自动结束
|
|
108
|
+
- 单 session 100 条消息 / 1M token
|
|
109
|
+
|
|
110
|
+
**Pitch 完成后**:agent 会调 `finalize_intake` 写入结构化档案,自动给我们团队
|
|
111
|
+
排进 inbox。我们看到后会主动联系你——不需要你再追。
|
|
112
|
+
|
|
113
|
+
> 想了解 Llama Ventures 在投什么?看 [llamaventures.vc](https://llamaventures.vc)。
|
|
114
|
+
> AI、Pre-seed 到 Series A、$3-5M 票,跨美中。**懂得用 AI 写代码、懂得让 AI
|
|
115
|
+
> 帮你 pitch 的 founder——我们爱看。**
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 安装
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npm i -g @llamaventures/cli
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
需要 **Node 18+**(用了原生 `fetch` 与 ESM)。CI 矩阵覆盖 18 / 20 / 22。
|
|
126
|
+
|
|
127
|
+
验证:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
llama --version
|
|
131
|
+
llama auth status # 会跑一次 /api/me 验证
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
同一次安装会把 `llama-mcp` 也放到 `PATH` 上——MCP server 不用单独装包。
|
|
135
|
+
|
|
136
|
+
> **从 `npm link` 升级过来?** CLI 以前住在 `llama-os/cli/` 目录,靠 `npm link`
|
|
137
|
+
> 分发。从 v1.x 起改名 `@llamaventures/cli` 走 npm。
|
|
138
|
+
> 跑一次 `npm i -g @llamaventures/cli@latest` 就完事;旧目录在 soak 期间
|
|
139
|
+
> 还能用,但已经不是 source of truth。详见
|
|
140
|
+
> [`llama-os/cli/DEPRECATED.md`](https://github.com/SoujiOkita98/llama-os/blob/main/cli/DEPRECATED.md)。
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 认证
|
|
145
|
+
|
|
146
|
+
客户端**按下面这个顺序**寻找凭证,每次调用都查一遍:
|
|
147
|
+
|
|
148
|
+
| # | 来源 | 发送的 header | 适合谁 |
|
|
149
|
+
|---|------|--------------|--------|
|
|
150
|
+
| 1 | `gcloud auth print-identity-token` | `Authorization: Bearer …` | Llama 团队成员(零配置) |
|
|
151
|
+
| 2 | `$LLAMA_TOKEN` 环境变量 | `X-Llama-Token` | CI runner、云上 sandbox agent |
|
|
152
|
+
| 3 | `~/.llama/token`(mode `0600`) | `X-Llama-Token` | 本地常驻安装 |
|
|
153
|
+
| 4 | `~/.llama-command/config.json` | `X-Llama-Token` | CLI v0.1 老路径——首次读取自动迁移到 `~/.llama/token` |
|
|
154
|
+
|
|
155
|
+
如果 Bearer 和 X-Llama-Token 同时存在,两个一起发。服务器先验 Bearer,
|
|
156
|
+
失败后回退到 X-Llama-Token。任何时候都可以用 `llama auth status`
|
|
157
|
+
看当前认证身份。
|
|
158
|
+
|
|
159
|
+
### 零配置 —— 团队成员推荐
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
gcloud auth login # 一次性,选你的 @llamaventures.vc 账号
|
|
163
|
+
llama auth status # → 显示 role + email
|
|
164
|
+
llama deal search acme-ai # 直接用
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 手动 token —— 适合无 gcloud / 稳定 CI
|
|
168
|
+
|
|
169
|
+
1. 登录 https://command.llamaventures.vc。
|
|
170
|
+
2. 打开 `/settings/tokens` → **Mint Token**。
|
|
171
|
+
3. 保存 `llc_…` 值:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
llama token set llc_paste_token_here
|
|
175
|
+
# → 写入 ~/.llama/token (mode 0600)
|
|
176
|
+
# → 落盘前会先打一次 /api/me,无效的 token 不会落到磁盘上
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
或在 CI / 一次性环境里:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
export LLAMA_TOKEN=llc_paste_token_here
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
> **没账号?** 邮件 [gavin@llamaventures.vc](mailto:gavin@llamaventures.vc)。
|
|
186
|
+
> 任何邮箱(包括非 `@llamaventures.vc`)都能拿 token;system admin
|
|
187
|
+
> 在 `/settings/tokens` 里 mint,token 第一次使用时自动建 user 行。
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## CLI 速览
|
|
192
|
+
|
|
193
|
+
CLI 是 canonical 接口。底下的 HTTP API 也稳定,但 CLI 帮你处理了认证、错误格式、
|
|
194
|
+
schema 前向兼容——**即使你写脚本,也优先用 CLI**。
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# 认证 + token
|
|
198
|
+
llama auth status
|
|
199
|
+
llama token set <llc_...>
|
|
200
|
+
llama token show
|
|
201
|
+
|
|
202
|
+
# Pipeline——读
|
|
203
|
+
llama deal search "acme ai"
|
|
204
|
+
llama deal list --owner alex --status Diligence
|
|
205
|
+
llama deal show <dealId>
|
|
206
|
+
|
|
207
|
+
# Pipeline——写
|
|
208
|
+
llama deal create "Acme AI" --description "..." --source Gavin
|
|
209
|
+
llama deal update <dealId> status Diligence
|
|
210
|
+
llama deal delete <dealId> # 软删除(审计日志记录)
|
|
211
|
+
llama deal restore <dealId>
|
|
212
|
+
|
|
213
|
+
# Deal Brief——有序的、有类型的 block(text · link · embed · callout)
|
|
214
|
+
llama brief blocks <dealId>
|
|
215
|
+
llama brief add-text <dealId> --heading "..." --body "..."
|
|
216
|
+
llama brief add-link <dealId> --url "..." --label "..."
|
|
217
|
+
llama brief add-callout <dealId> --tone insight --heading "..." --body "..."
|
|
218
|
+
llama brief edit <dealId> <blockId> [--heading ...] [--body ...]
|
|
219
|
+
llama brief history <dealId> <blockId>
|
|
220
|
+
|
|
221
|
+
# Ownership + 审批
|
|
222
|
+
llama claim <dealId>
|
|
223
|
+
llama nominate <dealId> --user <userId>
|
|
224
|
+
llama approvals list
|
|
225
|
+
llama approvals decide <approvalId> approved --note "..."
|
|
226
|
+
|
|
227
|
+
# 时间线 + 帖子
|
|
228
|
+
llama timeline <dealId>
|
|
229
|
+
llama post <dealId> "消息内容" [--link url]
|
|
230
|
+
|
|
231
|
+
# Wiki
|
|
232
|
+
llama wiki search "<query>"
|
|
233
|
+
llama wiki save <slug> --title "..." --content "..."
|
|
234
|
+
|
|
235
|
+
# Mentions 收件箱
|
|
236
|
+
llama mentions
|
|
237
|
+
llama mentions resolve <mentionId>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
跑 `llama --help` 看完整命令清单(约 40 个命令,覆盖 deals、briefs、ownership、
|
|
241
|
+
timeline、facts、wiki、mentions、skill corrections、admin event feeds)。
|
|
242
|
+
所有删除默认软删除——可恢复,且通过 `deal_events` 留下审计痕迹。
|
|
243
|
+
|
|
244
|
+
### 错误码(给 agent 用)
|
|
245
|
+
|
|
246
|
+
CLI 在 stderr 里抛错时带稳定的、可解析的前缀:
|
|
247
|
+
|
|
248
|
+
| 前缀 | 含义 | 怎么恢复 |
|
|
249
|
+
|------|------|---------|
|
|
250
|
+
| `Error[NO_AUTH]` | 一个凭证都没找到 | `gcloud auth login` **或** `llama token set` |
|
|
251
|
+
| `Error[UNAUTHORIZED]` | 服务端拒绝了我们发出去的凭证 | token 可能被 revoke / 过期 / gcloud 选错账号 |
|
|
252
|
+
|
|
253
|
+
MCP server 在 `isError: true` 内容里返回相同的前缀,agent 不用解析自然语言就能 pattern-match。
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## MCP server
|
|
258
|
+
|
|
259
|
+
随包发布的 `llama-mcp` 是一个 **stdio Model Context Protocol** server,
|
|
260
|
+
暴露 **19 个 typed tools**——基本镜像 CLI 最常用的命令。每个 tool 都是
|
|
261
|
+
具名、scoped 的;**没有**通用的 API passthrough,这是有意设计的(公开
|
|
262
|
+
package 里一个能被 prompt-injection 触达的逃生通道,正是我们要避开的形状)。
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
auth_status
|
|
266
|
+
|
|
267
|
+
deal_search deal_show
|
|
268
|
+
deal_create deal_update
|
|
269
|
+
|
|
270
|
+
brief_blocks brief_add_text
|
|
271
|
+
brief_add_link brief_add_callout
|
|
272
|
+
|
|
273
|
+
timeline post
|
|
274
|
+
|
|
275
|
+
wiki_search wiki_save
|
|
276
|
+
|
|
277
|
+
mentions_list
|
|
278
|
+
|
|
279
|
+
pitch_start pitch_send_message
|
|
280
|
+
pitch_upload_file pitch_status
|
|
281
|
+
pitch_finalize
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
认证链跟 CLI 完全一样(gcloud → `$LLAMA_TOKEN` → `~/.llama/token`)。
|
|
285
|
+
`agent_briefing` 这个 MCP **prompt** 还会原样吐出
|
|
286
|
+
[`AGENT_BRIEFING.md`](AGENT_BRIEFING.md)——刚装上 server 的 agent
|
|
287
|
+
不用离开协议就能给自己 onboard。
|
|
288
|
+
|
|
289
|
+
### 接到你的 agent 上
|
|
290
|
+
|
|
291
|
+
<details open>
|
|
292
|
+
<summary><strong>Claude Desktop</strong>(macOS 路径示例)</summary>
|
|
293
|
+
|
|
294
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
295
|
+
|
|
296
|
+
```json
|
|
297
|
+
{
|
|
298
|
+
"mcpServers": {
|
|
299
|
+
"llama": { "command": "llama-mcp" }
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
重启 Claude Desktop。工具会出现在 🛠️ 菜单里。
|
|
305
|
+
</details>
|
|
306
|
+
|
|
307
|
+
<details>
|
|
308
|
+
<summary><strong>Claude Code</strong></summary>
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
claude mcp add llama -- llama-mcp
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
或直接编辑 `~/.claude/claude.json`——JSON 结构和 Desktop 一样。
|
|
315
|
+
</details>
|
|
316
|
+
|
|
317
|
+
<details>
|
|
318
|
+
<summary><strong>Cursor</strong></summary>
|
|
319
|
+
|
|
320
|
+
`~/.cursor/mcp.json`:
|
|
321
|
+
|
|
322
|
+
```json
|
|
323
|
+
{
|
|
324
|
+
"mcpServers": {
|
|
325
|
+
"llama": { "command": "llama-mcp" }
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
</details>
|
|
330
|
+
|
|
331
|
+
<details>
|
|
332
|
+
<summary><strong>OpenCode / OpenClaw / Codex / 任何其它 stdio MCP 客户端</strong></summary>
|
|
333
|
+
|
|
334
|
+
大部分客户端都接受 `command` + `args`。先 `which llama-mcp` 找到可执行路径
|
|
335
|
+
(一般是 `/usr/local/bin/llama-mcp` 或 `~/.npm-global/bin/llama-mcp`),
|
|
336
|
+
把客户端指过去就行。无需协议扩展、无需 transport flag。
|
|
337
|
+
</details>
|
|
338
|
+
|
|
339
|
+
> 想让 agent 自己 onboard?跑 `llama agent-onboard`,或者从 MCP server
|
|
340
|
+
> 拉 `agent_briefing` prompt——那是 AI agent 的工作合约(autonomy 等级、
|
|
341
|
+
> attribution 语法、错误恢复、anti-pollution 规则)。
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## 稳定性
|
|
346
|
+
|
|
347
|
+
- **版本号:** 走 [SemVer](https://semver.org)。重命名或删除 CLI 命令 → **major**。
|
|
348
|
+
新增 tool / command / flag → minor。修 bug → patch。CLI 自带 `--version`;
|
|
349
|
+
MCP server 在 `serverInfo` 里报告同一个值。
|
|
350
|
+
- **向后兼容:** wire format(Bearer / X-Llama-Token)和 `Error[…]` 前缀
|
|
351
|
+
是公开契约,major 版本内不会变。
|
|
352
|
+
- **服务端 schema 漂移:** 当 API 多了一个端点,下一个 minor 版本会带
|
|
353
|
+
typed wrapper。在那之前,可以用 `llama` CLI 本身——它自带 40+ 命令
|
|
354
|
+
覆盖整个 API 表面,足够顶住 MCP 还没包到的端点。
|
|
355
|
+
|
|
356
|
+
详见 [`CHANGELOG.md`](CHANGELOG.md)。
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 安全
|
|
361
|
+
|
|
362
|
+
- **`@llamaventures/cli` 通过 npm
|
|
363
|
+
[Trusted Publishers](https://docs.npmjs.com/trusted-publishers) 发布**——
|
|
364
|
+
仓库里**没有** `NPM_TOKEN`,发不出来 token 也就泄漏不了。
|
|
365
|
+
每个版本带 `--provenance`(sigstore 签名),npm 会显示 **Provenance** 徽章,
|
|
366
|
+
可追溯到具体的 GitHub Action workflow 和 commit。
|
|
367
|
+
- **依赖树最小化。** CLI 本身零依赖;MCP server 只依赖
|
|
368
|
+
`@modelcontextprotocol/sdk`,pin 死版本。
|
|
369
|
+
- **Branch protection** 锁 `main`;Dependabot、secret scanning、
|
|
370
|
+
push protection 都开了。
|
|
371
|
+
- **Token:** 本地存在 `~/.llama/token`,mode `0600`。服务端只存 sha256 hash——
|
|
372
|
+
明文只会在用户手里出现,永远不在数据库里。
|
|
373
|
+
|
|
374
|
+
报告漏洞:见 [`SECURITY.md`](SECURITY.md)。**不要**在公开 issue 里报安全 bug。
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 贡献
|
|
379
|
+
|
|
380
|
+
这是 Llama Ventures 内部维护的工具。团队成员的 PR 欢迎——
|
|
381
|
+
详见 [`CONTRIBUTING.md`](CONTRIBUTING.md)(本地开发环、发版流程、
|
|
382
|
+
项目约定:零依赖、CLI/MCP 同步、稳定的 `Error[…]` 前缀)。
|
|
383
|
+
|
|
384
|
+
外部贡献:文档错漏、流程报告类的 issue 欢迎。如果你想做的事是
|
|
385
|
+
"我想让 Llama Ventures 看到我的项目"——请走
|
|
386
|
+
[向 Llama pitch](#给华人创业者-向-llama-pitch) 那条路。
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## License
|
|
391
|
+
|
|
392
|
+
[MIT](LICENSE) — © 2026 Llama Ventures, Inc.
|
package/bin/llama-mcp.mjs
CHANGED
|
@@ -7,10 +7,14 @@
|
|
|
7
7
|
// agent's MCP config — see README for snippets. Auth is identical to the
|
|
8
8
|
// CLI: gcloud (preferred) → $LLAMA_TOKEN → ~/.llama/token.
|
|
9
9
|
|
|
10
|
+
import { createRequire } from "module";
|
|
10
11
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
13
|
import { z } from "zod";
|
|
13
14
|
import { getAuthHeaders, readBriefing, request } from "../lib/client.mjs";
|
|
15
|
+
|
|
16
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
17
|
+
const { version: PKG_VERSION } = requireFromHere("../package.json");
|
|
14
18
|
import {
|
|
15
19
|
clearExternalSession,
|
|
16
20
|
getExternalSessionStatus,
|
|
@@ -38,7 +42,7 @@ async function callApi(method, path, body) {
|
|
|
38
42
|
|
|
39
43
|
const server = new McpServer({
|
|
40
44
|
name: "llama-mcp",
|
|
41
|
-
version:
|
|
45
|
+
version: PKG_VERSION,
|
|
42
46
|
});
|
|
43
47
|
|
|
44
48
|
// ============================================================
|
|
@@ -350,39 +354,6 @@ server.registerTool(
|
|
|
350
354
|
}
|
|
351
355
|
);
|
|
352
356
|
|
|
353
|
-
// ============================================================
|
|
354
|
-
// Escape hatch
|
|
355
|
-
// ============================================================
|
|
356
|
-
|
|
357
|
-
server.registerTool(
|
|
358
|
-
"llama_api",
|
|
359
|
-
{
|
|
360
|
-
description:
|
|
361
|
-
"Generic Llama Command HTTP API passthrough. Use this for endpoints that " +
|
|
362
|
-
"don't yet have a typed tool. Returns raw JSON. Path must start with /api/. " +
|
|
363
|
-
"See https://github.com/SoujiOkita98/llama-cli for the wrapped tool list.",
|
|
364
|
-
inputSchema: {
|
|
365
|
-
method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
|
|
366
|
-
path: z.string().describe("path starting with /api/"),
|
|
367
|
-
body: z
|
|
368
|
-
.any()
|
|
369
|
-
.optional()
|
|
370
|
-
.describe(
|
|
371
|
-
"request body — only used on POST / PUT / PATCH; should be a JSON-serializable object"
|
|
372
|
-
),
|
|
373
|
-
},
|
|
374
|
-
},
|
|
375
|
-
async ({ method, path, body }) => {
|
|
376
|
-
if (typeof path !== "string" || !path.startsWith("/api/")) {
|
|
377
|
-
return {
|
|
378
|
-
content: [{ type: "text", text: "Error: path must start with /api/" }],
|
|
379
|
-
isError: true,
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
return callApi(method, path, body);
|
|
383
|
-
}
|
|
384
|
-
);
|
|
385
|
-
|
|
386
357
|
// ============================================================
|
|
387
358
|
// External pitch (founder intake) — no Llama Command token required
|
|
388
359
|
// ============================================================
|
package/bin/llama.mjs
CHANGED
|
@@ -309,13 +309,19 @@ Upload a file (deck / pitch / one-pager):
|
|
|
309
309
|
Interactive REPL (requires existing session):
|
|
310
310
|
llama pitch
|
|
311
311
|
|
|
312
|
+
Wrap up the pitch (asks the agent to call finalize_intake immediately):
|
|
313
|
+
llama pitch finalize # use when you're done — agent stops asking
|
|
314
|
+
|
|
312
315
|
Inspect / clean up:
|
|
313
316
|
llama pitch status # session id, idle minutes, finalized?
|
|
314
317
|
llama pitch end # clear local session state
|
|
315
318
|
|
|
316
319
|
Caps (server-enforced):
|
|
317
|
-
5 sessions per IP per day, 3 per email per day,
|
|
320
|
+
5 sessions per IP per day, 3 per email per day, 60min idle timeout,
|
|
318
321
|
100 messages per session, 1M tokens per session.
|
|
322
|
+
|
|
323
|
+
Environment:
|
|
324
|
+
LLAMA_API_URL override base URL (dev: http://localhost:3000)
|
|
319
325
|
`);
|
|
320
326
|
return;
|
|
321
327
|
}
|
|
@@ -403,14 +409,49 @@ Caps (server-enforced):
|
|
|
403
409
|
cleared: !!had,
|
|
404
410
|
session_file: EXTERNAL_SESSION_FILE,
|
|
405
411
|
note: had
|
|
406
|
-
? "Local session state cleared. Server-side session may still be active until idle timeout (
|
|
412
|
+
? "Local session state cleared. Server-side session may still be active until idle timeout (60min)."
|
|
407
413
|
: "No local session was active.",
|
|
408
414
|
});
|
|
409
415
|
return;
|
|
410
416
|
}
|
|
411
417
|
|
|
418
|
+
if (action === "finalize") {
|
|
419
|
+
// Founder-initiated finalize: send a sentinel token in the chat
|
|
420
|
+
// stream that the system prompt recognizes as "wrap up now." The
|
|
421
|
+
// intake agent calls finalize_intake on this turn with whatever
|
|
422
|
+
// fields are recorded — no extra questions, no confirmation prompt.
|
|
423
|
+
// Local session is left as-is; on next read its `finalized=true`
|
|
424
|
+
// reflects the server's status.
|
|
425
|
+
const session = readExternalSession();
|
|
426
|
+
if (!session) {
|
|
427
|
+
throw new Error(
|
|
428
|
+
"No active pitch session. Run `llama pitch start --name \"...\" --email \"...\"` first."
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
if (session.finalized) {
|
|
432
|
+
throw new Error(
|
|
433
|
+
"This pitch session is already finalized. Run `llama pitch end` to clear local state."
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
process.stderr.write("Asking the agent to wrap up...\n");
|
|
437
|
+
const result = await sendExternalMessage("[FOUNDER_FINALIZE_REQUEST]");
|
|
438
|
+
process.stdout.write(result.text + "\n");
|
|
439
|
+
if (result.finalized) {
|
|
440
|
+
process.stderr.write("\n--- Pitch session finalized ---\n");
|
|
441
|
+
if (result.finalize_payload) {
|
|
442
|
+
process.stderr.write(JSON.stringify(result.finalize_payload, null, 2) + "\n");
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
process.stderr.write(
|
|
446
|
+
"\n⚠ Agent did not call finalize_intake on this turn. " +
|
|
447
|
+
"Try `llama pitch finalize` once more, or `llama pitch end` to abandon.\n"
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
412
453
|
// No action → REPL mode (requires existing session)
|
|
413
|
-
if (action === undefined || (rest.length === 0 && !["start", "say", "upload", "status", "end"].includes(action))) {
|
|
454
|
+
if (action === undefined || (rest.length === 0 && !["start", "say", "upload", "status", "end", "finalize"].includes(action))) {
|
|
414
455
|
// Treat any unknown bare action as "join existing session in REPL mode"
|
|
415
456
|
const session = readExternalSession();
|
|
416
457
|
if (!session) {
|
|
@@ -500,6 +541,13 @@ async function runPitchRepl() {
|
|
|
500
541
|
|
|
501
542
|
async function main() {
|
|
502
543
|
const [area, action, ...rest] = process.argv.slice(2);
|
|
544
|
+
if (area === "--version" || area === "-v" || area === "version") {
|
|
545
|
+
const { createRequire } = await import("module");
|
|
546
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
547
|
+
const { version } = requireFromHere("../package.json");
|
|
548
|
+
console.log(version);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
503
551
|
if (!area || area === "help" || area === "--help" || area === "-h") {
|
|
504
552
|
usage();
|
|
505
553
|
return;
|
|
@@ -608,7 +656,7 @@ https://command.llamaventures.vc/settings/tokens, run
|
|
|
608
656
|
throw new Error(`Verify call failed: HTTP ${res.status}. Not saving.`);
|
|
609
657
|
}
|
|
610
658
|
} catch (e) {
|
|
611
|
-
if (e instanceof Error && e.message.startsWith("Server rejected") || e.message.startsWith("Verify call failed")) {
|
|
659
|
+
if (e instanceof Error && (e.message.startsWith("Server rejected") || e.message.startsWith("Verify call failed"))) {
|
|
612
660
|
throw e;
|
|
613
661
|
}
|
|
614
662
|
// Network / DNS failure — surface but let the user override.
|
package/lib/external.mjs
CHANGED
|
@@ -100,6 +100,10 @@ export async function startExternalSession({ name, email }) {
|
|
|
100
100
|
pow_nonce: powNonce,
|
|
101
101
|
user_agent: "@llamaventures/cli",
|
|
102
102
|
}),
|
|
103
|
+
// Cap at 60s — start-session is PoW + DB insert, never legitimate
|
|
104
|
+
// beyond a few seconds. Without this, a network hang freezes the CLI
|
|
105
|
+
// indefinitely.
|
|
106
|
+
signal: AbortSignal.timeout(60_000),
|
|
103
107
|
});
|
|
104
108
|
|
|
105
109
|
if (!res.ok) {
|
|
@@ -218,6 +222,11 @@ export async function sendExternalMessage(message, { attachments, onChunk } = {}
|
|
|
218
222
|
message,
|
|
219
223
|
...(attachments ? { attachments } : {}),
|
|
220
224
|
}),
|
|
225
|
+
// 180s ceiling — covers a legitimate slow agent turn (multi-tool
|
|
226
|
+
// call + deck read + Sonnet ~2k token reply ≈ 90-120s in practice)
|
|
227
|
+
// while still detecting a dead connection. Without this, a hung
|
|
228
|
+
// SSE stream freezes the CLI indefinitely.
|
|
229
|
+
signal: AbortSignal.timeout(180_000),
|
|
221
230
|
});
|
|
222
231
|
|
|
223
232
|
if (!res.ok) {
|
|
@@ -343,6 +352,10 @@ export async function uploadExternalFile(filePath) {
|
|
|
343
352
|
method: "POST",
|
|
344
353
|
headers: { Cookie: `external_session=${session.session_id}` },
|
|
345
354
|
body: formData,
|
|
355
|
+
// 180s ceiling — covers a 50MB upload over a slow tether (~280KB/s).
|
|
356
|
+
// Faster networks return in seconds; this only kicks in on a dead
|
|
357
|
+
// connection so the CLI doesn't hang forever.
|
|
358
|
+
signal: AbortSignal.timeout(180_000),
|
|
346
359
|
});
|
|
347
360
|
|
|
348
361
|
if (!res.ok) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llamaventures/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "Llama Ventures CLI + MCP server. Internal team tool for command.llamaventures.vc.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,15 +28,23 @@
|
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"llama-ventures",
|
|
31
|
+
"venture-capital",
|
|
32
|
+
"investment-pipeline",
|
|
31
33
|
"cli",
|
|
32
34
|
"mcp",
|
|
33
|
-
"
|
|
35
|
+
"mcp-server",
|
|
36
|
+
"modelcontextprotocol",
|
|
37
|
+
"agent",
|
|
38
|
+
"ai-agent",
|
|
39
|
+
"anthropic"
|
|
34
40
|
],
|
|
35
41
|
"author": "Llama Ventures, Inc.",
|
|
42
|
+
"funding": "https://github.com/SoujiOkita98/llama-cli",
|
|
36
43
|
"publishConfig": {
|
|
37
44
|
"access": "public"
|
|
38
45
|
},
|
|
39
46
|
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "1.29.0"
|
|
47
|
+
"@modelcontextprotocol/sdk": "1.29.0",
|
|
48
|
+
"zod": "^4.4.3"
|
|
41
49
|
}
|
|
42
50
|
}
|