@table-bro/mcp 0.0.0-stage → 1.1.0

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -2
  3. package/dist/docs/docs.d.ts +21 -0
  4. package/dist/docs/docs.js +103 -0
  5. package/dist/docs/pages.d.ts +25 -0
  6. package/dist/docs/pages.js +1404 -0
  7. package/dist/docs/topics.d.ts +11 -0
  8. package/dist/docs/topics.js +396 -0
  9. package/dist/extension.d.ts +23 -0
  10. package/dist/extension.js +1 -0
  11. package/dist/generate/angular.d.ts +26 -0
  12. package/dist/generate/angular.js +241 -0
  13. package/dist/generate/cells.d.ts +22 -0
  14. package/dist/generate/cells.js +157 -0
  15. package/dist/generate/code.d.ts +48 -0
  16. package/dist/generate/code.js +153 -0
  17. package/dist/generate/config.d.ts +16 -0
  18. package/dist/generate/config.js +95 -0
  19. package/dist/generate/fillings.d.ts +49 -0
  20. package/dist/generate/fillings.js +130 -0
  21. package/dist/generate/filters.d.ts +36 -0
  22. package/dist/generate/filters.js +254 -0
  23. package/dist/generate/generate-code.d.ts +34 -0
  24. package/dist/generate/generate-code.js +59 -0
  25. package/dist/generate/names.d.ts +52 -0
  26. package/dist/generate/names.js +93 -0
  27. package/dist/generate/rows.d.ts +5 -0
  28. package/dist/generate/rows.js +22 -0
  29. package/dist/generate/scaffold.d.ts +35 -0
  30. package/dist/generate/scaffold.js +62 -0
  31. package/dist/generate/service.d.ts +16 -0
  32. package/dist/generate/service.js +320 -0
  33. package/dist/generate/setup.d.ts +34 -0
  34. package/dist/generate/setup.js +156 -0
  35. package/dist/generate/vanilla.d.ts +10 -0
  36. package/dist/generate/vanilla.js +160 -0
  37. package/dist/index.d.ts +14 -0
  38. package/dist/index.js +10 -0
  39. package/dist/project/inspect-project.d.ts +53 -0
  40. package/dist/project/inspect-project.js +223 -0
  41. package/dist/server/main.d.ts +2 -0
  42. package/dist/server/main.js +8 -0
  43. package/dist/server/server.d.ts +17 -0
  44. package/dist/server/server.js +212 -0
  45. package/dist/spec/builtin-specs.d.ts +13 -0
  46. package/dist/spec/builtin-specs.js +167 -0
  47. package/dist/spec/css-variables.d.ts +22 -0
  48. package/dist/spec/css-variables.js +54 -0
  49. package/dist/spec/schema.d.ts +19 -0
  50. package/dist/spec/schema.js +278 -0
  51. package/dist/spec/skin-config.d.ts +30 -0
  52. package/dist/spec/skin-config.js +67 -0
  53. package/dist/spec/spec.d.ts +157 -0
  54. package/dist/spec/spec.js +2 -0
  55. package/dist/spec/validate-spec.d.ts +54 -0
  56. package/dist/spec/validate-spec.js +979 -0
  57. package/dist/version.d.ts +2 -0
  58. package/dist/version.js +2 -0
  59. package/package.json +57 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Table, Bro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,90 @@
