eviews-mcp 1.2.0__tar.gz

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.
@@ -0,0 +1,25 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .venv/
7
+ venv/
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+
11
+ # Local MCP client registration, machine specific
12
+ .mcp.json
13
+
14
+ # EViews scratch and output
15
+ *.wf1
16
+ *.wf2
17
+ *.prg
18
+ *.log
19
+
20
+ # Graph and table exports produced by the examples and live tests
21
+ *.emf
22
+ *.wmf
23
+ *.eps
24
+ phillips_residuals.*
25
+ lib_graph.*
@@ -0,0 +1,65 @@
1
+ # Changelog
2
+
3
+ ## 1.2.0
4
+
5
+ ### Added
6
+ - Researcher guide (`docs/EViews-Researcher-Guide.md`): a zero-to-analysis
7
+ walkthrough with every command and output verified against a live session.
8
+ - `close_workfile` / `close_all_workfiles`. EViews caps how many workfiles may
9
+ be open and then refuses to create another.
10
+ - `show` now reads views that freeze into a spool rather than a table, such as
11
+ the ARDL cointegrating relationship and error-correction results, by writing
12
+ the frozen object out as text.
13
+
14
+ ### Fixed
15
+ - Importing a data file while a workfile was open made EViews truncate the file
16
+ to that page's length, silently. A 100-row file read into an open 12-row page
17
+ lost 88 rows with no warning. Imports now create a workfile sized to the file;
18
+ merging into the open page is opt-in via `into_current_page`.
19
+ - Long title and note rows padded column 0 across the whole table, pushing the
20
+ numbers far to the right in unit root and diagnostic output. Such rows are now
21
+ written full width and excluded from column measurement.
22
+ - `read_data` with `max_rows` below 20 sliced the head negatively and returned
23
+ more rows than asked for, not fewer.
24
+ - Table cells were truncated at 40 characters with a non-ASCII ellipsis, cutting
25
+ text such as "Included observations: 122 after adjustments" and mangling in
26
+ consoles that are not UTF-8.
27
+
28
+ ## 1.1.0
29
+
30
+ Restructured into a library with the MCP server as a thin adapter on top.
31
+
32
+ ### Added
33
+ - `EViews` client class as the public Python API, usable from scripts and
34
+ notebooks independently of MCP. Context-manager support.
35
+ - pandas integration: `to_dataframe` and `from_dataframe`, with the EViews page
36
+ frequency and span derived from a `DatetimeIndex` or `PeriodIndex`.
37
+ - `exists`, `describe`, `table` (raw rows at full precision), `value`,
38
+ `obs_labels`.
39
+ - Offline test suite that needs neither EViews nor Windows.
40
+ - Packaging metadata, MIT licence, examples.
41
+
42
+ ### Fixed
43
+ - `from_dataframe` wrote a dated frame into whatever page was already open when
44
+ that page was long enough, silently landing the values on the wrong dates. A
45
+ dated frame now governs the page.
46
+ - Writes default to the whole page. EViews honours the active sample on writes,
47
+ so under a restricted sample values outside it were silently left NA.
48
+
49
+ ### Changed
50
+ - Import on a non-Windows platform now raises a clear message instead of an
51
+ opaque `pythoncom` `ImportError`.
52
+
53
+ ## 1.0.0
54
+
55
+ First working version, built against the EViews 13 COM type library.
56
+
57
+ ### Fixed relative to the original prototype
58
+ - `GetScalar`, `PutScalar` and `GetString` do not exist on the EViews COM
59
+ interface and failed on every call. Replaced with `Get`, which covers all
60
+ three and infers the type.
61
+ - Log capture through `output(r) "file"` never wrote a file, so every run
62
+ reported "Done (no output)" whether it succeeded or failed. Results are now
63
+ read by freezing an object into a table and pulling it across COM.
64
+ - COM calls were made from arbitrary MCP worker threads. All EViews access is
65
+ now funnelled onto one apartment-initialised thread.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Merwan Roudane
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.
@@ -0,0 +1,300 @@
1
+ Metadata-Version: 2.5
2
+ Name: eviews-mcp
3
+ Version: 1.2.0
4
+ Summary: Drive EViews from Python, and expose it to LLM clients over MCP
5
+ Project-URL: Homepage, https://github.com/merwanroudane/MCP_EVIEWS
6
+ Project-URL: Repository, https://github.com/merwanroudane/MCP_EVIEWS
7
+ Project-URL: Issues, https://github.com/merwanroudane/MCP_EVIEWS/issues
8
+ Author-email: Merwan Roudane <merwanroudane920@gmail.com>
9
+ Maintainer-email: Merwan Roudane <merwanroudane920@gmail.com>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Merwan Roudane
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: com-automation,econometrics,eviews,mcp,model-context-protocol,regression,statistics,time-series
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Environment :: Console
35
+ Classifier: Intended Audience :: Financial and Insurance Industry
36
+ Classifier: Intended Audience :: Science/Research
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Operating System :: Microsoft :: Windows
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Programming Language :: Python :: 3.13
44
+ Classifier: Topic :: Office/Business :: Financial :: Investment
45
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
46
+ Requires-Python: >=3.10
47
+ Requires-Dist: mcp[cli]>=1.2.0
48
+ Requires-Dist: pywin32>=306; sys_platform == 'win32'
49
+ Provides-Extra: dev
50
+ Requires-Dist: pandas>=1.5; extra == 'dev'
51
+ Requires-Dist: pytest>=7.0; extra == 'dev'
52
+ Provides-Extra: pandas
53
+ Requires-Dist: pandas>=1.5; extra == 'pandas'
54
+ Description-Content-Type: text/markdown
55
+
56
+ # eviews-mcp
57
+
58
+ Drive **EViews** from Python, and expose it to LLM clients over the Model
59
+ Context Protocol.
60
+
61
+ Two things in one package:
62
+
63
+ - **A library.** An `EViews` class for scripts and notebooks — build workfiles,
64
+ estimate models, read results back as text or pandas DataFrames.
65
+ - **An MCP server.** The same capabilities as tools, so an assistant can do
66
+ econometrics in a real EViews session.
67
+
68
+ Built and tested against **EViews 13** on Windows; EViews 10–14 resolve
69
+ correctly through the same COM interface.
70
+
71
+ > **New to this?** The [**EViews Researcher Guide**](https://github.com/merwanroudane/MCP_EVIEWS/blob/main/docs/EViews-Researcher-Guide.md)
72
+ > takes you from a clean machine to a finished ARDL study, with every command and
73
+ > every output verified against a real EViews session. No Python knowledge assumed.
74
+
75
+ ## Install
76
+
77
+ ```bash
78
+ pip install git+https://github.com/merwanroudane/MCP_EVIEWS.git
79
+ ```
80
+
81
+ With pandas support:
82
+
83
+ ```bash
84
+ pip install "eviews-mcp[pandas] @ git+https://github.com/merwanroudane/MCP_EVIEWS.git"
85
+ ```
86
+
87
+ Or from a clone, for development:
88
+
89
+ ```bash
90
+ git clone https://github.com/merwanroudane/MCP_EVIEWS.git
91
+ cd MCP_EVIEWS
92
+ pip install -e .[dev]
93
+ ```
94
+
95
+ Requires Windows and a local EViews installation, since it drives EViews
96
+ through COM automation.
97
+
98
+ ## Library use
99
+
100
+ ```python
101
+ from eviews_mcp import EViews
102
+
103
+ with EViews() as ev:
104
+ ev.create_workfile("q", "1990q1", "2020q4")
105
+ ev.run("""
106
+ series k = 100 + @trend + 3*@nrnd
107
+ series l = 50 + 0.5*@trend + 2*@nrnd
108
+ series gdp = 10 + 0.6*k + 0.3*l + 2*@nrnd
109
+ equation eq1.ls gdp c k l
110
+ """)
111
+
112
+ print(ev.show("eq1"))
113
+ print(ev.value("eq1.@r2"))
114
+ ```
115
+
116
+ ```text
117
+ Dependent Variable: GDP
118
+ Method: Least Squares
119
+ Included observations: 124
120
+
121
+ Variable Coefficient Std. Error t-Statistic Prob.
122
+
123
+ C 9.58073 0.829252 11.5535 2.90e-21
124
+ K 0.591693 0.0333819 17.7250 1.99e-35
125
+ L 0.322394 0.0673315 4.78816 4.81e-06
126
+
127
+ R-squared 0.994702 Mean dependent var 131.080
128
+ ```
129
+
130
+ ### Any EViews view, as text
131
+
132
+ `show` takes a view, so diagnostics need no extra API:
133
+
134
+ ```python
135
+ ev.show("eq1", "wald c(2)=c(3)") # coefficient restriction test
136
+ ev.show("eq1", "resids(t)") # residual table
137
+ ev.show("eq1", "coefcov") # coefficient covariance
138
+ ev.show("eq1", "auto(2)") # Breusch-Godfrey serial correlation
139
+ ev.show("eq1", "white") # White heteroskedasticity test
140
+ ev.show("gdp", "uroot") # unit root test
141
+ ev.show("gdp", "correl") # correlogram
142
+ ev.show("ardl1", "cointrel") # ARDL long-run relationship
143
+ ev.show("var1", "impulse(t)") # impulse response table
144
+ ev.show("var1", "testexog") # Granger causality
145
+ ```
146
+
147
+ `resids` and `impulse` draw graphs by default; the `(t)` variants ask EViews
148
+ for the table form. Views that freeze into a spool rather than a table -- the
149
+ ARDL cointegrating relationship among them -- cannot be read over COM at all,
150
+ so `show` falls back to a text dump for those.
151
+
152
+ For the numbers rather than the layout, `table()` returns raw rows at full
153
+ double precision, and `value()` returns one number:
154
+
155
+ ```python
156
+ rows = ev.table("eq1") # tuple of row tuples
157
+ r2 = ev.value("eq1.@r2") # 0.9947015...
158
+ beta = ev.value("eq1.@coefs(2)")
159
+ ```
160
+
161
+ ### pandas both ways
162
+
163
+ ```python
164
+ frame = ev.to_dataframe(["gdp", "k", "l"]) # indexed 1990Q1, 1990Q2, ...
165
+ frame.corr()
166
+ ```
167
+
168
+ Writing back, a `DatetimeIndex` or `PeriodIndex` decides the page frequency and
169
+ span, so dates stay aligned:
170
+
171
+ ```python
172
+ import pandas as pd
173
+
174
+ index = pd.period_range("2005Q1", periods=40, freq="Q")
175
+ df = pd.DataFrame({"inflation": ..., "unemployment": ...}, index=index)
176
+
177
+ ev.from_dataframe(df) # creates a quarterly 2005Q1–2014Q4 page
178
+ ev.run("equation phillips.ls inflation c unemployment")
179
+ ```
180
+
181
+ Non-numeric columns are skipped rather than failing the whole frame.
182
+
183
+ ### Graphs
184
+
185
+ Graphs cannot be rendered as text, so write them to a file:
186
+
187
+ ```python
188
+ ev.export_object("phillips", "residuals.png", view="resids")
189
+ ```
190
+
191
+ Graph formats: `png`, `jpg`, `pdf`, `emf`, `wmf`, `bmp`, `gif`, `eps`, `tex`.
192
+ Table formats: `csv`, `rtf`, `txt`, `html`.
193
+
194
+ ### Errors
195
+
196
+ EViews reports failures precisely, including the line number inside a program,
197
+ and those messages are passed through unchanged:
198
+
199
+ ```python
200
+ ev.run("series ok = 1\nbroken_command\n")
201
+ ```
202
+
203
+ ```text
204
+ EViewsError: BROKEN_COMMAND is not defined or is an illegal command
205
+ in "BROKEN_COMMAND" in MCP_3BA1F7DC.PRG on line 2.
206
+ ```
207
+
208
+ ## MCP server use
209
+
210
+ Register the `eviews-mcp` command with your MCP client:
211
+
212
+ ```json
213
+ {
214
+ "mcpServers": {
215
+ "eviews": {
216
+ "command": "eviews-mcp"
217
+ }
218
+ }
219
+ }
220
+ ```
221
+
222
+ For Claude Code:
223
+
224
+ ```bash
225
+ claude mcp add eviews -- eviews-mcp
226
+ ```
227
+
228
+ ### Tools
229
+
230
+ | Tool | Purpose |
231
+ |---|---|
232
+ | `eviews_status` | Connection, version, active workfile. Start here when debugging. |
233
+ | `reset_eviews` | Discard the instance and start clean. |
234
+ | `set_eviews_visible` | Show or hide the EViews window. |
235
+ | `create_workfile` | New page by frequency and range. |
236
+ | `open_workfile` / `save_workfile` | Open and save `.wf1` / `.wf2`. |
237
+ | `close_workfile` | Close one or all open workfiles. |
238
+ | `workfile_info` | Name, page, frequency, range, sample. |
239
+ | `list_objects` | Inventory, filterable by EViews type. |
240
+ | `set_sample` | Set the estimation sample. |
241
+ | `run_eviews_code` | **Main tool.** Run a block of EViews program code. |
242
+ | `run_program_file` | Run an existing `.prg`, with arguments. |
243
+ | `command` | A single command line. |
244
+ | `show` | **Render any object as a text table.** |
245
+ | `evaluate` | One value from an expression. |
246
+ | `describe_object` | Type, plus statistics for a series. |
247
+ | `read_data` | Series as an aligned table or full-precision CSV. |
248
+ | `write_series` | Write values into a series. |
249
+ | `import_data` | Read `.xlsx`, `.csv`, `.dta`, `.sav`, and more. |
250
+ | `export_data` | Write series to a file. |
251
+ | `export_object` | Save an object — the way to retrieve graphs. |
252
+
253
+ Results are not echoed by `run_eviews_code`, because EViews sends program
254
+ output to its own log window where COM cannot reach it. Estimate into a named
255
+ object and call `show` on it.
256
+
257
+ ## Behaviour worth knowing
258
+
259
+ These are EViews characteristics that the library handles for you, documented
260
+ because they surprise people writing COM code directly.
261
+
262
+ - **Writes respect the active sample.** Under `smpl 2000m3 2000m6`, writing 12
263
+ values lands 4 and silently leaves the rest NA. Writes therefore default to
264
+ the whole page; pass `sample=""` to opt into the current sample instead.
265
+ - **`save` ignores the file extension.** `graph.save "out.png"` writes EMF
266
+ data. The format is passed explicitly, and a save that produces no file
267
+ raises rather than reporting success.
268
+ - **Relative paths resolve against EViews**, not the calling process, so paths
269
+ are made absolute before they are handed over.
270
+ - **A dated frame governs the page.** Writing a 12-row quarterly frame into an
271
+ open 80-row page would land the values on the wrong dates, so a page matching
272
+ the frame is created instead.
273
+ - **No log redirection.** The `output` command requires a frozen object name
274
+ and otherwise writes nothing at all, so it cannot capture a log. Results come
275
+ from freezing an object into a table and reading that.
276
+ - **No `GetScalar` / `PutScalar` / `GetString`.** These are not on the EViews
277
+ COM interface at all. `Get` covers them and infers the type.
278
+ - **One COM thread.** MCP dispatches synchronous tools across a thread pool,
279
+ and a COM pointer is not valid across apartments, so every EViews call is
280
+ funnelled onto a single apartment-initialised thread.
281
+ - **Importing into an open workfile truncates the file** to that page's length,
282
+ silently. Imports therefore create a new workfile by default; merging into the
283
+ current page is opt-in.
284
+ - **EViews limits how many workfiles may be open** and then refuses to create
285
+ another, so `close_workfile` exists to keep long sessions healthy.
286
+
287
+ ## Tests
288
+
289
+ ```bash
290
+ python tests/test_offline.py # 20 tests, no EViews needed
291
+ python tests/test_live.py # 25 tests, drives the MCP tool layer
292
+ python tests/test_live_client.py # 39 tests, drives the library API
293
+ ```
294
+
295
+ `pytest` runs the offline suite by default; the live suites are opt-in because
296
+ they need an EViews licence.
297
+
298
+ ## Licence
299
+
300
+ MIT. Copyright (c) 2026 Merwan Roudane.
@@ -0,0 +1,245 @@
1
+ # eviews-mcp
2
+
3
+ Drive **EViews** from Python, and expose it to LLM clients over the Model
4
+ Context Protocol.
5
+
6
+ Two things in one package:
7
+
8
+ - **A library.** An `EViews` class for scripts and notebooks — build workfiles,
9
+ estimate models, read results back as text or pandas DataFrames.
10
+ - **An MCP server.** The same capabilities as tools, so an assistant can do
11
+ econometrics in a real EViews session.
12
+
13
+ Built and tested against **EViews 13** on Windows; EViews 10–14 resolve
14
+ correctly through the same COM interface.
15
+
16
+ > **New to this?** The [**EViews Researcher Guide**](https://github.com/merwanroudane/MCP_EVIEWS/blob/main/docs/EViews-Researcher-Guide.md)
17
+ > takes you from a clean machine to a finished ARDL study, with every command and
18
+ > every output verified against a real EViews session. No Python knowledge assumed.
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ pip install git+https://github.com/merwanroudane/MCP_EVIEWS.git
24
+ ```
25
+
26
+ With pandas support:
27
+
28
+ ```bash
29
+ pip install "eviews-mcp[pandas] @ git+https://github.com/merwanroudane/MCP_EVIEWS.git"
30
+ ```
31
+
32
+ Or from a clone, for development:
33
+
34
+ ```bash
35
+ git clone https://github.com/merwanroudane/MCP_EVIEWS.git
36
+ cd MCP_EVIEWS
37
+ pip install -e .[dev]
38
+ ```
39
+
40
+ Requires Windows and a local EViews installation, since it drives EViews
41
+ through COM automation.
42
+
43
+ ## Library use
44
+
45
+ ```python
46
+ from eviews_mcp import EViews
47
+
48
+ with EViews() as ev:
49
+ ev.create_workfile("q", "1990q1", "2020q4")
50
+ ev.run("""
51
+ series k = 100 + @trend + 3*@nrnd
52
+ series l = 50 + 0.5*@trend + 2*@nrnd
53
+ series gdp = 10 + 0.6*k + 0.3*l + 2*@nrnd
54
+ equation eq1.ls gdp c k l
55
+ """)
56
+
57
+ print(ev.show("eq1"))
58
+ print(ev.value("eq1.@r2"))
59
+ ```
60
+
61
+ ```text
62
+ Dependent Variable: GDP
63
+ Method: Least Squares
64
+ Included observations: 124
65
+
66
+ Variable Coefficient Std. Error t-Statistic Prob.
67
+
68
+ C 9.58073 0.829252 11.5535 2.90e-21
69
+ K 0.591693 0.0333819 17.7250 1.99e-35
70
+ L 0.322394 0.0673315 4.78816 4.81e-06
71
+
72
+ R-squared 0.994702 Mean dependent var 131.080
73
+ ```
74
+
75
+ ### Any EViews view, as text
76
+
77
+ `show` takes a view, so diagnostics need no extra API:
78
+
79
+ ```python
80
+ ev.show("eq1", "wald c(2)=c(3)") # coefficient restriction test
81
+ ev.show("eq1", "resids(t)") # residual table
82
+ ev.show("eq1", "coefcov") # coefficient covariance
83
+ ev.show("eq1", "auto(2)") # Breusch-Godfrey serial correlation
84
+ ev.show("eq1", "white") # White heteroskedasticity test
85
+ ev.show("gdp", "uroot") # unit root test
86
+ ev.show("gdp", "correl") # correlogram
87
+ ev.show("ardl1", "cointrel") # ARDL long-run relationship
88
+ ev.show("var1", "impulse(t)") # impulse response table
89
+ ev.show("var1", "testexog") # Granger causality
90
+ ```
91
+
92
+ `resids` and `impulse` draw graphs by default; the `(t)` variants ask EViews
93
+ for the table form. Views that freeze into a spool rather than a table -- the
94
+ ARDL cointegrating relationship among them -- cannot be read over COM at all,
95
+ so `show` falls back to a text dump for those.
96
+
97
+ For the numbers rather than the layout, `table()` returns raw rows at full
98
+ double precision, and `value()` returns one number:
99
+
100
+ ```python
101
+ rows = ev.table("eq1") # tuple of row tuples
102
+ r2 = ev.value("eq1.@r2") # 0.9947015...
103
+ beta = ev.value("eq1.@coefs(2)")
104
+ ```
105
+
106
+ ### pandas both ways
107
+
108
+ ```python
109
+ frame = ev.to_dataframe(["gdp", "k", "l"]) # indexed 1990Q1, 1990Q2, ...
110
+ frame.corr()
111
+ ```
112
+
113
+ Writing back, a `DatetimeIndex` or `PeriodIndex` decides the page frequency and
114
+ span, so dates stay aligned:
115
+
116
+ ```python
117
+ import pandas as pd
118
+
119
+ index = pd.period_range("2005Q1", periods=40, freq="Q")
120
+ df = pd.DataFrame({"inflation": ..., "unemployment": ...}, index=index)
121
+
122
+ ev.from_dataframe(df) # creates a quarterly 2005Q1–2014Q4 page
123
+ ev.run("equation phillips.ls inflation c unemployment")
124
+ ```
125
+
126
+ Non-numeric columns are skipped rather than failing the whole frame.
127
+
128
+ ### Graphs
129
+
130
+ Graphs cannot be rendered as text, so write them to a file:
131
+
132
+ ```python
133
+ ev.export_object("phillips", "residuals.png", view="resids")
134
+ ```
135
+
136
+ Graph formats: `png`, `jpg`, `pdf`, `emf`, `wmf`, `bmp`, `gif`, `eps`, `tex`.
137
+ Table formats: `csv`, `rtf`, `txt`, `html`.
138
+
139
+ ### Errors
140
+
141
+ EViews reports failures precisely, including the line number inside a program,
142
+ and those messages are passed through unchanged:
143
+
144
+ ```python
145
+ ev.run("series ok = 1\nbroken_command\n")
146
+ ```
147
+
148
+ ```text
149
+ EViewsError: BROKEN_COMMAND is not defined or is an illegal command
150
+ in "BROKEN_COMMAND" in MCP_3BA1F7DC.PRG on line 2.
151
+ ```
152
+
153
+ ## MCP server use
154
+
155
+ Register the `eviews-mcp` command with your MCP client:
156
+
157
+ ```json
158
+ {
159
+ "mcpServers": {
160
+ "eviews": {
161
+ "command": "eviews-mcp"
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ For Claude Code:
168
+
169
+ ```bash
170
+ claude mcp add eviews -- eviews-mcp
171
+ ```
172
+
173
+ ### Tools
174
+
175
+ | Tool | Purpose |
176
+ |---|---|
177
+ | `eviews_status` | Connection, version, active workfile. Start here when debugging. |
178
+ | `reset_eviews` | Discard the instance and start clean. |
179
+ | `set_eviews_visible` | Show or hide the EViews window. |
180
+ | `create_workfile` | New page by frequency and range. |
181
+ | `open_workfile` / `save_workfile` | Open and save `.wf1` / `.wf2`. |
182
+ | `close_workfile` | Close one or all open workfiles. |
183
+ | `workfile_info` | Name, page, frequency, range, sample. |
184
+ | `list_objects` | Inventory, filterable by EViews type. |
185
+ | `set_sample` | Set the estimation sample. |
186
+ | `run_eviews_code` | **Main tool.** Run a block of EViews program code. |
187
+ | `run_program_file` | Run an existing `.prg`, with arguments. |
188
+ | `command` | A single command line. |
189
+ | `show` | **Render any object as a text table.** |
190
+ | `evaluate` | One value from an expression. |
191
+ | `describe_object` | Type, plus statistics for a series. |
192
+ | `read_data` | Series as an aligned table or full-precision CSV. |
193
+ | `write_series` | Write values into a series. |
194
+ | `import_data` | Read `.xlsx`, `.csv`, `.dta`, `.sav`, and more. |
195
+ | `export_data` | Write series to a file. |
196
+ | `export_object` | Save an object — the way to retrieve graphs. |
197
+
198
+ Results are not echoed by `run_eviews_code`, because EViews sends program
199
+ output to its own log window where COM cannot reach it. Estimate into a named
200
+ object and call `show` on it.
201
+
202
+ ## Behaviour worth knowing
203
+
204
+ These are EViews characteristics that the library handles for you, documented
205
+ because they surprise people writing COM code directly.
206
+
207
+ - **Writes respect the active sample.** Under `smpl 2000m3 2000m6`, writing 12
208
+ values lands 4 and silently leaves the rest NA. Writes therefore default to
209
+ the whole page; pass `sample=""` to opt into the current sample instead.
210
+ - **`save` ignores the file extension.** `graph.save "out.png"` writes EMF
211
+ data. The format is passed explicitly, and a save that produces no file
212
+ raises rather than reporting success.
213
+ - **Relative paths resolve against EViews**, not the calling process, so paths
214
+ are made absolute before they are handed over.
215
+ - **A dated frame governs the page.** Writing a 12-row quarterly frame into an
216
+ open 80-row page would land the values on the wrong dates, so a page matching
217
+ the frame is created instead.
218
+ - **No log redirection.** The `output` command requires a frozen object name
219
+ and otherwise writes nothing at all, so it cannot capture a log. Results come
220
+ from freezing an object into a table and reading that.
221
+ - **No `GetScalar` / `PutScalar` / `GetString`.** These are not on the EViews
222
+ COM interface at all. `Get` covers them and infers the type.
223
+ - **One COM thread.** MCP dispatches synchronous tools across a thread pool,
224
+ and a COM pointer is not valid across apartments, so every EViews call is
225
+ funnelled onto a single apartment-initialised thread.
226
+ - **Importing into an open workfile truncates the file** to that page's length,
227
+ silently. Imports therefore create a new workfile by default; merging into the
228
+ current page is opt-in.
229
+ - **EViews limits how many workfiles may be open** and then refuses to create
230
+ another, so `close_workfile` exists to keep long sessions healthy.
231
+
232
+ ## Tests
233
+
234
+ ```bash
235
+ python tests/test_offline.py # 20 tests, no EViews needed
236
+ python tests/test_live.py # 25 tests, drives the MCP tool layer
237
+ python tests/test_live_client.py # 39 tests, drives the library API
238
+ ```
239
+
240
+ `pytest` runs the offline suite by default; the live suites are opt-in because
241
+ they need an EViews licence.
242
+
243
+ ## Licence
244
+
245
+ MIT. Copyright (c) 2026 Merwan Roudane.