@myspec/mcp-server 0.1.0-next.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 +154 -0
- package/dist/index.js +3604 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# @myspec/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP server for the MySpec platform. Exposes projects, files, and attachments to MCP-aware clients (Claude Desktop, Claude Code, Cursor) over stdio.
|
|
4
|
+
|
|
5
|
+
## Install & run
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# One-shot via npx
|
|
9
|
+
npx -y @myspec/mcp-server login # browser-based OAuth sign-in
|
|
10
|
+
npx -y @myspec/mcp-server # start the MCP server (stdio)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
You can add the server to your MCP client before logging in — it will start up and connect successfully, and each tool call will return an error result prompting you to run `npx @myspec/mcp-server login`. Once you sign in, tools work immediately without restarting the MCP client.
|
|
14
|
+
|
|
15
|
+
## CLI
|
|
16
|
+
|
|
17
|
+
Run with `npx @myspec/mcp-server [command]` (or `myspec-mcp [command]` when installed on your PATH):
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
(default) Start MCP server over stdio
|
|
21
|
+
serve Start MCP server over stdio
|
|
22
|
+
login Sign in via browser loopback OAuth
|
|
23
|
+
login --paste Sign in by pasting a one-time code
|
|
24
|
+
login --provider <google|github|gitlab|linear|atlassian>
|
|
25
|
+
logout Revoke refresh token and clear local credentials
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Credentials are persisted at `$XDG_CONFIG_HOME/myspec/mcp-server.json` (POSIX) or `%APPDATA%\myspec\mcp-server.json` (Windows), mode `0600`.
|
|
29
|
+
|
|
30
|
+
## Environment variables
|
|
31
|
+
|
|
32
|
+
| Variable | Purpose |
|
|
33
|
+
|---|---|
|
|
34
|
+
| `MYSPEC_USER_AUTH_URL` | user-auth base URL (default `https://auth.myspec.dev`) |
|
|
35
|
+
| `MYSPEC_PLATFORM_URL` | platform API base URL (default `https://api.myspec.dev`) |
|
|
36
|
+
| `MYSPEC_REFRESH_TOKEN` | Skip file-based credentials; the server mints a fresh access token on first use via this refresh token. The supported way to wire the MCP server up without running `npx @myspec/mcp-server login`. |
|
|
37
|
+
| `MYSPEC_DOWNLOAD_ROOT` | Absolute path used by `read_file` as its on-disk cache root (default: `~/.myspec`). Tools never write outside this root. |
|
|
38
|
+
| `MYSPEC_WEBAPP_URL` | Webapp base URL used by `login --paste` to display the OAuth callback URL (default: derived from `MYSPEC_USER_AUTH_URL`) |
|
|
39
|
+
|
|
40
|
+
## Tools
|
|
41
|
+
|
|
42
|
+
| Name | Inputs | Output |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `list_projects` | `query?`, `limit?`, `offset?` | Paginated list of projects |
|
|
45
|
+
| `get_project` | `project_id` | Project + active sessions + files + attachments |
|
|
46
|
+
| `get_file` | `file_id`, optional `include_download_url` | File metadata; with `include_download_url=N` also returns a download URL targeting revision `N` |
|
|
47
|
+
| `read_file` | `file_id`, optional `revision` | UTF-8 content of the file (errors for binary). Cached on disk under `MYSPEC_DOWNLOAD_ROOT` |
|
|
48
|
+
| `get_attachment` | `attachment_id`, optional `include_download_url` | Attachment metadata (looked up org-scoped by id); with `include_download_url>0` also returns a signed download URL |
|
|
49
|
+
| `upload_attachment` | `project_id`, `file_path` (absolute), optional `file_name`, optional `mime_type`, optional `override` | Uploads the local file as a new attachment on the project. Returns `attachment_id`, `file_name` (the **effective** name the platform stored — may differ from the requested one when auto-dedup adds a `(N)` suffix), `has_file_name_conflict` (`true` when stored name ≠ requested name), `mime_type`, `file_size_bytes`, `checksum` (format: `sha256:<hex>`), `file_uri`, `reused_existing_attachment` (`true` when an existing attachment with the same name AND same checksum was found and returned without re-uploading; `file_uri` is then omitted because the list endpoint does not surface it — call `get_attachment` for a download URL). With `override=true`, any existing attachment whose recorded name matches is soft-deleted first (returned as `overridden_attachment_ids` — empty array means nothing matched) and the new upload keeps the requested name; the same-checksum short-circuit still applies, so a no-op re-upload never deletes anything. Max 10 MB. Supported content: PDF, DOCX, XLSX, and any UTF-8 text file (XML, JSON, YAML, HTML, Markdown, CSV, source code, ...) |
|
|
50
|
+
|
|
51
|
+
### `include_download_url` semantics
|
|
52
|
+
|
|
53
|
+
`get_file`:
|
|
54
|
+
|
|
55
|
+
- Omit or `0` → metadata only.
|
|
56
|
+
- Equal to current `revision_count` → adds `download_url` (signed) and `expires_at`.
|
|
57
|
+
- Less than `revision_count` → adds `download_url` pointing at `${platform}/project/v1/files/{id}/revisions/{N}`, `download_headers: ["Authorization: Bearer <access_token>"]`, and `expires_at` (the access token's expiry). Signed URLs are not available for historical revisions, so the consumer must send those headers. **Treat the response as sensitive — the token is short-lived but still a credential.**
|
|
58
|
+
- Greater than `revision_count` → tool error.
|
|
59
|
+
|
|
60
|
+
`get_attachment`:
|
|
61
|
+
|
|
62
|
+
- Omit or `0` → metadata only.
|
|
63
|
+
- Any positive integer → adds a signed `download_url` and `expires_at`. Attachments do not have revisions, so the integer value is just an on/off flag.
|
|
64
|
+
|
|
65
|
+
## Claude Desktop config snippet
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"myspec": {
|
|
71
|
+
"command": "npx",
|
|
72
|
+
"args": ["-y", "@myspec/mcp-server"]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cd projects/mcp-server
|
|
82
|
+
npm install
|
|
83
|
+
npm run typecheck
|
|
84
|
+
npm run lint
|
|
85
|
+
npm run test # unit tests (vitest)
|
|
86
|
+
npm run build # emits dist/index.js (Node 18+ ESM, bundled, with shebang)
|
|
87
|
+
npm run test:integration # builds dist + runs test/integration against mock servers
|
|
88
|
+
node dist/index.js login
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Releasing & publishing
|
|
92
|
+
|
|
93
|
+
This package is published to npm as `@myspec/mcp-server` by GitHub Actions.
|
|
94
|
+
Prereleases are automatic on merge to `main`
|
|
95
|
+
(`.github/workflows/mcp-server-push-main.yml`); the official `latest` release
|
|
96
|
+
is a separate manual workflow (`.github/workflows/mcp-server-release.yml`). The
|
|
97
|
+
published tarball is self-contained: `tsup` bundles the `@myspec/*` workspace
|
|
98
|
+
packages into `dist/index.js`, so they live in `devDependencies` and are not
|
|
99
|
+
installed by consumers.
|
|
100
|
+
|
|
101
|
+
### One-time setup
|
|
102
|
+
|
|
103
|
+
1. Ensure the `@myspec` scope exists on npm and your account can publish to it.
|
|
104
|
+
2. Create an npm **granular access token** with publish rights to the `@myspec`
|
|
105
|
+
scope and add it to the repo as the **`NPM_TOKEN`** secret
|
|
106
|
+
(Settings → Secrets and variables → Actions).
|
|
107
|
+
|
|
108
|
+
### Release flow
|
|
109
|
+
|
|
110
|
+
- **Every PR to `main`** runs `mcp-server-pr-main.yml`: lint, typecheck, unit
|
|
111
|
+
tests, build, integration tests, a tarball smoke test, and `npm publish
|
|
112
|
+
--dry-run`. Nothing is uploaded.
|
|
113
|
+
- **Every merge to `main`** runs `mcp-server-push-main.yml`, which
|
|
114
|
+
auto-publishes a prerelease `<version>-next.<run_number>` under the `next`
|
|
115
|
+
dist-tag (`npx @myspec/mcp-server@next`). The build fails if the base version
|
|
116
|
+
in `package.json` is already released — bump it first.
|
|
117
|
+
- **Cutting a real release** is manual and separate: run the
|
|
118
|
+
`mcp-server-release` workflow via **Actions → Run workflow**
|
|
119
|
+
(`workflow_dispatch`). It publishes the clean `package.json` version to the
|
|
120
|
+
`latest` dist-tag. It rejects prerelease versions and refuses to republish an
|
|
121
|
+
existing version. A `dry_run` input is available to validate without
|
|
122
|
+
uploading.
|
|
123
|
+
|
|
124
|
+
### Bumping the version
|
|
125
|
+
|
|
126
|
+
The version lives in `projects/mcp-server/package.json`. To bump it manually
|
|
127
|
+
(e.g. to choose the next release version), from `projects/mcp-server`:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm version patch --no-git-tag-version # 0.1.0 -> 0.1.1 (also updates the lockfile)
|
|
131
|
+
npm version minor --no-git-tag-version # 0.1.0 -> 0.2.0
|
|
132
|
+
npm version major --no-git-tag-version # 0.1.0 -> 1.0.0
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`--no-git-tag-version` edits `package.json` + `package-lock.json` only (no git
|
|
136
|
+
commit or tag). `main` is protected, so commit the bump on a branch and open a
|
|
137
|
+
PR.
|
|
138
|
+
|
|
139
|
+
**This is automated after a release.** The `mcp-server-release` workflow has a
|
|
140
|
+
`next_bump` input (`patch` by default; `minor`/`major` selectable). After a
|
|
141
|
+
successful publish to `@latest`, its `bump-next` job opens a PR bumping
|
|
142
|
+
`package.json` to the next version — so you normally don't bump by hand. Merge
|
|
143
|
+
that PR and `main` is ready for the next cycle. (The job uses the
|
|
144
|
+
`GOSU_GITHUB_TOKEN` PAT so the bump PR triggers CI and can be merged.)
|
|
145
|
+
|
|
146
|
+
### Conventions & gotchas
|
|
147
|
+
|
|
148
|
+
- **`package.json` always holds the next *unreleased* version.** After
|
|
149
|
+
releasing `0.2.0`, bump to `0.3.0` so prereleases on `main` stay ahead of
|
|
150
|
+
`@latest`. The post-release `bump-next` job does this for you.
|
|
151
|
+
- **`npx @myspec/mcp-server` (no tag) only resolves once a `latest` exists** —
|
|
152
|
+
run the manual release at least once. Until then, only `@next` is available.
|
|
153
|
+
- The `version` reported by `myspec-mcp --version` is read from `package.json`
|
|
154
|
+
at runtime, so it always matches the published version.
|