1
- # Temporary Holding Version
1
+ # @table-bro/mcp
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The MCP server of [Table, Bro](https://table-bro.com): pixel-perfect Material data tables for Angular, and more. A Web
4
+ Components table engine on top of existing UI components. The server gives an AI coding agent the reference of the table,
5
+ the check of a table spec and the code generator of a table for Angular and Vanilla JS, with the skins `mat` (Angular
6
+ Material), `bs` (Bootstrap 5) and `nv` (native HTML). The agent writes the files; the server only reads.
7
+
8
+ | Tool | What it gives |
9
+ | --- | --- |
10
+ | `get_started` | How Table, Bro works, the order of the tools and a minimal table for your target and skin, once a session |
11
+ | `get_docs` | A topic of the reference or a page of Docs with its code, the topics of a query, or the list of the topics |
12
+ | `inspect_project` | The packages, the skins, the CSS, the elements and the tables of the project, and the problems of its setup with their fixes |
13
+ | `validate_spec` | Every error and warning of a table spec, with its path and its fix |
14
+ | `generate_code` | The files of a new table from a spec or a built-in spec, the setup of the project and what to finish by hand |
15
+ | `scaffold_component` | One custom cell, the row details or the filters of the Filter Drawer for an existing table, with how to connect it |
16
+
17
+ ## Setup
18
+
19
+ The server describes one version of Table, Bro: run the version of `@table-bro/core` that the project has, as `1.1.0` below.
20
+ After an update of Table, Bro, change the version in the setup of the agent too; `inspect_project` compares the
21
+ versions and gives the line to change.
22
+
23
+ `npx` downloads the package and starts it: the project does not install `@table-bro/mcp`. Node.js 22.12 or newer.
24
+
25
+ **Claude Code**, `.mcp.json` in the root of the project:
26
+
27
+ ```json
28
+ {"mcpServers": {"table-bro": {"command": "npx", "args": ["-y", "@table-bro/mcp@1.1.0"]}}}
29
+ ```
30
+
31
+ or `claude mcp add --scope project table-bro -- npx -y @table-bro/mcp@1.1.0`.
32
+
33
+ **Codex**, `~/.codex/config.toml`:
34
+
35
+ ```toml
36
+ [mcp_servers.table-bro]
37
+ command = "npx"
38
+ args = ["-y", "@table-bro/mcp@1.1.0"]
39
+ ```
40
+
41
+ Codex calls the tools of the server when `AGENTS.md` of the project says so:
42
+
43
+ ```markdown
44
+ The tables of this project are Table, Bro. Its MCP server table-bro has the reference, the check of a table and the code generator: call its tool get_started before you write or change a table.
45
+ ```
46
+
47
+ **Cursor**, `.cursor/mcp.json` in the project:
48
+
49
+ ```json
50
+ {"mcpServers": {"table-bro": {"command": "npx", "args": ["-y", "@table-bro/mcp@1.1.0"]}}}
51
+ ```
52
+
53
+ **VS Code**, `.vscode/mcp.json` in the project:
54
+
55
+ ```json
56
+ {"servers": {"table-bro": {"type": "stdio", "command": "npx", "args": ["-y", "@table-bro/mcp@1.1.0"]}}}
57
+ ```
58
+
59
+ **Claude Desktop**, `claude_desktop_config.json`:
60
+
61
+ ```json
62
+ {"mcpServers": {"table-bro": {"command": "npx", "args": ["-y", "@table-bro/mcp@1.1.0"]}}}
63
+ ```
64
+
65
+ ## The folder of the project
66
+
67
+ `inspect_project` reads the project as text. It takes the folder in its argument `path`; without it, the first root of
68
+ the workspace that the client gives, else the folder where the client started the server. A client that starts the
69
+ server outside the project and gives no roots, as a desktop application may, needs `path`: the agent passes the root
70
+ of the project. The profile names the folder it describes.
71
+
72
+ ## Paid modules
73
+
74
+ A paid module of Table, Bro adds its fields of the config, its topics and its setup to the server when the server is
75
+ started with its name, and the module is installed in the project:
76
+
77
+ ```json
78
+ {"mcpServers": {"table-bro": {"command": "npx", "args": ["-y", "@table-bro/mcp@1.1.0", "--extension", "<the package of the module>"]}}}
79
+ ```
80
+
81
+ The server runs the code of no other package.
82
+
83
+ ## In code
84
+
85
+ The tools are pure functions, and the package exports them for Node.js and the browser: `validateSpec`,
86
+ `generateCode`, `getDocs`, the built-in specs, `builtinSpecs`, and the JSON Schema of a spec, `specSchema`.
87
+
88
+ ## License
89
+
90
+ MIT
@@ -0,0 +1,21 @@
1
+ import type { BroMcpExtension } from '../extension.js';
2
+ import { type BroTarget } from '../generate/setup.js';
3
+ import type { BroSpecSkin } from '../spec/spec.js';
4
+ import { type BroDocTopic } from './topics.js';
5
+ /** The short text the MCP server gives a client when it connects. */
6
+ export declare const serverInstructions: string;
7
+ /**
8
+ * The one text an agent always reads: how the table works, a minimal working example for the target and the skin
9
+ * of the project, and the topics of the reference.
10
+ */
11
+ export declare function getStarted(options?: {
12
+ target?: BroTarget;
13
+ skin?: BroSpecSkin;
14
+ }, extensions?: BroMcpExtension[]): string;
15
+ /** One topic of the reference, the topics that match a query, or the list of the topics. */
16
+ export declare function getDocs(request?: {
17
+ topic?: string;
18
+ query?: string;
19
+ }, extensions?: BroMcpExtension[]): string;
20
+ /** The topics of the reference with the topics of the paid modules that the server loads. */
21
+ export declare function allTopics(extensions: BroMcpExtension[]): BroDocTopic[];
@@ -0,0 +1,103 @@
1
+ import { generateCode } from '../generate/generate-code.js';
2
+ import { setupText } from '../generate/setup.js';
3
+ import { builtinSpecs } from '../spec/builtin-specs.js';
4
+ import { tableBroVersion } from '../version.js';
5
+ import { topics } from './topics.js';
6
+ /** The short text the MCP server gives a client when it connects. */
7
+ export const serverInstructions = `Table, Bro ${tableBroVersion}: pixel-perfect Material data tables for Angular, and more. A Web Components table engine on top of existing UI components: `
8
+ + 'the Custom Element <table-bro> with the skins mat (Angular Material), bs (Bootstrap 5) and nv (native HTML). '
9
+ + 'Call get_started first: it explains how the table works and which tool to use when. Describe a table as a BroTableSpec '
10
+ + '(with row details by default), check it with validate_spec, and get its code from generate_code. The server writes no files.';
11
+ /**
12
+ * The one text an agent always reads: how the table works, a minimal working example for the target and the skin
13
+ * of the project, and the topics of the reference.
14
+ */
15
+ export function getStarted(options = {}, extensions = []) {
16
+ const target = options.target ?? 'angular';
17
+ const skin = options.skin ?? (target === 'angular' ? 'mat' : 'bs');
18
+ const products = builtinSpecs.find(builtin => builtin.name === 'products');
19
+ const code = generateCode(products.spec, { target, skin });
20
+ // The page holds the cols, the rows and the config: the second file, after the type of the row
21
+ const page = code.files[1];
22
+ return [
23
+ header(extensions).trim(),
24
+ '## How Table, Bro works',
25
+ find('basics').text().trim(),
26
+ '## The order of the tools',
27
+ find('workflow').text().trim(),
28
+ `## A minimal table: ${target}, skin ${skin}`,
29
+ `Setup, once per project:\n\n${setupText(code.setup)}`,
30
+ `${page.path}:\n\n\`\`\`ts\n${page.content}\`\`\``,
31
+ '## Topics of get_docs',
32
+ topicList(extensions)
33
+ ].join('\n\n');
34
+ }
35
+ /** One topic of the reference, the topics that match a query, or the list of the topics. */
36
+ export function getDocs(request = {}, extensions = []) {
37
+ const all = allTopics(extensions);
38
+ if (request.topic) {
39
+ const topic = all.find(item => item.name === request.topic);
40
+ if (!topic) {
41
+ return `${header(extensions)}No topic ${request.topic}. The topics:\n\n${topicList(extensions)}`;
42
+ }
43
+ return `${header(extensions)}# ${topic.title}\n\n${topic.text().trim()}`;
44
+ }
45
+ if (request.query) {
46
+ const found = search(all, request.query).slice(0, 2);
47
+ if (found.length) {
48
+ return header(extensions) + found.map(topic => `# ${topic.title}\n\n${topic.text().trim()}`).join('\n\n');
49
+ }
50
+ return `${header(extensions)}Nothing found for "${request.query}". The topics:\n\n${topicList(extensions)}`;
51
+ }
52
+ return `${header(extensions)}The topics:\n\n${topicList(extensions)}`;
53
+ }
54
+ function find(name) {
55
+ return topics.find(topic => topic.name === name);
56
+ }
57
+ /** The topics of the reference with the topics of the paid modules that the server loads. */
58
+ export function allTopics(extensions) {
59
+ return [...topics, ...extensions.flatMap(extension => extension.topics ?? [])];
60
+ }
61
+ function topicList(extensions) {
62
+ return allTopics(extensions).map(topic => `- \`${topic.name}\`: ${topic.summary}`).join('\n');
63
+ }
64
+ /** Every answer names the version it describes and the paid modules that the server loads. */
65
+ function header(extensions) {
66
+ const modules = extensions.length ? `, with ${extensions.map(extension => extension.package).join(', ')}` : '';
67
+ return `_table-bro ${tableBroVersion}${modules}_\n\n`;
68
+ }
69
+ /**
70
+ * The topics of a query, the best first. A word that most topics have weighs little, as row, and a rare one decides,
71
+ * as height. A title and a summary weigh more than the text, and every next repeat of a word in the text adds less.
72
+ */
73
+ function search(all, query) {
74
+ const words = [...new Set(query.toLowerCase().split(/[^a-z0-9]+/).filter(word => word.length > 2).map(stem))];
75
+ const docs = all.map(topic => ({ topic, head: tokens(`${topic.name} ${topic.title} ${topic.summary}`), text: tokens(topic.text()) }));
76
+ const weights = words.map(word => Math.log((docs.length + 1) / (docs.filter(doc => count(doc.head, word) + count(doc.text, word)).length + 0.5)));
77
+ return docs
78
+ .map(doc => ({
79
+ topic: doc.topic,
80
+ score: words.reduce((sum, word, index) => {
81
+ const repeats = count(doc.text, word);
82
+ return sum + weights[index] * ((count(doc.head, word) ? 2 : 0) + 2 * repeats / (repeats + 1));
83
+ }, 0)
84
+ }))
85
+ .filter(item => item.score > 0)
86
+ .sort((a, b) => b.score - a.score)
87
+ .map(item => item.topic);
88
+ }
89
+ /** The words of a text in lower case; a name in camelCase gives itself and its parts, as replaceRows, replace and rows. */
90
+ function tokens(text) {
91
+ return text.split(/[^A-Za-z0-9]+/).flatMap(word => {
92
+ const parts = word.split(/(?<=[a-z0-9])(?=[A-Z])/);
93
+ return (parts.length > 1 ? [word, ...parts] : parts).map(part => part.toLowerCase());
94
+ });
95
+ }
96
+ /** A word of a query without the s of the plural: rows finds row and rows. */
97
+ function stem(word) {
98
+ return (word.length > 3 && word.endsWith('s') && !word.endsWith('ss')) ? word.slice(0, -1) : word;
99
+ }
100
+ /** A word of the text matches by its start: row finds rows, but not arrow. */
101
+ function count(words, word) {
102
+ return words.filter(item => item.startsWith(word)).length;
103
+ }
@@ -0,0 +1,25 @@
1
+ /** A file of code of a page of Docs, which the text of the page shows. */
2
+ export interface BroDocFile {
3
+ /** The name of the file, unique on its page; the text shows the file by the line {{file}}. */
4
+ file: string;
5
+ /** The language of the code, as of a Markdown code block: ts, js, scss, css, html, json, bash or text. */
6
+ language: string;
7
+ code: string;
8
+ }
9
+ /**
10
+ * A page of Docs: the one source of the page of Docs on table-bro.com and of its topic of get_docs. The text is
11
+ * Markdown of a few forms: paragraphs, headings ###, #### and #####, ordered lists whose items continue with blocks
12
+ * indented by three spaces, `code`, **strong**, _emphasis_ and [links](url). A line {{file}} shows a file of code, and a line
13
+ * <!-- name --> starts the part of the page that the site shows at that name, next to its tables.
14
+ */
15
+ export interface BroDocPage {
16
+ /** The path of the page under /docs. */
17
+ path: string;
18
+ name: string;
19
+ text: string;
20
+ files: BroDocFile[];
21
+ }
22
+ /** The pages of Docs, in the order of reading. Island Details have their own pages on the site, apart from this package. */
23
+ export declare const docPages: BroDocPage[];
24
+ /** The text of a page as Markdown: without the marks of its parts, with its files of code in code blocks. */
25
+ export declare function docPageMarkdown(page: BroDocPage): string;