@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.
Files changed (3) hide show
  1. package/README.md +154 -0
  2. package/dist/index.js +3604 -0
  3. 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.